Merge "ACL: Updated to cache interface/interface state details"
[netvirt.git] / vpnservice / it / src / test / java / org / opendaylight / netvirt / it / NetvirtIT.java
1 /*
2  * Copyright (c) 2016 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.netvirt.it;
9
10 import static org.junit.Assert.assertNotNull;
11 import static org.junit.Assert.assertTrue;
12 import static org.junit.Assert.fail;
13 import static org.ops4j.pax.exam.CoreOptions.composite;
14 import static org.ops4j.pax.exam.CoreOptions.maven;
15 import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
16 import static org.ops4j.pax.exam.CoreOptions.vmOption;
17 import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
18 import static org.ops4j.pax.exam.MavenUtils.asInProject;
19 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole;
20 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
21 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
22
23 import java.util.Properties;
24 import java.util.concurrent.atomic.AtomicBoolean;
25 import org.junit.Before;
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.controller.mdsal.it.base.AbstractMdsalTestBase;
31 import org.opendaylight.netvirt.utils.netvirt.it.utils.NetITUtil;
32 import org.opendaylight.netvirt.vpnmanager.VpnserviceProvider;
33 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
34 import org.opendaylight.ovsdb.utils.ovsdb.it.utils.DockerOvs;
35 import org.opendaylight.ovsdb.utils.ovsdb.it.utils.NodeInfo;
36 import org.opendaylight.ovsdb.utils.ovsdb.it.utils.OvsdbItUtils;
37 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
40 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
41 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
42 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
43 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
44 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
45 import org.ops4j.pax.exam.Configuration;
46 import org.ops4j.pax.exam.Option;
47 import org.ops4j.pax.exam.junit.PaxExam;
48 import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel;
49 import org.ops4j.pax.exam.options.MavenUrlReference;
50 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
51 import org.ops4j.pax.exam.spi.reactors.PerClass;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55 /**
56  *
57  * Integration tests for Netvirt
58  *
59  */
60
61 @RunWith(PaxExam.class)
62 @ExamReactorStrategy(PerClass.class)
63 public class NetvirtIT extends AbstractMdsalTestBase {
64
65     private static final Logger LOG = LoggerFactory.getLogger(NetvirtIT.class);
66     private static OvsdbItUtils itUtils;
67     private static MdsalUtils mdsalUtils = null;
68     private static SouthboundUtils southboundUtils;
69     private static String addressStr;
70     private static String portStr;
71     private static String connectionType;
72     private static String controllerStr;
73     private static AtomicBoolean setup = new AtomicBoolean(false);
74     private static DataBroker dataBroker = null;
75     private static final String NETVIRT_TOPOLOGY_ID = "netvirt:1";
76
77     @Override
78     public String getModuleName() {
79         return "vpnservice-impl";
80     }
81
82     @Override
83     public String getInstanceName() { return "vpnservice-default"; }
84
85
86     @Override
87     public MavenUrlReference getFeatureRepo() {
88         return maven()
89                 .groupId("org.opendaylight.netvirt")
90                 .artifactId("vpnservice-features")
91                 .classifier("features")
92                 .type("xml")
93                 .versionAsInProject();
94     }
95
96     @Override
97     public String getFeatureName() {
98         return "odl-netvirt-openstack-it";
99     }
100
101     @Configuration
102     @Override
103     public Option[] config() {
104         Option[] ovsProps = super.config();
105         Option[] propertiesOptions = DockerOvs.getSysPropOptions();
106         Option[] otherOptions = getOtherOptions();
107         Option[] options = new Option[ovsProps.length + propertiesOptions.length + otherOptions.length];
108         System.arraycopy(ovsProps, 0, options, 0, ovsProps.length);
109         System.arraycopy(propertiesOptions, 0, options, ovsProps.length, propertiesOptions.length);
110         System.arraycopy(otherOptions, 0, options, ovsProps.length + propertiesOptions.length,
111                 otherOptions.length);
112         return options;
113     }
114
115     private Option[] getOtherOptions() {
116         return new Option[] {
117                 wrappedBundle(
118                         mavenBundle("org.opendaylight.netvirt", "utils.mdsal-openflow")
119                                 .version(asInProject())
120                                 .type("jar")),
121 //                wrappedBundle(
122 //                        mavenBundle("org.opendaylight.netvirt", "utils.config")
123 //                                .version(asInProject())
124 //                                .type("jar")),
125                 configureConsole().startLocalConsole(),
126                 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
127                 keepRuntimeFolder()
128         };
129     }
130
131     @Override
132     public Option getLoggingOption() {
133         return composite(
134                 editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
135                         logConfiguration(NetvirtIT.class),
136                         LogLevel.INFO.name()),
137                 editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
138                         "log4j.logger.org.opendaylight.netvirt",
139                         LogLevel.DEBUG.name()),
140                 editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
141                         "log4j.logger.org.opendaylight.openflowjava.protocol.impl.util.ListDeserializer",
142                         LogLevel.ERROR.name()),
143                 editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
144                         "log4j.logger.org.opendaylight.controller.configpusherfeature.internal.FeatureConfigPusher",
145                         LogLevel.ERROR.name()),
146 //                editConfigurationFilePut(NetvirtITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
147 //                        "log4j.logger.org.opendaylight.ovsdb",
148 //                        LogLevel.TRACE.name()),
149                 super.getLoggingOption());
150     }
151
152     @Before
153     @Override
154     public void setup() throws InterruptedException {
155         if (setup.get()) {
156             LOG.info("Skipping setUp, already initialized");
157             return;
158         }
159
160         try {
161             super.setup();
162         } catch (Exception e) {
163             LOG.warn("Failed to setup test", e);
164             fail("Failed to setup test: " + e);
165         }
166
167         Thread.sleep(10*1000);
168         getProperties();
169
170         // get the dataBroker
171         dataBroker = VpnserviceProvider.getDataBroker();
172         assertNotNull("dataBroker should not be null", dataBroker);
173         itUtils = new OvsdbItUtils(dataBroker);
174         mdsalUtils = new MdsalUtils(dataBroker);
175         assertNotNull("mdsalUtils should not be null", mdsalUtils);
176         southboundUtils = new SouthboundUtils(mdsalUtils);
177         assertTrue("Did not find " + NETVIRT_TOPOLOGY_ID, this.getNetvirtTopology());
178
179 //      TODO: need to implement new pipelineOrchestrator for the vpnservice pipeline
180
181         setup.set(true);
182     }
183
184     private void getProperties() {
185         Properties props = System.getProperties();
186         addressStr = props.getProperty(NetvirtITConstants.SERVER_IPADDRESS);
187         portStr = props.getProperty(NetvirtITConstants.SERVER_PORT, NetvirtITConstants.DEFAULT_SERVER_PORT);
188         connectionType = props.getProperty(NetvirtITConstants.CONNECTION_TYPE, "active");
189         controllerStr = props.getProperty(NetvirtITConstants.CONTROLLER_IPADDRESS, "0.0.0.0");
190         String userSpaceEnabled = props.getProperty(NetvirtITConstants.USERSPACE_ENABLED, "no");
191         LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}, controller ip: {}, " +
192                         "userspace.enabled: {}",
193                 connectionType, addressStr, portStr, controllerStr, userSpaceEnabled);
194     }
195
196     private Boolean getNetvirtTopology() {
197         LOG.info("getNetvirtTopology: looking for {}...", NETVIRT_TOPOLOGY_ID);
198         Boolean found = false;
199         TopologyId topologyId = new TopologyId(NETVIRT_TOPOLOGY_ID);
200         InstanceIdentifier<Topology> path =
201                 InstanceIdentifier.create(NetworkTopology.class).child(Topology.class, new TopologyKey(topologyId));
202         for(int i = 0; i < 60; ++i) {
203             Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
204             if(topology != null) {
205                 LOG.info("getNetvirtTopology: found {}...", NETVIRT_TOPOLOGY_ID);
206                 found = Boolean.valueOf(true);
207                 break;
208             }
209
210             LOG.info("getNetvirtTopology: still looking ({})...", i);
211
212             try {
213                 Thread.sleep(1000);
214             } catch (InterruptedException var7) {
215                 LOG.warn("Interrupted while waiting for {}", "netvirt:1", var7);
216             }
217         }
218
219         return found;
220     }
221
222
223     /**
224      * Test for basic southbound events to netvirt.
225      * <pre>The test will:
226      * - connect to an OVSDB node and verify it is added to operational
227      * - then verify that br-int was created on the node and stored in operational
228      * - a port is then added to the bridge to verify that it is ignored by netvirt
229      * - remove the bridge
230      * - remove the node and verify it is not in operational
231      * </pre>
232      * @throws InterruptedException
233      */
234     @Test
235     public void testNetVirt() throws InterruptedException {
236         try(DockerOvs ovs = new DockerOvs()) {
237             ConnectionInfo connectionInfo = SouthboundUtils.
238                     getConnectionInfo(ovs.getOvsdbAddress(0), ovs.getOvsdbPort(0));
239             NodeInfo nodeInfo = itUtils.createNodeInfo(connectionInfo, null);
240             nodeInfo.connect();
241
242             LOG.info("testNetVirt: should be connected: {}", nodeInfo.ovsdbNode.getNodeId());
243
244             southboundUtils.addTerminationPoint(nodeInfo.bridgeNode, NetvirtITConstants.PORT_NAME,
245                     "internal", null, null, 0L);
246             Thread.sleep(1000);
247
248             OvsdbTerminationPointAugmentation terminationPointOfBridge = southboundUtils.
249                     getTerminationPointOfBridge(nodeInfo.bridgeNode, NetvirtITConstants.PORT_NAME);
250             assertNotNull("Did not find " + NetvirtITConstants.PORT_NAME, terminationPointOfBridge);
251
252             nodeInfo.disconnect();
253         } catch (Exception e) {
254             LOG.error("testNetVirt: Exception thrown by OvsDocker.OvsDocker()", e);
255             fail();
256         }
257     }
258
259
260     /**
261      * Test a basic neutron use case. This test constructs a Neutron network, subnet, and two "vm" ports
262      * and validates that the correct flows are installed on OVS. Then it pings from one VM port to the other.
263      * @throws InterruptedException if we're interrupted while waiting for some mdsal operation to complete
264      */
265     @Test
266     public void testNeutronNet() throws InterruptedException {
267         LOG.warn("testNeutronNet: starting test");
268         try(DockerOvs ovs = new DockerOvs()) {
269             ConnectionInfo connectionInfo = SouthboundUtils.
270                     getConnectionInfo(ovs.getOvsdbAddress(0), ovs.getOvsdbPort(0));
271             NodeInfo nodeInfo = itUtils.createNodeInfo(connectionInfo, null);
272             nodeInfo.connect();
273
274             // waiting for the default flows to be installed before adding the ports
275             Thread.sleep(20*100);
276
277             //create the neutron objects
278             NetITUtil net = new NetITUtil(ovs, southboundUtils, mdsalUtils);
279             net.createNetworkAndSubnet();
280             String port1 = net.createPort(nodeInfo.bridgeNode);
281             String port2 = net.createPort(nodeInfo.bridgeNode);
282
283 //          TODO - need to add pipeline validation
284
285             Thread.sleep(1000);
286
287             //ovs interface configuration for running the ping test
288             net.preparePortForPing(port1);
289             net.preparePortForPing(port2);
290
291             //run the ping test
292             net.ping(port1, port2);
293
294             //clean the neutron object and disconnect from odl
295             net.destroy();
296             nodeInfo.disconnect();
297         } catch (Exception e) {
298             LOG.error("testNeutronNet: Exception thrown by OvsDocker.OvsDocker()", e);
299             fail();
300         }
301     }
302 }