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.lang.annotation.Annotation;
23 import java.lang.reflect.Method;
24 import java.net.InetAddress;
25 import java.net.UnknownHostException;
26 import java.util.ArrayList;
27 import java.util.Collections;
28 import java.util.HashSet;
29 import java.util.List;
30 import java.util.Properties;
33 import javax.annotation.Nullable;
34 import javax.inject.Inject;
36 import org.junit.After;
37 import org.junit.Assert;
38 import org.junit.Before;
39 import org.junit.Ignore;
40 import org.junit.Test;
41 import org.junit.runner.RunWith;
42 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
43 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
44 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
45 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
46 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
47 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
48 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
49 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
50 import org.opendaylight.ovsdb.southbound.SouthboundProvider;
51 import org.opendaylight.ovsdb.southbound.SouthboundUtil;
52 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
53 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeBase;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes.VlanMode;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIdsBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.DatapathTypeEntry;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntryBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigs;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigsBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIds;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigs;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigsBuilder;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder;
96 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
97 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
98 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
99 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
100 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
101 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
102 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
103 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
104 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
105 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
106 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
107 import org.opendaylight.yangtools.concepts.Builder;
108 import org.opendaylight.yangtools.yang.binding.DataObject;
109 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
110 import org.ops4j.pax.exam.Configuration;
111 import org.ops4j.pax.exam.Option;
112 import org.ops4j.pax.exam.junit.PaxExam;
113 import org.ops4j.pax.exam.karaf.options.LogLevelOption;
114 import org.ops4j.pax.exam.options.MavenUrlReference;
115 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
116 import org.ops4j.pax.exam.spi.reactors.PerClass;
117 import org.osgi.framework.BundleContext;
118 import org.slf4j.Logger;
119 import org.slf4j.LoggerFactory;
122 * Integration tests for southbound-impl
124 * @author Sam Hague (shague@redhat.com)
126 @RunWith(PaxExam.class)
127 @ExamReactorStrategy(PerClass.class)
128 public class SouthboundIT extends AbstractMdsalTestBase {
129 private static final String NETDEV_DP_TYPE = "netdev";
130 private static final Logger LOG = LoggerFactory.getLogger(SouthboundIT.class);
131 private static final int OVSDB_UPDATE_TIMEOUT = 1000;
132 private static final int OVSDB_ROUNDTRIP_TIMEOUT = 10000;
133 private static final String FORMAT_STR = "%s_%s_%d";
134 private static String addressStr;
135 private static int portNumber;
136 private static String connectionType;
137 private static boolean setup = false;
138 private static MdsalUtils mdsalUtils = null;
139 private static Node ovsdbNode;
140 private static int testMethodsRemaining;
143 private BundleContext bundleContext;
145 private static final NotifyingDataChangeListener CONFIGURATION_LISTENER =
146 new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION);
147 private static final NotifyingDataChangeListener OPERATIONAL_LISTENER =
148 new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL);
150 private static class NotifyingDataChangeListener implements DataChangeListener {
151 private final LogicalDatastoreType type;
152 private final Set<InstanceIdentifier<?>> createdIids = new HashSet<>();
153 private final Set<InstanceIdentifier<?>> removedIids = new HashSet<>();
154 private final Set<InstanceIdentifier<?>> updatedIids = new HashSet<>();
156 private NotifyingDataChangeListener(LogicalDatastoreType type) {
161 public void onDataChanged(
162 AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> asyncDataChangeEvent) {
163 LOG.info("{} DataChanged: created {}", type, asyncDataChangeEvent.getCreatedData().keySet());
164 LOG.info("{} DataChanged: removed {}", type, asyncDataChangeEvent.getRemovedPaths());
165 LOG.info("{} DataChanged: updated {}", type, asyncDataChangeEvent.getUpdatedData().keySet());
166 createdIids.addAll(asyncDataChangeEvent.getCreatedData().keySet());
167 removedIids.addAll(asyncDataChangeEvent.getRemovedPaths());
168 updatedIids.addAll(asyncDataChangeEvent.getUpdatedData().keySet());
169 // Handled managed iids
170 for (DataObject obj : asyncDataChangeEvent.getCreatedData().values()) {
171 if (obj instanceof ManagedNodeEntry) {
172 ManagedNodeEntry managedNodeEntry = (ManagedNodeEntry) obj;
173 LOG.info("{} DataChanged: created managed {}", managedNodeEntry.getBridgeRef().getValue());
174 createdIids.add(managedNodeEntry.getBridgeRef().getValue());
182 public boolean isCreated(InstanceIdentifier<?> iid) {
183 return createdIids.remove(iid);
186 public boolean isRemoved(InstanceIdentifier<?> iid) {
187 return removedIids.remove(iid);
190 public boolean isUpdated(InstanceIdentifier<?> iid) {
191 return updatedIids.remove(iid);
196 public Option[] config() {
197 Option[] options = super.config();
198 Option[] propertyOptions = getPropertiesOptions();
199 Option[] otherOptions = getOtherOptions();
200 Option[] combinedOptions = new Option[options.length + propertyOptions.length + otherOptions.length];
201 System.arraycopy(options, 0, combinedOptions, 0, options.length);
202 System.arraycopy(propertyOptions, 0, combinedOptions, options.length, propertyOptions.length);
203 System.arraycopy(otherOptions, 0, combinedOptions, options.length + propertyOptions.length,
204 otherOptions.length);
205 return combinedOptions;
208 private Option[] getOtherOptions() {
209 return new Option[] {
210 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
216 public String getKarafDistro() {
218 .groupId("org.opendaylight.ovsdb")
219 .artifactId("southbound-karaf")
220 .versionAsInProject()
226 public String getModuleName() {
227 return "southbound-impl";
231 public String getInstanceName() {
232 return "southbound-default";
236 public MavenUrlReference getFeatureRepo() {
238 .groupId("org.opendaylight.ovsdb")
239 .artifactId("southbound-features")
240 .classifier("features")
242 .versionAsInProject();
246 public String getFeatureName() {
247 return "odl-ovsdb-southbound-test";
250 protected String usage() {
251 return "Integration Test needs a valid connection configuration as follows :\n"
252 + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
253 + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
257 public Option getLoggingOption() {
259 editConfigurationFilePut(SouthboundITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
260 "log4j.logger.org.opendaylight.ovsdb",
261 LogLevelOption.LogLevel.TRACE.name()),
262 super.getLoggingOption());
265 private Option[] getPropertiesOptions() {
266 Properties props = new Properties(System.getProperties());
267 String addressStr = props.getProperty(SouthboundITConstants.SERVER_IPADDRESS,
268 SouthboundITConstants.DEFAULT_SERVER_IPADDRESS);
269 String portStr = props.getProperty(SouthboundITConstants.SERVER_PORT,
270 SouthboundITConstants.DEFAULT_SERVER_PORT);
271 String connectionType = props.getProperty(SouthboundITConstants.CONNECTION_TYPE,
272 SouthboundITConstants.CONNECTION_TYPE_ACTIVE);
274 LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}",
275 connectionType, addressStr, portStr);
277 return new Option[] {
278 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
279 SouthboundITConstants.SERVER_IPADDRESS, addressStr),
280 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
281 SouthboundITConstants.SERVER_PORT, portStr),
282 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
283 SouthboundITConstants.CONNECTION_TYPE, connectionType),
289 public void setup() throws InterruptedException {
291 LOG.info("Skipping setup, already initialized");
297 } catch (Exception e) {
300 //dataBroker = getSession().getSALService(DataBroker.class);
302 DataBroker dataBroker = SouthboundProvider.getDb();
303 Assert.assertNotNull("db should not be null", dataBroker);
305 addressStr = bundleContext.getProperty(SouthboundITConstants.SERVER_IPADDRESS);
306 String portStr = bundleContext.getProperty(SouthboundITConstants.SERVER_PORT);
308 portNumber = Integer.parseInt(portStr);
309 } catch (NumberFormatException e) {
310 fail("Invalid port number " + portStr + System.lineSeparator() + usage());
312 connectionType = bundleContext.getProperty(SouthboundITConstants.CONNECTION_TYPE);
314 LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
315 connectionType, addressStr, portNumber);
316 if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_ACTIVE)) {
317 if (addressStr == null) {
322 mdsalUtils = new MdsalUtils(dataBroker);
323 final ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
324 final InstanceIdentifier<Node> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
325 dataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
326 iid, CONFIGURATION_LISTENER, AsyncDataBroker.DataChangeScope.SUBTREE);
327 dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
328 iid, OPERATIONAL_LISTENER, AsyncDataBroker.DataChangeScope.SUBTREE);
330 ovsdbNode = connectOvsdbNode(connectionInfo);
332 // Let's count the test methods (we need to use this instead of @AfterClass on teardown() since the latter is
333 // useless with pax-exam)
334 for (Method method : getClass().getMethods()) {
335 boolean testMethod = false;
336 boolean ignoreMethod = false;
337 for (Annotation annotation : method.getAnnotations()) {
338 if (Test.class.equals(annotation.annotationType())) {
341 if (Ignore.class.equals(annotation.annotationType())) {
345 if (testMethod && !ignoreMethod) {
346 testMethodsRemaining++;
349 LOG.info("{} test methods to run", testMethodsRemaining);
355 public void teardown() {
356 testMethodsRemaining--;
357 LOG.info("{} test methods remaining", testMethodsRemaining);
358 if (testMethodsRemaining == 0) {
360 disconnectOvsdbNode(getConnectionInfo(addressStr, portNumber));
361 } catch (InterruptedException e) {
362 LOG.warn("Interrupted while disconnecting", e);
368 * Test passive connection mode. The southbound starts in a listening mode waiting for connections on port
369 * 6640. This test will wait for incoming connections for {@link SouthboundITConstants#CONNECTION_INIT_TIMEOUT} ms.
371 * @throws InterruptedException
374 public void testPassiveNode() throws InterruptedException {
375 if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_PASSIVE)) {
376 //Wait for CONNECTION_INIT_TIMEOUT for the Passive connection to be initiated by the ovsdb-server.
377 Thread.sleep(SouthboundITConstants.CONNECTION_INIT_TIMEOUT);
381 private static ConnectionInfo getConnectionInfo(final String addressStr, final int portNumber) {
382 InetAddress inetAddress = null;
384 inetAddress = InetAddress.getByName(addressStr);
385 } catch (UnknownHostException e) {
386 fail("Could not resolve " + addressStr + ": " + e);
389 IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
390 PortNumber port = new PortNumber(portNumber);
392 final ConnectionInfo connectionInfo = new ConnectionInfoBuilder()
393 .setRemoteIp(address)
396 LOG.info("connectionInfo: {}", connectionInfo);
397 return connectionInfo;
401 public void testNetworkTopology() throws InterruptedException {
402 NetworkTopology networkTopology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION,
403 InstanceIdentifier.create(NetworkTopology.class));
404 Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.CONFIGURATION,
407 networkTopology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
408 InstanceIdentifier.create(NetworkTopology.class));
409 Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.OPERATIONAL,
414 public void testOvsdbTopology() throws InterruptedException {
415 InstanceIdentifier<Topology> path = InstanceIdentifier
416 .create(NetworkTopology.class)
417 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
419 Topology topology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
420 Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.CONFIGURATION,
423 topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
425 Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.OPERATIONAL,
429 private Node connectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
430 final InstanceIdentifier<Node> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
432 mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, iid, SouthboundUtils.createNode(connectionInfo)));
433 waitForOperationalCreation(iid);
434 Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid);
435 Assert.assertNotNull(node);
436 LOG.info("Connected to {}", SouthboundUtils.connectionInfoToString(connectionInfo));
440 private void waitForOperationalCreation(InstanceIdentifier<Node> iid) throws InterruptedException {
441 synchronized (OPERATIONAL_LISTENER) {
442 long _start = System.currentTimeMillis();
443 LOG.info("Waiting for OPERATIONAL DataChanged creation on {}", iid);
444 while (!OPERATIONAL_LISTENER.isCreated(
445 iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) {
446 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
448 LOG.info("Woke up, waited {} for creation of {}", (System.currentTimeMillis() - _start), iid);
452 private static void waitForOperationalDeletion(InstanceIdentifier<Node> iid) throws InterruptedException {
453 synchronized (OPERATIONAL_LISTENER) {
454 long _start = System.currentTimeMillis();
455 LOG.info("Waiting for OPERATIONAL DataChanged deletion on {}", iid);
456 while (!OPERATIONAL_LISTENER.isRemoved(
457 iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) {
458 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
460 LOG.info("Woke up, waited {} for deletion of {}", (System.currentTimeMillis() - _start), iid);
464 private void waitForOperationalUpdate(InstanceIdentifier<Node> iid) throws InterruptedException {
465 synchronized (OPERATIONAL_LISTENER) {
466 long _start = System.currentTimeMillis();
467 LOG.info("Waiting for OPERATIONAL DataChanged update on {}", iid);
468 while (!OPERATIONAL_LISTENER.isUpdated(
469 iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) {
470 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
472 LOG.info("Woke up, waited {} for update of {}", (System.currentTimeMillis() - _start), iid);
476 private static void disconnectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
477 final InstanceIdentifier<Node> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
478 Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
479 waitForOperationalDeletion(iid);
480 Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid);
481 Assert.assertNull(node);
482 LOG.info("Disconnected from {}", SouthboundUtils.connectionInfoToString(connectionInfo));
486 public void testAddDeleteOvsdbNode() throws InterruptedException {
487 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
488 // At this point we're connected, disconnect and reconnect (the connection will be removed at the very end)
489 disconnectOvsdbNode(connectionInfo);
490 connectOvsdbNode(connectionInfo);
494 public void testDpdkSwitch() throws InterruptedException {
495 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
496 List<DatapathTypeEntry> datapathTypeEntries = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class)
497 .getDatapathTypeEntry();
498 if (datapathTypeEntries == null) {
499 LOG.info("DPDK not supported on this node.");
501 for (DatapathTypeEntry dpTypeEntry : datapathTypeEntries) {
502 Class<? extends DatapathTypeBase> dpType = dpTypeEntry.getDatapathType();
503 String dpTypeStr = SouthboundConstants.DATAPATH_TYPE_MAP.get(dpType);
504 LOG.info("dp type is {}", dpTypeStr);
505 if (dpTypeStr.equals(NETDEV_DP_TYPE)) {
506 LOG.info("Found a DPDK node; adding a corresponding netdev device");
507 InstanceIdentifier<Node> bridgeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo,
508 new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME));
509 NodeId bridgeNodeId = SouthboundUtils.createManagedNodeId(bridgeIid);
510 try (TestBridge testBridge = new TestBridge(connectionInfo, bridgeIid,
511 SouthboundITConstants.BRIDGE_NAME, bridgeNodeId, false, null, true, dpType, null, null,
513 // Verify that the device is netdev
514 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
515 Assert.assertNotNull(bridge);
516 Assert.assertEquals(dpType, bridge.getDatapathType());
518 // Add port for all dpdk interface types (dpdkvhost not supported in existing dpdk ovs)
519 List<String> dpdkTypes = new ArrayList<String>();
520 dpdkTypes.add("dpdk");
521 dpdkTypes.add("dpdkr");
522 dpdkTypes.add("dpdkvhostuser");
523 //dpdkTypes.add("dpdkvhost");
525 for (String dpdkType : dpdkTypes) {
526 String testPortname = "test"+dpdkType+"port";
527 LOG.info("DPDK portname and type is {}, {}", testPortname, dpdkType);
528 Class<? extends InterfaceTypeBase> dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
530 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationpointBuilder =
531 createSpecificDpdkOvsdbTerminationPointAugmentationBuilder(testPortname,
534 addTerminationPoint(bridgeNodeId, testPortname, ovsdbTerminationpointBuilder));
537 // Verify that all DPDK ports are created
538 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
539 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
540 terminationPointIid);
541 Assert.assertNotNull(terminationPointNode);
543 // Verify that each termination point has the specific DPDK ifType
544 for (String dpdkType : dpdkTypes) {
545 String testPortname = "test"+dpdkType+"port";
546 Class<? extends InterfaceTypeBase> dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
548 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
549 for (TerminationPoint terminationPoint : terminationPoints) {
550 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = terminationPoint
551 .getAugmentation(OvsdbTerminationPointAugmentation.class);
552 if (ovsdbTerminationPointAugmentation.getName().equals(testPortname)) {
553 Class<? extends InterfaceTypeBase> opPort = ovsdbTerminationPointAugmentation
555 Assert.assertEquals(dpdkIfType, opPort);
567 public void testOvsdbNodeOvsVersion() throws InterruptedException {
568 OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
569 Assert.assertNotNull(ovsdbNodeAugmentation);
570 assertNotNull(ovsdbNodeAugmentation.getOvsVersion());
574 public void testOpenVSwitchOtherConfig() throws InterruptedException {
575 OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
576 Assert.assertNotNull(ovsdbNodeAugmentation);
577 List<OpenvswitchOtherConfigs> otherConfigsList = ovsdbNodeAugmentation.getOpenvswitchOtherConfigs();
578 if (otherConfigsList != null) {
579 for (OpenvswitchOtherConfigs otherConfig : otherConfigsList) {
580 if (otherConfig.getOtherConfigKey().equals("local_ip")) {
581 LOG.info("local_ip: {}", otherConfig.getOtherConfigValue());
584 LOG.info("other_config {}:{}", otherConfig.getOtherConfigKey(), otherConfig.getOtherConfigValue());
588 LOG.info("other_config is not present");
593 public void testOvsdbBridgeControllerInfo() throws InterruptedException {
594 ConnectionInfo connectionInfo = getConnectionInfo(addressStr,portNumber);
595 String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
596 assertNotNull("Failed to get controller target", controllerTarget);
597 List<ControllerEntry> setControllerEntry = createControllerEntry(controllerTarget);
598 Uri setUri = new Uri(controllerTarget);
599 try (TestBridge testBridge = new TestBridge(connectionInfo, null, SouthboundITConstants.BRIDGE_NAME,null, true,
600 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null,
601 setControllerEntry, null)) {
602 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
603 Assert.assertNotNull("bridge was not found: " + SouthboundITConstants.BRIDGE_NAME, bridge);
604 Assert.assertNotNull("ControllerEntry was not found: " + setControllerEntry.iterator().next(),
605 bridge.getControllerEntry());
606 List<ControllerEntry> getControllerEntries = bridge.getControllerEntry();
607 for (ControllerEntry entry : getControllerEntries) {
608 if (entry.getTarget() != null) {
609 Assert.assertEquals(setUri.toString(), entry.getTarget().toString());
615 private List<ControllerEntry> createControllerEntry(String controllerTarget) {
616 List<ControllerEntry> controllerEntriesList = new ArrayList<>();
617 controllerEntriesList.add(new ControllerEntryBuilder()
618 .setTarget(new Uri(controllerTarget))
620 return controllerEntriesList;
623 private static void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
624 final ConnectionInfo connectionInfo) {
625 InstanceIdentifier<Node> connectionNodePath = SouthboundUtils.createInstanceIdentifier(connectionInfo);
626 ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
629 private static List<ProtocolEntry> createMdsalProtocols() {
630 List<ProtocolEntry> protocolList = new ArrayList<>();
631 ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
632 SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
633 protocolList.add(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build());
637 private OvsdbTerminationPointAugmentationBuilder createGenericOvsdbTerminationPointAugmentationBuilder() {
638 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder =
639 new OvsdbTerminationPointAugmentationBuilder();
640 ovsdbTerminationPointAugmentationBuilder.setInterfaceType(
641 new InterfaceTypeEntryBuilder()
643 SouthboundMapper.createInterfaceType("internal"))
644 .build().getInterfaceType());
645 return ovsdbTerminationPointAugmentationBuilder;
648 private OvsdbTerminationPointAugmentationBuilder createGenericDpdkOvsdbTerminationPointAugmentationBuilder(
649 final String portName) {
650 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
651 createGenericOvsdbTerminationPointAugmentationBuilder();
652 ovsdbTerminationBuilder.setName(portName);
653 Class<? extends InterfaceTypeBase> ifType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
655 ovsdbTerminationBuilder.setInterfaceType(ifType);
656 return ovsdbTerminationBuilder;
659 private OvsdbTerminationPointAugmentationBuilder createSpecificDpdkOvsdbTerminationPointAugmentationBuilder(
660 String testPortname,Class<? extends InterfaceTypeBase> dpdkIfType) {
661 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
662 createGenericOvsdbTerminationPointAugmentationBuilder();
663 ovsdbTerminationBuilder.setName(testPortname);
664 ovsdbTerminationBuilder.setInterfaceType(dpdkIfType);
665 return ovsdbTerminationBuilder;
668 private boolean addTerminationPoint(final NodeId bridgeNodeId, final String portName,
669 final OvsdbTerminationPointAugmentationBuilder
670 ovsdbTerminationPointAugmentationBuilder)
671 throws InterruptedException {
673 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(bridgeNodeId);
674 NodeBuilder portNodeBuilder = new NodeBuilder();
675 NodeId portNodeId = SouthboundMapper.createManagedNodeId(portIid);
676 portNodeBuilder.setNodeId(portNodeId);
677 TerminationPointBuilder entry = new TerminationPointBuilder();
678 entry.setKey(new TerminationPointKey(new TpId(portName)));
679 entry.addAugmentation(
680 OvsdbTerminationPointAugmentation.class,
681 ovsdbTerminationPointAugmentationBuilder.build());
682 portNodeBuilder.setTerminationPoint(Lists.newArrayList(entry.build()));
683 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
684 portIid, portNodeBuilder.build());
685 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
689 private static class TestBridge implements AutoCloseable {
690 private final ConnectionInfo connectionInfo;
691 private final String bridgeName;
694 * Creates a test bridge which can be automatically removed when no longer necessary.
696 * @param connectionInfo The connection information.
697 * @param bridgeIid The bridge identifier; if {@code null}, one is created based on {@code bridgeName}.
698 * @param bridgeName The bridge name; must be provided.
699 * @param bridgeNodeId The bridge node identifier; if {@code null}, one is created based on {@code bridgeIid}.
700 * @param setProtocolEntries {@code true} to set default protocol entries for the bridge.
701 * @param failMode The fail mode to set for the bridge.
702 * @param setManagedBy {@code true} to specify {@code setManagedBy} for the bridge.
703 * @param dpType The datapath type.
704 * @param externalIds The external identifiers if any.
705 * @param otherConfigs The other configuration items if any.
707 public TestBridge(final ConnectionInfo connectionInfo, @Nullable InstanceIdentifier<Node> bridgeIid,
708 final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
709 final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
710 @Nullable final Class<? extends DatapathTypeBase> dpType,
711 @Nullable final List<BridgeExternalIds> externalIds,
712 @Nullable final List<ControllerEntry> controllerEntries,
713 @Nullable final List<BridgeOtherConfigs> otherConfigs) {
714 this.connectionInfo = connectionInfo;
715 this.bridgeName = bridgeName;
716 NodeBuilder bridgeNodeBuilder = new NodeBuilder();
717 if (bridgeIid == null) {
718 bridgeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
720 if (bridgeNodeId == null) {
721 bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
723 bridgeNodeBuilder.setNodeId(bridgeNodeId);
724 OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
725 ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
726 if (setProtocolEntries) {
727 ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
729 ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
731 setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
733 ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
734 ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
735 ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries);
736 ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
737 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
738 LOG.debug("Built with the intent to store bridge data {}", ovsdbBridgeAugmentationBuilder.toString());
740 mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, bridgeNodeBuilder.build()));
742 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
743 } catch (InterruptedException e) {
744 LOG.warn("Sleep interrupted while waiting for bridge creation (bridge {})", bridgeName, e);
748 public TestBridge(final ConnectionInfo connectionInfo, final String bridgeName) {
749 this(connectionInfo, null, bridgeName, null, true,
750 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null);
754 public void close() {
755 final InstanceIdentifier<Node> iid =
756 SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
757 Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
759 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
760 } catch (InterruptedException e) {
761 LOG.warn("Sleep interrupted while waiting for bridge deletion (bridge {})", bridgeName, e);
766 private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo) {
767 return getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
771 * Extract the <code>store</code> type data store contents for the particular bridge identified by
772 * <code>bridgeName</code>.
774 * @param connectionInfo the connection information
775 * @param bridgeName the bridge name
776 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
777 * @return <code>store</code> type data store contents
779 private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
780 LogicalDatastoreType store) {
781 Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
782 Assert.assertNotNull(bridgeNode);
783 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
784 Assert.assertNotNull(ovsdbBridgeAugmentation);
785 return ovsdbBridgeAugmentation;
789 * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
790 * identified by <code>bridgeName</code>
792 * @param connectionInfo the connection information
793 * @param bridgeName the bridge name
794 * @see <code>SouthboundIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
795 * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
797 private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
798 return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
802 * Extract the node contents from <code>store</code> type data store for the
803 * bridge identified by <code>bridgeName</code>
805 * @param connectionInfo the connection information
806 * @param bridgeName the bridge name
807 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
808 * @return <code>store</code> type data store contents
810 private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
811 InstanceIdentifier<Node> bridgeIid =
812 SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
813 return mdsalUtils.read(store, bridgeIid);
817 * Extract the node contents from <code>LogicalDataStoreType.OPERATIONAL</code> data store for the
818 * bridge identified by <code>bridgeName</code>
820 * @param connectionInfo the connection information
821 * @param bridgeName the bridge name
822 * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
824 private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName) {
825 return getBridgeNode(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
829 public void testAddDeleteBridge() throws InterruptedException {
830 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
832 try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
833 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
834 Assert.assertNotNull(bridge);
835 LOG.info("bridge: {}", bridge);
839 private InstanceIdentifier<Node> getTpIid(ConnectionInfo connectionInfo, OvsdbBridgeAugmentation bridge) {
840 return SouthboundUtils.createInstanceIdentifier(connectionInfo, bridge.getBridgeName());
844 * Extracts the <code>TerminationPointAugmentation</code> for the <code>index</code> <code>TerminationPoint</code>
845 * on <code>bridgeName</code>
847 * @param connectionInfo the connection information
848 * @param bridgeName the bridge name
849 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
850 * @param index the index we're interested in
851 * @return the augmentation (or {@code null} if none)
853 private OvsdbTerminationPointAugmentation getOvsdbTerminationPointAugmentation(
854 ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store, int index) {
856 List<TerminationPoint> tpList = getBridgeNode(connectionInfo, bridgeName, store).getTerminationPoint();
857 if (tpList == null) {
860 return tpList.get(index).getAugmentation(OvsdbTerminationPointAugmentation.class);
864 public void testCRDTerminationPointOfPort() throws InterruptedException {
865 final Long OFPORT_EXPECTED = 45002L;
867 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
870 try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
871 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
872 Assert.assertNotNull(bridge);
873 LOG.info("bridge: {}", bridge);
874 NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
875 connectionInfo, bridge.getBridgeName()));
876 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
877 createGenericOvsdbTerminationPointAugmentationBuilder();
878 String portName = "testOfPort";
879 ovsdbTerminationBuilder.setName(portName);
881 ovsdbTerminationBuilder.setOfport(OFPORT_EXPECTED);
882 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
883 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
884 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
885 Assert.assertNotNull(terminationPointNode);
888 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
889 for (TerminationPoint terminationPoint : terminationPoints) {
890 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
891 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
892 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
893 Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
894 // if ephemeral port 45002 is in use, ofPort is set to 1
895 Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(1L));
896 LOG.info("ofPort: {}", ofPort);
900 // UPDATE- Not Applicable. From the OpenVSwitch Documentation:
901 // "A client should ideally set this column’s value in the same database transaction that it uses to create
904 // DELETE handled by TestBridge
909 public void testCRDTerminationPointOfPortRequest() throws InterruptedException {
910 final Long OFPORT_EXPECTED = 45008L;
911 final Long OFPORT_INPUT = 45008L;
913 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
916 try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
917 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
918 Assert.assertNotNull(bridge);
919 NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
920 connectionInfo, bridge.getBridgeName()));
921 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
922 createGenericOvsdbTerminationPointAugmentationBuilder();
923 String portName = "testOfPortRequest";
924 ovsdbTerminationBuilder.setName(portName);
925 Integer ofPortRequestExpected = OFPORT_EXPECTED.intValue();
926 ovsdbTerminationBuilder.setOfport(OFPORT_INPUT);
927 ovsdbTerminationBuilder.setOfportRequest(ofPortRequestExpected);
928 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
929 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
930 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
931 Assert.assertNotNull(terminationPointNode);
934 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
935 for (TerminationPoint terminationPoint : terminationPoints) {
936 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
937 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
938 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
939 Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
940 // if ephemeral port 45008 is in use, ofPort is set to 1
941 Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(1L));
942 LOG.info("ofPort: {}", ofPort);
944 Integer ofPortRequest = ovsdbTerminationPointAugmentation.getOfportRequest();
945 Assert.assertTrue(ofPortRequest.equals(ofPortRequestExpected));
946 LOG.info("ofPortRequest: {}", ofPortRequest);
950 // UPDATE- Not Applicable. From the OpenVSwitch documentation:
951 // "A client should ideally set this column’s value in the same database transaction that it uses to
952 // create the interface. "
954 // DELETE handled by TestBridge
958 private <T> void assertExpectedExist(List<T> expected, List<T> test) {
959 if (expected != null && test != null) {
960 for (T exp : expected) {
961 Assert.assertTrue("The retrieved values don't contain " + exp, test.contains(exp));
966 private interface SouthboundTerminationPointHelper<T> {
967 void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List<T> values);
968 List<T> readValues(OvsdbTerminationPointAugmentation augmentation);
972 * Tests the CRUD operations for <code>Port</code> <code>external_ids</code>.
974 * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
976 private <T> void testCRUDTerminationPoint(
977 KeyValueBuilder<T> builder, String prefix, SouthboundTerminationPointHelper<T> helper)
978 throws InterruptedException {
979 final int TERMINATION_POINT_TEST_INDEX = 0;
981 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
983 // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
984 // the update has been performed.
985 List<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
986 List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
988 for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
989 for (SouthboundTestCase<T> updateToTestCase : updateToTestCases) {
990 String testBridgeAndPortName = String.format("%s_%s", prefix, updateToTestCase.name);
992 // CREATE: Create the test bridge
993 try (TestBridge testBridge = new TestBridge(connectionInfo, null, testBridgeAndPortName, null, true,
994 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null,
996 NodeId testBridgeNodeId = SouthboundUtils.createManagedNodeId(
997 SouthboundUtils.createInstanceIdentifier(connectionInfo,
998 new OvsdbBridgeName(testBridgeAndPortName)));
999 OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
1000 createGenericOvsdbTerminationPointAugmentationBuilder();
1001 tpCreateAugmentationBuilder.setName(testBridgeAndPortName);
1002 helper.writeValues(tpCreateAugmentationBuilder, updateFromTestCase.inputValues);
1004 addTerminationPoint(testBridgeNodeId, testBridgeAndPortName, tpCreateAugmentationBuilder));
1006 // READ: Read the test port and ensure changes are propagated to the CONFIGURATION data store,
1007 // then repeat for OPERATIONAL data store
1008 OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
1009 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1010 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1011 if (updateFromConfigurationTerminationPointAugmentation != null) {
1012 List<T> updateFromConfigurationValues =
1013 helper.readValues(updateFromConfigurationTerminationPointAugmentation);
1014 assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationValues);
1016 OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation =
1017 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1018 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1019 if (updateFromOperationalTerminationPointAugmentation != null) {
1020 List<T> updateFromOperationalValues =
1021 helper.readValues(updateFromOperationalTerminationPointAugmentation);
1022 assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalValues);
1025 // UPDATE: update the values
1026 testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeAndPortName).getNodeId();
1027 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1028 new OvsdbTerminationPointAugmentationBuilder();
1029 helper.writeValues(tpUpdateAugmentationBuilder, updateToTestCase.inputValues);
1030 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1031 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1032 NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1033 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1034 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1035 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testBridgeAndPortName)));
1036 tpUpdateBuilder.addAugmentation(
1037 OvsdbTerminationPointAugmentation.class,
1038 tpUpdateAugmentationBuilder.build());
1039 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1040 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1041 portIid, portUpdateNodeBuilder.build()));
1042 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1044 // READ: the test port and ensure changes are propagated to the CONFIGURATION data store,
1045 // then repeat for OPERATIONAL data store
1046 OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
1047 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1048 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1049 if (updateToConfigurationTerminationPointAugmentation != null) {
1050 List<T> updateToConfigurationValues =
1051 helper.readValues(updateToConfigurationTerminationPointAugmentation);
1052 assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationValues);
1053 assertExpectedExist(updateFromTestCase.expectedValues, updateToConfigurationValues);
1055 OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
1056 getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1057 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1058 if (updateToOperationalTerminationPointAugmentation != null) {
1059 List<T> updateToOperationalValues =
1060 helper.readValues(updateToOperationalTerminationPointAugmentation);
1061 if (updateFromTestCase.expectedValues != null) {
1062 assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalValues);
1063 assertExpectedExist(updateFromTestCase.expectedValues, updateToOperationalValues);
1067 // DELETE handled by TestBridge
1074 * Tests the CRUD operations for <code>Port</code> <code>external_ids</code>.
1076 * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
1079 public void testCRUDTerminationPointPortExternalIds() throws InterruptedException {
1080 testCRUDTerminationPoint(new SouthboundPortExternalIdsBuilder(), "TPPortExternalIds",
1081 new PortExternalIdsSouthboundHelper());
1085 * Tests the CRUD operations for <code>Interface</code> <code>external_ids</code>.
1087 * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1090 public void testCRUDTerminationPointInterfaceExternalIds() throws InterruptedException {
1091 testCRUDTerminationPoint(new SouthboundInterfaceExternalIdsBuilder(), "TPInterfaceExternalIds",
1092 new InterfaceExternalIdsSouthboundHelper());
1096 * Tests the CRUD operations for <code>TerminationPoint</code> <code>options</code>.
1098 * @see <code>SouthboundIT.generateTerminationPointOptions()</code> for specific test case information
1101 public void testCRUDTerminationPointOptions() throws InterruptedException {
1102 testCRUDTerminationPoint(new SouthboundOptionsBuilder(), "TPOptions", new OptionsSouthboundHelper());
1106 * Tests the CRUD operations for <code>Interface</code> <code>other_configs</code>.
1108 * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1111 public void testCRUDTerminationPointInterfaceOtherConfigs() throws InterruptedException {
1112 testCRUDTerminationPoint(new SouthboundInterfaceOtherConfigsBuilder(), "TPInterfaceOtherConfigs",
1113 new InterfaceOtherConfigsSouthboundHelper());
1117 * Tests the CRUD operations for <code>Port</code> <code>other_configs</code>.
1119 * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
1122 public void testCRUDTerminationPointPortOtherConfigs() throws InterruptedException {
1123 testCRUDTerminationPoint(new SouthboundPortOtherConfigsBuilder(), "TPPortOtherConfigs",
1124 new PortOtherConfigsSouthboundHelper());
1128 public void testCRUDTerminationPointVlan() throws InterruptedException {
1129 final Integer CREATED_VLAN_ID = 4000;
1130 final Integer UPDATED_VLAN_ID = 4001;
1132 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1135 try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1136 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1137 Assert.assertNotNull(bridge);
1138 NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1139 connectionInfo, bridge.getBridgeName()));
1140 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1141 createGenericOvsdbTerminationPointAugmentationBuilder();
1142 String portName = "testTerminationPointVlanId";
1143 ovsdbTerminationBuilder.setName(portName);
1144 ovsdbTerminationBuilder.setVlanTag(new VlanId(CREATED_VLAN_ID));
1145 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1146 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1147 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1148 Assert.assertNotNull(terminationPointNode);
1151 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1152 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation;
1153 for (TerminationPoint terminationPoint : terminationPoints) {
1154 ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
1155 OvsdbTerminationPointAugmentation.class);
1156 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1157 VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
1158 Assert.assertNotNull(actualVlanId);
1159 Integer actualVlanIdInt = actualVlanId.getValue();
1160 Assert.assertEquals(CREATED_VLAN_ID, actualVlanIdInt);
1165 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1166 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1167 new OvsdbTerminationPointAugmentationBuilder();
1168 tpUpdateAugmentationBuilder.setVlanTag(new VlanId(UPDATED_VLAN_ID));
1169 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1170 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1171 NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1172 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1173 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1174 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1175 tpUpdateBuilder.addAugmentation(
1176 OvsdbTerminationPointAugmentation.class,
1177 tpUpdateAugmentationBuilder.build());
1178 tpUpdateBuilder.setTpId(new TpId(portName));
1179 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1181 mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
1182 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1184 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1185 terminationPoints = terminationPointNode.getTerminationPoint();
1186 for (TerminationPoint terminationPoint : terminationPoints) {
1187 ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
1188 OvsdbTerminationPointAugmentation.class);
1189 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1190 VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
1191 Assert.assertNotNull(actualVlanId);
1192 Integer actualVlanIdInt = actualVlanId.getValue();
1193 Assert.assertEquals(UPDATED_VLAN_ID, actualVlanIdInt);
1197 // DELETE handled by TestBridge
1202 public void testCRUDTerminationPointVlanModes() throws InterruptedException {
1203 final VlanMode UPDATED_VLAN_MODE = VlanMode.Access;
1204 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1205 VlanMode []vlanModes = VlanMode.values();
1206 for (VlanMode vlanMode : vlanModes) {
1208 try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1209 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1210 Assert.assertNotNull(bridge);
1211 NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1212 connectionInfo, bridge.getBridgeName()));
1213 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1214 createGenericOvsdbTerminationPointAugmentationBuilder();
1215 String portName = "testTerminationPointVlanMode" + vlanMode.toString();
1216 ovsdbTerminationBuilder.setName(portName);
1217 ovsdbTerminationBuilder.setVlanMode(vlanMode);
1218 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1219 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1220 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1221 Assert.assertNotNull(terminationPointNode);
1224 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1225 for (TerminationPoint terminationPoint : terminationPoints) {
1226 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1227 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1228 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1230 Assert.assertTrue(ovsdbTerminationPointAugmentation.getVlanMode().equals(vlanMode));
1235 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1236 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1237 new OvsdbTerminationPointAugmentationBuilder();
1238 tpUpdateAugmentationBuilder.setVlanMode(UPDATED_VLAN_MODE);
1239 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1240 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1241 NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1242 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1243 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1244 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1245 tpUpdateBuilder.addAugmentation(
1246 OvsdbTerminationPointAugmentation.class,
1247 tpUpdateAugmentationBuilder.build());
1248 tpUpdateBuilder.setTpId(new TpId(portName));
1249 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1251 mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
1252 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1254 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1255 terminationPoints = terminationPointNode.getTerminationPoint();
1256 for (TerminationPoint terminationPoint : terminationPoints) {
1257 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1258 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1259 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1261 Assert.assertEquals(UPDATED_VLAN_MODE, ovsdbTerminationPointAugmentation.getVlanMode());
1265 // DELETE handled by TestBridge
1270 @SuppressWarnings("unchecked")
1271 private List<Set<Integer>> generateVlanSets() {
1274 return Lists.newArrayList(
1275 Collections.<Integer>emptySet(),
1276 Sets.newHashSet(2222),
1277 Sets.newHashSet(min, max, min + 1, max - 1, (max - min) / 2));
1280 private List<Trunks> buildTrunkList(Set<Integer> trunkSet) {
1281 List<Trunks> trunkList = Lists.newArrayList();
1282 for (Integer trunk : trunkSet) {
1283 TrunksBuilder trunkBuilder = new TrunksBuilder();
1284 trunkBuilder.setTrunk(new VlanId(trunk));
1285 trunkList.add(trunkBuilder.build());
1291 public void testCRUDTerminationPointVlanTrunks() throws InterruptedException {
1292 final List<Trunks> UPDATED_TRUNKS = buildTrunkList(Sets.newHashSet(2011));
1293 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1294 Iterable<Set<Integer>> vlanSets = generateVlanSets();
1296 for (Set<Integer> vlanSet : vlanSets) {
1299 try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1300 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1301 Assert.assertNotNull(bridge);
1302 NodeId nodeId = SouthboundUtils.createManagedNodeId(connectionInfo, bridge.getBridgeName());
1303 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1304 createGenericOvsdbTerminationPointAugmentationBuilder();
1305 String portName = "testTerminationPointVlanTrunks" + testCase;
1306 ovsdbTerminationBuilder.setName(portName);
1307 List<Trunks> trunks = buildTrunkList(vlanSet);
1308 ovsdbTerminationBuilder.setTrunks(trunks);
1309 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1310 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1311 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1312 Assert.assertNotNull(terminationPointNode);
1315 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1316 for (TerminationPoint terminationPoint : terminationPoints) {
1317 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1318 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1319 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1320 List<Trunks> actualTrunks = ovsdbTerminationPointAugmentation.getTrunks();
1321 for (Trunks trunk : trunks) {
1322 Assert.assertTrue(actualTrunks.contains(trunk));
1329 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1330 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1331 new OvsdbTerminationPointAugmentationBuilder();
1332 tpUpdateAugmentationBuilder.setTrunks(UPDATED_TRUNKS);
1333 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1334 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1335 NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1336 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1337 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1338 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1339 tpUpdateBuilder.addAugmentation(
1340 OvsdbTerminationPointAugmentation.class,
1341 tpUpdateAugmentationBuilder.build());
1342 tpUpdateBuilder.setTpId(new TpId(portName));
1343 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1345 mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
1346 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1348 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1349 terminationPoints = terminationPointNode.getTerminationPoint();
1350 for (TerminationPoint terminationPoint : terminationPoints) {
1351 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1352 terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1353 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1355 Assert.assertEquals(UPDATED_TRUNKS, ovsdbTerminationPointAugmentation.getTrunks());
1359 // DELETE handled by TestBridge
1365 public void testGetOvsdbNodes() throws InterruptedException {
1366 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1367 InstanceIdentifier<Topology> topologyPath = InstanceIdentifier
1368 .create(NetworkTopology.class)
1369 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
1371 Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, topologyPath);
1372 InstanceIdentifier<Node> expectedNodeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
1373 NodeId expectedNodeId = expectedNodeIid.firstKeyOf(Node.class, NodeKey.class).getNodeId();
1374 Node foundNode = null;
1375 Assert.assertNotNull("Expected to find topology: " + topologyPath, topology);
1376 Assert.assertNotNull("Expected to find some nodes" + topology.getNode());
1377 LOG.info("expectedNodeId: {}, getNode: {}", expectedNodeId, topology.getNode());
1378 for (Node node : topology.getNode()) {
1379 if (node.getNodeId().getValue().equals(expectedNodeId.getValue())) {
1384 Assert.assertNotNull("Expected to find Node: " + expectedNodeId, foundNode);
1388 * @see <code>SouthboundIT.generateBridgeOtherConfigsTestCases()</code> for specific test case information.
1391 public void testCRUDBridgeOtherConfigs() throws InterruptedException {
1392 testCRUDBridge("BridgeOtherConfigs", new SouthboundBridgeOtherConfigsBuilder(),
1393 new BridgeOtherConfigsSouthboundHelper());
1396 private interface SouthboundBridgeHelper<T> {
1397 void writeValues(OvsdbBridgeAugmentationBuilder builder, List<T> values);
1398 List<T> readValues(OvsdbBridgeAugmentation augmentation);
1401 private <T> void testCRUDBridge(String prefix, KeyValueBuilder<T> builder, SouthboundBridgeHelper<T> helper)
1402 throws InterruptedException {
1403 ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1404 // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
1405 // the update has been performed.
1406 List<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
1407 List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
1408 for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
1409 for (SouthboundTestCase<T> updateToTestCase : updateToTestCases) {
1410 String testBridgeName = String.format("%s_%s", prefix, updateToTestCase.name);
1412 // CREATE: Create the test bridge
1413 final OvsdbBridgeName ovsdbBridgeName = new OvsdbBridgeName(testBridgeName);
1414 final InstanceIdentifier<Node> bridgeIid =
1415 SouthboundUtils.createInstanceIdentifier(connectionInfo, ovsdbBridgeName);
1416 final NodeId bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
1417 final NodeBuilder bridgeCreateNodeBuilder = new NodeBuilder();
1418 bridgeCreateNodeBuilder.setNodeId(bridgeNodeId);
1419 OvsdbBridgeAugmentationBuilder bridgeCreateAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
1420 bridgeCreateAugmentationBuilder.setBridgeName(ovsdbBridgeName);
1421 bridgeCreateAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
1422 bridgeCreateAugmentationBuilder.setFailMode(
1423 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"));
1424 setManagedBy(bridgeCreateAugmentationBuilder, connectionInfo);
1425 helper.writeValues(bridgeCreateAugmentationBuilder, updateFromTestCase.inputValues);
1426 bridgeCreateNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class,
1427 bridgeCreateAugmentationBuilder.build());
1428 LOG.debug("Built with the intent to store bridge data {}", bridgeCreateAugmentationBuilder.toString());
1429 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
1430 bridgeCreateNodeBuilder.build()));
1431 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1433 // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
1434 // then repeat for OPERATIONAL data store
1435 List<T> updateFromConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName,
1436 LogicalDatastoreType.CONFIGURATION));
1437 assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationExternalIds);
1438 List<T> updateFromOperationalExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName));
1439 assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalExternalIds);
1441 // UPDATE: update the values
1442 final OvsdbBridgeAugmentationBuilder bridgeUpdateAugmentationBuilder =
1443 new OvsdbBridgeAugmentationBuilder();
1444 helper.writeValues(bridgeUpdateAugmentationBuilder, updateToTestCase.inputValues);
1445 final NodeBuilder bridgeUpdateNodeBuilder = new NodeBuilder();
1446 final Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
1447 bridgeUpdateNodeBuilder.setNodeId(bridgeNode.getNodeId());
1448 bridgeUpdateNodeBuilder.setKey(bridgeNode.getKey());
1449 bridgeUpdateNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class,
1450 bridgeUpdateAugmentationBuilder.build());
1451 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
1452 bridgeUpdateNodeBuilder.build()));
1453 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1455 // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
1456 // then repeat for OPERATIONAL data store
1457 List<T> updateToConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName,
1458 LogicalDatastoreType.CONFIGURATION));
1459 assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationExternalIds);
1460 assertExpectedExist(updateFromTestCase.expectedValues, updateToConfigurationExternalIds);
1461 List<T> updateToOperationalExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName));
1462 if (updateFromTestCase.expectedValues != null) {
1463 assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalExternalIds);
1464 assertExpectedExist(updateFromTestCase.expectedValues, updateToOperationalExternalIds);
1468 Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, bridgeIid));
1469 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1475 * @see <code>SouthboundIT.generateBridgeExternalIdsTestCases()</code> for specific test case information
1478 public void testCRUDBridgeExternalIds() throws InterruptedException {
1479 testCRUDBridge("BridgeExternalIds", new SouthboundBridgeExternalIdsBuilder(),
1480 new BridgeExternalIdsSouthboundHelper());
1485 * Representation of a southbound test case. Each test case has a name, a list of input values and a list of
1486 * expected values. The input values are provided to the augmentation builder, and the expected values are checked
1487 * against the output of the resulting augmentation.
1490 * Instances of this class are immutable.
1493 * @param <T> The type of data used for the test case.
1495 private static final class SouthboundTestCase<T> {
1496 private final String name;
1497 private final List<T> inputValues;
1498 private final List<T> expectedValues;
1501 * Creates an instance of a southbound test case.
1503 * @param name The test case's name.
1504 * @param inputValues The input values (provided as input to the underlying augmentation builder).
1505 * @param expectedValues The expected values (checked against the output of the underlying augmentation).
1507 public SouthboundTestCase(
1508 final String name, final List<T> inputValues, final List<T> expectedValues) {
1510 this.inputValues = inputValues;
1511 this.expectedValues = expectedValues;
1516 * Southbound test case builder.
1518 * @param <T> The type of data used for the test case.
1520 private static final class SouthboundTestCaseBuilder<T> {
1521 private String name;
1522 private List<T> inputValues;
1523 private List<T> expectedValues;
1526 * Creates a builder. Builders may be reused, the generated immutable instances are independent of the
1527 * builders. There are no default values.
1529 public SouthboundTestCaseBuilder() {
1534 * Sets the test case's name.
1536 * @param name The test case's name.
1537 * @return The builder.
1539 public SouthboundTestCaseBuilder<T> name(final String name) {
1545 * Sets the input values.
1547 * @param inputValues The input values.
1548 * @return The builder.
1551 public final SouthboundTestCaseBuilder<T> input(final T... inputValues) {
1552 this.inputValues = Lists.newArrayList(inputValues);
1557 * Indicates that the provided input values should be expected as output values.
1559 * @return The builder.
1561 public SouthboundTestCaseBuilder<T> expectInputAsOutput() {
1562 this.expectedValues = this.inputValues;
1567 * Indicates that no output should be expected.
1569 * @return The builder.
1571 public SouthboundTestCaseBuilder<T> expectNoOutput() {
1572 this.expectedValues = null;
1577 * Builds an immutable instance representing the test case.
1579 * @return The test case.
1581 @SuppressWarnings("unchecked")
1582 public SouthboundTestCase<T> build() {
1583 return new SouthboundTestCase<>(name, inputValues, expectedValues);
1587 private abstract static class KeyValueBuilder<T> {
1588 private static final int COUNTER_START = 0;
1589 private int counter = COUNTER_START;
1591 protected abstract Builder<T> builder();
1593 protected abstract void setKey(Builder<T> builder, String key);
1595 protected abstract void setValue(Builder<T> builder, String value);
1597 protected abstract boolean isValueMandatory();
1599 public final T build(final String testName, final String key, final String value) {
1600 final Builder<T> builder = builder();
1603 setKey(builder, String.format(FORMAT_STR, testName, key, this.counter));
1605 if (value != null) {
1606 setValue(builder, String.format(FORMAT_STR, testName, value, this.counter));
1608 return builder.build();
1611 public final void reset() {
1612 this.counter = COUNTER_START;
1616 private static final class SouthboundPortExternalIdsBuilder extends KeyValueBuilder<PortExternalIds> {
1618 protected Builder<PortExternalIds> builder() {
1619 return new PortExternalIdsBuilder();
1623 protected void setKey(Builder<PortExternalIds> builder, String key) {
1624 ((PortExternalIdsBuilder) builder).setExternalIdKey(key);
1628 protected void setValue(Builder<PortExternalIds> builder, String value) {
1629 ((PortExternalIdsBuilder) builder).setExternalIdValue(value);
1633 protected boolean isValueMandatory() {
1638 private static final class SouthboundInterfaceExternalIdsBuilder extends KeyValueBuilder<InterfaceExternalIds> {
1640 protected Builder<InterfaceExternalIds> builder() {
1641 return new InterfaceExternalIdsBuilder();
1645 protected void setKey(Builder<InterfaceExternalIds> builder, String key) {
1646 ((InterfaceExternalIdsBuilder) builder).setExternalIdKey(key);
1650 protected void setValue(Builder<InterfaceExternalIds> builder, String value) {
1651 ((InterfaceExternalIdsBuilder) builder).setExternalIdValue(value);
1655 protected boolean isValueMandatory() {
1660 private static final class SouthboundOptionsBuilder extends KeyValueBuilder<Options> {
1662 protected Builder<Options> builder() {
1663 return new OptionsBuilder();
1667 protected void setKey(Builder<Options> builder, String key) {
1668 ((OptionsBuilder) builder).setOption(key);
1672 protected void setValue(Builder<Options> builder, String value) {
1673 ((OptionsBuilder) builder).setValue(value);
1677 protected boolean isValueMandatory() {
1682 private static final class SouthboundInterfaceOtherConfigsBuilder extends KeyValueBuilder<InterfaceOtherConfigs> {
1684 protected Builder<InterfaceOtherConfigs> builder() {
1685 return new InterfaceOtherConfigsBuilder();
1689 protected void setKey(Builder<InterfaceOtherConfigs> builder, String key) {
1690 ((InterfaceOtherConfigsBuilder) builder).setOtherConfigKey(key);
1694 protected void setValue(Builder<InterfaceOtherConfigs> builder, String value) {
1695 ((InterfaceOtherConfigsBuilder) builder).setOtherConfigValue(value);
1699 protected boolean isValueMandatory() {
1704 private static final class SouthboundPortOtherConfigsBuilder extends KeyValueBuilder<PortOtherConfigs> {
1706 protected Builder<PortOtherConfigs> builder() {
1707 return new PortOtherConfigsBuilder();
1711 protected void setKey(Builder<PortOtherConfigs> builder, String key) {
1712 ((PortOtherConfigsBuilder) builder).setOtherConfigKey(key);
1716 protected void setValue(Builder<PortOtherConfigs> builder, String value) {
1717 ((PortOtherConfigsBuilder) builder).setOtherConfigValue(value);
1721 protected boolean isValueMandatory() {
1726 private static final class SouthboundBridgeOtherConfigsBuilder extends KeyValueBuilder<BridgeOtherConfigs> {
1728 protected Builder<BridgeOtherConfigs> builder() {
1729 return new BridgeOtherConfigsBuilder();
1733 protected void setKey(Builder<BridgeOtherConfigs> builder, String key) {
1734 ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigKey(key);
1738 protected void setValue(Builder<BridgeOtherConfigs> builder, String value) {
1739 ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigValue(value);
1743 protected boolean isValueMandatory() {
1748 private static final class SouthboundBridgeExternalIdsBuilder extends KeyValueBuilder<BridgeExternalIds> {
1750 protected Builder<BridgeExternalIds> builder() {
1751 return new BridgeExternalIdsBuilder();
1755 protected void setKey(Builder<BridgeExternalIds> builder, String key) {
1756 ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdKey(key);
1760 protected void setValue(Builder<BridgeExternalIds> builder, String value) {
1761 ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdValue(value);
1765 protected boolean isValueMandatory() {
1771 * Generates the test cases involved in testing key-value-based data. See inline comments for descriptions of
1772 * the particular cases considered.
1774 private static <T> List<SouthboundTestCase<T>> generateKeyValueTestCases(
1775 KeyValueBuilder<T> builder, String testName) {
1776 List<SouthboundTestCase<T>> testCases = new ArrayList<>();
1778 final String GOOD_KEY = "GoodKey";
1779 final String GOOD_VALUE = "GoodValue";
1780 final String NO_VALUE_FOR_KEY = "NoValueForKey";
1782 final String idKey = testName + "Key";
1783 final String idValue = testName + "Value";
1785 // Test Case 1: TestOne
1786 // Test Type: Positive
1787 // Description: Create a termination point with one value
1788 // Expected: A port is created with the single value specified below
1789 final String testOneName = "TestOne" + testName;
1790 testCases.add(new SouthboundTestCaseBuilder<T>()
1792 .input(builder.build(testOneName, idKey, idValue))
1793 .expectInputAsOutput()
1797 // Test Case 2: TestFive
1798 // Test Type: Positive
1799 // Description: Create a termination point with multiple (five) values
1800 // Expected: A port is created with the five values specified below
1801 final String testFiveName = "TestFive" + testName;
1802 testCases.add(new SouthboundTestCaseBuilder<T>()
1805 builder.build(testFiveName, idKey, idValue),
1806 builder.build(testFiveName, idKey, idValue),
1807 builder.build(testFiveName, idKey, idValue),
1808 builder.build(testFiveName, idKey, idValue),
1809 builder.build(testFiveName, idKey, idValue))
1810 .expectInputAsOutput()
1814 if (!builder.isValueMandatory()) {
1815 // Test Case 3: TestOneGoodOneMalformedValue
1816 // Test Type: Negative
1818 // One perfectly fine input
1819 // (TestOneGoodOneMalformedValue_GoodKey_1,
1820 // TestOneGoodOneMalformedValue_GoodValue_1)
1821 // and one malformed input which only has key specified
1822 // (TestOneGoodOneMalformedValue_NoValueForKey_2,
1824 // Expected: A port is created without any values
1825 final String testOneGoodOneMalformedValueName = "TestOneGoodOneMalformedValue" + testName;
1826 testCases.add(new SouthboundTestCaseBuilder<T>()
1827 .name(testOneGoodOneMalformedValueName)
1829 builder.build(testOneGoodOneMalformedValueName, GOOD_KEY, GOOD_VALUE),
1830 builder.build(testOneGoodOneMalformedValueName, NO_VALUE_FOR_KEY, null))
1835 LOG.info("generateKeyValueTestCases: skipping test case 3 for {}", builder.getClass().getSimpleName());
1841 private static class PortExternalIdsSouthboundHelper implements SouthboundTerminationPointHelper<PortExternalIds> {
1843 public void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List<PortExternalIds> values) {
1844 builder.setPortExternalIds(values);
1848 public List<PortExternalIds> readValues(OvsdbTerminationPointAugmentation augmentation) {
1849 return augmentation.getPortExternalIds();
1853 private static class InterfaceExternalIdsSouthboundHelper implements
1854 SouthboundTerminationPointHelper<InterfaceExternalIds> {
1856 public void writeValues(
1857 OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceExternalIds> values) {
1858 builder.setInterfaceExternalIds(values);
1862 public List<InterfaceExternalIds> readValues(OvsdbTerminationPointAugmentation augmentation) {
1863 return augmentation.getInterfaceExternalIds();
1867 private static class OptionsSouthboundHelper implements SouthboundTerminationPointHelper<Options> {
1869 public void writeValues(
1870 OvsdbTerminationPointAugmentationBuilder builder, List<Options> values) {
1871 builder.setOptions(values);
1875 public List<Options> readValues(OvsdbTerminationPointAugmentation augmentation) {
1876 return augmentation.getOptions();
1880 private static class InterfaceOtherConfigsSouthboundHelper implements
1881 SouthboundTerminationPointHelper<InterfaceOtherConfigs> {
1883 public void writeValues(
1884 OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceOtherConfigs> values) {
1885 builder.setInterfaceOtherConfigs(values);
1889 public List<InterfaceOtherConfigs> readValues(OvsdbTerminationPointAugmentation augmentation) {
1890 return augmentation.getInterfaceOtherConfigs();
1894 private static class PortOtherConfigsSouthboundHelper implements
1895 SouthboundTerminationPointHelper<PortOtherConfigs> {
1897 public void writeValues(
1898 OvsdbTerminationPointAugmentationBuilder builder, List<PortOtherConfigs> values) {
1899 builder.setPortOtherConfigs(values);
1903 public List<PortOtherConfigs> readValues(OvsdbTerminationPointAugmentation augmentation) {
1904 return augmentation.getPortOtherConfigs();
1908 private static class BridgeExternalIdsSouthboundHelper implements SouthboundBridgeHelper<BridgeExternalIds> {
1910 public void writeValues(
1911 OvsdbBridgeAugmentationBuilder builder, List<BridgeExternalIds> values) {
1912 builder.setBridgeExternalIds(values);
1916 public List<BridgeExternalIds> readValues(OvsdbBridgeAugmentation augmentation) {
1917 return augmentation.getBridgeExternalIds();
1921 private static class BridgeOtherConfigsSouthboundHelper implements SouthboundBridgeHelper<BridgeOtherConfigs> {
1923 public void writeValues(
1924 OvsdbBridgeAugmentationBuilder builder, List<BridgeOtherConfigs> values) {
1925 builder.setBridgeOtherConfigs(values);
1929 public List<BridgeOtherConfigs> readValues(OvsdbBridgeAugmentation augmentation) {
1930 return augmentation.getBridgeOtherConfigs();