Add netvirt integration tests
[ovsdb.git] / openstack / net-virt-it / src / test / java / org / opendaylight / ovsdb / openstack / netvirt / it / NetvirtIT.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.openstack.netvirt.it;
9
10 import static org.junit.Assert.fail;
11 import static org.ops4j.pax.exam.CoreOptions.maven;
12 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
13
14 import com.google.common.collect.ImmutableBiMap;
15 import com.google.common.collect.Lists;
16 import com.google.common.collect.ObjectArrays;
17 import java.net.InetAddress;
18 import java.net.UnknownHostException;
19 import java.util.ArrayList;
20 import java.util.List;
21 import java.util.Properties;
22 import javax.inject.Inject;
23 import org.junit.Assert;
24 import org.junit.Before;
25 import org.junit.Ignore;
26 import org.junit.Test;
27 import org.junit.runner.RunWith;
28 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
29 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.*;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntryBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
41 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
42 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
43 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
44 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
45 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
46 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
47 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
48 import org.ops4j.pax.exam.Configuration;
49 import org.ops4j.pax.exam.Option;
50 import org.ops4j.pax.exam.junit.PaxExam;
51 import org.ops4j.pax.exam.karaf.options.LogLevelOption;
52 import org.ops4j.pax.exam.options.MavenUrlReference;
53 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
54 import org.ops4j.pax.exam.spi.reactors.PerClass;
55 import org.osgi.framework.Bundle;
56 import org.osgi.framework.BundleContext;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59
60 /**
61  * Integration tests for netvirt
62  *
63  * @author Sam Hague (shague@redhat.com)
64  */
65 @RunWith(PaxExam.class)
66 @ExamReactorStrategy(PerClass.class)
67 public class NetvirtIT extends AbstractMdsalTestBase {
68     private static final Logger LOG = LoggerFactory.getLogger(NetvirtIT.class);
69     private static final int OVSDB_UPDATE_TIMEOUT = 1000;
70     private static DataBroker dataBroker = null;
71     private static String addressStr;
72     private static String portStr;
73     private static String connectionType;
74     private static Boolean setup = false;
75     private static MdsalUtils mdsalUtils = null;
76     private static final String NETVIRT = "org.opendaylight.ovsdb.openstack.net-virt";
77     private static final String NETVIRTPROVIDERS = "org.opendaylight.ovsdb.openstack.net-virt-providers";
78
79     @Inject
80     private BundleContext bundleContext;
81
82     @Configuration
83     public Option[] config() {
84         return super.config();
85     }
86
87     @Override
88     public String getModuleName() {
89         return "openstack.net-virt";
90     }
91
92     @Override
93     public String getInstanceName() {
94         return "net-virt-default";
95     }
96
97     @Override
98     public MavenUrlReference getFeatureRepo() {
99         return maven()
100                 .groupId("org.opendaylight.ovsdb")
101                 .artifactId("features-ovsdb")
102                 .classifier("features")
103                 .type("xml")
104                 .versionAsInProject();
105     }
106
107     @Override
108     public String getFeatureName() {
109         return "odl-ovsdb-openstack-sb";
110     }
111
112     protected String usage() {
113         return "Integration Test needs a valid connection configuration as follows :\n"
114                 + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
115                 + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
116     }
117
118     @Override
119     public Option[] getFeaturesOptions() {
120         return new Option[]{};
121     }
122
123     @Override
124     public Option[] getLoggingOptions() {
125         Option[] options;
126
127         options = new Option[] {
128             editConfigurationFilePut(NetvirtITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
129                     "log4j.logger.org.opendaylight.ovsdb",
130                     LogLevelOption.LogLevel.DEBUG.name()),
131             editConfigurationFilePut(NetvirtITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
132                     "log4j.logger.org.opendaylight.ovsdb.lib",
133                     LogLevelOption.LogLevel.TRACE.name()),
134             /*editConfigurationFilePut(NetvirtITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
135                     "log4j.logger.org.opendaylight.ovsdb.openstack.net-virt",
136                     LogLevelOption.LogLevel.DEBUG.name())*/
137         };
138
139         options = ObjectArrays.concat(options, super.getLoggingOptions(), Option.class);
140         return options;
141     }
142
143     @Override
144     public Option[] getPropertiesOptions() {
145         Properties props = new Properties(System.getProperties());
146         String addressStr = props.getProperty(NetvirtITConstants.SERVER_IPADDRESS,
147                 NetvirtITConstants.DEFAULT_SERVER_IPADDRESS);
148         String portStr = props.getProperty(NetvirtITConstants.SERVER_PORT,
149                 NetvirtITConstants.DEFAULT_SERVER_PORT);
150         String connectionType = props.getProperty(NetvirtITConstants.CONNECTION_TYPE,
151                 NetvirtITConstants.CONNECTION_TYPE_ACTIVE);
152
153         LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}",
154                 connectionType, addressStr, portStr);
155
156         Option[] options = new Option[] {
157                 editConfigurationFilePut(NetvirtITConstants.CUSTOM_PROPERTIES,
158                         NetvirtITConstants.SERVER_IPADDRESS, addressStr),
159                 editConfigurationFilePut(NetvirtITConstants.CUSTOM_PROPERTIES,
160                         NetvirtITConstants.SERVER_PORT, portStr),
161                 editConfigurationFilePut(NetvirtITConstants.CUSTOM_PROPERTIES,
162                         NetvirtITConstants.CONNECTION_TYPE, connectionType),
163         };
164         return options;
165     }
166
167     @Before
168     public void setUp() throws InterruptedException {
169         if (setup == true) {
170             LOG.info("Skipping setUp, already initialized");
171             return;
172         }
173
174         try {
175             super.setup();
176         } catch (Exception e) {
177             e.printStackTrace();
178         }
179
180         addressStr = bundleContext.getProperty(NetvirtITConstants.SERVER_IPADDRESS);
181         portStr = bundleContext.getProperty(NetvirtITConstants.SERVER_PORT);
182         connectionType = bundleContext.getProperty(NetvirtITConstants.CONNECTION_TYPE);
183
184         LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
185                 connectionType, addressStr, portStr);
186         if (connectionType.equalsIgnoreCase(NetvirtITConstants.CONNECTION_TYPE_ACTIVE)) {
187             if (addressStr == null) {
188                 fail(usage());
189             }
190         }
191
192         isBundleReady(bundleContext, NETVIRT);
193         isBundleReady(bundleContext, NETVIRTPROVIDERS);
194
195         //dataBroker = getSession().getSALService(DataBroker.class);
196         Thread.sleep(10000);
197         //dataBroker = OvsdbInventoryServiceImpl.getDataBroker();
198         dataBroker = org.opendaylight.ovsdb.openstack.netvirt.MdsalUtils.getDatabroker();
199         Assert.assertNotNull("db should not be null", dataBroker);
200
201         mdsalUtils = new MdsalUtils(dataBroker);
202         setup = true;
203     }
204
205     /**
206      * Test passive connection mode. The southbound starts in a listening mode waiting for connections on port
207      * 6640. This test will wait for incoming connections for {@link NetvirtITConstants.CONNECTION_INIT_TIMEOUT} ms.
208      *
209      * @throws InterruptedException
210      */
211     @Test
212     public void testPassiveNode() throws InterruptedException {
213         if (connectionType.equalsIgnoreCase(NetvirtITConstants.CONNECTION_TYPE_PASSIVE)) {
214             //Wait for CONNECTION_INIT_TIMEOUT for the Passive connection to be initiated by the ovsdb-server.
215             Thread.sleep(NetvirtITConstants.CONNECTION_INIT_TIMEOUT);
216         }
217     }
218
219     private ConnectionInfo getConnectionInfo(final String addressStr, final String portStr) {
220         InetAddress inetAddress = null;
221         try {
222             inetAddress = InetAddress.getByName(addressStr);
223         } catch (UnknownHostException e) {
224             fail("Could not allocate InetAddress: " + e);
225         }
226
227         IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
228         PortNumber port = new PortNumber(Integer.parseInt(portStr));
229
230         LOG.info("connectionInfo: {}", new ConnectionInfoBuilder()
231                 .setRemoteIp(address)
232                 .setRemotePort(port)
233                 .build());
234         return new ConnectionInfoBuilder()
235                        .setRemoteIp(address)
236                        .setRemotePort(port)
237                        .build();
238     }
239
240     private String connectionInfoToString(final ConnectionInfo connectionInfo) {
241         return new String(connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
242     }
243
244     private boolean addOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
245         boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
246                 SouthboundMapper.createInstanceIdentifier(connectionInfo),
247                 SouthboundMapper.createNode(connectionInfo));
248         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
249         return result;
250     }
251
252     private Node getOvsdbNode(final ConnectionInfo connectionInfo) {
253         Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
254                 SouthboundMapper.createInstanceIdentifier(connectionInfo));
255         return node;
256     }
257
258     private boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
259         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
260                 SouthboundMapper.createInstanceIdentifier(connectionInfo));
261         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
262         return result;
263     }
264
265     private Node connectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
266         Assert.assertTrue(addOvsdbNode(connectionInfo));
267         Node node = getOvsdbNode(connectionInfo);
268         Assert.assertNotNull("Should find OVSDB node after connect", node);
269         LOG.info("Connected to {}", connectionInfoToString(connectionInfo));
270         return node;
271     }
272
273     private boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
274         Assert.assertTrue(deleteOvsdbNode(connectionInfo));
275         Node node = getOvsdbNode(connectionInfo);
276         Assert.assertNull("Should not find OVSDB node after disconnect", node);
277         //Assume.assumeNotNull(node); // Using assumeNotNull because there is no assumeNull
278         LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
279         return true;
280     }
281
282     @Test
283     public void testAddDeleteOvsdbNode() throws InterruptedException {
284         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
285         connectOvsdbNode(connectionInfo);
286         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
287         //Assume.assumeTrue(disconnectOvsdbNode(connectionInfo));
288     }
289
290     @Ignore
291     @Test
292     public void testOpenVSwitchOtherConfig() throws InterruptedException {
293         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
294         Node ovsdbNode = connectOvsdbNode(connectionInfo);
295         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
296         Assert.assertNotNull(ovsdbNodeAugmentation);
297         List<OpenvswitchOtherConfigs> otherConfigsList = ovsdbNodeAugmentation.getOpenvswitchOtherConfigs();
298         if (otherConfigsList != null) {
299             for (OpenvswitchOtherConfigs otherConfig : otherConfigsList) {
300                 if (otherConfig.getOtherConfigKey().equals("local_ip")) {
301                     LOG.info("local_ip: {}", otherConfig.getOtherConfigValue());
302                     break;
303                 } else {
304                     LOG.info("other_config {}:{}", otherConfig.getOtherConfigKey(), otherConfig.getOtherConfigValue());
305                 }
306             }
307         } else {
308             LOG.info("other_config is not present");
309         }
310         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
311         //Assume.assumeTrue(disconnectOvsdbNode(connectionInfo));
312     }
313
314     private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
315                               final ConnectionInfo connectionInfo) {
316         InstanceIdentifier<Node> connectionNodePath = SouthboundMapper.createInstanceIdentifier(connectionInfo);
317         ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
318     }
319
320     private List<ProtocolEntry> createMdsalProtocols() {
321         List<ProtocolEntry> protocolList = new ArrayList<ProtocolEntry>();
322         ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
323                 SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
324         protocolList.add(new ProtocolEntryBuilder().
325                 setProtocol((Class<? extends OvsdbBridgeProtocolBase>) mapper.get("OpenFlow13")).build());
326         return protocolList;
327     }
328
329     private OvsdbTerminationPointAugmentationBuilder createGenericOvsdbTerminationPointAugmentationBuilder() {
330         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder =
331                 new OvsdbTerminationPointAugmentationBuilder();
332         ovsdbTerminationPointAugmentationBuilder.setInterfaceType(
333                 new InterfaceTypeEntryBuilder()
334                         .setInterfaceType(
335                                 SouthboundMapper.createInterfaceType("internal"))
336                         .build().getInterfaceType());
337         return ovsdbTerminationPointAugmentationBuilder;
338     }
339
340     private boolean addTerminationPoint(final NodeId bridgeNodeId, final String portName,
341             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder)
342         throws InterruptedException {
343
344         InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(bridgeNodeId);
345         NodeBuilder portNodeBuilder = new NodeBuilder();
346         NodeId portNodeId = SouthboundMapper.createManagedNodeId(portIid);
347         portNodeBuilder.setNodeId(portNodeId);
348         TerminationPointBuilder entry = new TerminationPointBuilder();
349         entry.setKey(new TerminationPointKey(new TpId(portName)));
350         entry.addAugmentation(
351                 OvsdbTerminationPointAugmentation.class,
352                 ovsdbTerminationPointAugmentationBuilder.build());
353         portNodeBuilder.setTerminationPoint(Lists.newArrayList(entry.build()));
354         boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
355                 portIid, portNodeBuilder.build());
356         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
357         return result;
358     }
359
360     /*
361      * base method for adding test bridges.  Other helper methods used to create bridges should utilize this method.
362      *
363      * @param connectionInfo
364      * @param bridgeIid if passed null, one is created
365      * @param bridgeName cannot be null
366      * @param bridgeNodeId if passed null, one is created based on <code>bridgeIid</code>
367      * @param setProtocolEntries toggles whether default protocol entries are set for the bridge
368      * @param failMode toggles whether default fail mode is set for the bridge
369      * @param setManagedBy toggles whether to setManagedBy for the bridge
370      * @param dpType if passed null, this parameter is ignored
371      * @param externalIds if passed null, this parameter is ignored
372      * @param otherConfig if passed null, this parameter is ignored
373      * @return success of bridge addition
374      * @throws InterruptedException
375      */
376     private boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
377             final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
378             final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
379             final Class<? extends DatapathTypeBase> dpType,
380             final List<BridgeExternalIds> externalIds,
381             final List<BridgeOtherConfigs> otherConfigs) throws InterruptedException {
382
383         NodeBuilder bridgeNodeBuilder = new NodeBuilder();
384         if (bridgeIid == null) {
385             bridgeIid = SouthboundMapper.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
386         }
387         if (bridgeNodeId == null) {
388             bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
389         }
390         bridgeNodeBuilder.setNodeId(bridgeNodeId);
391         OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
392         ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
393         if (setProtocolEntries) {
394             ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
395         }
396         if (failMode != null) {
397             ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
398         }
399         if (setManagedBy) {
400             setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
401         }
402         if (dpType != null) {
403             ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
404         }
405         if (externalIds != null) {
406             ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
407         }
408         if (otherConfigs != null) {
409             ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
410         }
411         bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
412         LOG.debug("Built with the intent to store bridge data {}",
413                 ovsdbBridgeAugmentationBuilder.toString());
414         boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
415                 bridgeIid, bridgeNodeBuilder.build());
416         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
417         return result;
418     }
419
420     private boolean addBridge(final ConnectionInfo connectionInfo, final String bridgeName)
421         throws InterruptedException {
422
423         return addBridge(connectionInfo, null, bridgeName, null, true,
424                 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null);
425     }
426
427     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo) {
428         return getBridge(connectionInfo, NetvirtITConstants.BRIDGE_NAME);
429     }
430
431     /**
432      * Extract the <code>store</code> type data store contents for the particular bridge identified by
433      * <code>bridgeName</code>.
434      *
435      * @param connectionInfo
436      * @param bridgeName
437      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
438      * @return <code>store</code> type data store contents
439      */
440     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
441             LogicalDatastoreType store) {
442         Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
443         Assert.assertNotNull(bridgeNode);
444         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
445         Assert.assertNotNull(ovsdbBridgeAugmentation);
446         return ovsdbBridgeAugmentation;
447     }
448
449     /**
450      * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
451      * identified by <code>bridgeName</code>
452      *
453      * @param connectionInfo
454      * @param bridgeName
455      * @see <code>NetvirtIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
456      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
457      */
458     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
459         return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
460     }
461
462     /**
463      * Extract the node contents from <code>store</code> type data store for the
464      * bridge identified by <code>bridgeName</code>
465      *
466      * @param connectionInfo
467      * @param bridgeName
468      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
469      * @return <code>store</code> type data store contents
470      */
471     private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
472         InstanceIdentifier<Node> bridgeIid =
473                 SouthboundMapper.createInstanceIdentifier(connectionInfo,
474                     new OvsdbBridgeName(bridgeName));
475         return mdsalUtils.read(store, bridgeIid);
476     }
477
478     /**
479      * Extract the node contents from <code>LogicalDataStoreType.OPERATIONAL</code> data store for the
480      * bridge identified by <code>bridgeName</code>
481      *
482      * @param connectionInfo
483      * @param bridgeName
484      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
485      */
486     private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName) {
487         return getBridgeNode(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
488     }
489
490     private boolean deleteBridge(ConnectionInfo connectionInfo) throws InterruptedException {
491         return deleteBridge(connectionInfo, NetvirtITConstants.BRIDGE_NAME);
492     }
493
494     private boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName)
495         throws InterruptedException {
496
497         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
498                 SouthboundMapper.createInstanceIdentifier(connectionInfo,
499                         new OvsdbBridgeName(bridgeName)));
500         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
501         return result;
502     }
503
504     private InstanceIdentifier<Node> getTpIid(ConnectionInfo connectionInfo, OvsdbBridgeAugmentation bridge) {
505         return SouthboundMapper.createInstanceIdentifier(connectionInfo,
506             bridge.getBridgeName());
507     }
508
509     /**
510      * isBundleReady is used to check if the requested bundle is Active
511      */
512     public void isBundleReady(BundleContext bundleContext, String bundleName) throws InterruptedException {
513         boolean ready = false;
514
515         while (!ready) {
516             int state = Bundle.UNINSTALLED;
517             Bundle[] bundles = bundleContext.getBundles();
518             for (Bundle element : bundles) {
519                 if (element.getSymbolicName().equals(bundleName)) {
520                     state = element.getState();
521                     LOG.info(">>>>> bundle is ready {}", bundleName);
522                     break;
523                 }
524             }
525             if (state != Bundle.ACTIVE) {
526                 LOG.info(">>>>> bundle not ready {}", bundleName);
527                 Thread.sleep(5000);
528             } else {
529                 ready = true;
530             }
531         }
532     }
533
534     private void netVirtAddPort(ConnectionInfo connectionInfo) throws InterruptedException {
535         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, NetvirtITConstants.INTEGRATION_BRIDGE_NAME);
536         Assert.assertNotNull(bridge);
537         NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier(
538                 connectionInfo, bridge.getBridgeName()));
539         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
540                 createGenericOvsdbTerminationPointAugmentationBuilder();
541         String portName = NetvirtITConstants.PORT_NAME;
542         ovsdbTerminationBuilder.setName(portName);
543         Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
544         InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
545         Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
546         Assert.assertNotNull(terminationPointNode);
547     }
548
549     /**
550      * Test for basic southbound events to netvirt.
551      * <pre>The test will:
552      * - connect to an OVSDB node and verify it is added to operational
553      * - then verify that br-int was created on the node and stored in operational
554      * - a port is then added to the bridge to verify that it is ignored by netvirt
555      * - remove the bridge
556      * - remove the node and verify it is not in operational
557      * </pre>
558      * @throws InterruptedException
559      */
560     // TODO add verification of flows
561     @Test
562     public void testNetVirt() throws InterruptedException {
563         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
564         connectOvsdbNode(connectionInfo);
565         Thread.sleep(10000);
566         netVirtAddPort(connectionInfo);
567         Thread.sleep(10000);
568         Assert.assertTrue(deleteBridge(connectionInfo, NetvirtITConstants.INTEGRATION_BRIDGE_NAME));
569         Thread.sleep(10000);
570         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
571     }
572 }