d3e23c7bee76ab4dcea65bfac0973899ae2a9639
[netvirt.git] / netvirt / it / src / test / java / org / opendaylight / netvirt / netvirt / it / NetvirtIT.java
1 /*
2  * Copyright © 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
9 package org.opendaylight.netvirt.netvirt.it;
10
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertTrue;
13 import static org.junit.Assert.fail;
14 import static org.ops4j.pax.exam.CoreOptions.composite;
15 import static org.ops4j.pax.exam.CoreOptions.maven;
16 import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
17 import static org.ops4j.pax.exam.CoreOptions.propagateSystemProperties;
18 import static org.ops4j.pax.exam.CoreOptions.vmOption;
19 import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
20 import static org.ops4j.pax.exam.MavenUtils.asInProject;
21 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole;
22 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
23 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
24
25 import java.util.ArrayList;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Properties;
29 import java.util.concurrent.atomic.AtomicBoolean;
30 import org.junit.After;
31 import org.junit.Before;
32 import org.junit.Test;
33 import org.junit.runner.RunWith;
34 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
35 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
36 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
37 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
38 import org.opendaylight.neutron.spi.NeutronNetwork;
39 import org.opendaylight.netvirt.utils.netvirt.it.utils.ItConstants;
40 import org.opendaylight.netvirt.utils.netvirt.it.utils.NetvirtItUtils;
41 import org.opendaylight.netvirt.utils.neutron.utils.NeutronModelsDataStoreHelper;
42 import org.opendaylight.netvirt.utils.neutron.utils.NeutronUtils;
43 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
44 import org.opendaylight.ovsdb.utils.mdsal.utils.NotifyingDataChangeListener;
45 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
48 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
49 import org.ops4j.pax.exam.Configuration;
50 import org.ops4j.pax.exam.Option;
51 import org.ops4j.pax.exam.junit.PaxExam;
52 import org.ops4j.pax.exam.karaf.options.LogLevelOption;
53 import org.ops4j.pax.exam.options.MavenUrlReference;
54 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
55 import org.ops4j.pax.exam.spi.reactors.PerClass;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58
59 @RunWith(PaxExam.class)
60 @ExamReactorStrategy(PerClass.class)
61 public class NetvirtIT extends AbstractMdsalTestBase {
62     private static final Logger LOG = LoggerFactory.getLogger(NetvirtIT.class);
63     private static final String FEATURE = "odl-netvirt-it";
64     private static DataBroker dataBroker = null;
65     private static NetvirtItUtils itUtils;
66     private static String addressStr;
67     private static String portStr;
68     private static String connectionType;
69     private static String controllerStr;
70     private static AtomicBoolean setup = new AtomicBoolean(false);
71     private static MdsalUtils mdsalUtils = null;
72     private static SouthboundUtils southboundUtils;
73     private static NeutronUtils neutronUtils = new NeutronUtils();
74     private static NeutronModelsDataStoreHelper neutronModelsDataStoreHelper;
75     private static final String NETWORK_TYPE_VXLAN = "vxlan";
76
77     @Override
78     public String getModuleName() {
79         return "netvirt-neutron";
80     }
81
82     @Override
83     public String getInstanceName() { return "netvirt-neutron"; }
84
85     @Override
86     public MavenUrlReference getFeatureRepo() {
87         return maven()
88                 .groupId("org.opendaylight.netvirt")
89                 .artifactId("features-netvirt")
90                 .classifier("features")
91                 .type("xml")
92                 .versionAsInProject();
93     }
94
95     @Override
96     public String getFeatureName() {
97         return FEATURE;
98     }
99
100     @Configuration
101     @Override
102     public Option[] config() {
103         Option[] parentOptions = super.config();
104         Option[] propertiesOptions = getPropertiesOptions();
105         Option[] otherOptions = getOtherOptions();
106         Option[] options = new Option[parentOptions.length + propertiesOptions.length + otherOptions.length];
107         System.arraycopy(parentOptions, 0, options, 0, parentOptions.length);
108         System.arraycopy(propertiesOptions, 0, options, parentOptions.length, propertiesOptions.length);
109         System.arraycopy(otherOptions, 0, options, parentOptions.length + propertiesOptions.length,
110                 otherOptions.length);
111         return options;
112     }
113
114     private Option[] getOtherOptions() {
115         return new Option[] {
116                 wrappedBundle(
117                         mavenBundle("org.opendaylight.netvirt", "utils.mdsal-openflow")
118                                 .version(asInProject())
119                                 .type("jar")),
120                 configureConsole().startLocalConsole(),
121                 //vmOption("-verbose:class"),
122                 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
123                 keepRuntimeFolder()
124         };
125     }
126
127     private Option[] getPropertiesOptions() {
128         return new Option[] {
129                 propagateSystemProperties(ItConstants.SERVER_IPADDRESS, ItConstants.SERVER_PORT,
130                         ItConstants.CONNECTION_TYPE, ItConstants.CONTROLLER_IPADDRESS,
131                         ItConstants.USERSPACE_ENABLED),
132         };
133     }
134
135     @Override
136     public Option getLoggingOption() {
137         return composite(
138                 editConfigurationFilePut(ItConstants.ORG_OPS4J_PAX_LOGGING_CFG,
139                         "log4j.logger.org.opendaylight.ovsdb",
140                         LogLevelOption.LogLevel.TRACE.name()),
141                 editConfigurationFilePut(ItConstants.ORG_OPS4J_PAX_LOGGING_CFG,
142                         logConfiguration(NetvirtIT.class),
143                         LogLevelOption.LogLevel.INFO.name()),
144                 editConfigurationFilePut(ItConstants.ORG_OPS4J_PAX_LOGGING_CFG,
145                         "log4j.logger.org.opendaylight.neutron",
146                         LogLevelOption.LogLevel.TRACE.name()),
147                 super.getLoggingOption());
148     }
149
150     protected String usage() {
151         return "Integration Test needs a valid connection configuration as follows :\n"
152                 + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
153                 + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
154     }
155
156     private void getProperties() {
157         Properties props = System.getProperties();
158         addressStr = props.getProperty(ItConstants.SERVER_IPADDRESS);
159         portStr = props.getProperty(ItConstants.SERVER_PORT, ItConstants.DEFAULT_SERVER_PORT);
160         connectionType = props.getProperty(ItConstants.CONNECTION_TYPE, "active");
161         controllerStr = props.getProperty(ItConstants.CONTROLLER_IPADDRESS, "0.0.0.0");
162         String userSpaceEnabled = props.getProperty(ItConstants.USERSPACE_ENABLED, "no");
163         LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}, controller ip: {}, " +
164                         "userspace.enabled: {}",
165                 connectionType, addressStr, portStr, controllerStr, userSpaceEnabled);
166         if (connectionType.equalsIgnoreCase(ItConstants.CONNECTION_TYPE_ACTIVE)) {
167             if (addressStr == null) {
168                 fail(usage());
169             }
170         }
171     }
172
173     @After
174     public void teardown() {
175         closeWaitFors();
176     }
177
178     @Before
179     @Override
180     public void setup() throws InterruptedException {
181         if (setup.get()) {
182             LOG.info("Skipping setUp, already initialized");
183             return;
184         }
185
186         try {
187             super.setup();
188         } catch (Exception e) {
189             LOG.warn("Failed to setup test", e);
190             fail("Failed to setup test: " + e);
191         }
192
193         getProperties();
194
195         if (connectionType.equalsIgnoreCase(ItConstants.CONNECTION_TYPE_ACTIVE)) {
196             if (addressStr == null) {
197                 fail(usage());
198             }
199         }
200
201         dataBroker = NetvirtItUtils.getDatabroker(getProviderContext());
202         itUtils = new NetvirtItUtils(dataBroker);
203         mdsalUtils = new MdsalUtils(dataBroker);
204         assertNotNull("mdsalUtils should not be null", mdsalUtils);
205         // TODO: Not used yet since openstack is not running to write the netvirt:1 to mdsal
206         // Only need neutron northbound right now
207         //assertTrue("Did not find " + ItConstants.NETVIRT_TOPOLOGY_ID, itUtils.getNetvirtTopology());
208         southboundUtils = new SouthboundUtils(mdsalUtils);
209         neutronModelsDataStoreHelper = new NeutronModelsDataStoreHelper(dataBroker);
210         setup.set(true);
211     }
212
213     private BindingAwareBroker.ProviderContext getProviderContext() {
214         BindingAwareBroker.ProviderContext providerContext = null;
215         for (int i=0; i < 60; i++) {
216             providerContext = getSession();
217             if (providerContext != null) {
218                 break;
219             } else {
220                 try {
221                     Thread.sleep(1000);
222                 } catch (InterruptedException e) {
223                     LOG.warn("Interrupted while waiting for provider context", e);
224                 }
225             }
226         }
227         assertNotNull("providercontext should not be null", providerContext);
228         /* One more second to let the provider finish initialization */
229         try {
230             Thread.sleep(1000);
231         } catch (InterruptedException e) {
232             LOG.warn("Interrupted while waiting for other provider", e);
233         }
234         return providerContext;
235     }
236
237     @Test
238     public void testNetvirtFeatureLoad() {
239         assertTrue("Feature " + FEATURE + " was not loaded", true);
240     }
241
242     private List<NotifyingDataChangeListener> waitList = new ArrayList<>();
243     private void closeWaitFors() {
244         for (Iterator<NotifyingDataChangeListener> iterator = waitList.iterator(); iterator.hasNext();) {
245             NotifyingDataChangeListener listener = iterator.next();
246             iterator.remove();
247             try {
248                 listener.close();
249             } catch (Exception ex) {
250                 LOG.warn("Failed to close registration {}", listener, ex);
251             }
252         }
253         LOG.info("waitList size {}", waitList.size());
254     }
255
256     @Test
257     public void testNetvirtNeutron() throws InterruptedException {
258         final String networkId = "521e29d6-67b8-4b3c-8633-027d21195111";
259         final String tenantId = "521e29d6-67b8-4b3c-8633-027d21195100";
260
261         InstanceIdentifier<Network> path = neutronModelsDataStoreHelper.getNeutronNetworkPath(new Uuid(networkId));
262         final NotifyingDataChangeListener networkOperationalListener =
263                 new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION, path, waitList);
264         networkOperationalListener.registerDataChangeListener(dataBroker);
265
266         NeutronNetwork nn = neutronUtils.createNeutronNetwork(networkId, tenantId,
267                 NETWORK_TYPE_VXLAN, "100");
268
269         networkOperationalListener.waitForCreation();
270
271         Network network = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
272         assertNotNull("the network was not found in mdsal", network);
273     }
274 }