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