<executions>
<execution>
<id>generate-config</id>
+ <phase>none</phase>
<goals>
<goal>generate-depends-file</goal>
</goals>
<!-- Add Pax Exam -->
<dependency>
<groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-container-forked</artifactId>
+ <artifactId>pax-exam-container-native</artifactId>
<version>${exam.version}</version>
<scope>test</scope>
</dependency>
</execution>
</executions>
</plugin>
+ <plugin>
+ <groupId>org.apache.servicemix.tooling</groupId>
+ <artifactId>depends-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>generate-depends-file</id>
+ <goals>
+ <goal>generate-depends-file</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <version>${failsafe.version}</version>
+ <executions>
+ <execution>
+ <id>failsafe-integration-tests</id>
+ <phase>integration-test</phase>
+ <goals>
+ <goal>integration-test</goal>
+ </goals>
+ <configuration>
+ <forkCount>1</forkCount>
+ <reuseForks>false</reuseForks>
+ <parallel>none</parallel>
+ <threadCount>1</threadCount>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
<scm>
package org.opendaylight.ovsdb.integrationtest.northbound;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
private Logger log = LoggerFactory.getLogger(OvsdbNorthboundIT.class);
public static final String USERNAME = "admin";
public static final String PASSWORD = "admin";
- public static final String BASE_URI = "http://localhost:8088";
+ public static final String BASE_URI = "http://localhost:8888";
+ public static final String MEDIA_TYPE_JSON = "application/json";
+ public static final String NODE_ID_REPLACEMENT_PATTERN = "${node}";
+ public static final String UUID_REPLACEMENT_PATTERN = "${uuid}";
+ public static final String BRIDGE_UUID_REPLACEMENT_PATTERN = "${bridge_uuid}";
+ public static final String PORT_UUID_REPLACEMENT_PATTERN = "${port_uuid}";
+ public static final String QOS_UUID_REPLACEMENT_PATTERN = "${qos_uuid}";
+ public static final String OVS_UUID_REPLACEMENT_PATTERN = "${ovs_uuid}";
@Inject
private BundleContext bc;
private Node node = null;
private IUserManager userManager;
- @Parameterized.Parameters(name="{index}:({0})")
+ @Parameterized.Parameters(name = "ApiTest{index}:{0}")
public static List<Object[]> getData() throws FileNotFoundException {
ClassLoader classloader = OvsdbNorthboundIT.class.getClassLoader();
InputStream input = classloader.getResourceAsStream("northbound.yaml");
Yaml yaml = new Yaml();
List<Map<String, Object>> object = (List<Map<String, Object>>) yaml.load(input);
- List parameters = Lists.newArrayList();
+ List<Object[]> parameters = Lists.newArrayList();
for (Map<String, Object> o : object){
Object[] l = o.values().toArray();
fExpectedStatusCode = expectedStatusCode;
}
- private String expandPath(String path){
- String uri = BASE_URI + path;
- uri = uri.replace("${node}", node.getNodeIDString());
- return uri;
- }
-
@Test
- public void testApi(){
-
- System.out.println("Running " + fTestCase);
-
+ public void testApi() {
+ System.out.println("Running " + fTestCase + "...\n");
Client client = Client.create();
client.addFilter(new HTTPBasicAuthFilter(USERNAME , PASSWORD));
- WebResource webResource = client.resource(expandPath(fPath));
+ String uri = BASE_URI + fPath;
+ WebResource webResource = client.resource(expand(uri));
ClientResponse response = null;
switch (fOperation) {
case "GET":
- response = webResource.accept("application/json")
+ response = webResource.accept(MEDIA_TYPE_JSON)
.get(ClientResponse.class);
break;
case "POST":
- response = webResource.accept("application/json")
- .post(ClientResponse.class, fJson);
+ response = webResource.accept(MEDIA_TYPE_JSON)
+ .header("Content-Type", MEDIA_TYPE_JSON)
+ .post(ClientResponse.class, expand(fJson));
+ UuidHelper.setUuid(response.getEntity(String.class));
+ saveUuid(fPath);
break;
case "PUT":
- response = webResource.accept("application/json")
+ response = webResource.accept(MEDIA_TYPE_JSON)
+ .header("Content-Type", MEDIA_TYPE_JSON)
.put(ClientResponse.class, fJson);
break;
case "DELETE":
- response = webResource.accept("application/json")
- .put(ClientResponse.class, fJson);
+ response = webResource.delete(ClientResponse.class);
+ UuidHelper.setUuid("");
break;
default:
fail("Unsupported operation");
}
-
- System.out.println("" + response.toString());
assertEquals(fExpectedStatusCode, response.getStatus());
}
+ private String expand(String content){
+ if (content.contains(NODE_ID_REPLACEMENT_PATTERN)) {
+ content = content.replace(NODE_ID_REPLACEMENT_PATTERN,
+ node.getNodeIDString());
+ }
+ if (content.contains(UUID_REPLACEMENT_PATTERN)) {
+ content = content.replace(UUID_REPLACEMENT_PATTERN,
+ UuidHelper.getUuid());
+ }
+ if (content.contains(BRIDGE_UUID_REPLACEMENT_PATTERN)) {
+ content = content.replace(BRIDGE_UUID_REPLACEMENT_PATTERN,
+ UuidHelper.getBridgeUuid());
+ }
+ if (content.contains(PORT_UUID_REPLACEMENT_PATTERN)) {
+ content = content.replace(PORT_UUID_REPLACEMENT_PATTERN,
+ UuidHelper.getPortUuid());
+ }
+ if (content.contains(QOS_UUID_REPLACEMENT_PATTERN)) {
+ content = content.replace(QOS_UUID_REPLACEMENT_PATTERN,
+ UuidHelper.getQosUuid());
+ }
+ if (content.contains(OVS_UUID_REPLACEMENT_PATTERN)) {
+ content = content.replace(OVS_UUID_REPLACEMENT_PATTERN,
+ getOvsUuid());
+ }
+ return content;
+ }
+
+ private void saveUuid(String path){
+ if (path.contains("bridge")) {
+ UuidHelper.setBridgeUuid(UuidHelper.getUuid());
+ }
+ if (path.contains("port")) {
+ UuidHelper.setPortUuid(UuidHelper.getUuid());
+ }
+ if (path.contains("qos")) {
+ UuidHelper.setQosUuid(UuidHelper.getUuid());
+ }
+ }
+
+ private String getOvsUuid() {
+ if (UuidHelper.getOvsUuid() == null) {
+ Client client = Client.create();
+ client.addFilter(new HTTPBasicAuthFilter(USERNAME, PASSWORD));
+ String uri = OvsdbNorthboundIT.BASE_URI + "/ovsdb/nb/v2/node/OVS/${node}/tables/open_vswitch/rows";
+ WebResource webResource = client.resource(expand(uri));
+ ClientResponse response = webResource.accept(MEDIA_TYPE_JSON)
+ .get(ClientResponse.class);
+
+ assertEquals(200, response.getStatus());
+
+ String row = response.getEntity(String.class);
+ assertNotNull(row);
+
+ try {
+ ObjectMapper objectMapper = new ObjectMapper();
+ JsonNode rowsNode = objectMapper.readTree(row).get("rows");
+ assertNotNull(rowsNode);
+ // The first fieldName is the UUID
+ String uuid = rowsNode.fieldNames().next();
+ assertNotNull(uuid);
+ UuidHelper.setOvsUuid(uuid);
+ } catch (IOException e) {
+ fail("Cannot get the UUID for the Open_vSwitch table");
+ }
+ }
+
+ return UuidHelper.getOvsUuid();
+ }
+
private String stateToString(int state) {
switch (state) {
case Bundle.ACTIVE:
}
@Before
- public void areWeReady() {
+ public void areWeReady() throws InterruptedException {
assertNotNull(bc);
boolean debugit = false;
Bundle b[] = bc.getBundles();
} catch (IOException e) {
e.printStackTrace();
}
+
+ // Wait before making a REST call to avoid overloading Tomcat
+ Thread.sleep(500);
+
}
@Configuration
return options(
//
systemProperty("logback.configurationFile").value(
- "file:" + PathUtils.getBaseDir()
- + "/src/test/resources/logback.xml"
+ PathUtils.getBaseDir() + "/src/test/resources/logback.xml"
),
systemProperty("org.eclipse.gemini.web.tomcat.config.path").value(
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Authors : Dave Tucker
+ */
+
+package org.opendaylight.ovsdb.integrationtest.northbound;
+
+/**
+ * This class persists UUID's generated during the IT run. This is required
+ * as the parameterized runner creates an instance of the NorthboundIT class for every test case
+ */
+public class UuidHelper {
+
+ private static String uuid;
+ private static String bridgeUuid;
+ private static String portUuid;
+ private static String qosUuid;
+ private static String ovsUuid;
+
+ public static String getUuid() {
+ return uuid;
+ }
+
+ public static void setUuid(String uuid) {
+ UuidHelper.uuid = uuid;
+ }
+
+ public static String getBridgeUuid() {
+ return bridgeUuid;
+ }
+
+ public static void setBridgeUuid(String bridgeUuid) {
+ UuidHelper.bridgeUuid = bridgeUuid;
+ }
+
+ public static String getPortUuid() {
+ return portUuid;
+ }
+
+ public static void setPortUuid(String portUuid) {
+ UuidHelper.portUuid = portUuid;
+ }
+
+ public static String getQosUuid() {
+ return qosUuid;
+ }
+
+ public static void setQosUuid(String qosUuid) {
+ UuidHelper.qosUuid = qosUuid;
+ }
+
+ public static String getOvsUuid() {
+ return ovsUuid;
+ }
+
+ public static void setOvsUuid(String ovsUuid) {
+ UuidHelper.ovsUuid = ovsUuid;
+ }
+}
# This file contains test cases for the OVSDB Northbound API
+# The ordering of the test data MUST be as follows:
+# name:
+# operation:
+# uri:
+# json:
+# expected:
+#
+# The tests are run in the order specified in this file
+# The following variables are permitted in the URI or JSON:
+#
+# ${node} = The node identifier
+# ${uuid} = The last UUID returned by a POST operation
+# ${bridge_uuid} = The UUID of the test bridge
+# ${port_uuid} = The UUID of the test port
---
- name: testGetBridgeRows
operation: GET
uri: /ovsdb/nb/v2/node/OVS/${node}/tables/open_vswitch/rows
json:
expected: 200
+
+# Bridge
+
+- name: testCreateBridge
+ operation: POST
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/bridge/rows
+ json: >
+ {
+ "row": {
+ "Bridge": {
+ "name": "bridge1",
+ "datapath_type": "OPENFLOW"
+ }
+ }
+ }
+ expected: 201
+
+- name: testGetBridgeRow
+ operation: GET
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/bridge/rows/${uuid}
+ json:
+ expected: 200
+
+- name: testUpdateBridgeRow
+ operation: PUT
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/bridge/rows/${uuid}
+ json: >
+ {
+ "row": {
+ "Bridge": {
+ "stp_enable": true
+ }
+ }
+ }
+ expected: 200
+
+# Port
+
+- name: testCreatePort
+ operation: POST
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/port/rows
+ json: >
+ {
+ "parent_uuid":"${bridge_uuid}",
+ "row":{
+ "Port":{
+ "name":"testPort1"
+ }
+ }
+ }
+ expected: 201
+
+- name: testGetPortRow
+ operation: GET
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/port/rows/${uuid}
+ json:
+ expected: 200
+
+- name: testUpdatePortRow
+ operation: PUT
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/port/rows/${uuid}
+ json: >
+ {
+ "row": {
+ "Port": {
+ "fake_bridge": true
+ }
+ }
+ }
+ expected: 200
+
+# Interface
+
+- name: testCreateInteface
+ operation: POST
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/interface/rows
+ json: >
+ {
+ "parent_uuid": "${port_uuid}",
+ "row":{
+ "Interface":{
+ "name":"testInterface",
+ "admin_state":"up"
+ }
+ }
+ }
+ expected: 201
+
+- name: testGetInterfaceRow
+ operation: GET
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/interface/rows/${uuid}
+ json:
+ expected: 200
+
+- name: testUpdateInterfaceRow
+ operation: PUT
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/interface/rows/${uuid}
+ json: >
+ {
+ "row":{
+ "Interface":{
+ "type": "gre"
+ }
+ }
+ }
+ expected: 200
+
+- name: testDeleteInterfaceRow
+ operation: DELETE
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/interface/rows/${uuid}
+ json:
+ expected: 204
+
+# Controller
+
+- name: testCreateController
+ operation: POST
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/controller/rows
+ json: >
+ {
+ "parent_uuid" : "${bridge_uuid}",
+ "row" : {
+ "Controller": {
+ "target": "1.1.1.1"
+ }
+ }
+ }
+ expected: 201
+
+- name: testGetControllerRow
+ operation: GET
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/controller/rows/${uuid}
+ json:
+ expected: 200
+
+- name: testUpdateControllerRow
+ operation: PUT
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/controller/rows/${uuid}
+ json: >
+ {
+ "row":{
+ "Controller":{
+ "is_connected": false
+ }
+ }
+ }
+ expected: 200
+
+- name: testDeleteControllerRow
+ operation: DELETE
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/controller/rows/${uuid}
+ json:
+ expected: 204
+
+# SSL
+
+- name: testCreateSslRow
+ operation: POST
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/ssl/rows
+ json: >
+ {
+ "row":{
+ "SSL":{
+ "name":"mySSL",
+ "ca_cert" : "ca_cert",
+ "bootstrap_ca_cert" : true,
+ "certificate":"pieceofpaper",
+ "private_key" : "private"
+ }
+ }
+ }
+ expected: 201
+
+- name: testGetSslRow
+ operation: GET
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/ssl/rows/${uuid}
+ json:
+ expected: 200
+
+- name: testUpdateSslRow
+ operation: PUT
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/ssl/rows/${uuid}
+ json: >
+ {
+ "row":{
+ "SSL":{
+ "private_key" : "secret"
+ }
+ }
+ }
+ expected: 200
+
+- name: testDeleteSslRow
+ operation: DELETE
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/ssl/rows/${uuid}
+ json:
+ expected: 204
+
+# sFlow
+
+- name: testCreateSflowRow
+ operation: POST
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/sflow/rows
+ json: >
+ {
+ "parent_uuid": "${bridge_uuid}",
+ "row": {
+ "sFlow": {
+ "targets": [
+ "set",
+ [
+ "targets_string"
+ ]
+ ]
+ }
+ }
+ }
+ expected: 201
+
+- name: testGetSflowRow
+ operation: GET
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/sflow/rows/${uuid}
+ json:
+ expected: 200
+
+- name: testUpdateSflowRow
+ operation: PUT
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/sflow/rows/${uuid}
+ json: >
+ {
+ "row":{
+ "sFlow":{
+ "targets": [
+ "set",
+ [
+ "targets_string",
+ "second_target"
+ ]
+ ]
+ }
+ }
+ }
+ expected: 200
+
+- name: testDeleteSflowRow
+ operation: DELETE
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/sflow/rows/${uuid}
+ json:
+ expected: 204
+
+# QoS
+
+- name: testCreateQosRow
+ operation: POST
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/qos/rows
+ json: >
+ {
+ "parent_uuid" : "${port_uuid}",
+ "row" : {
+ "QoS": {
+ "type": "linux-htb"
+ }
+ }
+ }
+ expected: 201
+
+- name: testGetQosRow
+ operation: GET
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/qos/rows/${uuid}
+ json:
+ expected: 200
+
+- name: testUpdateQosRow
+ operation: PUT
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/qos/rows/${uuid}
+ json: >
+ {
+ "row":{
+ "QoS":{
+ "type": "linux-hfsc"
+ }
+ }
+ }
+ expected: 200
+
+# Queue
+
+- name: testCreateQueueRow
+ operation: POST
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/queue/rows
+ json: >
+ {
+ "parent_uuid": "${qos_uuid}",
+ "row": {
+ "Queue": {
+ "dscp" : [
+ "set",
+ [
+ 25
+ ]
+ ]
+ }
+ }
+ }
+ expected: 201
+
+- name: testGetQueueRow
+ operation: GET
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/queue/rows/${uuid}
+ json:
+ expected: 200
+
+- name: testUpdateQueueRow
+ operation: PUT
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/queue/rows/${uuid}
+ json: >
+ {
+ "row":{
+ "Queue":{
+ "other_config" : [
+ "map", ["foo", "bar" ]
+ ]
+ }
+ }
+ }
+ expected: 200
+
+- name: testDeleteQueueRow
+ operation: DELETE
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/queue/rows/${uuid}
+ json:
+ expected: 204
+
+# NetFlow
+
+- name: testCreateNetflowRow
+ operation: POST
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/netflow/rows
+ json: >
+ {
+ "parent_uuid":"${bridge_uuid}",
+ "row" : {
+ "NetFlow":{
+ "targets" : [
+ "set", ["192.168.1.102:9998"]],
+ "active_timeout" : "0"
+ }
+ }
+ }
+ expected: 201
+
+- name: testGetNetflowRow
+ operation: GET
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/netflow/rows/${uuid}
+ json:
+ expected: 200
+
+- name: testUpdateNetflowRow
+ operation: PUT
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/netflow/rows/${uuid}
+ json: >
+ {
+ "row" : {
+ "NetFlow":{
+ "targets" : [
+ "set", ["192.168.1.102:9998", "192.168.2.102:9998"]]
+ }
+ }
+ }
+ expected: 200
+
+- name: testDeleteNetflowRow
+ operation: DELETE
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/netflow/rows/${uuid}
+ json:
+ expected: 204
+
+# Manager
+
+- name: testCreateManagerRow
+ operation: POST
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/manager/rows
+ json: >
+ {
+ "parent_uuid":"${ovs_uuid}",
+ "row":{
+ "Manager":{
+ "target":"a_string",
+ "is_connected": true,
+ "state":"active"
+ }
+ }
+ }
+ expected: 201
+
+- name: testGetManagerRow
+ operation: GET
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/manager/rows/${uuid}
+ json:
+ expected: 200
+
+- name: testUpdateManagerRow
+ operation: PUT
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/manager/rows/${uuid}
+ json: >
+ {
+ "row":{
+ "Manager":{
+ "is_connected": false
+ }
+ }
+ }
+ expected: 200
+
+- name: testDeleteManagerRow
+ operation: DELETE
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/manager/rows/${uuid}
+ json:
+ expected: 204
+
+# Cleanup
+
+- name: testDeleteQosRow
+ operation: DELETE
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/qos/rows/${qos_uuid}
+ json:
+ expected: 204
+
+- name: testDeletePortRow
+ operation: DELETE
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/port/rows/${port_uuid}
+ json:
+ expected: 204
+
+- name: testDeleteBridgeRow
+ operation: DELETE
+ uri: /ovsdb/nb/v2/node/OVS/${node}/tables/bridge/rows/${bridge_uuid}
+ json:
+ expected: 204
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<Service name="Catalina">
- <Connector port="8088" protocol="HTTP/1.1"
+ <Connector port="8888" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
redirectPort="8443" />