2 * Copyright (C) 2014 Red Hat, Inc.
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
8 * Authors : Dave Tucker
11 package org.opendaylight.ovsdb.integrationtest.neutron;
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;
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;
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.Ignore;
46 import org.junit.Test;
47 import org.junit.runner.RunWith;
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.spi.reactors.ExamReactorStrategy;
52 import org.ops4j.pax.exam.spi.reactors.PerClass;
53 import org.ops4j.pax.exam.util.PathUtils;
54 import org.osgi.framework.Bundle;
55 import org.osgi.framework.BundleContext;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
59 import java.io.IOException;
60 import java.net.InetAddress;
62 import java.util.Properties;
63 import java.util.concurrent.ExecutionException;
64 import java.util.concurrent.TimeoutException;
66 import javax.inject.Inject;
69 @RunWith(PaxExam.class)
70 @ExamReactorStrategy(PerClass.class)
71 public class NeutronIT extends OvsdbIntegrationTestBase {
72 private Logger log = LoggerFactory.getLogger(NeutronIT.class);
74 private BundleContext bc;
77 private OvsdbConfigurationService ovsdbConfigurationService;
78 private Node node = null;
80 Component of10Provider;
81 Component of13Provider;
84 BridgeConfigurationManager bridgeConfigurationManager;
86 ConfigurationService netVirtConfigurationService;
88 Boolean tearDownBridge = false;
89 ImmutablePair<UUID, Map<String, String>> tearDownOpenVSwitchOtherConfig = null;
91 // Configure the OSGi container
93 public Option[] config() {
96 systemProperty("logback.configurationFile").value(
97 "file:" + PathUtils.getBaseDir()
98 + "/src/test/resources/logback.xml"
100 // To start OSGi console for inspection remotely
101 systemProperty("osgi.console").value("2401"),
103 propagateSystemProperty("ovsdbserver.ipaddress"),
104 propagateSystemProperty("ovsdbserver.port"),
106 ConfigurationBundles.controllerBundles(),
107 ConfigurationBundles.ovsdbLibraryBundles(),
108 ConfigurationBundles.ovsdbDefaultSchemaBundles(),
109 ConfigurationBundles.ovsdbPluginBundles(),
110 ConfigurationBundles.ovsdbNeutronBundles(),
116 public void areWeReady() throws InterruptedException, ExecutionException, IOException, TimeoutException {
118 boolean debugit = false;
119 Bundle b[] = bc.getBundles();
120 for (Bundle element : b) {
121 int state = element.getState();
122 if (state != Bundle.ACTIVE && state != Bundle.RESOLVED) {
123 log.info("Bundle:" + element.getSymbolicName() + " state:"
124 + stateToString(state));
129 log.debug("Do some debugging because some bundle is unresolved");
132 assertFalse(debugit);
136 node = getPluginTestConnection();
137 } catch (Exception e) {
138 fail("Exception : " + e.getMessage());
142 //Register fake NetworkingProviders
143 Properties of10Properties = new Properties();
144 of10Properties.put(Constants.OPENFLOW_VERSION_PROPERTY, Constants.OPENFLOW10);
146 Properties of13Properties = new Properties();
147 of13Properties.put(Constants.OPENFLOW_VERSION_PROPERTY, Constants.OPENFLOW13);
149 DependencyManager dm = new DependencyManager(bc);
151 of10Provider = dm.createComponent();
152 of10Provider.setInterface(NetworkingProvider.class.getName(), of10Properties);
153 of10Provider.setImplementation(new FakeOF10Provider());
155 of13Provider = dm.createComponent();
156 of13Provider.setInterface(NetworkingProvider.class.getName(), of13Properties);
157 of13Provider.setImplementation(new FakeOF13Provider());
159 dm.add(of10Provider);
160 dm.add(of13Provider);
164 public void testPrepareNode() throws Exception {
167 // Create the integration bridge
168 bridgeConfigurationManager.prepareNode(node);
172 ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Bridge.class));
173 Assert.assertEquals(1, bridgeRows.size());
175 Bridge bridgeRow = ovsdbConfigurationService.getTypedRow(node, Bridge.class, bridgeRows.values().iterator().next());
176 Assert.assertEquals(netVirtConfigurationService.getIntegrationBridgeName(), bridgeRow.getName());
178 String uuid = bridgeConfigurationManager.getBridgeUuid(node, netVirtConfigurationService.getIntegrationBridgeName());
179 Assert.assertEquals(uuid, bridgeRow.getUuid().toString());
181 tearDownBridge = true;
185 public void testGetTunnelEndpoint() throws Exception {
188 final String endpointAddress = "10.10.10.10";
190 Map<String, Row> ovsRows = ovsdbConfigurationService.getRows(node,
191 ovsdbConfigurationService.getTableName(node, OpenVSwitch.class));
192 OpenVSwitch ovsRow = ovsdbConfigurationService.getTypedRow(node,
194 ovsRows.values().iterator().next());
196 Assert.assertEquals(null, netVirtConfigurationService.getTunnelEndPoint(node));
197 final UUID originalVersion = ovsRow.getVersion();
199 OpenVSwitch updateOvsRow = ovsdbConfigurationService.createTypedRow(node, OpenVSwitch.class);
201 updateOvsRow.setOtherConfig(
202 ImmutableMap.of(netVirtConfigurationService.getTunnelEndpointKey(), endpointAddress));
204 ovsdbConfigurationService.updateRow(node,
205 ovsdbConfigurationService.getTableName(node, OpenVSwitch.class),
207 ovsRow.getUuid().toString(),
208 updateOvsRow.getRow());
210 // Remember original value so it can be restored on tearDown
211 tearDownOpenVSwitchOtherConfig = ImmutablePair.of(ovsRow.getUuid(),
212 ovsRow.getOtherConfigColumn().getData());
214 // Make sure tunnel end point was set
215 Assert.assertEquals(InetAddress.getByName(endpointAddress), netVirtConfigurationService.getTunnelEndPoint(node));
217 // Fetch rows again, and compare tunnel end point values
218 ovsRows = ovsdbConfigurationService.getRows(node,
219 ovsdbConfigurationService.getTableName(node, OpenVSwitch.class));
220 ovsRow = ovsdbConfigurationService.getTypedRow(node,
222 ovsRows.values().iterator().next());
224 Assert.assertEquals(ovsRow.getOtherConfigColumn(), updateOvsRow.getOtherConfigColumn());
226 // expect version of row to be changed, due to the update
227 Assert.assertNotEquals(ovsRow.getVersion(), originalVersion);
230 // Note: The openFlow version is now determined by configuration's getProperty("ovsdb.of.version", "1.3").
231 // Thus, the ovs version attribute (returned by ovs' OpenVSwitch table) is not used to determine what is
232 // the openFlow version chosen by netVirtConfigurationService.
233 // See: https://git.opendaylight.org/gerrit/#/c/11084/
234 // https://github.com/opendaylight/ovsdb/commit/2bc58c9cca16dc3e389cdfc18593578748fd52d5
235 @Ignore("netVirtConfigurationService.getOpenflowVersion(node) is not dependent on Constants.OPENFLOW13_SUPPORTED")
237 public void testGetOpenflowVersion() throws Exception {
240 Version ovsVersion = this.getOvsVersion();
242 if (ovsVersion.compareTo(Constants.OPENFLOW13_SUPPORTED) < 0) {
243 Assert.assertEquals(Constants.OPENFLOW10, netVirtConfigurationService.getOpenflowVersion(node));
245 Assert.assertEquals(Constants.OPENFLOW13, netVirtConfigurationService.getOpenflowVersion(node));
250 public void testGetDefaultGatewayMacAddress() throws Exception {
251 // Thread.sleep(5000);
252 String defaultGatewayMacAddress = netVirtConfigurationService.getDefaultGatewayMacAddress(node);
254 if (defaultGatewayMacAddress != null) {
255 String[] splits = defaultGatewayMacAddress.split(":");
256 Assert.assertTrue("Unexpected mac format", splits.length == 6);
258 // log.info("testGetDefaultGatewayMacAddress got mac {}", defaultGatewayMacAddress);
262 public void tearDown() throws InterruptedException {
265 if (tearDownBridge) {
267 String uuid = bridgeConfigurationManager.getBridgeUuid(node,
268 netVirtConfigurationService.getIntegrationBridgeName());
269 ovsdbConfigurationService.deleteRow(node, ovsdbConfigurationService.getTableName(node, Bridge.class), uuid);
270 } catch (Exception e) {
271 log.error("tearDownBridge Exception : " + e.getMessage());
273 tearDownBridge = false;
276 if (tearDownOpenVSwitchOtherConfig != null) {
278 OpenVSwitch updateOvsRow = ovsdbConfigurationService.createTypedRow(node, OpenVSwitch.class);
279 updateOvsRow.setOtherConfig(tearDownOpenVSwitchOtherConfig.getRight());
280 ovsdbConfigurationService.updateRow(node,
281 ovsdbConfigurationService.getTableName(node, OpenVSwitch.class),
283 tearDownOpenVSwitchOtherConfig.getLeft().toString(),
284 updateOvsRow.getRow());
285 } catch (Exception e) {
286 log.error("tearDownOpenVSwitchOtherConfig Exception : " + e.getMessage());
288 tearDownOpenVSwitchOtherConfig = null;
291 DependencyManager dm = new DependencyManager(bc);
292 dm.remove(of10Provider);
293 dm.remove(of13Provider);
296 private Version getOvsVersion(){
297 Map<String, Row> ovsRows = ovsdbConfigurationService.getRows(node,
298 ovsdbConfigurationService.getTableName(node, OpenVSwitch.class));
299 OpenVSwitch ovsRow = ovsdbConfigurationService.getTypedRow(node,
301 ovsRows.values().iterator().next());
302 return Version.fromString(ovsRow.getOvsVersionColumn().getData().iterator().next());
305 private class FakeOF10Provider implements NetworkingProvider {
308 public String getName() {
313 public boolean supportsServices() {
318 public boolean hasPerTenantTunneling() {
323 public Status handleInterfaceUpdate(String tunnelType, String tunnelKey) {
328 public Status handleInterfaceUpdate(NeutronNetwork network, Node source, Interface intf) {
333 public Status handleInterfaceDelete(String tunnelType, NeutronNetwork network, Node source, Interface intf,
334 boolean isLastInstanceOnNode) {
339 public void initializeFlowRules(Node node) {
344 public void initializeOFFlowRules(Node openflowNode) {
349 private class FakeOF13Provider implements NetworkingProvider {
352 public String getName() {
357 public boolean supportsServices() {
362 public boolean hasPerTenantTunneling() {
367 public Status handleInterfaceUpdate(String tunnelType, String tunnelKey) {
372 public Status handleInterfaceUpdate(NeutronNetwork network, Node source, Interface intf) {
377 public Status handleInterfaceDelete(String tunnelType, NeutronNetwork network, Node source, Interface intf,
378 boolean isLastInstanceOnNode) {
383 public void initializeFlowRules(Node node) {
388 public void initializeOFFlowRules(Node openflowNode) {