2 * Copyright © 2015 Red Hat, Inc. and others. All rights reserved.
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
9 package org.opendaylight.ovsdb.openstack.netvirt.sfc;
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;
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;
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;
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";
95 public String getModuleName() {
100 public String getInstanceName() {
101 return "netvirt-sfc-default";
105 public MavenUrlReference getFeatureRepo() {
107 .groupId("org.opendaylight.ovsdb")
108 .artifactId("openstack.net-virt-sfc-features-test")
109 .classifier("features")
111 .versionAsInProject();
115 public String getFeatureName() {
116 return "odl-ovsdb-sfc-test";
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);
133 private Option[] getOtherOptions() {
134 return new Option[] {
135 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
140 public Option[] getPropertiesOptions() {
141 return new Option[] {
142 propagateSystemProperties(SERVER_IPADDRESS, SERVER_PORT, CONNECTION_TYPE),
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());
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";
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) {
177 public void setup() {
179 LOG.info("Skipping setUp, already initialized");
186 } catch (Exception e) {
190 DataBroker dataBroker = getDatabroker(getProviderContext());
191 mdsalUtils = new MdsalUtils(dataBroker);
192 assertNotNull("mdsalUtils should not be null", mdsalUtils);
193 southboundUtils = new SouthboundUtils(mdsalUtils);
198 private ProviderContext getProviderContext() {
199 ProviderContext providerContext = null;
200 for (int i=0; i < 60; i++) {
201 providerContext = getSession();
202 if (providerContext != null) {
207 } catch (InterruptedException e) {
212 assertNotNull("providercontext should not be null", providerContext);
213 /* One more second to let the provider finish initialization */
216 } catch (InterruptedException e) {
219 return providerContext;
222 private DataBroker getDatabroker(ProviderContext providerContext) {
223 DataBroker dataBroker = providerContext.getSALService(DataBroker.class);
224 assertNotNull("dataBroker should not be null", dataBroker);
229 public void testNetvirtSfcFeatureLoad() {
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(),
244 LOG.info("AccessLists: {}", accessListsBuilder.build());
245 return accessListsBuilder;
249 public void testAccessLists() {
250 testModel(setAccessLists(), AccessLists.class);
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(),
260 LOG.info("Classifiers: {}", classifiersBuilder.build());
261 return classifiersBuilder;
265 public void testClassifiers() {
266 testModel(setClassifiers(), Classifiers.class);
269 private SfcBuilder setSfc() {
270 SfcBuilder sfcBuilder = sfcUtils.createSfc(new SfcBuilder(), "sfc");
275 public void testSfc() {
276 testModel(setSfc(), Sfc.class);
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);
291 public void testDoIt() throws InterruptedException {
292 ConnectionInfo connectionInfo = southboundUtils.getConnectionInfo(addressStr, portStr);
293 Node ovsdbNode = southboundUtils.connectOvsdbNode(connectionInfo);
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());
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 */
318 Assert.assertTrue(southboundUtils.deleteBridge(connectionInfo, BRIDGE_NAME));
319 southboundUtils.disconnectOvsdbNode(connectionInfo);