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