038edc3e11fd95a0ee2fd1b3f84da08c4e8b9353
[ovsdb.git] / southbound / southbound-it / src / test / java / org / opendaylight / ovsdb / southbound / it / SouthboundIT.java
1 /*
2  * Copyright (c) 2015 Red Hat, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.ovsdb.southbound.it;
9
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;
19
20 import com.google.common.collect.ImmutableBiMap;
21 import com.google.common.collect.Lists;
22 import com.google.common.collect.Sets;
23
24 import java.io.File;
25 import java.net.InetAddress;
26 import java.net.UnknownHostException;
27 import java.util.ArrayList;
28 import java.util.Collections;
29 import java.util.List;
30 import java.util.Properties;
31 import java.util.Set;
32
33 import javax.inject.Inject;
34
35 import org.junit.Assert;
36 import org.junit.Before;
37 import org.junit.Test;
38 import org.junit.runner.RunWith;
39 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
40 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
41 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
42 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
43 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
44 import org.opendaylight.ovsdb.southbound.SouthboundProvider;
45 import org.opendaylight.ovsdb.southbound.SouthboundUtil;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeBase;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentationBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes.VlanMode;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIdsBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.DatapathTypeEntry;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntryBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigs;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigsBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIds;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigs;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigsBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder;
88 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
89 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
90 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
91 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
92 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
93 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
94 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
95 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
96 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
97 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
98 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
99 import org.opendaylight.yangtools.concepts.Builder;
100 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
101 import org.ops4j.pax.exam.Configuration;
102 import org.ops4j.pax.exam.Option;
103 import org.ops4j.pax.exam.junit.PaxExam;
104 import org.ops4j.pax.exam.karaf.options.KarafDistributionOption;
105 import org.ops4j.pax.exam.karaf.options.LogLevelOption;
106 import org.ops4j.pax.exam.options.MavenUrlReference;
107 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
108 import org.ops4j.pax.exam.spi.reactors.PerClass;
109 import org.osgi.framework.BundleContext;
110 import org.slf4j.Logger;
111 import org.slf4j.LoggerFactory;
112
113 /**
114  * Integration tests for southbound-impl
115  *
116  * @author Sam Hague (shague@redhat.com)
117  */
118 @RunWith(PaxExam.class)
119 @ExamReactorStrategy(PerClass.class)
120 public class SouthboundIT extends AbstractMdsalTestBase {
121     private static final String NETDEV_DP_TYPE = "netdev";
122     private static final Logger LOG = LoggerFactory.getLogger(SouthboundIT.class);
123     private static final int OVSDB_UPDATE_TIMEOUT = 1000;
124     private static final String FORMAT_STR = "%s_%s_%d";
125     private static String addressStr;
126     private static int portNumber;
127     private static String connectionType;
128     private static Boolean setup = false;
129     private static MdsalUtils mdsalUtils = null;
130
131     // TODO Constants copied from AbstractConfigTestBase, need to be removed (see TODO below)
132     private static final String PAX_EXAM_UNPACK_DIRECTORY = "target/exam";
133     private static final String KARAF_DEBUG_PORT = "5005";
134     private static final String KARAF_DEBUG_PROP = "karaf.debug";
135     private static final String KEEP_UNPACK_DIRECTORY_PROP = "karaf.keep.unpack";
136
137     @Inject
138     private BundleContext bundleContext;
139
140     @Configuration
141     public Option[] config() {
142         // TODO Figure out how to use the parent Karaf setup, then just use super.config()
143         Option[] options = new Option[] {
144                 when(Boolean.getBoolean(KARAF_DEBUG_PROP))
145                         .useOptions(KarafDistributionOption.debugConfiguration(KARAF_DEBUG_PORT, true)),
146                 karafDistributionConfiguration().frameworkUrl(getKarafDistro())
147                         .unpackDirectory(new File(PAX_EXAM_UNPACK_DIRECTORY))
148                         .useDeployFolder(false),
149                 when(Boolean.getBoolean(KEEP_UNPACK_DIRECTORY_PROP)).useOptions(keepRuntimeFolder()),
150                 // Works only if we don't specify the feature repo and name
151                 getLoggingOption()};
152         Option[] propertyOptions = getPropertiesOptions();
153         Option[] otherOptions = getOtherOptions();
154         Option[] combinedOptions = new Option[options.length + propertyOptions.length + otherOptions.length];
155         System.arraycopy(options, 0, combinedOptions, 0, options.length);
156         System.arraycopy(propertyOptions, 0, combinedOptions, options.length, propertyOptions.length);
157         System.arraycopy(otherOptions, 0, combinedOptions, options.length + propertyOptions.length,
158                 otherOptions.length);
159         return combinedOptions;
160     }
161
162     private Option[] getOtherOptions() {
163         return new Option[] {
164                 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
165                 keepRuntimeFolder()
166         };
167     }
168
169     @Override
170     public String getKarafDistro() {
171         return maven()
172                 .groupId("org.opendaylight.ovsdb")
173                 .artifactId("southbound-karaf")
174                 .versionAsInProject()
175                 .type("zip")
176                 .getURL();
177     }
178
179     @Override
180     public String getModuleName() {
181         return "southbound-impl";
182     }
183
184     @Override
185     public String getInstanceName() {
186         return "southbound-default";
187     }
188
189     @Override
190     public MavenUrlReference getFeatureRepo() {
191         return maven()
192                 .groupId("org.opendaylight.ovsdb")
193                 .artifactId("southbound-features")
194                 .classifier("features")
195                 .type("xml")
196                 .versionAsInProject();
197     }
198
199     @Override
200     public String getFeatureName() {
201         return "odl-ovsdb-southbound-impl-ui";
202     }
203
204     protected String usage() {
205         return "Integration Test needs a valid connection configuration as follows :\n"
206                 + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
207                 + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
208     }
209
210     @Override
211     public Option getLoggingOption() {
212         return composite(
213                 editConfigurationFilePut(SouthboundITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
214                         "log4j.logger.org.opendaylight.ovsdb",
215                         LogLevelOption.LogLevel.TRACE.name()),
216                 super.getLoggingOption());
217     }
218
219     private Option[] getPropertiesOptions() {
220         Properties props = new Properties(System.getProperties());
221         String addressStr = props.getProperty(SouthboundITConstants.SERVER_IPADDRESS,
222                 SouthboundITConstants.DEFAULT_SERVER_IPADDRESS);
223         String portStr = props.getProperty(SouthboundITConstants.SERVER_PORT,
224                 SouthboundITConstants.DEFAULT_SERVER_PORT);
225         String connectionType = props.getProperty(SouthboundITConstants.CONNECTION_TYPE,
226                 SouthboundITConstants.CONNECTION_TYPE_ACTIVE);
227
228         LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}",
229                 connectionType, addressStr, portStr);
230
231         return new Option[] {
232                 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
233                         SouthboundITConstants.SERVER_IPADDRESS, addressStr),
234                 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
235                         SouthboundITConstants.SERVER_PORT, portStr),
236                 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
237                         SouthboundITConstants.CONNECTION_TYPE, connectionType),
238         };
239     }
240
241     @Before
242     @Override
243     public void setup() throws InterruptedException {
244         if (setup) {
245             LOG.info("Skipping setup, already initialized");
246             return;
247         }
248
249         try {
250             super.setup();
251         } catch (Exception e) {
252             e.printStackTrace();
253         }
254         //dataBroker = getSession().getSALService(DataBroker.class);
255         Thread.sleep(3000);
256         DataBroker dataBroker = SouthboundProvider.getDb();
257         Assert.assertNotNull("db should not be null", dataBroker);
258
259         addressStr = bundleContext.getProperty(SouthboundITConstants.SERVER_IPADDRESS);
260         String portStr = bundleContext.getProperty(SouthboundITConstants.SERVER_PORT);
261         try {
262             portNumber = Integer.parseInt(portStr);
263         } catch (NumberFormatException e) {
264             fail("Invalid port number " + portStr + System.lineSeparator() + usage());
265         }
266         connectionType = bundleContext.getProperty(SouthboundITConstants.CONNECTION_TYPE);
267
268         LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
269                 connectionType, addressStr, portNumber);
270         if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_ACTIVE)) {
271             if (addressStr == null) {
272                 fail(usage());
273             }
274         }
275
276         mdsalUtils = new MdsalUtils(dataBroker);
277         setup = true;
278     }
279
280     /**
281      * Test passive connection mode. The southbound starts in a listening mode waiting for connections on port
282      * 6640. This test will wait for incoming connections for {@link SouthboundITConstants#CONNECTION_INIT_TIMEOUT} ms.
283      *
284      * @throws InterruptedException
285      */
286     @Test
287     public void testPassiveNode() throws InterruptedException {
288         if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_PASSIVE)) {
289             //Wait for CONNECTION_INIT_TIMEOUT for the Passive connection to be initiated by the ovsdb-server.
290             Thread.sleep(SouthboundITConstants.CONNECTION_INIT_TIMEOUT);
291         }
292     }
293
294     private ConnectionInfo getConnectionInfo(final String addressStr, final int portNumber) {
295         InetAddress inetAddress = null;
296         try {
297             inetAddress = InetAddress.getByName(addressStr);
298         } catch (UnknownHostException e) {
299             fail("Could not resolve " + addressStr + ": " + e);
300         }
301
302         IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
303         PortNumber port = new PortNumber(portNumber);
304
305         final ConnectionInfo connectionInfo = new ConnectionInfoBuilder()
306                 .setRemoteIp(address)
307                 .setRemotePort(port)
308                 .build();
309         LOG.info("connectionInfo: {}", connectionInfo);
310         return connectionInfo;
311     }
312
313     private String connectionInfoToString(final ConnectionInfo connectionInfo) {
314         return new String(connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
315     }
316
317     @Test
318     public void testNetworkTopology() throws InterruptedException {
319         NetworkTopology networkTopology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION,
320                 InstanceIdentifier.create(NetworkTopology.class));
321         Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.CONFIGURATION,
322                 networkTopology);
323
324         networkTopology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
325                 InstanceIdentifier.create(NetworkTopology.class));
326         Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.OPERATIONAL,
327                 networkTopology);
328     }
329
330     @Test
331     public void testOvsdbTopology() throws InterruptedException {
332         InstanceIdentifier<Topology> path = InstanceIdentifier
333                 .create(NetworkTopology.class)
334                 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
335
336         Topology topology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
337         Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.CONFIGURATION,
338                 topology);
339
340         topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
341
342         Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.OPERATIONAL,
343                 topology);
344     }
345
346     private boolean addOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
347         boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
348                 createInstanceIdentifier(connectionInfo),
349                 createNode(connectionInfo));
350         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
351         return result;
352     }
353
354     private InstanceIdentifier<Node> createInstanceIdentifier(
355             ConnectionInfo connectionInfo) {
356         return InstanceIdentifier
357                 .create(NetworkTopology.class)
358                 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
359                 .child(Node.class,
360                         createNodeKey(connectionInfo.getRemoteIp(), connectionInfo.getRemotePort()));
361     }
362
363     private Node getOvsdbNode(final ConnectionInfo connectionInfo) {
364         return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
365                 createInstanceIdentifier(connectionInfo));
366     }
367
368     private boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
369         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
370                 createInstanceIdentifier(connectionInfo));
371         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
372         return result;
373     }
374
375     private Node connectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
376         Assert.assertTrue(addOvsdbNode(connectionInfo));
377         Node node = getOvsdbNode(connectionInfo);
378         Assert.assertNotNull(node);
379         LOG.info("Connected to {}", connectionInfoToString(connectionInfo));
380         return node;
381     }
382
383     private boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
384         Assert.assertTrue(deleteOvsdbNode(connectionInfo));
385         Node node = getOvsdbNode(connectionInfo);
386         Assert.assertNull(node);
387         //Assume.assumeNotNull(node); // Using assumeNotNull because there is no assumeNull
388         LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
389         return true;
390     }
391
392     @Test
393     public void testAddDeleteOvsdbNode() throws InterruptedException {
394         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
395         connectOvsdbNode(connectionInfo);
396         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
397     }
398
399     @Test
400     public void testDpdkSwitch() throws InterruptedException {
401         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
402         Node ovsdbNode = connectOvsdbNode(connectionInfo);
403         List<DatapathTypeEntry> datapathTypeEntries = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class)
404                 .getDatapathTypeEntry();
405         if (datapathTypeEntries == null) {
406             LOG.info("DPDK not supported on this node.");
407         } else {
408             for (DatapathTypeEntry dpTypeEntry : datapathTypeEntries) {
409                 Class<? extends DatapathTypeBase> dpType = dpTypeEntry.getDatapathType();
410                 String dpTypeStr = SouthboundConstants.DATAPATH_TYPE_MAP.get(dpType);
411                 LOG.info("dp type is {}", dpTypeStr);
412                 if (dpTypeStr.equals(NETDEV_DP_TYPE)) {
413                     LOG.info("Found a DPDK node; adding a corresponding netdev device");
414                     InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(connectionInfo,
415                             new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME));
416                     NodeId bridgeNodeId = createManagedNodeId(bridgeIid);
417                     addBridge(connectionInfo, bridgeIid, SouthboundITConstants.BRIDGE_NAME, bridgeNodeId, false, null,
418                             true, dpType, null, null, null);
419
420                     // Verify that the device is netdev
421                     OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
422                     Assert.assertNotNull(bridge);
423                     Assert.assertEquals(dpType, bridge.getDatapathType());
424
425                     // Add dpdk port
426                     final String TEST_PORT_NAME = "testDPDKPort";
427                     OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
428                             createGenericDpdkOvsdbTerminationPointAugmentationBuilder(TEST_PORT_NAME);
429                     Assert.assertTrue(addTerminationPoint(bridgeNodeId, TEST_PORT_NAME, ovsdbTerminationBuilder));
430
431                     // Verify that DPDK port was created
432                     InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
433                     Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
434                             terminationPointIid);
435                     Assert.assertNotNull(terminationPointNode);
436
437                     // Verify that each termination point has DPDK ifType
438                     Class<? extends InterfaceTypeBase> dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
439                             .get("dpdk");
440                     List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
441                     for (TerminationPoint terminationPoint : terminationPoints) {
442                         OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = terminationPoint
443                                 .getAugmentation(OvsdbTerminationPointAugmentation.class);
444                         if (ovsdbTerminationPointAugmentation.getName().equals(TEST_PORT_NAME)) {
445                             Class<? extends InterfaceTypeBase> opPort = ovsdbTerminationPointAugmentation
446                                     .getInterfaceType();
447                             Assert.assertEquals(dpdkIfType, opPort);
448                         }
449                     }
450                     Assert.assertTrue(deleteBridge(connectionInfo));
451                     break;
452                 }
453             }
454         }
455         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
456     }
457
458     @Test
459     public void testOvsdbNodeOvsVersion() throws InterruptedException {
460         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
461         Node ovsdbNode = connectOvsdbNode(connectionInfo);
462         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
463         Assert.assertNotNull(ovsdbNodeAugmentation);
464         assertNotNull(ovsdbNodeAugmentation.getOvsVersion());
465         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
466     }
467
468     @Test
469     public void testOpenVSwitchOtherConfig() throws InterruptedException {
470         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
471         Node ovsdbNode = connectOvsdbNode(connectionInfo);
472         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
473         Assert.assertNotNull(ovsdbNodeAugmentation);
474         List<OpenvswitchOtherConfigs> otherConfigsList = ovsdbNodeAugmentation.getOpenvswitchOtherConfigs();
475         if (otherConfigsList != null) {
476             for (OpenvswitchOtherConfigs otherConfig : otherConfigsList) {
477                 if (otherConfig.getOtherConfigKey().equals("local_ip")) {
478                     LOG.info("local_ip: {}", otherConfig.getOtherConfigValue());
479                     break;
480                 } else {
481                     LOG.info("other_config {}:{}", otherConfig.getOtherConfigKey(), otherConfig.getOtherConfigValue());
482                 }
483             }
484         } else {
485             LOG.info("other_config is not present");
486         }
487         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
488     }
489
490     @Test
491     public void testOvsdbBridgeControllerInfo() throws InterruptedException {
492         ConnectionInfo connectionInfo = getConnectionInfo(addressStr,portNumber);
493         Node ovsdbNode = connectOvsdbNode(connectionInfo);
494         String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
495         assertNotNull("Failed to get controller target", controllerTarget);
496         List<ControllerEntry> setControllerEntry = createControllerEntry(controllerTarget);
497         Uri setUri = new Uri(controllerTarget);
498         Assert.assertTrue(addBridge(connectionInfo, null, SouthboundITConstants.BRIDGE_NAME,null, true,
499                 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null,
500                 setControllerEntry, null));
501         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
502         Assert.assertNotNull("bridge was not found: " + SouthboundITConstants.BRIDGE_NAME,  bridge);
503         Assert.assertNotNull("ControllerEntry was not found: " + setControllerEntry.iterator().next(),
504                 bridge.getControllerEntry());
505         List<ControllerEntry> getControllerEntries = bridge.getControllerEntry();
506         for (ControllerEntry entry : getControllerEntries) {
507             if (entry.getTarget() != null) {
508                 Assert.assertEquals(setUri.toString(), entry.getTarget().toString());
509             }
510         }
511
512         Assert.assertTrue(deleteBridge(connectionInfo));
513         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
514     }
515
516     private List<ControllerEntry> createControllerEntry(String controllerTarget) {
517         List<ControllerEntry> controllerEntriesList = new ArrayList<>();
518         controllerEntriesList.add(new ControllerEntryBuilder()
519                 .setTarget(new Uri(controllerTarget))
520                 .build());
521         return controllerEntriesList;
522     }
523
524     private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
525                               final ConnectionInfo connectionInfo) {
526         InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(connectionInfo);
527         ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
528     }
529
530     private List<ProtocolEntry> createMdsalProtocols() {
531         List<ProtocolEntry> protocolList = new ArrayList<>();
532         ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
533                 SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
534         protocolList.add(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build());
535         return protocolList;
536     }
537
538     private OvsdbTerminationPointAugmentationBuilder createGenericOvsdbTerminationPointAugmentationBuilder() {
539         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder =
540                 new OvsdbTerminationPointAugmentationBuilder();
541         ovsdbTerminationPointAugmentationBuilder.setInterfaceType(
542                 new InterfaceTypeEntryBuilder()
543                         .setInterfaceType(
544                                 SouthboundMapper.createInterfaceType("internal"))
545                         .build().getInterfaceType());
546         return ovsdbTerminationPointAugmentationBuilder;
547     }
548
549     private OvsdbTerminationPointAugmentationBuilder createGenericDpdkOvsdbTerminationPointAugmentationBuilder(
550             final String portName) {
551         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
552                 createGenericOvsdbTerminationPointAugmentationBuilder();
553         ovsdbTerminationBuilder.setName(portName);
554         Class<? extends InterfaceTypeBase> ifType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
555                 .get("dpdk");
556         ovsdbTerminationBuilder.setInterfaceType(ifType);
557         return ovsdbTerminationBuilder;
558     }
559
560     private boolean addTerminationPoint(final NodeId bridgeNodeId, final String portName,
561                                         final OvsdbTerminationPointAugmentationBuilder
562                                                 ovsdbTerminationPointAugmentationBuilder)
563             throws InterruptedException {
564
565         InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(bridgeNodeId);
566         NodeBuilder portNodeBuilder = new NodeBuilder();
567         NodeId portNodeId = SouthboundMapper.createManagedNodeId(portIid);
568         portNodeBuilder.setNodeId(portNodeId);
569         TerminationPointBuilder entry = new TerminationPointBuilder();
570         entry.setKey(new TerminationPointKey(new TpId(portName)));
571         entry.addAugmentation(
572                 OvsdbTerminationPointAugmentation.class,
573                 ovsdbTerminationPointAugmentationBuilder.build());
574         portNodeBuilder.setTerminationPoint(Lists.newArrayList(entry.build()));
575         boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
576                 portIid, portNodeBuilder.build());
577         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
578         return result;
579     }
580
581     /*
582      * base method for adding test bridges.  Other helper methods used to create bridges should utilize this method.
583      *
584      * @param connectionInfo
585      * @param bridgeIid if passed null, one is created
586      * @param bridgeName cannot be null
587      * @param bridgeNodeId if passed null, one is created based on <code>bridgeIid</code>
588      * @param setProtocolEntries toggles whether default protocol entries are set for the bridge
589      * @param failMode toggles whether default fail mode is set for the bridge
590      * @param setManagedBy toggles whether to setManagedBy for the bridge
591      * @param dpType if passed null, this parameter is ignored
592      * @param externalIds if passed null, this parameter is ignored
593      * @param otherConfigs if passed null, this parameter is ignored
594      * @return success of bridge addition
595      * @throws InterruptedException
596      */
597     private boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
598                               final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
599                               final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
600                               final Class<? extends DatapathTypeBase> dpType,
601                               final List<BridgeExternalIds> externalIds,
602                               final List<ControllerEntry> controllerEntries,
603                               final List<BridgeOtherConfigs> otherConfigs) throws InterruptedException {
604
605         NodeBuilder bridgeNodeBuilder = new NodeBuilder();
606         if (bridgeIid == null) {
607             bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
608         }
609         if (bridgeNodeId == null) {
610             bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
611         }
612         bridgeNodeBuilder.setNodeId(bridgeNodeId);
613         OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
614         ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
615         if (setProtocolEntries) {
616             ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
617         }
618         if (failMode != null) {
619             ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
620         }
621         if (setManagedBy) {
622             setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
623         }
624         if (dpType != null) {
625             ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
626         }
627         if (externalIds != null) {
628             ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
629         }
630         if (controllerEntries != null) {
631             ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries);
632         }
633         if (otherConfigs != null) {
634             ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
635         }
636         bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
637         LOG.debug("Built with the intent to store bridge data {}",
638                 ovsdbBridgeAugmentationBuilder.toString());
639         boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
640                 bridgeIid, bridgeNodeBuilder.build());
641         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
642         return result;
643     }
644
645     private boolean addBridge(final ConnectionInfo connectionInfo, final String bridgeName)
646             throws InterruptedException {
647
648         return addBridge(connectionInfo, null, bridgeName, null, true,
649                 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null);
650     }
651
652     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo) {
653         return getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
654     }
655
656     /**
657      * Extract the <code>store</code> type data store contents for the particular bridge identified by
658      * <code>bridgeName</code>.
659      *
660      * @param connectionInfo the connection information
661      * @param bridgeName the bridge name
662      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
663      * @return <code>store</code> type data store contents
664      */
665     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
666                                               LogicalDatastoreType store) {
667         Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
668         Assert.assertNotNull(bridgeNode);
669         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
670         Assert.assertNotNull(ovsdbBridgeAugmentation);
671         return ovsdbBridgeAugmentation;
672     }
673
674     /**
675      * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
676      * identified by <code>bridgeName</code>
677      *
678      * @param connectionInfo the connection information
679      * @param bridgeName the bridge name
680      * @see <code>SouthboundIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
681      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
682      */
683     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
684         return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
685     }
686
687     /**
688      * Extract the node contents from <code>store</code> type data store for the
689      * bridge identified by <code>bridgeName</code>
690      *
691      * @param connectionInfo the connection information
692      * @param bridgeName the bridge name
693      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
694      * @return <code>store</code> type data store contents
695      */
696     private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
697         InstanceIdentifier<Node> bridgeIid =
698                 createInstanceIdentifier(connectionInfo,
699                         new OvsdbBridgeName(bridgeName));
700         return mdsalUtils.read(store, bridgeIid);
701     }
702
703     /**
704      * Extract the node contents from <code>LogicalDataStoreType.OPERATIONAL</code> data store for the
705      * bridge identified by <code>bridgeName</code>
706      *
707      * @param connectionInfo the connection information
708      * @param bridgeName the bridge name
709      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
710      */
711     private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName) {
712         return getBridgeNode(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
713     }
714
715     private boolean deleteBridge(ConnectionInfo connectionInfo) throws InterruptedException {
716         return deleteBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
717     }
718
719     private boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName)
720             throws InterruptedException {
721
722         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
723                 createInstanceIdentifier(connectionInfo,
724                         new OvsdbBridgeName(bridgeName)));
725         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
726         return result;
727     }
728
729     @Test
730     public void testAddDeleteBridge() throws InterruptedException {
731         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
732         connectOvsdbNode(connectionInfo);
733
734         Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
735         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
736         Assert.assertNotNull(bridge);
737         LOG.info("bridge: {}", bridge);
738
739         Assert.assertTrue(deleteBridge(connectionInfo));
740
741         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
742     }
743
744     private InstanceIdentifier<Node> getTpIid(ConnectionInfo connectionInfo, OvsdbBridgeAugmentation bridge) {
745         return createInstanceIdentifier(connectionInfo,
746                 bridge.getBridgeName());
747     }
748
749     /**
750      * Extracts the <code>TerminationPointAugmentation</code> for the <code>index</code> <code>TerminationPoint</code>
751      * on <code>bridgeName</code>
752      *
753      * @param connectionInfo the connection information
754      * @param bridgeName the bridge name
755      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
756      * @param index the index we're interested in
757      * @return the augmentation (or {@code null} if none)
758      */
759     private OvsdbTerminationPointAugmentation getOvsdbTerminationPointAugmentation(
760             ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store, int index) {
761
762         List<TerminationPoint> tpList = getBridgeNode(connectionInfo, bridgeName, store).getTerminationPoint();
763         if (tpList == null) {
764             return null;
765         }
766         return tpList.get(index).getAugmentation(OvsdbTerminationPointAugmentation.class);
767     }
768
769     @Test
770     public void testCRDTerminationPointOfPort() throws InterruptedException {
771         final Long OFPORT_EXPECTED = 45002L;
772
773         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
774         connectOvsdbNode(connectionInfo);
775
776         // CREATE
777         Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
778         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
779         Assert.assertNotNull(bridge);
780         LOG.info("bridge: {}", bridge);
781         NodeId nodeId = SouthboundMapper.createManagedNodeId(createInstanceIdentifier(
782                 connectionInfo, bridge.getBridgeName()));
783         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
784                 createGenericOvsdbTerminationPointAugmentationBuilder();
785         String portName = "testOfPort";
786         ovsdbTerminationBuilder.setName(portName);
787
788         ovsdbTerminationBuilder.setOfport(OFPORT_EXPECTED);
789         Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
790         InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
791         Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
792         Assert.assertNotNull(terminationPointNode);
793
794         // READ
795         List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
796         for (TerminationPoint terminationPoint : terminationPoints) {
797             OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
798                     terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
799             if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
800                 Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
801                 // if ephemeral port 45002 is in use, ofPort is set to 1
802                 Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(new Long(1)));
803                 LOG.info("ofPort: {}", ofPort);
804             }
805         }
806
807         // UPDATE- Not Applicable.  From the OpenVSwitch Documentation:
808         //   "A client should ideally set this column’s value in the same database transaction that it uses to create
809         //   the interface."
810
811         // DELETE
812         Assert.assertTrue(deleteBridge(connectionInfo));
813         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
814     }
815
816     @Test
817     public void testCRDTerminationPointOfPortRequest() throws InterruptedException {
818         final Long OFPORT_EXPECTED = 45008L;
819         final Long OFPORT_INPUT = 45008L;
820
821         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
822         connectOvsdbNode(connectionInfo);
823
824         // CREATE
825         Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
826         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
827         Assert.assertNotNull(bridge);
828         NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
829                 connectionInfo, bridge.getBridgeName()));
830         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
831                 createGenericOvsdbTerminationPointAugmentationBuilder();
832         String portName = "testOfPortRequest";
833         ovsdbTerminationBuilder.setName(portName);
834         Integer ofPortRequestExpected = OFPORT_EXPECTED.intValue();
835         ovsdbTerminationBuilder.setOfport(OFPORT_INPUT);
836         ovsdbTerminationBuilder.setOfportRequest(ofPortRequestExpected);
837         Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
838         InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
839         Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
840         Assert.assertNotNull(terminationPointNode);
841
842         // READ
843         List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
844         for (TerminationPoint terminationPoint : terminationPoints) {
845             OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
846                     terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
847             if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
848                 Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
849                 // if ephemeral port 45008 is in use, ofPort is set to 1
850                 Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(new Long(1)));
851                 LOG.info("ofPort: {}", ofPort);
852
853                 Integer ofPortRequest = ovsdbTerminationPointAugmentation.getOfportRequest();
854                 Assert.assertTrue(ofPortRequest.equals(ofPortRequestExpected));
855                 LOG.info("ofPortRequest: {}", ofPortRequest);
856             }
857         }
858
859         // UPDATE- Not Applicable.  From the OpenVSwitch documentation:
860         //   "A client should ideally set this column’s value in the same database transaction that it uses to create
861         //   the interface. "
862
863         // DELETE
864         Assert.assertTrue(deleteBridge(connectionInfo));
865         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
866     }
867
868     /*
869      * @see <code>SouthboundIT.testCRUDPortExternalIds()</code>
870      * This is helper test method to compare a test "set" of BridgeExternalIds against an expected "set"
871      */
872     private void assertExpectedPortExternalIdsExist( List<PortExternalIds> expected,
873                                                      List<PortExternalIds> test ) {
874
875         if (expected != null) {
876             for (PortExternalIds expectedExternalId : expected) {
877                 Assert.assertTrue("The retrieved ids don't contain " + expectedExternalId,
878                         test.contains(expectedExternalId));
879             }
880         }
881     }
882
883     /*
884      * Tests the CRUD operations for <code>Port</code> <code>external_ids</code>.
885      *
886      * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
887      */
888     @Test
889     public void testCRUDTerminationPointPortExternalIds() throws InterruptedException {
890         final String TEST_PREFIX = "CRUDTPPortExternalIds";
891         final int TERMINATION_POINT_TEST_INDEX = 0;
892
893         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
894         connectOvsdbNode(connectionInfo);
895
896         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
897         // the update has been performed.
898         List<SouthboundTestCase<PortExternalIds>> updateFromTestCases =
899                 generateKeyValueTestCases(new SouthboundPortExternalIdsBuilder(), "PortExternalIdsFrom");
900         List<SouthboundTestCase<PortExternalIds>> updateToTestCases =
901                 generateKeyValueTestCases(new SouthboundPortExternalIdsBuilder(), "PortExternalIdsTo");
902
903         for (SouthboundTestCase<PortExternalIds> updateFromTestCase : updateFromTestCases) {
904             List<PortExternalIds> updateFromInputExternalIds = updateFromTestCase.inputValues;
905             List<PortExternalIds> updateFromExpectedExternalIds = updateFromTestCase.expectedValues;
906             for (SouthboundTestCase<PortExternalIds> updateToTestCase : updateToTestCases) {
907                 String testBridgeAndPortName = String.format("%s_%s", TEST_PREFIX, updateToTestCase.name);
908                 List<PortExternalIds> updateToInputExternalIds = updateToTestCase.inputValues;
909                 List<PortExternalIds> updateToExpectedExternalIds = updateToTestCase.expectedValues;
910
911                 // CREATE: Create the test bridge
912                 Assert.assertTrue(addBridge(connectionInfo, null, testBridgeAndPortName, null, true,
913                         SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null));
914                 NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
915                         connectionInfo, new OvsdbBridgeName(testBridgeAndPortName)));
916                 OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
917                         createGenericOvsdbTerminationPointAugmentationBuilder();
918                 tpCreateAugmentationBuilder.setName(testBridgeAndPortName);
919                 tpCreateAugmentationBuilder.setPortExternalIds(updateFromInputExternalIds);
920                 Assert.assertTrue(
921                         addTerminationPoint(testBridgeNodeId, testBridgeAndPortName, tpCreateAugmentationBuilder));
922
923                 // READ: Read the test port and ensure changes are propagated to the CONFIGURATION data store,
924                 // then repeat for OPERATIONAL data store
925                 OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
926                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
927                                 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
928                 if (updateFromConfigurationTerminationPointAugmentation != null) {
929                     List<PortExternalIds> updateFromConfigurationExternalIds =
930                             updateFromConfigurationTerminationPointAugmentation.getPortExternalIds();
931                     assertExpectedPortExternalIdsExist(updateFromExpectedExternalIds,
932                             updateFromConfigurationExternalIds);
933                 }
934                 OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation =
935                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
936                                 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
937                 if (updateFromOperationalTerminationPointAugmentation != null) {
938                     List<PortExternalIds> updateFromOperationalExternalIds =
939                             updateFromOperationalTerminationPointAugmentation.getPortExternalIds();
940                     assertExpectedPortExternalIdsExist(updateFromExpectedExternalIds, updateFromOperationalExternalIds);
941                 }
942
943                 // UPDATE:  update the external_ids
944                 testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeAndPortName).getNodeId();
945                 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
946                         new OvsdbTerminationPointAugmentationBuilder();
947                 tpUpdateAugmentationBuilder.setPortExternalIds(updateToInputExternalIds);
948                 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
949                 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
950                 NodeId portUpdateNodeId = createManagedNodeId(portIid);
951                 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
952                 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
953                 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testBridgeAndPortName)));
954                 tpUpdateBuilder.addAugmentation(
955                         OvsdbTerminationPointAugmentation.class,
956                         tpUpdateAugmentationBuilder.build());
957                 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
958                 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
959                         portIid, portUpdateNodeBuilder.build()));
960                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
961
962                 // READ: the test port and ensure changes are propagated to the CONFIGURATION data store,
963                 // then repeat for OPERATIONAL data store
964                 OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
965                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
966                                 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
967                 if (updateToConfigurationTerminationPointAugmentation != null) {
968                     List<PortExternalIds> updateToConfigurationExternalIds =
969                             updateToConfigurationTerminationPointAugmentation.getPortExternalIds();
970                     assertExpectedPortExternalIdsExist(updateToExpectedExternalIds, updateToConfigurationExternalIds);
971                     assertExpectedPortExternalIdsExist(updateFromExpectedExternalIds, updateToConfigurationExternalIds);
972                 }
973                 OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
974                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
975                                 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
976                 if (updateToOperationalTerminationPointAugmentation != null) {
977                     List<PortExternalIds> updateToOperationalExternalIds =
978                             updateToOperationalTerminationPointAugmentation.getPortExternalIds();
979                     if (updateFromExpectedExternalIds != null ) {
980                         assertExpectedPortExternalIdsExist(updateToExpectedExternalIds, updateToOperationalExternalIds);
981                         assertExpectedPortExternalIdsExist(updateFromExpectedExternalIds,
982                                 updateToOperationalExternalIds);
983                     }
984                     // testCRUDTerminationPointInterfaceExternalIds()'s null assertion of updateToOperationalExternalIds
985                     // fails here
986                 }
987
988                 // DELETE
989                 Assert.assertTrue(deleteBridge(connectionInfo, testBridgeAndPortName));
990             }
991         }
992         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
993     }
994
995     /*
996      * @see <code>SouthboundIT.testCRUDInterfaceExternalIds()</code>
997      * This is helper test method to compare a test "set" of InterfaceExternalIds against an expected "set"
998      */
999     private void assertExpectedInterfaceExternalIdsExist( List<InterfaceExternalIds> expected,
1000                                                           List<InterfaceExternalIds> test ) {
1001
1002         if (expected != null) {
1003             for (InterfaceExternalIds expectedExternalId : expected) {
1004                 Assert.assertTrue(test.contains(expectedExternalId));
1005             }
1006         }
1007     }
1008
1009     /*
1010      * Tests the CRUD operations for <code>Interface</code> <code>external_ids</code>.
1011      *
1012      * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1013      */
1014     @Test
1015     public void testCRUDTerminationPointInterfaceExternalIds() throws InterruptedException {
1016         final String TEST_PREFIX = "CRUDTPInterfaceExternalIds";
1017         final int TERMINATION_POINT_TEST_INDEX = 0;
1018
1019         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1020         connectOvsdbNode(connectionInfo);
1021
1022         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
1023         // the update has been performed.
1024         List<SouthboundTestCase<InterfaceExternalIds>> updateFromTestCases = generateKeyValueTestCases(
1025                 new SouthboundInterfaceExternalIdsBuilder(), "InterfaceExternalIdsFrom");
1026         List<SouthboundTestCase<InterfaceExternalIds>> updateToTestCases = generateKeyValueTestCases(
1027                 new SouthboundInterfaceExternalIdsBuilder(), "InterfaceExternalIdsTo");
1028
1029         for (SouthboundTestCase<InterfaceExternalIds> updateFromTestCase : updateFromTestCases) {
1030             List<InterfaceExternalIds> updateFromInputExternalIds = updateFromTestCase.inputValues;
1031             List<InterfaceExternalIds> updateFromExpectedExternalIds = updateFromTestCase.expectedValues;
1032             for (SouthboundTestCase<InterfaceExternalIds> updateToTestCase : updateToTestCases) {
1033                 String testBridgeAndPortName = String.format("%s_%s", TEST_PREFIX, updateToTestCase.name);
1034                 List<InterfaceExternalIds> updateToInputExternalIds = updateToTestCase.inputValues;
1035                 List<InterfaceExternalIds> updateToExpectedExternalIds = updateToTestCase.expectedValues;
1036
1037                 // CREATE: Create the test interface
1038                 Assert.assertTrue(addBridge(connectionInfo, null, testBridgeAndPortName, null, true,
1039                         SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null));
1040                 NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
1041                         connectionInfo, new OvsdbBridgeName(testBridgeAndPortName)));
1042                 OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
1043                         createGenericOvsdbTerminationPointAugmentationBuilder();
1044                 tpCreateAugmentationBuilder.setName(testBridgeAndPortName);
1045                 tpCreateAugmentationBuilder.setInterfaceExternalIds(updateFromInputExternalIds);
1046                 Assert.assertTrue(
1047                         addTerminationPoint(testBridgeNodeId, testBridgeAndPortName, tpCreateAugmentationBuilder));
1048
1049                 // READ: Read the test interface and ensure changes are propagated to the CONFIGURATION data store,
1050                 // then repeat for OPERATIONAL data store
1051                 OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
1052                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1053                                 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1054                 if (updateFromConfigurationTerminationPointAugmentation != null) {
1055                     List<InterfaceExternalIds> updateFromConfigurationExternalIds =
1056                             updateFromConfigurationTerminationPointAugmentation.getInterfaceExternalIds();
1057                     assertExpectedInterfaceExternalIdsExist(updateFromExpectedExternalIds,
1058                             updateFromConfigurationExternalIds);
1059                 }
1060                 OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation =
1061                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1062                                 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1063                 if (updateFromOperationalTerminationPointAugmentation != null) {
1064                     List<InterfaceExternalIds> updateFromOperationalExternalIds =
1065                             updateFromOperationalTerminationPointAugmentation.getInterfaceExternalIds();
1066                     assertExpectedInterfaceExternalIdsExist(updateFromExpectedExternalIds,
1067                             updateFromOperationalExternalIds);
1068                 }
1069
1070                 // UPDATE:  update the external_ids
1071                 testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeAndPortName).getNodeId();
1072                 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1073                         new OvsdbTerminationPointAugmentationBuilder();
1074                 tpUpdateAugmentationBuilder.setInterfaceExternalIds(updateToInputExternalIds);
1075                 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1076                 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1077                 NodeId portUpdateNodeId = createManagedNodeId(portIid);
1078                 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1079                 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1080                 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testBridgeAndPortName)));
1081                 tpUpdateBuilder.addAugmentation(
1082                         OvsdbTerminationPointAugmentation.class,
1083                         tpUpdateAugmentationBuilder.build());
1084                 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1085                 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1086                         portIid, portUpdateNodeBuilder.build()));
1087                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1088
1089                 // READ: the test interface and ensure changes are propagated to the CONFIGURATION data store,
1090                 // then repeat for OPERATIONAL data store
1091                 OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
1092                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1093                                 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1094                 if (updateToConfigurationTerminationPointAugmentation != null) {
1095                     List<InterfaceExternalIds> updateToConfigurationExternalIds =
1096                             updateToConfigurationTerminationPointAugmentation.getInterfaceExternalIds();
1097                     assertExpectedInterfaceExternalIdsExist(updateToExpectedExternalIds,
1098                             updateToConfigurationExternalIds);
1099                     assertExpectedInterfaceExternalIdsExist(updateFromExpectedExternalIds,
1100                             updateToConfigurationExternalIds);
1101                 }
1102                 OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
1103                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1104                                 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1105                 if (updateToOperationalTerminationPointAugmentation != null) {
1106                     List<InterfaceExternalIds> updateToOperationalExternalIds =
1107                             updateToOperationalTerminationPointAugmentation.getInterfaceExternalIds();
1108                     if (updateFromExpectedExternalIds != null) {
1109                         assertExpectedInterfaceExternalIdsExist(updateToExpectedExternalIds,
1110                                 updateToOperationalExternalIds);
1111                         assertExpectedInterfaceExternalIdsExist(updateFromExpectedExternalIds,
1112                                 updateToOperationalExternalIds);
1113                     } else {
1114                         Assert.assertNull(updateToOperationalExternalIds);
1115                     }
1116                 }
1117
1118                 // DELETE
1119                 Assert.assertTrue(deleteBridge(connectionInfo, testBridgeAndPortName));
1120             }
1121         }
1122         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1123     }
1124
1125     /*
1126      * @see <code>SouthboundIT.testCRUDTerminationPointOptions()</code>
1127      * This is helper test method to compare a test "set" of Options against an expected "set"
1128      */
1129     private void assertExpectedOptionsExist( List<Options> expected,
1130                                              List<Options> test ) {
1131
1132         if (expected != null) {
1133             for (Options expectedOption : expected) {
1134                 Assert.assertTrue(test.contains(expectedOption));
1135             }
1136         }
1137     }
1138
1139     /*
1140      * Tests the CRUD operations for <code>TerminationPoint</code> <code>options</code>.
1141      *
1142      * @see <code>SouthboundIT.generateTerminationPointOptions()</code> for specific test case information
1143      */
1144     @Test
1145     public void testCRUDTerminationPointOptions() throws InterruptedException {
1146         final String TEST_PREFIX = "CRUDTPOptions";
1147         final int TERMINATION_POINT_TEST_INDEX = 0;
1148
1149         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1150         connectOvsdbNode(connectionInfo);
1151
1152         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
1153         // the update has been performed.
1154         List<SouthboundTestCase<Options>> updateFromTestCases =
1155                 generateKeyValueTestCases(new SouthboundOptionsBuilder(), "OptionsFrom");
1156         List<SouthboundTestCase<Options>> updateToTestCases = generateKeyValueTestCases(new SouthboundOptionsBuilder(),
1157                 "OptionsTo");
1158
1159         for (SouthboundTestCase<Options> updateFromTestCase : updateFromTestCases) {
1160             List<Options> updateFromInputOptions = updateFromTestCase.inputValues;
1161             List<Options> updateFromExpectedOptions = updateFromTestCase.expectedValues;
1162             for (SouthboundTestCase<Options> updateToTestCase : updateToTestCases) {
1163                 String testBridgeAndPortName = String.format("%s_%s", TEST_PREFIX, updateToTestCase.name);
1164                 List<Options> updateToInputOptions = updateToTestCase.inputValues;
1165                 List<Options> updateToExpectedOptions = updateToTestCase.expectedValues;
1166
1167                 // CREATE: Create the test interface
1168                 Assert.assertTrue(addBridge(connectionInfo, null, testBridgeAndPortName, null, true,
1169                         SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null));
1170                 NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
1171                         connectionInfo, new OvsdbBridgeName(testBridgeAndPortName)));
1172                 OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
1173                         createGenericOvsdbTerminationPointAugmentationBuilder();
1174                 tpCreateAugmentationBuilder.setName(testBridgeAndPortName);
1175                 tpCreateAugmentationBuilder.setOptions(updateFromInputOptions);
1176                 Assert.assertTrue(
1177                         addTerminationPoint(testBridgeNodeId, testBridgeAndPortName, tpCreateAugmentationBuilder));
1178
1179                 // READ: Read the test interface and ensure changes are propagated to the CONFIGURATION data store,
1180                 // then repeat for OPERATIONAL data store
1181                 OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
1182                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1183                                 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1184                 if (updateFromConfigurationTerminationPointAugmentation != null) {
1185                     List<Options> updateFromConfigurationOptions =
1186                             updateFromConfigurationTerminationPointAugmentation.getOptions();
1187                     assertExpectedOptionsExist(updateFromExpectedOptions, updateFromConfigurationOptions);
1188                 }
1189                 OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation =
1190                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1191                                 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1192                 if (updateFromOperationalTerminationPointAugmentation != null) {
1193                     List<Options> updateFromOperationalOptions =
1194                             updateFromOperationalTerminationPointAugmentation.getOptions();
1195                     assertExpectedOptionsExist(updateFromExpectedOptions, updateFromOperationalOptions);
1196                 }
1197
1198                 // UPDATE:  update the external_ids
1199                 testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeAndPortName).getNodeId();
1200                 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1201                         new OvsdbTerminationPointAugmentationBuilder();
1202                 tpUpdateAugmentationBuilder.setOptions(updateToInputOptions);
1203                 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1204                 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1205                 NodeId portUpdateNodeId = createManagedNodeId(portIid);
1206                 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1207                 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1208                 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testBridgeAndPortName)));
1209                 tpUpdateBuilder.addAugmentation(
1210                         OvsdbTerminationPointAugmentation.class,
1211                         tpUpdateAugmentationBuilder.build());
1212                 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1213                 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1214                         portIid, portUpdateNodeBuilder.build()));
1215                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1216
1217                 // READ: the test interface and ensure changes are propagated to the CONFIGURATION data store,
1218                 // then repeat for OPERATIONAL data store
1219                 OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
1220                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1221                                 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1222                 if (updateToConfigurationTerminationPointAugmentation != null) {
1223                     List<Options> updateToConfigurationOptions =
1224                             updateToConfigurationTerminationPointAugmentation.getOptions();
1225                     assertExpectedOptionsExist(updateToExpectedOptions, updateToConfigurationOptions);
1226                     assertExpectedOptionsExist(updateFromExpectedOptions, updateToConfigurationOptions);
1227                 }
1228                 OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
1229                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1230                                 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1231                 if (updateToOperationalTerminationPointAugmentation != null) {
1232                     List<Options> updateToOperationalOptions =
1233                             updateToOperationalTerminationPointAugmentation.getOptions();
1234                     if (updateFromExpectedOptions != null) {
1235                         assertExpectedOptionsExist(updateToExpectedOptions, updateToOperationalOptions);
1236                         assertExpectedOptionsExist(updateFromExpectedOptions, updateToOperationalOptions);
1237                     }
1238                 }
1239
1240                 // DELETE
1241                 Assert.assertTrue(deleteBridge(connectionInfo, testBridgeAndPortName));
1242             }
1243         }
1244         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1245     }
1246
1247     /*
1248      * @see <code>SouthboundIT.testCRUDInterfaceOtherConfigs()</code>
1249      * This is helper test method to compare a test "set" of Options against an expected "set"
1250      */
1251     private void assertExpectedInterfaceOtherConfigsExist( List<InterfaceOtherConfigs> expected,
1252                                                            List<InterfaceOtherConfigs> test ) {
1253
1254         if (expected != null && test != null) {
1255             for (InterfaceOtherConfigs expectedOtherConfigs : expected) {
1256                 Assert.assertTrue(test.contains(expectedOtherConfigs));
1257             }
1258         }
1259     }
1260
1261     /*
1262      * Tests the CRUD operations for <code>Interface</code> <code>other_configs</code>.
1263      *
1264      * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1265      */
1266     @Test
1267     public void testCRUDTerminationPointInterfaceOtherConfigs() throws InterruptedException {
1268         final String TEST_PREFIX = "CRUDTPInterfaceOtherConfigs";
1269         final int TERMINATION_POINT_TEST_INDEX = 0;
1270
1271         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1272         connectOvsdbNode(connectionInfo);
1273
1274         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
1275         // the update has been performed.
1276         List<SouthboundTestCase<InterfaceOtherConfigs>> updateFromTestCases =
1277                 generateKeyValueTestCases(new SouthboundInterfaceOtherConfigsBuilder(), "InterfaceOtherConfigsFrom");
1278         List<SouthboundTestCase<InterfaceOtherConfigs>> updateToTestCases =
1279                 generateKeyValueTestCases(new SouthboundInterfaceOtherConfigsBuilder(), "InterfaceOtherConfigsTo");
1280
1281         for (SouthboundTestCase<InterfaceOtherConfigs> updateFromTestCase : updateFromTestCases) {
1282             List<InterfaceOtherConfigs> updateFromInputOtherConfigs = updateFromTestCase.inputValues;
1283             List<InterfaceOtherConfigs> updateFromExpectedOtherConfigs = updateFromTestCase.expectedValues;
1284             for (SouthboundTestCase<InterfaceOtherConfigs> updateToTestCase : updateToTestCases) {
1285                 String testBridgeAndPortName = String.format("%s_%s", TEST_PREFIX, updateToTestCase.name);
1286                 List<InterfaceOtherConfigs> updateToInputOtherConfigs = updateToTestCase.inputValues;
1287                 List<InterfaceOtherConfigs> updateToExpectedOtherConfigs = updateToTestCase.expectedValues;
1288
1289                 // CREATE: Create the test interface
1290                 Assert.assertTrue(addBridge(connectionInfo, null, testBridgeAndPortName, null, true,
1291                         SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null));
1292                 NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
1293                         connectionInfo, new OvsdbBridgeName(testBridgeAndPortName)));
1294                 OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
1295                         createGenericOvsdbTerminationPointAugmentationBuilder();
1296                 tpCreateAugmentationBuilder.setName(testBridgeAndPortName);
1297                 tpCreateAugmentationBuilder.setInterfaceOtherConfigs(updateFromInputOtherConfigs);
1298                 Assert.assertTrue(
1299                         addTerminationPoint(testBridgeNodeId, testBridgeAndPortName, tpCreateAugmentationBuilder));
1300
1301                 // READ: Read the test interface and ensure changes are propagated to the CONFIGURATION data store,
1302                 // then repeat for OPERATIONAL data store
1303                 OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
1304                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1305                                 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1306                 if (updateFromConfigurationTerminationPointAugmentation != null) {
1307                     List<InterfaceOtherConfigs> updateFromConfigurationOtherConfigs =
1308                             updateFromConfigurationTerminationPointAugmentation.getInterfaceOtherConfigs();
1309                     assertExpectedInterfaceOtherConfigsExist(updateFromExpectedOtherConfigs,
1310                             updateFromConfigurationOtherConfigs);
1311                 }
1312                 OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation =
1313                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1314                                 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1315                 if (updateFromOperationalTerminationPointAugmentation != null) {
1316                     List<InterfaceOtherConfigs> updateFromOperationalOtherConfigs =
1317                             updateFromOperationalTerminationPointAugmentation.getInterfaceOtherConfigs();
1318                     assertExpectedInterfaceOtherConfigsExist(updateFromExpectedOtherConfigs,
1319                             updateFromOperationalOtherConfigs);
1320                 }
1321
1322                 // UPDATE:  update the other_configs
1323                 testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeAndPortName).getNodeId();
1324                 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1325                         new OvsdbTerminationPointAugmentationBuilder();
1326                 tpUpdateAugmentationBuilder.setInterfaceOtherConfigs(updateToInputOtherConfigs);
1327                 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1328                 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1329                 NodeId portUpdateNodeId = createManagedNodeId(portIid);
1330                 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1331                 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1332                 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testBridgeAndPortName)));
1333                 tpUpdateBuilder.addAugmentation(
1334                         OvsdbTerminationPointAugmentation.class,
1335                         tpUpdateAugmentationBuilder.build());
1336                 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1337                 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1338                         portIid, portUpdateNodeBuilder.build()));
1339                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1340
1341                 // READ: the test interface and ensure changes are propagated to the CONFIGURATION data store,
1342                 // then repeat for OPERATIONAL data store
1343                 OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
1344                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1345                                 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1346                 if (updateToConfigurationTerminationPointAugmentation != null) {
1347                     List<InterfaceOtherConfigs> updateToConfigurationOtherConfigs =
1348                             updateToConfigurationTerminationPointAugmentation.getInterfaceOtherConfigs();
1349                     assertExpectedInterfaceOtherConfigsExist(updateToExpectedOtherConfigs,
1350                             updateToConfigurationOtherConfigs);
1351                     assertExpectedInterfaceOtherConfigsExist(updateFromExpectedOtherConfigs,
1352                             updateToConfigurationOtherConfigs);
1353                 }
1354                 OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
1355                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1356                                 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1357                 if (updateToOperationalTerminationPointAugmentation != null) {
1358                     List<InterfaceOtherConfigs> updateToOperationalOtherConfigs =
1359                             updateToOperationalTerminationPointAugmentation.getInterfaceOtherConfigs();
1360                     if (updateFromExpectedOtherConfigs != null) {
1361                         assertExpectedInterfaceOtherConfigsExist(updateToExpectedOtherConfigs,
1362                                 updateToOperationalOtherConfigs);
1363                         assertExpectedInterfaceOtherConfigsExist(updateFromExpectedOtherConfigs,
1364                                 updateToOperationalOtherConfigs);
1365                     }
1366                 }
1367
1368                 // DELETE
1369                 Assert.assertTrue(deleteBridge(connectionInfo, testBridgeAndPortName));
1370             }
1371         }
1372         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1373     }
1374
1375     /*
1376      * @see <code>SouthboundIT.testCRUDPortOtherConfigs()</code>
1377      * This is helper test method to compare a test "set" of Options against an expected "set"
1378      */
1379     private void assertExpectedPortOtherConfigsExist( List<PortOtherConfigs> expected,
1380                                                       List<PortOtherConfigs> test ) {
1381
1382         if (expected != null && test != null) {
1383             for (PortOtherConfigs expectedOtherConfigs : expected) {
1384                 Assert.assertTrue(test.contains(expectedOtherConfigs));
1385             }
1386         }
1387     }
1388
1389     /*
1390      * Tests the CRUD operations for <code>Port</code> <code>other_configs</code>.
1391      *
1392      * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
1393      */
1394     @Test
1395     public void testCRUDTerminationPointPortOtherConfigs() throws InterruptedException {
1396         final String TEST_PREFIX = "CRUDTPPortOtherConfigs";
1397         final int TERMINATION_POINT_TEST_INDEX = 0;
1398
1399         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1400         connectOvsdbNode(connectionInfo);
1401
1402         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
1403         // the update has been performed.
1404         List<SouthboundTestCase<PortOtherConfigs>> updateFromTestCases =
1405                 generateKeyValueTestCases(new SouthboundPortOtherConfigsBuilder(), "PortOtherConfigsFrom");
1406         List<SouthboundTestCase<PortOtherConfigs>> updateToTestCases =
1407                 generateKeyValueTestCases(new SouthboundPortOtherConfigsBuilder(), "PortOtherConfigsTo");
1408
1409         for (SouthboundTestCase<PortOtherConfigs> updateFromTestCase : updateFromTestCases) {
1410             List<PortOtherConfigs> updateFromInputOtherConfigs = updateFromTestCase.inputValues;
1411             List<PortOtherConfigs> updateFromExpectedOtherConfigs = updateFromTestCase.expectedValues;
1412             for (SouthboundTestCase<PortOtherConfigs> updateToTestCase : updateToTestCases) {
1413                 String testBridgeAndPortName = String.format("%s_%s", TEST_PREFIX, updateToTestCase.name);
1414                 List<PortOtherConfigs> updateToInputOtherConfigs = updateToTestCase.inputValues;
1415                 List<PortOtherConfigs> updateToExpectedOtherConfigs = updateToTestCase.expectedValues;
1416
1417                 // CREATE: Create the test port
1418                 Assert.assertTrue(addBridge(connectionInfo, null, testBridgeAndPortName, null, true,
1419                         SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null));
1420                 NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
1421                         connectionInfo, new OvsdbBridgeName(testBridgeAndPortName)));
1422                 OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
1423                         createGenericOvsdbTerminationPointAugmentationBuilder();
1424                 tpCreateAugmentationBuilder.setName(testBridgeAndPortName);
1425                 tpCreateAugmentationBuilder.setPortOtherConfigs(updateFromInputOtherConfigs);
1426                 Assert.assertTrue(
1427                         addTerminationPoint(testBridgeNodeId, testBridgeAndPortName, tpCreateAugmentationBuilder));
1428
1429                 // READ: Read the test port and ensure changes are propagated to the CONFIGURATION data store,
1430                 // then repeat for OPERATIONAL data store
1431                 OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
1432                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1433                                 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1434                 if (updateFromConfigurationTerminationPointAugmentation != null) {
1435                     List<PortOtherConfigs> updateFromConfigurationOtherConfigs =
1436                             updateFromConfigurationTerminationPointAugmentation.getPortOtherConfigs();
1437                     assertExpectedPortOtherConfigsExist(updateFromExpectedOtherConfigs,
1438                             updateFromConfigurationOtherConfigs);
1439                 }
1440                 OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation =
1441                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1442                                 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1443                 if (updateFromOperationalTerminationPointAugmentation != null) {
1444                     List<PortOtherConfigs> updateFromOperationalOtherConfigs =
1445                             updateFromOperationalTerminationPointAugmentation.getPortOtherConfigs();
1446                     assertExpectedPortOtherConfigsExist(updateFromExpectedOtherConfigs,
1447                             updateFromOperationalOtherConfigs);
1448                 }
1449
1450                 // UPDATE:  update the other_configs
1451                 testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeAndPortName).getNodeId();
1452                 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1453                         new OvsdbTerminationPointAugmentationBuilder();
1454                 tpUpdateAugmentationBuilder.setPortOtherConfigs(updateToInputOtherConfigs);
1455                 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1456                 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1457                 NodeId portUpdateNodeId = createManagedNodeId(portIid);
1458                 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1459                 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1460                 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testBridgeAndPortName)));
1461                 tpUpdateBuilder.addAugmentation(
1462                         OvsdbTerminationPointAugmentation.class,
1463                         tpUpdateAugmentationBuilder.build());
1464                 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1465                 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1466                         portIid, portUpdateNodeBuilder.build()));
1467                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1468
1469                 // READ: the test port and ensure changes are propagated to the CONFIGURATION data store,
1470                 // then repeat for OPERATIONAL data store
1471                 OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
1472                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1473                                 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1474                 if (updateToConfigurationTerminationPointAugmentation != null) {
1475                     List<PortOtherConfigs> updateToConfigurationOtherConfigs =
1476                             updateToConfigurationTerminationPointAugmentation.getPortOtherConfigs();
1477                     assertExpectedPortOtherConfigsExist(updateToExpectedOtherConfigs,
1478                             updateToConfigurationOtherConfigs);
1479                     assertExpectedPortOtherConfigsExist(updateFromExpectedOtherConfigs,
1480                             updateToConfigurationOtherConfigs);
1481                 }
1482                 OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
1483                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1484                                 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1485                 if (updateToOperationalTerminationPointAugmentation != null) {
1486                     List<PortOtherConfigs> updateToOperationalOtherConfigs =
1487                             updateToOperationalTerminationPointAugmentation.getPortOtherConfigs();
1488                     if (updateFromExpectedOtherConfigs != null) {
1489                         assertExpectedPortOtherConfigsExist(updateToExpectedOtherConfigs,
1490                                 updateToOperationalOtherConfigs);
1491                         assertExpectedPortOtherConfigsExist(updateFromExpectedOtherConfigs,
1492                                 updateToOperationalOtherConfigs);
1493                     }
1494                 }
1495
1496                 // DELETE
1497                 Assert.assertTrue(deleteBridge(connectionInfo, testBridgeAndPortName));
1498             }
1499         }
1500         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1501     }
1502
1503     @Test
1504     public void testCRUDTerminationPointVlan() throws InterruptedException {
1505         final Integer CREATED_VLAN_ID = 4000;
1506         final Integer UPDATED_VLAN_ID = 4001;
1507
1508         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1509         connectOvsdbNode(connectionInfo);
1510
1511         // CREATE
1512         Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
1513         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1514         Assert.assertNotNull(bridge);
1515         NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
1516                 connectionInfo, bridge.getBridgeName()));
1517         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1518                 createGenericOvsdbTerminationPointAugmentationBuilder();
1519         String portName = "testTerminationPointVlanId";
1520         ovsdbTerminationBuilder.setName(portName);
1521         ovsdbTerminationBuilder.setVlanTag(new VlanId(CREATED_VLAN_ID));
1522         Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1523         InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1524         Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1525         Assert.assertNotNull(terminationPointNode);
1526
1527         // READ
1528         List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1529         OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation;
1530         for (TerminationPoint terminationPoint : terminationPoints) {
1531             ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
1532                     OvsdbTerminationPointAugmentation.class);
1533             if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1534                 VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
1535                 Assert.assertNotNull(actualVlanId);
1536                 Integer actualVlanIdInt = actualVlanId.getValue();
1537                 Assert.assertEquals(CREATED_VLAN_ID, actualVlanIdInt);
1538             }
1539         }
1540
1541         // UPDATE
1542         NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1543         OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1544                 new OvsdbTerminationPointAugmentationBuilder();
1545         tpUpdateAugmentationBuilder.setVlanTag(new VlanId(UPDATED_VLAN_ID));
1546         InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1547         NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1548         NodeId portUpdateNodeId = createManagedNodeId(portIid);
1549         portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1550         TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1551         tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1552         tpUpdateBuilder.addAugmentation(
1553                 OvsdbTerminationPointAugmentation.class,
1554                 tpUpdateAugmentationBuilder.build());
1555         tpUpdateBuilder.setTpId(new TpId(portName));
1556         portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1557         boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1558                 portIid, portUpdateNodeBuilder.build());
1559         Assert.assertTrue(result);
1560         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1561
1562         terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1563         terminationPoints = terminationPointNode.getTerminationPoint();
1564         for (TerminationPoint terminationPoint : terminationPoints) {
1565             ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
1566                     OvsdbTerminationPointAugmentation.class);
1567             if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1568                 VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
1569                 Assert.assertNotNull(actualVlanId);
1570                 Integer actualVlanIdInt = actualVlanId.getValue();
1571                 Assert.assertEquals(UPDATED_VLAN_ID, actualVlanIdInt);
1572             }
1573         }
1574
1575         // DELETE
1576         Assert.assertTrue(deleteBridge(connectionInfo));
1577         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1578     }
1579
1580     @Test
1581     public void testCRUDTerminationPointVlanModes() throws InterruptedException {
1582         final VlanMode UPDATED_VLAN_MODE = VlanMode.Access;
1583         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1584         connectOvsdbNode(connectionInfo);
1585         VlanMode []vlanModes = VlanMode.values();
1586         for (VlanMode vlanMode : vlanModes) {
1587             // CREATE
1588             Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
1589             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1590             Assert.assertNotNull(bridge);
1591             NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
1592                     connectionInfo, bridge.getBridgeName()));
1593             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1594                     createGenericOvsdbTerminationPointAugmentationBuilder();
1595             String portName = "testTerminationPointVlanMode" + vlanMode.toString();
1596             ovsdbTerminationBuilder.setName(portName);
1597             ovsdbTerminationBuilder.setVlanMode(vlanMode);
1598             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1599             InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1600             Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1601             Assert.assertNotNull(terminationPointNode);
1602
1603             // READ
1604             List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1605             for (TerminationPoint terminationPoint : terminationPoints) {
1606                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1607                         terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1608                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1609                     //test
1610                     Assert.assertTrue(ovsdbTerminationPointAugmentation.getVlanMode().equals(vlanMode));
1611                 }
1612             }
1613
1614             // UPDATE
1615             NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1616             OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1617                     new OvsdbTerminationPointAugmentationBuilder();
1618             tpUpdateAugmentationBuilder.setVlanMode(UPDATED_VLAN_MODE);
1619             InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1620             NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1621             NodeId portUpdateNodeId = createManagedNodeId(portIid);
1622             portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1623             TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1624             tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1625             tpUpdateBuilder.addAugmentation(
1626                     OvsdbTerminationPointAugmentation.class,
1627                     tpUpdateAugmentationBuilder.build());
1628             tpUpdateBuilder.setTpId(new TpId(portName));
1629             portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1630             boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1631                     portIid, portUpdateNodeBuilder.build());
1632             Assert.assertTrue(result);
1633             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1634
1635             terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1636             terminationPoints = terminationPointNode.getTerminationPoint();
1637             for (TerminationPoint terminationPoint : terminationPoints) {
1638                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1639                         terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1640                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1641                     //test
1642                     Assert.assertEquals(UPDATED_VLAN_MODE, ovsdbTerminationPointAugmentation.getVlanMode());
1643                 }
1644             }
1645
1646             // DELETE
1647             Assert.assertTrue(deleteBridge(connectionInfo));
1648         }
1649         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1650     }
1651
1652     @SuppressWarnings("unchecked")
1653     private List<Set<Integer>> generateVlanSets() {
1654         int min = 0;
1655         int max = 4095;
1656         return Lists.newArrayList(
1657                 Collections.<Integer>emptySet(),
1658                 Sets.newHashSet(2222),
1659                 Sets.newHashSet(min, max, min + 1, max - 1, (max - min) / 2));
1660     }
1661
1662     private List<Trunks> buildTrunkList(Set<Integer> trunkSet) {
1663         List<Trunks> trunkList = Lists.newArrayList();
1664         for (Integer trunk : trunkSet) {
1665             TrunksBuilder trunkBuilder = new TrunksBuilder();
1666             trunkBuilder.setTrunk(new VlanId(trunk));
1667             trunkList.add(trunkBuilder.build());
1668         }
1669         return trunkList;
1670     }
1671
1672     @Test
1673     public void testCRUDTerminationPointVlanTrunks() throws InterruptedException {
1674         final List<Trunks> UPDATED_TRUNKS = buildTrunkList(Sets.newHashSet(2011));
1675         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1676         connectOvsdbNode(connectionInfo);
1677         Iterable<Set<Integer>> vlanSets = generateVlanSets();
1678         int testCase = 0;
1679         for (Set<Integer> vlanSet : vlanSets) {
1680             ++testCase;
1681             // CREATE
1682             Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
1683             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1684             Assert.assertNotNull(bridge);
1685             NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
1686                     connectionInfo, bridge.getBridgeName()));
1687             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1688                     createGenericOvsdbTerminationPointAugmentationBuilder();
1689             String portName = "testTerminationPointVlanTrunks" + testCase;
1690             ovsdbTerminationBuilder.setName(portName);
1691             List<Trunks> trunks = buildTrunkList(vlanSet);
1692             ovsdbTerminationBuilder.setTrunks(trunks);
1693             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1694             InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1695             Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1696             Assert.assertNotNull(terminationPointNode);
1697
1698             // READ
1699             List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1700             for (TerminationPoint terminationPoint : terminationPoints) {
1701                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1702                         terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1703                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1704                     List<Trunks> actualTrunks = ovsdbTerminationPointAugmentation.getTrunks();
1705                     for (Trunks trunk : trunks) {
1706                         Assert.assertTrue(actualTrunks.contains(trunk));
1707                     }
1708                 }
1709             }
1710
1711
1712             // UPDATE
1713             NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1714             OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1715                     new OvsdbTerminationPointAugmentationBuilder();
1716             tpUpdateAugmentationBuilder.setTrunks(UPDATED_TRUNKS);
1717             InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1718             NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1719             NodeId portUpdateNodeId = createManagedNodeId(portIid);
1720             portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1721             TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1722             tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1723             tpUpdateBuilder.addAugmentation(
1724                     OvsdbTerminationPointAugmentation.class,
1725                     tpUpdateAugmentationBuilder.build());
1726             tpUpdateBuilder.setTpId(new TpId(portName));
1727             portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1728             boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1729                     portIid, portUpdateNodeBuilder.build());
1730             Assert.assertTrue(result);
1731             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1732
1733             terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1734             terminationPoints = terminationPointNode.getTerminationPoint();
1735             for (TerminationPoint terminationPoint : terminationPoints) {
1736                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1737                         terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1738                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1739                     //test
1740                     Assert.assertEquals(UPDATED_TRUNKS, ovsdbTerminationPointAugmentation.getTrunks());
1741                 }
1742             }
1743
1744             // DELETE
1745             Assert.assertTrue(deleteBridge(connectionInfo));
1746         }
1747         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1748     }
1749
1750     @Test
1751     public void testGetOvsdbNodes() throws InterruptedException {
1752         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1753         connectOvsdbNode(connectionInfo);
1754         InstanceIdentifier<Topology> topologyPath = InstanceIdentifier
1755                 .create(NetworkTopology.class)
1756                 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
1757
1758         Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, topologyPath);
1759         InstanceIdentifier<Node> expectedNodeIid = createInstanceIdentifier(connectionInfo);
1760         NodeId expectedNodeId = expectedNodeIid.firstKeyOf(Node.class, NodeKey.class).getNodeId();
1761         Node foundNode = null;
1762         Assert.assertNotNull("Expected to find topology: " + topologyPath, topology);
1763         Assert.assertNotNull("Expected to find some nodes" + topology.getNode());
1764         LOG.info("expectedNodeId: {}, getNode: {}", expectedNodeId, topology.getNode());
1765         for (Node node : topology.getNode()) {
1766             if (node.getNodeId().getValue().equals(expectedNodeId.getValue())) {
1767                 foundNode = node;
1768                 break;
1769             }
1770         }
1771         Assert.assertNotNull("Expected to find Node: " + expectedNodeId, foundNode);
1772         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1773     }
1774
1775     /*
1776      * @see <code>SouthboundIT.testCRUDBridgeOtherConfigs()</code>
1777      * This is helper test method to compare a test "set" of BridgeExternalIds against an expected "set"
1778      */
1779     private void assertExpectedBridgeOtherConfigsExist( List<BridgeOtherConfigs> expected,
1780                                                         List<BridgeOtherConfigs> test ) {
1781
1782         if (expected != null) {
1783             for (BridgeOtherConfigs expectedOtherConfig : expected) {
1784                 Assert.assertTrue(test.contains(expectedOtherConfig));
1785             }
1786         }
1787     }
1788
1789     /*
1790      * @see <code>SouthboundIT.generateBridgeOtherConfigsTestCases()</code> for specific test case information.
1791      */
1792     @Test
1793     public void testCRUDBridgeOtherConfigs() throws InterruptedException {
1794         final String TEST_BRIDGE_PREFIX = "CRUDBridgeOtherConfigs";
1795         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1796         connectOvsdbNode(connectionInfo);
1797         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
1798         // the update has been performed.
1799         List<SouthboundTestCase<BridgeOtherConfigs>> updateFromTestCases =
1800                 generateKeyValueTestCases(new SouthboundBridgeOtherConfigsBuilder(), "BridgeOtherConfigsFrom");
1801         List<SouthboundTestCase<BridgeOtherConfigs>> updateToTestCases = generateKeyValueTestCases(
1802                 new SouthboundBridgeOtherConfigsBuilder(), "BridgeOtherConfigsTo");
1803         for (SouthboundTestCase<BridgeOtherConfigs> updateFromTestCase : updateFromTestCases) {
1804             List<BridgeOtherConfigs> updateFromInputOtherConfigs = updateFromTestCase.inputValues;
1805             List<BridgeOtherConfigs> updateFromExpectedOtherConfigs = updateFromTestCase.expectedValues;
1806             for (SouthboundTestCase<BridgeOtherConfigs> updateToTestCase : updateToTestCases) {
1807                 String testBridgeName = String.format("%s_%s", TEST_BRIDGE_PREFIX, updateToTestCase.name);
1808                 List<BridgeOtherConfigs> updateToInputOtherConfigs = updateToTestCase.inputValues;
1809                 List<BridgeOtherConfigs> updateToExpectedOtherConfigs = updateToTestCase.expectedValues;
1810
1811                 // CREATE: Create the test bridge
1812                 boolean bridgeAdded = addBridge(connectionInfo, null,
1813                         testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
1814                         true, null, null, null, updateFromInputOtherConfigs);
1815                 Assert.assertTrue(bridgeAdded);
1816
1817                 // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
1818                 // then repeat for OPERATIONAL data store
1819                 List<BridgeOtherConfigs> updateFromConfigurationOtherConfigs = getBridge(connectionInfo, testBridgeName,
1820                         LogicalDatastoreType.CONFIGURATION).getBridgeOtherConfigs();
1821                 assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
1822                         updateFromConfigurationOtherConfigs);
1823                 List<BridgeOtherConfigs> updateFromOperationalOtherConfigs = getBridge(connectionInfo, testBridgeName).getBridgeOtherConfigs();
1824                 assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
1825                         updateFromOperationalOtherConfigs);
1826
1827                 // UPDATE:  update the external_ids
1828                 OvsdbBridgeAugmentationBuilder bridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
1829                 bridgeAugmentationBuilder.setBridgeOtherConfigs(updateToInputOtherConfigs);
1830                 InstanceIdentifier<Node> bridgeIid =
1831                         createInstanceIdentifier(connectionInfo,
1832                                 new OvsdbBridgeName(testBridgeName));
1833                 NodeBuilder bridgeNodeBuilder = new NodeBuilder();
1834                 Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
1835                 bridgeNodeBuilder.setNodeId(bridgeNode.getNodeId());
1836                 bridgeNodeBuilder.setKey(bridgeNode.getKey());
1837                 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, bridgeAugmentationBuilder.build());
1838                 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
1839                         bridgeNodeBuilder.build());
1840                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1841                 Assert.assertTrue(result);
1842
1843                 // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
1844                 // then repeat for OPERATIONAL data store
1845                 List<BridgeOtherConfigs> updateToConfigurationOtherConfigs = getBridge(connectionInfo, testBridgeName,
1846                         LogicalDatastoreType.CONFIGURATION).getBridgeOtherConfigs();
1847                 assertExpectedBridgeOtherConfigsExist(updateToExpectedOtherConfigs, updateToConfigurationOtherConfigs);
1848                 assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
1849                         updateToConfigurationOtherConfigs);
1850                 List<BridgeOtherConfigs> updateToOperationalOtherConfigs = getBridge(connectionInfo, testBridgeName)
1851                         .getBridgeOtherConfigs();
1852                 if (updateFromExpectedOtherConfigs != null) {
1853                     assertExpectedBridgeOtherConfigsExist(updateToExpectedOtherConfigs,
1854                             updateToOperationalOtherConfigs);
1855                     assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
1856                             updateToOperationalOtherConfigs);
1857                 }
1858
1859                 // DELETE
1860                 Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
1861             }
1862         }
1863         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1864     }
1865
1866     /*
1867      * @see <code>SouthboundIT.testCRUDBridgeExternalIds()</code>
1868      * This is helper test method to compare a test "set" of BridgeExternalIds against an expected "set"
1869      */
1870     private void assertExpectedBridgeExternalIdsExist( List<BridgeExternalIds> expected,
1871                                                        List<BridgeExternalIds> test ) {
1872
1873         if (expected != null) {
1874             for (BridgeExternalIds expectedExternalId : expected) {
1875                 Assert.assertTrue(test.contains(expectedExternalId));
1876             }
1877         }
1878     }
1879
1880     /*
1881      * @see <code>SouthboundIT.generateBridgeExternalIdsTestCases()</code> for specific test case information
1882      */
1883     @Test
1884     public void testCRUDBridgeExternalIds() throws InterruptedException {
1885         final String TEST_BRIDGE_PREFIX = "CRUDBridgeExternalIds";
1886         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1887         connectOvsdbNode(connectionInfo);
1888         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
1889         // the update has been performed.
1890         List<SouthboundTestCase<BridgeExternalIds>> updateFromTestCases = generateKeyValueTestCases(
1891                 new SouthboundBridgeExternalIdsBuilder(), "BridgeExternalIdsFrom");
1892         List<SouthboundTestCase<BridgeExternalIds>> updateToTestCases = generateKeyValueTestCases(
1893                 new SouthboundBridgeExternalIdsBuilder(), "BridgeExternalIdsTo");
1894         for (SouthboundTestCase<BridgeExternalIds> updateFromTestCase : updateFromTestCases) {
1895             List<BridgeExternalIds> updateFromInputExternalIds = updateFromTestCase.inputValues;
1896             List<BridgeExternalIds> updateFromExpectedExternalIds = updateFromTestCase.expectedValues;
1897             for (SouthboundTestCase<BridgeExternalIds> updateToTestCase : updateToTestCases) {
1898                 String testBridgeName = String.format("%s_%s", TEST_BRIDGE_PREFIX, updateToTestCase.name);
1899                 List<BridgeExternalIds> updateToInputExternalIds = updateToTestCase.inputValues;
1900                 List<BridgeExternalIds> updateToExpectedExternalIds = updateToTestCase.expectedValues;
1901
1902                 // CREATE: Create the test bridge
1903                 boolean bridgeAdded = addBridge(connectionInfo, null,
1904                         testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
1905                         true, null, updateFromInputExternalIds, null, null);
1906                 Assert.assertTrue(bridgeAdded);
1907
1908                 // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
1909                 // then repeat for OPERATIONAL data store
1910                 List<BridgeExternalIds> updateFromConfigurationExternalIds = getBridge(connectionInfo, testBridgeName,
1911                         LogicalDatastoreType.CONFIGURATION).getBridgeExternalIds();
1912                 assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateFromConfigurationExternalIds);
1913                 List<BridgeExternalIds> updateFromOperationalExternalIds = getBridge(connectionInfo, testBridgeName).getBridgeExternalIds();
1914                 assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateFromOperationalExternalIds);
1915
1916                 // UPDATE:  update the external_ids
1917                 OvsdbBridgeAugmentationBuilder bridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
1918                 bridgeAugmentationBuilder.setBridgeExternalIds(updateToInputExternalIds);
1919                 InstanceIdentifier<Node> bridgeIid =
1920                         createInstanceIdentifier(connectionInfo,
1921                                 new OvsdbBridgeName(testBridgeName));
1922                 NodeBuilder bridgeNodeBuilder = new NodeBuilder();
1923                 Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
1924                 bridgeNodeBuilder.setNodeId(bridgeNode.getNodeId());
1925                 bridgeNodeBuilder.setKey(bridgeNode.getKey());
1926                 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, bridgeAugmentationBuilder.build());
1927                 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
1928                         bridgeNodeBuilder.build());
1929                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1930                 Assert.assertTrue(result);
1931
1932                 // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
1933                 // then repeat for OPERATIONAL data store
1934                 List<BridgeExternalIds> updateToConfigurationExternalIds = getBridge(connectionInfo, testBridgeName,
1935                         LogicalDatastoreType.CONFIGURATION).getBridgeExternalIds();
1936                 assertExpectedBridgeExternalIdsExist(updateToExpectedExternalIds, updateToConfigurationExternalIds);
1937                 assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateToConfigurationExternalIds);
1938                 List<BridgeExternalIds> updateToOperationalExternalIds = getBridge(connectionInfo, testBridgeName)
1939                         .getBridgeExternalIds();
1940                 if (updateFromExpectedExternalIds != null) {
1941                     assertExpectedBridgeExternalIdsExist(updateToExpectedExternalIds, updateToOperationalExternalIds);
1942                     assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateToOperationalExternalIds);
1943                 }
1944
1945                 // DELETE
1946                 Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
1947             }
1948         }
1949         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1950     }
1951
1952     public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key,OvsdbBridgeName bridgeName) {
1953         return SouthboundMapper.createInstanceIdentifier(createManagedNodeId(key, bridgeName));
1954     }
1955
1956     public static NodeId createManagedNodeId(ConnectionInfo key, OvsdbBridgeName bridgeName) {
1957         return createManagedNodeId(key.getRemoteIp(), key.getRemotePort(), bridgeName);
1958     }
1959
1960     public static NodeId createManagedNodeId(IpAddress ip, PortNumber port, OvsdbBridgeName bridgeName) {
1961         return new NodeId(createNodeId(ip,port).getValue()
1962                 + "/" + SouthboundConstants.BRIDGE_URI_PREFIX + "/" + bridgeName.getValue());
1963     }
1964
1965     public static NodeId createNodeId(IpAddress ip, PortNumber port) {
1966         String uriString = SouthboundConstants.OVSDB_URI_PREFIX + "://"
1967                 + new String(ip.getValue()) + ":" + port.getValue();
1968         Uri uri = new Uri(uriString);
1969         return new NodeId(uri);
1970     }
1971
1972     public static NodeKey createNodeKey(IpAddress ip, PortNumber port) {
1973         return new NodeKey(createNodeId(ip,port));
1974     }
1975
1976     public static Node createNode(ConnectionInfo key) {
1977         NodeBuilder nodeBuilder = new NodeBuilder();
1978         nodeBuilder.setNodeId(createNodeId(key.getRemoteIp(),key.getRemotePort()));
1979         nodeBuilder.addAugmentation(OvsdbNodeAugmentation.class, createOvsdbAugmentation(key));
1980         return nodeBuilder.build();
1981     }
1982
1983     public static OvsdbNodeAugmentation createOvsdbAugmentation(ConnectionInfo key) {
1984         OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = new OvsdbNodeAugmentationBuilder();
1985         ovsdbNodeBuilder.setConnectionInfo(key);
1986         return ovsdbNodeBuilder.build();
1987     }
1988
1989     public static NodeId createManagedNodeId(InstanceIdentifier<Node> iid) {
1990         NodeKey nodeKey = iid.firstKeyOf(Node.class, NodeKey.class);
1991         return nodeKey.getNodeId();
1992     }
1993
1994     /**
1995      * <p>
1996      * Representation of a southbound test case. Each test case has a name, a list of input values and a list of
1997      * expected values. The input values are provided to the augmentation builder, and the expected values are checked
1998      * against the output of the resulting augmentation.
1999      * </p>
2000      * <p>
2001      * Instances of this class are immutable.
2002      * </p>
2003      *
2004      * @param <T> The type of data used for the test case.
2005      */
2006     private static final class SouthboundTestCase<T> {
2007         private final String name;
2008         private final List<T> inputValues;
2009         private final List<T> expectedValues;
2010
2011         /**
2012          * Creates an instance of a southbound test case.
2013          *
2014          * @param name The test case's name.
2015          * @param inputValues The input values (provided as input to the underlying augmentation builder).
2016          * @param expectedValues The expected values (checked against the output of the underlying augmentation).
2017          */
2018         public SouthboundTestCase(
2019                 final String name, final List<T> inputValues, final List<T> expectedValues) {
2020             this.name = name;
2021             this.inputValues = inputValues;
2022             this.expectedValues = expectedValues;
2023         }
2024     }
2025
2026     /**
2027      * Southbound test case builder.
2028      *
2029      * @param <T> The type of data used for the test case.
2030      */
2031     private static final class SouthboundTestCaseBuilder<T> {
2032         private String name;
2033         private List<T> inputValues;
2034         private List<T> expectedValues;
2035
2036         /**
2037          * Creates a builder. Builders may be reused, the generated immutable instances are independent of the
2038          * builders. There are no default values.
2039          */
2040         public SouthboundTestCaseBuilder() {
2041             // Nothing to do
2042         }
2043
2044         /**
2045          * Sets the test case's name.
2046          *
2047          * @param name The test case's name.
2048          * @return The builder.
2049          */
2050         public SouthboundTestCaseBuilder<T> name(final String name) {
2051             this.name = name;
2052             return this;
2053         }
2054
2055         /**
2056          * Sets the input values.
2057          *
2058          * @param inputValues The input values.
2059          * @return The builder.
2060          */
2061         @SafeVarargs
2062         public final SouthboundTestCaseBuilder<T> input(final T... inputValues) {
2063             this.inputValues = Lists.newArrayList(inputValues);
2064             return this;
2065         }
2066
2067         /**
2068          * Indicates that the provided input values should be expected as output values.
2069          *
2070          * @return The builder.
2071          */
2072         public SouthboundTestCaseBuilder<T> expectInputAsOutput() {
2073             this.expectedValues = this.inputValues;
2074             return this;
2075         }
2076
2077         /**
2078          * Indicates that no output should be expected.
2079          *
2080          * @return The builder.
2081          */
2082         public SouthboundTestCaseBuilder<T> expectNoOutput() {
2083             this.expectedValues = null;
2084             return this;
2085         }
2086
2087         /**
2088          * Builds an immutable instance representing the test case.
2089          *
2090          * @return The test case.
2091          */
2092         @SuppressWarnings("unchecked")
2093         public SouthboundTestCase<T> build() {
2094             return new SouthboundTestCase<>(name, inputValues, expectedValues);
2095         }
2096     }
2097
2098     private abstract static class KeyValueBuilder<T> {
2099         private static final int COUNTER_START = 0;
2100         private int counter = COUNTER_START;
2101
2102         protected abstract Builder<T> builder();
2103
2104         protected abstract void setKey(Builder<T> builder, String key);
2105
2106         protected abstract void setValue(Builder<T> builder, String value);
2107
2108         public final T build(final String testName, final String key, final String value) {
2109             final Builder<T> builder = builder();
2110             this.counter++;
2111             if (key != null) {
2112                 setKey(builder, String.format(FORMAT_STR, testName, key, this.counter));
2113             }
2114             if (value != null) {
2115                 setValue(builder, String.format(FORMAT_STR, testName, value, this.counter));
2116             }
2117             return builder.build();
2118         }
2119
2120         public final void reset() {
2121             this.counter = COUNTER_START;
2122         }
2123     }
2124
2125     private static final class SouthboundPortExternalIdsBuilder extends KeyValueBuilder<PortExternalIds> {
2126         @Override
2127         protected Builder<PortExternalIds> builder() {
2128             return new PortExternalIdsBuilder();
2129         }
2130
2131         @Override
2132         protected void setKey(Builder<PortExternalIds> builder, String key) {
2133             ((PortExternalIdsBuilder) builder).setExternalIdKey(key);
2134         }
2135
2136         @Override
2137         protected void setValue(Builder<PortExternalIds> builder, String value) {
2138             ((PortExternalIdsBuilder) builder).setExternalIdValue(value);
2139         }
2140     }
2141
2142     private static final class SouthboundInterfaceExternalIdsBuilder extends KeyValueBuilder<InterfaceExternalIds> {
2143         @Override
2144         protected Builder<InterfaceExternalIds> builder() {
2145             return new InterfaceExternalIdsBuilder();
2146         }
2147
2148         @Override
2149         protected void setKey(Builder<InterfaceExternalIds> builder, String key) {
2150             ((InterfaceExternalIdsBuilder) builder).setExternalIdKey(key);
2151         }
2152
2153         @Override
2154         protected void setValue(Builder<InterfaceExternalIds> builder, String value) {
2155             ((InterfaceExternalIdsBuilder) builder).setExternalIdValue(value);
2156         }
2157     }
2158
2159     private static final class SouthboundOptionsBuilder extends KeyValueBuilder<Options> {
2160         @Override
2161         protected Builder<Options> builder() {
2162             return new OptionsBuilder();
2163         }
2164
2165         @Override
2166         protected void setKey(Builder<Options> builder, String key) {
2167             ((OptionsBuilder) builder).setOption(key);
2168         }
2169
2170         @Override
2171         protected void setValue(Builder<Options> builder, String value) {
2172             ((OptionsBuilder) builder).setValue(value);
2173         }
2174     }
2175
2176     private static final class SouthboundInterfaceOtherConfigsBuilder extends KeyValueBuilder<InterfaceOtherConfigs> {
2177         @Override
2178         protected Builder<InterfaceOtherConfigs> builder() {
2179             return new InterfaceOtherConfigsBuilder();
2180         }
2181
2182         @Override
2183         protected void setKey(Builder<InterfaceOtherConfigs> builder, String key) {
2184             ((InterfaceOtherConfigsBuilder) builder).setOtherConfigKey(key);
2185         }
2186
2187         @Override
2188         protected void setValue(Builder<InterfaceOtherConfigs> builder, String value) {
2189             ((InterfaceOtherConfigsBuilder) builder).setOtherConfigValue(value);
2190         }
2191     }
2192
2193     private static final class SouthboundPortOtherConfigsBuilder extends KeyValueBuilder<PortOtherConfigs> {
2194         @Override
2195         protected Builder<PortOtherConfigs> builder() {
2196             return new PortOtherConfigsBuilder();
2197         }
2198
2199         @Override
2200         protected void setKey(Builder<PortOtherConfigs> builder, String key) {
2201             ((PortOtherConfigsBuilder) builder).setOtherConfigKey(key);
2202         }
2203
2204         @Override
2205         protected void setValue(Builder<PortOtherConfigs> builder, String value) {
2206             ((PortOtherConfigsBuilder) builder).setOtherConfigValue(value);
2207         }
2208     }
2209
2210     private static final class SouthboundBridgeOtherConfigsBuilder extends KeyValueBuilder<BridgeOtherConfigs> {
2211         @Override
2212         protected Builder<BridgeOtherConfigs> builder() {
2213             return new BridgeOtherConfigsBuilder();
2214         }
2215
2216         @Override
2217         protected void setKey(Builder<BridgeOtherConfigs> builder, String key) {
2218             ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigKey(key);
2219         }
2220
2221         @Override
2222         protected void setValue(Builder<BridgeOtherConfigs> builder, String value) {
2223             ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigValue(value);
2224         }
2225     }
2226
2227     private static final class SouthboundBridgeExternalIdsBuilder extends KeyValueBuilder<BridgeExternalIds> {
2228         @Override
2229         protected Builder<BridgeExternalIds> builder() {
2230             return new BridgeExternalIdsBuilder();
2231         }
2232
2233         @Override
2234         protected void setKey(Builder<BridgeExternalIds> builder, String key) {
2235             ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdKey(key);
2236         }
2237
2238         @Override
2239         protected void setValue(Builder<BridgeExternalIds> builder, String value) {
2240             ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdValue(value);
2241         }
2242     }
2243
2244     /*
2245      * Generates the test cases involved in testing key-value-based data.  See inline comments for descriptions of
2246      * the particular cases considered.
2247      */
2248     private static <T> List<SouthboundTestCase<T>> generateKeyValueTestCases(
2249             KeyValueBuilder<T> builder, String testName) {
2250         List<SouthboundTestCase<T>> testCases = new ArrayList<>();
2251
2252         final String GOOD_KEY = "GoodKey";
2253         final String GOOD_VALUE = "GoodValue";
2254         final String NO_VALUE_FOR_KEY = "NoValueForKey";
2255
2256         final String idKey = testName + "Key";
2257         final String idValue = testName + "Value";
2258
2259         // Test Case 1:  TestOne
2260         // Test Type:    Positive
2261         // Description:  Create a termination point with one value
2262         // Expected:     A port is created with the single value specified below
2263         final String testOneName = "TestOne" + testName;
2264         testCases.add(new SouthboundTestCaseBuilder<T>()
2265                 .name(testOneName)
2266                 .input(builder.build(testOneName, idKey, idValue))
2267                 .expectInputAsOutput()
2268                 .build());
2269
2270         // Test Case 2:  TestFive
2271         // Test Type:    Positive
2272         // Description:  Create a termination point with multiple (five) values
2273         // Expected:     A port is created with the five values specified below
2274         final String testFiveName = "TestFive" + testName;
2275         builder.reset();
2276         testCases.add(new SouthboundTestCaseBuilder<T>()
2277                 .name(testFiveName)
2278                 .input(
2279                         builder.build(testFiveName, idKey, idValue),
2280                         builder.build(testFiveName, idKey, idValue),
2281                         builder.build(testFiveName, idKey, idValue),
2282                         builder.build(testFiveName, idKey, idValue),
2283                         builder.build(testFiveName, idKey, idValue))
2284                 .expectInputAsOutput()
2285                 .build());
2286
2287         // Test Case 3:  TestOneGoodOneMalformedValue
2288         // Test Type:    Negative
2289         // Description:
2290         //     One perfectly fine input
2291         //        (TestOneGoodOneMalformedValue_GoodKey_1,
2292         //        TestOneGoodOneMalformedValue_GoodValue_1)
2293         //     and one malformed input which only has key specified
2294         //        (TestOneGoodOneMalformedValue_NoValueForKey_2,
2295         //        UNSPECIFIED)
2296         // Expected:     A port is created without any values
2297         final String testOneGoodOneMalformedValueName = "TestOneGoodOneMalformedValue" + testName;
2298         builder.reset();
2299         testCases.add(new SouthboundTestCaseBuilder<T>()
2300                 .name(testOneGoodOneMalformedValueName)
2301                 .input(
2302                         builder.build(testOneGoodOneMalformedValueName, GOOD_KEY, GOOD_VALUE),
2303                         builder.build(testOneGoodOneMalformedValueName, NO_VALUE_FOR_KEY, null))
2304                 .expectNoOutput()
2305                 .build());
2306         builder.reset();
2307
2308         return testCases;
2309     }
2310 }