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)); } }