Squashed commit of the following:
[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 java.net.InetAddress;
20 import java.net.UnknownHostException;
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.HashSet;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Properties;
27 import java.util.Set;
28
29 import javax.inject.Inject;
30
31 import org.junit.Assert;
32 import org.junit.Before;
33 import org.junit.Test;
34 import org.junit.runner.RunWith;
35 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
36 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
37 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
38 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
39 import org.opendaylight.ovsdb.southbound.SouthboundProvider;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeBase;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes.VlanMode;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIdsBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.DatapathTypeEntry;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntryBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigs;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigsBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIds;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigs;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigsBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder;
78 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
79 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
80 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
81 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
82 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
83 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
84 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
85 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
86 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
87 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
88 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
89 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
90 import org.ops4j.pax.exam.Configuration;
91 import org.ops4j.pax.exam.Option;
92 import org.ops4j.pax.exam.junit.PaxExam;
93 import org.ops4j.pax.exam.karaf.options.LogLevelOption;
94 import org.ops4j.pax.exam.options.MavenUrlReference;
95 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
96 import org.ops4j.pax.exam.spi.reactors.PerClass;
97 import org.osgi.framework.BundleContext;
98 import org.slf4j.Logger;
99 import org.slf4j.LoggerFactory;
100
101 /**
102  * Integration tests for southbound-impl
103  *
104  * @author Sam Hague (shague@redhat.com)
105  */
106 @RunWith(PaxExam.class)
107 @ExamReactorStrategy(PerClass.class)
108 public class SouthboundIT extends AbstractMdsalTestBase {
109     private static final String EXPECTED_VALUES_KEY = "ExpectedValuesKey";
110     private static final String INPUT_VALUES_KEY = "InputValuesKey";
111     private static final String NETDEV_DP_TYPE = "netdev";
112     private static final Logger LOG = LoggerFactory.getLogger(SouthboundIT.class);
113     private static final int OVSDB_UPDATE_TIMEOUT = 1000;
114     private static DataBroker dataBroker = null;
115     private static String addressStr;
116     private static String portStr;
117     private static String connectionType;
118     private static Boolean setup = false;
119     private static MdsalUtils mdsalUtils = null;
120     private static final String NETVIRT = "org.opendaylight.ovsdb.openstack.net-virt";
121     private static final String NETVIRTPROVIDERS = "org.opendaylight.ovsdb.openstack.net-virt-providers";
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         return ((OvsdbTerminationPointAugmentation)
682                 getBridgeNode(connectionInfo, bridgeName, store)
683                 .getTerminationPoint().get(index)
684                 .getAugmentation(OvsdbTerminationPointAugmentation.class));
685     }
686
687     @Test
688     public void testTerminationPointOfPort() throws InterruptedException {
689         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
690         connectOvsdbNode(connectionInfo);
691
692         Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
693         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
694         Assert.assertNotNull(bridge);
695         LOG.info("bridge: {}", bridge);
696         NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier(
697                 connectionInfo, bridge.getBridgeName()));
698         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
699                 createGenericOvsdbTerminationPointAugmentationBuilder();
700         String portName = "testOfPort";
701         ovsdbTerminationBuilder.setName(portName);
702         Long ofPortExpected = new Long(45002);
703         ovsdbTerminationBuilder.setOfport(ofPortExpected);
704         Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
705         InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
706         Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
707         Assert.assertNotNull(terminationPointNode);
708
709         List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
710         for (TerminationPoint terminationPoint : terminationPoints) {
711             OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
712                     terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
713             if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
714                 Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
715                 // if ephemeral port 45002 is in use, ofPort is set to 1
716                 Assert.assertTrue(ofPort.equals(ofPortExpected) || ofPort.equals(new Long(1)));
717                 LOG.info("ofPort: {}", ofPort);
718             }
719         }
720         Assert.assertTrue(deleteBridge(connectionInfo));
721         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
722     }
723
724     @Test
725     public void testTerminationPointOfPortRequest() throws InterruptedException {
726         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
727         connectOvsdbNode(connectionInfo);
728         Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
729         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
730         Assert.assertNotNull(bridge);
731         NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier(
732                 connectionInfo, bridge.getBridgeName()));
733         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
734                 createGenericOvsdbTerminationPointAugmentationBuilder();
735         String portName = "testOfPortRequest";
736         ovsdbTerminationBuilder.setName(portName);
737         Long ofPortExpected = new Long(45008);
738         Integer ofPortRequestExpected = ofPortExpected.intValue();
739         Long ofPortInput = new Long(45008);
740         ovsdbTerminationBuilder.setOfport(ofPortInput);
741         ovsdbTerminationBuilder.setOfportRequest(ofPortRequestExpected);
742         Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
743         InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
744         Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
745         Assert.assertNotNull(terminationPointNode);
746
747         List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
748         for (TerminationPoint terminationPoint : terminationPoints) {
749             OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
750                     terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
751             if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
752                 Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
753                 // if ephemeral port 45002 is in use, ofPort is set to 1
754                 Assert.assertTrue(ofPort.equals(ofPortExpected) || ofPort.equals(new Long(1)));
755                 LOG.info("ofPort: {}", ofPort);
756
757                 Integer ofPortRequest = ovsdbTerminationPointAugmentation.getOfportRequest();
758                 Assert.assertTrue(ofPortRequest.equals(ofPortRequestExpected));
759                 LOG.info("ofPortRequest: {}", ofPortRequest);
760             }
761         }
762         Assert.assertTrue(deleteBridge(connectionInfo));
763         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
764     }
765
766     /*
767      * Generates the test cases involved in testing PortExternalIds.  See inline comments for descriptions of
768      * the particular cases considered.
769      *
770      * The return value is a Map in the form (K,V)=(testCaseName,testCase).
771      * - testCaseName is a String
772      * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of
773      *     either corresponding INPUT port external_ids, or EXPECTED port external_ids
774      *     INPUT    is the List we use when calling
775      *              <code>TerminationPointAugmentationBuilder.setPortExternalIds()</code>
776      *     EXPECTED is the List we expect to receive after calling
777      *              <code>TerminationPointAugmentationBuilder.getPortExternalIds()</code>
778      */
779     private Map<String, Map<String, List<PortExternalIds>>> generatePortExternalIdsTestCases() {
780         Map<String, Map<String, List<PortExternalIds>>> testMap =
781                 new HashMap<String, Map<String, List<PortExternalIds>>>();
782
783         final String PORT_EXTERNAL_ID_KEY = "PortExternalIdKey";
784         final String PORT_EXTERNAL_ID_VALUE = "PortExternalIdValue";
785         final String FORMAT_STR = "%s_%s_%d";
786         final String GOOD_KEY = "GoodKey";
787         final String GOOD_VALUE = "GoodValue";
788         final String NO_VALUE_FOR_KEY = "NoValueForKey";
789         final String NO_KEY_FOR_VALUE = "NoKeyForValue";
790
791         // Test Case 1:  TestOneExternalId
792         // Test Type:    Positive
793         // Description:  Create a termination point with one PortExternalIds
794         // Expected:     A port is created with the single external_ids specified below
795         final String testOneExternalIdName = "TestOneExternalId";
796         int externalIdCounter = 0;
797         List<PortExternalIds> oneExternalId = (List<PortExternalIds>) Lists.newArrayList(
798             (new PortExternalIdsBuilder()
799                 .setExternalIdKey(String.format(FORMAT_STR, testOneExternalIdName,
800                             PORT_EXTERNAL_ID_KEY, ++externalIdCounter))
801                     .setExternalIdValue(String.format(FORMAT_STR, testOneExternalIdName,
802                             PORT_EXTERNAL_ID_VALUE, externalIdCounter))
803                     .build()));
804         Map<String,List<PortExternalIds>> testCase = Maps.newHashMap();
805         testCase.put(EXPECTED_VALUES_KEY, oneExternalId);
806         testCase.put(INPUT_VALUES_KEY, oneExternalId);
807         testMap.put(testOneExternalIdName, testCase);
808
809         // Test Case 2:  TestFiveExternalId
810         // Test Type:    Positive
811         // Description:  Create a termination point with multiple (five) PortExternalIds
812         // Expected:     A port is created with the five external_ids specified below
813         final String testFiveExternalIdName = "TestFiveExternalId";
814         externalIdCounter = 0;
815         List<PortExternalIds> fiveExternalId = (List<PortExternalIds>) Lists.newArrayList(
816             (new PortExternalIdsBuilder()
817                 .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
818                             PORT_EXTERNAL_ID_KEY, ++externalIdCounter))
819                     .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
820                             PORT_EXTERNAL_ID_VALUE, externalIdCounter))
821                     .build()),
822             (new PortExternalIdsBuilder()
823                 .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
824                             PORT_EXTERNAL_ID_KEY, ++externalIdCounter))
825                     .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
826                             PORT_EXTERNAL_ID_VALUE, externalIdCounter))
827                     .build()),
828             (new PortExternalIdsBuilder()
829                 .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
830                             PORT_EXTERNAL_ID_KEY, ++externalIdCounter))
831                     .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
832                             PORT_EXTERNAL_ID_VALUE, externalIdCounter))
833                     .build()),
834             (new PortExternalIdsBuilder()
835                 .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
836                             PORT_EXTERNAL_ID_KEY, ++externalIdCounter))
837                     .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
838                             PORT_EXTERNAL_ID_VALUE, externalIdCounter))
839                     .build()),
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         testCase = Maps.newHashMap();
847         testCase.put(EXPECTED_VALUES_KEY, fiveExternalId);
848         testCase.put(INPUT_VALUES_KEY, fiveExternalId);
849         testMap.put(testOneExternalIdName, testCase);
850
851         // Test Case 3:  TestOneGoodExternalIdOneMalformedExternalIdValue
852         // Test Type:    Negative
853         // Description:
854         //     One perfectly fine PortExternalId
855         //        (TestOneGoodExternalIdOneMalformedExternalIdValue_PortExternalIdKey_1,
856         //        TestOneGoodExternalIdOneMalformedExternalId_PortExternalIdValue_1)
857         //     and one malformed PortExternalId which only has key specified
858         //        (TestOneGoodExternalIdOneMalformedExternalIdValue_NoValueForKey_2,
859         //        UNSPECIFIED)
860         // Expected:     A port is created without any external_ids
861         final String testOneGoodExternalIdOneMalformedExternalIdValueName =
862                 "TestOneGoodExternalIdOneMalformedExternalIdValue";
863         externalIdCounter = 0;
864         PortExternalIds oneGood = new PortExternalIdsBuilder()
865             .setExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdValueName,
866                     GOOD_KEY, ++externalIdCounter))
867                 .setExternalIdValue(String.format("FORMAT_STR",
868                         testOneGoodExternalIdOneMalformedExternalIdValueName,
869                             GOOD_VALUE, externalIdCounter))
870                 .build();
871         PortExternalIds oneBad = new PortExternalIdsBuilder()
872             .setExternalIdKey(String.format(FORMAT_STR,
873                     testOneGoodExternalIdOneMalformedExternalIdValueName, NO_VALUE_FOR_KEY, ++externalIdCounter))
874                 .build();
875         List<PortExternalIds> oneGoodOneBadInput = (List<PortExternalIds>) Lists.newArrayList(
876                 oneGood, oneBad);
877         List<PortExternalIds> oneGoodOneBadExpected = null;
878         testCase = Maps.newHashMap();
879         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
880         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
881
882         // Test Case 4:  TestOneGoodExternalIdOneMalformedExternalIdKey
883         // Test Type:    Negative
884         // Description:
885         //     One perfectly fine PortExternalId
886         //        (TestOneGoodExternalIdOneMalformedExternalIdValue_PortExternalIdKey_1,
887         //        TestOneGoodExternalIdOneMalformedExternalId_PortExternalIdValue_1)
888         //     and one malformed PortExternalId which only has key specified
889         //        (UNSPECIFIED,
890         //        TestOneGoodExternalIdOneMalformedExternalIdKey_NoKeyForValue_2)
891         // Expected:     A port is created without any external_ids
892         final String testOneGoodExternalIdOneMalformedExternalIdKeyName =
893                 "TestOneGoodExternalIdOneMalformedExternalIdKey";
894         externalIdCounter = 0;
895         oneGood = new PortExternalIdsBuilder()
896             .setExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdKeyName,
897                     GOOD_KEY, ++externalIdCounter))
898                 .setExternalIdValue(String.format("FORMAT_STR",
899                         testOneGoodExternalIdOneMalformedExternalIdKeyName,
900                             GOOD_VALUE, externalIdCounter))
901                 .build();
902         oneBad = new PortExternalIdsBuilder()
903             .setExternalIdKey(String.format(FORMAT_STR,
904                     testOneGoodExternalIdOneMalformedExternalIdKeyName, NO_KEY_FOR_VALUE, ++externalIdCounter))
905                 .build();
906         oneGoodOneBadInput = (List<PortExternalIds>) Lists.newArrayList(
907                 oneGood, oneBad);
908         oneGoodOneBadExpected = null;
909         testCase = Maps.newHashMap();
910         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
911         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
912
913         return testMap;
914     }
915
916     /*
917      * @see <code>SouthboundIT.testCRUDPortExternalIds()</code>
918      * This is helper test method to compare a test "set" of BridgeExternalIds against an expected "set"
919      */
920     private void assertExpectedPortExternalIdsExist( List<PortExternalIds> expected,
921             List<PortExternalIds> test ) {
922
923         if (expected != null) {
924             for (PortExternalIds expectedExternalId : expected) {
925                 Assert.assertTrue(test.contains(expectedExternalId));
926             }
927         } else {
928             Assert.assertNull(test);
929         }
930     }
931
932     /*
933      * @see <code>SouthboundIT.testCRUDPortExternalIds()</code>
934      * This is a helper test method.  The method only checks if
935      * <code>updateFromInputExternalIds != updateToInputExternalIds</code>,  (i.e., the updateTo "set" isn't the same
936      * as the updateFrom "set".  Then, the method ensures each element of erase is not an element of test, as the input
937      * test cases are divergent.
938      */
939     private void assertPortExternalIdsErased( List<PortExternalIds> updateFromInputExternalIds,
940             List<PortExternalIds> updateToInputExternalIds,
941             List<PortExternalIds> updateFromExpectedExternalIds,
942             List<PortExternalIds> updateToTestExternalIds ) {
943
944         if (!updateFromInputExternalIds.containsAll(updateToInputExternalIds)) {
945             for (PortExternalIds erasedExternalId : updateFromExpectedExternalIds) {
946                 Assert.assertTrue(!updateToTestExternalIds.contains(erasedExternalId));
947             }
948         }
949     }
950
951     /*
952      * Tests the CRUD operations for <code>Port</code> <code>external_ids</code>.
953      *
954      * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
955      */
956     @Test
957     public void testCRUDTerminationPointPortExternalIds() throws InterruptedException {
958         final String TEST_PREFIX = "CRUDTPPortExternalIds";
959         final int TERMINATION_POINT_TEST_INDEX = 0;
960
961         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
962         connectOvsdbNode(connectionInfo);
963
964         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
965         // the update has been performed.
966         Map<String, Map<String, List<PortExternalIds>>> updateFromTestCases = generatePortExternalIdsTestCases();
967         Map<String, Map<String, List<PortExternalIds>>> updateToTestCases = generatePortExternalIdsTestCases();
968         Map<String, List<PortExternalIds>> updateFromTestCase = null;
969         List<PortExternalIds> updateFromInputExternalIds = null;
970         List<PortExternalIds> updateFromExpectedExternalIds = null;
971         List<PortExternalIds> updateFromConfigurationExternalIds = null;
972         List<PortExternalIds> updateFromOperationalExternalIds = null;
973         Map<String, List<PortExternalIds>> updateToTestCase = null;
974         List<PortExternalIds> updateToInputExternalIds = null;
975         List<PortExternalIds> updateToExpectedExternalIds = null;
976         List<PortExternalIds> updateToConfigurationExternalIds = null;
977         List<PortExternalIds> updateToOperationalExternalIds = null;
978         String testBridgeName = null;
979         String testPortName = null;
980         OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation = null;
981         OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmenation = null;
982         OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation = null;
983         OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation = null;
984         OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder = null;
985         OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder = null;
986         TerminationPointBuilder tpUpdateBuilder = null;
987         NodeBuilder portUpdateNodeBuilder = null;
988         NodeId testBridgeNodeId = null;
989         NodeId portUpdateNodeId = null;
990         InstanceIdentifier<Node> portIid = null;
991         boolean result = false;
992
993         for (String updateFromTestCaseKey : updateFromTestCases.keySet()) {
994             updateFromTestCase = updateFromTestCases.get(updateFromTestCaseKey);
995             updateFromInputExternalIds = updateFromTestCase.get(INPUT_VALUES_KEY);
996             updateFromExpectedExternalIds = updateFromTestCase.get(EXPECTED_VALUES_KEY);
997             for (String testCaseKey : updateToTestCases.keySet()) {
998                 testPortName = testBridgeName = String.format("%s_%s", TEST_PREFIX, testCaseKey);
999                 updateToTestCase = updateToTestCases.get(testCaseKey);
1000                 updateToInputExternalIds = updateToTestCase.get(INPUT_VALUES_KEY);
1001                 updateToExpectedExternalIds = updateToTestCase.get(EXPECTED_VALUES_KEY);
1002
1003                 // CREATE: Create the test bridge
1004                 Assert.assertTrue(addBridge(connectionInfo, null,
1005                         testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
1006                         true, null, null, null));
1007                 testBridgeNodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier(
1008                         connectionInfo, new OvsdbBridgeName(testBridgeName)));
1009                 tpCreateAugmentationBuilder = createGenericOvsdbTerminationPointAugmentationBuilder();
1010                 tpCreateAugmentationBuilder.setName(testPortName);
1011                 tpCreateAugmentationBuilder.setPortExternalIds(updateFromInputExternalIds);
1012                 Assert.assertTrue(addTerminationPoint(testBridgeNodeId, testPortName, tpCreateAugmentationBuilder));
1013
1014                 // READ: Read the test port and ensure changes are propagated to the CONFIGURATION data store,
1015                 // then repeat for OPERATIONAL data store
1016                 updateFromConfigurationTerminationPointAugmentation =
1017                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1018                                 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1019                 updateFromConfigurationExternalIds = updateFromConfigurationTerminationPointAugmentation
1020                         .getPortExternalIds();
1021                 assertExpectedPortExternalIdsExist(updateFromExpectedExternalIds, updateFromConfigurationExternalIds);
1022                 updateFromOperationalTerminationPointAugmenation =
1023                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1024                                 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1025                 updateFromOperationalExternalIds = updateFromOperationalTerminationPointAugmenation
1026                         .getPortExternalIds();
1027                 assertExpectedPortExternalIdsExist(updateFromExpectedExternalIds, updateFromOperationalExternalIds);
1028
1029                 // UPDATE:  update the external_ids
1030                 testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeName).getNodeId();
1031                 tpUpdateAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
1032                 tpUpdateAugmentationBuilder.setPortExternalIds(updateToInputExternalIds);
1033                 portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1034                 portUpdateNodeBuilder = new NodeBuilder();
1035                 portUpdateNodeId = SouthboundMapper.createManagedNodeId(portIid);
1036                 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1037                 tpUpdateBuilder = new TerminationPointBuilder();
1038                 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testPortName)));
1039                 tpUpdateBuilder.addAugmentation(
1040                         OvsdbTerminationPointAugmentation.class,
1041                         tpUpdateAugmentationBuilder.build());
1042                 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1043                 result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1044                         portIid, portUpdateNodeBuilder.build());
1045                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1046                 Assert.assertTrue(result);
1047
1048                 // READ: the test port and ensure changes are propagated to the CONFIGURATION data store,
1049                 // then repeat for OPERATIONAL data store
1050                 updateToConfigurationTerminationPointAugmentation =
1051                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1052                                 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1053                 updateToConfigurationExternalIds = updateToConfigurationTerminationPointAugmentation
1054                         .getPortExternalIds();
1055                 assertExpectedPortExternalIdsExist(updateToExpectedExternalIds, updateToConfigurationExternalIds);
1056                 updateToOperationalTerminationPointAugmentation =
1057                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1058                                 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1059                 updateToOperationalExternalIds = updateToOperationalTerminationPointAugmentation.getPortExternalIds();
1060                 assertExpectedPortExternalIdsExist(updateToExpectedExternalIds, updateToOperationalExternalIds);
1061
1062                 // Make sure the old port external ids aren't present in the CONFIGURATION data store
1063                 assertPortExternalIdsErased(updateFromInputExternalIds, updateToInputExternalIds,
1064                         updateFromExpectedExternalIds, updateToConfigurationExternalIds);
1065                 assertPortExternalIdsErased(updateFromInputExternalIds, updateToInputExternalIds,
1066                         updateFromExpectedExternalIds, updateToConfigurationExternalIds);
1067
1068                 // DELETE
1069                 Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
1070             }
1071         }
1072         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1073     }
1074
1075     /*
1076      * Generates the test cases involved in testing InterfaceExternalIds.  See inline comments for descriptions of
1077      * the particular cases considered.
1078      *
1079      * The return value is a Map in the form (K,V)=(testCaseName,testCase).
1080      * - testCaseName is a String
1081      * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of
1082      *     either corresponding INPUT interface external_ids, or EXPECTED interface external_ids
1083      *     INPUT    is the List we use when calling
1084      *              <code>TerminationPointAugmentationBuilder.setInterfaceExternalIds()</code>
1085      *     EXPECTED is the List we expect to receive after calling
1086      *              <code>TerminationPointAugmentationBuilder.getInterfaceExternalIds()</code>
1087      */
1088     private Map<String, Map<String, List<InterfaceExternalIds>>> generateInterfaceExternalIdsTestCases() {
1089         Map<String, Map<String, List<InterfaceExternalIds>>> testMap =
1090                 new HashMap<String, Map<String, List<InterfaceExternalIds>>>();
1091
1092         final String INTERFACE_EXTERNAL_ID_KEY = "IntExternalIdKey";
1093         final String INTERFACE_EXTERNAL_ID_VALUE = "IntExternalIdValue";
1094         final String FORMAT_STR = "%s_%s_%d";
1095         final String GOOD_KEY = "GoodKey";
1096         final String GOOD_VALUE = "GoodValue";
1097         final String NO_VALUE_FOR_KEY = "NoValueForKey";
1098         final String NO_KEY_FOR_VALUE = "NoKeyForValue";
1099
1100         // Test Case 1:  TestOneExternalId
1101         // Test Type:    Positive
1102         // Description:  Create a termination point with one InterfaceExternalIds
1103         // Expected:     A termination point is created with the single external_ids specified below
1104         final String testOneExternalIdName = "TestOneExternalId";
1105         int externalIdCounter = 0;
1106         List<InterfaceExternalIds> oneExternalId = (List<InterfaceExternalIds>) Lists.newArrayList(
1107             (new InterfaceExternalIdsBuilder()
1108                 .setExternalIdKey(String.format(FORMAT_STR, testOneExternalIdName,
1109                             INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter))
1110                     .setExternalIdValue(String.format(FORMAT_STR, testOneExternalIdName,
1111                             INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter))
1112                     .build()));
1113         Map<String,List<InterfaceExternalIds>> testCase = Maps.newHashMap();
1114         testCase.put(EXPECTED_VALUES_KEY, oneExternalId);
1115         testCase.put(INPUT_VALUES_KEY, oneExternalId);
1116         testMap.put(testOneExternalIdName, testCase);
1117
1118         // Test Case 2:  TestFiveExternalId
1119         // Test Type:    Positive
1120         // Description:  Create a termination point with multiple (five) InterfaceExternalIds
1121         // Expected:     A termination point is created with the five external_ids specified below
1122         final String testFiveExternalIdName = "TestFiveExternalId";
1123         externalIdCounter = 0;
1124         List<InterfaceExternalIds> fiveExternalId = (List<InterfaceExternalIds>) Lists.newArrayList(
1125             (new InterfaceExternalIdsBuilder()
1126                 .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
1127                             INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter))
1128                     .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
1129                             INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter))
1130                     .build()),
1131             (new InterfaceExternalIdsBuilder()
1132                 .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
1133                             INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter))
1134                     .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
1135                             INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter))
1136                     .build()),
1137             (new InterfaceExternalIdsBuilder()
1138                 .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
1139                             INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter))
1140                     .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
1141                             INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter))
1142                     .build()),
1143             (new InterfaceExternalIdsBuilder()
1144                 .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
1145                             INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter))
1146                     .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
1147                             INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter))
1148                     .build()),
1149             (new InterfaceExternalIdsBuilder()
1150                 .setExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
1151                         INTERFACE_EXTERNAL_ID_KEY, ++externalIdCounter))
1152                     .setExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
1153                             INTERFACE_EXTERNAL_ID_VALUE, externalIdCounter))
1154                     .build()));
1155         testCase = Maps.newHashMap();
1156         testCase.put(EXPECTED_VALUES_KEY, fiveExternalId);
1157         testCase.put(INPUT_VALUES_KEY, fiveExternalId);
1158         testMap.put(testOneExternalIdName, testCase);
1159
1160         // Test Case 3:  TestOneGoodExternalIdOneMalformedExternalIdValue
1161         // Test Type:    Negative
1162         // Description:
1163         //     One perfectly fine InterfaceExternalId
1164         //        (TestOneGoodExternalIdOneMalformedExternalIdValue_IntExternalIdKey_1,
1165         //        TestOneGoodExternalIdOneMalformedExternalId_IntExternalIdValue_1)
1166         //     and one malformed PortExternalId which only has key specified
1167         //        (TestOneGoodExternalIdOneMalformedExternalIdValue_NoValueForKey_2,
1168         //        UNSPECIFIED)
1169         // Expected:     A termination point is created without any external_ids
1170         final String testOneGoodExternalIdOneMalformedExternalIdValueName =
1171                 "TestOneGoodExternalIdOneMalformedExternalIdValue";
1172         externalIdCounter = 0;
1173         InterfaceExternalIds oneGood = new InterfaceExternalIdsBuilder()
1174             .setExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdValueName,
1175                     GOOD_KEY, ++externalIdCounter))
1176                 .setExternalIdValue(String.format("FORMAT_STR",
1177                         testOneGoodExternalIdOneMalformedExternalIdValueName,
1178                             GOOD_VALUE, externalIdCounter))
1179                 .build();
1180         InterfaceExternalIds oneBad = new InterfaceExternalIdsBuilder()
1181             .setExternalIdKey(String.format(FORMAT_STR,
1182                     testOneGoodExternalIdOneMalformedExternalIdValueName, NO_VALUE_FOR_KEY, ++externalIdCounter))
1183                 .build();
1184         List<InterfaceExternalIds> oneGoodOneBadInput = (List<InterfaceExternalIds>) Lists.newArrayList(
1185                 oneGood, oneBad);
1186         List<InterfaceExternalIds> oneGoodOneBadExpected = null;
1187         testCase = Maps.newHashMap();
1188         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
1189         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
1190
1191         // Test Case 4:  TestOneGoodExternalIdOneMalformedExternalIdKey
1192         // Test Type:    Negative
1193         // Description:
1194         //     One perfectly fine InterfaceExternalId
1195         //        (TestOneGoodExternalIdOneMalformedExternalIdValue_IntExternalIdKey_1,
1196         //        TestOneGoodExternalIdOneMalformedExternalId_IntExternalIdValue_1)
1197         //     and one malformed BridgeExternalId which only has key specified
1198         //        (UNSPECIFIED,
1199         //        TestOneGoodExternalIdOneMalformedExternalIdKey_NoKeyForValue_2)
1200         // Expected:     A termination point is created without any external_ids
1201         final String testOneGoodExternalIdOneMalformedExternalIdKeyName =
1202                 "TestOneGoodExternalIdOneMalformedExternalIdKey";
1203         externalIdCounter = 0;
1204         oneGood = new InterfaceExternalIdsBuilder()
1205             .setExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdKeyName,
1206                     GOOD_KEY, ++externalIdCounter))
1207                 .setExternalIdValue(String.format("FORMAT_STR",
1208                         testOneGoodExternalIdOneMalformedExternalIdKeyName,
1209                             GOOD_VALUE, externalIdCounter))
1210                 .build();
1211         oneBad = new InterfaceExternalIdsBuilder()
1212             .setExternalIdKey(String.format(FORMAT_STR,
1213                     testOneGoodExternalIdOneMalformedExternalIdKeyName, NO_KEY_FOR_VALUE, ++externalIdCounter))
1214                 .build();
1215         oneGoodOneBadInput = (List<InterfaceExternalIds>) Lists.newArrayList(
1216                 oneGood, oneBad);
1217         oneGoodOneBadExpected = null;
1218         testCase = Maps.newHashMap();
1219         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
1220         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
1221
1222         return testMap;
1223     }
1224
1225     /*
1226      * @see <code>SouthboundIT.testCRUDInterfaceExternalIds()</code>
1227      * This is helper test method to compare a test "set" of InterfaceExternalIds against an expected "set"
1228      */
1229     private void assertExpectedInterfaceExternalIdsExist( List<InterfaceExternalIds> expected,
1230             List<InterfaceExternalIds> test ) {
1231
1232         if (expected != null) {
1233             for (InterfaceExternalIds expectedExternalId : expected) {
1234                 Assert.assertTrue(test.contains(expectedExternalId));
1235             }
1236         } else {
1237             Assert.assertNull(test);
1238         }
1239     }
1240
1241     /*
1242      * @see <code>SouthboundIT.testCRUDInterfaceExternalIds()</code>
1243      * This is a helper test method.  The method only checks if
1244      * <code>updateFromInputExternalIds != updateToInputExternalIds</code>,  (i.e., the updateTo "set" isn't the same
1245      * as the updateFrom "set".  Then, the method ensures each element of erase is not an element of test, as the input
1246      * test cases are divergent.
1247      */
1248     private void assertInterfaceExternalIdsErased( List<InterfaceExternalIds> updateFromInputExternalIds,
1249             List<InterfaceExternalIds> updateToInputExternalIds,
1250             List<InterfaceExternalIds> updateFromExpectedExternalIds,
1251             List<InterfaceExternalIds> updateToTestExternalIds ) {
1252
1253         if (!updateFromInputExternalIds.containsAll(updateToInputExternalIds)) {
1254             for (InterfaceExternalIds erasedExternalId : updateFromExpectedExternalIds) {
1255                 Assert.assertTrue(!updateToTestExternalIds.contains(erasedExternalId));
1256             }
1257         }
1258     }
1259
1260     /*
1261      * Tests the CRUD operations for <code>Interface</code> <code>external_ids</code>.
1262      *
1263      * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1264      */
1265     @Test
1266     public void testCRUDTerminationPointInterfaceExternalIds() throws InterruptedException {
1267         final String TEST_PREFIX = "CRUDTPInterfaceExternalIds";
1268         final int TERMINATION_POINT_TEST_INDEX = 0;
1269
1270         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
1271         connectOvsdbNode(connectionInfo);
1272
1273         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
1274         // the update has been performed.
1275         Map<String, Map<String, List<InterfaceExternalIds>>> updateFromTestCases =
1276                 generateInterfaceExternalIdsTestCases();
1277         Map<String, Map<String, List<InterfaceExternalIds>>> updateToTestCases =
1278                 generateInterfaceExternalIdsTestCases();
1279         Map<String, List<InterfaceExternalIds>> updateFromTestCase = null;
1280         List<InterfaceExternalIds> updateFromInputExternalIds = null;
1281         List<InterfaceExternalIds> updateFromExpectedExternalIds = null;
1282         List<InterfaceExternalIds> updateFromConfigurationExternalIds = null;
1283         List<InterfaceExternalIds> updateFromOperationalExternalIds = null;
1284         Map<String, List<InterfaceExternalIds>> updateToTestCase = null;
1285         List<InterfaceExternalIds> updateToInputExternalIds = null;
1286         List<InterfaceExternalIds> updateToExpectedExternalIds = null;
1287         List<InterfaceExternalIds> updateToConfigurationExternalIds = null;
1288         List<InterfaceExternalIds> updateToOperationalExternalIds = null;
1289         String testBridgeName = null;
1290         String testPortName = null;
1291         OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation = null;
1292         OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmenation = null;
1293         OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation = null;
1294         OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation = null;
1295         OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder = null;
1296         OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder = null;
1297         TerminationPointBuilder tpUpdateBuilder = null;
1298         NodeBuilder portUpdateNodeBuilder = null;
1299         NodeId testBridgeNodeId = null;
1300         NodeId portUpdateNodeId = null;
1301         InstanceIdentifier<Node> portIid = null;
1302         boolean result = false;
1303
1304         for (String updateFromTestCaseKey : updateFromTestCases.keySet()) {
1305             updateFromTestCase = updateFromTestCases.get(updateFromTestCaseKey);
1306             updateFromInputExternalIds = updateFromTestCase.get(INPUT_VALUES_KEY);
1307             updateFromExpectedExternalIds = updateFromTestCase.get(EXPECTED_VALUES_KEY);
1308             for (String testCaseKey : updateToTestCases.keySet()) {
1309                 testPortName = testBridgeName = String.format("%s_%s", TEST_PREFIX, testCaseKey);
1310                 updateToTestCase = updateToTestCases.get(testCaseKey);
1311                 updateToInputExternalIds = updateToTestCase.get(INPUT_VALUES_KEY);
1312                 updateToExpectedExternalIds = updateToTestCase.get(EXPECTED_VALUES_KEY);
1313
1314                 // CREATE: Create the test interface
1315                 Assert.assertTrue(addBridge(connectionInfo, null,
1316                         testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
1317                         true, null, null, null));
1318                 testBridgeNodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier(
1319                         connectionInfo, new OvsdbBridgeName(testBridgeName)));
1320                 tpCreateAugmentationBuilder = createGenericOvsdbTerminationPointAugmentationBuilder();
1321                 tpCreateAugmentationBuilder.setName(testPortName);
1322                 tpCreateAugmentationBuilder.setInterfaceExternalIds(updateFromInputExternalIds);
1323                 Assert.assertTrue(addTerminationPoint(testBridgeNodeId, testPortName, tpCreateAugmentationBuilder));
1324
1325                 // READ: Read the test interface and ensure changes are propagated to the CONFIGURATION data store,
1326                 // then repeat for OPERATIONAL data store
1327                 updateFromConfigurationTerminationPointAugmentation =
1328                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1329                                 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1330                 updateFromConfigurationExternalIds = updateFromConfigurationTerminationPointAugmentation
1331                         .getInterfaceExternalIds();
1332                 assertExpectedInterfaceExternalIdsExist(updateFromExpectedExternalIds,
1333                         updateFromConfigurationExternalIds);
1334                 updateFromOperationalTerminationPointAugmenation =
1335                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1336                                 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1337                 updateFromOperationalExternalIds = updateFromOperationalTerminationPointAugmenation
1338                         .getInterfaceExternalIds();
1339                 assertExpectedInterfaceExternalIdsExist(updateFromExpectedExternalIds,
1340                         updateFromOperationalExternalIds);
1341
1342                 // UPDATE:  update the external_ids
1343                 testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeName).getNodeId();
1344                 tpUpdateAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
1345                 tpUpdateAugmentationBuilder.setInterfaceExternalIds(updateToInputExternalIds);
1346                 portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1347                 portUpdateNodeBuilder = new NodeBuilder();
1348                 portUpdateNodeId = SouthboundMapper.createManagedNodeId(portIid);
1349                 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1350                 tpUpdateBuilder = new TerminationPointBuilder();
1351                 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testPortName)));
1352                 tpUpdateBuilder.addAugmentation(
1353                         OvsdbTerminationPointAugmentation.class,
1354                         tpUpdateAugmentationBuilder.build());
1355                 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1356                 result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1357                         portIid, portUpdateNodeBuilder.build());
1358                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1359                 Assert.assertTrue(result);
1360
1361                 // READ: the test interface and ensure changes are propagated to the CONFIGURATION data store,
1362                 // then repeat for OPERATIONAL data store
1363                 updateToConfigurationTerminationPointAugmentation =
1364                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1365                                 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1366                 updateToConfigurationExternalIds = updateToConfigurationTerminationPointAugmentation
1367                         .getInterfaceExternalIds();
1368                 assertExpectedInterfaceExternalIdsExist(updateToExpectedExternalIds, updateToConfigurationExternalIds);
1369                 updateToOperationalTerminationPointAugmentation =
1370                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1371                                 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1372                 updateToOperationalExternalIds = updateToOperationalTerminationPointAugmentation
1373                         .getInterfaceExternalIds();
1374                 assertExpectedInterfaceExternalIdsExist(updateToExpectedExternalIds, updateToOperationalExternalIds);
1375
1376                 // Make sure the old interface external ids aren't present in the CONFIGURATION data store
1377                 assertInterfaceExternalIdsErased(updateFromInputExternalIds, updateToInputExternalIds,
1378                         updateFromExpectedExternalIds, updateToConfigurationExternalIds);
1379                 assertInterfaceExternalIdsErased(updateFromInputExternalIds, updateToInputExternalIds,
1380                         updateFromExpectedExternalIds, updateToConfigurationExternalIds);
1381
1382                 // DELETE
1383                 Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
1384             }
1385         }
1386         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1387     }
1388
1389     /*
1390      * Generates the test cases involved in testing TP Options.  See inline comments for descriptions of
1391      * the particular cases considered.
1392      *
1393      * The return value is a Map in the form (K,V)=(testCaseName,testCase).
1394      * - testCaseName is a String
1395      * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of
1396      *     either corresponding INPUT TP Options, or EXPECTED TP Options
1397      *     INPUT    is the List we use when calling
1398      *              <code>TerminationPointAugmentationBuilder.setOptions()</code>
1399      *     EXPECTED is the List we expect to receive after calling
1400      *              <code>TerminationPointAugmentationBuilder.getOptions()</code>
1401      */
1402     private Map<String, Map<String, List<Options>>> generateTerminationPointOptionsTestCases() {
1403         Map<String, Map<String, List<Options>>> testMap =
1404                 new HashMap<String, Map<String, List<Options>>>();
1405
1406         final String TP_OPTIONS_KEY = "TPOptionsKey";
1407         final String TP_OPTIONS_VALUE = "TPOptionsValue";
1408         final String FORMAT_STR = "%s_%s_%d";
1409         final String GOOD_KEY = "GoodKey";
1410         final String GOOD_VALUE = "GoodValue";
1411         final String NO_VALUE_FOR_KEY = "NoValueForKey";
1412         final String NO_KEY_FOR_VALUE = "NoKeyForValue";
1413
1414         // Test Case 1:  TestOneOptions
1415         // Test Type:    Positive
1416         // Description:  Create a termination point with one Options
1417         // Expected:     A termination point is created with the single Options specified below
1418         final String testOneOptionsName = "TestOneOptions";
1419         int optionsCounter = 0;
1420         List<Options> oneOptions = (List<Options>) Lists.newArrayList(
1421             (new OptionsBuilder()
1422                 .setOption(String.format(FORMAT_STR, testOneOptionsName,
1423                             TP_OPTIONS_KEY, ++optionsCounter))
1424                     .setValue(String.format(FORMAT_STR, testOneOptionsName,
1425                             TP_OPTIONS_VALUE, optionsCounter))
1426                     .build()));
1427         Map<String,List<Options>> testCase = Maps.newHashMap();
1428         testCase.put(EXPECTED_VALUES_KEY, oneOptions);
1429         testCase.put(INPUT_VALUES_KEY, oneOptions);
1430         testMap.put(testOneOptionsName, testCase);
1431
1432         // Test Case 2:  TestFiveOptions
1433         // Test Type:    Positive
1434         // Description:  Create a termination point with multiple (five) Options
1435         // Expected:     A termination point is created with the five options specified below
1436         final String testFiveOptions = "TestFiveOptions";
1437         optionsCounter = 0;
1438         List<Options> fiveOptions = (List<Options>) Lists.newArrayList(
1439             (new OptionsBuilder()
1440                 .setOption(String.format(FORMAT_STR, testFiveOptions,
1441                             TP_OPTIONS_KEY, ++optionsCounter))
1442                     .setValue(String.format(FORMAT_STR, testFiveOptions,
1443                             TP_OPTIONS_VALUE, optionsCounter))
1444                     .build()),
1445             (new OptionsBuilder()
1446                 .setOption(String.format(FORMAT_STR, testFiveOptions,
1447                             TP_OPTIONS_KEY, ++optionsCounter))
1448                     .setValue(String.format(FORMAT_STR, testFiveOptions,
1449                             TP_OPTIONS_VALUE, optionsCounter))
1450                     .build()),
1451             (new OptionsBuilder()
1452                 .setOption(String.format(FORMAT_STR, testFiveOptions,
1453                             TP_OPTIONS_KEY, ++optionsCounter))
1454                     .setValue(String.format(FORMAT_STR, testFiveOptions,
1455                             TP_OPTIONS_VALUE, optionsCounter))
1456                     .build()),
1457             (new OptionsBuilder()
1458                 .setOption(String.format(FORMAT_STR, testFiveOptions,
1459                             TP_OPTIONS_KEY, ++optionsCounter))
1460                     .setValue(String.format(FORMAT_STR, testFiveOptions,
1461                             TP_OPTIONS_VALUE, optionsCounter))
1462                     .build()),
1463             (new OptionsBuilder()
1464                 .setOption(String.format(FORMAT_STR, testFiveOptions,
1465                         TP_OPTIONS_KEY, ++optionsCounter))
1466                     .setValue(String.format(FORMAT_STR, testFiveOptions,
1467                             TP_OPTIONS_VALUE, optionsCounter))
1468                     .build()));
1469         testCase = Maps.newHashMap();
1470         testCase.put(EXPECTED_VALUES_KEY, fiveOptions);
1471         testCase.put(INPUT_VALUES_KEY, fiveOptions);
1472         testMap.put(testOneOptionsName, testCase);
1473
1474         // Test Case 3:  TestOneGoodOptionsOneMalformedOptionsValue
1475         // Test Type:    Negative
1476         // Description:
1477         //     One perfectly fine Options
1478         //        (TestOneGoodOptionsOneMalformedOptionsValue_OptionsKey_1,
1479         //        TestOneGoodOptionsOneMalformedOptions_OptionsValue_1)
1480         //     and one malformed Options which only has key specified
1481         //        (TestOneGoodOptionsOneMalformedOptionsValue_NoValueForKey_2,
1482         //        UNSPECIFIED)
1483         // Expected:     A termination point is created without any options
1484         final String testOneGoodOptionsOneMalformedOptionsValueName =
1485                 "TestOneGoodOptionsOneMalformedOptionsValue";
1486         optionsCounter = 0;
1487         Options oneGood = new OptionsBuilder()
1488             .setOption(String.format(FORMAT_STR, testOneGoodOptionsOneMalformedOptionsValueName,
1489                     GOOD_KEY, ++optionsCounter))
1490                 .setValue(String.format("FORMAT_STR",
1491                         testOneGoodOptionsOneMalformedOptionsValueName,
1492                             GOOD_VALUE, optionsCounter))
1493                 .build();
1494         Options oneBad = new OptionsBuilder()
1495             .setOption(String.format(FORMAT_STR,
1496                     testOneGoodOptionsOneMalformedOptionsValueName, NO_VALUE_FOR_KEY, ++optionsCounter))
1497                 .build();
1498         List<Options> oneGoodOneBadInput = (List<Options>) Lists.newArrayList(
1499                 oneGood, oneBad);
1500         List<Options> oneGoodOneBadExpected = null;
1501         testCase = Maps.newHashMap();
1502         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
1503         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
1504
1505         // Test Case 4:  TestOneGoodOptionsOneMalformedOptionsKey
1506         // Test Type:    Negative
1507         // Description:
1508         //     One perfectly fine Options
1509         //        (TestOneGoodOptionsOneMalformedOptionsValue_OptionsKey_1,
1510         //        TestOneGoodOptionsOneMalformedOptions_OptionsValue_1)
1511         //     and one malformed Options which only has key specified
1512         //        (UNSPECIFIED,
1513         //        TestOneGoodOptionsOneMalformedOptionsKey_NoKeyForValue_2)
1514         // Expected:     A termination point is created without any options
1515         final String testOneGoodOptionsOneMalformedOptionsKeyName =
1516                 "TestOneGoodOptionsOneMalformedOptionsKey";
1517         optionsCounter = 0;
1518         oneGood = new OptionsBuilder()
1519             .setOption(String.format(FORMAT_STR, testOneGoodOptionsOneMalformedOptionsKeyName,
1520                     GOOD_KEY, ++optionsCounter))
1521                 .setValue(String.format("FORMAT_STR",
1522                         testOneGoodOptionsOneMalformedOptionsKeyName,
1523                             GOOD_VALUE, optionsCounter))
1524                 .build();
1525         oneBad = new OptionsBuilder()
1526             .setOption(String.format(FORMAT_STR,
1527                     testOneGoodOptionsOneMalformedOptionsKeyName, NO_KEY_FOR_VALUE, ++optionsCounter))
1528                 .build();
1529         oneGoodOneBadInput = (List<Options>) Lists.newArrayList(
1530                 oneGood, oneBad);
1531         oneGoodOneBadExpected = null;
1532         testCase = Maps.newHashMap();
1533         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
1534         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
1535
1536         return testMap;
1537     }
1538
1539     /*
1540      * @see <code>SouthboundIT.testCRUDTerminationPointOptions()</code>
1541      * This is helper test method to compare a test "set" of Options against an expected "set"
1542      */
1543     private void assertExpectedOptionsExist( List<Options> expected,
1544             List<Options> test ) {
1545
1546         if (expected != null) {
1547             for (Options expectedOption : expected) {
1548                 Assert.assertTrue(test.contains(expectedOption));
1549             }
1550         } else {
1551             Assert.assertNull(test);
1552         }
1553     }
1554
1555     /*
1556      * @see <code>SouthboundIT.testCRUDTPOptions()</code>
1557      * This is a helper test method.  The method only checks if
1558      * <code>updateFromInputOptions != updateToInputOptions</code>,  (i.e., the updateTo "set" isn't the same
1559      * as the updateFrom "set".  Then, the method ensures each element of erase is not an element of test, as the input
1560      * test cases are divergent.
1561      */
1562     private void assertOptionsErased( List<Options> updateFromInputOptions,
1563             List<Options> updateToInputOptions,
1564             List<Options> updateFromExpectedOptions,
1565             List<Options> updateToTestOptions ) {
1566
1567         if (!updateFromInputOptions.containsAll(updateToInputOptions)) {
1568             for (Options erasedOption : updateFromExpectedOptions) {
1569                 Assert.assertTrue(!updateToTestOptions.contains(erasedOption));
1570             }
1571         }
1572     }
1573
1574     /*
1575      * Tests the CRUD operations for <code>TerminationPoint</code> <code>options</code>.
1576      *
1577      * @see <code>SouthboundIT.generateTerminationPointOptions()</code> for specific test case information
1578      */
1579     @Test
1580     public void testCRUDTerminationPointOptions() throws InterruptedException {
1581         final String TEST_PREFIX = "CRUDTPOptions";
1582         final int TERMINATION_POINT_TEST_INDEX = 0;
1583
1584         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
1585         connectOvsdbNode(connectionInfo);
1586
1587         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
1588         // the update has been performed.
1589         Map<String, Map<String, List<Options>>> updateFromTestCases =
1590                 generateTerminationPointOptionsTestCases();
1591         Map<String, Map<String, List<Options>>> updateToTestCases =
1592                 generateTerminationPointOptionsTestCases();
1593         Map<String, List<Options>> updateFromTestCase = null;
1594         List<Options> updateFromInputOptions = null;
1595         List<Options> updateFromExpectedOptions = null;
1596         List<Options> updateFromConfigurationOptions = null;
1597         List<Options> updateFromOperationalOptions = null;
1598         Map<String, List<Options>> updateToTestCase = null;
1599         List<Options> updateToInputOptions = null;
1600         List<Options> updateToExpectedOptions = null;
1601         List<Options> updateToConfigurationOptions = null;
1602         List<Options> updateToOperationalOptions = null;
1603         String testBridgeName = null;
1604         String testPortName = null;
1605         OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation = null;
1606         OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmenation = null;
1607         OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation = null;
1608         OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation = null;
1609         OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder = null;
1610         OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder = null;
1611         TerminationPointBuilder tpUpdateBuilder = null;
1612         NodeBuilder portUpdateNodeBuilder = null;
1613         NodeId testBridgeNodeId = null;
1614         NodeId portUpdateNodeId = null;
1615         InstanceIdentifier<Node> portIid = null;
1616         boolean result = false;
1617
1618         for (String updateFromTestCaseKey : updateFromTestCases.keySet()) {
1619             updateFromTestCase = updateFromTestCases.get(updateFromTestCaseKey);
1620             updateFromInputOptions = updateFromTestCase.get(INPUT_VALUES_KEY);
1621             updateFromExpectedOptions = updateFromTestCase.get(EXPECTED_VALUES_KEY);
1622             for (String testCaseKey : updateToTestCases.keySet()) {
1623                 testPortName = testBridgeName = String.format("%s_%s", TEST_PREFIX, testCaseKey);
1624                 updateToTestCase = updateToTestCases.get(testCaseKey);
1625                 updateToInputOptions = updateToTestCase.get(INPUT_VALUES_KEY);
1626                 updateToExpectedOptions = updateToTestCase.get(EXPECTED_VALUES_KEY);
1627
1628                 // CREATE: Create the test interface
1629                 Assert.assertTrue(addBridge(connectionInfo, null,
1630                         testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
1631                         true, null, null, null));
1632                 testBridgeNodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier(
1633                         connectionInfo, new OvsdbBridgeName(testBridgeName)));
1634                 tpCreateAugmentationBuilder = createGenericOvsdbTerminationPointAugmentationBuilder();
1635                 tpCreateAugmentationBuilder.setName(testPortName);
1636                 tpCreateAugmentationBuilder.setOptions(updateFromInputOptions);
1637                 Assert.assertTrue(addTerminationPoint(testBridgeNodeId, testPortName, tpCreateAugmentationBuilder));
1638
1639                 // READ: Read the test interface and ensure changes are propagated to the CONFIGURATION data store,
1640                 // then repeat for OPERATIONAL data store
1641                 updateFromConfigurationTerminationPointAugmentation =
1642                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1643                                 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1644                 updateFromConfigurationOptions = updateFromConfigurationTerminationPointAugmentation
1645                         .getOptions();
1646                 assertExpectedOptionsExist(updateFromExpectedOptions,
1647                         updateFromConfigurationOptions);
1648                 updateFromOperationalTerminationPointAugmenation =
1649                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1650                                 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1651                 updateFromOperationalOptions = updateFromOperationalTerminationPointAugmenation
1652                         .getOptions();
1653                 assertExpectedOptionsExist(updateFromExpectedOptions,
1654                         updateFromOperationalOptions);
1655
1656                 // UPDATE:  update the external_ids
1657                 testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeName).getNodeId();
1658                 tpUpdateAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
1659                 tpUpdateAugmentationBuilder.setOptions(updateToInputOptions);
1660                 portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1661                 portUpdateNodeBuilder = new NodeBuilder();
1662                 portUpdateNodeId = SouthboundMapper.createManagedNodeId(portIid);
1663                 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1664                 tpUpdateBuilder = new TerminationPointBuilder();
1665                 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testPortName)));
1666                 tpUpdateBuilder.addAugmentation(
1667                         OvsdbTerminationPointAugmentation.class,
1668                         tpUpdateAugmentationBuilder.build());
1669                 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1670                 result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1671                         portIid, portUpdateNodeBuilder.build());
1672                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1673                 Assert.assertTrue(result);
1674
1675                 // READ: the test interface and ensure changes are propagated to the CONFIGURATION data store,
1676                 // then repeat for OPERATIONAL data store
1677                 updateToConfigurationTerminationPointAugmentation =
1678                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1679                                 LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1680                 updateToConfigurationOptions = updateToConfigurationTerminationPointAugmentation
1681                         .getOptions();
1682                 assertExpectedOptionsExist(updateToExpectedOptions, updateToConfigurationOptions);
1683                 updateToOperationalTerminationPointAugmentation =
1684                         getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeName,
1685                                 LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1686                 updateToOperationalOptions = updateToOperationalTerminationPointAugmentation
1687                         .getOptions();
1688                 assertExpectedOptionsExist(updateToExpectedOptions, updateToOperationalOptions);
1689
1690                 // Make sure the old interface external ids aren't present in the CONFIGURATION data store
1691                 assertOptionsErased(updateFromInputOptions, updateToInputOptions,
1692                         updateFromExpectedOptions, updateToConfigurationOptions);
1693                 assertOptionsErased(updateFromInputOptions, updateToInputOptions,
1694                         updateFromExpectedOptions, updateToConfigurationOptions);
1695
1696                 // DELETE
1697                 Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
1698             }
1699         }
1700         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1701     }
1702
1703     @Test
1704     public void testTerminationPointInterfaceOtherConfigs() throws InterruptedException {
1705         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
1706         connectOvsdbNode(connectionInfo);
1707         Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
1708         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1709         Assert.assertNotNull(bridge);
1710         NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier(
1711                 connectionInfo, bridge.getBridgeName()));
1712         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1713                 createGenericOvsdbTerminationPointAugmentationBuilder();
1714         String portName = "testInterfaceOtherConfigs";
1715         ovsdbTerminationBuilder.setName(portName);
1716         //setup
1717         InterfaceOtherConfigsBuilder interfaceBuilder1 = new InterfaceOtherConfigsBuilder();
1718         interfaceBuilder1.setOtherConfigKey("interfaceOtherConfigsKey1");
1719         interfaceBuilder1.setOtherConfigValue("interfaceOtherConfigsValue1");
1720         InterfaceOtherConfigsBuilder interfaceBuilder2 = new InterfaceOtherConfigsBuilder();
1721         interfaceBuilder2.setOtherConfigKey("interfaceOtherConfigsKey2");
1722         interfaceBuilder2.setOtherConfigValue("interfaceOtherConfigsValue2");
1723         List<InterfaceOtherConfigs> interfaceOtherConfigs = Lists.newArrayList(interfaceBuilder1.build(),
1724                 interfaceBuilder2.build());
1725         ovsdbTerminationBuilder.setInterfaceOtherConfigs(interfaceOtherConfigs);
1726
1727         Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1728         Thread.sleep(1000);
1729         InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1730         Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1731         Assert.assertNotNull(terminationPointNode);
1732
1733         List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1734         for (TerminationPoint terminationPoint : terminationPoints) {
1735             OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1736                     terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1737             if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1738                 List<InterfaceOtherConfigs> actualInterfaceOtherConfigs = ovsdbTerminationPointAugmentation.
1739                         getInterfaceOtherConfigs();
1740                 Assert.assertNotNull(actualInterfaceOtherConfigs);
1741                 Assert.assertNotNull(interfaceOtherConfigs);
1742                 Assert.assertTrue(interfaceOtherConfigs.size() == actualInterfaceOtherConfigs.size());
1743                 for (InterfaceOtherConfigs interfaceOtherConfig : interfaceOtherConfigs) {
1744                     Assert.assertTrue(actualInterfaceOtherConfigs.contains(interfaceOtherConfig));
1745                 }
1746             }
1747         }
1748         Assert.assertTrue(deleteBridge(connectionInfo));
1749         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1750     }
1751
1752     @Test
1753     public void testTerminationPointPortOtherConfigs() throws InterruptedException {
1754         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
1755         connectOvsdbNode(connectionInfo);
1756         Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
1757         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1758         Assert.assertNotNull(bridge);
1759         NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier(
1760                 connectionInfo, bridge.getBridgeName()));
1761         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1762                 createGenericOvsdbTerminationPointAugmentationBuilder();
1763         String portName = "testPortOtherConfigs";
1764         ovsdbTerminationBuilder.setName(portName);
1765         //setup
1766         PortOtherConfigsBuilder portBuilder1 = new PortOtherConfigsBuilder();
1767         portBuilder1.setOtherConfigKey("portOtherConfigsKey1");
1768         portBuilder1.setOtherConfigValue("portOtherConfigsValue1");
1769         PortOtherConfigsBuilder portBuilder2 = new PortOtherConfigsBuilder();
1770         portBuilder2.setOtherConfigKey("portOtherConfigsKey2");
1771         portBuilder2.setOtherConfigValue("portOtherConfigsValue2");
1772         List<PortOtherConfigs> portOtherConfigs = Lists.newArrayList(portBuilder1.build(),
1773                 portBuilder2.build());
1774         ovsdbTerminationBuilder.setPortOtherConfigs(portOtherConfigs);
1775
1776         Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1777         InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1778         Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1779         Assert.assertNotNull(terminationPointNode);
1780
1781         List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1782         for (TerminationPoint terminationPoint : terminationPoints) {
1783             OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1784                     terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1785             if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1786                 List<PortOtherConfigs> actualPortOtherConfigs = ovsdbTerminationPointAugmentation.
1787                         getPortOtherConfigs();
1788                 Assert.assertTrue((portOtherConfigs.size() == actualPortOtherConfigs.size()));
1789                 for (PortOtherConfigs portOtherConfig : portOtherConfigs) {
1790                     Assert.assertTrue(actualPortOtherConfigs.contains(portOtherConfig));
1791                 }
1792             }
1793         }
1794         Assert.assertTrue(deleteBridge(connectionInfo));
1795         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1796     }
1797
1798     @Test
1799     public void testTerminationPointVlan() throws InterruptedException {
1800         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
1801         connectOvsdbNode(connectionInfo);
1802         Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
1803         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1804         Assert.assertNotNull(bridge);
1805         NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier(
1806                 connectionInfo, bridge.getBridgeName()));
1807         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1808                 createGenericOvsdbTerminationPointAugmentationBuilder();
1809         String portName = "testTerminationPointVlanId";
1810         ovsdbTerminationBuilder.setName(portName);
1811         //setup
1812         Integer vlanId = new Integer(4000);
1813         ovsdbTerminationBuilder.setVlanTag(new VlanId(vlanId));
1814
1815         Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1816         InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1817         Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1818         Assert.assertNotNull(terminationPointNode);
1819
1820         List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1821         for (TerminationPoint terminationPoint : terminationPoints) {
1822             OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1823                     terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1824             if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1825                 //test
1826                 VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
1827                 Assert.assertNotNull(actualVlanId);
1828                 Integer actualVlanIdInt = actualVlanId.getValue();
1829                 Assert.assertTrue(actualVlanIdInt.equals(vlanId));
1830             }
1831         }
1832         Assert.assertTrue(deleteBridge(connectionInfo));
1833         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1834     }
1835
1836     @Test
1837     public void testTerminationPointVlanModes() throws InterruptedException {
1838         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
1839         connectOvsdbNode(connectionInfo);
1840         VlanMode []vlanModes = VlanMode.values();
1841         for (VlanMode vlanMode : vlanModes) {
1842
1843             Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
1844             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1845             Assert.assertNotNull(bridge);
1846             NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier(
1847                     connectionInfo, bridge.getBridgeName()));
1848             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1849                     createGenericOvsdbTerminationPointAugmentationBuilder();
1850             String portName = "testTerminationPointVlanMode" + vlanMode.toString();
1851             ovsdbTerminationBuilder.setName(portName);
1852             //setup
1853             ovsdbTerminationBuilder.setVlanMode(vlanMode);
1854             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1855             InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1856             Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1857             Assert.assertNotNull(terminationPointNode);
1858
1859             List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1860             for (TerminationPoint terminationPoint : terminationPoints) {
1861                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1862                         terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1863                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1864                     //test
1865                     Assert.assertTrue(ovsdbTerminationPointAugmentation.getVlanMode().equals(vlanMode));
1866                 }
1867             }
1868             Assert.assertTrue(deleteBridge(connectionInfo));
1869         }
1870         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1871     }
1872
1873     private ArrayList<Set<Integer>> generateVlanSets() {
1874         ArrayList<Set<Integer>> vlanSets = new ArrayList<Set<Integer>>();
1875
1876         Set<Integer> emptySet = new HashSet<Integer>();
1877         vlanSets.add(emptySet);
1878
1879         Set<Integer> singleSet = new HashSet<Integer>();
1880         Integer single = new Integer(2222);
1881         singleSet.add(single);
1882         vlanSets.add(singleSet);
1883
1884         Set<Integer> minMaxMiddleSet = new HashSet<Integer>();
1885         Integer min = new Integer(0);
1886         minMaxMiddleSet.add(min);
1887         Integer max = new Integer(4095);
1888         minMaxMiddleSet.add(max);
1889         Integer minPlusOne = new Integer(min + 1);
1890         minMaxMiddleSet.add(minPlusOne);
1891         Integer maxMinusOne = new Integer(max - 1);
1892         minMaxMiddleSet.add(maxMinusOne);
1893         Integer middle = new Integer((max - min) / 2);
1894         minMaxMiddleSet.add(middle);
1895         vlanSets.add(minMaxMiddleSet);
1896
1897         return vlanSets;
1898     }
1899
1900     private List<Trunks> buildTrunkList(Set<Integer> trunkSet) {
1901         List<Trunks> trunkList = Lists.newArrayList();
1902         for (Integer trunk : trunkSet) {
1903             TrunksBuilder trunkBuilder = new TrunksBuilder();
1904             trunkBuilder.setTrunk(new VlanId(trunk));
1905             trunkList.add(trunkBuilder.build());
1906         }
1907         return trunkList;
1908     }
1909
1910     @Test
1911     public void testTerminationPointVlanTrunks() throws InterruptedException {
1912         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
1913         connectOvsdbNode(connectionInfo);
1914         ArrayList<Set<Integer>> vlanSets = generateVlanSets();
1915         int testCase = 0;
1916         for (Set<Integer> vlanSet : vlanSets) {
1917             ++testCase;
1918             Assert.assertTrue(addBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME));
1919             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1920             Assert.assertNotNull(bridge);
1921             NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier(
1922                     connectionInfo, bridge.getBridgeName()));
1923             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1924                     createGenericOvsdbTerminationPointAugmentationBuilder();
1925             String portName = "testTerminationPointVlanTrunks" + testCase;
1926             ovsdbTerminationBuilder.setName(portName);
1927             //setup
1928             List<Trunks> trunks = buildTrunkList(vlanSet);
1929             ovsdbTerminationBuilder.setTrunks(trunks);
1930             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1931             InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1932             Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1933             Assert.assertNotNull(terminationPointNode);
1934
1935             List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1936             for (TerminationPoint terminationPoint : terminationPoints) {
1937                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1938                         terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1939                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1940                     List<Trunks> actualTrunks = ovsdbTerminationPointAugmentation.getTrunks();
1941                     for (Trunks trunk : trunks) {
1942                         Assert.assertTrue(actualTrunks.contains(trunk));
1943                     }
1944                 }
1945             }
1946             Assert.assertTrue(deleteBridge(connectionInfo));
1947         }
1948         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1949     }
1950
1951     @Test
1952     public void testGetOvsdbNodes() throws InterruptedException {
1953         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
1954         connectOvsdbNode(connectionInfo);
1955         InstanceIdentifier<Topology> topologyPath = InstanceIdentifier
1956                 .create(NetworkTopology.class)
1957                 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
1958
1959         Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, topologyPath);
1960         Assert.assertEquals("There should only be one node in the topology", 1, topology.getNode().size());
1961         InstanceIdentifier<Node> expectedNodeIid = SouthboundMapper.createInstanceIdentifier(connectionInfo);
1962         Node node = topology.getNode().iterator().next();
1963         NodeId expectedNodeId = expectedNodeIid.firstKeyOf(Node.class, NodeKey.class).getNodeId();
1964         Assert.assertEquals(expectedNodeId, node.getNodeId());
1965         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
1966     }
1967
1968     /*
1969      * Generates the test cases involved in testing BridgeExternalIds.  See inline comments for descriptions of
1970      * the particular cases considered.
1971      *
1972      * The return value is a Map in the form (K,V)=(testCaseName,testCase).
1973      * - testCaseName is a String
1974      * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of
1975      *     either corresponding INPUT bridge external ids, or EXPECTED bridge external ids
1976      *     INPUT is the List we use when calling BridgeAugmentationBuilder.setBridgeExternalIds()
1977      *     EXPECTED is the List we expect to receive after calling BridgeAugmentationBuilder.getBridgeExternalIds()
1978      */
1979     private Map<String, Map<String, List<BridgeExternalIds>>> generateBridgeExternalIdsTestCases() {
1980         Map<String, Map<String, List<BridgeExternalIds>>> testMap =
1981                 new HashMap<String, Map<String, List<BridgeExternalIds>>>();
1982
1983         final String BRIDGE_EXTERNAL_ID_KEY = "BridgeExternalIdKey";
1984         final String BRIDGE_EXTERNAL_ID_VALUE = "BridgeExternalIdValue";
1985         final String FORMAT_STR = "%s_%s_%d";
1986         final String GOOD_KEY = "GoodKey";
1987         final String GOOD_VALUE = "GoodValue";
1988         final String NO_VALUE_FOR_KEY = "NoValueForKey";
1989         final String NO_KEY_FOR_VALUE = "NoKeyForValue";
1990
1991         // Test Case 1:  TestOneExternalId
1992         // Test Type:    Positive
1993         // Description:  Create a bridge with one BridgeExternalIds
1994         // Expected:     A bridge is created with the single external_ids specified below
1995         final String testOneExternalIdName = "TestOneExternalId";
1996         int externalIdCounter = 0;
1997         List<BridgeExternalIds> oneExternalId = (List<BridgeExternalIds>) Lists.newArrayList(
1998             (new BridgeExternalIdsBuilder()
1999                 .setBridgeExternalIdKey(String.format(FORMAT_STR, testOneExternalIdName,
2000                             BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter))
2001                     .setBridgeExternalIdValue(String.format(FORMAT_STR, testOneExternalIdName,
2002                             BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter))
2003                     .build()));
2004         Map<String,List<BridgeExternalIds>> testCase = Maps.newHashMap();
2005         testCase.put(EXPECTED_VALUES_KEY, oneExternalId);
2006         testCase.put(INPUT_VALUES_KEY, oneExternalId);
2007         testMap.put(testOneExternalIdName, testCase);
2008
2009         // Test Case 2:  TestFiveExternalId
2010         // Test Type:    Positive
2011         // Description:  Create a bridge with multiple (five) BridgeExternalIds
2012         // Expected:     A bridge is created with the five external_ids specified below
2013         final String testFiveExternalIdName = "TestFiveExternalId";
2014         externalIdCounter = 0;
2015         List<BridgeExternalIds> fiveExternalId = (List<BridgeExternalIds>) Lists.newArrayList(
2016             (new BridgeExternalIdsBuilder()
2017                 .setBridgeExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
2018                             BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter))
2019                     .setBridgeExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
2020                             BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter))
2021                     .build()),
2022             (new BridgeExternalIdsBuilder()
2023                 .setBridgeExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
2024                             BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter))
2025                     .setBridgeExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
2026                             BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter))
2027                     .build()),
2028             (new BridgeExternalIdsBuilder()
2029                 .setBridgeExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
2030                             BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter))
2031                     .setBridgeExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
2032                             BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter))
2033                     .build()),
2034             (new BridgeExternalIdsBuilder()
2035                 .setBridgeExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
2036                             BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter))
2037                     .setBridgeExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
2038                             BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter))
2039                     .build()),
2040             (new BridgeExternalIdsBuilder()
2041                 .setBridgeExternalIdKey(String.format(FORMAT_STR, testFiveExternalIdName,
2042                         BRIDGE_EXTERNAL_ID_KEY, ++externalIdCounter))
2043                     .setBridgeExternalIdValue(String.format(FORMAT_STR, testFiveExternalIdName,
2044                             BRIDGE_EXTERNAL_ID_VALUE, externalIdCounter))
2045                     .build()));
2046         testCase = Maps.newHashMap();
2047         testCase.put(EXPECTED_VALUES_KEY, fiveExternalId);
2048         testCase.put(INPUT_VALUES_KEY, fiveExternalId);
2049         testMap.put(testOneExternalIdName, testCase);
2050
2051         // Test Case 3:  TestOneGoodExternalIdOneMalformedExternalIdValue
2052         // Test Type:    Negative
2053         // Description:
2054         //     One perfectly fine BridgeExternalId
2055         //        (TestOneGoodExternalIdOneMalformedExternalIdValue_BridgeExternalIdKey_1,
2056         //        TestOneGoodExternalIdOneMalformedExternalId_BridgeExternalIdValue_1)
2057         //     and one malformed BridgeExternalId which only has key specified
2058         //        (TestOneGoodExternalIdOneMalformedExternalIdValue_NoValueForKey_2,
2059         //        UNSPECIFIED)
2060         // Expected:     A bridge is created without any external_ids
2061         final String testOneGoodExternalIdOneMalformedExternalIdValueName =
2062                 "TestOneGoodExternalIdOneMalformedExternalIdValue";
2063         externalIdCounter = 0;
2064         BridgeExternalIds oneGood = new BridgeExternalIdsBuilder()
2065             .setBridgeExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdValueName,
2066                     GOOD_KEY, ++externalIdCounter))
2067                 .setBridgeExternalIdValue(String.format("FORMAT_STR",
2068                         testOneGoodExternalIdOneMalformedExternalIdValueName,
2069                             GOOD_VALUE, externalIdCounter))
2070                 .build();
2071         BridgeExternalIds oneBad = new BridgeExternalIdsBuilder()
2072             .setBridgeExternalIdKey(String.format(FORMAT_STR,
2073                     testOneGoodExternalIdOneMalformedExternalIdValueName, NO_VALUE_FOR_KEY, ++externalIdCounter))
2074                 .build();
2075         List<BridgeExternalIds> oneGoodOneBadInput = (List<BridgeExternalIds>) Lists.newArrayList(
2076                 oneGood, oneBad);
2077         List<BridgeExternalIds> oneGoodOneBadExpected = null;
2078         testCase = Maps.newHashMap();
2079         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
2080         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
2081
2082         // Test Case 4:  TestOneGoodExternalIdOneMalformedExternalIdKey
2083         // Test Type:    Negative
2084         // Description:
2085         //     One perfectly fine BridgeExternalId
2086         //        (TestOneGoodExternalIdOneMalformedExternalIdValue_BridgeExternalIdKey_1,
2087         //        TestOneGoodExternalIdOneMalformedExternalId_BridgeExternalIdValue_1)
2088         //     and one malformed BridgeExternalId which only has key specified
2089         //        (UNSPECIFIED,
2090         //        TestOneGoodExternalIdOneMalformedExternalIdKey_NoKeyForValue_2)
2091         // Expected:     A bridge is created without any external_ids
2092         final String testOneGoodExternalIdOneMalformedExternalIdKeyName =
2093                 "TestOneGoodExternalIdOneMalformedExternalIdKey";
2094         externalIdCounter = 0;
2095         oneGood = new BridgeExternalIdsBuilder()
2096             .setBridgeExternalIdKey(String.format(FORMAT_STR, testOneGoodExternalIdOneMalformedExternalIdKeyName,
2097                     GOOD_KEY, ++externalIdCounter))
2098                 .setBridgeExternalIdValue(String.format("FORMAT_STR",
2099                         testOneGoodExternalIdOneMalformedExternalIdKeyName,
2100                             GOOD_VALUE, externalIdCounter))
2101                 .build();
2102         oneBad = new BridgeExternalIdsBuilder()
2103             .setBridgeExternalIdKey(String.format(FORMAT_STR,
2104                     testOneGoodExternalIdOneMalformedExternalIdKeyName, NO_KEY_FOR_VALUE, ++externalIdCounter))
2105                 .build();
2106         oneGoodOneBadInput = (List<BridgeExternalIds>) Lists.newArrayList(
2107                 oneGood, oneBad);
2108         oneGoodOneBadExpected = null;
2109         testCase = Maps.newHashMap();
2110         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
2111         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
2112
2113         return testMap;
2114     }
2115
2116     /*
2117      * Generates the test cases involved in testing BridgeOtherConfigs.  See inline comments for descriptions of
2118      * the particular cases considered.
2119      *
2120      * The return value is a Map in the form (K,V)=(testCaseName,testCase).
2121      * - testCaseName is a String
2122      * - testCase is a Map in the form (K,V) s.t. K=(EXPECTED_VALUES_KEY|INPUT_VALUES_KEY) and V is a List of
2123      *     either corresponding INPUT bridge other_configs, or EXPECTED bridge other_configs
2124      *     INPUT is the List we use when calling BridgeAugmentationBuilder.setBridgeOtherConfigs()
2125      *     EXPECTED is the List we expect to receive after calling BridgeAugmentationBuilder.getBridgeOtherConfigs()
2126      */
2127     private Map<String, Map<String, List<BridgeOtherConfigs>>> generateBridgeOtherConfigsTestCases() {
2128         Map<String, Map<String, List<BridgeOtherConfigs>>> testMap =
2129                 new HashMap<String, Map<String, List<BridgeOtherConfigs>>>();
2130
2131         final String BRIDGE_OTHER_CONFIGS_KEY = "BridgeOtherConfigKey";
2132         final String BRIDGE_OTHER_CONFIGS_VALUE = "BridgeOtherConfigValue";
2133         final String FORMAT_STR = "%s_%s_%d";
2134         final String GOOD_KEY = "GoodKey";
2135         final String GOOD_VALUE = "GoodValue";
2136         final String NO_VALUE_FOR_KEY = "NoValueForKey";
2137         final String NO_KEY_FOR_VALUE = "NoKeyForValue";
2138
2139         // Test Case 1:  TestOneOtherConfig
2140         // Test Type:    Positive
2141         // Description:  Create a bridge with one other_config
2142         // Expected:     A bridge is created with the single other_config specified below
2143         final String testOneOtherConfigName = "TestOneOtherConfig";
2144         int otherConfigCounter = 0;
2145         List<BridgeOtherConfigs> oneOtherConfig = (List<BridgeOtherConfigs>) Lists.newArrayList(
2146             (new BridgeOtherConfigsBuilder()
2147                 .setBridgeOtherConfigKey(String.format(FORMAT_STR, testOneOtherConfigName,
2148                             BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter))
2149                     .setBridgeOtherConfigValue(String.format(FORMAT_STR, testOneOtherConfigName,
2150                             BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter))
2151                     .build()));
2152         Map<String,List<BridgeOtherConfigs>> testCase = Maps.newHashMap();
2153         testCase.put(EXPECTED_VALUES_KEY, oneOtherConfig);
2154         testCase.put(INPUT_VALUES_KEY, oneOtherConfig);
2155         testMap.put(testOneOtherConfigName, testCase);
2156
2157         // Test Case 2:  TestFiveOtherConfig
2158         // Test Type:    Positive
2159         // Description:  Create a bridge with multiple (five) other_configs
2160         // Expected:     A bridge is created with the five other_configs specified below
2161         final String testFiveOtherConfigName = "TestFiveOtherConfig";
2162         otherConfigCounter = 0;
2163         List<BridgeOtherConfigs> fiveOtherConfig = (List<BridgeOtherConfigs>) Lists.newArrayList(
2164             (new BridgeOtherConfigsBuilder()
2165                 .setBridgeOtherConfigKey(String.format(FORMAT_STR, testFiveOtherConfigName,
2166                             BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter))
2167                     .setBridgeOtherConfigValue(String.format(FORMAT_STR, testFiveOtherConfigName,
2168                             BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter))
2169                     .build()),
2170             (new BridgeOtherConfigsBuilder()
2171                 .setBridgeOtherConfigKey(String.format(FORMAT_STR, testFiveOtherConfigName,
2172                             BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter))
2173                     .setBridgeOtherConfigValue(String.format(FORMAT_STR, testFiveOtherConfigName,
2174                             BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter))
2175                     .build()),
2176             (new BridgeOtherConfigsBuilder()
2177                 .setBridgeOtherConfigKey(String.format(FORMAT_STR, testFiveOtherConfigName,
2178                             BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter))
2179                     .setBridgeOtherConfigValue(String.format(FORMAT_STR, testFiveOtherConfigName,
2180                             BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter))
2181                     .build()),
2182             (new BridgeOtherConfigsBuilder()
2183                 .setBridgeOtherConfigKey(String.format(FORMAT_STR, testFiveOtherConfigName,
2184                             BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter))
2185                     .setBridgeOtherConfigValue(String.format(FORMAT_STR, testFiveOtherConfigName,
2186                             BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter))
2187                     .build()),
2188             (new BridgeOtherConfigsBuilder()
2189                 .setBridgeOtherConfigKey(String.format(FORMAT_STR, testFiveOtherConfigName,
2190                         BRIDGE_OTHER_CONFIGS_KEY, ++otherConfigCounter))
2191                     .setBridgeOtherConfigValue(String.format(FORMAT_STR, testFiveOtherConfigName,
2192                             BRIDGE_OTHER_CONFIGS_VALUE, otherConfigCounter))
2193                     .build()));
2194         testCase = Maps.newHashMap();
2195         testCase.put(EXPECTED_VALUES_KEY, fiveOtherConfig);
2196         testCase.put(INPUT_VALUES_KEY, fiveOtherConfig);
2197         testMap.put(testOneOtherConfigName, testCase);
2198
2199         // Test Case 3:  TestOneGoodOtherConfigOneMalformedOtherConfigValue
2200         // Test Type:    Negative
2201         // Description:
2202         //     One perfectly fine BridgeOtherConfig
2203         //        (TestOneGoodOtherConfigOneMalformedOtherConfigValue_BridgeOtherConfigKey_1,
2204         //        TestOneGoodOtherConfigOneMalformedOtherConfig_BridgeOtherConfigValue_1)
2205         //     and one malformed BridgeOtherConfig which only has key specified
2206         //        (TestOneGoodOtherConfigOneMalformedOtherConfigValue_NoValueForKey_2,
2207         //        UNSPECIFIED)
2208         // Expected:     A bridge is created without any other_config
2209         final String testOneGoodOtherConfigOneMalformedOtherConfigValueName =
2210                 "TestOneGoodOtherConfigOneMalformedOtherConfigValue";
2211         otherConfigCounter = 0;
2212         BridgeOtherConfigs oneGood = new BridgeOtherConfigsBuilder()
2213             .setBridgeOtherConfigKey(String.format(FORMAT_STR, testOneGoodOtherConfigOneMalformedOtherConfigValueName,
2214                     GOOD_KEY, ++otherConfigCounter))
2215                 .setBridgeOtherConfigValue(String.format("FORMAT_STR",
2216                         testOneGoodOtherConfigOneMalformedOtherConfigValueName,
2217                             GOOD_VALUE, otherConfigCounter))
2218                 .build();
2219         BridgeOtherConfigs oneBad = new BridgeOtherConfigsBuilder()
2220             .setBridgeOtherConfigKey(String.format(FORMAT_STR,
2221                     testOneGoodOtherConfigOneMalformedOtherConfigValueName, NO_VALUE_FOR_KEY, ++otherConfigCounter))
2222                 .build();
2223         List<BridgeOtherConfigs> oneGoodOneBadInput = (List<BridgeOtherConfigs>) Lists.newArrayList(
2224                 oneGood, oneBad);
2225         List<BridgeOtherConfigs> oneGoodOneBadExpected = null;
2226         testCase = Maps.newHashMap();
2227         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
2228         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
2229
2230         // Test Case 4:  TestOneGoodOtherConfigOneMalformedOtherConfigKey
2231         // Test Type:    Negative
2232         // Description:
2233         //     One perfectly fine BridgeOtherConfig
2234         //        (TestOneGoodOtherConfigOneMalformedOtherConfigValue_BridgeOtherConfigKey_1,
2235         //        TestOneGoodOtherConfigOneMalformedOtherConfig_BridgeOtherConfigValue_1)
2236         //     and one malformed BridgeOtherConfig which only has key specified
2237         //        (UNSPECIFIED,
2238         //        TestOneGoodOtherConfigOneMalformedOtherConfigKey_NoKeyForValue_2)
2239         // Expected:     A bridge is created without any other_config
2240         final String testOneGoodOtherConfigOneMalformedOtherConfigKeyName =
2241                 "TestOneGoodOtherConfigOneMalformedOtherConfigIdKey";
2242         otherConfigCounter = 0;
2243         oneGood = new BridgeOtherConfigsBuilder()
2244             .setBridgeOtherConfigKey(String.format(FORMAT_STR, testOneGoodOtherConfigOneMalformedOtherConfigKeyName,
2245                     GOOD_KEY, ++otherConfigCounter))
2246                 .setBridgeOtherConfigValue(String.format("FORMAT_STR",
2247                         testOneGoodOtherConfigOneMalformedOtherConfigKeyName,
2248                             GOOD_VALUE, otherConfigCounter))
2249                 .build();
2250         oneBad = new BridgeOtherConfigsBuilder()
2251             .setBridgeOtherConfigKey(String.format(FORMAT_STR,
2252                     testOneGoodOtherConfigOneMalformedOtherConfigKeyName, NO_KEY_FOR_VALUE, ++otherConfigCounter))
2253                 .build();
2254         oneGoodOneBadInput = (List<BridgeOtherConfigs>) Lists.newArrayList(
2255                 oneGood, oneBad);
2256         oneGoodOneBadExpected = null;
2257         testCase = Maps.newHashMap();
2258         testCase.put(INPUT_VALUES_KEY, oneGoodOneBadInput);
2259         testCase.put(EXPECTED_VALUES_KEY, oneGoodOneBadExpected);
2260
2261         return testMap;
2262     }
2263
2264     /*
2265      * @see <code>SouthboundIT.generateBridgeOtherConfigsTestCases()</code> for specific test case information.
2266      */
2267     @Test
2268     public void testBridgeOtherConfigs() throws InterruptedException {
2269         final String TEST_BRIDGE_PREFIX = "BridgeOtherConfig";
2270         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
2271         connectOvsdbNode(connectionInfo);
2272
2273         Map<String,Map<String, List<BridgeOtherConfigs>>> testCases =
2274                 generateBridgeOtherConfigsTestCases();
2275         List<BridgeOtherConfigs> inputBridgeOtherConfigs = null;
2276         List<BridgeOtherConfigs> expectedBridgeOtherConfigs = null;
2277         List<BridgeOtherConfigs> actualBridgeOtherConfigs = null;
2278         String testBridgeName = null;
2279         boolean bridgeAdded = false;
2280         for (String testCaseKey : testCases.keySet()) {
2281             testBridgeName = String.format("%s_%s", TEST_BRIDGE_PREFIX, testCaseKey);
2282             inputBridgeOtherConfigs = testCases.get(testCaseKey).get(INPUT_VALUES_KEY);
2283             expectedBridgeOtherConfigs = testCases.get(testCaseKey).get(EXPECTED_VALUES_KEY);
2284             bridgeAdded = addBridge(connectionInfo, null, testBridgeName, null, true,
2285                     SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null,
2286                     null, inputBridgeOtherConfigs);
2287             Assert.assertTrue(bridgeAdded);
2288
2289             actualBridgeOtherConfigs = getBridge(connectionInfo, testBridgeName).getBridgeOtherConfigs();
2290
2291             // Verify the expected other_config are present, or no (null) other_config are present
2292             if (expectedBridgeOtherConfigs != null) {
2293                 for (BridgeOtherConfigs expectedOtherConfig : expectedBridgeOtherConfigs) {
2294                     Assert.assertTrue(actualBridgeOtherConfigs.contains(expectedOtherConfig));
2295                 }
2296             } else {
2297                 Assert.assertNull(actualBridgeOtherConfigs);
2298             }
2299             Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
2300         }
2301         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
2302     }
2303
2304     /*
2305      * @see <code>SouthboundIT.testCRUDBridgeExternalIds()</code>
2306      * This is helper test method to compare a test "set" of BridgeExternalIds against an expected "set"
2307      */
2308     private void assertExpectedBridgeExternalIdsExist( List<BridgeExternalIds> expected,
2309             List<BridgeExternalIds> test ) {
2310
2311         if (expected != null) {
2312             for (BridgeExternalIds expectedExternalId : expected) {
2313                 Assert.assertTrue(test.contains(expectedExternalId));
2314             }
2315         } else {
2316             Assert.assertNull(test);
2317         }
2318     }
2319
2320     /*
2321      * @see <code>SouthboundIT.testCRUDBridgeExternalIds()</code>
2322      * This is a helper test method.  The method only checks if
2323      * <code>updateFromInputExternalIds != updateToInputExternalIds</code>,  (i.e., the updateTo "set" isn't the same
2324      * as the updateFrom "set".  Then, the method ensures each element of erase is not an element of test, as the input
2325      * test cases are divergent.
2326      */
2327     private void assertBridgeExternalIdsErased( List<BridgeExternalIds> updateFromInputExternalIds,
2328             List<BridgeExternalIds> updateToInputExternalIds,
2329             List<BridgeExternalIds> updateFromExpectedExternalIds,
2330             List<BridgeExternalIds> updateToTestExternalIds ) {
2331
2332         if (!updateFromInputExternalIds.containsAll(updateToInputExternalIds)) {
2333             for (BridgeExternalIds erasedExternalId : updateFromExpectedExternalIds) {
2334                 Assert.assertTrue(!updateToTestExternalIds.contains(erasedExternalId));
2335             }
2336         }
2337     }
2338
2339     /*
2340      * @see <code>SouthboundIT.generateBridgeExternalIdsTestCases()</code> for specific test case information
2341      */
2342     @Test
2343     public void testCRUDBridgeExternalIds() throws InterruptedException {
2344         final String TEST_BRIDGE_PREFIX = "CRUDBridgeExternalIds";
2345         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
2346         connectOvsdbNode(connectionInfo);
2347         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
2348         // the update has been performed.
2349         Map<String, Map<String, List<BridgeExternalIds>>> updateFromTestCases = generateBridgeExternalIdsTestCases();
2350         Map<String, Map<String, List<BridgeExternalIds>>> updateToTestCases = generateBridgeExternalIdsTestCases();
2351         Map<String, List<BridgeExternalIds>> updateFromTestCase = null;
2352         List<BridgeExternalIds> updateFromInputExternalIds = null;
2353         List<BridgeExternalIds> updateFromExpectedExternalIds = null;
2354         List<BridgeExternalIds> updateFromConfigurationExternalIds = null;
2355         List<BridgeExternalIds> updateFromOperationalExternalIds = null;
2356         Map<String, List<BridgeExternalIds>> updateToTestCase = null;
2357         List<BridgeExternalIds> updateToInputExternalIds = null;
2358         List<BridgeExternalIds> updateToExpectedExternalIds = null;
2359         List<BridgeExternalIds> updateToConfigurationExternalIds = null;
2360         List<BridgeExternalIds> updateToOperationalExternalIds = null;
2361         String testBridgeName = null;
2362         for (String updateFromTestCaseKey : updateFromTestCases.keySet()) {
2363             updateFromTestCase = updateFromTestCases.get(updateFromTestCaseKey);
2364             updateFromInputExternalIds = updateFromTestCase.get(INPUT_VALUES_KEY);
2365             updateFromExpectedExternalIds = updateFromTestCase.get(EXPECTED_VALUES_KEY);
2366             for (String testCaseKey : updateToTestCases.keySet()) {
2367                 testBridgeName = String.format("%s_%s", TEST_BRIDGE_PREFIX, testCaseKey);
2368                 updateToTestCase = updateToTestCases.get(testCaseKey);
2369                 updateToInputExternalIds = updateToTestCase.get(INPUT_VALUES_KEY);
2370                 updateToExpectedExternalIds = updateToTestCase.get(EXPECTED_VALUES_KEY);
2371
2372                 // CREATE: Create the test bridge
2373                 boolean bridgeAdded = addBridge(connectionInfo, null,
2374                         testBridgeName, null, true, SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
2375                         true, null, updateFromInputExternalIds, null);
2376                 Assert.assertTrue(bridgeAdded);
2377
2378                 // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
2379                 // then repeat for OPERATIONAL data store
2380                 updateFromConfigurationExternalIds = getBridge(connectionInfo, testBridgeName,
2381                         LogicalDatastoreType.CONFIGURATION).getBridgeExternalIds();
2382                 assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateFromConfigurationExternalIds);
2383                 updateFromOperationalExternalIds = getBridge(connectionInfo, testBridgeName).getBridgeExternalIds();
2384                 assertExpectedBridgeExternalIdsExist(updateFromExpectedExternalIds, updateFromOperationalExternalIds);
2385
2386                 // UPDATE:  update the external_ids
2387                 OvsdbBridgeAugmentationBuilder bridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
2388                 bridgeAugmentationBuilder.setBridgeExternalIds(updateToInputExternalIds);
2389                 InstanceIdentifier<Node> bridgeIid =
2390                         SouthboundMapper.createInstanceIdentifier(connectionInfo,
2391                             new OvsdbBridgeName(testBridgeName));
2392                 NodeBuilder bridgeNodeBuilder = new NodeBuilder();
2393                 Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
2394                 bridgeNodeBuilder.setNodeId(bridgeNode.getNodeId());
2395                 bridgeNodeBuilder.setKey(bridgeNode.getKey());
2396                 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, bridgeAugmentationBuilder.build());
2397                 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, 
2398                         bridgeNodeBuilder.build());
2399                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2400                 Assert.assertTrue(result);
2401
2402                 // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
2403                 // then repeat for OPERATIONAL data store
2404                 updateToConfigurationExternalIds = getBridge(connectionInfo, testBridgeName,
2405                         LogicalDatastoreType.CONFIGURATION).getBridgeExternalIds();
2406                 assertExpectedBridgeExternalIdsExist(updateToExpectedExternalIds, updateToConfigurationExternalIds);
2407                 updateToOperationalExternalIds = getBridge(connectionInfo, testBridgeName)
2408                         .getBridgeExternalIds();
2409                 assertExpectedBridgeExternalIdsExist(updateToExpectedExternalIds, updateToOperationalExternalIds);
2410
2411                 // Make sure the old bridge external ids aren't present in the CONFIGURATION data store
2412                 assertBridgeExternalIdsErased(updateFromInputExternalIds, updateToInputExternalIds,
2413                         updateFromExpectedExternalIds, updateToConfigurationExternalIds);
2414                 assertBridgeExternalIdsErased(updateFromInputExternalIds, updateToInputExternalIds,
2415                         updateFromExpectedExternalIds, updateToConfigurationExternalIds);
2416
2417                 // DELETE
2418                 Assert.assertTrue(deleteBridge(connectionInfo, testBridgeName));
2419             }
2420         }
2421         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
2422     }
2423 }