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