Merge "Checkstyle fixes (to be enforced)"
[ovsdb.git] / hwvtepsouthbound / hwvtepsouthbound-it / src / test / java / org / opendaylight / ovsdb / hwvtepsouthbound / it / HwvtepSouthboundIT.java
1 /*
2  * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.hwvtepsouthbound.it;
9
10 import static org.junit.Assert.assertTrue;
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.karaf.options.KarafDistributionOption.editConfigurationFilePut;
16 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
17
18 import java.lang.annotation.Annotation;
19 import java.lang.reflect.Method;
20 import java.net.InetAddress;
21 import java.net.UnknownHostException;
22 import java.util.Collection;
23 import java.util.HashSet;
24 import java.util.List;
25 import java.util.Properties;
26 import java.util.Set;
27
28 import javax.annotation.Nullable;
29 import javax.inject.Inject;
30
31 import org.junit.After;
32 import org.junit.Assert;
33 import org.junit.Before;
34 import org.junit.Ignore;
35 import org.junit.Test;
36 import org.junit.runner.RunWith;
37 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
38 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
39 import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
40 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
41 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
42 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
43 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
44 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundConstants;
45 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
46 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundProvider;
47 import org.opendaylight.ovsdb.utils.hwvtepsouthbound.utils.HwvtepSouthboundUtils;
48 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalRef;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentationBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.ConnectionInfo;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.ConnectionInfoBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.ManagementIps;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelIps;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.Tunnels;
60 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
61 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
62 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
63 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
64 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
65 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
66 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
67 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
68 import org.ops4j.pax.exam.Configuration;
69 import org.ops4j.pax.exam.Option;
70 import org.ops4j.pax.exam.junit.PaxExam;
71 import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel;
72 import org.ops4j.pax.exam.options.MavenUrlReference;
73 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
74 import org.ops4j.pax.exam.spi.reactors.PerClass;
75 import org.ops4j.pax.exam.util.Filter;
76 import org.osgi.framework.BundleContext;
77 import org.slf4j.Logger;
78 import org.slf4j.LoggerFactory;
79
80 @RunWith(PaxExam.class)
81 @ExamReactorStrategy(PerClass.class)
82 public class HwvtepSouthboundIT extends AbstractMdsalTestBase {
83     private static final Logger LOG = LoggerFactory.getLogger(HwvtepSouthboundIT.class);
84
85     //Constants
86
87     public static final String ORG_OPS4J_PAX_LOGGING_CFG = "etc/org.ops4j.pax.logging.cfg";
88     public static final String CUSTOM_PROPERTIES = "etc/custom.properties";
89     public static final String SERVER_IPADDRESS = "ovsdbserver.ipaddress";
90     public static final String DEFAULT_SERVER_IPADDRESS = "127.0.0.1";
91     public static final String SERVER_PORT = "ovsdbserver.port";
92     public static final String DEFAULT_SERVER_PORT = "6640";
93     public static final String CONNECTION_TYPE = "ovsdbserver.connection";
94     public static final String CONNECTION_TYPE_ACTIVE = "active";
95     public static final String CONNECTION_TYPE_PASSIVE = "passive";
96     public static final int CONNECTION_INIT_TIMEOUT = 10000;
97     public static final String OPENFLOW_CONNECTION_PROTOCOL = "tcp";
98     private static final String PS_NAME = "ps0";
99
100     private static final int OVSDB_UPDATE_TIMEOUT = 1000;
101     private static final int OVSDB_ROUNDTRIP_TIMEOUT = 10000;
102
103     private static MdsalUtils mdsalUtils = null;
104     private static boolean setup = false;
105     private static int testMethodsRemaining;
106     private static String addressStr;
107     private static int portNumber;
108     private static String connectionType;
109     private static Node hwvtepNode;
110     @Inject @Filter(timeout=60000)
111     private static DataBroker dataBroker = null;
112     @Inject
113     private BundleContext bundleContext;
114
115     private static final NotifyingDataChangeListener OPERATIONAL_LISTENER =
116             new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL);
117
118     private static class NotifyingDataChangeListener implements DataTreeChangeListener<Node> {
119         private final LogicalDatastoreType type;
120         private final Set<InstanceIdentifier<Node>> createdNodes = new HashSet<>();
121         private final Set<InstanceIdentifier<Node>> removedNodes = new HashSet<>();
122         private final Set<InstanceIdentifier<Node>> updatedNodes = new HashSet<>();
123
124         private NotifyingDataChangeListener(LogicalDatastoreType type) {
125             this.type = type;
126         }
127
128         @Override
129         public void onDataTreeChanged(Collection<DataTreeModification<Node>> changes) {
130             for (DataTreeModification<Node> change : changes) {
131                 final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
132                 final DataObjectModification<Node> mod = change.getRootNode();
133                     switch (mod.getModificationType()) {
134                     case DELETE:
135                         removedNodes.add(key);
136                         break;
137                     case SUBTREE_MODIFIED:
138                         updatedNodes.add(key);
139                         break;
140                     case WRITE:
141                         if (mod.getDataBefore() == null) {
142                             LOG.trace("Data added: {}", mod.getDataAfter());
143                             createdNodes.add(key);
144                         } else {
145                             updatedNodes.add(key);
146                         }
147                         break;
148                     default:
149                         throw new IllegalArgumentException("Unhandled modification type " + mod.getModificationType());
150                     }
151             }
152         }
153
154         public boolean isCreated(InstanceIdentifier<Node> iid) {
155             return createdNodes.remove(iid);
156         }
157
158         public boolean isRemoved(InstanceIdentifier<Node> iid) {
159             return removedNodes.remove(iid);
160         }
161
162         public boolean isUpdated(InstanceIdentifier<Node> iid) {
163             return updatedNodes.remove(iid);
164         }
165     }
166
167     @Configuration
168     public Option[] config() {
169         Option[] options = super.config();
170         Option[] propertyOptions = getPropertiesOptions();
171         Option[] otherOptions = getOtherOptions();
172         Option[] combinedOptions = new Option[options.length + propertyOptions.length + otherOptions.length];
173         System.arraycopy(options, 0, combinedOptions, 0, options.length);
174         System.arraycopy(propertyOptions, 0, combinedOptions, options.length, propertyOptions.length);
175         System.arraycopy(otherOptions, 0, combinedOptions, options.length + propertyOptions.length,
176                 otherOptions.length);
177         return combinedOptions;
178     }
179
180     private Option[] getOtherOptions() {
181         return new Option[] {
182                 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
183                 keepRuntimeFolder()
184         };
185     }
186
187     @Override
188     public String getKarafDistro() {
189         return maven()
190                 .groupId("org.opendaylight.ovsdb")
191                 .artifactId("hwvtepsouthbound-karaf")
192                 .versionAsInProject()
193                 .type("zip")
194                 .getURL();
195     }
196
197     @Override
198     public MavenUrlReference getFeatureRepo() {
199         return maven()
200                 .groupId("org.opendaylight.ovsdb")
201                 .artifactId("hwvtepsouthbound-features")
202                 .classifier("features")
203                 .type("xml")
204                 .versionAsInProject();
205     }
206
207     @Override
208     public String getFeatureName() {
209         return "odl-ovsdb-hwvtepsouthbound-test";
210     }
211
212     protected String usage() {
213         return "Integration Test needs a valid connection configuration as follows :\n"
214                 + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
215                 + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
216     }
217
218     @Override
219     public Option getLoggingOption() {
220         Option option = editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
221                 logConfiguration(HwvtepSouthboundIT.class),
222                 LogLevel.INFO.name());
223         option = composite(option, super.getLoggingOption());
224         return option;
225     }
226
227     private Option[] getPropertiesOptions() {
228         Properties props = new Properties(System.getProperties());
229         String addressStr = props.getProperty(SERVER_IPADDRESS, DEFAULT_SERVER_IPADDRESS);
230         String portStr = props.getProperty(SERVER_PORT, DEFAULT_SERVER_PORT);
231         String connectionType = props.getProperty(CONNECTION_TYPE, CONNECTION_TYPE_ACTIVE);
232
233         LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}",
234                 connectionType, addressStr, portStr);
235
236         return new Option[] {
237                 editConfigurationFilePut(CUSTOM_PROPERTIES, SERVER_IPADDRESS, addressStr),
238                 editConfigurationFilePut(CUSTOM_PROPERTIES, SERVER_PORT, portStr),
239                 editConfigurationFilePut(CUSTOM_PROPERTIES, CONNECTION_TYPE, connectionType),
240         };
241     }
242
243     @Before
244     @Override
245     public void setup() throws InterruptedException {
246         if (setup) {
247             LOG.info("Skipping setup, already initialized");
248             return;
249         }
250
251         try {
252             super.setup();
253         } catch (Exception e) {
254             LOG.warn("Failed to setup test", e);
255             fail("Failed to setup test: " + e);
256         }
257
258         addressStr = bundleContext.getProperty(SERVER_IPADDRESS);
259         String portStr = bundleContext.getProperty(SERVER_PORT);
260         try {
261             portNumber = Integer.parseInt(portStr);
262         } catch (NumberFormatException e) {
263             fail("Invalid port number " + portStr + System.lineSeparator() + usage() + e);
264         }
265
266         connectionType = bundleContext.getProperty(CONNECTION_TYPE);
267
268         LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
269                 connectionType, addressStr, portNumber);
270         if (connectionType.equalsIgnoreCase(CONNECTION_TYPE_ACTIVE)) {
271             if (addressStr == null) {
272                 fail(usage());
273             }
274         }
275
276         mdsalUtils = new MdsalUtils(dataBroker);
277         assertTrue("Did not find " + HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID.getValue(), getHwvtepTopology());
278         final ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
279         final InstanceIdentifier<Node> iid = HwvtepSouthboundUtils.createInstanceIdentifier(connectionInfo);
280         final DataTreeIdentifier<Node> treeId =
281                         new DataTreeIdentifier<Node>(LogicalDatastoreType.OPERATIONAL, iid);
282
283         dataBroker.registerDataTreeChangeListener(treeId, OPERATIONAL_LISTENER);
284
285         hwvtepNode = connectHwvtepNode(connectionInfo);
286         // Let's count the test methods (we need to use this instead of @AfterClass on teardown() since the latter is
287         // useless with pax-exam)
288         for (Method method : getClass().getMethods()) {
289             boolean testMethod = false;
290             boolean ignoreMethod = false;
291             for (Annotation annotation : method.getAnnotations()) {
292                 if (Test.class.equals(annotation.annotationType())) {
293                     testMethod = true;
294                 }
295                 if (Ignore.class.equals(annotation.annotationType())) {
296                     ignoreMethod = true;
297                 }
298             }
299             if (testMethod && !ignoreMethod) {
300                 testMethodsRemaining++;
301             }
302         }
303         LOG.info("{} test methods to run", testMethodsRemaining);
304
305         setup = true;
306     }
307
308     private Boolean getHwvtepTopology() {
309         LOG.info("getHwvtepTopology: looking for {}...", HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID.getValue());
310         Boolean found = false;
311         final TopologyId topologyId = HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID;
312         InstanceIdentifier<Topology> path =
313                 InstanceIdentifier.create(NetworkTopology.class).child(Topology.class, new TopologyKey(topologyId));
314         for (int i = 0; i < 60; i++) {
315             Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
316             if (topology != null) {
317                 LOG.info("getHwvtepTopology: found {}...", HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID.getValue());
318                 found = true;
319                 break;
320             } else {
321                 LOG.info("getHwvtepTopology: still looking ({})...", i);
322                 try {
323                     Thread.sleep(1000);
324                 } catch (InterruptedException e) {
325                     LOG.warn("Interrupted while waiting for {}",
326                             HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID.getValue(), e);
327                 }
328             }
329         }
330         return found;
331     }
332
333     private Node connectHwvtepNode(ConnectionInfo connectionInfo) throws InterruptedException {
334         final InstanceIdentifier<Node> iid = HwvtepSouthboundUtils.createInstanceIdentifier(connectionInfo);
335         Assert.assertTrue(mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
336                         iid, HwvtepSouthboundUtils.createNode(connectionInfo)));
337         waitForOperationalCreation(iid);
338         Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid);
339         Assert.assertNotNull(node);
340         LOG.info("Connected to {}", HwvtepSouthboundUtils.connectionInfoToString(connectionInfo));
341         return node;
342     }
343
344     private static void disconnectHwvtepNode(final ConnectionInfo connectionInfo) throws InterruptedException {
345         final InstanceIdentifier<Node> iid = HwvtepSouthboundUtils.createInstanceIdentifier(connectionInfo);
346         Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
347         waitForOperationalDeletion(iid);
348         Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid);
349         Assert.assertNull(node);
350         LOG.info("Disconnected from {}", HwvtepSouthboundUtils.connectionInfoToString(connectionInfo));
351     }
352
353     private void waitForOperationalCreation(InstanceIdentifier<Node> iid) throws InterruptedException {
354         synchronized (OPERATIONAL_LISTENER) {
355             long _start = System.currentTimeMillis();
356             LOG.info("Waiting for OPERATIONAL DataChanged creation on {}", iid);
357             while (!OPERATIONAL_LISTENER.isCreated(
358                     iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) {
359                 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
360             }
361             LOG.info("Woke up, waited {} for creation of {}", (System.currentTimeMillis() - _start), iid);
362         }
363     }
364
365     private static void waitForOperationalDeletion(InstanceIdentifier<Node> iid) throws InterruptedException {
366         synchronized (OPERATIONAL_LISTENER) {
367             long _start = System.currentTimeMillis();
368             LOG.info("Waiting for OPERATIONAL DataChanged deletion on {}", iid);
369             while (!OPERATIONAL_LISTENER.isRemoved(
370                     iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) {
371                 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
372             }
373             LOG.info("Woke up, waited {} for deletion of {}", (System.currentTimeMillis() - _start), iid);
374         }
375     }
376
377     private ConnectionInfo getConnectionInfo(String addressStr, int portNumber) {
378         InetAddress inetAddress = null;
379         try {
380             inetAddress = InetAddress.getByName(addressStr);
381         } catch (UnknownHostException e) {
382             fail("Could not resolve " + addressStr + ": " + e);
383         }
384
385         IpAddress address = HwvtepSouthboundMapper.createIpAddress(inetAddress);
386         PortNumber port = new PortNumber(portNumber);
387
388         final ConnectionInfo connectionInfo = new ConnectionInfoBuilder()
389                 .setRemoteIp(address)
390                 .setRemotePort(port)
391                 .build();
392         LOG.info("connectionInfo: {}", connectionInfo);
393         return connectionInfo;
394     }
395
396     private static class TestPhysicalSwitch implements AutoCloseable {
397         private final ConnectionInfo connectionInfo;
398         private final String psName;
399
400
401         public TestPhysicalSwitch(final ConnectionInfo connectionInfo, String psName) {
402             this(connectionInfo, psName, null, null, null, true, null, null, null);
403         }
404
405         public TestPhysicalSwitch (final ConnectionInfo connectionInfo, final String name,
406                         @Nullable InstanceIdentifier<Node> psIid, @Nullable NodeId psNodeId,
407                         @Nullable final String description, final boolean setManagedBy,
408                         @Nullable final List<ManagementIps> managementIps,
409                         @Nullable final List<TunnelIps> tunnelIps,
410                         @Nullable final List<Tunnels> tunnels) {
411             this.connectionInfo = connectionInfo;
412             this.psName = name;
413             NodeBuilder psNodeBuilder = new NodeBuilder();
414             if(psIid == null) {
415                 psIid = HwvtepSouthboundUtils.createInstanceIdentifier(connectionInfo, new HwvtepNodeName(psName));
416             }
417             if(psNodeId == null) {
418                 psNodeId = HwvtepSouthboundMapper.createManagedNodeId(psIid);
419             }
420             psNodeBuilder.setNodeId(psNodeId);
421             PhysicalSwitchAugmentationBuilder psAugBuilder = new PhysicalSwitchAugmentationBuilder();
422             psAugBuilder.setHwvtepNodeName(new HwvtepNodeName(psName));
423             if(description != null) {
424                 psAugBuilder.setHwvtepNodeDescription(description);
425             }
426             if(setManagedBy) {
427                 InstanceIdentifier<Node> nodePath = HwvtepSouthboundUtils.createInstanceIdentifier(connectionInfo);
428                 psAugBuilder.setManagedBy(new HwvtepGlobalRef(nodePath));
429             }
430             psAugBuilder.setManagementIps(managementIps);
431             psAugBuilder.setTunnelIps(tunnelIps);
432             psAugBuilder.setTunnels(tunnels);
433             psNodeBuilder.addAugmentation(PhysicalSwitchAugmentation.class, psAugBuilder.build());
434             LOG.debug("Built with intent to store PhysicalSwitch data {}", psAugBuilder.toString());
435             Assert.assertTrue(
436                             mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, psIid, psNodeBuilder.build()));
437                     try {
438                         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
439                     } catch (InterruptedException e) {
440                         LOG.warn("Sleep interrupted while waiting for bridge creation (bridge {})", psName, e);
441                     }
442         }
443
444         @Override
445         public void close() {
446             final InstanceIdentifier<Node> iid =
447                             HwvtepSouthboundUtils.createInstanceIdentifier(connectionInfo, new HwvtepNodeName(psName));
448             Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
449             try {
450                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
451             } catch (InterruptedException e) {
452                 LOG.warn("Sleep interrupted while waiting for bridge deletion (bridge {})", psName, e);
453             }
454         }
455     }
456
457     @After
458     public void teardown() {
459         testMethodsRemaining--;
460         LOG.info("{} test methods remaining", testMethodsRemaining);
461     }
462
463     @Test
464     public void testhwvtepsouthboundFeatureLoad() {
465         Assert.assertTrue(true);
466     }
467
468     @Test
469     public void testNetworkTopology() throws InterruptedException {
470         NetworkTopology networkTopology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION,
471                 InstanceIdentifier.create(NetworkTopology.class));
472         Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.CONFIGURATION,
473                 networkTopology);
474
475         networkTopology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
476                 InstanceIdentifier.create(NetworkTopology.class));
477         Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.OPERATIONAL,
478                 networkTopology);
479     }
480
481     @Test
482     public void testHwvtepTopology() throws InterruptedException {
483         InstanceIdentifier<Topology> path = InstanceIdentifier
484                 .create(NetworkTopology.class)
485                 .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID));
486
487         Topology topology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
488         Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.CONFIGURATION,
489                 topology);
490
491         topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
492
493         Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.OPERATIONAL,
494                 topology);
495     }
496
497     @Test
498     public void testAddDeleteHwvtepNode() throws InterruptedException {
499         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
500         // At this point we're connected, disconnect and reconnect (the connection will be removed at the very end)
501         disconnectHwvtepNode(connectionInfo);
502         connectHwvtepNode(connectionInfo);
503     }
504
505     @Test
506     public void testAddDeletePhysicalSwitch() throws InterruptedException {
507         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
508
509         try (TestPhysicalSwitch testPSwitch = new TestPhysicalSwitch(connectionInfo, PS_NAME)) {
510             PhysicalSwitchAugmentation pSwitch = getPhysicalSwitch(connectionInfo);
511             Assert.assertNotNull(pSwitch);
512             LOG.info("PhysicalSwitch: {}", pSwitch);
513         }
514     }
515
516     private PhysicalSwitchAugmentation getPhysicalSwitch(ConnectionInfo connectionInfo) {
517         return getPhysicalSwitch(connectionInfo, PS_NAME);
518     }
519
520     private PhysicalSwitchAugmentation getPhysicalSwitch(ConnectionInfo connectionInfo, String psName) {
521         return getPhysicalSwitch(connectionInfo, psName, LogicalDatastoreType.OPERATIONAL);
522     }
523
524     private PhysicalSwitchAugmentation getPhysicalSwitch(ConnectionInfo connectionInfo, String psName,
525                     LogicalDatastoreType dataStore) {
526         Node psNode = getPhysicalSwitchNode(connectionInfo, psName, dataStore);
527         Assert.assertNotNull(psNode);
528         PhysicalSwitchAugmentation psAugmentation = psNode.getAugmentation(PhysicalSwitchAugmentation.class);
529         Assert.assertNotNull(psAugmentation);
530         return psAugmentation;
531     }
532
533     private Node getPhysicalSwitchNode(ConnectionInfo connectionInfo, String psName, LogicalDatastoreType dataStore) {
534         InstanceIdentifier<Node> psIid =
535                         HwvtepSouthboundUtils.createInstanceIdentifier(connectionInfo, new HwvtepNodeName(psName));
536                 return mdsalUtils.read(dataStore, psIid);
537     }
538
539 }