| 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.Assert; |
| 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"; |
| |
| /** |
| * 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 dstDpid0 = dst0.getString("dpid"); |
| assertThat(dstDpid0, is(equalTo("00:00:00:00:00:00:00:04"))); |
| int dstPortNumber0 = dst0.getInt("portNumber"); |
| assertThat(dstPortNumber0, is(equalTo(41))); |
| final JSONObject src0 = ports0.getJSONObject("src"); |
| assertThat(src0, is(notNullValue())); |
| final String srcDpid0 = src0.getString("dpid"); |
| assertThat(srcDpid0, is(equalTo("00:00:00:00:00:00:00:01"))); |
| int srcPortNumber0 = src0.getInt("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 dstDpid1 = dst1.getString("dpid"); |
| assertThat(dstDpid1, is(equalTo("00:00:00:00:00:00:00:03"))); |
| int dstPortNumber1 = dst1.getInt("portNumber"); |
| assertThat(dstPortNumber1, is(equalTo(32))); |
| final JSONObject src1 = ports1.getJSONObject("src"); |
| assertThat(src1, is(notNullValue())); |
| final String srcDpid1 = src1.getString("dpid"); |
| assertThat(srcDpid1, is(equalTo("00:00:00:00:00:00:00:02"))); |
| int srcPortNumber1 = src1.getInt("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)); |
| } |
| } |
| |