Fix sonar integration test reporting
[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.Maps;
23 import com.google.common.collect.Sets;
24
25 import java.io.File;
26 import java.net.InetAddress;
27 import java.net.UnknownHostException;
28 import java.util.ArrayList;
29 import java.util.HashMap;
30 import java.util.HashSet;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Properties;
34 import java.util.Set;
35 import java.util.concurrent.ExecutionException;
36 import java.util.concurrent.ExecutorService;
37 import java.util.concurrent.Executors;
38 import java.util.concurrent.TimeUnit;
39
40 import javax.inject.Inject;
41
42 import org.junit.Assert;
43 import org.junit.Before;
44 import org.junit.Test;
45 import org.junit.runner.RunWith;
46 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
47 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
48 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
49 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
50 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
51 import org.opendaylight.ovsdb.southbound.SouthboundProvider;
52 import org.opendaylight.ovsdb.southbound.SouthboundUtil;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeBase;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentationBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes.VlanMode;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIdsBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.DatapathTypeEntry;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntryBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigs;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigsBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIds;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigs;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigsBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder;
95 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
96 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
97 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
98 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
99 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
100 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
101 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
102 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
103 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
104 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
105 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
106 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
107 import org.ops4j.pax.exam.Configuration;
108 import org.ops4j.pax.exam.Option;
109 import org.ops4j.pax.exam.junit.PaxExam;
110 import org.ops4j.pax.exam.karaf.options.KarafDistributionOption;
111 import org.ops4j.pax.exam.karaf.options.LogLevelOption;
112 import org.ops4j.pax.exam.options.MavenUrlReference;
113 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
114 import org.ops4j.pax.exam.spi.reactors.PerClass;
115 import org.osgi.framework.BundleContext;
116 import org.slf4j.Logger;
117 import org.slf4j.LoggerFactory;
118
119 /**
120  * Integration tests for southbound-impl
121  *
122  * @author Sam Hague (shague@redhat.com)
123  */
124 @RunWith(PaxExam.class)
125 @ExamReactorStrategy(PerClass.class)
126 public class SouthboundIT extends AbstractMdsalTestBase {
127     private static final String EXPECTED_VALUES_KEY = "ExpectedValuesKey";
128     private static final String INPUT_VALUES_KEY = "InputValuesKey";
129     private static final String NETDEV_DP_TYPE = "netdev";
130     private static final Logger LOG = LoggerFactory.getLogger(SouthboundIT.class);
131     private static final int OVSDB_UPDATE_TIMEOUT = 1000;
132     public static final int NUM_THREADS = 4;
133     private static DataBroker dataBroker = null;
134     private static String addressStr;
135     private static String portStr;
136     private static String connectionType;
137     private static Boolean setup = false;
138     private static MdsalUtils mdsalUtils = null;
139
140     // TODO Constants copied frmo AbstractConfigTestBase, need to be removed (see TODO below)
141     private static final String PAX_EXAM_UNPACK_DIRECTORY = "target/exam";
142     private static final String KARAF_DEBUG_PORT = "5005";
143     private static final String KARAF_DEBUG_PROP = "karaf.debug";
144     private static final String KEEP_UNPACK_DIRECTORY_PROP = "karaf.keep.unpack";
145
146     @Inject
147     private BundleContext bundleContext;
148
149     @Configuration
150     public Option[] config() {
151         // TODO Figure out how to use the parent Karaf setup, then just use super.config()
152         Option[] options = new Option[] {
153                 when(Boolean.getBoolean(KARAF_DEBUG_PROP))
154                         .useOptions(KarafDistributionOption.debugConfiguration(KARAF_DEBUG_PORT, true)),
155                 karafDistributionConfiguration().frameworkUrl(getKarafDistro())
156                         .unpackDirectory(new File(PAX_EXAM_UNPACK_DIRECTORY))
157                         .useDeployFolder(false),
158                 when(Boolean.getBoolean(KEEP_UNPACK_DIRECTORY_PROP)).useOptions(keepRuntimeFolder()),
159                 // Works only if we don't specify the feature repo and name
160                 getLoggingOption()};
161         Option[] propertyOptions = getPropertiesOptions();
162         Option[] otherOptions = getOtherOptions();
163         Option[] combinedOptions = new Option[options.length + propertyOptions.length + otherOptions.length];
164         System.arraycopy(options, 0, combinedOptions, 0, options.length);
165         System.arraycopy(propertyOptions, 0, combinedOptions, options.length, propertyOptions.length);
166         System.arraycopy(otherOptions, 0, combinedOptions, options.length + propertyOptions.length,
167                 otherOptions.length);
168         return combinedOptions;
169     }
170
171     private Option[] getOtherOptions() {
172         return new Option[] {
173                 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
174                 keepRuntimeFolder()
175         };
176     }
177
178     @Override
179     public String getKarafDistro() {
180         return maven()
181                 .groupId("org.opendaylight.ovsdb")
182                 .artifactId("southbound-karaf")
183                 .versionAsInProject()
184                 .type("zip")
185                 .getURL();
186     }
187
188     @Override
189     public String getModuleName() {
190         return "southbound-impl";
191     }
192
193     @Override
194     public String getInstanceName() {
195         return "southbound-default";
196     }
197
198     @Override
199     public MavenUrlReference getFeatureRepo() {
200         return maven()
201                 .groupId("org.opendaylight.ovsdb")
202                 .artifactId("southbound-features")
203                 .classifier("features")
204                 .type("xml")
205                 .versionAsInProject();
206     }
207
208     @Override
209     public String getFeatureName() {
210         return "odl-ovsdb-southbound-impl-ui";
211     }
212
213     protected String usage() {
214         return "Integration Test needs a valid connection configuration as follows :\n"
215                 + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
216                 + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
217     }
218
219     @Override
220     public Option getLoggingOption() {
221         return composite(
222                 editConfigurationFilePut(SouthboundITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
223                         "log4j.logger.org.opendaylight.ovsdb",
224                         LogLevelOption.LogLevel.TRACE.name()),
225                 super.getLoggingOption());
226     }
227
228     private Option[] getPropertiesOptions() {
229         Properties props = new Properties(System.getProperties());
230         String addressStr = props.getProperty(SouthboundITConstants.SERVER_IPADDRESS,
231                 SouthboundITConstants.DEFAULT_SERVER_IPADDRESS);
232         String portStr = props.getProperty(SouthboundITConstants.SERVER_PORT,
233                 SouthboundITConstants.DEFAULT_SERVER_PORT);
234         String connectionType = props.getProperty(SouthboundITConstants.CONNECTION_TYPE,
235                 SouthboundITConstants.CONNECTION_TYPE_ACTIVE);
236
237         LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}",
238                 connectionType, addressStr, portStr);
239
240         Option[] options = new Option[] {
241                 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
242                         SouthboundITConstants.SERVER_IPADDRESS, addressStr),
243                 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
244                         SouthboundITConstants.SERVER_PORT, portStr),
245                 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
246                         SouthboundITConstants.CONNECTION_TYPE, connectionType),
247         };
248         return options;
249     }
250
251     @Before
252     @Override
253     public void setup() throws InterruptedException {
254         if (setup) {
255             LOG.info("Skipping setUp, already initialized");
256             return;
257         }
258
259         try {
260             super.setup();
261         } catch (Exception e) {
262             e.printStackTrace();
263         }
264         //dataBroker = getSession().getSALService(DataBroker.class);
265         Thread.sleep(3000);
266         dataBroker = SouthboundProvider.getDb();
267         Assert.assertNotNull("db should not be null", dataBroker);
268
269         addressStr = bundleContext.getProperty(SouthboundITConstants.SERVER_IPADDRESS);
270         portStr = bundleContext.getProperty(SouthboundITConstants.SERVER_PORT);
271         connectionType = bundleContext.getProperty(SouthboundITConstants.CONNECTION_TYPE);
272
273         LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
274                 connectionType, addressStr, portStr);
275         if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_ACTIVE)) {
276             if (addressStr == null) {
277                 fail(usage());
278             }
279         }
280
281         mdsalUtils = new MdsalUtils(dataBroker);
282         setup = true;
283     }
284
285     /**
286      * Test passive connection mode. The southbound starts in a listening mode waiting for connections on port
287      * 6640. This test will wait for incoming connections for {@link SouthboundITConstants.CONNECTION_INIT_TIMEOUT} ms.
288      *
289      * @throws InterruptedException
290      */
291     @Test
292     public void testPassiveNode() throws InterruptedException {
293         if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_PASSIVE)) {
294             //Wait for CONNECTION_INIT_TIMEOUT for the Passive connection to be initiated by the ovsdb-server.
295             Thread.sleep(SouthboundITConstants.CONNECTION_INIT_TIMEOUT);
296         }
297     }
298
299     private ConnectionInfo getConnectionInfo(final String addressStr, final String portStr) {
300         InetAddress inetAddress = null;
301         try {
302             inetAddress = InetAddress.getByName(addressStr);
303         } catch (UnknownHostException e) {
304             fail("Could not allocate InetAddress: " + e);
305         }
306
307         IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
308         PortNumber port = new PortNumber(Integer.parseInt(portStr));
309
310         LOG.info("connectionInfo: {}", new ConnectionInfoBuilder()
311                 .setRemoteIp(address)
312                 .setRemotePort(port)
313                 .build());
314         return new ConnectionInfoBuilder()
315                 .setRemoteIp(address)
316                 .setRemotePort(port)
317                 .build();
318     }
319
320     private String connectionInfoToString(final ConnectionInfo connectionInfo) {
321         return new String(connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
322     }
323
324     @Test
325     public void testNetworkTopology() throws InterruptedException {
326         NetworkTopology networkTopology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION,
327                 InstanceIdentifier.create(NetworkTopology.class));
328         Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.CONFIGURATION,
329                 networkTopology);
330
331         networkTopology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
332                 InstanceIdentifier.create(NetworkTopology.class));
333         Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.OPERATIONAL,
334                 networkTopology);
335     }
336
337     @Test
338     public void testOvsdbTopology() throws InterruptedException {
339         InstanceIdentifier<Topology> path = InstanceIdentifier
340                 .create(NetworkTopology.class)
341                 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
342
343         Topology topology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
344         Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.CONFIGURATION,
345                 topology);
346
347         topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
348
349         Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.OPERATIONAL,
350                 topology);
351     }
352
353     private boolean addOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
354         InstanceIdentifier<Node> iid = createInstanceIdentifier(connectionInfo);
355         // Check that the node doesn't already exist (we don't support connecting twice)
356         Assert.assertNull("The OVSDB node has already been added",
357                 mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, iid));
358         boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
359                 iid,
360                 createNode(connectionInfo));
361         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
362         return result;
363     }
364
365     private InstanceIdentifier<Node> createInstanceIdentifier(
366             ConnectionInfo connectionInfo) {
367         return InstanceIdentifier
368                 .create(NetworkTopology.class)
369                 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
370                 .child(Node.class,
371                         createNodeKey(connectionInfo.getRemoteIp(),connectionInfo.getRemotePort()));
372     }
373
374     private Node getOvsdbNode(final ConnectionInfo connectionInfo) {
375         Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
376                 createInstanceIdentifier(connectionInfo));
377         return node;
378     }
379
380     private boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
381         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
382                 createInstanceIdentifier(connectionInfo));
383         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
384         return result;
385     }
386
387     private Node connectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
388         Assert.assertTrue(addOvsdbNode(connectionInfo));
389         Node node = getOvsdbNode(connectionInfo);
390         Assert.assertNotNull(node);
391         LOG.info("Connected to {}", connectionInfoToString(connectionInfo));
392         return node;
393     }
394
395     private boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
396         Assert.assertTrue(deleteOvsdbNode(connectionInfo));
397         Node node = getOvsdbNode(connectionInfo);
398         Assert.assertNull(node);
399         //Assume.assumeNotNull(node); // Using assumeNotNull because there is no assumeNull
400         LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
401         return true;
402     }
403
404     @Test
405     public void testAddDeleteOvsdbNode() throws InterruptedException {
406         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
407         Node ovsdbNode = connectOvsdbNode(connectionInfo);
408         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
409         //Assume.assumeTrue(disconnectOvsdbNode(connectionInfo));
410     }
411
412     @Test
413     public void testDpdkSwitch() throws InterruptedException {
414         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
415         Node ovsdbNode = connectOvsdbNode(connectionInfo);
416         List<DatapathTypeEntry> datapathTypeEntries = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class)
417                 .getDatapathTypeEntry();
418         if (datapathTypeEntries == null) {
419             LOG.info("DPDK not supported on this node.");
420         } else {
421             Class<? extends DatapathTypeBase> dpType = null;
422             String dpTypeStr = null;
423             for (DatapathTypeEntry dpTypeEntry : datapathTypeEntries) {
424                 dpType = dpTypeEntry.getDatapathType();
425                 dpTypeStr = SouthboundConstants.DATAPATH_TYPE_MAP.get(dpType);
426                 LOG.info("dp type is {}", dpTypeStr);
427                 if (dpTypeStr.equals(NETDEV_DP_TYPE)) {
428                     LOG.info("Found a DPDK node; adding a corresponding netdev device");
429                     InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(connectionInfo,
430                             new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME));
431                     NodeId bridgeNodeId = createManagedNodeId(bridgeIid);
432                     addBridge(connectionInfo, bridgeIid, SouthboundITConstants.BRIDGE_NAME, bridgeNodeId, false, null,
433                             true, dpType, null, null, null);
434
435                     // Verify that the device is netdev
436                     OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
437                     Assert.assertNotNull(bridge);
438                     Assert.assertEquals(dpTypeStr, bridge.getDatapathType());
439
440                     // Add dpdk port
441                     final String TEST_PORT_NAME = "testDPDKPort";
442                     OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
443                             createGenericDpdkOvsdbTerminationPointAugmentationBuilder(TEST_PORT_NAME);
444                     Assert.assertTrue(addTerminationPoint(bridgeNodeId, TEST_PORT_NAME, ovsdbTerminationBuilder));
445
446                     // Verify that DPDK port was created
447                     InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
448                     Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
449                             terminationPointIid);
450                     Assert.assertNotNull(terminationPointNode);
451
452                     // Verify that each termination point has DPDK ifType
453                     Class<? extends InterfaceTypeBase> dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
454                             .get("dpdk");
455                     Class<? extends InterfaceTypeBase> opPort = null;
456                     List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
457                     for (TerminationPoint terminationPoint : terminationPoints) {
458                         OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = terminationPoint
459                                 .getAugmentation(OvsdbTerminationPointAugmentation.class);
460                         if (ovsdbTerminationPointAugmentation.getName().equals(TEST_PORT_NAME)) {
461                             opPort = ovsdbTerminationPointAugmentation
462                                     .getInterfaceType();
463                             Assert.assertEquals(dpdkIfType, opPort);
464                         }
465                     }
466                     Assert.assertTrue(deleteBridge(connectionInfo));
467                     break;
468                 }
469             }
470         }
471         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
472     }
473
474     @Test
475     public void testOvsdbNodeOvsVersion() throws InterruptedException {
476         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
477         Node ovsdbNode = connectOvsdbNode(connectionInfo);
478         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
479         Assert.assertNotNull(ovsdbNodeAugmentation);
480         assertNotNull(ovsdbNodeAugmentation.getOvsVersion());
481         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
482         //Assume.assumeTrue(disconnectOvsdbNode(connectionInfo));
483     }
484
485     @Test
486     public void testOpenVSwitchOtherConfig() throws InterruptedException {
487         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
488         Node ovsdbNode = connectOvsdbNode(connectionInfo);
489         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
490         Assert.assertNotNull(ovsdbNodeAugmentation);
491         List<OpenvswitchOtherConfigs> otherConfigsList = ovsdbNodeAugmentation.getOpenvswitchOtherConfigs();
492         if (otherConfigsList != null) {
493             for (OpenvswitchOtherConfigs otherConfig : otherConfigsList) {
494                 if (otherConfig.getOtherConfigKey().equals("local_ip")) {
495                     LOG.info("local_ip: {}", otherConfig.getOtherConfigValue());
496                     break;
497                 } else {
498                     LOG.info("other_config {}:{}", otherConfig.getOtherConfigKey(), otherConfig.getOtherConfigValue());
499                 }
500             }
501         } else {
502             LOG.info("other_config is not present");
503         }
504         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
505         //Assume.assumeTrue(disconnectOvsdbNode(connectionInfo));
506     }
507
508     @Test
509     public void testOvsdbBridgeControllerInfo() throws InterruptedException {
510         ConnectionInfo connectionInfo = getConnectionInfo(addressStr,portStr);
511         Node ovsdbNode = connectOvsdbNode(connectionInfo);
512         String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
513         assertNotNull("Failed to get controller target", controllerTarget);
514         List<ControllerEntry> setControllerEntry = createControllerEntry(controllerTarget);
515         Uri setUri = new Uri(controllerTarget);
516         Assert.assertTrue(addBridge(connectionInfo, null, SouthboundITConstants.BRIDGE_NAME,null, true,
517                 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null,
518                 setControllerEntry, null));
519         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
520         Assert.assertNotNull("bridge was not found: " + SouthboundITConstants.BRIDGE_NAME,  bridge);
521         Assert.assertNotNull("ControllerEntry was not found: " + setControllerEntry.iterator().next(),
522                 bridge.getControllerEntry());
523         List<ControllerEntry> getControllerEntries = bridge.getControllerEntry();
524         for (ControllerEntry entry : getControllerEntries) {
525             if (entry.getTarget() != null) {
526                 Assert.assertEquals(setUri.toString(), entry.getTarget().toString());
527             }
528         }
529
530         Assert.assertTrue(deleteBridge(connectionInfo));
531         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
532     }
533
534     private List<ControllerEntry> createControllerEntry(String controllerTarget) {
535         List<ControllerEntry> controllerEntriesList = new ArrayList<ControllerEntry>();
536         controllerEntriesList.add(new ControllerEntryBuilder()
537                 .setTarget(new Uri(controllerTarget))
538                 .build());
539         return controllerEntriesList;
540     }
541
542     private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
543                               final ConnectionInfo connectionInfo) {
544         InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(connectionInfo);
545         ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
546     }
547
548     private List<ProtocolEntry> createMdsalProtocols() {
549         List<ProtocolEntry> protocolList = new ArrayList<ProtocolEntry>();
550         ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
551                 SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
552         protocolList.add(new ProtocolEntryBuilder().
553                 setProtocol((Class<? extends OvsdbBridgeProtocolBase>) mapper.get("OpenFlow13")).build());
554         return protocolList;
555     }
556
557     private OvsdbTerminationPointAugmentationBuilder createGenericOvsdbTerminationPointAugmentationBuilder() {
558         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder =
559                 new OvsdbTerminationPointAugmentationBuilder();
560         ovsdbTerminationPointAugmentationBuilder.setInterfaceType(
561                 new InterfaceTypeEntryBuilder()
562                         .setInterfaceType(
563                                 SouthboundMapper.createInterfaceType("internal"))
564                         .build().getInterfaceType());
565         return ovsdbTerminationPointAugmentationBuilder;
566     }
567
568     private OvsdbTerminationPointAugmentationBuilder createGenericDpdkOvsdbTerminationPointAugmentationBuilder(
569             final String portName) {
570         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
571                 createGenericOvsdbTerminationPointAugmentationBuilder();
572         ovsdbTerminationBuilder.setName(portName);
573         Class<? extends InterfaceTypeBase> ifType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
574                 .get("dpdk");
575         ovsdbTerminationBuilder.setInterfaceType(ifType);
576         return ovsdbTerminationBuilder;
577     }
578
579     private boolean addTerminationPoint(final NodeId bridgeNodeId, final String portName,
580                                         final OvsdbTerminationPointAugmentationBuilder
581                                                 ovsdbTerminationPointAugmentationBuilder)
582             throws InterruptedException {
583
584         InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(bridgeNodeId);
585         NodeBuilder portNodeBuilder = new NodeBuilder();
586         NodeId portNodeId = SouthboundMapper.createManagedNodeId(portIid);
587         portNodeBuilder.setNodeId(portNodeId);
588         TerminationPointBuilder entry = new TerminationPointBuilder();
589         entry.setKey(new TerminationPointKey(new TpId(portName)));
590         entry.addAugmentation(
591                 OvsdbTerminationPointAugmentation.class,
592                 ovsdbTerminationPointAugmentationBuilder.build());
593         portNodeBuilder.setTerminationPoint(Lists.newArrayList(entry.build()));
594         boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
595                 portIid, portNodeBuilder.build());
596         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
597         return result;
598     }
599
600     /*
601      * base method for adding test bridges.  Other helper methods used to create bridges should utilize this method.
602      *
603      * @param connectionInfo
604      * @param bridgeIid if passed null, one is created
605      * @param bridgeName cannot be null
606      * @param bridgeNodeId if passed null, one is created based on <code>bridgeIid</code>
607      * @param setProtocolEntries toggles whether default protocol entries are set for the bridge
608      * @param failMode toggles whether default fail mode is set for the bridge
609      * @param setManagedBy toggles whether to setManagedBy for the bridge
610      * @param dpType if passed null, this parameter is ignored
611      * @param externalIds if passed null, this parameter is ignored
612      * @param otherConfig if passed null, this parameter is ignored
613      * @return success of bridge addition
614      * @throws InterruptedException
615      */
616     private boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
617                               final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
618                               final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
619                               final Class<? extends DatapathTypeBase> dpType,
620                               final List<BridgeExternalIds> externalIds,
621                               final List<ControllerEntry> controllerEntries,
622                               final List<BridgeOtherConfigs> otherConfigs) throws InterruptedException {
623
624         NodeBuilder bridgeNodeBuilder = new NodeBuilder();
625         if (bridgeIid == null) {
626             bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
627         }
628         if (bridgeNodeId == null) {
629             bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
630         }
631         bridgeNodeBuilder.setNodeId(bridgeNodeId);
632         OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
633         ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
634         if (setProtocolEntries) {
635             ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
636         }
637         if (failMode != null) {
638             ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
639         }
640         if (setManagedBy) {
641             setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
642         }
643         if (dpType != null) {
644             ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
645         }
646         if (externalIds != null) {
647             ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
648         }
649         if (controllerEntries != null) {
650             ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries);
651         }
652         if (otherConfigs != null) {
653             ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
654         }
655         bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
656         LOG.debug("Built with the intent to store bridge data {}",
657                 ovsdbBridgeAugmentationBuilder.toString());
658         boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
659                 bridgeIid, bridgeNodeBuilder.build());
660         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
661         return result;
662     }
663
664     private boolean addBridge(final ConnectionInfo connectionInfo, final String bridgeName)
665             throws InterruptedException {
666
667         return addBridge(connectionInfo, null, bridgeName, null, true,
668                 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null);
669     }
670
671     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo) {
672         return getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
673     }
674
675     /**
676      * Extract the <code>store</code> type data store contents for the particular bridge identified by
677      * <code>bridgeName</code>.
678      *
679      * @param connectionInfo
680      * @param bridgeName
681      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
682      * @return <code>store</code> type data store contents
683      */
684     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
685                                               LogicalDatastoreType store) {
686         Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
687         Assert.assertNotNull(bridgeNode);
688         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
689         Assert.assertNotNull(ovsdbBridgeAugmentation);
690         return ovsdbBridgeAugmentation;
691     }
692
693     /**
694      * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
695      * identified by <code>bridgeName</code>
696      *
697      * @param connectionInfo
698      * @param bridgeName
699      * @see <code>SouthboundIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
700      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
701      */
702     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
703         return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
704     }
705
706     /**
707      * Extract the node contents from <code>store</code> type data store for the
708      * bridge identified by <code>bridgeName</code>
709      *
710      * @param connectionInfo
711      * @param bridgeName
712      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
713      * @return <code>store</code> type data store contents
714      */
715     private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
716         InstanceIdentifier<Node> bridgeIid =
717                 createInstanceIdentifier(connectionInfo,
718                         new OvsdbBridgeName(bridgeName));
719         return mdsalUtils.read(store, bridgeIid);
720     }
721
722     /**
723      * Extract the node contents from <code>LogicalDataStoreType.OPERATIONAL</code> data store for the
724      * bridge identified by <code>bridgeName</code>
725      *
726      * @param connectionInfo
727      * @param bridgeName
728      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
729      */
730     private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName) {
731         return getBridgeNode(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
732     }
733
734     private boolean deleteBridge(ConnectionInfo connectionInfo) throws InterruptedException {
735         return deleteBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
736     }
737
738     private boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName)
739             throws InterruptedException {
740
741         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
742                 createInstanceIdentifier(connectionInfo,
743                         new OvsdbBridgeName(bridgeName)));
744         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
745         return result;
746     }
747
748     @Test
749     public void testAddDeleteBridge() throws InterruptedException {
750         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
751         Node ovsdbNode = connectOvsdbNode(connectionInfo);
752
753         Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
754         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
755         Assert.assertNotNull(bridge);
756         LOG.info("bridge: {}", bridge);
757
758         Assert.assertTrue(deleteBridge(connectionInfo));
759
760         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
761         //Assume.assumeTrue(disconnectOvsdbNode(connectionInfo));
762     }
763
764     private InstanceIdentifier<Node> getTpIid(ConnectionInfo connectionInfo, OvsdbBridgeAugmentation bridge) {
765         return createInstanceIdentifier(connectionInfo,
766                 bridge.getBridgeName());
767     }
768
769     /**
770      * Extracts the <code>TerminationPointAugmentation</code> for the <code>index</code> <code>TerminationPoint</code>
771      * on <code>bridgeName</code>
772      *
773      * @param connectionInfo
774      * @param bridgeName
775      * @param store
776      * @param index
777      * @return
778      */
779     private OvsdbTerminationPointAugmentation getOvsdbTerminationPointAugmentation(
780             ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store, int index ) {
781
782         List<TerminationPoint> tpList = getBridgeNode(connectionInfo, bridgeName, store).getTerminationPoint();
783         if (tpList == null) {
784             return null;
785         }
786         return ((OvsdbTerminationPointAugmentation)
787                 tpList.get(index)
788                         .getAugmentation(OvsdbTerminationPointAugmentation.class));
789     }
790
791     @Test
792     public void testCRDTerminationPointOfPort() throws InterruptedException {
793         final Long OFPORT_EXPECTED = new Long(45002);
794
795         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
796         connectOvsdbNode(connectionInfo);
797
798         // CREATE
799         Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
800         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
801         Assert.assertNotNull(bridge);
802         LOG.info("bridge: {}", bridge);
803         NodeId nodeId = SouthboundMapper.createManagedNodeId(createInstanceIdentifier(
804                 connectionInfo, bridge.getBridgeName()));
805         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
806                 createGenericOvsdbTerminationPointAugmentationBuilder();
807         String portName = "testOfPort";
808         ovsdbTerminationBuilder.setName(portName);
809
810         ovsdbTerminationBuilder.setOfport(OFPORT_EXPECTED);
811         Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
812         InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
813         Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
814         Assert.assertNotNull(terminationPointNode);
815
816         // READ
817         List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
818         for (TerminationPoint terminationPoint : terminationPoints) {
819             OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
820                     terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
821             if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
822                 Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
823                 // if ephemeral port 45002 is in use, ofPort is set to 1
824                 Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(new Long(1)));
825                 LOG.info("ofPort: {}", ofPort);
826             }
827         }
828
829         // UPDATE- Not Applicable.  From the OpenVSwitch Documentation:
830         //   "A client should ideally set this column’s value in the same database transaction that it uses to create
831         //   the interface."
832
833         // DELETE
834         Assert.assertTrue(deleteBridge(connectionInfo));
835         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
836     }
837
838     @Test
839     public void testCRDTerminationPointOfPortRequest() throws InterruptedException {
840         final Long OFPORT_EXPECTED = new Long(45008);
841         final Long OFPORT_INPUT = new Long(45008);
842
843         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
844         connectOvsdbNode(connectionInfo);
845
846         // CREATE
847         Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
848         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
849         Assert.assertNotNull(bridge);
850         NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
851                 connectionInfo, bridge.getBridgeName()));
852         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
853                 createGenericOvsdbTerminationPointAugmentationBuilder();
854         String portName = "testOfPortRequest";
855         ovsdbTerminationBuilder.setName(portName);
856         Integer ofPortRequestExpected = OFPORT_EXPECTED.intValue();
857         ovsdbTerminationBuilder.setOfport(OFPORT_INPUT);
858         ovsdbTerminationBuilder.setOfportRequest(ofPortRequestExpected);
859         Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
860         InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
861         Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
862         Assert.assertNotNull(terminationPointNode);
863
864         // READ
865         List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
866         for (TerminationPoint terminationPoint : terminationPoints) {
867             OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
868                     terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
869             if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
870                 Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
871                 // if ephemeral port 45008 is in use, ofPort is set to 1
872                 Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(new Long(1)));
873                 LOG.info("ofPort: {}", ofPort);
874
875                 Integer ofPortRequest = ovsdbTerminationPointAugmentation.getOfportRequest();
876                 Assert.assertTrue(ofPortRequest.equals(ofPortRequestExpected));
877                 LOG.info("ofPortRequest: {}", ofPortRequest);
878             }
879         }
880
881         // UPDATE- Not Applicable.  From the OpenVSwitch documentation:
882         //   "A client should ideally set this column’s value in the same database transaction that it uses to create
883         //   the interface. "
884
885         // DELETE
886         Assert.assertTrue(deleteBridge(connectionInfo));
887         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
888     }
889
890     /*
891      * Generates the test cases involved in testing PortExternalIds.  See inline comments for descriptions of
892      * the particular cases considered.
893      *
894      * The return value is a Map in the form (K,V)=(testCaseName,testCase).
895      * - testCaseName is a String
896      * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of
897      *     either corresponding INPUT port external_ids, or EXPECTED port external_ids
898      *     INPUT    is the List we use when calling
899      *              <code>TerminationPointAugmentationBuilder.setPortExternalIds()</code>
900      *     EXPECTED is the List we expect to receive after calling
901      *              <code>TerminationPointAugmentationBuilder.getPortExternalIds()</code>
902      */
903     private Map<String, Map<String, List<PortExternalIds>>> generatePortExternalIdsTestCases() {
904         Map<String, Map<String, List<PortExternalIds>>> testMap =
905                 new HashMap<String, Map<String, List<PortExternalIds>>>();
906
907         final String PORT_EXTERNAL_ID_KEY = "PortExternalIdKey";
908         final String PORT_EXTERNAL_ID_VALUE = "PortExternalIdValue";
909         final String FORMAT_STR = "%s_%s_%d";
910         final String GOOD_KEY = "GoodKey";
911         final String GOOD_VALUE = "GoodValue";
912         final String NO_VALUE_FOR_KEY = "NoValueForKey";
913         final String NO_KEY_FOR_VALUE = "NoKeyForValue";
914
915         // Test Case 1:  TestOneExternalId
916         // Test Type:    Positive
917         // Description:  Create a termination point with one PortExternalIds
918         // Expected:     A port is created with the single external_ids specified below
919         final String testOneExternalIdName = "TestOneExternalId";
920         int externalIdCounter = 0;
921         List<PortExternalIds> oneExternalId = (List<PortExternalIds>) Lists.newArrayList(
922                 (new PortExternalIdsBuilder()
923                         .setExternalIdKey(String.format(FORMAT_STR, testOneExternalIdName,
924                                 PORT_EXTERNAL_ID_KEY, ++externalIdCounter))
925                         .setExternalIdValue(String.format(FORMAT_STR, testOneExternalIdName,
926                                 PORT_EXTERNAL_ID_VALUE, externalIdCounter))
927                         .build()));
928         Map<String,List<PortExternalIds>> testCase = Maps.newHashMap();
929         testCase.put(EXPECTED_VALUES_KEY, oneExternalId);
930         testCase.put(INPUT_VALUES_KEY, oneExternalId);
931         testMap.put(testOneExternalIdName, testCase);
932
933         // Test Case 2:  TestFiveExternalId
934         // Test Type:    Positive
935         // Description:  Create a termination point with multiple (five) PortExternalIds
936         // Expected:     A port is created with the five external_ids specified below
937         final String testFiveExternalIdName = "TestFiveExternalId";
938         externalIdCounter = 0;
939         List<PortExternalIds> fiveExternalId = (List<PortExternalIds>) Lists.newArrayList(
940                 (new PortExternalIdsBuilder()
941                         .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
942                                 PORT_EXTERNAL_ID_KEY, ++externalIdCounter))
943                         .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
944                                 PORT_EXTERNAL_ID_VALUE, externalIdCounter))
945                         .build()),
946                 (new PortExternalIdsBuilder()
947                         .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
948                                 PORT_EXTERNAL_ID_KEY, ++externalIdCounter))
949                         .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
950                                 PORT_EXTERNAL_ID_VALUE, externalIdCounter))
951                         .build()),
952                 (new PortExternalIdsBuilder()
953                         .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
954                                 PORT_EXTERNAL_ID_KEY, ++externalIdCounter))
955                         .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
956                                 PORT_EXTERNAL_ID_VALUE, externalIdCounter))
957                         .build()),
958                 (new PortExternalIdsBuilder()
959                         .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
960                                 PORT_EXTERNAL_ID_KEY, ++externalIdCounter))
961                         .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
962                                 PORT_EXTERNAL_ID_VALUE, externalIdCounter))
963                         .build()),
964                 (new PortExternalIdsBuilder()
965                         .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
966                                 PORT_EXTERNAL_ID_KEY, ++externalIdCounter))
967                         .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
968                                 PORT_EXTERNAL_ID_VALUE, externalIdCounter))
969                         .build()));
970         testCase = Maps.newHashMap();
971         testCase.put(EXPECTED_VALUES_KEY, fiveExternalId);
972         testCase.put(INPUT_VALUES_KEY, fiveExternalId);
973         testMap.put(testFiveExternalIdName, testCase);
974
975         // Test Case 3:  TestOneGoodExternalIdOneMalformedExternalIdValue
976         // Test Type:    Negative
977         // Description:
978         //     One perfectly fine PortExternalId
979         //        (TestOneGoodExternalIdOneMalformedExternalIdValue_PortExternalIdKey_1,
980         //        TestOneGoodExternalIdOneMalformedExternalId_PortExternalIdValue_1)
981         //     and one malformed PortExternalId which only has key specified
982         //        (TestOneGoodExternalIdOneMalformedExternalIdValue_NoValueForKey_2,
983         //        UNSPECIFIED)
984         // Expected:     A port is created without any external_ids
985         final String testOneGoodExternalIdOneMalformedExternalIdValueName =
986                 "TestOneGoodExternalIdOneMalformedExternalIdValue";
987         externalIdCounter = 0;
988         PortExternalIds oneGood = new PortExternalIdsBuilder()
989                 .setExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdValueName,
990                         GOOD_KEY, ++externalIdCounter))
991                 .setExternalIdValue(String.format(FORMAT_STR,
992                         testOneGoodExternalIdOneMalformedExternalIdValueName,
993                         GOOD_VALUE, externalIdCounter))
994                 .build();
995         PortExternalIds oneBad = new PortExternalIdsBuilder()
996                 .setExternalIdKey(String.format(FORMAT_STR,
997                         testOneGoodExternalIdOneMalformedExternalIdValueName, NO_VALUE_FOR_KEY, ++externalIdCounter))
998                 .build();
999         List<PortExternalIds> oneGoodOneBadInput = (List<PortExternalIds>) Lists.newArrayList(
1000                 oneGood, oneBad);
1001         List<PortExternalIds> oneGoodOneBadExpected = null;
1002         testCase = Maps.newHashMap();
1003         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
1004         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
1005         testMap.put(testOneGoodExternalIdOneMalformedExternalIdValueName, testCase);
1006
1007         // Test Case 4:  TestOneGoodExternalIdOneMalformedExternalIdKey
1008         // Test Type:    Negative
1009         // Description:
1010         //     One perfectly fine PortExternalId
1011         //        (TestOneGoodExternalIdOneMalformedExternalIdValue_PortExternalIdKey_1,
1012         //        TestOneGoodExternalIdOneMalformedExternalId_PortExternalIdValue_1)
1013         //     and one malformed PortExternalId which only has key specified
1014         //        (UNSPECIFIED,
1015         //        TestOneGoodExternalIdOneMalformedExternalIdKey_NoKeyForValue_2)
1016         // Expected:     A port is created without any external_ids
1017         final String testOneGoodExternalIdOneMalformedExternalIdKeyName =
1018                 "TestOneGoodExternalIdOneMalformedExternalIdKey";
1019         externalIdCounter = 0;
1020         oneGood = new PortExternalIdsBuilder()
1021                 .setExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdKeyName,
1022                         GOOD_KEY, ++externalIdCounter))
1023                 .setExternalIdValue(String.format(FORMAT_STR,
1024                         testOneGoodExternalIdOneMalformedExternalIdKeyName,
1025                         GOOD_VALUE, externalIdCounter))
1026                 .build();
1027         oneBad = new PortExternalIdsBuilder()
1028                 .setExternalIdKey(String.format(FORMAT_STR,
1029                         testOneGoodExternalIdOneMalformedExternalIdKeyName, NO_KEY_FOR_VALUE, ++externalIdCounter))
1030                 .build();
1031         oneGoodOneBadInput = (List<PortExternalIds>) Lists.newArrayList(
1032                 oneGood, oneBad);
1033         oneGoodOneBadExpected = null;
1034         testCase = Maps.newHashMap();
1035         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
1036         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
1037         testMap.put(testOneGoodExternalIdOneMalformedExternalIdKeyName, testCase);
1038
1039         return testMap;
1040     }
1041
1042     /*
1043      * @see <code>SouthboundIT.testCRUDPortExternalIds()</code>
1044      * This is helper test method to compare a test "set" of BridgeExternalIds against an expected "set"
1045      */
1046     private void assertExpectedPortExternalIdsExist( List<PortExternalIds> expected,
1047                                                      List<PortExternalIds> test ) {
1048
1049         if (expected != null) {
1050             for (PortExternalIds expectedExternalId : expected) {
1051                 Assert.assertTrue(test.contains(expectedExternalId));
1052             }
1053         }
1054     }
1055
1056     /*
1057      * Tests the CRUD operations for <code>Port</code>
1058      * <code>external_ids</code>.
1059      *
1060      * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for
1061      * specific test case information
1062      */
1063     @Test
1064     public void testCRUDTerminationPointPortExternalIds()
1065             throws InterruptedException, ExecutionException {
1066
1067         final String TEST_PREFIX = "CRUDTPPortExternalIds";
1068
1069         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
1070         connectOvsdbNode(connectionInfo);
1071
1072         // updateFromTestCases represent the original test case value.
1073         // updateToTestCases represent the new value after the update has been
1074         // performed.
1075         Map<String, Map<String, List<PortExternalIds>>> updateFromTestCases =
1076                 generatePortExternalIdsTestCases();
1077         Map<String, Map<String, List<PortExternalIds>>> updateToTestCases =
1078                 generatePortExternalIdsTestCases();
1079         Map<String, List<PortExternalIds>> updateFromTestCase;
1080         List<PortExternalIds> updateFromInputExternalIds;
1081         List<PortExternalIds> updateFromExpectedExternalIds;
1082         Map<String, List<PortExternalIds>> updateToTestCase;
1083         List<PortExternalIds> updateToInputExternalIds;
1084         List<PortExternalIds> updateToExpectedExternalIds;
1085         String testBridgeName;
1086         String testPortName;
1087
1088         int counter = 1;
1089         // multihreads the test using NUM_THREADS
1090         ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
1091         for (String updateFromTestCaseKey : updateFromTestCases.keySet()) {
1092             updateFromTestCase = updateFromTestCases.get(
1093                     updateFromTestCaseKey);
1094             updateFromInputExternalIds = updateFromTestCase.get(
1095                     INPUT_VALUES_KEY);
1096             updateFromExpectedExternalIds = updateFromTestCase.get(
1097                     EXPECTED_VALUES_KEY);
1098             for (String testCaseKey : updateToTestCases.keySet()) {
1099                 testPortName = testBridgeName = String.format("%s_%s_%d",
1100                         TEST_PREFIX, testCaseKey, counter);
1101                 counter += 1;
1102                 updateToTestCase = updateToTestCases.get(testCaseKey);
1103                 updateToInputExternalIds = updateToTestCase.get(
1104                         INPUT_VALUES_KEY);
1105                 updateToExpectedExternalIds = updateToTestCase.get(
1106                         EXPECTED_VALUES_KEY);
1107                 TestCRUDTerminationPointPortExternalIdsRunnable testRunnable =
1108                         new TestCRUDTerminationPointPortExternalIdsRunnable(
1109                                 connectionInfo, testBridgeName, testPortName,
1110                                 updateFromInputExternalIds,
1111                                 updateFromExpectedExternalIds,
1112                                 updateToInputExternalIds,
1113                                 updateToExpectedExternalIds);
1114                 executor.submit(testRunnable);
1115             }
1116         }
1117         executor.shutdown();
1118         executor.awaitTermination(5, TimeUnit.MINUTES);
1119         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1120     }
1121
1122     class TestCRUDTerminationPointPortExternalIdsRunnable implements Runnable {
1123         ConnectionInfo connectionInfo;
1124         String testBridgeName;
1125         String testPortName;
1126         List<PortExternalIds> updateFromInputExternalIds;
1127         List<PortExternalIds> updateFromExpectedExternalIds;
1128         List<PortExternalIds> updateToInputExternalIds;
1129         List<PortExternalIds> updateToExpectedExternalIds;
1130
1131         public TestCRUDTerminationPointPortExternalIdsRunnable(
1132                 ConnectionInfo connectionInfo,
1133                 String testBridgeName, String testPortName,
1134                 List<PortExternalIds> updateFromInputExternalIds,
1135                 List<PortExternalIds> updateFromExpectedExternalIds,
1136                 List<PortExternalIds> updateToInputExternalIds,
1137                 List<PortExternalIds> updateToExpectedExternalIds) {
1138
1139             this.connectionInfo = connectionInfo;
1140             this.testBridgeName = testBridgeName;
1141             this.testPortName = testPortName;
1142             this.updateFromInputExternalIds = updateFromInputExternalIds;
1143             this.updateFromExpectedExternalIds = updateFromExpectedExternalIds;
1144             this.updateToInputExternalIds = updateToInputExternalIds;
1145             this.updateToExpectedExternalIds = updateToExpectedExternalIds;
1146         }
1147
1148         @Override
1149         public void run() {
1150             try {
1151                 test();
1152             } catch (InterruptedException e) {
1153                 e.printStackTrace();
1154             }
1155         }
1156
1157         private void test() throws InterruptedException {
1158
1159             final int TERMINATION_POINT_TEST_INDEX = 0;
1160             // CREATE: Create the test bridge
1161             Assert.assertTrue(addBridge(connectionInfo, null,
1162                     testBridgeName, null, true,
1163                     SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
1164                     true, null, null, null, null));
1165             NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
1166                     connectionInfo, new OvsdbBridgeName(testBridgeName)));
1167             OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
1168                     createGenericOvsdbTerminationPointAugmentationBuilder();
1169             tpCreateAugmentationBuilder.setName(testPortName);
1170             tpCreateAugmentationBuilder.setPortExternalIds(updateFromInputExternalIds);
1171             Assert.assertTrue(addTerminationPoint(testBridgeNodeId, testPortName, tpCreateAugmentationBuilder));
1172
1173             // READ: Read the test port and ensure changes are propagated to the CONFIGURATION data store,
1174             // then repeat for OPERATIONAL data store
1175             OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
1176                     getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1177                             LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1178             List<PortExternalIds> updateFromConfigurationExternalIds =
1179                     updateFromConfigurationTerminationPointAugmentation
1180                             .getPortExternalIds();
1181             assertExpectedPortExternalIdsExist(updateFromExpectedExternalIds, updateFromConfigurationExternalIds);
1182             OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmenation =
1183                     getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1184                             LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1185             List<PortExternalIds> updateFromOperationalExternalIds = updateFromOperationalTerminationPointAugmenation
1186                     .getPortExternalIds();
1187             assertExpectedPortExternalIdsExist(updateFromExpectedExternalIds, updateFromOperationalExternalIds);
1188
1189             // UPDATE:  update the external_ids
1190             testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeName).getNodeId();
1191             OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1192                     new OvsdbTerminationPointAugmentationBuilder();
1193             tpUpdateAugmentationBuilder.setPortExternalIds(updateToInputExternalIds);
1194             InstanceIdentifier portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1195             NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1196             NodeId portUpdateNodeId = createManagedNodeId(portIid);
1197             portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1198             TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1199             tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testPortName)));
1200             tpUpdateBuilder.addAugmentation(
1201                     OvsdbTerminationPointAugmentation.class,
1202                     tpUpdateAugmentationBuilder.build());
1203             portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1204             boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1205                     portIid, portUpdateNodeBuilder.build());
1206             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1207             Assert.assertTrue(result);
1208
1209             // READ: the test port and ensure changes are propagated to the CONFIGURATION data store,
1210             // then repeat for OPERATIONAL data store
1211             OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
1212                     getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1213                             LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1214             List<PortExternalIds> updateToConfigurationExternalIds = updateToConfigurationTerminationPointAugmentation
1215                     .getPortExternalIds();
1216             assertExpectedPortExternalIdsExist(updateToExpectedExternalIds, updateToConfigurationExternalIds);
1217             assertExpectedPortExternalIdsExist(updateFromExpectedExternalIds, updateToConfigurationExternalIds);
1218             OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
1219                     getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1220                             LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1221             List<PortExternalIds> updateToOperationalExternalIds =
1222                     updateToOperationalTerminationPointAugmentation.getPortExternalIds();
1223             if (updateFromExpectedExternalIds != null) {
1224                 assertExpectedPortExternalIdsExist(updateToExpectedExternalIds, updateToOperationalExternalIds);
1225                 assertExpectedPortExternalIdsExist(updateFromExpectedExternalIds, updateToOperationalExternalIds);
1226             }
1227
1228             // DELETE
1229             Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
1230         }
1231     }
1232
1233
1234
1235     /*
1236      * Generates the test cases involved in testing InterfaceExternalIds.  See inline comments for descriptions of
1237      * the particular cases considered.
1238      *
1239      * The return value is a Map in the form (K,V)=(testCaseName,testCase).
1240      * - testCaseName is a String
1241      * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of
1242      *     either corresponding INPUT interface external_ids, or EXPECTED interface external_ids
1243      *     INPUT    is the List we use when calling
1244      *              <code>TerminationPointAugmentationBuilder.setInterfaceExternalIds()</code>
1245      *     EXPECTED is the List we expect to receive after calling
1246      *              <code>TerminationPointAugmentationBuilder.getInterfaceExternalIds()</code>
1247      */
1248     private Map<String, Map<String, List<InterfaceExternalIds>>> generateInterfaceExternalIdsTestCases() {
1249         Map<String, Map<String, List<InterfaceExternalIds>>> testMap =
1250                 new HashMap<String, Map<String, List<InterfaceExternalIds>>>();
1251
1252         final String INTERFACE_EXTERNAL_ID_KEY = "IntExternalIdKey";
1253         final String INTERFACE_EXTERNAL_ID_VALUE = "IntExternalIdValue";
1254         final String FORMAT_STR = "%s_%s_%d";
1255         final String GOOD_KEY = "GoodKey";
1256         final String GOOD_VALUE = "GoodValue";
1257         final String NO_VALUE_FOR_KEY = "NoValueForKey";
1258         final String NO_KEY_FOR_VALUE = "NoKeyForValue";
1259
1260         // Test Case 1:  TestOneExternalId
1261         // Test Type:    Positive
1262         // Description:  Create a termination point with one InterfaceExternalIds
1263         // Expected:     A termination point is created with the single external_ids specified below
1264         final String testOneExternalIdName = "TestOneExternalId";
1265         int externalIdCounter = 0;
1266         List<InterfaceExternalIds> oneExternalId = (List<InterfaceExternalIds>) Lists.newArrayList(
1267                 (new InterfaceExternalIdsBuilder()
1268                         .setExternalIdKey(String.format(FORMAT_STR, testOneExternalIdName,
1269                                 INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter))
1270                         .setExternalIdValue(String.format(FORMAT_STR, testOneExternalIdName,
1271                                 INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter))
1272                         .build()));
1273         Map<String,List<InterfaceExternalIds>> testCase = Maps.newHashMap();
1274         testCase.put(EXPECTED_VALUES_KEY, oneExternalId);
1275         testCase.put(INPUT_VALUES_KEY, oneExternalId);
1276         testMap.put(testOneExternalIdName, testCase);
1277
1278         // Test Case 2:  TestFiveExternalId
1279         // Test Type:    Positive
1280         // Description:  Create a termination point with multiple (five) InterfaceExternalIds
1281         // Expected:     A termination point is created with the five external_ids specified below
1282         final String testFiveExternalIdName = "TestFiveExternalId";
1283         externalIdCounter = 0;
1284         List<InterfaceExternalIds> fiveExternalId = (List<InterfaceExternalIds>) Lists.newArrayList(
1285                 (new InterfaceExternalIdsBuilder()
1286                         .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
1287                                 INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter))
1288                         .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
1289                                 INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter))
1290                         .build()),
1291                 (new InterfaceExternalIdsBuilder()
1292                         .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
1293                                 INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter))
1294                         .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
1295                                 INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter))
1296                         .build()),
1297                 (new InterfaceExternalIdsBuilder()
1298                         .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
1299                                 INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter))
1300                         .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
1301                                 INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter))
1302                         .build()),
1303                 (new InterfaceExternalIdsBuilder()
1304                         .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
1305                                 INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter))
1306                         .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
1307                                 INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter))
1308                         .build()),
1309                 (new InterfaceExternalIdsBuilder()
1310                         .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
1311                                 INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter))
1312                         .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
1313                                 INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter))
1314                         .build()));
1315         testCase = Maps.newHashMap();
1316         testCase.put(EXPECTED_VALUES_KEY, fiveExternalId);
1317         testCase.put(INPUT_VALUES_KEY, fiveExternalId);
1318         testMap.put(testFiveExternalIdName, testCase);
1319
1320         // Test Case 3:  TestOneGoodExternalIdOneMalformedExternalIdValue
1321         // Test Type:    Negative
1322         // Description:
1323         //     One perfectly fine InterfaceExternalId
1324         //        (TestOneGoodExternalIdOneMalformedExternalIdValue_IntExternalIdKey_1,
1325         //        TestOneGoodExternalIdOneMalformedExternalId_IntExternalIdValue_1)
1326         //     and one malformed PortExternalId which only has key specified
1327         //        (TestOneGoodExternalIdOneMalformedExternalIdValue_NoValueForKey_2,
1328         //        UNSPECIFIED)
1329         // Expected:     A termination point is created without any external_ids
1330         final String testOneGoodExternalIdOneMalformedExternalIdValueName =
1331                 "TestOneGoodExternalIdOneMalformedExternalIdValue";
1332         externalIdCounter = 0;
1333         InterfaceExternalIds oneGood = new InterfaceExternalIdsBuilder()
1334                 .setExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdValueName,
1335                         GOOD_KEY, ++externalIdCounter))
1336                 .setExternalIdValue(String.format(FORMAT_STR,
1337                         testOneGoodExternalIdOneMalformedExternalIdValueName,
1338                         GOOD_VALUE, externalIdCounter))
1339                 .build();
1340         InterfaceExternalIds oneBad = new InterfaceExternalIdsBuilder()
1341                 .setExternalIdKey(String.format(FORMAT_STR,
1342                         testOneGoodExternalIdOneMalformedExternalIdValueName, NO_VALUE_FOR_KEY, ++externalIdCounter))
1343                 .build();
1344         List<InterfaceExternalIds> oneGoodOneBadInput = (List<InterfaceExternalIds>) Lists.newArrayList(
1345                 oneGood, oneBad);
1346         List<InterfaceExternalIds> oneGoodOneBadExpected = null;
1347         testCase = Maps.newHashMap();
1348         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
1349         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
1350         testMap.put(testOneGoodExternalIdOneMalformedExternalIdValueName, testCase);
1351
1352         // Test Case 4:  TestOneGoodExternalIdOneMalformedExternalIdKey
1353         // Test Type:    Negative
1354         // Description:
1355         //     One perfectly fine InterfaceExternalId
1356         //        (TestOneGoodExternalIdOneMalformedExternalIdValue_IntExternalIdKey_1,
1357         //        TestOneGoodExternalIdOneMalformedExternalId_IntExternalIdValue_1)
1358         //     and one malformed BridgeExternalId which only has key specified
1359         //        (UNSPECIFIED,
1360         //        TestOneGoodExternalIdOneMalformedExternalIdKey_NoKeyForValue_2)
1361         // Expected:     A termination point is created without any external_ids
1362         final String testOneGoodExternalIdOneMalformedExternalIdKeyName =
1363                 "TestOneGoodExternalIdOneMalformedExternalIdKey";
1364         externalIdCounter = 0;
1365         oneGood = new InterfaceExternalIdsBuilder()
1366                 .setExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdKeyName,
1367                         GOOD_KEY, ++externalIdCounter))
1368                 .setExternalIdValue(String.format(FORMAT_STR,
1369                         testOneGoodExternalIdOneMalformedExternalIdKeyName,
1370                         GOOD_VALUE, externalIdCounter))
1371                 .build();
1372         oneBad = new InterfaceExternalIdsBuilder()
1373                 .setExternalIdKey(String.format(FORMAT_STR,
1374                         testOneGoodExternalIdOneMalformedExternalIdKeyName, NO_KEY_FOR_VALUE, ++externalIdCounter))
1375                 .build();
1376         oneGoodOneBadInput = (List<InterfaceExternalIds>) Lists.newArrayList(
1377                 oneGood, oneBad);
1378         oneGoodOneBadExpected = null;
1379         testCase = Maps.newHashMap();
1380         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
1381         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
1382         testMap.put(testOneGoodExternalIdOneMalformedExternalIdKeyName, testCase);
1383
1384         return testMap;
1385     }
1386
1387     /*
1388      * @see <code>SouthboundIT.testCRUDInterfaceExternalIds()</code>
1389      * This is helper test method to compare a test "set" of InterfaceExternalIds against an expected "set"
1390      */
1391     private void assertExpectedInterfaceExternalIdsExist( List<InterfaceExternalIds> expected,
1392                                                           List<InterfaceExternalIds> test ) {
1393
1394         if (expected != null) {
1395             for (InterfaceExternalIds expectedExternalId : expected) {
1396                 Assert.assertTrue(test.contains(expectedExternalId));
1397             }
1398         }
1399     }
1400
1401     /*
1402      * Tests the CRUD operations for <code>Interface</code> <code>external_ids</code>.
1403      *
1404      * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1405      */
1406     @Test
1407     public void testCRUDTerminationPointInterfaceExternalIds() throws InterruptedException, ExecutionException {
1408         final String TEST_PREFIX = "CRUDTPInterfaceExternalIds";
1409         final int TERMINATION_POINT_TEST_INDEX = 0;
1410
1411         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
1412         connectOvsdbNode(connectionInfo);
1413
1414         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
1415         // the update has been performed.
1416         Map<String, Map<String, List<InterfaceExternalIds>>> updateFromTestCases =
1417                 generateInterfaceExternalIdsTestCases();
1418         Map<String, Map<String, List<InterfaceExternalIds>>> updateToTestCases =
1419                 generateInterfaceExternalIdsTestCases();
1420         Map<String, List<InterfaceExternalIds>> updateFromTestCase;
1421         List<InterfaceExternalIds> updateFromInputExternalIds;
1422         List<InterfaceExternalIds> updateFromExpectedExternalIds;
1423         Map<String, List<InterfaceExternalIds>> updateToTestCase;
1424         List<InterfaceExternalIds> updateToInputExternalIds;
1425         List<InterfaceExternalIds> updateToExpectedExternalIds;
1426         String testBridgeName;
1427         String testPortName;
1428
1429         int counter = 1;
1430         // multihreads the test using NUM_THREADS
1431         ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
1432         for (String updateFromTestCaseKey : updateFromTestCases.keySet()) {
1433             updateFromTestCase = updateFromTestCases.get(updateFromTestCaseKey);
1434             updateFromInputExternalIds = updateFromTestCase.get(INPUT_VALUES_KEY);
1435             updateFromExpectedExternalIds = updateFromTestCase.get(EXPECTED_VALUES_KEY);
1436             for (String testCaseKey : updateToTestCases.keySet()) {
1437                 testPortName = testBridgeName = String.format("%s_%s_%d", TEST_PREFIX, testCaseKey, counter);
1438                 counter += 1;
1439                 updateToTestCase = updateToTestCases.get(testCaseKey);
1440                 updateToInputExternalIds = updateToTestCase.get(INPUT_VALUES_KEY);
1441                 updateToExpectedExternalIds = updateToTestCase.get(EXPECTED_VALUES_KEY);
1442
1443                 TestCRUDTerminationPointInterfaceExternalIdsRunnable testRunnable =
1444                         new TestCRUDTerminationPointInterfaceExternalIdsRunnable(
1445                                 connectionInfo, testBridgeName, testPortName,
1446                                 updateFromInputExternalIds,
1447                                 updateFromExpectedExternalIds,
1448                                 updateToInputExternalIds,
1449                                 updateToExpectedExternalIds);
1450                 executor.submit(testRunnable);
1451             }
1452         }
1453         executor.shutdown();
1454         executor.awaitTermination(5, TimeUnit.MINUTES);
1455         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1456     }
1457
1458     class TestCRUDTerminationPointInterfaceExternalIdsRunnable implements Runnable {
1459
1460         ConnectionInfo connectionInfo;
1461         String testBridgeName;
1462         String testPortName;
1463         List<InterfaceExternalIds> updateFromInputExternalIds;
1464         List<InterfaceExternalIds> updateFromExpectedExternalIds;
1465         List<InterfaceExternalIds> updateToInputExternalIds;
1466         List<InterfaceExternalIds> updateToExpectedExternalIds;
1467
1468         TestCRUDTerminationPointInterfaceExternalIdsRunnable(
1469                 ConnectionInfo connectionInfo, String testBridgeName,
1470                 String testPortName,
1471                 List<InterfaceExternalIds> updateFromInputExternalIds,
1472                 List<InterfaceExternalIds> updateFromExpectedExternalIds,
1473                 List<InterfaceExternalIds> updateToInputExternalIds,
1474                 List<InterfaceExternalIds> updateToExpectedExternalIds) {
1475
1476             this.connectionInfo = connectionInfo;
1477             this.testBridgeName = testBridgeName;
1478             this.testPortName = testPortName;
1479             this.updateFromInputExternalIds = updateFromInputExternalIds;
1480             this.updateFromExpectedExternalIds = updateFromExpectedExternalIds;
1481             this.updateToInputExternalIds = updateToInputExternalIds;
1482             this.updateToExpectedExternalIds = updateToExpectedExternalIds;
1483         }
1484
1485         @Override
1486         public void run() {
1487             try {
1488                 test();
1489             } catch (InterruptedException e) {
1490                 e.printStackTrace();
1491             }
1492         }
1493
1494         public void test() throws InterruptedException {
1495
1496             final int TERMINATION_POINT_TEST_INDEX = 0;
1497             // CREATE: Create the test interface
1498             Assert.assertTrue(addBridge(connectionInfo, null,
1499                     testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
1500                     true, null, null, null, null));
1501             NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
1502                     connectionInfo, new OvsdbBridgeName(testBridgeName)));
1503             OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
1504                     createGenericOvsdbTerminationPointAugmentationBuilder();
1505             tpCreateAugmentationBuilder.setName(testPortName);
1506             tpCreateAugmentationBuilder.setInterfaceExternalIds(updateFromInputExternalIds);
1507             Assert.assertTrue(addTerminationPoint(testBridgeNodeId, testPortName, tpCreateAugmentationBuilder));
1508
1509             // READ: Read the test interface and ensure changes are propagated to the CONFIGURATION data store,
1510             // then repeat for OPERATIONAL data store
1511             OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
1512                     getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1513                             LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1514             List<InterfaceExternalIds> updateFromConfigurationExternalIds =
1515                     updateFromConfigurationTerminationPointAugmentation
1516                             .getInterfaceExternalIds();
1517             assertExpectedInterfaceExternalIdsExist(updateFromExpectedExternalIds,
1518                     updateFromConfigurationExternalIds);
1519             OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmenation =
1520                     getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1521                             LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1522             List<InterfaceExternalIds> updateFromOperationalExternalIds =
1523                     updateFromOperationalTerminationPointAugmenation
1524                             .getInterfaceExternalIds();
1525             assertExpectedInterfaceExternalIdsExist(updateFromExpectedExternalIds,
1526                     updateFromOperationalExternalIds);
1527
1528             // UPDATE:  update the external_ids
1529             testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeName).getNodeId();
1530             OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1531                     new OvsdbTerminationPointAugmentationBuilder();
1532             tpUpdateAugmentationBuilder.setInterfaceExternalIds(updateToInputExternalIds);
1533             InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1534             NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1535             NodeId portUpdateNodeId = createManagedNodeId(portIid);
1536             portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1537             TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1538             tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testPortName)));
1539             tpUpdateBuilder.addAugmentation(
1540                     OvsdbTerminationPointAugmentation.class,
1541                     tpUpdateAugmentationBuilder.build());
1542             portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1543             boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1544                     portIid, portUpdateNodeBuilder.build());
1545             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1546             Assert.assertTrue(result);
1547
1548             // READ: the test interface and ensure changes are propagated to the CONFIGURATION data store,
1549             // then repeat for OPERATIONAL data store
1550             OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
1551                     getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1552                             LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1553             List<InterfaceExternalIds> updateToConfigurationExternalIds =
1554                     updateToConfigurationTerminationPointAugmentation
1555                     .getInterfaceExternalIds();
1556             assertExpectedInterfaceExternalIdsExist(updateToExpectedExternalIds, updateToConfigurationExternalIds);
1557             assertExpectedInterfaceExternalIdsExist(updateFromExpectedExternalIds,
1558                     updateToConfigurationExternalIds);
1559             OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
1560                     getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1561                             LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1562             List<InterfaceExternalIds> updateToOperationalExternalIds = updateToOperationalTerminationPointAugmentation
1563                     .getInterfaceExternalIds();
1564             if (updateFromExpectedExternalIds != null) {
1565                 assertExpectedInterfaceExternalIdsExist(updateToExpectedExternalIds,
1566                         updateToOperationalExternalIds);
1567                 assertExpectedInterfaceExternalIdsExist(updateFromExpectedExternalIds,
1568                         updateToOperationalExternalIds);
1569             } else {
1570                 Assert.assertNull(updateToOperationalExternalIds);
1571             }
1572
1573             // DELETE
1574             Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
1575         }
1576     }
1577
1578     /*
1579      * Generates the test cases involved in testing TP Options.  See inline comments for descriptions of
1580      * the particular cases considered.
1581      *
1582      * The return value is a Map in the form (K,V)=(testCaseName,testCase).
1583      * - testCaseName is a String
1584      * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of
1585      *     either corresponding INPUT TP Options, or EXPECTED TP Options
1586      *     INPUT    is the List we use when calling
1587      *              <code>TerminationPointAugmentationBuilder.setOptions()</code>
1588      *     EXPECTED is the List we expect to receive after calling
1589      *              <code>TerminationPointAugmentationBuilder.getOptions()</code>
1590      */
1591     private Map<String, Map<String, List<Options>>> generateTerminationPointOptionsTestCases() {
1592         Map<String, Map<String, List<Options>>> testMap =
1593                 new HashMap<String, Map<String, List<Options>>>();
1594
1595         final String TP_OPTIONS_KEY = "TPOptionsKey";
1596         final String TP_OPTIONS_VALUE = "TPOptionsValue";
1597         final String FORMAT_STR = "%s_%s_%d";
1598         final String GOOD_KEY = "GoodKey";
1599         final String GOOD_VALUE = "GoodValue";
1600         final String NO_VALUE_FOR_KEY = "NoValueForKey";
1601         final String NO_KEY_FOR_VALUE = "NoKeyForValue";
1602
1603         // Test Case 1:  TestOneOptions
1604         // Test Type:    Positive
1605         // Description:  Create a termination point with one Options
1606         // Expected:     A termination point is created with the single Options specified below
1607         final String testOneOptionsName = "TestOneOptions";
1608         int optionsCounter = 0;
1609         List<Options> oneOptions = (List<Options>) Lists.newArrayList(
1610                 (new OptionsBuilder()
1611                         .setOption(String.format(FORMAT_STR, testOneOptionsName,
1612                                 TP_OPTIONS_KEY, ++optionsCounter))
1613                         .setValue(String.format(FORMAT_STR, testOneOptionsName,
1614                                 TP_OPTIONS_VALUE, optionsCounter))
1615                         .build()));
1616         Map<String,List<Options>> testCase = Maps.newHashMap();
1617         testCase.put(EXPECTED_VALUES_KEY, oneOptions);
1618         testCase.put(INPUT_VALUES_KEY, oneOptions);
1619         testMap.put(testOneOptionsName, testCase);
1620
1621         // Test Case 2:  TestFiveOptions
1622         // Test Type:    Positive
1623         // Description:  Create a termination point with multiple (five) Options
1624         // Expected:     A termination point is created with the five options specified below
1625         final String testFiveOptionsName = "TestFiveOptions";
1626         optionsCounter = 0;
1627         List<Options> fiveOptions = (List<Options>) Lists.newArrayList(
1628                 (new OptionsBuilder()
1629                         .setOption(String.format(FORMAT_STR, testFiveOptionsName,
1630                                 TP_OPTIONS_KEY, ++optionsCounter))
1631                         .setValue(String.format(FORMAT_STR, testFiveOptionsName,
1632                                 TP_OPTIONS_VALUE, optionsCounter))
1633                         .build()),
1634                 (new OptionsBuilder()
1635                         .setOption(String.format(FORMAT_STR, testFiveOptionsName,
1636                                 TP_OPTIONS_KEY, ++optionsCounter))
1637                         .setValue(String.format(FORMAT_STR, testFiveOptionsName,
1638                                 TP_OPTIONS_VALUE, optionsCounter))
1639                         .build()),
1640                 (new OptionsBuilder()
1641                         .setOption(String.format(FORMAT_STR, testFiveOptionsName,
1642                                 TP_OPTIONS_KEY, ++optionsCounter))
1643                         .setValue(String.format(FORMAT_STR, testFiveOptionsName,
1644                                 TP_OPTIONS_VALUE, optionsCounter))
1645                         .build()),
1646                 (new OptionsBuilder()
1647                         .setOption(String.format(FORMAT_STR, testFiveOptionsName,
1648                                 TP_OPTIONS_KEY, ++optionsCounter))
1649                         .setValue(String.format(FORMAT_STR, testFiveOptionsName,
1650                                 TP_OPTIONS_VALUE, optionsCounter))
1651                         .build()),
1652                 (new OptionsBuilder()
1653                         .setOption(String.format(FORMAT_STR, testFiveOptionsName,
1654                                 TP_OPTIONS_KEY, ++optionsCounter))
1655                         .setValue(String.format(FORMAT_STR, testFiveOptionsName,
1656                                 TP_OPTIONS_VALUE, optionsCounter))
1657                         .build()));
1658         testCase = Maps.newHashMap();
1659         testCase.put(EXPECTED_VALUES_KEY, fiveOptions);
1660         testCase.put(INPUT_VALUES_KEY, fiveOptions);
1661         testMap.put(testFiveOptionsName, testCase);
1662
1663         // Test Case 3:  TestOneGoodOptionsOneMalformedOptionsValue
1664         // Test Type:    Negative
1665         // Description:
1666         //     One perfectly fine Options
1667         //        (TestOneGoodOptionsOneMalformedOptionsValue_OptionsKey_1,
1668         //        TestOneGoodOptionsOneMalformedOptions_OptionsValue_1)
1669         //     and one malformed Options which only has key specified
1670         //        (TestOneGoodOptionsOneMalformedOptionsValue_NoValueForKey_2,
1671         //        UNSPECIFIED)
1672         // Expected:     A termination point is created without any options
1673         final String testOneGoodOptionsOneMalformedOptionsValueName =
1674                 "TestOneGoodOptionsOneMalformedOptionsValue";
1675         optionsCounter = 0;
1676         Options oneGood = new OptionsBuilder()
1677                 .setOption(String.format(FORMAT_STR, testOneGoodOptionsOneMalformedOptionsValueName,
1678                         GOOD_KEY, ++optionsCounter))
1679                 .setValue(String.format(FORMAT_STR,
1680                         testOneGoodOptionsOneMalformedOptionsValueName,
1681                         GOOD_VALUE, optionsCounter))
1682                 .build();
1683         Options oneBad = new OptionsBuilder()
1684                 .setOption(String.format(FORMAT_STR,
1685                         testOneGoodOptionsOneMalformedOptionsValueName, NO_VALUE_FOR_KEY, ++optionsCounter))
1686                 .build();
1687         List<Options> oneGoodOneBadInput = (List<Options>) Lists.newArrayList(
1688                 oneGood, oneBad);
1689         List<Options> oneGoodOneBadExpected = null;
1690         testCase = Maps.newHashMap();
1691         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
1692         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
1693         testMap.put(testOneGoodOptionsOneMalformedOptionsValueName, testCase);
1694
1695         // Test Case 4:  TestOneGoodOptionsOneMalformedOptionsKey
1696         // Test Type:    Negative
1697         // Description:
1698         //     One perfectly fine Options
1699         //        (TestOneGoodOptionsOneMalformedOptionsValue_OptionsKey_1,
1700         //        TestOneGoodOptionsOneMalformedOptions_OptionsValue_1)
1701         //     and one malformed Options which only has key specified
1702         //        (UNSPECIFIED,
1703         //        TestOneGoodOptionsOneMalformedOptionsKey_NoKeyForValue_2)
1704         // Expected:     A termination point is created without any options
1705         final String testOneGoodOptionsOneMalformedOptionsKeyName =
1706                 "TestOneGoodOptionsOneMalformedOptionsKey";
1707         optionsCounter = 0;
1708         oneGood = new OptionsBuilder()
1709                 .setOption(String.format(FORMAT_STR, testOneGoodOptionsOneMalformedOptionsKeyName,
1710                         GOOD_KEY, ++optionsCounter))
1711                 .setValue(String.format(FORMAT_STR,
1712                         testOneGoodOptionsOneMalformedOptionsKeyName,
1713                         GOOD_VALUE, optionsCounter))
1714                 .build();
1715         oneBad = new OptionsBuilder()
1716                 .setOption(String.format(FORMAT_STR,
1717                         testOneGoodOptionsOneMalformedOptionsKeyName, NO_KEY_FOR_VALUE, ++optionsCounter))
1718                 .build();
1719         oneGoodOneBadInput = (List<Options>) Lists.newArrayList(
1720                 oneGood, oneBad);
1721         oneGoodOneBadExpected = null;
1722         testCase = Maps.newHashMap();
1723         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
1724         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
1725         testMap.put(testOneGoodOptionsOneMalformedOptionsKeyName, testCase);
1726
1727         return testMap;
1728     }
1729
1730     /*
1731      * @see <code>SouthboundIT.testCRUDTerminationPointOptions()</code>
1732      * This is helper test method to compare a test "set" of Options against an expected "set"
1733      */
1734     private void assertExpectedOptionsExist( List<Options> expected,
1735                                              List<Options> test ) {
1736
1737         if (expected != null) {
1738             for (Options expectedOption : expected) {
1739                 Assert.assertTrue(test.contains(expectedOption));
1740             }
1741         }
1742     }
1743
1744     /*
1745      * Tests the CRUD operations for <code>TerminationPoint</code> <code>options</code>.
1746      *
1747      * @see <code>SouthboundIT.generateTerminationPointOptions()</code> for specific test case information
1748      */
1749     @Test
1750     public void testCRUDTerminationPointOptions() throws InterruptedException {
1751         final String TEST_PREFIX = "CRUDTPOptions";
1752
1753         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
1754         connectOvsdbNode(connectionInfo);
1755
1756         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
1757         // the update has been performed.
1758         Map<String, Map<String, List<Options>>> updateFromTestCases =
1759                 generateTerminationPointOptionsTestCases();
1760         Map<String, Map<String, List<Options>>> updateToTestCases =
1761                 generateTerminationPointOptionsTestCases();
1762         Map<String, List<Options>> updateFromTestCase;
1763         List<Options> updateFromInputOptions;
1764         List<Options> updateFromExpectedOptions;
1765         Map<String, List<Options>> updateToTestCase;
1766         List<Options> updateToInputOptions;
1767         List<Options> updateToExpectedOptions;
1768         String testBridgeName;
1769         String testPortName;
1770
1771         int counter = 1;
1772         ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
1773         for (String updateFromTestCaseKey : updateFromTestCases.keySet()) {
1774             updateFromTestCase = updateFromTestCases.get(updateFromTestCaseKey);
1775             updateFromInputOptions = updateFromTestCase.get(INPUT_VALUES_KEY);
1776             updateFromExpectedOptions = updateFromTestCase.get(EXPECTED_VALUES_KEY);
1777             for (String testCaseKey : updateToTestCases.keySet()) {
1778                 testPortName = testBridgeName = String.format("%s_%s_%d", TEST_PREFIX, testCaseKey, counter);
1779                 counter += 1;
1780                 updateToTestCase = updateToTestCases.get(testCaseKey);
1781                 updateToInputOptions = updateToTestCase.get(INPUT_VALUES_KEY);
1782                 updateToExpectedOptions = updateToTestCase.get(EXPECTED_VALUES_KEY);
1783
1784                 TestCRUDTerminationPointOptionsRunnable testRunnable =
1785                         new TestCRUDTerminationPointOptionsRunnable(
1786                                 connectionInfo, testBridgeName, testPortName,
1787                                 updateFromInputOptions,
1788                                 updateFromExpectedOptions,
1789                                 updateToInputOptions,
1790                                 updateToExpectedOptions);
1791                 executor.submit(testRunnable);
1792             }
1793         }
1794         executor.shutdown();
1795         executor.awaitTermination(5, TimeUnit.MINUTES);
1796         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1797     }
1798
1799     class TestCRUDTerminationPointOptionsRunnable implements Runnable {
1800
1801         ConnectionInfo connectionInfo;
1802         String testBridgeName;
1803         String testPortName;
1804         List<Options> updateFromInputOptions;
1805         List<Options> updateFromExpectedOptions;
1806         List<Options> updateToInputOptions;
1807         List<Options> updateToExpectedOptions;
1808
1809         TestCRUDTerminationPointOptionsRunnable(
1810                 ConnectionInfo connectionInfo, String testBridgeName,
1811                 String testPortName,
1812                 List<Options> updateFromInputOptions,
1813                 List<Options> updateFromExpectedOptions,
1814                 List<Options> updateToInputOptions,
1815                 List<Options> updateToExpectedOptions) {
1816
1817             this.connectionInfo = connectionInfo;
1818             this.testBridgeName = testBridgeName;
1819             this.testPortName = testPortName;
1820             this.updateFromInputOptions = updateFromInputOptions;
1821             this.updateFromExpectedOptions = updateFromExpectedOptions;
1822             this.updateToInputOptions = updateToInputOptions;
1823             this.updateToExpectedOptions = updateToExpectedOptions;
1824         }
1825
1826         @Override
1827         public void run() {
1828             try {
1829                 test();
1830             } catch (InterruptedException e) {
1831                 e.printStackTrace();
1832             }
1833         }
1834
1835         public void test() throws InterruptedException {
1836             final int TERMINATION_POINT_TEST_INDEX = 0;
1837             // CREATE: Create the test interface
1838             Assert.assertTrue(addBridge(connectionInfo, null,
1839                     testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
1840                     true, null, null, null, null));
1841             NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
1842                     connectionInfo, new OvsdbBridgeName(testBridgeName)));
1843             OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
1844                     createGenericOvsdbTerminationPointAugmentationBuilder();
1845             tpCreateAugmentationBuilder.setName(testPortName);
1846             tpCreateAugmentationBuilder.setOptions(updateFromInputOptions);
1847             Assert.assertTrue(addTerminationPoint(testBridgeNodeId, testPortName, tpCreateAugmentationBuilder));
1848
1849             // READ: Read the test interface and ensure changes are propagated to the CONFIGURATION data store,
1850             // then repeat for OPERATIONAL data store
1851             OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
1852                     getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1853                             LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1854             List<Options> updateFromConfigurationOptions = updateFromConfigurationTerminationPointAugmentation
1855                     .getOptions();
1856             assertExpectedOptionsExist(updateFromExpectedOptions,
1857                     updateFromConfigurationOptions);
1858             OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmenation =
1859                     getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1860                             LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1861             List<Options> updateFromOperationalOptions = updateFromOperationalTerminationPointAugmenation
1862                     .getOptions();
1863             assertExpectedOptionsExist(updateFromExpectedOptions,
1864                     updateFromOperationalOptions);
1865
1866             // UPDATE:  update the external_ids
1867             testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeName).getNodeId();
1868             OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1869                     new OvsdbTerminationPointAugmentationBuilder();
1870             tpUpdateAugmentationBuilder.setOptions(updateToInputOptions);
1871             InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1872             NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1873             NodeId portUpdateNodeId = createManagedNodeId(portIid);
1874             portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1875             TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1876             tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testPortName)));
1877             tpUpdateBuilder.addAugmentation(
1878                     OvsdbTerminationPointAugmentation.class,
1879                     tpUpdateAugmentationBuilder.build());
1880             portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1881             boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1882                     portIid, portUpdateNodeBuilder.build());
1883             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1884             Assert.assertTrue(result);
1885
1886             // READ: the test interface and ensure changes are propagated to the CONFIGURATION data store,
1887             // then repeat for OPERATIONAL data store
1888             OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
1889                     getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1890                             LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1891             List<Options> updateToConfigurationOptions = updateToConfigurationTerminationPointAugmentation
1892                     .getOptions();
1893             assertExpectedOptionsExist(updateToExpectedOptions, updateToConfigurationOptions);
1894             assertExpectedOptionsExist(updateFromExpectedOptions, updateToConfigurationOptions);
1895             OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
1896                     getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1897                             LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1898             List<Options> updateToOperationalOptions = updateToOperationalTerminationPointAugmentation
1899                     .getOptions();
1900             if (updateFromExpectedOptions != null) {
1901                 assertExpectedOptionsExist(updateToExpectedOptions, updateToOperationalOptions);
1902                 assertExpectedOptionsExist(updateFromExpectedOptions, updateToOperationalOptions);
1903             }
1904
1905             // DELETE
1906             Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
1907         }
1908     }
1909
1910     /*
1911      * Generates the test cases involved in testing Interface other_configs.  See inline comments for descriptions of
1912      * the particular cases considered.
1913      *
1914      * The return value is a Map in the form (K,V)=(testCaseName,testCase).
1915      * - testCaseName is a String
1916      * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of
1917      *     either corresponding INPUT interface other_configs, or EXPECTED interface other_configs
1918      *     INPUT    is the List we use when calling
1919      *              <code>TerminationPointAugmentationBuilder.setInterfaceOtherConfigs()</code>
1920      *     EXPECTED is the List we expect to receive after calling
1921      *              <code>TerminationPointAugmentationBuilder.getInterfaceOtherConfigs()</code>
1922      */
1923     private Map<String, Map<String, List<InterfaceOtherConfigs>>> generateInterfaceOtherConfigsTestCases() {
1924         Map<String, Map<String, List<InterfaceOtherConfigs>>> testMap =
1925                 new HashMap<String, Map<String, List<InterfaceOtherConfigs>>>();
1926
1927         final String INT_OTHER_CONFIGS_KEY = "IntOtherConfigsKey";
1928         final String INT_OTHER_CONFIGS_VALUE = "IntOtherConfigsValue";
1929         final String FORMAT_STR = "%s_%s_%d";
1930         final String GOOD_KEY = "GoodKey";
1931         final String GOOD_VALUE = "GoodValue";
1932         final String NO_VALUE_FOR_KEY = "NoValueForKey";
1933         final String NO_KEY_FOR_VALUE = "NoKeyForValue";
1934
1935         // Test Case 1:  TestOneOtherConfigs
1936         // Test Type:    Positive
1937         // Description:  Create an interface with one other_Configs
1938         // Expected:     An interface is created with the single other_configs specified below
1939         final String testOneOtherConfigsName = "TestOneInterfaceOtherConfigs";
1940         int otherConfigsCounter = 0;
1941         List<InterfaceOtherConfigs> oneOtherConfigs = (List<InterfaceOtherConfigs>) Lists.newArrayList(
1942                 (new InterfaceOtherConfigsBuilder()
1943                         .setOtherConfigKey(String.format(FORMAT_STR, testOneOtherConfigsName,
1944                                 INT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
1945                         .setOtherConfigValue(String.format(FORMAT_STR, testOneOtherConfigsName,
1946                                 INT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
1947                         .build()));
1948         Map<String,List<InterfaceOtherConfigs>> testCase = Maps.newHashMap();
1949         testCase.put(EXPECTED_VALUES_KEY, oneOtherConfigs);
1950         testCase.put(INPUT_VALUES_KEY, oneOtherConfigs);
1951         testMap.put(testOneOtherConfigsName, testCase);
1952
1953         // Test Case 2:  TestFiveInterfaceOtherConfigs
1954         // Test Type:    Positive
1955         // Description:  Create a termination point with multiple (five) InterfaceOtherConfigs
1956         // Expected:     A termination point is created with the five InterfaceOtherConfigs specified below
1957         final String testFiveInterfaceOtherConfigsName = "TestFiveInterfaceOtherConfigs";
1958         otherConfigsCounter = 0;
1959         List<InterfaceOtherConfigs> fiveInterfaceOtherConfigs = (List<InterfaceOtherConfigs>) Lists.newArrayList(
1960                 (new InterfaceOtherConfigsBuilder()
1961                         .setOtherConfigKey(String.format(FORMAT_STR, testFiveInterfaceOtherConfigsName,
1962                                 INT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
1963                         .setOtherConfigValue(String.format(FORMAT_STR, testFiveInterfaceOtherConfigsName,
1964                                 INT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
1965                         .build()),
1966                 (new InterfaceOtherConfigsBuilder()
1967                         .setOtherConfigKey(String.format(FORMAT_STR, testFiveInterfaceOtherConfigsName,
1968                                 INT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
1969                         .setOtherConfigValue(String.format(FORMAT_STR, testFiveInterfaceOtherConfigsName,
1970                                 INT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
1971                         .build()),
1972                 (new InterfaceOtherConfigsBuilder()
1973                         .setOtherConfigKey(String.format(FORMAT_STR, testFiveInterfaceOtherConfigsName,
1974                                 INT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
1975                         .setOtherConfigValue(String.format(FORMAT_STR, testFiveInterfaceOtherConfigsName,
1976                                 INT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
1977                         .build()),
1978                 (new InterfaceOtherConfigsBuilder()
1979                         .setOtherConfigKey(String.format(FORMAT_STR, testFiveInterfaceOtherConfigsName,
1980                                 INT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
1981                         .setOtherConfigValue(String.format(FORMAT_STR, testFiveInterfaceOtherConfigsName,
1982                                 INT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
1983                         .build()),
1984                 (new InterfaceOtherConfigsBuilder()
1985                         .setOtherConfigKey(String.format(FORMAT_STR, testFiveInterfaceOtherConfigsName,
1986                                 INT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
1987                         .setOtherConfigValue(String.format(FORMAT_STR, testFiveInterfaceOtherConfigsName,
1988                                 INT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
1989                         .build()));
1990         testCase = Maps.newHashMap();
1991         testCase.put(EXPECTED_VALUES_KEY, fiveInterfaceOtherConfigs);
1992         testCase.put(INPUT_VALUES_KEY, fiveInterfaceOtherConfigs);
1993         testMap.put(testFiveInterfaceOtherConfigsName, testCase);
1994
1995         // Test Case 3:  TestOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsValue
1996         // Test Type:    Negative
1997         // Description:
1998         //     One perfectly fine InterfaceOtherConfigs
1999         //        (TestOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsValue_InterfaceOtherConfigsKey_1,
2000         //        TestOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigs_InterfaceOtherConfigsValue_1)
2001         //     and one malformed InterfaceOtherConfigs which only has key specified
2002         //        (TestOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsValue_NoValueForKey_2,
2003         //        UNSPECIFIED)
2004         // Expected:     A termination point is created without any InterfaceOtherConfigs
2005         final String testOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsValueName =
2006                 "TestOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsValue";
2007         otherConfigsCounter = 0;
2008         InterfaceOtherConfigs oneGood = new InterfaceOtherConfigsBuilder()
2009                 .setOtherConfigKey(String.format(FORMAT_STR,
2010                         testOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsValueName,
2011                         GOOD_KEY, ++otherConfigsCounter))
2012                 .setOtherConfigValue(String.format(FORMAT_STR,
2013                         testOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsValueName,
2014                         GOOD_VALUE, otherConfigsCounter))
2015                 .build();
2016         InterfaceOtherConfigs oneBad = new InterfaceOtherConfigsBuilder()
2017                 .setOtherConfigKey(String.format(FORMAT_STR,
2018                         testOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsValueName, NO_VALUE_FOR_KEY,
2019                         ++otherConfigsCounter))
2020                 .build();
2021         List<InterfaceOtherConfigs> oneGoodOneBadInput = (List<InterfaceOtherConfigs>) Lists.newArrayList(
2022                 oneGood, oneBad);
2023         List<InterfaceOtherConfigs> oneGoodOneBadExpected = null;
2024         testCase = Maps.newHashMap();
2025         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
2026         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
2027         testMap.put(testOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsValueName, testCase);
2028
2029         // Test Case 4:  TestOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsKey
2030         // Test Type:    Negative
2031         // Description:
2032         //     One perfectly fine InterfaceOtherConfigs
2033         //        (TestOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsValue_InterfaceOtherConfigsKey_1,
2034         //        TestOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigs_InterfaceOtherConfigsValue_1)
2035         //     and one malformed InterfaceOtherConfigs which only has key specified
2036         //        (UNSPECIFIED,
2037         //        TestOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsKey_NoKeyForValue_2)
2038         // Expected:     A termination point is created without any InterfaceOtherConfigs
2039         final String testOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsKeyName =
2040                 "TestOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsKey";
2041         otherConfigsCounter = 0;
2042         oneGood = new InterfaceOtherConfigsBuilder()
2043                 .setOtherConfigKey(String.format(FORMAT_STR,
2044                         testOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsKeyName,
2045                         GOOD_KEY, ++otherConfigsCounter))
2046                 .setOtherConfigValue(String.format(FORMAT_STR,
2047                         testOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsKeyName,
2048                         GOOD_VALUE, otherConfigsCounter))
2049                 .build();
2050         oneBad = new InterfaceOtherConfigsBuilder()
2051                 .setOtherConfigKey(String.format(FORMAT_STR,
2052                         testOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsKeyName, NO_KEY_FOR_VALUE,
2053                         ++otherConfigsCounter))
2054                 .build();
2055         oneGoodOneBadInput = (List<InterfaceOtherConfigs>) Lists.newArrayList(
2056                 oneGood, oneBad);
2057         oneGoodOneBadExpected = null;
2058         testCase = Maps.newHashMap();
2059         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
2060         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
2061         testMap.put(testOneGoodInterfaceOtherConfigsOneMalformedInterfaceOtherConfigsKeyName, testCase);
2062
2063         return testMap;
2064     }
2065
2066     /*
2067      * @see <code>SouthboundIT.testCRUDInterfaceOtherConfigs()</code>
2068      * This is helper test method to compare a test "set" of Options against an expected "set"
2069      */
2070     private void assertExpectedInterfaceOtherConfigsExist( List<InterfaceOtherConfigs> expected,
2071                                                            List<InterfaceOtherConfigs> test ) {
2072
2073         if (expected != null && test != null) {
2074             for (InterfaceOtherConfigs expectedOtherConfigs : expected) {
2075                 Assert.assertTrue(test.contains(expectedOtherConfigs));
2076             }
2077         }
2078     }
2079
2080     /*
2081      * Tests the CRUD operations for <code>Interface</code> <code>other_configs</code>.
2082      *
2083      * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
2084      */
2085     @Test
2086     public void testCRUDTerminationPointInterfaceOtherConfigs() throws InterruptedException {
2087         final String TEST_PREFIX = "CRUDTPInterfaceOtherConfigs";
2088
2089         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
2090         connectOvsdbNode(connectionInfo);
2091
2092         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
2093         // the update has been performed.
2094         Map<String, Map<String, List<InterfaceOtherConfigs>>> updateFromTestCases =
2095                 generateInterfaceOtherConfigsTestCases();
2096         Map<String, Map<String, List<InterfaceOtherConfigs>>> updateToTestCases =
2097                 generateInterfaceOtherConfigsTestCases();
2098         Map<String, List<InterfaceOtherConfigs>> updateFromTestCase;
2099         List<InterfaceOtherConfigs> updateFromInputOtherConfigs;
2100         List<InterfaceOtherConfigs> updateFromExpectedOtherConfigs;
2101         Map<String, List<InterfaceOtherConfigs>> updateToTestCase;
2102         List<InterfaceOtherConfigs> updateToInputOtherConfigs;
2103         List<InterfaceOtherConfigs> updateToExpectedOtherConfigs;
2104         String testBridgeName;
2105         String testPortName;
2106
2107         int counter = 1;
2108         ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
2109         for (String updateFromTestCaseKey : updateFromTestCases.keySet()) {
2110             updateFromTestCase = updateFromTestCases.get(updateFromTestCaseKey);
2111             updateFromInputOtherConfigs = updateFromTestCase.get(INPUT_VALUES_KEY);
2112             updateFromExpectedOtherConfigs = updateFromTestCase.get(EXPECTED_VALUES_KEY);
2113             for (String testCaseKey : updateToTestCases.keySet()) {
2114                 testPortName = testBridgeName = String.format("%s_%s_%d", TEST_PREFIX, testCaseKey, counter);
2115                 counter += 1;
2116                 updateToTestCase = updateToTestCases.get(testCaseKey);
2117                 updateToInputOtherConfigs = updateToTestCase.get(INPUT_VALUES_KEY);
2118                 updateToExpectedOtherConfigs = updateToTestCase.get(EXPECTED_VALUES_KEY);
2119
2120                 TestCRUDTerminationPointInterfaceOtherConfigsRunnable testRunnable =
2121                         new TestCRUDTerminationPointInterfaceOtherConfigsRunnable(
2122                                 connectionInfo, testBridgeName, testPortName,
2123                                 updateFromInputOtherConfigs,
2124                                 updateFromExpectedOtherConfigs,
2125                                 updateToInputOtherConfigs,
2126                                 updateToExpectedOtherConfigs);
2127                 executor.submit(testRunnable);
2128             }
2129         }
2130         executor.shutdown();
2131         executor.awaitTermination(5, TimeUnit.MINUTES);
2132         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
2133     }
2134
2135     class TestCRUDTerminationPointInterfaceOtherConfigsRunnable implements Runnable {
2136
2137         ConnectionInfo connectionInfo;
2138         String testBridgeName;
2139         String testPortName;
2140         List<InterfaceOtherConfigs> updateFromInputOtherConfigs;
2141         List<InterfaceOtherConfigs> updateFromExpectedOtherConfigs;
2142         List<InterfaceOtherConfigs> updateToInputOtherConfigs;
2143         List<InterfaceOtherConfigs> updateToExpectedOtherConfigs;
2144
2145         TestCRUDTerminationPointInterfaceOtherConfigsRunnable(
2146                 ConnectionInfo connectionInfo, String testBridgeName,
2147                 String testPortName,
2148                 List<InterfaceOtherConfigs> updateFromInputOtherConfigs,
2149                 List<InterfaceOtherConfigs> updateFromExpectedOtherConfigs,
2150                 List<InterfaceOtherConfigs> updateToInputOtherConfigs,
2151                 List<InterfaceOtherConfigs> updateToExpectedOtherConfigs) {
2152
2153             this.connectionInfo = connectionInfo;
2154             this.testBridgeName = testBridgeName;
2155             this.testPortName = testPortName;
2156             this.updateFromInputOtherConfigs = updateFromInputOtherConfigs;
2157             this.updateFromExpectedOtherConfigs = updateFromExpectedOtherConfigs;
2158             this.updateToInputOtherConfigs = updateToInputOtherConfigs;
2159             this.updateToExpectedOtherConfigs = updateToExpectedOtherConfigs;
2160         }
2161
2162         @Override
2163         public void run() {
2164             try {
2165                 test();
2166             } catch (InterruptedException e) {
2167                 e.printStackTrace();
2168             }
2169         }
2170
2171         public void test() throws InterruptedException {
2172             final int TERMINATION_POINT_TEST_INDEX = 0;
2173
2174             // CREATE: Create the test interface
2175             Assert.assertTrue(addBridge(connectionInfo, null,
2176                     testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
2177                     true, null, null, null, null));
2178             NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
2179                     connectionInfo, new OvsdbBridgeName(testBridgeName)));
2180             OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
2181                     createGenericOvsdbTerminationPointAugmentationBuilder();
2182             tpCreateAugmentationBuilder.setName(testPortName);
2183             tpCreateAugmentationBuilder.setInterfaceOtherConfigs(updateFromInputOtherConfigs);
2184             Assert.assertTrue(addTerminationPoint(testBridgeNodeId, testPortName, tpCreateAugmentationBuilder));
2185
2186             // READ: Read the test interface and ensure changes are propagated to the CONFIGURATION data store,
2187             // then repeat for OPERATIONAL data store
2188             OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
2189                     getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
2190                     LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
2191             List<InterfaceOtherConfigs> updateFromConfigurationOtherConfigs;
2192             if (updateFromConfigurationTerminationPointAugmentation != null) {
2193                 updateFromConfigurationOtherConfigs = updateFromConfigurationTerminationPointAugmentation
2194                         .getInterfaceOtherConfigs();
2195             } else {
2196                 updateFromConfigurationOtherConfigs = null;
2197             }
2198             assertExpectedInterfaceOtherConfigsExist(updateFromExpectedOtherConfigs,
2199                     updateFromConfigurationOtherConfigs);
2200             OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmenation =
2201                     getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
2202                             LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
2203             List<InterfaceOtherConfigs> updateFromOperationalOtherConfigs =
2204                     updateFromOperationalTerminationPointAugmenation.getInterfaceOtherConfigs();
2205             if (updateFromOperationalOtherConfigs != null) {
2206                 updateFromOperationalOtherConfigs = updateFromOperationalTerminationPointAugmenation
2207                         .getInterfaceOtherConfigs();
2208             } else {
2209                 updateFromOperationalOtherConfigs = null;
2210             }
2211             assertExpectedInterfaceOtherConfigsExist(updateFromExpectedOtherConfigs,
2212                     updateFromOperationalOtherConfigs);
2213
2214             // UPDATE:  update the other_configs
2215             testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeName).getNodeId();
2216             OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
2217                     new OvsdbTerminationPointAugmentationBuilder();
2218             tpUpdateAugmentationBuilder.setInterfaceOtherConfigs(updateToInputOtherConfigs);
2219             InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
2220             NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
2221             NodeId portUpdateNodeId = createManagedNodeId(portIid);
2222             portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
2223             TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
2224             tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testPortName)));
2225             tpUpdateBuilder.addAugmentation(
2226                     OvsdbTerminationPointAugmentation.class,
2227                     tpUpdateAugmentationBuilder.build());
2228             portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
2229             boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2230                     portIid, portUpdateNodeBuilder.build());
2231             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2232             Assert.assertTrue(result);
2233
2234             // READ: the test interface and ensure changes are propagated to the CONFIGURATION data store,
2235             // then repeat for OPERATIONAL data store
2236             OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
2237                     getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
2238                             LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
2239             List<InterfaceOtherConfigs> updateToConfigurationOtherConfigs =
2240                     updateToConfigurationTerminationPointAugmentation
2241                             .getInterfaceOtherConfigs();
2242             assertExpectedInterfaceOtherConfigsExist(updateToExpectedOtherConfigs,
2243                     updateToConfigurationOtherConfigs);
2244             assertExpectedInterfaceOtherConfigsExist(updateFromExpectedOtherConfigs,
2245                     updateToConfigurationOtherConfigs);
2246             OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
2247                     getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
2248                             LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
2249             List<InterfaceOtherConfigs> updateToOperationalOtherConfigs =
2250                     updateToOperationalTerminationPointAugmentation
2251                             .getInterfaceOtherConfigs();
2252             if (updateFromExpectedOtherConfigs != null) {
2253                 assertExpectedInterfaceOtherConfigsExist(updateToExpectedOtherConfigs,
2254                         updateToOperationalOtherConfigs);
2255                 assertExpectedInterfaceOtherConfigsExist(updateFromExpectedOtherConfigs,
2256                         updateToOperationalOtherConfigs);
2257             }
2258
2259             // DELETE
2260             Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
2261         }
2262     }
2263
2264     /*
2265      * Generates the test cases involved in testing Port other_configs.  See inline comments for descriptions of
2266      * the particular cases considered.
2267      *
2268      * The return value is a Map in the form (K,V)=(testCaseName,testCase).
2269      * - testCaseName is a String
2270      * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of
2271      *     either corresponding INPUT port other_configs, or EXPECTED port other_configs
2272      *     INPUT    is the List we use when calling
2273      *              <code>TerminationPointAugmentationBuilder.setPortOtherConfigs()</code>
2274      *     EXPECTED is the List we expect to receive after calling
2275      *              <code>TerminationPointAugmentationBuilder.getPortOtherConfigs()</code>
2276      */
2277     private Map<String, Map<String, List<PortOtherConfigs>>> generatePortOtherConfigsTestCases() {
2278         Map<String, Map<String, List<PortOtherConfigs>>> testMap =
2279                 new HashMap<String, Map<String, List<PortOtherConfigs>>>();
2280
2281         final String PORT_OTHER_CONFIGS_KEY = "PortOtherConfigsKey";
2282         final String PORT_OTHER_CONFIGS_VALUE = "PortOtherConfigsValue";
2283         final String FORMAT_STR = "%s_%s_%d";
2284         final String GOOD_KEY = "GoodKey";
2285         final String GOOD_VALUE = "GoodValue";
2286         final String NO_VALUE_FOR_KEY = "NoValueForKey";
2287         final String NO_KEY_FOR_VALUE = "NoKeyForValue";
2288
2289         // Test Case 1:  TestOneOtherConfigs
2290         // Test Type:    Positive
2291         // Description:  Create an port with one other_Configs
2292         // Expected:     A port is created with the single other_configs specified below
2293         final String testOneOtherConfigsName = "TestOnePortOtherConfigs";
2294         int otherConfigsCounter = 0;
2295         List<PortOtherConfigs> oneOtherConfigs = (List<PortOtherConfigs>) Lists.newArrayList(
2296                 (new PortOtherConfigsBuilder()
2297                         .setOtherConfigKey(String.format(FORMAT_STR, testOneOtherConfigsName,
2298                                 PORT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
2299                         .setOtherConfigValue(String.format(FORMAT_STR, testOneOtherConfigsName,
2300                                 PORT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
2301                         .build()));
2302         Map<String,List<PortOtherConfigs>> testCase = Maps.newHashMap();
2303         testCase.put(EXPECTED_VALUES_KEY, oneOtherConfigs);
2304         testCase.put(INPUT_VALUES_KEY, oneOtherConfigs);
2305         testMap.put(testOneOtherConfigsName, testCase);
2306
2307         // Test Case 2:  TestFivePortOtherConfigs
2308         // Test Type:    Positive
2309         // Description:  Create a termination point with multiple (five) PortOtherConfigs
2310         // Expected:     A termination point is created with the five PortOtherConfigs specified below
2311         final String testFivePortOtherConfigsName = "TestFivePortOtherConfigs";
2312         otherConfigsCounter = 0;
2313         List<PortOtherConfigs> fivePortOtherConfigs = (List<PortOtherConfigs>) Lists.newArrayList(
2314                 (new PortOtherConfigsBuilder()
2315                         .setOtherConfigKey(String.format(FORMAT_STR, testFivePortOtherConfigsName,
2316                                 PORT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
2317                         .setOtherConfigValue(String.format(FORMAT_STR, testFivePortOtherConfigsName,
2318                                 PORT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
2319                         .build()),
2320                 (new PortOtherConfigsBuilder()
2321                         .setOtherConfigKey(String.format(FORMAT_STR, testFivePortOtherConfigsName,
2322                                 PORT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
2323                         .setOtherConfigValue(String.format(FORMAT_STR, testFivePortOtherConfigsName,
2324                                 PORT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
2325                         .build()),
2326                 (new PortOtherConfigsBuilder()
2327                         .setOtherConfigKey(String.format(FORMAT_STR, testFivePortOtherConfigsName,
2328                                 PORT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
2329                         .setOtherConfigValue(String.format(FORMAT_STR, testFivePortOtherConfigsName,
2330                                 PORT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
2331                         .build()),
2332                 (new PortOtherConfigsBuilder()
2333                         .setOtherConfigKey(String.format(FORMAT_STR, testFivePortOtherConfigsName,
2334                                 PORT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
2335                         .setOtherConfigValue(String.format(FORMAT_STR, testFivePortOtherConfigsName,
2336                                 PORT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
2337                         .build()),
2338                 (new PortOtherConfigsBuilder()
2339                         .setOtherConfigKey(String.format(FORMAT_STR, testFivePortOtherConfigsName,
2340                                 PORT_OTHER_CONFIGS_KEY, ++otherConfigsCounter))
2341                         .setOtherConfigValue(String.format(FORMAT_STR, testFivePortOtherConfigsName,
2342                                 PORT_OTHER_CONFIGS_VALUE, otherConfigsCounter))
2343                         .build()));
2344         testCase = Maps.newHashMap();
2345         testCase.put(EXPECTED_VALUES_KEY, fivePortOtherConfigs);
2346         testCase.put(INPUT_VALUES_KEY, fivePortOtherConfigs);
2347         testMap.put(testFivePortOtherConfigsName, testCase);
2348
2349         // Test Case 3:  TestOneGoodPortOtherConfigsOneMalformedPortOtherConfigsValue
2350         // Test Type:    Negative
2351         // Description:
2352         //     One perfectly fine PortOtherConfigs
2353         //        (TestOneGoodPortOtherConfigsOneMalformedPortOtherConfigsValue_PortOtherConfigsKey_1,
2354         //        TestOneGoodPortOtherConfigsOneMalformedPortOtherConfigs_PortOtherConfigsValue_1)
2355         //     and one malformed PortOtherConfigs which only has key specified
2356         //        (TestOneGoodPortOtherConfigsOneMalformedPortOtherConfigsValue_NoValueForKey_2,
2357         //        UNSPECIFIED)
2358         // Expected:     A termination point is created without any PortOtherConfigs
2359         final String testOneGoodPortOtherConfigsOneMalformedPortOtherConfigsValueName =
2360                 "TestOneGoodPortOtherConfigsOneMalformedPortOtherConfigsValue";
2361         otherConfigsCounter = 0;
2362         PortOtherConfigs oneGood = new PortOtherConfigsBuilder()
2363                 .setOtherConfigKey(String.format(FORMAT_STR,
2364                         testOneGoodPortOtherConfigsOneMalformedPortOtherConfigsValueName,
2365                         GOOD_KEY, ++otherConfigsCounter))
2366                 .setOtherConfigValue(String.format(FORMAT_STR,
2367                         testOneGoodPortOtherConfigsOneMalformedPortOtherConfigsValueName,
2368                         GOOD_VALUE, otherConfigsCounter))
2369                 .build();
2370         PortOtherConfigs oneBad = new PortOtherConfigsBuilder()
2371                 .setOtherConfigKey(String.format(FORMAT_STR,
2372                         testOneGoodPortOtherConfigsOneMalformedPortOtherConfigsValueName, NO_VALUE_FOR_KEY,
2373                         ++otherConfigsCounter))
2374                 .build();
2375         List<PortOtherConfigs> oneGoodOneBadInput = (List<PortOtherConfigs>) Lists.newArrayList(
2376                 oneGood, oneBad);
2377         List<PortOtherConfigs> oneGoodOneBadExpected = null;
2378         testCase = Maps.newHashMap();
2379         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
2380         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
2381         testMap.put(testOneGoodPortOtherConfigsOneMalformedPortOtherConfigsValueName, testCase);
2382
2383         // Test Case 4:  TestOneGoodPortOtherConfigsOneMalformedPortOtherConfigsKey
2384         // Test Type:    Negative
2385         // Description:
2386         //     One perfectly fine PortOtherConfigs
2387         //        (TestOneGoodPortOtherConfigsOneMalformedPortOtherConfigsValue_PortOtherConfigsKey_1,
2388         //        TestOneGoodPortOtherConfigsOneMalformedPortOtherConfigs_PortOtherConfigsValue_1)
2389         //     and one malformed PortOtherConfigs which only has key specified
2390         //        (UNSPECIFIED,
2391         //        TestOneGoodPortOtherConfigsOneMalformedPortOtherConfigsKey_NoKeyForValue_2)
2392         // Expected:     A termination point is created without any PortOtherConfigs
2393         final String testOneGoodPortOtherConfigsOneMalformedPortOtherConfigsKeyName =
2394                 "TestOneGoodPortOtherConfigsOneMalformedPortOtherConfigsKey";
2395         otherConfigsCounter = 0;
2396         oneGood = new PortOtherConfigsBuilder()
2397                 .setOtherConfigKey(String.format(FORMAT_STR,
2398                         testOneGoodPortOtherConfigsOneMalformedPortOtherConfigsKeyName,
2399                         GOOD_KEY, ++otherConfigsCounter))
2400                 .setOtherConfigValue(String.format(FORMAT_STR,
2401                         testOneGoodPortOtherConfigsOneMalformedPortOtherConfigsKeyName,
2402                         GOOD_VALUE, otherConfigsCounter))
2403                 .build();
2404         oneBad = new PortOtherConfigsBuilder()
2405                 .setOtherConfigKey(String.format(FORMAT_STR,
2406                         testOneGoodPortOtherConfigsOneMalformedPortOtherConfigsKeyName, NO_KEY_FOR_VALUE,
2407                         ++otherConfigsCounter))
2408                 .build();
2409         oneGoodOneBadInput = (List<PortOtherConfigs>) Lists.newArrayList(
2410                 oneGood, oneBad);
2411         oneGoodOneBadExpected = null;
2412         testCase = Maps.newHashMap();
2413         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
2414         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
2415         testMap.put(testOneGoodPortOtherConfigsOneMalformedPortOtherConfigsKeyName, testCase);
2416
2417         return testMap;
2418     }
2419
2420     /*
2421      * @see <code>SouthboundIT.testCRUDPortOtherConfigs()</code>
2422      * This is helper test method to compare a test "set" of Options against an expected "set"
2423      */
2424     private void assertExpectedPortOtherConfigsExist( List<PortOtherConfigs> expected,
2425                                                       List<PortOtherConfigs> test ) {
2426
2427         if (expected != null && test != null) {
2428             for (PortOtherConfigs expectedOtherConfigs : expected) {
2429                 Assert.assertTrue(test.contains(expectedOtherConfigs));
2430             }
2431         }
2432     }
2433
2434     /*
2435      * Tests the CRUD operations for <code>Port</code> <code>other_configs</code>.
2436      *
2437      * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
2438      */
2439     @Test
2440     public void testCRUDTerminationPointPortOtherConfigs() throws InterruptedException {
2441         final String TEST_PREFIX = "CRUDTPPortOtherConfigs";
2442
2443         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
2444         connectOvsdbNode(connectionInfo);
2445
2446         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
2447         // the update has been performed.
2448         Map<String, Map<String, List<PortOtherConfigs>>> updateFromTestCases =
2449                 generatePortOtherConfigsTestCases();
2450         Map<String, Map<String, List<PortOtherConfigs>>> updateToTestCases =
2451                 generatePortOtherConfigsTestCases();
2452         Map<String, List<PortOtherConfigs>> updateFromTestCase;
2453         List<PortOtherConfigs> updateFromInputOtherConfigs;
2454         List<PortOtherConfigs> updateFromExpectedOtherConfigs;
2455         Map<String, List<PortOtherConfigs>> updateToTestCase;
2456         List<PortOtherConfigs> updateToInputOtherConfigs;
2457         List<PortOtherConfigs> updateToExpectedOtherConfigs;
2458         String testBridgeName;
2459         String testPortName;
2460
2461         int counter = 1;
2462         ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
2463         for (String updateFromTestCaseKey : updateFromTestCases.keySet()) {
2464             updateFromTestCase = updateFromTestCases.get(updateFromTestCaseKey);
2465             updateFromInputOtherConfigs = updateFromTestCase.get(INPUT_VALUES_KEY);
2466             updateFromExpectedOtherConfigs = updateFromTestCase.get(EXPECTED_VALUES_KEY);
2467             for (String testCaseKey : updateToTestCases.keySet()) {
2468                 testPortName = testBridgeName = String.format("%s_%s_%d", TEST_PREFIX, testCaseKey, counter);
2469                 counter += 1;
2470                 updateToTestCase = updateToTestCases.get(testCaseKey);
2471                 updateToInputOtherConfigs = updateToTestCase.get(INPUT_VALUES_KEY);
2472                 updateToExpectedOtherConfigs = updateToTestCase.get(EXPECTED_VALUES_KEY);
2473
2474                 TestCRUDTerminationPointPortOtherConfigsRunnable testRunnable =
2475                         new TestCRUDTerminationPointPortOtherConfigsRunnable(
2476                                 connectionInfo, testBridgeName, testPortName,
2477                                 updateFromInputOtherConfigs,
2478                                 updateFromExpectedOtherConfigs,
2479                                 updateToInputOtherConfigs,
2480                                 updateToExpectedOtherConfigs);
2481                 executor.submit(testRunnable);
2482             }
2483         }
2484         executor.shutdown();
2485         executor.awaitTermination(5, TimeUnit.MINUTES);
2486         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
2487     }
2488
2489     class TestCRUDTerminationPointPortOtherConfigsRunnable implements Runnable {
2490         ConnectionInfo connectionInfo;
2491         String testBridgeName;
2492         String testPortName;
2493         List<PortOtherConfigs> updateFromInputOtherConfigs;
2494         List<PortOtherConfigs> updateFromExpectedOtherConfigs;
2495         List<PortOtherConfigs> updateToInputOtherConfigs;
2496         List<PortOtherConfigs> updateToExpectedOtherConfigs;
2497
2498         TestCRUDTerminationPointPortOtherConfigsRunnable(
2499                 ConnectionInfo connectionInfo, String testBridgeName,
2500                 String testPortName,
2501                 List<PortOtherConfigs> updateFromInputOtherConfigs,
2502                 List<PortOtherConfigs> updateFromExpectedOtherConfigs,
2503                 List<PortOtherConfigs> updateToInputOtherConfigs,
2504                 List<PortOtherConfigs> updateToExpectedOtherConfigs) {
2505
2506             this.connectionInfo = connectionInfo;
2507             this.testBridgeName = testBridgeName;
2508             this.testPortName = testPortName;
2509             this.updateFromInputOtherConfigs = updateFromInputOtherConfigs;
2510             this.updateFromExpectedOtherConfigs = updateFromExpectedOtherConfigs;
2511             this.updateToInputOtherConfigs = updateToInputOtherConfigs;
2512             this.updateToExpectedOtherConfigs = updateToExpectedOtherConfigs;
2513         }
2514
2515         @Override
2516         public void run() {
2517             try {
2518                 test();
2519             } catch (InterruptedException e) {
2520                 e.printStackTrace();
2521             }
2522         }
2523
2524         public void test() throws InterruptedException {
2525             final int TERMINATION_POINT_TEST_INDEX = 0;
2526             // CREATE: Create the test port
2527             Assert.assertTrue(addBridge(connectionInfo, null,
2528                     testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
2529                     true, null, null, null, null));
2530             NodeId testBridgeNodeId = createManagedNodeId(createInstanceIdentifier(
2531                     connectionInfo, new OvsdbBridgeName(testBridgeName)));
2532             OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
2533                     createGenericOvsdbTerminationPointAugmentationBuilder();
2534             tpCreateAugmentationBuilder.setName(testPortName);
2535             tpCreateAugmentationBuilder.setPortOtherConfigs(updateFromInputOtherConfigs);
2536             Assert.assertTrue(addTerminationPoint(testBridgeNodeId, testPortName, tpCreateAugmentationBuilder));
2537
2538             // READ: Read the test port and ensure changes are propagated to the CONFIGURATION data store,
2539             // then repeat for OPERATIONAL data store
2540             OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
2541                     getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
2542                             LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
2543             List<PortOtherConfigs> updateFromConfigurationOtherConfigs;
2544             if (updateFromConfigurationTerminationPointAugmentation != null) {
2545                 updateFromConfigurationOtherConfigs = updateFromConfigurationTerminationPointAugmentation
2546                         .getPortOtherConfigs();
2547             } else {
2548                 updateFromConfigurationOtherConfigs = null;
2549             }
2550             assertExpectedPortOtherConfigsExist(updateFromExpectedOtherConfigs,
2551                     updateFromConfigurationOtherConfigs);
2552             OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmenation =
2553                     getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
2554                             LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
2555             List<PortOtherConfigs> updateFromOperationalOtherConfigs =
2556                     updateFromOperationalTerminationPointAugmenation.getPortOtherConfigs();
2557             if (updateFromOperationalOtherConfigs != null) {
2558                 updateFromOperationalOtherConfigs = updateFromOperationalTerminationPointAugmenation
2559                         .getPortOtherConfigs();
2560             } else {
2561                 updateFromOperationalOtherConfigs = null;
2562             }
2563             assertExpectedPortOtherConfigsExist(updateFromExpectedOtherConfigs,
2564                     updateFromOperationalOtherConfigs);
2565
2566             // UPDATE:  update the other_configs
2567             testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeName).getNodeId();
2568             OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
2569                     new OvsdbTerminationPointAugmentationBuilder();
2570             tpUpdateAugmentationBuilder.setPortOtherConfigs(updateToInputOtherConfigs);
2571             InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
2572             NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
2573             NodeId portUpdateNodeId = createManagedNodeId(portIid);
2574             portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
2575             TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
2576             tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testPortName)));
2577             tpUpdateBuilder.addAugmentation(
2578                     OvsdbTerminationPointAugmentation.class,
2579                     tpUpdateAugmentationBuilder.build());
2580             portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
2581             boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2582                     portIid, portUpdateNodeBuilder.build());
2583             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2584             Assert.assertTrue(result);
2585
2586             // READ: the test port and ensure changes are propagated to the CONFIGURATION data store,
2587             // then repeat for OPERATIONAL data store
2588             OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
2589                     getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
2590                             LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
2591             List<PortOtherConfigs> updateToConfigurationOtherConfigs = updateToConfigurationTerminationPointAugmentation
2592                     .getPortOtherConfigs();
2593             assertExpectedPortOtherConfigsExist(updateToExpectedOtherConfigs,
2594                     updateToConfigurationOtherConfigs);
2595             assertExpectedPortOtherConfigsExist(updateFromExpectedOtherConfigs,
2596                     updateToConfigurationOtherConfigs);
2597             OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
2598                     getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
2599                             LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
2600             List<PortOtherConfigs> updateToOperationalOtherConfigs = updateToOperationalTerminationPointAugmentation
2601                     .getPortOtherConfigs();
2602             if (updateFromExpectedOtherConfigs != null) {
2603                 assertExpectedPortOtherConfigsExist(updateToExpectedOtherConfigs,
2604                         updateToOperationalOtherConfigs);
2605                 assertExpectedPortOtherConfigsExist(updateFromExpectedOtherConfigs,
2606                         updateToOperationalOtherConfigs);
2607             }
2608
2609             // DELETE
2610             Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
2611         }
2612     }
2613
2614     @Test
2615     public void testCRUDTerminationPointVlan() throws InterruptedException {
2616         final Integer CREATED_VLAN_ID = new Integer(4000);
2617         final Integer UPDATED_VLAN_ID = new Integer(4001);
2618
2619         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
2620         connectOvsdbNode(connectionInfo);
2621
2622         // CREATE
2623         Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
2624         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
2625         Assert.assertNotNull(bridge);
2626         NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
2627                 connectionInfo, bridge.getBridgeName()));
2628         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
2629                 createGenericOvsdbTerminationPointAugmentationBuilder();
2630         String portName = "testTerminationPointVlanId";
2631         ovsdbTerminationBuilder.setName(portName);
2632         ovsdbTerminationBuilder.setVlanTag(new VlanId(CREATED_VLAN_ID));
2633         Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
2634         InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
2635         Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
2636         Assert.assertNotNull(terminationPointNode);
2637
2638         // READ
2639         List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
2640         OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = null;
2641         for (TerminationPoint terminationPoint : terminationPoints) {
2642             ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
2643                     OvsdbTerminationPointAugmentation.class);
2644             if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
2645                 VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
2646                 Assert.assertNotNull(actualVlanId);
2647                 Integer actualVlanIdInt = actualVlanId.getValue();
2648                 Assert.assertEquals(CREATED_VLAN_ID, actualVlanIdInt);
2649             }
2650         }
2651
2652         // UPDATE
2653         NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
2654         OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
2655                 new OvsdbTerminationPointAugmentationBuilder();
2656         tpUpdateAugmentationBuilder.setVlanTag(new VlanId(UPDATED_VLAN_ID));
2657         InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
2658         NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
2659         NodeId portUpdateNodeId = createManagedNodeId(portIid);
2660         portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
2661         TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
2662         tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
2663         tpUpdateBuilder.addAugmentation(
2664                 OvsdbTerminationPointAugmentation.class,
2665                 tpUpdateAugmentationBuilder.build());
2666         tpUpdateBuilder.setTpId(new TpId(portName));
2667         portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
2668         boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2669                 portIid, portUpdateNodeBuilder.build());
2670         Assert.assertTrue(result);
2671         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2672
2673         terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
2674         terminationPoints = terminationPointNode.getTerminationPoint();
2675         for (TerminationPoint terminationPoint : terminationPoints) {
2676             ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
2677                     OvsdbTerminationPointAugmentation.class);
2678             if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
2679                 VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
2680                 Assert.assertNotNull(actualVlanId);
2681                 Integer actualVlanIdInt = actualVlanId.getValue();
2682                 Assert.assertEquals(UPDATED_VLAN_ID, actualVlanIdInt);
2683             }
2684         }
2685
2686         // DELETE
2687         Assert.assertTrue(deleteBridge(connectionInfo));
2688         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
2689     }
2690
2691     @Test
2692     public void testCRUDTerminationPointVlanModes() throws InterruptedException {
2693         final VlanMode UPDATED_VLAN_MODE = VlanMode.Access;
2694         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
2695         connectOvsdbNode(connectionInfo);
2696         VlanMode []vlanModes = VlanMode.values();
2697         for (VlanMode vlanMode : vlanModes) {
2698             // CREATE
2699             Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
2700             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
2701             Assert.assertNotNull(bridge);
2702             NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
2703                     connectionInfo, bridge.getBridgeName()));
2704             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
2705                     createGenericOvsdbTerminationPointAugmentationBuilder();
2706             String portName = "testTerminationPointVlanMode" + vlanMode.toString();
2707             ovsdbTerminationBuilder.setName(portName);
2708             ovsdbTerminationBuilder.setVlanMode(vlanMode);
2709             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
2710             InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
2711             Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
2712             Assert.assertNotNull(terminationPointNode);
2713
2714             // READ
2715             List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
2716             for (TerminationPoint terminationPoint : terminationPoints) {
2717                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
2718                         terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
2719                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
2720                     //test
2721                     Assert.assertTrue(ovsdbTerminationPointAugmentation.getVlanMode().equals(vlanMode));
2722                 }
2723             }
2724
2725             // UPDATE
2726             NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
2727             OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
2728                     new OvsdbTerminationPointAugmentationBuilder();
2729             tpUpdateAugmentationBuilder.setVlanMode(UPDATED_VLAN_MODE);
2730             InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
2731             NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
2732             NodeId portUpdateNodeId = createManagedNodeId(portIid);
2733             portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
2734             TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
2735             tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
2736             tpUpdateBuilder.addAugmentation(
2737                     OvsdbTerminationPointAugmentation.class,
2738                     tpUpdateAugmentationBuilder.build());
2739             tpUpdateBuilder.setTpId(new TpId(portName));
2740             portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
2741             boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2742                     portIid, portUpdateNodeBuilder.build());
2743             Assert.assertTrue(result);
2744             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2745
2746             terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
2747             terminationPoints = terminationPointNode.getTerminationPoint();
2748             for (TerminationPoint terminationPoint : terminationPoints) {
2749                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
2750                         terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
2751                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
2752                     //test
2753                     Assert.assertEquals(UPDATED_VLAN_MODE, ovsdbTerminationPointAugmentation.getVlanMode());
2754                 }
2755             }
2756
2757             // DELETE
2758             Assert.assertTrue(deleteBridge(connectionInfo));
2759         }
2760         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
2761     }
2762
2763     private ArrayList<Set<Integer>> generateVlanSets() {
2764         ArrayList<Set<Integer>> vlanSets = new ArrayList<Set<Integer>>();
2765
2766         Set<Integer> emptySet = new HashSet<Integer>();
2767         vlanSets.add(emptySet);
2768
2769         Set<Integer> singleSet = new HashSet<Integer>();
2770         Integer single = new Integer(2222);
2771         singleSet.add(single);
2772         vlanSets.add(singleSet);
2773
2774         Set<Integer> minMaxMiddleSet = new HashSet<Integer>();
2775         Integer min = new Integer(0);
2776         minMaxMiddleSet.add(min);
2777         Integer max = new Integer(4095);
2778         minMaxMiddleSet.add(max);
2779         Integer minPlusOne = new Integer(min + 1);
2780         minMaxMiddleSet.add(minPlusOne);
2781         Integer maxMinusOne = new Integer(max - 1);
2782         minMaxMiddleSet.add(maxMinusOne);
2783         Integer middle = new Integer((max - min) / 2);
2784         minMaxMiddleSet.add(middle);
2785         vlanSets.add(minMaxMiddleSet);
2786
2787         return vlanSets;
2788     }
2789
2790     private List<Trunks> buildTrunkList(Set<Integer> trunkSet) {
2791         List<Trunks> trunkList = Lists.newArrayList();
2792         for (Integer trunk : trunkSet) {
2793             TrunksBuilder trunkBuilder = new TrunksBuilder();
2794             trunkBuilder.setTrunk(new VlanId(trunk));
2795             trunkList.add(trunkBuilder.build());
2796         }
2797         return trunkList;
2798     }
2799
2800     @Test
2801     public void testCRUDTerminationPointVlanTrunks() throws InterruptedException {
2802         final List<Trunks> UPDATED_TRUNKS = buildTrunkList(Sets.newHashSet(2011));
2803         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
2804         connectOvsdbNode(connectionInfo);
2805         Iterable<Set<Integer>> vlanSets = generateVlanSets();
2806         int testCase = 0;
2807         for (Set<Integer> vlanSet : vlanSets) {
2808             ++testCase;
2809             // CREATE
2810             Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
2811             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
2812             Assert.assertNotNull(bridge);
2813             NodeId nodeId = createManagedNodeId(createInstanceIdentifier(
2814                     connectionInfo, bridge.getBridgeName()));
2815             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
2816                     createGenericOvsdbTerminationPointAugmentationBuilder();
2817             String portName = "testTerminationPointVlanTrunks" + testCase;
2818             ovsdbTerminationBuilder.setName(portName);
2819             List<Trunks> trunks = buildTrunkList(vlanSet);
2820             ovsdbTerminationBuilder.setTrunks(trunks);
2821             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
2822             InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
2823             Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
2824             Assert.assertNotNull(terminationPointNode);
2825
2826             // READ
2827             List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
2828             for (TerminationPoint terminationPoint : terminationPoints) {
2829                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
2830                         terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
2831                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
2832                     List<Trunks> actualTrunks = ovsdbTerminationPointAugmentation.getTrunks();
2833                     for (Trunks trunk : trunks) {
2834                         Assert.assertTrue(actualTrunks.contains(trunk));
2835                     }
2836                 }
2837             }
2838
2839
2840             // UPDATE
2841             NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
2842             OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
2843                     new OvsdbTerminationPointAugmentationBuilder();
2844             tpUpdateAugmentationBuilder.setTrunks(UPDATED_TRUNKS);
2845             InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
2846             NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
2847             NodeId portUpdateNodeId = createManagedNodeId(portIid);
2848             portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
2849             TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
2850             tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
2851             tpUpdateBuilder.addAugmentation(
2852                     OvsdbTerminationPointAugmentation.class,
2853                     tpUpdateAugmentationBuilder.build());
2854             tpUpdateBuilder.setTpId(new TpId(portName));
2855             portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
2856             boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2857                     portIid, portUpdateNodeBuilder.build());
2858             Assert.assertTrue(result);
2859             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2860
2861             terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
2862             terminationPoints = terminationPointNode.getTerminationPoint();
2863             for (TerminationPoint terminationPoint : terminationPoints) {
2864                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
2865                         terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
2866                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
2867                     //test
2868                     Assert.assertEquals(UPDATED_TRUNKS, ovsdbTerminationPointAugmentation.getTrunks());
2869                 }
2870             }
2871
2872             // DELETE
2873             Assert.assertTrue(deleteBridge(connectionInfo));
2874         }
2875         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
2876     }
2877
2878     @Test
2879     public void testGetOvsdbNodes() throws InterruptedException {
2880         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
2881         connectOvsdbNode(connectionInfo);
2882         InstanceIdentifier<Topology> topologyPath = InstanceIdentifier
2883                 .create(NetworkTopology.class)
2884                 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
2885
2886         Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, topologyPath);
2887         InstanceIdentifier<Node> expectedNodeIid = createInstanceIdentifier(connectionInfo);
2888         NodeId expectedNodeId = expectedNodeIid.firstKeyOf(Node.class, NodeKey.class).getNodeId();
2889         Node foundNode = null;
2890         Assert.assertNotNull("Expected to find topology: " + topologyPath, topology);
2891         Assert.assertNotNull("Expected to find some nodes" + topology.getNode());
2892         LOG.info("expectedNodeId: {}, getNode: {}", expectedNodeId, topology.getNode());
2893         for (Node node : topology.getNode()) {
2894             if (node.getNodeId().getValue().equals(expectedNodeId.getValue())) {
2895                 foundNode = node;
2896                 break;
2897             }
2898         }
2899         Assert.assertNotNull("Expected to find Node: " + expectedNodeId, foundNode);
2900         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
2901     }
2902
2903     /*
2904      * Generates the test cases involved in testing BridgeOtherConfigs.  See inline comments for descriptions of
2905      * the particular cases considered.
2906      *
2907      * The return value is a Map in the form (K,V)=(testCaseName,testCase).
2908      * - testCaseName is a String
2909      * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of
2910      *     either corresponding INPUT bridge other_configs, or EXPECTED bridge other_configs
2911      *     INPUT is the List we use when calling BridgeAugmentationBuilder.setBridgeOtherConfigs()
2912      *     EXPECTED is the List we expect to receive after calling BridgeAugmentationBuilder.getBridgeOtherConfigs()
2913      */
2914     private Map<String, Map<String, List<BridgeOtherConfigs>>> generateBridgeOtherConfigsTestCases() {
2915         Map<String, Map<String, List<BridgeOtherConfigs>>> testMap =
2916                 new HashMap<String, Map<String, List<BridgeOtherConfigs>>>();
2917
2918         final String BRIDGE_OTHER_CONFIGS_KEY = "BridgeOtherConfigKey";
2919         final String BRIDGE_OTHER_CONFIGS_VALUE = "BridgeOtherConfigValue";
2920         final String FORMAT_STR = "%s_%s_%d";
2921         final String GOOD_KEY = "GoodKey";
2922         final String GOOD_VALUE = "GoodValue";
2923         final String NO_VALUE_FOR_KEY = "NoValueForKey";
2924         final String NO_KEY_FOR_VALUE = "NoKeyForValue";
2925
2926         // Test Case 1:  TestOneOtherConfig
2927         // Test Type:    Positive
2928         // Description:  Create a bridge with one other_config
2929         // Expected:     A bridge is created with the single other_config specified below
2930         final String testOneOtherConfigName = "TestOneOtherConfig";
2931         int otherConfigCounter = 0;
2932         List<BridgeOtherConfigs> oneOtherConfig = (List<BridgeOtherConfigs>) Lists.newArrayList(
2933                 (new BridgeOtherConfigsBuilder()
2934                         .setBridgeOtherConfigKey(String.format(FORMAT_STR, testOneOtherConfigName,
2935                                 BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter))
2936                         .setBridgeOtherConfigValue(String.format(FORMAT_STR, testOneOtherConfigName,
2937                                 BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter))
2938                         .build()));
2939         Map<String,List<BridgeOtherConfigs>> testCase = Maps.newHashMap();
2940         testCase.put(EXPECTED_VALUES_KEY, oneOtherConfig);
2941         testCase.put(INPUT_VALUES_KEY, oneOtherConfig);
2942         testMap.put(testOneOtherConfigName, testCase);
2943
2944         // Test Case 2:  TestFiveOtherConfig
2945         // Test Type:    Positive
2946         // Description:  Create a bridge with multiple (five) other_configs
2947         // Expected:     A bridge is created with the five other_configs specified below
2948         final String testFiveOtherConfigName = "TestFiveOtherConfig";
2949         otherConfigCounter = 0;
2950         List<BridgeOtherConfigs> fiveOtherConfig = (List<BridgeOtherConfigs>) Lists.newArrayList(
2951                 (new BridgeOtherConfigsBuilder()
2952                         .setBridgeOtherConfigKey(String.format(FORMAT_STR, testFiveOtherConfigName,
2953                                 BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter))
2954                         .setBridgeOtherConfigValue(String.format(FORMAT_STR, testFiveOtherConfigName,
2955                                 BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter))
2956                         .build()),
2957                 (new BridgeOtherConfigsBuilder()
2958                         .setBridgeOtherConfigKey(String.format(FORMAT_STR, testFiveOtherConfigName,
2959                                 BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter))
2960                         .setBridgeOtherConfigValue(String.format(FORMAT_STR, testFiveOtherConfigName,
2961                                 BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter))
2962                         .build()),
2963                 (new BridgeOtherConfigsBuilder()
2964                         .setBridgeOtherConfigKey(String.format(FORMAT_STR, testFiveOtherConfigName,
2965                                 BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter))
2966                         .setBridgeOtherConfigValue(String.format(FORMAT_STR, testFiveOtherConfigName,
2967                                 BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter))
2968                         .build()),
2969                 (new BridgeOtherConfigsBuilder()
2970                         .setBridgeOtherConfigKey(String.format(FORMAT_STR, testFiveOtherConfigName,
2971                                 BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter))
2972                         .setBridgeOtherConfigValue(String.format(FORMAT_STR, testFiveOtherConfigName,
2973                                 BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter))
2974                         .build()),
2975                 (new BridgeOtherConfigsBuilder()
2976                         .setBridgeOtherConfigKey(String.format(FORMAT_STR, testFiveOtherConfigName,
2977                                 BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter))
2978                         .setBridgeOtherConfigValue(String.format(FORMAT_STR, testFiveOtherConfigName,
2979                                 BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter))
2980                         .build()));
2981         testCase = Maps.newHashMap();
2982         testCase.put(EXPECTED_VALUES_KEY, fiveOtherConfig);
2983         testCase.put(INPUT_VALUES_KEY, fiveOtherConfig);
2984         testMap.put(testFiveOtherConfigName, testCase);
2985
2986         // Test Case 3:  TestOneGoodOtherConfigOneMalformedOtherConfigValue
2987         // Test Type:    Negative
2988         // Description:
2989         //     One perfectly fine BridgeOtherConfig
2990         //        (TestOneGoodOtherConfigOneMalformedOtherConfigValue_BridgeOtherConfigKey_1,
2991         //        TestOneGoodOtherConfigOneMalformedOtherConfig_BridgeOtherConfigValue_1)
2992         //     and one malformed BridgeOtherConfig which only has key specified
2993         //        (TestOneGoodOtherConfigOneMalformedOtherConfigValue_NoValueForKey_2,
2994         //        UNSPECIFIED)
2995         // Expected:     A bridge is created without any other_config
2996         final String testOneGoodOtherConfigOneMalformedOtherConfigValueName =
2997                 "TestOneGoodOtherConfigOneMalformedOtherConfigValue";
2998         otherConfigCounter = 0;
2999         BridgeOtherConfigs oneGood = new BridgeOtherConfigsBuilder()
3000                 .setBridgeOtherConfigKey(String.format(FORMAT_STR,
3001                         testOneGoodOtherConfigOneMalformedOtherConfigValueName, GOOD_KEY, ++otherConfigCounter))
3002                 .setBridgeOtherConfigValue(String.format(FORMAT_STR,
3003                         testOneGoodOtherConfigOneMalformedOtherConfigValueName,
3004                         GOOD_VALUE, otherConfigCounter))
3005                 .build();
3006         BridgeOtherConfigs oneBad = new BridgeOtherConfigsBuilder()
3007                 .setBridgeOtherConfigKey(String.format(FORMAT_STR,
3008                         testOneGoodOtherConfigOneMalformedOtherConfigValueName, NO_VALUE_FOR_KEY, ++otherConfigCounter))
3009                 .build();
3010         List<BridgeOtherConfigs> oneGoodOneBadInput = (List<BridgeOtherConfigs>) Lists.newArrayList(
3011                 oneGood, oneBad);
3012         List<BridgeOtherConfigs> oneGoodOneBadExpected = null;
3013         testCase = Maps.newHashMap();
3014         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
3015         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
3016         testMap.put(testOneGoodOtherConfigOneMalformedOtherConfigValueName, testCase);
3017
3018         // Test Case 4:  TestOneGoodOtherConfigOneMalformedOtherConfigKey
3019         // Test Type:    Negative
3020         // Description:
3021         //     One perfectly fine BridgeOtherConfig
3022         //        (TestOneGoodOtherConfigOneMalformedOtherConfigValue_BridgeOtherConfigKey_1,
3023         //        TestOneGoodOtherConfigOneMalformedOtherConfig_BridgeOtherConfigValue_1)
3024         //     and one malformed BridgeOtherConfig which only has key specified
3025         //        (UNSPECIFIED,
3026         //        TestOneGoodOtherConfigOneMalformedOtherConfigKey_NoKeyForValue_2)
3027         // Expected:     A bridge is created without any other_config
3028         final String testOneGoodOtherConfigOneMalformedOtherConfigKeyName =
3029                 "TestOneGoodOtherConfigOneMalformedOtherConfigIdKey";
3030         otherConfigCounter = 0;
3031         oneGood = new BridgeOtherConfigsBuilder()
3032                 .setBridgeOtherConfigKey(String.format(FORMAT_STR, testOneGoodOtherConfigOneMalformedOtherConfigKeyName,
3033                         GOOD_KEY, ++otherConfigCounter))
3034                 .setBridgeOtherConfigValue(String.format(FORMAT_STR,
3035                         testOneGoodOtherConfigOneMalformedOtherConfigKeyName,
3036                         GOOD_VALUE, otherConfigCounter))
3037                 .build();
3038         oneBad = new BridgeOtherConfigsBuilder()
3039                 .setBridgeOtherConfigKey(String.format(FORMAT_STR,
3040                         testOneGoodOtherConfigOneMalformedOtherConfigKeyName, NO_KEY_FOR_VALUE, ++otherConfigCounter))
3041                 .build();
3042         oneGoodOneBadInput = (List<BridgeOtherConfigs>) Lists.newArrayList(
3043                 oneGood, oneBad);
3044         oneGoodOneBadExpected = null;
3045         testCase = Maps.newHashMap();
3046         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
3047         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
3048         testMap.put(testOneGoodOtherConfigOneMalformedOtherConfigKeyName, testCase);
3049
3050         return testMap;
3051     }
3052
3053     /*
3054      * @see <code>SouthboundIT.testCRUDBridgeOtherConfigs()</code>
3055      * This is helper test method to compare a test "set" of BridgeExternalIds against an expected "set"
3056      */
3057     private void assertExpectedBridgeOtherConfigsExist( List<BridgeOtherConfigs> expected,
3058                                                         List<BridgeOtherConfigs> test ) {
3059
3060         if (expected != null) {
3061             for (BridgeOtherConfigs expectedOtherConfig : expected) {
3062                 Assert.assertTrue(test.contains(expectedOtherConfig));
3063             }
3064         }
3065     }
3066
3067     /*
3068      * @see <code>SouthboundIT.generateBridgeOtherConfigsTestCases()</code> for specific test case information.
3069      */
3070     @Test
3071     public void testCRUDBridgeOtherConfigs() throws InterruptedException {
3072         final String TEST_BRIDGE_PREFIX = "CRUDBridgeOtherConfigs";
3073         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
3074         connectOvsdbNode(connectionInfo);
3075         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
3076         // the update has been performed.
3077         Map<String, Map<String, List<BridgeOtherConfigs>>> updateFromTestCases = generateBridgeOtherConfigsTestCases();
3078         Map<String, Map<String, List<BridgeOtherConfigs>>> updateToTestCases = generateBridgeOtherConfigsTestCases();
3079         Map<String, List<BridgeOtherConfigs>> updateFromTestCase;
3080         Map<String, List<BridgeOtherConfigs>> updateToTestCase;
3081         List<BridgeOtherConfigs> updateFromInputOtherConfigs;
3082         List<BridgeOtherConfigs> updateFromExpectedOtherConfigs;
3083         List<BridgeOtherConfigs> updateToInputOtherConfigs;
3084         List<BridgeOtherConfigs> updateToExpectedOtherConfigs;
3085         String testBridgeName;
3086
3087         int counter = 1;
3088         ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
3089         for (String updateFromTestCaseKey : updateFromTestCases.keySet()) {
3090             updateFromTestCase = updateFromTestCases.get(updateFromTestCaseKey);
3091             updateFromInputOtherConfigs = updateFromTestCase.get(INPUT_VALUES_KEY);
3092             updateFromExpectedOtherConfigs = updateFromTestCase.get(EXPECTED_VALUES_KEY);
3093             for (String testCaseKey : updateToTestCases.keySet()) {
3094                 testBridgeName = String.format("%s_%s_%d", TEST_BRIDGE_PREFIX, testCaseKey, counter);
3095                 counter += 1;
3096                 updateToTestCase = updateToTestCases.get(testCaseKey);
3097                 updateToInputOtherConfigs = updateToTestCase.get(INPUT_VALUES_KEY);
3098                 updateToExpectedOtherConfigs = updateToTestCase.get(EXPECTED_VALUES_KEY);
3099
3100                 TestCRUDBridgeOtherConfigsRunnable testRunnable =
3101                         new TestCRUDBridgeOtherConfigsRunnable(
3102                                 connectionInfo, testBridgeName,
3103                                 updateFromInputOtherConfigs,
3104                                 updateFromExpectedOtherConfigs,
3105                                 updateToInputOtherConfigs,
3106                                 updateToExpectedOtherConfigs);
3107                 executor.submit(testRunnable);
3108             }
3109         }
3110         executor.shutdown();
3111         executor.awaitTermination(5, TimeUnit.MINUTES);
3112
3113         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
3114     }
3115
3116     class TestCRUDBridgeOtherConfigsRunnable implements Runnable {
3117
3118         ConnectionInfo connectionInfo;
3119         String testBridgeName;
3120         List<BridgeOtherConfigs> updateFromInputOtherConfigs;
3121         List<BridgeOtherConfigs> updateFromExpectedOtherConfigs;
3122         List<BridgeOtherConfigs> updateToInputOtherConfigs;
3123         List<BridgeOtherConfigs> updateToExpectedOtherConfigs;
3124
3125         TestCRUDBridgeOtherConfigsRunnable(
3126                 ConnectionInfo connectionInfo, String testBridgeName,
3127                 List<BridgeOtherConfigs> updateFromInputOtherConfigs,
3128                 List<BridgeOtherConfigs> updateFromExpectedOtherConfigs,
3129                 List<BridgeOtherConfigs> updateToInputOtherConfigs,
3130                 List<BridgeOtherConfigs> updateToExpectedOtherConfigs) {
3131
3132             this.connectionInfo = connectionInfo;
3133             this.testBridgeName = testBridgeName;
3134             this.updateFromInputOtherConfigs = updateFromInputOtherConfigs;
3135             this.updateFromExpectedOtherConfigs = updateFromExpectedOtherConfigs;
3136             this.updateToInputOtherConfigs = updateToInputOtherConfigs;
3137             this.updateToExpectedOtherConfigs = updateToExpectedOtherConfigs;
3138         }
3139
3140         @Override
3141         public void run() {
3142             try {
3143                 test();
3144             } catch (InterruptedException e) {
3145                 e.printStackTrace();
3146             }
3147         }
3148
3149         public void test() throws InterruptedException {
3150             // CREATE: Create the test bridge
3151             boolean bridgeAdded = addBridge(connectionInfo, null,
3152                     testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
3153                     true, null, null, null, updateFromInputOtherConfigs);
3154             Assert.assertTrue(bridgeAdded);
3155
3156             // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
3157             // then repeat for OPERATIONAL data store
3158             List<BridgeOtherConfigs> updateFromConfigurationOtherConfigs = getBridge(connectionInfo, testBridgeName,
3159                     LogicalDatastoreType.CONFIGURATION).getBridgeOtherConfigs();
3160             assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
3161                     updateFromConfigurationOtherConfigs);
3162             List<BridgeOtherConfigs> updateFromOperationalOtherConfigs = getBridge(connectionInfo, testBridgeName)
3163                     .getBridgeOtherConfigs();
3164             assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
3165                     updateFromOperationalOtherConfigs);
3166
3167             // UPDATE:  update the external_ids
3168             OvsdbBridgeAugmentationBuilder bridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
3169             bridgeAugmentationBuilder.setBridgeOtherConfigs(updateToInputOtherConfigs);
3170             InstanceIdentifier<Node> bridgeIid =
3171                     createInstanceIdentifier(connectionInfo,
3172                             new OvsdbBridgeName(testBridgeName));
3173             NodeBuilder bridgeNodeBuilder = new NodeBuilder();
3174             Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
3175             bridgeNodeBuilder.setNodeId(bridgeNode.getNodeId());
3176             bridgeNodeBuilder.setKey(bridgeNode.getKey());
3177             bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, bridgeAugmentationBuilder.build());
3178             boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
3179                     bridgeNodeBuilder.build());
3180             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
3181             Assert.assertTrue(result);
3182
3183             // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
3184             // then repeat for OPERATIONAL data store
3185             List<BridgeOtherConfigs> updateToConfigurationOtherConfigs = getBridge(connectionInfo, testBridgeName,
3186                     LogicalDatastoreType.CONFIGURATION).getBridgeOtherConfigs();
3187             assertExpectedBridgeOtherConfigsExist(updateToExpectedOtherConfigs, updateToConfigurationOtherConfigs);
3188             assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
3189                     updateToConfigurationOtherConfigs);
3190             List<BridgeOtherConfigs> updateToOperationalOtherConfigs = getBridge(connectionInfo, testBridgeName)
3191                     .getBridgeOtherConfigs();
3192             if (updateFromExpectedOtherConfigs != null) {
3193                 assertExpectedBridgeOtherConfigsExist(updateToExpectedOtherConfigs,
3194                         updateToOperationalOtherConfigs);
3195                 assertExpectedBridgeOtherConfigsExist(updateFromExpectedOtherConfigs,
3196                         updateToOperationalOtherConfigs);
3197             }
3198
3199             // DELETE
3200             Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
3201         }
3202     }
3203
3204     /*
3205      * Generates the test cases involved in testing BridgeExternalIds.  See inline comments for descriptions of
3206      * the particular cases considered.
3207      *
3208      * The return value is a Map in the form (K,V)=(testCaseName,testCase).
3209      * - testCaseName is a String
3210      * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of
3211      *     either corresponding INPUT bridge external ids, or EXPECTED bridge external ids
3212      *     INPUT is the List we use when calling BridgeAugmentationBuilder.setBridgeExternalIds()
3213      *     EXPECTED is the List we expect to receive after calling BridgeAugmentationBuilder.getBridgeExternalIds()
3214      */
3215     private Map<String, Map<String, List<BridgeExternalIds>>> generateBridgeExternalIdsTestCases() {
3216         Map<String, Map<String, List<BridgeExternalIds>>> testMap =
3217                 new HashMap<String, Map<String, List<BridgeExternalIds>>>();
3218
3219         final String BRIDGE_EXTERNAL_ID_KEY = "BridgeExternalIdKey";
3220         final String BRIDGE_EXTERNAL_ID_VALUE = "BridgeExternalIdValue";
3221         final String FORMAT_STR = "%s_%s_%d";
3222         final String GOOD_KEY = "GoodKey";
3223         final String GOOD_VALUE = "GoodValue";
3224         final String NO_VALUE_FOR_KEY = "NoValueForKey";
3225         final String NO_KEY_FOR_VALUE = "NoKeyForValue";
3226
3227         // Test Case 1:  TestOneExternalId
3228         // Test Type:    Positive
3229         // Description:  Create a bridge with one BridgeExternalIds
3230         // Expected:     A bridge is created with the single external_ids specified below
3231         final String testOneExternalIdName = "TestOneExternalId";
3232         int externalIdCounter = 0;
3233         List<BridgeExternalIds> oneExternalId = (List<BridgeExternalIds>) Lists.newArrayList(
3234                 (new BridgeExternalIdsBuilder()
3235                         .setBridgeExternalIdKey(String.format(FORMAT_STR, testOneExternalIdName,
3236                                 BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter))
3237                         .setBridgeExternalIdValue(String.format(FORMAT_STR, testOneExternalIdName,
3238                                 BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter))
3239                         .build()));
3240         Map<String,List<BridgeExternalIds>> testCase = Maps.newHashMap();
3241         testCase.put(EXPECTED_VALUES_KEY, oneExternalId);
3242         testCase.put(INPUT_VALUES_KEY, oneExternalId);
3243         testMap.put(testOneExternalIdName, testCase);
3244
3245         // Test Case 2:  TestFiveExternalId
3246         // Test Type:    Positive
3247         // Description:  Create a bridge with multiple (five) BridgeExternalIds
3248         // Expected:     A bridge is created with the five external_ids specified below
3249         final String testFiveExternalIdName = "TestFiveExternalId";
3250         externalIdCounter = 0;
3251         List<BridgeExternalIds> fiveExternalId = (List<BridgeExternalIds>) Lists.newArrayList(
3252                 (new BridgeExternalIdsBuilder()
3253                         .setBridgeExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
3254                                 BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter))
3255                         .setBridgeExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
3256                                 BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter))
3257                         .build()),
3258                 (new BridgeExternalIdsBuilder()
3259                         .setBridgeExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
3260                                 BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter))
3261                         .setBridgeExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
3262                                 BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter))
3263                         .build()),
3264                 (new BridgeExternalIdsBuilder()
3265                         .setBridgeExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
3266                                 BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter))
3267                         .setBridgeExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
3268                                 BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter))
3269                         .build()),
3270                 (new BridgeExternalIdsBuilder()
3271                         .setBridgeExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
3272                                 BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter))
3273                         .setBridgeExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
3274                                 BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter))
3275                         .build()),
3276                 (new BridgeExternalIdsBuilder()
3277                         .setBridgeExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
3278                                 BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter))
3279                         .setBridgeExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
3280                                 BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter))
3281                         .build()));
3282         testCase = Maps.newHashMap();
3283         testCase.put(EXPECTED_VALUES_KEY, fiveExternalId);
3284         testCase.put(INPUT_VALUES_KEY, fiveExternalId);
3285         testMap.put(testFiveExternalIdName, testCase);
3286
3287         // Test Case 3:  TestOneGoodExternalIdOneMalformedExternalIdValue
3288         // Test Type:    Negative
3289         // Description:
3290         //     One perfectly fine BridgeExternalId
3291         //        (TestOneGoodExternalIdOneMalformedExternalIdValue_BridgeExternalIdKey_1,
3292         //        TestOneGoodExternalIdOneMalformedExternalId_BridgeExternalIdValue_1)
3293         //     and one malformed BridgeExternalId which only has key specified
3294         //        (TestOneGoodExternalIdOneMalformedExternalIdValue_NoValueForKey_2,
3295         //        UNSPECIFIED)
3296         // Expected:     A bridge is created without any external_ids
3297         final String testOneGoodExternalIdOneMalformedExternalIdValueName =
3298                 "TestOneGoodExternalIdOneMalformedExternalIdValue";
3299         externalIdCounter = 0;
3300         BridgeExternalIds oneGood = new BridgeExternalIdsBuilder()
3301                 .setBridgeExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdValueName,
3302                         GOOD_KEY, ++externalIdCounter))
3303                 .setBridgeExternalIdValue(String.format(FORMAT_STR,
3304                         testOneGoodExternalIdOneMalformedExternalIdValueName,
3305                         GOOD_VALUE, externalIdCounter))
3306                 .build();
3307         BridgeExternalIds oneBad = new BridgeExternalIdsBuilder()
3308                 .setBridgeExternalIdKey(String.format(FORMAT_STR,
3309                         testOneGoodExternalIdOneMalformedExternalIdValueName, NO_VALUE_FOR_KEY, ++externalIdCounter))
3310                 .build();
3311         List<BridgeExternalIds> oneGoodOneBadInput = (List<BridgeExternalIds>) Lists.newArrayList(
3312                 oneGood, oneBad);
3313         List<BridgeExternalIds> oneGoodOneBadExpected = null;
3314         testCase = Maps.newHashMap();
3315         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
3316         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
3317         testMap.put(testOneGoodExternalIdOneMalformedExternalIdValueName, testCase);
3318
3319         // Test Case 4:  TestOneGoodExternalIdOneMalformedExternalIdKey
3320         // Test Type:    Negative
3321         // Description:
3322         //     One perfectly fine BridgeExternalId
3323         //        (TestOneGoodExternalIdOneMalformedExternalIdValue_BridgeExternalIdKey_1,
3324         //        TestOneGoodExternalIdOneMalformedExternalId_BridgeExternalIdValue_1)
3325         //     and one malformed BridgeExternalId which only has key specified
3326         //        (UNSPECIFIED,
3327         //        TestOneGoodExternalIdOneMalformedExternalIdKey_NoKeyForValue_2)
3328         // Expected:     A bridge is created without any external_ids
3329         final String testOneGoodExternalIdOneMalformedExternalIdKeyName =
3330                 "TestOneGoodExternalIdOneMalformedExternalIdKey";
3331         externalIdCounter = 0;
3332         oneGood = new BridgeExternalIdsBuilder()
3333                 .setBridgeExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdKeyName,
3334                         GOOD_KEY, ++externalIdCounter))
3335                 .setBridgeExternalIdValue(String.format(FORMAT_STR,
3336                         testOneGoodExternalIdOneMalformedExternalIdKeyName,
3337                         GOOD_VALUE, externalIdCounter))
3338                 .build();
3339         oneBad = new BridgeExternalIdsBuilder()
3340                 .setBridgeExternalIdKey(String.format(FORMAT_STR,
3341                         testOneGoodExternalIdOneMalformedExternalIdKeyName, NO_KEY_FOR_VALUE, ++externalIdCounter))
3342                 .build();
3343         oneGoodOneBadInput = (List<BridgeExternalIds>) Lists.newArrayList(
3344                 oneGood, oneBad);
3345         oneGoodOneBadExpected = null;
3346         testCase = Maps.newHashMap();
3347         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
3348         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
3349         testMap.put(testOneGoodExternalIdOneMalformedExternalIdKeyName, testCase);
3350         return testMap;
3351     }
3352
3353     /*
3354      * @see <code>SouthboundIT.testCRUDBridgeExternalIds()</code>
3355      * This is helper test method to compare a test "set" of BridgeExternalIds against an expected "set"
3356      */
3357     private void assertExpectedBridgeExternalIdsExist( List<BridgeExternalIds> expected,
3358                                                        List<BridgeExternalIds> test ) {
3359
3360         if (expected != null) {
3361             for (BridgeExternalIds expectedExternalId : expected) {
3362                 Assert.assertTrue(test.contains(expectedExternalId));
3363             }
3364         }
3365     }
3366
3367     /*
3368      * @see <code>SouthboundIT.generateBridgeExternalIdsTestCases()</code> for specific test case information
3369      */
3370     @Test
3371     public void testCRUDBridgeExternalIds() throws InterruptedException {
3372         final String TEST_BRIDGE_PREFIX = "CRUDBridgeExternalIds";
3373         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
3374         connectOvsdbNode(connectionInfo);
3375         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
3376         // the update has been performed.
3377         Map<String, Map<String, List<BridgeExternalIds>>> updateFromTestCases = generateBridgeExternalIdsTestCases();
3378         Map<String, Map<String, List<BridgeExternalIds>>> updateToTestCases = generateBridgeExternalIdsTestCases();
3379         Map<String, List<BridgeExternalIds>> updateFromTestCase;
3380         List<BridgeExternalIds> updateFromInputExternalIds;
3381         List<BridgeExternalIds> updateFromExpectedExternalIds;
3382         Map<String, List<BridgeExternalIds>> updateToTestCase;
3383         List<BridgeExternalIds> updateToInputExternalIds;
3384         List<BridgeExternalIds> updateToExpectedExternalIds;
3385         String testBridgeName;
3386
3387         int counter = 1;
3388         ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
3389         for (String updateFromTestCaseKey : updateFromTestCases.keySet()) {
3390             updateFromTestCase = updateFromTestCases.get(updateFromTestCaseKey);
3391             updateFromInputExternalIds = updateFromTestCase.get(INPUT_VALUES_KEY);
3392             updateFromExpectedExternalIds = updateFromTestCase.get(EXPECTED_VALUES_KEY);
3393             for (String testCaseKey : updateToTestCases.keySet()) {
3394                 testBridgeName = String.format("%s_%s_d", TEST_BRIDGE_PREFIX, testCaseKey, counter);
3395                 counter += 1;
3396                 updateToTestCase = updateToTestCases.get(testCaseKey);
3397                 updateToInputExternalIds = updateToTestCase.get(INPUT_VALUES_KEY);
3398                 updateToExpectedExternalIds = updateToTestCase.get(EXPECTED_VALUES_KEY);
3399
3400                 TestCRUDBridgeExternalIdsRunnable testRunnable =
3401                         new TestCRUDBridgeExternalIdsRunnable(
3402                                 connectionInfo, testBridgeName,
3403                                 updateFromInputExternalIds,
3404                                 updateFromExpectedExternalIds,
3405                                 updateToInputExternalIds,
3406                                 updateToExpectedExternalIds);
3407                 executor.submit(testRunnable);
3408             }
3409         }
3410         executor.shutdown();
3411         executor.awaitTermination(5, TimeUnit.MINUTES);
3412
3413         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
3414     }
3415
3416     class TestCRUDBridgeExternalIdsRunnable implements Runnable {
3417         ConnectionInfo connectionInfo;
3418         String testBridgeName;
3419         List<BridgeExternalIds> updateFromInputExternalIds;
3420         List<BridgeExternalIds> updateFromExpectedExternalIds;
3421         List<BridgeExternalIds> updateToInputExternalIds;
3422         List<BridgeExternalIds> updateToExpectedExternalIds;
3423
3424         TestCRUDBridgeExternalIdsRunnable(
3425                 ConnectionInfo connectionInfo, String testBridgeName,
3426                 List<BridgeExternalIds> updateFromInputExternalIds,
3427                 List<BridgeExternalIds> updateFromExpectedExternalIds,
3428                 List<BridgeExternalIds> updateToInputExternalIds,
3429                 List<BridgeExternalIds> updateToExpectedExternalIds) {
3430
3431             this.connectionInfo = connectionInfo;
3432             this.testBridgeName = testBridgeName;
3433             this.updateFromInputExternalIds = updateFromInputExternalIds;
3434             this.updateFromExpectedExternalIds = updateFromExpectedExternalIds;
3435             this.updateToInputExternalIds = updateToInputExternalIds;
3436             this.updateToExpectedExternalIds = updateToExpectedExternalIds;
3437         }
3438
3439         @Override
3440         public void run() {
3441             try {
3442                 test();
3443             } catch (InterruptedException e) {
3444                 e.printStackTrace();
3445             }
3446         }
3447
3448         public void test() throws InterruptedException {
3449             // CREATE: Create the test bridge
3450             boolean bridgeAdded = addBridge(connectionInfo, null,
3451                     testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
3452                     true, null, updateFromInputExternalIds, null, null);
3453             Assert.assertTrue(bridgeAdded);
3454
3455             // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
3456             // then repeat for OPERATIONAL data store
3457             List<BridgeExternalIds> updateFromConfigurationExternalIds = getBridge(connectionInfo, testBridgeName,
3458                     LogicalDatastoreType.CONFIGURATION).getBridgeExternalIds();
3459             assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateFromConfigurationExternalIds);
3460             List<BridgeExternalIds> updateFromOperationalExternalIds = getBridge(connectionInfo, testBridgeName)
3461                     .getBridgeExternalIds();
3462             assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateFromOperationalExternalIds);
3463
3464             // UPDATE:  update the external_ids
3465             OvsdbBridgeAugmentationBuilder bridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
3466             bridgeAugmentationBuilder.setBridgeExternalIds(updateToInputExternalIds);
3467             InstanceIdentifier<Node> bridgeIid =
3468                     createInstanceIdentifier(connectionInfo,
3469                             new OvsdbBridgeName(testBridgeName));
3470             NodeBuilder bridgeNodeBuilder = new NodeBuilder();
3471             Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
3472             bridgeNodeBuilder.setNodeId(bridgeNode.getNodeId());
3473             bridgeNodeBuilder.setKey(bridgeNode.getKey());
3474             bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, bridgeAugmentationBuilder.build());
3475             boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
3476                     bridgeNodeBuilder.build());
3477             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
3478             Assert.assertTrue(result);
3479
3480             // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
3481             // then repeat for OPERATIONAL data store
3482             List<BridgeExternalIds> updateToConfigurationExternalIds = getBridge(connectionInfo, testBridgeName,
3483                     LogicalDatastoreType.CONFIGURATION).getBridgeExternalIds();
3484             assertExpectedBridgeExternalIdsExist(updateToExpectedExternalIds, updateToConfigurationExternalIds);
3485             assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateToConfigurationExternalIds);
3486             List<BridgeExternalIds> updateToOperationalExternalIds = getBridge(connectionInfo, testBridgeName)
3487                     .getBridgeExternalIds();
3488             if (updateFromExpectedExternalIds != null) {
3489                 assertExpectedBridgeExternalIdsExist(updateToExpectedExternalIds, updateToOperationalExternalIds);
3490                 assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateToOperationalExternalIds);
3491             }
3492
3493             // DELETE
3494             Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
3495         }
3496     }
3497
3498     public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key,OvsdbBridgeName bridgeName) {
3499         return SouthboundMapper.createInstanceIdentifier(createManagedNodeId(key, bridgeName));
3500     }
3501
3502     public static NodeId createManagedNodeId(ConnectionInfo key, OvsdbBridgeName bridgeName) {
3503         return createManagedNodeId(key.getRemoteIp(),key.getRemotePort(),bridgeName);
3504     }
3505
3506     public static NodeId createManagedNodeId(IpAddress ip, PortNumber port, OvsdbBridgeName bridgeName) {
3507         return new NodeId(createNodeId(ip,port).getValue()
3508                 + "/" + SouthboundConstants.BRIDGE_URI_PREFIX + "/" + bridgeName.getValue());
3509     }
3510
3511     public static NodeId createNodeId(IpAddress ip, PortNumber port) {
3512         String uriString = SouthboundConstants.OVSDB_URI_PREFIX + "://"
3513                 + new String(ip.getValue()) + ":" + port.getValue();
3514         Uri uri = new Uri(uriString);
3515         NodeId nodeId = new NodeId(uri);
3516         return nodeId;
3517     }
3518
3519     public static NodeKey createNodeKey(IpAddress ip, PortNumber port) {
3520         return new NodeKey(createNodeId(ip,port));
3521     }
3522
3523     public static Node createNode(ConnectionInfo key) {
3524         NodeBuilder nodeBuilder = new NodeBuilder();
3525         nodeBuilder.setNodeId(createNodeId(key.getRemoteIp(),key.getRemotePort()));
3526         nodeBuilder.addAugmentation(OvsdbNodeAugmentation.class, createOvsdbAugmentation(key));
3527         return nodeBuilder.build();
3528     }
3529
3530     public static OvsdbNodeAugmentation createOvsdbAugmentation(ConnectionInfo key) {
3531         OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = new OvsdbNodeAugmentationBuilder();
3532         ovsdbNodeBuilder.setConnectionInfo(key);
3533         return ovsdbNodeBuilder.build();
3534     }
3535
3536     public static NodeId createManagedNodeId(InstanceIdentifier<Node> iid) {
3537         NodeKey nodeKey = iid.firstKeyOf(Node.class, NodeKey.class);
3538         return nodeKey.getNodeId();
3539     }
3540 }