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.net.InetAddress;
26 import java.net.UnknownHostException;
27 import java.util.ArrayList;
28 import java.util.Collections;
29 import java.util.HashSet;
30 import java.util.List;
31 import java.util.Properties;
34 import javax.inject.Inject;
36 import org.junit.Assert;
37 import org.junit.Before;
38 import org.junit.Test;
39 import org.junit.runner.RunWith;
40 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
41 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
42 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
43 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
44 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
45 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
46 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
47 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
48 import org.opendaylight.ovsdb.southbound.SouthboundProvider;
49 import org.opendaylight.ovsdb.southbound.SouthboundUtil;
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.OvsdbNodeAugmentationBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes.VlanMode;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIdsBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.DatapathTypeEntry;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntryBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigs;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigsBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIds;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigs;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigsBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder;
93 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
94 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
95 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
96 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
97 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
98 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
99 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
100 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
101 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
102 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
103 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
104 import org.opendaylight.yangtools.concepts.Builder;
105 import org.opendaylight.yangtools.yang.binding.DataObject;
106 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
107 import org.ops4j.pax.exam.Configuration;
108 import org.ops4j.pax.exam.Option;
109 import org.ops4j.pax.exam.junit.PaxExam;
110 import org.ops4j.pax.exam.karaf.options.KarafDistributionOption;
111 import org.ops4j.pax.exam.karaf.options.LogLevelOption;
112 import org.ops4j.pax.exam.options.MavenUrlReference;
113 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
114 import org.ops4j.pax.exam.spi.reactors.PerClass;
115 import org.osgi.framework.BundleContext;
116 import org.slf4j.Logger;
117 import org.slf4j.LoggerFactory;
120 * Integration tests for southbound-impl
122 * @author Sam Hague (shague@redhat.com)
124 @RunWith(PaxExam.class)
125 @ExamReactorStrategy(PerClass.class)
126 public class SouthboundIT extends AbstractMdsalTestBase {
127 private static final String NETDEV_DP_TYPE = "netdev";
128 private static final Logger LOG = LoggerFactory.getLogger(SouthboundIT.class);
129 private static final int OVSDB_UPDATE_TIMEOUT = 1000;
130 private static final int OVSDB_ROUNDTRIP_TIMEOUT = 10000;
131 private static final String FORMAT_STR = "%s_%s_%d";
132 private static String addressStr;
133 private static int portNumber;
134 private static String connectionType;
135 private static boolean setup = false;
136 private static MdsalUtils mdsalUtils = null;
138 // TODO Constants copied from AbstractConfigTestBase, need to be removed (see TODO below)
139 private static final String PAX_EXAM_UNPACK_DIRECTORY = "target/exam";
140 private static final String KARAF_DEBUG_PORT = "5005";
141 private static final String KARAF_DEBUG_PROP = "karaf.debug";
142 private static final String KEEP_UNPACK_DIRECTORY_PROP = "karaf.keep.unpack";
145 private BundleContext bundleContext;
147 private static final NotifyingDataChangeListener CONFIGURATION_LISTENER =
148 new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION);
149 private static final NotifyingDataChangeListener OPERATIONAL_LISTENER =
150 new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL);
152 private static class NotifyingDataChangeListener implements DataChangeListener {
153 private final LogicalDatastoreType type;
154 private final Set<InstanceIdentifier<?>> createdIids = new HashSet<>();
155 private final Set<InstanceIdentifier<?>> removedIids = new HashSet<>();
156 private final Set<InstanceIdentifier<?>> updatedIids = new HashSet<>();
158 private NotifyingDataChangeListener(LogicalDatastoreType type) {
163 public void onDataChanged(
164 AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> asyncDataChangeEvent) {
165 LOG.info("{} DataChanged: created {}", type, asyncDataChangeEvent.getCreatedData().keySet());
166 LOG.info("{} DataChanged: removed {}", type, asyncDataChangeEvent.getRemovedPaths());
167 LOG.info("{} DataChanged: updated {}", type, asyncDataChangeEvent.getUpdatedData().keySet());
168 createdIids.addAll(asyncDataChangeEvent.getCreatedData().keySet());
169 removedIids.addAll(asyncDataChangeEvent.getRemovedPaths());
170 updatedIids.addAll(asyncDataChangeEvent.getUpdatedData().keySet());
171 // Handled managed iids
172 for (DataObject obj : asyncDataChangeEvent.getCreatedData().values()) {
173 if (obj instanceof ManagedNodeEntry) {
174 ManagedNodeEntry managedNodeEntry = (ManagedNodeEntry) obj;
175 LOG.info("{} DataChanged: created managed {}", managedNodeEntry.getBridgeRef().getValue());
176 createdIids.add(managedNodeEntry.getBridgeRef().getValue());
184 public boolean isCreated(InstanceIdentifier<?> iid) {
185 return createdIids.remove(iid);
188 public boolean isRemoved(InstanceIdentifier<?> iid) {
189 return removedIids.remove(iid);
192 public boolean isUpdated(InstanceIdentifier<?> iid) {
193 return updatedIids.remove(iid);
198 public Option[] config() {
199 // TODO Figure out how to use the parent Karaf setup, then just use super.config()
200 Option[] options = new Option[] {
201 when(Boolean.getBoolean(KARAF_DEBUG_PROP))
202 .useOptions(KarafDistributionOption.debugConfiguration(KARAF_DEBUG_PORT, true)),
203 karafDistributionConfiguration().frameworkUrl(getKarafDistro())
204 .unpackDirectory(new File(PAX_EXAM_UNPACK_DIRECTORY))
205 .useDeployFolder(false),
206 when(Boolean.getBoolean(KEEP_UNPACK_DIRECTORY_PROP)).useOptions(keepRuntimeFolder()),
207 // Works only if we don't specify the feature repo and name
209 Option[] propertyOptions = getPropertiesOptions();
210 Option[] otherOptions = getOtherOptions();
211 Option[] combinedOptions = new Option[options.length + propertyOptions.length + otherOptions.length];
212 System.arraycopy(options, 0, combinedOptions, 0, options.length);
213 System.arraycopy(propertyOptions, 0, combinedOptions, options.length, propertyOptions.length);
214 System.arraycopy(otherOptions, 0, combinedOptions, options.length + propertyOptions.length,
215 otherOptions.length);
216 return combinedOptions;
219 private Option[] getOtherOptions() {
220 return new Option[] {
221 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
227 public String getKarafDistro() {
229 .groupId("org.opendaylight.ovsdb")
230 .artifactId("southbound-karaf")
231 .versionAsInProject()
237 public String getModuleName() {
238 return "southbound-impl";
242 public String getInstanceName() {
243 return "southbound-default";
247 public MavenUrlReference getFeatureRepo() {
249 .groupId("org.opendaylight.ovsdb")
250 .artifactId("southbound-features")
251 .classifier("features")
253 .versionAsInProject();
257 public String getFeatureName() {
258 return "odl-ovsdb-southbound-impl-ui";
261 protected String usage() {
262 return "Integration Test needs a valid connection configuration as follows :\n"
263 + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
264 + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
268 public Option getLoggingOption() {
270 editConfigurationFilePut(SouthboundITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
271 "log4j.logger.org.opendaylight.ovsdb",
272 LogLevelOption.LogLevel.TRACE.name()),
273 super.getLoggingOption());
276 private Option[] getPropertiesOptions() {
277 Properties props = new Properties(System.getProperties());
278 String addressStr = props.getProperty(SouthboundITConstants.SERVER_IPADDRESS,
279 SouthboundITConstants.DEFAULT_SERVER_IPADDRESS);
280 String portStr = props.getProperty(SouthboundITConstants.SERVER_PORT,
281 SouthboundITConstants.DEFAULT_SERVER_PORT);
282 String connectionType = props.getProperty(SouthboundITConstants.CONNECTION_TYPE,
283 SouthboundITConstants.CONNECTION_TYPE_ACTIVE);
285 LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}",
286 connectionType, addressStr, portStr);
288 return new Option[] {
289 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
290 SouthboundITConstants.SERVER_IPADDRESS, addressStr),
291 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
292 SouthboundITConstants.SERVER_PORT, portStr),
293 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
294 SouthboundITConstants.CONNECTION_TYPE, connectionType),
300 public void setup() throws InterruptedException {
302 LOG.info("Skipping setup, already initialized");
308 } catch (Exception e) {
311 //dataBroker = getSession().getSALService(DataBroker.class);
313 DataBroker dataBroker = SouthboundProvider.getDb();
314 Assert.assertNotNull("db should not be null", dataBroker);
316 addressStr = bundleContext.getProperty(SouthboundITConstants.SERVER_IPADDRESS);
317 String portStr = bundleContext.getProperty(SouthboundITConstants.SERVER_PORT);
319 portNumber = Integer.parseInt(portStr);
320 } catch (NumberFormatException e) {
321 fail("Invalid port number " + portStr + System.lineSeparator() + usage());
323 connectionType = bundleContext.getProperty(SouthboundITConstants.CONNECTION_TYPE);
325 LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
326 connectionType, addressStr, portNumber);
327 if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_ACTIVE)) {
328 if (addressStr == null) {
333 mdsalUtils = new MdsalUtils(dataBroker);
334 dataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
335 createInstanceIdentifier(getConnectionInfo(addressStr, portNumber)), CONFIGURATION_LISTENER,
336 AsyncDataBroker.DataChangeScope.SUBTREE);
337 dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
338 createInstanceIdentifier(getConnectionInfo(addressStr, portNumber)), OPERATIONAL_LISTENER,
339 AsyncDataBroker.DataChangeScope.SUBTREE);
345 * Test passive connection mode. The southbound starts in a listening mode waiting for connections on port
346 * 6640. This test will wait for incoming connections for {@link SouthboundITConstants#CONNECTION_INIT_TIMEOUT} ms.
348 * @throws InterruptedException
351 public void testPassiveNode() throws InterruptedException {
352 if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_PASSIVE)) {
353 //Wait for CONNECTION_INIT_TIMEOUT for the Passive connection to be initiated by the ovsdb-server.
354 Thread.sleep(SouthboundITConstants.CONNECTION_INIT_TIMEOUT);
358 private ConnectionInfo getConnectionInfo(final String addressStr, final int portNumber) {
359 InetAddress inetAddress = null;
361 inetAddress = InetAddress.getByName(addressStr);
362 } catch (UnknownHostException e) {
363 fail("Could not resolve " + addressStr + ": " + e);
366 IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
367 PortNumber port = new PortNumber(portNumber);
369 final ConnectionInfo connectionInfo = new ConnectionInfoBuilder()
370 .setRemoteIp(address)
373 LOG.info("connectionInfo: {}", connectionInfo);
374 return connectionInfo;
377 private String connectionInfoToString(final ConnectionInfo connectionInfo) {
378 return new String(connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
382 public void testNetworkTopology() throws InterruptedException {
383 NetworkTopology networkTopology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION,
384 InstanceIdentifier.create(NetworkTopology.class));
385 Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.CONFIGURATION,
388 networkTopology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
389 InstanceIdentifier.create(NetworkTopology.class));
390 Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.OPERATIONAL,
395 public void testOvsdbTopology() throws InterruptedException {
396 InstanceIdentifier<Topology> path = InstanceIdentifier
397 .create(NetworkTopology.class)
398 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
400 Topology topology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
401 Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.CONFIGURATION,
404 topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
406 Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.OPERATIONAL,
410 private InstanceIdentifier<Node> createInstanceIdentifier(
411 ConnectionInfo connectionInfo) {
412 return InstanceIdentifier
413 .create(NetworkTopology.class)
414 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
416 createNodeKey(connectionInfo.getRemoteIp(), connectionInfo.getRemotePort()));
419 private Node connectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
420 final InstanceIdentifier<Node> iid = createInstanceIdentifier(connectionInfo);
421 Assert.assertTrue(mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, iid, createNode(connectionInfo)));
422 waitForOperationalCreation(iid);
423 Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid);
424 Assert.assertNotNull(node);
425 LOG.info("Connected to {}", connectionInfoToString(connectionInfo));
429 private void waitForOperationalCreation(InstanceIdentifier<Node> iid) throws InterruptedException {
430 synchronized (OPERATIONAL_LISTENER) {
431 long _start = System.currentTimeMillis();
432 LOG.info("Waiting for OPERATIONAL DataChanged creation on {}", iid);
433 while (!OPERATIONAL_LISTENER.isCreated(
434 iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) {
435 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
437 LOG.info("Woke up, waited {} for creation of {}", (System.currentTimeMillis() - _start), iid);
441 private void waitForOperationalDeletion(InstanceIdentifier<Node> iid) throws InterruptedException {
442 synchronized (OPERATIONAL_LISTENER) {
443 long _start = System.currentTimeMillis();
444 LOG.info("Waiting for OPERATIONAL DataChanged deletion on {}", iid);
445 while (!OPERATIONAL_LISTENER.isRemoved(
446 iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) {
447 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
449 LOG.info("Woke up, waited {} for deletion of {}", (System.currentTimeMillis() - _start), iid);
453 private void waitForOperationalUpdate(InstanceIdentifier<Node> iid) throws InterruptedException {
454 synchronized (OPERATIONAL_LISTENER) {
455 long _start = System.currentTimeMillis();
456 LOG.info("Waiting for OPERATIONAL DataChanged update on {}", iid);
457 while (!OPERATIONAL_LISTENER.isUpdated(
458 iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) {
459 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
461 LOG.info("Woke up, waited {} for update of {}", (System.currentTimeMillis() - _start), iid);
465 private void disconnectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
466 final InstanceIdentifier<Node> iid = createInstanceIdentifier(connectionInfo);
467 Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
468 waitForOperationalDeletion(iid);
469 Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid);
470 Assert.assertNull(node);
471 LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
475 public void testAddDeleteOvsdbNode() throws InterruptedException {
476 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
477 connectOvsdbNode(connectionInfo);
478 disconnectOvsdbNode(connectionInfo);
482 public void testDpdkSwitch() throws InterruptedException {
483 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
484 Node ovsdbNode = connectOvsdbNode(connectionInfo);
485 List<DatapathTypeEntry> datapathTypeEntries = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class)
486 .getDatapathTypeEntry();
487 if (datapathTypeEntries == null) {
488 LOG.info("DPDK not supported on this node.");
490 for (DatapathTypeEntry dpTypeEntry : datapathTypeEntries) {
491 Class<? extends DatapathTypeBase> dpType = dpTypeEntry.getDatapathType();
492 String dpTypeStr = SouthboundConstants.DATAPATH_TYPE_MAP.get(dpType);
493 LOG.info("dp type is {}", dpTypeStr);
494 if (dpTypeStr.equals(NETDEV_DP_TYPE)) {
495 LOG.info("Found a DPDK node; adding a corresponding netdev device");
496 InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(connectionInfo,
497 new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME));
498 NodeId bridgeNodeId = createManagedNodeId(bridgeIid);
499 addBridge(connectionInfo, bridgeIid, SouthboundITConstants.BRIDGE_NAME, bridgeNodeId, false, null,
500 true, dpType, null, null, null);
502 // Verify that the device is netdev
503 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
504 Assert.assertNotNull(bridge);
505 Assert.assertEquals(dpType, bridge.getDatapathType());
507 // Add port for all dpdk interface types (dpdkvhost not supported in existing dpdk ovs)
508 List<String> dpdkTypes = new ArrayList<String>();
509 dpdkTypes.add("dpdk");
510 dpdkTypes.add("dpdkr");
511 dpdkTypes.add("dpdkvhostuser");
512 //dpdkTypes.add("dpdkvhost");
514 for (String dpdkType : dpdkTypes) {
515 String testPortname = "test"+dpdkType+"port";
516 LOG.info("DPDK portname and type is {}, {}", testPortname, dpdkType);
517 Class<? extends InterfaceTypeBase> dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
519 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationpointBuilder =
520 createSpecificDpdkOvsdbTerminationPointAugmentationBuilder(testPortname, dpdkIfType);
521 Assert.assertTrue(addTerminationPoint(bridgeNodeId, testPortname , ovsdbTerminationpointBuilder));
524 // Verify that all DPDK ports are created
525 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
526 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
527 terminationPointIid);
528 Assert.assertNotNull(terminationPointNode);
530 // Verify that each termination point has the specific DPDK ifType
531 for (String dpdkType : dpdkTypes) {
532 String testPortname = "test"+dpdkType+"port";
533 Class<? extends InterfaceTypeBase> dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
535 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
536 for (TerminationPoint terminationPoint : terminationPoints) {
537 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = terminationPoint
538 .getAugmentation(OvsdbTerminationPointAugmentation.class);
539 if (ovsdbTerminationPointAugmentation.getName().equals(testPortname)) {
540 Class<? extends InterfaceTypeBase> opPort = ovsdbTerminationPointAugmentation
542 Assert.assertEquals(dpdkIfType, opPort);
547 Assert.assertTrue(deleteBridge(connectionInfo));
551 disconnectOvsdbNode(connectionInfo);
555 public void testOvsdbNodeOvsVersion() throws InterruptedException {
556 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
557 Node ovsdbNode = connectOvsdbNode(connectionInfo);
558 OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
559 Assert.assertNotNull(ovsdbNodeAugmentation);
560 assertNotNull(ovsdbNodeAugmentation.getOvsVersion());
561 disconnectOvsdbNode(connectionInfo);
565 public void testOpenVSwitchOtherConfig() throws InterruptedException {
566 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
567 Node ovsdbNode = connectOvsdbNode(connectionInfo);
568 OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
569 Assert.assertNotNull(ovsdbNodeAugmentation);
570 List<OpenvswitchOtherConfigs> otherConfigsList = ovsdbNodeAugmentation.getOpenvswitchOtherConfigs();
571 if (otherConfigsList != null) {
572 for (OpenvswitchOtherConfigs otherConfig : otherConfigsList) {
573 if (otherConfig.getOtherConfigKey().equals("local_ip")) {
574 LOG.info("local_ip: {}", otherConfig.getOtherConfigValue());
577 LOG.info("other_config {}:{}", otherConfig.getOtherConfigKey(), otherConfig.getOtherConfigValue());
581 LOG.info("other_config is not present");
583 disconnectOvsdbNode(connectionInfo);
587 public void testOvsdbBridgeControllerInfo() throws InterruptedException {
588 ConnectionInfo connectionInfo = getConnectionInfo(addressStr,portNumber);
589 Node ovsdbNode = connectOvsdbNode(connectionInfo);
590 String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
591 assertNotNull("Failed to get controller target", controllerTarget);
592 List<ControllerEntry> setControllerEntry = createControllerEntry(controllerTarget);
593 Uri setUri = new Uri(controllerTarget);
594 Assert.assertTrue(addBridge(connectionInfo, null, SouthboundITConstants.BRIDGE_NAME,null, true,
595 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null,
596 setControllerEntry, null));
597 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
598 Assert.assertNotNull("bridge was not found: " + SouthboundITConstants.BRIDGE_NAME, bridge);
599 Assert.assertNotNull("ControllerEntry was not found: " + setControllerEntry.iterator().next(),
600 bridge.getControllerEntry());
601 List<ControllerEntry> getControllerEntries = bridge.getControllerEntry();
602 for (ControllerEntry entry : getControllerEntries) {
603 if (entry.getTarget() != null) {
604 Assert.assertEquals(setUri.toString(), entry.getTarget().toString());
608 Assert.assertTrue(deleteBridge(connectionInfo));
609 disconnectOvsdbNode(connectionInfo);
612 private List<ControllerEntry> createControllerEntry(String controllerTarget) {
613 List<ControllerEntry> controllerEntriesList = new ArrayList<>();
614 controllerEntriesList.add(new ControllerEntryBuilder()
615 .setTarget(new Uri(controllerTarget))
617 return controllerEntriesList;
620 private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
621 final ConnectionInfo connectionInfo) {
622 InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(connectionInfo);
623 ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
626 private List<ProtocolEntry> createMdsalProtocols() {
627 List<ProtocolEntry> protocolList = new ArrayList<>();
628 ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
629 SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
630 protocolList.add(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build());
634 private OvsdbTerminationPointAugmentationBuilder createGenericOvsdbTerminationPointAugmentationBuilder() {
635 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder =
636 new OvsdbTerminationPointAugmentationBuilder();
637 ovsdbTerminationPointAugmentationBuilder.setInterfaceType(
638 new InterfaceTypeEntryBuilder()
640 SouthboundMapper.createInterfaceType("internal"))
641 .build().getInterfaceType());
642 return ovsdbTerminationPointAugmentationBuilder;
645 private OvsdbTerminationPointAugmentationBuilder createGenericDpdkOvsdbTerminationPointAugmentationBuilder(
646 final String portName) {
647 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
648 createGenericOvsdbTerminationPointAugmentationBuilder();
649 ovsdbTerminationBuilder.setName(portName);
650 Class<? extends InterfaceTypeBase> ifType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
652 ovsdbTerminationBuilder.setInterfaceType(ifType);
653 return ovsdbTerminationBuilder;
656 private OvsdbTerminationPointAugmentationBuilder createSpecificDpdkOvsdbTerminationPointAugmentationBuilder(
657 String testPortname,Class<? extends InterfaceTypeBase> dpdkIfType) {
658 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
659 createGenericOvsdbTerminationPointAugmentationBuilder();
660 ovsdbTerminationBuilder.setName(testPortname);
661 ovsdbTerminationBuilder.setInterfaceType(dpdkIfType);
662 return ovsdbTerminationBuilder;
665 private boolean addTerminationPoint(final NodeId bridgeNodeId, final String portName,
666 final OvsdbTerminationPointAugmentationBuilder
667 ovsdbTerminationPointAugmentationBuilder)
668 throws InterruptedException {
670 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(bridgeNodeId);
671 NodeBuilder portNodeBuilder = new NodeBuilder();
672 NodeId portNodeId = SouthboundMapper.createManagedNodeId(portIid);
673 portNodeBuilder.setNodeId(portNodeId);
674 TerminationPointBuilder entry = new TerminationPointBuilder();
675 entry.setKey(new TerminationPointKey(new TpId(portName)));
676 entry.addAugmentation(
677 OvsdbTerminationPointAugmentation.class,
678 ovsdbTerminationPointAugmentationBuilder.build());
679 portNodeBuilder.setTerminationPoint(Lists.newArrayList(entry.build()));
680 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
681 portIid, portNodeBuilder.build());
682 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
687 * base method for adding test bridges. Other helper methods used to create bridges should utilize this method.
689 * @param connectionInfo
690 * @param bridgeIid if passed null, one is created
691 * @param bridgeName cannot be null
692 * @param bridgeNodeId if passed null, one is created based on <code>bridgeIid</code>
693 * @param setProtocolEntries toggles whether default protocol entries are set for the bridge
694 * @param failMode toggles whether default fail mode is set for the bridge
695 * @param setManagedBy toggles whether to setManagedBy for the bridge
696 * @param dpType if passed null, this parameter is ignored
697 * @param externalIds if passed null, this parameter is ignored
698 * @param otherConfigs if passed null, this parameter is ignored
699 * @return success of bridge addition
700 * @throws InterruptedException
702 private boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
703 final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
704 final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
705 final Class<? extends DatapathTypeBase> dpType,
706 final List<BridgeExternalIds> externalIds,
707 final List<ControllerEntry> controllerEntries,
708 final List<BridgeOtherConfigs> otherConfigs) throws InterruptedException {
710 NodeBuilder bridgeNodeBuilder = new NodeBuilder();
711 if (bridgeIid == null) {
712 bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
714 if (bridgeNodeId == null) {
715 bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
717 bridgeNodeBuilder.setNodeId(bridgeNodeId);
718 OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
719 ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
720 if (setProtocolEntries) {
721 ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
723 if (failMode != null) {
724 ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
727 setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
729 if (dpType != null) {
730 ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
732 if (externalIds != null) {
733 ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
735 if (controllerEntries != null) {
736 ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries);
738 if (otherConfigs != null) {
739 ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
741 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
742 LOG.debug("Built with the intent to store bridge data {}", ovsdbBridgeAugmentationBuilder.toString());
743 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
744 bridgeIid, bridgeNodeBuilder.build());
745 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
749 private boolean addBridge(final ConnectionInfo connectionInfo, final String bridgeName)
750 throws InterruptedException {
752 return addBridge(connectionInfo, null, bridgeName, null, true,
753 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null);
756 private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo) {
757 return getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
761 * Extract the <code>store</code> type data store contents for the particular bridge identified by
762 * <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 * @return <code>store</code> type data store contents
769 private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
770 LogicalDatastoreType store) {
771 Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
772 Assert.assertNotNull(bridgeNode);
773 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
774 Assert.assertNotNull(ovsdbBridgeAugmentation);
775 return ovsdbBridgeAugmentation;
779 * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
780 * identified by <code>bridgeName</code>
782 * @param connectionInfo the connection information
783 * @param bridgeName the bridge name
784 * @see <code>SouthboundIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
785 * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
787 private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
788 return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
792 * Extract the node contents from <code>store</code> type data store for the
793 * bridge identified by <code>bridgeName</code>
795 * @param connectionInfo the connection information
796 * @param bridgeName the bridge name
797 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
798 * @return <code>store</code> type data store contents
800 private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
801 InstanceIdentifier<Node> bridgeIid =
802 createInstanceIdentifier(connectionInfo,
803 new OvsdbBridgeName(bridgeName));
804 return mdsalUtils.read(store, bridgeIid);
808 * Extract the node contents from <code>LogicalDataStoreType.OPERATIONAL</code> data store for the
809 * bridge identified by <code>bridgeName</code>
811 * @param connectionInfo the connection information
812 * @param bridgeName the bridge name
813 * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
815 private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName) {
816 return getBridgeNode(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
819 private boolean deleteBridge(ConnectionInfo connectionInfo) throws InterruptedException {
820 return deleteBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
823 private boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName)
824 throws InterruptedException {
826 final InstanceIdentifier<Node> iid = createInstanceIdentifier(connectionInfo,
827 new OvsdbBridgeName(bridgeName));
828 boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid);
829 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
834 public void testAddDeleteBridge() throws InterruptedException {
835 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
836 connectOvsdbNode(connectionInfo);
838 Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
839 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
840 Assert.assertNotNull(bridge);
841 LOG.info("bridge: {}", bridge);
843 Assert.assertTrue(deleteBridge(connectionInfo));
845 disconnectOvsdbNode(connectionInfo);
848 private InstanceIdentifier<Node> getTpIid(ConnectionInfo connectionInfo, OvsdbBridgeAugmentation bridge) {
849 return createInstanceIdentifier(connectionInfo,
850 bridge.getBridgeName());
854 * Extracts the <code>TerminationPointAugmentation</code> for the <code>index</code> <code>TerminationPoint</code>
855 * on <code>bridgeName</code>
857 * @param connectionInfo the connection information
858 * @param bridgeName the bridge name
859 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
860 * @param index the index we're interested in
861 * @return the augmentation (or {@code null} if none)
863 private OvsdbTerminationPointAugmentation getOvsdbTerminationPointAugmentation(
864 ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store, int index) {
866 List<TerminationPoint> tpList = getBridgeNode(connectionInfo, bridgeName, store).getTerminationPoint();
867 if (tpList == null) {
870 return tpList.get(index).getAugmentation(OvsdbTerminationPointAugmentation.class);
874 public void testCRDTerminationPointOfPort() throws InterruptedException {
875 final Long OFPORT_EXPECTED = 45002L;
877 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
878 connectOvsdbNode(connectionInfo);
881 Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
882 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
883 Assert.assertNotNull(bridge);
884 LOG.info("bridge: {}", bridge);
885 NodeId nodeId = SouthboundMapper.createManagedNodeId(createInstanceIdentifier(
886 connectionInfo, bridge.getBridgeName()));
887 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
888 createGenericOvsdbTerminationPointAugmentationBuilder();
889 String portName = "testOfPort";
890 ovsdbTerminationBuilder.setName(portName);
892 ovsdbTerminationBuilder.setOfport(OFPORT_EXPECTED);
893 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
894 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
895 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
896 Assert.assertNotNull(terminationPointNode);
899 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
900 for (TerminationPoint terminationPoint : terminationPoints) {
901 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
902 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
903 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
904 Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
905 // if ephemeral port 45002 is in use, ofPort is set to 1
906 Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(new Long(1)));
907 LOG.info("ofPort: {}", ofPort);
911 // UPDATE- Not Applicable. From the OpenVSwitch Documentation:
912 // "A client should ideally set this column’s value in the same database transaction that it uses to create
916 Assert.assertTrue(deleteBridge(connectionInfo));
917 disconnectOvsdbNode(connectionInfo);
921 public void testCRDTerminationPointOfPortRequest() throws InterruptedException {
922 final Long OFPORT_EXPECTED = 45008L;
923 final Long OFPORT_INPUT = 45008L;
925 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
926 connectOvsdbNode(connectionInfo);
929 Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
930 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
931 Assert.assertNotNull(bridge);
932 NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
933 connectionInfo, bridge.getBridgeName()));
934 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
935 createGenericOvsdbTerminationPointAugmentationBuilder();
936 String portName = "testOfPortRequest";
937 ovsdbTerminationBuilder.setName(portName);
938 Integer ofPortRequestExpected = OFPORT_EXPECTED.intValue();
939 ovsdbTerminationBuilder.setOfport(OFPORT_INPUT);
940 ovsdbTerminationBuilder.setOfportRequest(ofPortRequestExpected);
941 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
942 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
943 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
944 Assert.assertNotNull(terminationPointNode);
947 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
948 for (TerminationPoint terminationPoint : terminationPoints) {
949 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
950 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
951 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
952 Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
953 // if ephemeral port 45008 is in use, ofPort is set to 1
954 Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(new Long(1)));
955 LOG.info("ofPort: {}", ofPort);
957 Integer ofPortRequest = ovsdbTerminationPointAugmentation.getOfportRequest();
958 Assert.assertTrue(ofPortRequest.equals(ofPortRequestExpected));
959 LOG.info("ofPortRequest: {}", ofPortRequest);
963 // UPDATE- Not Applicable. From the OpenVSwitch documentation:
964 // "A client should ideally set this column’s value in the same database transaction that it uses to create
968 Assert.assertTrue(deleteBridge(connectionInfo));
969 disconnectOvsdbNode(connectionInfo);
972 private <T> void assertExpectedExist(List<T> expected, List<T> test) {
973 if (expected != null && test != null) {
974 for (T exp : expected) {
975 Assert.assertTrue("The retrieved values don't contain " + exp, test.contains(exp));
980 private interface SouthboundTerminationPointHelper<T> {
981 void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List<T> values);
982 List<T> readValues(OvsdbTerminationPointAugmentation augmentation);
986 * Tests the CRUD operations for <code>Port</code> <code>external_ids</code>.
988 * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
990 private <T> void testCRUDTerminationPoint(
991 KeyValueBuilder<T> builder, String prefix, SouthboundTerminationPointHelper<T> helper)
992 throws InterruptedException {
993 final int TERMINATION_POINT_TEST_INDEX = 0;
995 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
996 connectOvsdbNode(connectionInfo);
998 // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
999 // the update has been performed.
1000 List<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
1001 List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
1003 for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
1004 for (SouthboundTestCase<T> updateToTestCase : updateToTestCases) {
1005 String testBridgeAndPortName = String.format("%s_%s", prefix, updateToTestCase.name);
1007 // CREATE: Create the test bridge
1008 Assert.assertTrue(addBridge(connectionInfo, null, testBridgeAndPortName, null, true,
1009 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null));
1010 NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
1011 connectionInfo, new OvsdbBridgeName(testBridgeAndPortName)));
1012 OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
1013 createGenericOvsdbTerminationPointAugmentationBuilder();
1014 tpCreateAugmentationBuilder.setName(testBridgeAndPortName);
1015 helper.writeValues(tpCreateAugmentationBuilder, updateFromTestCase.inputValues);
1017 addTerminationPoint(testBridgeNodeId, testBridgeAndPortName, tpCreateAugmentationBuilder));
1019 // READ: Read the test port and ensure changes are propagated to the CONFIGURATION data store,
1020 // then repeat for OPERATIONAL data store
1021 OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
1022 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1023 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1024 if (updateFromConfigurationTerminationPointAugmentation != null) {
1025 List<T> updateFromConfigurationValues =
1026 helper.readValues(updateFromConfigurationTerminationPointAugmentation);
1027 assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationValues);
1029 OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation =
1030 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1031 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1032 if (updateFromOperationalTerminationPointAugmentation != null) {
1033 List<T> updateFromOperationalValues =
1034 helper.readValues(updateFromOperationalTerminationPointAugmentation);
1035 assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalValues);
1038 // UPDATE: update the values
1039 testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeAndPortName).getNodeId();
1040 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1041 new OvsdbTerminationPointAugmentationBuilder();
1042 helper.writeValues(tpUpdateAugmentationBuilder, updateToTestCase.inputValues);
1043 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1044 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1045 NodeId portUpdateNodeId = createManagedNodeId(portIid);
1046 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1047 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1048 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testBridgeAndPortName)));
1049 tpUpdateBuilder.addAugmentation(
1050 OvsdbTerminationPointAugmentation.class,
1051 tpUpdateAugmentationBuilder.build());
1052 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1053 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1054 portIid, portUpdateNodeBuilder.build()));
1055 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1057 // READ: the test port and ensure changes are propagated to the CONFIGURATION data store,
1058 // then repeat for OPERATIONAL data store
1059 OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
1060 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1061 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1062 if (updateToConfigurationTerminationPointAugmentation != null) {
1063 List<T> updateToConfigurationValues =
1064 helper.readValues(updateToConfigurationTerminationPointAugmentation);
1065 assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationValues);
1066 assertExpectedExist(updateFromTestCase.expectedValues, updateToConfigurationValues);
1068 OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
1069 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1070 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1071 if (updateToOperationalTerminationPointAugmentation != null) {
1072 List<T> updateToOperationalValues =
1073 helper.readValues(updateToOperationalTerminationPointAugmentation);
1074 if (updateFromTestCase.expectedValues != null ) {
1075 assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalValues);
1076 assertExpectedExist(updateFromTestCase.expectedValues, updateToOperationalValues);
1081 Assert.assertTrue(deleteBridge(connectionInfo, testBridgeAndPortName));
1084 disconnectOvsdbNode(connectionInfo);
1088 * Tests the CRUD operations for <code>Port</code> <code>external_ids</code>.
1090 * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
1093 public void testCRUDTerminationPointPortExternalIds() throws InterruptedException {
1094 testCRUDTerminationPoint(new SouthboundPortExternalIdsBuilder(), "TPPortExternalIds",
1095 new PortExternalIdsSouthboundHelper());
1099 * Tests the CRUD operations for <code>Interface</code> <code>external_ids</code>.
1101 * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1104 public void testCRUDTerminationPointInterfaceExternalIds() throws InterruptedException {
1105 testCRUDTerminationPoint(new SouthboundInterfaceExternalIdsBuilder(), "TPInterfaceExternalIds",
1106 new InterfaceExternalIdsSouthboundHelper());
1110 * Tests the CRUD operations for <code>TerminationPoint</code> <code>options</code>.
1112 * @see <code>SouthboundIT.generateTerminationPointOptions()</code> for specific test case information
1115 public void testCRUDTerminationPointOptions() throws InterruptedException {
1116 testCRUDTerminationPoint(new SouthboundOptionsBuilder(), "TPOptions", new OptionsSouthboundHelper());
1120 * Tests the CRUD operations for <code>Interface</code> <code>other_configs</code>.
1122 * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1125 public void testCRUDTerminationPointInterfaceOtherConfigs() throws InterruptedException {
1126 testCRUDTerminationPoint(new SouthboundInterfaceOtherConfigsBuilder(), "TPInterfaceOtherConfigs",
1127 new InterfaceOtherConfigsSouthboundHelper());
1131 * Tests the CRUD operations for <code>Port</code> <code>other_configs</code>.
1133 * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
1136 public void testCRUDTerminationPointPortOtherConfigs() throws InterruptedException {
1137 testCRUDTerminationPoint(new SouthboundPortOtherConfigsBuilder(), "TPPortOtherConfigs",
1138 new PortOtherConfigsSouthboundHelper());
1142 public void testCRUDTerminationPointVlan() throws InterruptedException {
1143 final Integer CREATED_VLAN_ID = 4000;
1144 final Integer UPDATED_VLAN_ID = 4001;
1146 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1147 connectOvsdbNode(connectionInfo);
1150 Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
1151 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1152 Assert.assertNotNull(bridge);
1153 NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
1154 connectionInfo, bridge.getBridgeName()));
1155 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1156 createGenericOvsdbTerminationPointAugmentationBuilder();
1157 String portName = "testTerminationPointVlanId";
1158 ovsdbTerminationBuilder.setName(portName);
1159 ovsdbTerminationBuilder.setVlanTag(new VlanId(CREATED_VLAN_ID));
1160 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1161 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1162 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1163 Assert.assertNotNull(terminationPointNode);
1166 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1167 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation;
1168 for (TerminationPoint terminationPoint : terminationPoints) {
1169 ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
1170 OvsdbTerminationPointAugmentation.class);
1171 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1172 VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
1173 Assert.assertNotNull(actualVlanId);
1174 Integer actualVlanIdInt = actualVlanId.getValue();
1175 Assert.assertEquals(CREATED_VLAN_ID, actualVlanIdInt);
1180 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1181 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1182 new OvsdbTerminationPointAugmentationBuilder();
1183 tpUpdateAugmentationBuilder.setVlanTag(new VlanId(UPDATED_VLAN_ID));
1184 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1185 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1186 NodeId portUpdateNodeId = createManagedNodeId(portIid);
1187 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1188 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1189 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1190 tpUpdateBuilder.addAugmentation(
1191 OvsdbTerminationPointAugmentation.class,
1192 tpUpdateAugmentationBuilder.build());
1193 tpUpdateBuilder.setTpId(new TpId(portName));
1194 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1195 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
1196 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1198 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1199 terminationPoints = terminationPointNode.getTerminationPoint();
1200 for (TerminationPoint terminationPoint : terminationPoints) {
1201 ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
1202 OvsdbTerminationPointAugmentation.class);
1203 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1204 VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
1205 Assert.assertNotNull(actualVlanId);
1206 Integer actualVlanIdInt = actualVlanId.getValue();
1207 Assert.assertEquals(UPDATED_VLAN_ID, actualVlanIdInt);
1212 Assert.assertTrue(deleteBridge(connectionInfo));
1213 disconnectOvsdbNode(connectionInfo);
1217 public void testCRUDTerminationPointVlanModes() throws InterruptedException {
1218 final VlanMode UPDATED_VLAN_MODE = VlanMode.Access;
1219 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1220 connectOvsdbNode(connectionInfo);
1221 VlanMode []vlanModes = VlanMode.values();
1222 for (VlanMode vlanMode : vlanModes) {
1224 Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
1225 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1226 Assert.assertNotNull(bridge);
1227 NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
1228 connectionInfo, bridge.getBridgeName()));
1229 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1230 createGenericOvsdbTerminationPointAugmentationBuilder();
1231 String portName = "testTerminationPointVlanMode" + vlanMode.toString();
1232 ovsdbTerminationBuilder.setName(portName);
1233 ovsdbTerminationBuilder.setVlanMode(vlanMode);
1234 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1235 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1236 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1237 Assert.assertNotNull(terminationPointNode);
1240 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1241 for (TerminationPoint terminationPoint : terminationPoints) {
1242 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1243 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1244 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1246 Assert.assertTrue(ovsdbTerminationPointAugmentation.getVlanMode().equals(vlanMode));
1251 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1252 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1253 new OvsdbTerminationPointAugmentationBuilder();
1254 tpUpdateAugmentationBuilder.setVlanMode(UPDATED_VLAN_MODE);
1255 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1256 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1257 NodeId portUpdateNodeId = createManagedNodeId(portIid);
1258 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1259 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1260 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1261 tpUpdateBuilder.addAugmentation(
1262 OvsdbTerminationPointAugmentation.class,
1263 tpUpdateAugmentationBuilder.build());
1264 tpUpdateBuilder.setTpId(new TpId(portName));
1265 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1267 mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
1268 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1270 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1271 terminationPoints = terminationPointNode.getTerminationPoint();
1272 for (TerminationPoint terminationPoint : terminationPoints) {
1273 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1274 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1275 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1277 Assert.assertEquals(UPDATED_VLAN_MODE, ovsdbTerminationPointAugmentation.getVlanMode());
1282 Assert.assertTrue(deleteBridge(connectionInfo));
1284 disconnectOvsdbNode(connectionInfo);
1287 @SuppressWarnings("unchecked")
1288 private List<Set<Integer>> generateVlanSets() {
1291 return Lists.newArrayList(
1292 Collections.<Integer>emptySet(),
1293 Sets.newHashSet(2222),
1294 Sets.newHashSet(min, max, min + 1, max - 1, (max - min) / 2));
1297 private List<Trunks> buildTrunkList(Set<Integer> trunkSet) {
1298 List<Trunks> trunkList = Lists.newArrayList();
1299 for (Integer trunk : trunkSet) {
1300 TrunksBuilder trunkBuilder = new TrunksBuilder();
1301 trunkBuilder.setTrunk(new VlanId(trunk));
1302 trunkList.add(trunkBuilder.build());
1308 public void testCRUDTerminationPointVlanTrunks() throws InterruptedException {
1309 final List<Trunks> UPDATED_TRUNKS = buildTrunkList(Sets.newHashSet(2011));
1310 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1311 connectOvsdbNode(connectionInfo);
1312 Iterable<Set<Integer>> vlanSets = generateVlanSets();
1314 for (Set<Integer> vlanSet : vlanSets) {
1317 Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
1318 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1319 Assert.assertNotNull(bridge);
1320 NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
1321 connectionInfo, bridge.getBridgeName()));
1322 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1323 createGenericOvsdbTerminationPointAugmentationBuilder();
1324 String portName = "testTerminationPointVlanTrunks" + testCase;
1325 ovsdbTerminationBuilder.setName(portName);
1326 List<Trunks> trunks = buildTrunkList(vlanSet);
1327 ovsdbTerminationBuilder.setTrunks(trunks);
1328 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1329 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1330 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1331 Assert.assertNotNull(terminationPointNode);
1334 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1335 for (TerminationPoint terminationPoint : terminationPoints) {
1336 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1337 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1338 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1339 List<Trunks> actualTrunks = ovsdbTerminationPointAugmentation.getTrunks();
1340 for (Trunks trunk : trunks) {
1341 Assert.assertTrue(actualTrunks.contains(trunk));
1348 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1349 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1350 new OvsdbTerminationPointAugmentationBuilder();
1351 tpUpdateAugmentationBuilder.setTrunks(UPDATED_TRUNKS);
1352 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1353 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1354 NodeId portUpdateNodeId = createManagedNodeId(portIid);
1355 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1356 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1357 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1358 tpUpdateBuilder.addAugmentation(
1359 OvsdbTerminationPointAugmentation.class,
1360 tpUpdateAugmentationBuilder.build());
1361 tpUpdateBuilder.setTpId(new TpId(portName));
1362 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1364 mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
1365 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1367 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1368 terminationPoints = terminationPointNode.getTerminationPoint();
1369 for (TerminationPoint terminationPoint : terminationPoints) {
1370 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1371 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1372 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1374 Assert.assertEquals(UPDATED_TRUNKS, ovsdbTerminationPointAugmentation.getTrunks());
1379 Assert.assertTrue(deleteBridge(connectionInfo));
1381 disconnectOvsdbNode(connectionInfo);
1385 public void testGetOvsdbNodes() throws InterruptedException {
1386 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1387 connectOvsdbNode(connectionInfo);
1388 InstanceIdentifier<Topology> topologyPath = InstanceIdentifier
1389 .create(NetworkTopology.class)
1390 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
1392 Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, topologyPath);
1393 InstanceIdentifier<Node> expectedNodeIid = createInstanceIdentifier(connectionInfo);
1394 NodeId expectedNodeId = expectedNodeIid.firstKeyOf(Node.class, NodeKey.class).getNodeId();
1395 Node foundNode = null;
1396 Assert.assertNotNull("Expected to find topology: " + topologyPath, topology);
1397 Assert.assertNotNull("Expected to find some nodes" + topology.getNode());
1398 LOG.info("expectedNodeId: {}, getNode: {}", expectedNodeId, topology.getNode());
1399 for (Node node : topology.getNode()) {
1400 if (node.getNodeId().getValue().equals(expectedNodeId.getValue())) {
1405 Assert.assertNotNull("Expected to find Node: " + expectedNodeId, foundNode);
1406 disconnectOvsdbNode(connectionInfo);
1410 * @see <code>SouthboundIT.generateBridgeOtherConfigsTestCases()</code> for specific test case information.
1413 public void testCRUDBridgeOtherConfigs() throws InterruptedException {
1414 testCRUDBridge("BridgeOtherConfigs", new SouthboundBridgeOtherConfigsBuilder(),
1415 new BridgeOtherConfigsSouthboundHelper());
1418 private interface SouthboundBridgeHelper<T> {
1419 void writeValues(OvsdbBridgeAugmentationBuilder builder, List<T> values);
1420 List<T> readValues(OvsdbBridgeAugmentation augmentation);
1423 private <T> void testCRUDBridge(String prefix, KeyValueBuilder<T> builder, SouthboundBridgeHelper<T> helper)
1424 throws InterruptedException {
1425 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1426 connectOvsdbNode(connectionInfo);
1427 // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
1428 // the update has been performed.
1429 List<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
1430 List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
1431 for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
1432 for (SouthboundTestCase<T> updateToTestCase : updateToTestCases) {
1433 String testBridgeName = String.format("%s_%s", prefix, updateToTestCase.name);
1435 // CREATE: Create the test bridge
1436 final OvsdbBridgeName ovsdbBridgeName = new OvsdbBridgeName(testBridgeName);
1437 final InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(connectionInfo, ovsdbBridgeName);
1438 final NodeId bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
1439 final NodeBuilder bridgeCreateNodeBuilder = new NodeBuilder();
1440 bridgeCreateNodeBuilder.setNodeId(bridgeNodeId);
1441 OvsdbBridgeAugmentationBuilder bridgeCreateAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
1442 bridgeCreateAugmentationBuilder.setBridgeName(ovsdbBridgeName);
1443 bridgeCreateAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
1444 bridgeCreateAugmentationBuilder.setFailMode(
1445 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"));
1446 setManagedBy(bridgeCreateAugmentationBuilder, connectionInfo);
1447 helper.writeValues(bridgeCreateAugmentationBuilder, updateFromTestCase.inputValues);
1448 bridgeCreateNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class,
1449 bridgeCreateAugmentationBuilder.build());
1450 LOG.debug("Built with the intent to store bridge data {}", bridgeCreateAugmentationBuilder.toString());
1451 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
1452 bridgeCreateNodeBuilder.build()));
1453 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1455 // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
1456 // then repeat for OPERATIONAL data store
1457 List<T> updateFromConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName,
1458 LogicalDatastoreType.CONFIGURATION));
1459 assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationExternalIds);
1460 List<T> updateFromOperationalExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName));
1461 assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalExternalIds);
1463 // UPDATE: update the values
1464 final OvsdbBridgeAugmentationBuilder bridgeUpdateAugmentationBuilder =
1465 new OvsdbBridgeAugmentationBuilder();
1466 helper.writeValues(bridgeUpdateAugmentationBuilder, updateToTestCase.inputValues);
1467 final NodeBuilder bridgeUpdateNodeBuilder = new NodeBuilder();
1468 final Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
1469 bridgeUpdateNodeBuilder.setNodeId(bridgeNode.getNodeId());
1470 bridgeUpdateNodeBuilder.setKey(bridgeNode.getKey());
1471 bridgeUpdateNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class,
1472 bridgeUpdateAugmentationBuilder.build());
1473 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
1474 bridgeUpdateNodeBuilder.build()));
1475 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1477 // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
1478 // then repeat for OPERATIONAL data store
1479 List<T> updateToConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName,
1480 LogicalDatastoreType.CONFIGURATION));
1481 assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationExternalIds);
1482 assertExpectedExist(updateFromTestCase.expectedValues, updateToConfigurationExternalIds);
1483 List<T> updateToOperationalExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName));
1484 if (updateFromTestCase.expectedValues != null) {
1485 assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalExternalIds);
1486 assertExpectedExist(updateFromTestCase.expectedValues, updateToOperationalExternalIds);
1490 Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
1493 disconnectOvsdbNode(connectionInfo);
1497 * @see <code>SouthboundIT.generateBridgeExternalIdsTestCases()</code> for specific test case information
1500 public void testCRUDBridgeExternalIds() throws InterruptedException {
1501 testCRUDBridge("BridgeExternalIds", new SouthboundBridgeExternalIdsBuilder(),
1502 new BridgeExternalIdsSouthboundHelper());
1505 public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key,OvsdbBridgeName bridgeName) {
1506 return SouthboundMapper.createInstanceIdentifier(createManagedNodeId(key, bridgeName));
1509 public static NodeId createManagedNodeId(ConnectionInfo key, OvsdbBridgeName bridgeName) {
1510 return createManagedNodeId(key.getRemoteIp(), key.getRemotePort(), bridgeName);
1513 public static NodeId createManagedNodeId(IpAddress ip, PortNumber port, OvsdbBridgeName bridgeName) {
1514 return new NodeId(createNodeId(ip,port).getValue()
1515 + "/" + SouthboundConstants.BRIDGE_URI_PREFIX + "/" + bridgeName.getValue());
1518 public static NodeId createNodeId(IpAddress ip, PortNumber port) {
1519 String uriString = SouthboundConstants.OVSDB_URI_PREFIX + "://"
1520 + new String(ip.getValue()) + ":" + port.getValue();
1521 Uri uri = new Uri(uriString);
1522 return new NodeId(uri);
1525 public static NodeKey createNodeKey(IpAddress ip, PortNumber port) {
1526 return new NodeKey(createNodeId(ip,port));
1529 public static Node createNode(ConnectionInfo key) {
1530 NodeBuilder nodeBuilder = new NodeBuilder();
1531 nodeBuilder.setNodeId(createNodeId(key.getRemoteIp(),key.getRemotePort()));
1532 nodeBuilder.addAugmentation(OvsdbNodeAugmentation.class, createOvsdbAugmentation(key));
1533 return nodeBuilder.build();
1536 public static OvsdbNodeAugmentation createOvsdbAugmentation(ConnectionInfo key) {
1537 OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = new OvsdbNodeAugmentationBuilder();
1538 ovsdbNodeBuilder.setConnectionInfo(key);
1539 return ovsdbNodeBuilder.build();
1542 public static NodeId createManagedNodeId(InstanceIdentifier<Node> iid) {
1543 NodeKey nodeKey = iid.firstKeyOf(Node.class, NodeKey.class);
1544 return nodeKey.getNodeId();
1549 * Representation of a southbound test case. Each test case has a name, a list of input values and a list of
1550 * expected values. The input values are provided to the augmentation builder, and the expected values are checked
1551 * against the output of the resulting augmentation.
1554 * Instances of this class are immutable.
1557 * @param <T> The type of data used for the test case.
1559 private static final class SouthboundTestCase<T> {
1560 private final String name;
1561 private final List<T> inputValues;
1562 private final List<T> expectedValues;
1565 * Creates an instance of a southbound test case.
1567 * @param name The test case's name.
1568 * @param inputValues The input values (provided as input to the underlying augmentation builder).
1569 * @param expectedValues The expected values (checked against the output of the underlying augmentation).
1571 public SouthboundTestCase(
1572 final String name, final List<T> inputValues, final List<T> expectedValues) {
1574 this.inputValues = inputValues;
1575 this.expectedValues = expectedValues;
1580 * Southbound test case builder.
1582 * @param <T> The type of data used for the test case.
1584 private static final class SouthboundTestCaseBuilder<T> {
1585 private String name;
1586 private List<T> inputValues;
1587 private List<T> expectedValues;
1590 * Creates a builder. Builders may be reused, the generated immutable instances are independent of the
1591 * builders. There are no default values.
1593 public SouthboundTestCaseBuilder() {
1598 * Sets the test case's name.
1600 * @param name The test case's name.
1601 * @return The builder.
1603 public SouthboundTestCaseBuilder<T> name(final String name) {
1609 * Sets the input values.
1611 * @param inputValues The input values.
1612 * @return The builder.
1615 public final SouthboundTestCaseBuilder<T> input(final T... inputValues) {
1616 this.inputValues = Lists.newArrayList(inputValues);
1621 * Indicates that the provided input values should be expected as output values.
1623 * @return The builder.
1625 public SouthboundTestCaseBuilder<T> expectInputAsOutput() {
1626 this.expectedValues = this.inputValues;
1631 * Indicates that no output should be expected.
1633 * @return The builder.
1635 public SouthboundTestCaseBuilder<T> expectNoOutput() {
1636 this.expectedValues = null;
1641 * Builds an immutable instance representing the test case.
1643 * @return The test case.
1645 @SuppressWarnings("unchecked")
1646 public SouthboundTestCase<T> build() {
1647 return new SouthboundTestCase<>(name, inputValues, expectedValues);
1651 private abstract static class KeyValueBuilder<T> {
1652 private static final int COUNTER_START = 0;
1653 private int counter = COUNTER_START;
1655 protected abstract Builder<T> builder();
1657 protected abstract void setKey(Builder<T> builder, String key);
1659 protected abstract void setValue(Builder<T> builder, String value);
1661 public final T build(final String testName, final String key, final String value) {
1662 final Builder<T> builder = builder();
1665 setKey(builder, String.format(FORMAT_STR, testName, key, this.counter));
1667 if (value != null) {
1668 setValue(builder, String.format(FORMAT_STR, testName, value, this.counter));
1670 return builder.build();
1673 public final void reset() {
1674 this.counter = COUNTER_START;
1678 private static final class SouthboundPortExternalIdsBuilder extends KeyValueBuilder<PortExternalIds> {
1680 protected Builder<PortExternalIds> builder() {
1681 return new PortExternalIdsBuilder();
1685 protected void setKey(Builder<PortExternalIds> builder, String key) {
1686 ((PortExternalIdsBuilder) builder).setExternalIdKey(key);
1690 protected void setValue(Builder<PortExternalIds> builder, String value) {
1691 ((PortExternalIdsBuilder) builder).setExternalIdValue(value);
1695 private static final class SouthboundInterfaceExternalIdsBuilder extends KeyValueBuilder<InterfaceExternalIds> {
1697 protected Builder<InterfaceExternalIds> builder() {
1698 return new InterfaceExternalIdsBuilder();
1702 protected void setKey(Builder<InterfaceExternalIds> builder, String key) {
1703 ((InterfaceExternalIdsBuilder) builder).setExternalIdKey(key);
1707 protected void setValue(Builder<InterfaceExternalIds> builder, String value) {
1708 ((InterfaceExternalIdsBuilder) builder).setExternalIdValue(value);
1712 private static final class SouthboundOptionsBuilder extends KeyValueBuilder<Options> {
1714 protected Builder<Options> builder() {
1715 return new OptionsBuilder();
1719 protected void setKey(Builder<Options> builder, String key) {
1720 ((OptionsBuilder) builder).setOption(key);
1724 protected void setValue(Builder<Options> builder, String value) {
1725 ((OptionsBuilder) builder).setValue(value);
1729 private static final class SouthboundInterfaceOtherConfigsBuilder extends KeyValueBuilder<InterfaceOtherConfigs> {
1731 protected Builder<InterfaceOtherConfigs> builder() {
1732 return new InterfaceOtherConfigsBuilder();
1736 protected void setKey(Builder<InterfaceOtherConfigs> builder, String key) {
1737 ((InterfaceOtherConfigsBuilder) builder).setOtherConfigKey(key);
1741 protected void setValue(Builder<InterfaceOtherConfigs> builder, String value) {
1742 ((InterfaceOtherConfigsBuilder) builder).setOtherConfigValue(value);
1746 private static final class SouthboundPortOtherConfigsBuilder extends KeyValueBuilder<PortOtherConfigs> {
1748 protected Builder<PortOtherConfigs> builder() {
1749 return new PortOtherConfigsBuilder();
1753 protected void setKey(Builder<PortOtherConfigs> builder, String key) {
1754 ((PortOtherConfigsBuilder) builder).setOtherConfigKey(key);
1758 protected void setValue(Builder<PortOtherConfigs> builder, String value) {
1759 ((PortOtherConfigsBuilder) builder).setOtherConfigValue(value);
1763 private static final class SouthboundBridgeOtherConfigsBuilder extends KeyValueBuilder<BridgeOtherConfigs> {
1765 protected Builder<BridgeOtherConfigs> builder() {
1766 return new BridgeOtherConfigsBuilder();
1770 protected void setKey(Builder<BridgeOtherConfigs> builder, String key) {
1771 ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigKey(key);
1775 protected void setValue(Builder<BridgeOtherConfigs> builder, String value) {
1776 ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigValue(value);
1780 private static final class SouthboundBridgeExternalIdsBuilder extends KeyValueBuilder<BridgeExternalIds> {
1782 protected Builder<BridgeExternalIds> builder() {
1783 return new BridgeExternalIdsBuilder();
1787 protected void setKey(Builder<BridgeExternalIds> builder, String key) {
1788 ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdKey(key);
1792 protected void setValue(Builder<BridgeExternalIds> builder, String value) {
1793 ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdValue(value);
1798 * Generates the test cases involved in testing key-value-based data. See inline comments for descriptions of
1799 * the particular cases considered.
1801 private static <T> List<SouthboundTestCase<T>> generateKeyValueTestCases(
1802 KeyValueBuilder<T> builder, String testName) {
1803 List<SouthboundTestCase<T>> testCases = new ArrayList<>();
1805 final String GOOD_KEY = "GoodKey";
1806 final String GOOD_VALUE = "GoodValue";
1807 final String NO_VALUE_FOR_KEY = "NoValueForKey";
1809 final String idKey = testName + "Key";
1810 final String idValue = testName + "Value";
1812 // Test Case 1: TestOne
1813 // Test Type: Positive
1814 // Description: Create a termination point with one value
1815 // Expected: A port is created with the single value specified below
1816 final String testOneName = "TestOne" + testName;
1817 testCases.add(new SouthboundTestCaseBuilder<T>()
1819 .input(builder.build(testOneName, idKey, idValue))
1820 .expectInputAsOutput()
1823 // Test Case 2: TestFive
1824 // Test Type: Positive
1825 // Description: Create a termination point with multiple (five) values
1826 // Expected: A port is created with the five values specified below
1827 final String testFiveName = "TestFive" + testName;
1829 testCases.add(new SouthboundTestCaseBuilder<T>()
1832 builder.build(testFiveName, idKey, idValue),
1833 builder.build(testFiveName, idKey, idValue),
1834 builder.build(testFiveName, idKey, idValue),
1835 builder.build(testFiveName, idKey, idValue),
1836 builder.build(testFiveName, idKey, idValue))
1837 .expectInputAsOutput()
1840 // Test Case 3: TestOneGoodOneMalformedValue
1841 // Test Type: Negative
1843 // One perfectly fine input
1844 // (TestOneGoodOneMalformedValue_GoodKey_1,
1845 // TestOneGoodOneMalformedValue_GoodValue_1)
1846 // and one malformed input which only has key specified
1847 // (TestOneGoodOneMalformedValue_NoValueForKey_2,
1849 // Expected: A port is created without any values
1850 final String testOneGoodOneMalformedValueName = "TestOneGoodOneMalformedValue" + testName;
1852 testCases.add(new SouthboundTestCaseBuilder<T>()
1853 .name(testOneGoodOneMalformedValueName)
1855 builder.build(testOneGoodOneMalformedValueName, GOOD_KEY, GOOD_VALUE),
1856 builder.build(testOneGoodOneMalformedValueName, NO_VALUE_FOR_KEY, null))
1864 private static class PortExternalIdsSouthboundHelper implements SouthboundTerminationPointHelper<PortExternalIds> {
1866 public void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List<PortExternalIds> values) {
1867 builder.setPortExternalIds(values);
1871 public List<PortExternalIds> readValues(OvsdbTerminationPointAugmentation augmentation) {
1872 return augmentation.getPortExternalIds();
1876 private static class InterfaceExternalIdsSouthboundHelper implements
1877 SouthboundTerminationPointHelper<InterfaceExternalIds> {
1879 public void writeValues(
1880 OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceExternalIds> values) {
1881 builder.setInterfaceExternalIds(values);
1885 public List<InterfaceExternalIds> readValues(OvsdbTerminationPointAugmentation augmentation) {
1886 return augmentation.getInterfaceExternalIds();
1890 private static class OptionsSouthboundHelper implements SouthboundTerminationPointHelper<Options> {
1892 public void writeValues(
1893 OvsdbTerminationPointAugmentationBuilder builder, List<Options> values) {
1894 builder.setOptions(values);
1898 public List<Options> readValues(OvsdbTerminationPointAugmentation augmentation) {
1899 return augmentation.getOptions();
1903 private static class InterfaceOtherConfigsSouthboundHelper implements
1904 SouthboundTerminationPointHelper<InterfaceOtherConfigs> {
1906 public void writeValues(
1907 OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceOtherConfigs> values) {
1908 builder.setInterfaceOtherConfigs(values);
1912 public List<InterfaceOtherConfigs> readValues(OvsdbTerminationPointAugmentation augmentation) {
1913 return augmentation.getInterfaceOtherConfigs();
1917 private static class PortOtherConfigsSouthboundHelper implements
1918 SouthboundTerminationPointHelper<PortOtherConfigs> {
1920 public void writeValues(
1921 OvsdbTerminationPointAugmentationBuilder builder, List<PortOtherConfigs> values) {
1922 builder.setPortOtherConfigs(values);
1926 public List<PortOtherConfigs> readValues(OvsdbTerminationPointAugmentation augmentation) {
1927 return augmentation.getPortOtherConfigs();
1931 private static class BridgeExternalIdsSouthboundHelper implements SouthboundBridgeHelper<BridgeExternalIds> {
1933 public void writeValues(
1934 OvsdbBridgeAugmentationBuilder builder, List<BridgeExternalIds> values) {
1935 builder.setBridgeExternalIds(values);
1939 public List<BridgeExternalIds> readValues(OvsdbBridgeAugmentation augmentation) {
1940 return augmentation.getBridgeExternalIds();
1944 private static class BridgeOtherConfigsSouthboundHelper implements SouthboundBridgeHelper<BridgeOtherConfigs> {
1946 public void writeValues(
1947 OvsdbBridgeAugmentationBuilder builder, List<BridgeOtherConfigs> values) {
1948 builder.setBridgeOtherConfigs(values);
1952 public List<BridgeOtherConfigs> readValues(OvsdbBridgeAugmentation augmentation) {
1953 return augmentation.getBridgeOtherConfigs();