Merge "Adding copyright header to ovsdb/southbound UT"
[netvirt.git] / openstack / net-virt-sfc / it / src / test / java / org / opendaylight / ovsdb / openstack / netvirt / sfc / NetvirtSfcIT.java
1 /*
2  * Copyright © 2015 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.ovsdb.openstack.netvirt.sfc;
10
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertNull;
13 import static org.junit.Assert.assertTrue;
14 import static org.junit.Assert.fail;
15 import static org.ops4j.pax.exam.CoreOptions.composite;
16 import static org.ops4j.pax.exam.CoreOptions.maven;
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.karaf.options.KarafDistributionOption.editConfigurationFilePut;
20 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
21
22 import java.util.List;
23 import java.util.Properties;
24 import java.util.concurrent.atomic.AtomicBoolean;
25 import org.junit.Assert;
26 import org.junit.Before;
27 import org.junit.Test;
28 import org.junit.runner.RunWith;
29 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
30 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
31 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
32 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
33 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.AclUtils;
34 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ClassifierUtils;
35 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.SfcUtils;
36 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
37 import org.opendaylight.ovsdb.southbound.SouthboundUtil;
38 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
39 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.AccessLists;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.AccessListsBuilder;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.AccessListBuilder;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.AccessListEntriesBuilder;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.AccessListEntryBuilder;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.ActionsBuilder;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.MatchesBuilder;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.Classifiers;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.ClassifiersBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.ClassifierBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.SffsBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.SffBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105.Sfc;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105.SfcBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
58 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
59 import org.opendaylight.yangtools.concepts.Builder;
60 import org.opendaylight.yangtools.yang.binding.DataObject;
61 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
62
63 import org.ops4j.pax.exam.Configuration;
64 import org.ops4j.pax.exam.Option;
65 import org.ops4j.pax.exam.junit.PaxExam;
66 import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel;
67 import org.ops4j.pax.exam.options.MavenUrlReference;
68 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
69 import org.ops4j.pax.exam.spi.reactors.PerClass;
70 import org.slf4j.Logger;
71 import org.slf4j.LoggerFactory;
72
73 @RunWith(PaxExam.class)
74 @ExamReactorStrategy(PerClass.class)
75 public class NetvirtSfcIT extends AbstractMdsalTestBase {
76     private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcIT.class);
77     private static AclUtils aclUtils = new AclUtils();
78     private static ClassifierUtils classifierUtils = new ClassifierUtils();
79     private static SfcUtils sfcUtils = new SfcUtils();
80     private static MdsalUtils mdsalUtils;
81     private static AtomicBoolean setup = new AtomicBoolean(false);
82     private static SouthboundUtils southboundUtils;
83     private static String addressStr;
84     private static String portStr;
85     private static String connectionType;
86     public static final String SERVER_IPADDRESS = "ovsdbserver.ipaddress";
87     public static final String SERVER_PORT = "ovsdbserver.port";
88     public static final String CONNECTION_TYPE = "ovsdbserver.connection";
89     public static final String CONNECTION_TYPE_ACTIVE = "active";
90     public static final String CONNECTION_TYPE_PASSIVE = "passive";
91     public static final String DEFAULT_SERVER_PORT = "6640";
92     public static final String BRIDGE_NAME = "brtest";
93
94     @Override
95     public String getModuleName() {
96         return "netvirt-sfc";
97     }
98
99     @Override
100     public String getInstanceName() {
101         return "netvirt-sfc-default";
102     }
103
104     @Override
105     public MavenUrlReference getFeatureRepo() {
106         return maven()
107                 .groupId("org.opendaylight.ovsdb")
108                 .artifactId("openstack.net-virt-sfc-features-test")
109                 .classifier("features")
110                 .type("xml")
111                 .versionAsInProject();
112     }
113
114     @Override
115     public String getFeatureName() {
116         return "odl-ovsdb-sfc-test";
117     }
118
119     @Configuration
120     @Override
121     public Option[] config() {
122         Option[] parentOptions = super.config();
123         Option[] propertiesOptions = getPropertiesOptions();
124         Option[] otherOptions = getOtherOptions();
125         Option[] options = new Option[parentOptions.length + propertiesOptions.length + otherOptions.length];
126         System.arraycopy(parentOptions, 0, options, 0, parentOptions.length);
127         System.arraycopy(propertiesOptions, 0, options, parentOptions.length, propertiesOptions.length);
128         System.arraycopy(otherOptions, 0, options, parentOptions.length + propertiesOptions.length,
129                 otherOptions.length);
130         return options;
131     }
132
133     private Option[] getOtherOptions() {
134         return new Option[] {
135                 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
136                 keepRuntimeFolder()
137         };
138     }
139
140     public Option[] getPropertiesOptions() {
141         return new Option[] {
142                 propagateSystemProperties(SERVER_IPADDRESS, SERVER_PORT, CONNECTION_TYPE),
143         };
144     }
145
146     @Override
147     public Option getLoggingOption() {
148         Option option = editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
149                 logConfiguration(NetvirtSfcIT.class),
150                 LogLevel.INFO.name());
151         option = composite(option, super.getLoggingOption());
152         return option;
153     }
154
155     protected String usage() {
156         return "Integration Test needs a valid connection configuration as follows :\n"
157                 + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
158                 + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
159     }
160
161     private void getProperties() {
162         Properties props = System.getProperties();
163         addressStr = props.getProperty(SERVER_IPADDRESS);
164         portStr = props.getProperty(SERVER_PORT, DEFAULT_SERVER_PORT);
165         connectionType = props.getProperty(CONNECTION_TYPE, "active");
166         LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
167                 connectionType, addressStr, portStr);
168         if (connectionType.equalsIgnoreCase(CONNECTION_TYPE_ACTIVE)) {
169             if (addressStr == null) {
170                 fail(usage());
171             }
172         }
173     }
174
175     @Before
176     @Override
177     public void setup() {
178         if (setup.get()) {
179             LOG.info("Skipping setUp, already initialized");
180             return;
181         }
182
183         try {
184             Thread.sleep(1000);
185             super.setup();
186         } catch (Exception e) {
187             e.printStackTrace();
188         }
189
190         DataBroker dataBroker = getDatabroker(getProviderContext());
191         mdsalUtils = new MdsalUtils(dataBroker);
192         assertNotNull("mdsalUtils should not be null", mdsalUtils);
193         southboundUtils = new SouthboundUtils(mdsalUtils);
194         getProperties();
195         setup.set(true);
196     }
197
198     private ProviderContext getProviderContext() {
199         ProviderContext providerContext = null;
200         for (int i=0; i < 60; i++) {
201             providerContext = getSession();
202             if (providerContext != null) {
203                 break;
204             } else {
205                 try {
206                     Thread.sleep(1000);
207                 } catch (InterruptedException e) {
208                     e.printStackTrace();
209                 }
210             }
211         }
212         assertNotNull("providercontext should not be null", providerContext);
213         /* One more second to let the provider finish initialization */
214         try {
215             Thread.sleep(1000);
216         } catch (InterruptedException e) {
217             e.printStackTrace();
218         }
219         return providerContext;
220     }
221
222     private DataBroker getDatabroker(ProviderContext providerContext) {
223         DataBroker dataBroker = providerContext.getSALService(DataBroker.class);
224         assertNotNull("dataBroker should not be null", dataBroker);
225         return dataBroker;
226     }
227
228     @Test
229     public void testNetvirtSfcFeatureLoad() {
230         assertTrue(true);
231     }
232
233     private AccessListsBuilder setAccessLists () {
234         MatchesBuilder matchesBuilder = aclUtils.createMatches(new MatchesBuilder(), 80);
235         ActionsBuilder actionsBuilder = aclUtils.createActions(new ActionsBuilder(), Boolean.TRUE);
236         AccessListEntryBuilder accessListEntryBuilder = aclUtils.createAccessListEntryBuilder(
237                 new AccessListEntryBuilder(), "http", matchesBuilder, actionsBuilder);
238         AccessListEntriesBuilder accessListEntriesBuilder = aclUtils.createAccessListEntries(
239                 new AccessListEntriesBuilder(), accessListEntryBuilder);
240         AccessListBuilder accessListBuilder = aclUtils.createAccessList(new AccessListBuilder(),
241                 "http", accessListEntriesBuilder);
242         AccessListsBuilder accessListsBuilder = aclUtils.createAccessLists(new AccessListsBuilder(),
243                 accessListBuilder);
244         LOG.info("AccessLists: {}", accessListsBuilder.build());
245         return accessListsBuilder;
246     }
247
248     @Test
249     public void testAccessLists() {
250         testModel(setAccessLists(), AccessLists.class);
251     }
252
253     private ClassifiersBuilder setClassifiers() {
254         SffBuilder sffBuilder = classifierUtils.createSff(new SffBuilder(), "sffname");
255         SffsBuilder sffsBuilder = classifierUtils.createSffs(new SffsBuilder(), sffBuilder);
256         ClassifierBuilder classifierBuilder = classifierUtils.createClassifier(new ClassifierBuilder(),
257                 "classifierName", "aclName", sffsBuilder);
258         ClassifiersBuilder classifiersBuilder = classifierUtils.createClassifiers(new ClassifiersBuilder(),
259                 classifierBuilder);
260         LOG.info("Classifiers: {}", classifiersBuilder.build());
261         return classifiersBuilder;
262     }
263
264     @Test
265     public void testClassifiers() {
266         testModel(setClassifiers(), Classifiers.class);
267     }
268
269     private SfcBuilder setSfc() {
270         SfcBuilder sfcBuilder = sfcUtils.createSfc(new SfcBuilder(), "sfc");
271         return sfcBuilder;
272     }
273
274     @Test
275     public void testSfc() {
276         testModel(setSfc(), Sfc.class);
277     }
278
279     private <T extends DataObject> void testModel(Builder<T> builder, Class<T> clazz) {
280         InstanceIdentifier<T> path = InstanceIdentifier.create(clazz);
281         assertTrue(mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, path, builder.build()));
282         T result = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
283         assertNotNull(clazz.getSimpleName() + " should not be null", result);
284         assertTrue("Failed to remove " + clazz.getSimpleName(),
285                 mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, path));
286         result = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
287         assertNull(clazz.getSimpleName() + " should be null", result);
288     }
289
290     @Test
291     public void testDoIt() throws InterruptedException {
292         ConnectionInfo connectionInfo = southboundUtils.getConnectionInfo(addressStr, portStr);
293         Node ovsdbNode = southboundUtils.connectOvsdbNode(connectionInfo);
294
295         String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
296         assertNotNull("Failed to get controller target", controllerTarget);
297         List<ControllerEntry> setControllerEntry = southboundUtils.createControllerEntry(controllerTarget);
298         Uri setUri = new Uri(controllerTarget);
299         Assert.assertTrue(southboundUtils.addBridge(connectionInfo, null, BRIDGE_NAME, null, true,
300                 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null,
301                 setControllerEntry, null));
302         OvsdbBridgeAugmentation bridge = southboundUtils.getBridge(connectionInfo, BRIDGE_NAME);
303         Assert.assertNotNull("bridge was not found: " + BRIDGE_NAME,  bridge);
304         Assert.assertNotNull("ControllerEntry was not found: " + setControllerEntry.iterator().next(),
305                 bridge.getControllerEntry());
306         List<ControllerEntry> getControllerEntries = bridge.getControllerEntry();
307         for (ControllerEntry entry : getControllerEntries) {
308             if (entry.getTarget() != null) {
309                 Assert.assertEquals(setUri.toString(), entry.getTarget().toString());
310             }
311         }
312
313         /* TODO: add code to write to mdsal to exercise the sfc dataChangeListener */
314         /* allow some time to let the impl code do it's work to push flows */
315         /* or just comment out below lines and just manually verify on the bridges and reset them */
316         Thread.sleep(10000);
317
318         Assert.assertTrue(southboundUtils.deleteBridge(connectionInfo, BRIDGE_NAME));
319         southboundUtils.disconnectOvsdbNode(connectionInfo);
320     }
321 }