Fix NeutronIT testGetTunnelEndpoint
[ovsdb.git] / integrationtest / src / test / java / org / opendaylight / ovsdb / integrationtest / neutron / NeutronIT.java
1 /*
2  * Copyright (C) 2014 Red Hat, Inc.
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  * Authors : Dave Tucker
9  */
10
11 package org.opendaylight.ovsdb.integrationtest.neutron;
12
13 import static org.junit.Assert.assertFalse;
14 import static org.junit.Assert.assertNotNull;
15 import static org.junit.Assert.fail;
16 import static org.ops4j.pax.exam.CoreOptions.junitBundles;
17 import static org.ops4j.pax.exam.CoreOptions.options;
18 import static org.ops4j.pax.exam.CoreOptions.propagateSystemProperty;
19 import static org.ops4j.pax.exam.CoreOptions.systemProperty;
20
21 import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
22 import org.opendaylight.controller.sal.core.Node;
23 import org.opendaylight.controller.sal.utils.Status;
24 import org.opendaylight.ovsdb.integrationtest.ConfigurationBundles;
25 import org.opendaylight.ovsdb.integrationtest.OvsdbIntegrationTestBase;
26 import org.opendaylight.ovsdb.lib.notation.Row;
27 import org.opendaylight.ovsdb.lib.notation.UUID;
28 import org.opendaylight.ovsdb.lib.notation.Version;
29 import org.opendaylight.ovsdb.openstack.netvirt.api.ConfigurationService;
30 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
31 import org.opendaylight.ovsdb.openstack.netvirt.api.BridgeConfigurationManager;
32 import org.opendaylight.ovsdb.openstack.netvirt.api.NetworkingProvider;
33 import org.opendaylight.ovsdb.plugin.api.OvsdbConfigurationService;
34 import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
35 import org.opendaylight.ovsdb.schema.openvswitch.Interface;
36 import org.opendaylight.ovsdb.schema.openvswitch.OpenVSwitch;
37
38 import com.google.common.collect.ImmutableMap;
39 import org.apache.commons.lang3.tuple.ImmutablePair;
40 import org.apache.felix.dm.Component;
41 import org.apache.felix.dm.DependencyManager;
42 import org.junit.After;
43 import org.junit.Assert;
44 import org.junit.Before;
45 import org.junit.Test;
46 import org.junit.runner.RunWith;
47 import org.ops4j.pax.exam.Configuration;
48 import org.ops4j.pax.exam.Option;
49 import org.ops4j.pax.exam.junit.PaxExam;
50 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
51 import org.ops4j.pax.exam.spi.reactors.PerClass;
52 import org.ops4j.pax.exam.util.PathUtils;
53 import org.osgi.framework.Bundle;
54 import org.osgi.framework.BundleContext;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57
58 import java.io.IOException;
59 import java.net.InetAddress;
60 import java.util.Map;
61 import java.util.Properties;
62 import java.util.concurrent.ExecutionException;
63 import java.util.concurrent.TimeoutException;
64
65 import javax.inject.Inject;
66
67
68 @RunWith(PaxExam.class)
69 @ExamReactorStrategy(PerClass.class)
70 public class NeutronIT extends OvsdbIntegrationTestBase {
71     private Logger log = LoggerFactory.getLogger(NeutronIT.class);
72     @Inject
73     private BundleContext bc;
74
75     @Inject
76     private OvsdbConfigurationService ovsdbConfigurationService;
77     private Node node = null;
78
79     Component of10Provider;
80     Component of13Provider;
81
82     @Inject
83     BridgeConfigurationManager bridgeConfigurationManager;
84     @Inject
85     ConfigurationService netVirtConfigurationService;
86
87     Boolean tearDownBridge = false;
88     ImmutablePair<UUID, Map<String, String>> tearDownOpenVSwitchOtherConfig = null;
89
90     // Configure the OSGi container
91     @Configuration
92     public Option[] config() {
93         return options(
94                 //
95                 systemProperty("logback.configurationFile").value(
96                         "file:" + PathUtils.getBaseDir()
97                         + "/src/test/resources/logback.xml"
98                 ),
99                 // To start OSGi console for inspection remotely
100                 systemProperty("osgi.console").value("2401"),
101
102                 propagateSystemProperty("ovsdbserver.ipaddress"),
103                 propagateSystemProperty("ovsdbserver.port"),
104
105                 ConfigurationBundles.controllerBundles(),
106                 ConfigurationBundles.ovsdbLibraryBundles(),
107                 ConfigurationBundles.ovsdbDefaultSchemaBundles(),
108                 ConfigurationBundles.ovsdbPluginBundles(),
109                 ConfigurationBundles.ovsdbNeutronBundles(),
110                 junitBundles()
111         );
112     }
113
114     private String stateToString(int state) {
115         switch (state) {
116             case Bundle.ACTIVE:
117                 return "ACTIVE";
118             case Bundle.INSTALLED:
119                 return "INSTALLED";
120             case Bundle.RESOLVED:
121                 return "RESOLVED";
122             case Bundle.UNINSTALLED:
123                 return "UNINSTALLED";
124             default:
125                 return "Not CONVERTED";
126         }
127     }
128
129     @Before
130     public void areWeReady() throws InterruptedException, ExecutionException, IOException, TimeoutException {
131         assertNotNull(bc);
132         boolean debugit = false;
133         Bundle b[] = bc.getBundles();
134         for (Bundle element : b) {
135             int state = element.getState();
136             if (state != Bundle.ACTIVE && state != Bundle.RESOLVED) {
137                 log.info("Bundle:" + element.getSymbolicName() + " state:"
138                          + stateToString(state));
139                 debugit = true;
140             }
141         }
142         if (debugit) {
143             log.debug("Do some debugging because some bundle is unresolved");
144         }
145
146         assertFalse(debugit);
147
148         if (node == null) {
149             try {
150                 node = getPluginTestConnection();
151             } catch (Exception e) {
152                 fail("Exception : " + e.getMessage());
153             }
154         }
155
156         //Register fake NetworkingProviders
157         Properties of10Properties = new Properties();
158         of10Properties.put(Constants.OPENFLOW_VERSION_PROPERTY, Constants.OPENFLOW10);
159
160         Properties of13Properties = new Properties();
161         of13Properties.put(Constants.OPENFLOW_VERSION_PROPERTY, Constants.OPENFLOW13);
162
163         DependencyManager dm = new DependencyManager(bc);
164
165         of10Provider = dm.createComponent();
166         of10Provider.setInterface(NetworkingProvider.class.getName(), of10Properties);
167         of10Provider.setImplementation(new FakeOF10Provider());
168
169         of13Provider = dm.createComponent();
170         of13Provider.setInterface(NetworkingProvider.class.getName(), of13Properties);
171         of13Provider.setImplementation(new FakeOF13Provider());
172
173         dm.add(of10Provider);
174         dm.add(of13Provider);
175     }
176
177     @Test
178     public void testPrepareNode() throws Exception {
179         Thread.sleep(5000);
180
181         // Create the integration bridge
182         bridgeConfigurationManager.prepareNode(node);
183
184         Map<String, Row>
185                 bridgeRows =
186                 ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Bridge.class));
187         Assert.assertEquals(1, bridgeRows.size());
188
189         Bridge bridgeRow = ovsdbConfigurationService.getTypedRow(node, Bridge.class, bridgeRows.values().iterator().next());
190         Assert.assertEquals(netVirtConfigurationService.getIntegrationBridgeName(), bridgeRow.getName());
191
192         String uuid = bridgeConfigurationManager.getBridgeUuid(node, netVirtConfigurationService.getIntegrationBridgeName());
193         Assert.assertEquals(uuid, bridgeRow.getUuid().toString());
194
195         tearDownBridge = true;
196     }
197
198     @Test
199     public void testGetTunnelEndpoint() throws Exception {
200         Thread.sleep(5000);
201
202         final String endpointAddress = "10.10.10.10";
203
204         Map<String, Row> ovsRows = ovsdbConfigurationService.getRows(node,
205                                                               ovsdbConfigurationService.getTableName(node, OpenVSwitch.class));
206         OpenVSwitch ovsRow = ovsdbConfigurationService.getTypedRow(node,
207                                                             OpenVSwitch.class,
208                                                             ovsRows.values().iterator().next());
209
210         Assert.assertEquals(null, netVirtConfigurationService.getTunnelEndPoint(node));
211         final UUID originalVersion = ovsRow.getVersion();
212
213         OpenVSwitch updateOvsRow = ovsdbConfigurationService.createTypedRow(node, OpenVSwitch.class);
214
215         updateOvsRow.setOtherConfig(
216                 ImmutableMap.of(netVirtConfigurationService.getTunnelEndpointKey(), endpointAddress));
217
218         ovsdbConfigurationService.updateRow(node,
219                                             ovsdbConfigurationService.getTableName(node, OpenVSwitch.class),
220                                             null,
221                                             ovsRow.getUuid().toString(),
222                                             updateOvsRow.getRow());
223
224         // Remember original value so it can be restored on tearDown
225         tearDownOpenVSwitchOtherConfig = ImmutablePair.of(ovsRow.getUuid(),
226                                                           ovsRow.getOtherConfigColumn().getData());
227
228         // Make sure tunnel end point was set
229         Assert.assertEquals(InetAddress.getByName(endpointAddress), netVirtConfigurationService.getTunnelEndPoint(node));
230
231         // Fetch rows again, and compare tunnel end point values
232         ovsRows = ovsdbConfigurationService.getRows(node,
233                                                     ovsdbConfigurationService.getTableName(node, OpenVSwitch.class));
234         ovsRow = ovsdbConfigurationService.getTypedRow(node,
235                                                        OpenVSwitch.class,
236                                                        ovsRows.values().iterator().next());
237
238         Assert.assertEquals(ovsRow.getOtherConfigColumn(), updateOvsRow.getOtherConfigColumn());
239
240         // expect version of row to be changed, due to the update
241         Assert.assertNotEquals(ovsRow.getVersion(), originalVersion);
242     }
243
244     @Test
245     public void testGetOpenflowVersion() throws Exception {
246         Thread.sleep(5000);
247
248         Version ovsVersion = this.getOvsVersion();
249
250         if (ovsVersion.compareTo(Constants.OPENFLOW13_SUPPORTED) < 0) {
251             Assert.assertEquals(Constants.OPENFLOW10, netVirtConfigurationService.getOpenflowVersion(node));
252         } else {
253             Assert.assertEquals(Constants.OPENFLOW13, netVirtConfigurationService.getOpenflowVersion(node));
254         }
255     }
256
257     @Test
258     public void testGetDefaultGatewayMacAddress() throws Exception {
259         // Thread.sleep(5000);
260         String defaultGatewayMacAddress = netVirtConfigurationService.getDefaultGatewayMacAddress(node);
261
262         if (defaultGatewayMacAddress != null) {
263             String[] splits = defaultGatewayMacAddress.split(":");
264             Assert.assertTrue("Unexpected mac format", splits.length == 6);
265         }
266         // log.info("testGetDefaultGatewayMacAddress got mac {}", defaultGatewayMacAddress);
267     }
268
269     @After
270     public void tearDown() throws InterruptedException {
271         Thread.sleep(5000);
272
273         if (tearDownBridge) {
274             try {
275                 String uuid = bridgeConfigurationManager.getBridgeUuid(node,
276                                                                        netVirtConfigurationService.getIntegrationBridgeName());
277                 ovsdbConfigurationService.deleteRow(node, ovsdbConfigurationService.getTableName(node, Bridge.class), uuid);
278             } catch (Exception e) {
279                 log.error("tearDownBridge Exception : " + e.getMessage());
280             }
281             tearDownBridge = false;
282         }
283
284         if (tearDownOpenVSwitchOtherConfig != null) {
285             try {
286                 OpenVSwitch updateOvsRow = ovsdbConfigurationService.createTypedRow(node, OpenVSwitch.class);
287                 updateOvsRow.setOtherConfig(tearDownOpenVSwitchOtherConfig.getRight());
288                 ovsdbConfigurationService.updateRow(node,
289                                                     ovsdbConfigurationService.getTableName(node, OpenVSwitch.class),
290                                                     null,
291                                                     tearDownOpenVSwitchOtherConfig.getLeft().toString(),
292                                                     updateOvsRow.getRow());
293             } catch (Exception e) {
294                 log.error("tearDownOpenVSwitchOtherConfig Exception : " + e.getMessage());
295             }
296             tearDownOpenVSwitchOtherConfig = null;
297         }
298
299         DependencyManager dm = new DependencyManager(bc);
300         dm.remove(of10Provider);
301         dm.remove(of13Provider);
302     }
303
304     private Version getOvsVersion(){
305         Map<String, Row> ovsRows = ovsdbConfigurationService.getRows(node,
306                                                               ovsdbConfigurationService.getTableName(node, OpenVSwitch.class));
307         OpenVSwitch ovsRow = ovsdbConfigurationService.getTypedRow(node,
308                                                             OpenVSwitch.class,
309                                                             ovsRows.values().iterator().next());
310         return Version.fromString(ovsRow.getOvsVersionColumn().getData().iterator().next());
311     }
312
313     private class FakeOF10Provider implements NetworkingProvider {
314
315         @Override
316         public String getName() {
317             return null;
318         }
319
320         @Override
321         public boolean supportsServices() {
322             return false;
323         }
324
325         @Override
326         public boolean hasPerTenantTunneling() {
327             return true;
328         }
329
330         @Override
331         public Status handleInterfaceUpdate(String tunnelType, String tunnelKey) {
332             return null;
333         }
334
335         @Override
336         public Status handleInterfaceUpdate(NeutronNetwork network, Node source, Interface intf) {
337             return null;
338         }
339
340         @Override
341         public Status handleInterfaceDelete(String tunnelType, NeutronNetwork network, Node source, Interface intf,
342                                             boolean isLastInstanceOnNode) {
343             return null;
344         }
345
346         @Override
347         public void initializeFlowRules(Node node) {
348
349         }
350
351         @Override
352         public void initializeOFFlowRules(Node openflowNode) {
353
354         }
355     }
356
357     private class FakeOF13Provider implements NetworkingProvider {
358
359         @Override
360         public String getName() {
361             return null;
362         }
363
364         @Override
365         public boolean supportsServices() {
366             return false;
367         }
368
369         @Override
370         public boolean hasPerTenantTunneling() {
371             return false;
372         }
373
374         @Override
375         public Status handleInterfaceUpdate(String tunnelType, String tunnelKey) {
376             return null;
377         }
378
379         @Override
380         public Status handleInterfaceUpdate(NeutronNetwork network, Node source, Interface intf) {
381             return null;
382         }
383
384         @Override
385         public Status handleInterfaceDelete(String tunnelType, NeutronNetwork network, Node source, Interface intf,
386                                             boolean isLastInstanceOnNode) {
387             return null;
388         }
389
390         @Override
391         public void initializeFlowRules(Node node) {
392
393         }
394
395         @Override
396         public void initializeOFFlowRules(Node openflowNode) {
397
398         }
399     }
400 }