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