Add REST unit tests for Low Level Intents
- GET of all low level intents
- GET of a single low level intent that exists
- GET of a single low level intent that does not exist
Change-Id: I881777629799c0b075d64bf22007eeabe5c1929b
diff --git a/src/test/java/net/onrc/onos/api/rest/TestRest.java b/src/test/java/net/onrc/onos/api/rest/TestRest.java
index 21bc4be..f91e8dc 100644
--- a/src/test/java/net/onrc/onos/api/rest/TestRest.java
+++ b/src/test/java/net/onrc/onos/api/rest/TestRest.java
@@ -1,6 +1,10 @@
package net.onrc.onos.api.rest;
import net.floodlightcontroller.restserver.RestletRoutable;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.restlet.resource.ClientResource;
import java.util.LinkedList;
import java.util.List;
@@ -91,4 +95,38 @@
return portStartRange + (random.nextInt(portEndRange - portStartRange));
}
+
+ /**
+ * Get the JSON object representation for the top level object referred
+ * to by the given client.
+ *
+ * @param client the ClientResource that references the JSON object
+ * @return JSONObject that represents the object, null if it can't be
+ * fetched
+ */
+ protected static JSONObject getJSONObject(final ClientResource client) {
+ try {
+ final String responseJSONString = client.get(String.class);
+ return new JSONObject(responseJSONString);
+ } catch (JSONException jsonException) {
+ return null;
+ }
+ }
+
+ /**
+ * Get the JSON array representation for the array referred to by
+ * the given client.
+ *
+ * @param client the ClientResource that references the JSON array
+ * @return JSONArray that represents the array, null if it can't be
+ * fetched.
+ */
+ protected static JSONArray getJSONArray(final ClientResource client) {
+ try {
+ final String responseJSONString = client.get(String.class);
+ return new JSONArray(responseJSONString);
+ } catch (JSONException jsonException) {
+ return null;
+ }
+ }
}
diff --git a/src/test/java/net/onrc/onos/api/rest/TestRestIntent.java b/src/test/java/net/onrc/onos/api/rest/TestRestIntent.java
index 630000e..b229121 100644
--- a/src/test/java/net/onrc/onos/api/rest/TestRestIntent.java
+++ b/src/test/java/net/onrc/onos/api/rest/TestRestIntent.java
@@ -94,6 +94,15 @@
}
/**
+ * Fetch the URL to use for Low Level Intents REST API calls.
+ *
+ * @return low level intents REST API URL
+ */
+ String getLowRestIntentUrl() {
+ return getBaseRestIntentUrl() + "/low";
+ }
+
+ /**
* Utility function to locate an intent in a JSON collection
* that has the given id.
* The JSON collection of intents looks like:
diff --git a/src/test/java/net/onrc/onos/api/rest/TestRestIntentLowGet.java b/src/test/java/net/onrc/onos/api/rest/TestRestIntentLowGet.java
new file mode 100644
index 0000000..86beb1b
--- /dev/null
+++ b/src/test/java/net/onrc/onos/api/rest/TestRestIntentLowGet.java
@@ -0,0 +1,253 @@
+package net.onrc.onos.api.rest;
+
+
+import com.google.common.net.InetAddresses;
+import net.onrc.onos.core.intent.IntentOperation;
+import net.onrc.onos.core.intent.IntentOperationList;
+import net.onrc.onos.core.intent.ShortestPathIntent;
+import net.onrc.onos.core.intent.runtime.PathCalcRuntimeModule;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.restlet.data.Status;
+import org.restlet.resource.ClientResource;
+import org.restlet.resource.ResourceException;
+
+import static net.onrc.onos.api.rest.ClientResourceStatusMatcher.hasStatusOf;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+
+/**
+ * Unit tests to test the Intents GET REST APIs.
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(PathCalcRuntimeModule.class)
+public class TestRestIntentLowGet extends TestRestIntent {
+ private static final Long LOCAL_PORT = 0xFFFEL;
+ private static final String BAD_SWITCH_INTENT_NAME = "No Such Switch Intent";
+ private static final String IP_ADDRESS_1 = "127.0.0.1";
+ private static final String IP_ADDRESS_2 = "127.0.0.2";
+ private static final String IP_ADDRESS_3 = "127.0.0.3";
+
+ /**
+ * Create the web server, PathCalcRuntime, and mocks required for
+ * all of the tests.
+ */
+ @Before
+ public void beforeTest() {
+ setRestPort(generateRandomPort());
+ setUp();
+ }
+
+
+ /**
+ * Remove anything that will interfere with the next test running correctly.
+ * Shuts down the test REST web server and removes the mocks.
+ */
+ @After
+ public void afterTest() {
+ tearDown();
+ }
+
+
+ /**
+ * Make a set of Intents that can be used as test data.
+ */
+ private void makeDefaultIntents() {
+ final int ipAddress1AsInt = InetAddresses.coerceToInteger(
+ InetAddresses.forString(IP_ADDRESS_1));
+ final int ipAddress2AsInt = InetAddresses.coerceToInteger(
+ InetAddresses.forString(IP_ADDRESS_2));
+ final int ipAddress3AsInt = InetAddresses.coerceToInteger(
+ InetAddresses.forString(IP_ADDRESS_3));
+
+ // create shortest path intents
+ final IntentOperationList opList = new IntentOperationList();
+ opList.add(IntentOperation.Operator.ADD,
+ new ShortestPathIntent(BAD_SWITCH_INTENT_NAME, 111L, 12L,
+ LOCAL_PORT, 2L, 21L, LOCAL_PORT));
+ opList.add(IntentOperation.Operator.ADD,
+ new ShortestPathIntent("1:2", 1L, 14L, LOCAL_PORT, ipAddress1AsInt,
+ 4L, 41L, LOCAL_PORT, ipAddress2AsInt));
+ opList.add(IntentOperation.Operator.ADD,
+ new ShortestPathIntent("1:3", 2L, 23L, LOCAL_PORT, ipAddress2AsInt,
+ 3L, 32L, LOCAL_PORT, ipAddress3AsInt));
+
+ // compile high-level intent operations into low-level intent
+ // operations (calculate paths)
+
+ final IntentOperationList pathIntentOpList =
+ getRuntime().executeIntentOperations(opList);
+ assertThat(pathIntentOpList, notNullValue());
+
+ }
+
+ /**
+ * Find the intent with the given ID in the intent array.
+ *
+ * @param intents array of intents
+ * @param id this is the id too look up
+ * @return JSONObject for the intent if found, null otherwise
+ * @throws JSONException if the intent object marshalling fails
+ */
+ private JSONObject findIntent(final JSONArray intents, final String id)
+ throws JSONException {
+
+ if (id == null) {
+ return null;
+ }
+
+ JSONObject result = null;
+ for (int intentIndex = 0; intentIndex < intents.length(); intentIndex++) {
+ final JSONObject thisIntent = intents.getJSONObject(intentIndex);
+ if (id.equals(thisIntent.getString("id"))) {
+ result = thisIntent;
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Test that the GET of all Intents REST call returns the proper result.
+ * The call to get all Intents should return 3 items, an HTTP status of OK,
+ * and the proper Intent data.
+ *
+ * @throws Exception to fail the test if any unhandled errors occur
+ */
+ @Test
+ public void testFetchOfAllLowLevelIntents() throws Exception {
+
+ makeDefaultIntents();
+
+ final ClientResource client = new ClientResource(getLowRestIntentUrl());
+ final JSONArray intents = getJSONArray(client);
+ assertThat(intents, is(notNullValue()));
+
+ // HTTP status should be OK
+ assertThat(client, hasStatusOf(Status.SUCCESS_OK));
+
+ // 2 low level intents should have been fetched - one of the
+ // high level intents is in error
+ assertThat(intents.length(), is(equalTo(2)));
+
+ // Check that intent 0 is correct
+ final JSONObject intent0 = findIntent(intents, "1:2___0");
+ assertThat(intent0, is(notNullValue()));
+
+ // Check the values of the fields in low level intent 0
+ assertThat(intent0.getString("id"), is(equalTo("1:2___0")));
+ assertThat(intent0.getString("state"), is(equalTo("INST_REQ")));
+ assertThat(intent0.getBoolean("pathFrozen"), is(equalTo(false)));
+
+ // Check the path on intent 0
+ final JSONArray path0 = intent0.getJSONArray("path");
+ assertThat(path0, is(notNullValue()));
+ final JSONObject ports0 = path0.getJSONObject(0);
+ assertThat(ports0, is(notNullValue()));
+ final JSONObject dst0 = ports0.getJSONObject("dst");
+ assertThat(dst0, is(notNullValue()));
+ final String dstPortNumber0 = dst0.getString("portNumber");
+ assertThat(dstPortNumber0, is(equalTo("41")));
+ final JSONObject src0 = ports0.getJSONObject("src");
+ assertThat(src0, is(notNullValue()));
+ final String srcPortNumber0 = src0.getString("portNumber");
+ assertThat(srcPortNumber0, is(equalTo("14")));
+
+ // Check that intent 1 is correct
+ final JSONObject intent1 = findIntent(intents, "1:3___0");
+ assertThat(intent1, is(notNullValue()));
+
+ // Check the values of the fields in low level intent 1
+ assertThat(intent1.getString("id"), is(equalTo("1:3___0")));
+ assertThat(intent1.getString("state"), is(equalTo("INST_REQ")));
+ assertThat(intent1.getBoolean("pathFrozen"), is(equalTo(false)));
+
+ // Check the path on intent 1
+ final JSONArray path1 = intent1.getJSONArray("path");
+ assertThat(path1, is(notNullValue()));
+ final JSONObject ports1 = path1.getJSONObject(0);
+ assertThat(ports1, is(notNullValue()));
+ final JSONObject dst1 = ports1.getJSONObject("dst");
+ assertThat(dst1, is(notNullValue()));
+ final String dstPortNumber1 = dst1.getString("portNumber");
+ assertThat(dstPortNumber1, is(equalTo("32")));
+ final JSONObject src1 = ports1.getJSONObject("src");
+ assertThat(src1, is(notNullValue()));
+ final String srcPortNumber1 = src1.getString("portNumber");
+ assertThat(srcPortNumber1, is(equalTo("23")));
+ }
+
+ /**
+ * Test that the GET of a single Intent REST call returns the proper result
+ * when given a bad Intent id. The call to get the Intent should return a
+ * status of NOT_FOUND.
+ *
+ * @throws JSONException if a bad JSON object is returned for the error
+ */
+ @Test
+ public void testFetchOfBadLowLevelIntent() throws JSONException {
+
+ makeDefaultIntents();
+
+ final ClientResource client = new ClientResource(getLowRestIntentUrl() + "/2334");
+
+ try {
+ client.get();
+ // The get operation should have thrown a ResourceException.
+ // Fail because the Exception was not seen.
+ Assert.fail("Invalid intent fetch did not cause an exception");
+ } catch (ResourceException resourceError) {
+ // The HTTP status should be NOT FOUND
+ assertThat(client, hasStatusOf(Status.CLIENT_ERROR_NOT_FOUND));
+
+ // Check that the error entity is correct
+ final String responseErrorString = client.getResponse().getEntityAsText();
+ final JSONObject responseError = new JSONObject(responseErrorString);
+ assertThat(responseError.getString("code"),
+ is(equalTo("INTENT_NOT_FOUND")));
+ assertThat(responseError.getString("summary"),
+ is(equalTo("Intent not found")));
+ assertThat(responseError.getString("formattedDescription"),
+ containsString("An intent with the identifier"));
+ }
+ }
+
+ /**
+ * Test that the GET of a single Low Level Intent REST call returns the
+ * proper result for an existing Intent. The call to get the Low Level
+ * Intent should return a status of OK, and the data for the
+ * Low Level Intent should be correct.
+ *
+ * @throws JSONException if the JSON cannot be marshalled into an object.
+ */
+ @Test
+ public void testFetchOfGoodLowLevelIntent() throws JSONException {
+
+ makeDefaultIntents();
+
+ final ClientResource client = new ClientResource(getLowRestIntentUrl() + "/3___0");
+ final JSONObject intent = getJSONObject(client);
+
+ // HTTP status should be OK
+ assertThat(client, hasStatusOf(Status.SUCCESS_OK));
+
+ // Intent data should be correct
+ assertThat(intent, is(notNullValue()));
+
+ assertThat(intent.getString("id"), is(equalTo("1:3___0")));
+ assertThat(intent.getString("state"), is(equalTo("INST_REQ")));
+ assertThat(intent.getBoolean("pathFrozen"), is(false));
+ }
+}
+
diff --git a/src/test/java/net/onrc/onos/api/rest/TestRestTopology.java b/src/test/java/net/onrc/onos/api/rest/TestRestTopology.java
index 3ef89eb..aef7262 100644
--- a/src/test/java/net/onrc/onos/api/rest/TestRestTopology.java
+++ b/src/test/java/net/onrc/onos/api/rest/TestRestTopology.java
@@ -6,10 +6,6 @@
import net.onrc.onos.core.intent.runtime.PathCalcRuntimeModule;
import net.onrc.onos.core.topology.ITopologyService;
import net.onrc.onos.core.topology.web.TopologyWebRoutable;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.restlet.resource.ClientResource;
/**
* Test harness for Topology based REST API tests. This class maintains the
@@ -72,37 +68,4 @@
return getBaseRestUrl() + "/topology";
}
- /**
- * Get the JSON object representation for the top level object referred
- * to by the given client.
- *
- * @param client the ClientResource that references the JSON object
- * @return JSONObject that represents the object, null if it can't be
- * fetched
- */
- JSONObject getJSONObject(final ClientResource client) {
- try {
- final String topologyJSONString = client.get(String.class);
- return new JSONObject(topologyJSONString);
- } catch (JSONException jsonException) {
- return null;
- }
- }
-
- /**
- * Get the JSON array representation for the array referred to by
- * the given client.
- *
- * @param client the ClientResource that references the JSON array
- * @return JSONArray that represents the array, null if it can't be
- * fetched.
- */
- JSONArray getJSONArray(final ClientResource client) {
- try {
- final String topologyJSONString = client.get(String.class);
- return new JSONArray(topologyJSONString);
- } catch (JSONException jsonException) {
- return null;
- }
- }
}