Ray Milkey | 213e56a | 2014-06-23 10:45:45 -0700 | [diff] [blame] | 1 | package net.onrc.onos.api.rest; |
| 2 | |
| 3 | |
| 4 | import com.google.common.net.InetAddresses; |
| 5 | import net.onrc.onos.core.intent.IntentOperation; |
| 6 | import net.onrc.onos.core.intent.IntentOperationList; |
| 7 | import net.onrc.onos.core.intent.ShortestPathIntent; |
| 8 | import net.onrc.onos.core.intent.runtime.PathCalcRuntimeModule; |
| 9 | import org.json.JSONArray; |
| 10 | import org.json.JSONException; |
| 11 | import org.json.JSONObject; |
| 12 | import org.junit.After; |
| 13 | import org.junit.Assert; |
| 14 | import org.junit.Before; |
| 15 | import org.junit.Test; |
| 16 | import org.junit.runner.RunWith; |
| 17 | import org.powermock.core.classloader.annotations.PrepareForTest; |
| 18 | import org.powermock.modules.junit4.PowerMockRunner; |
| 19 | import org.restlet.data.Status; |
| 20 | import org.restlet.resource.ClientResource; |
| 21 | import org.restlet.resource.ResourceException; |
| 22 | |
| 23 | import static net.onrc.onos.api.rest.ClientResourceStatusMatcher.hasStatusOf; |
| 24 | import static org.hamcrest.MatcherAssert.assertThat; |
| 25 | import static org.hamcrest.Matchers.containsString; |
| 26 | import static org.hamcrest.Matchers.equalTo; |
| 27 | import static org.hamcrest.Matchers.is; |
| 28 | import static org.hamcrest.Matchers.notNullValue; |
| 29 | |
| 30 | /** |
| 31 | * Unit tests to test the Intents GET REST APIs. |
| 32 | */ |
| 33 | @RunWith(PowerMockRunner.class) |
| 34 | @PrepareForTest(PathCalcRuntimeModule.class) |
| 35 | public class TestRestIntentLowGet extends TestRestIntent { |
| 36 | private static final Long LOCAL_PORT = 0xFFFEL; |
| 37 | private static final String BAD_SWITCH_INTENT_NAME = "No Such Switch Intent"; |
| 38 | private static final String IP_ADDRESS_1 = "127.0.0.1"; |
| 39 | private static final String IP_ADDRESS_2 = "127.0.0.2"; |
| 40 | private static final String IP_ADDRESS_3 = "127.0.0.3"; |
| 41 | |
| 42 | /** |
| 43 | * Create the web server, PathCalcRuntime, and mocks required for |
| 44 | * all of the tests. |
| 45 | */ |
| 46 | @Before |
| 47 | public void beforeTest() { |
| 48 | setRestPort(generateRandomPort()); |
| 49 | setUp(); |
| 50 | } |
| 51 | |
| 52 | |
| 53 | /** |
| 54 | * Remove anything that will interfere with the next test running correctly. |
| 55 | * Shuts down the test REST web server and removes the mocks. |
| 56 | */ |
| 57 | @After |
| 58 | public void afterTest() { |
| 59 | tearDown(); |
| 60 | } |
| 61 | |
| 62 | |
| 63 | /** |
| 64 | * Make a set of Intents that can be used as test data. |
| 65 | */ |
| 66 | private void makeDefaultIntents() { |
| 67 | final int ipAddress1AsInt = InetAddresses.coerceToInteger( |
| 68 | InetAddresses.forString(IP_ADDRESS_1)); |
| 69 | final int ipAddress2AsInt = InetAddresses.coerceToInteger( |
| 70 | InetAddresses.forString(IP_ADDRESS_2)); |
| 71 | final int ipAddress3AsInt = InetAddresses.coerceToInteger( |
| 72 | InetAddresses.forString(IP_ADDRESS_3)); |
| 73 | |
| 74 | // create shortest path intents |
| 75 | final IntentOperationList opList = new IntentOperationList(); |
| 76 | opList.add(IntentOperation.Operator.ADD, |
| 77 | new ShortestPathIntent(BAD_SWITCH_INTENT_NAME, 111L, 12L, |
| 78 | LOCAL_PORT, 2L, 21L, LOCAL_PORT)); |
| 79 | opList.add(IntentOperation.Operator.ADD, |
| 80 | new ShortestPathIntent("1:2", 1L, 14L, LOCAL_PORT, ipAddress1AsInt, |
| 81 | 4L, 41L, LOCAL_PORT, ipAddress2AsInt)); |
| 82 | opList.add(IntentOperation.Operator.ADD, |
| 83 | new ShortestPathIntent("1:3", 2L, 23L, LOCAL_PORT, ipAddress2AsInt, |
| 84 | 3L, 32L, LOCAL_PORT, ipAddress3AsInt)); |
| 85 | |
| 86 | // compile high-level intent operations into low-level intent |
| 87 | // operations (calculate paths) |
| 88 | |
| 89 | final IntentOperationList pathIntentOpList = |
| 90 | getRuntime().executeIntentOperations(opList); |
| 91 | assertThat(pathIntentOpList, notNullValue()); |
| 92 | |
| 93 | } |
| 94 | |
| 95 | /** |
| 96 | * Find the intent with the given ID in the intent array. |
| 97 | * |
| 98 | * @param intents array of intents |
| 99 | * @param id this is the id too look up |
| 100 | * @return JSONObject for the intent if found, null otherwise |
| 101 | * @throws JSONException if the intent object marshalling fails |
| 102 | */ |
| 103 | private JSONObject findIntent(final JSONArray intents, final String id) |
| 104 | throws JSONException { |
| 105 | |
| 106 | if (id == null) { |
| 107 | return null; |
| 108 | } |
| 109 | |
| 110 | JSONObject result = null; |
| 111 | for (int intentIndex = 0; intentIndex < intents.length(); intentIndex++) { |
| 112 | final JSONObject thisIntent = intents.getJSONObject(intentIndex); |
| 113 | if (id.equals(thisIntent.getString("id"))) { |
| 114 | result = thisIntent; |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | return result; |
| 119 | } |
| 120 | |
| 121 | /** |
| 122 | * Test that the GET of all Intents REST call returns the proper result. |
| 123 | * The call to get all Intents should return 3 items, an HTTP status of OK, |
| 124 | * and the proper Intent data. |
| 125 | * |
| 126 | * @throws Exception to fail the test if any unhandled errors occur |
| 127 | */ |
| 128 | @Test |
| 129 | public void testFetchOfAllLowLevelIntents() throws Exception { |
| 130 | |
| 131 | makeDefaultIntents(); |
| 132 | |
| 133 | final ClientResource client = new ClientResource(getLowRestIntentUrl()); |
| 134 | final JSONArray intents = getJSONArray(client); |
| 135 | assertThat(intents, is(notNullValue())); |
| 136 | |
| 137 | // HTTP status should be OK |
| 138 | assertThat(client, hasStatusOf(Status.SUCCESS_OK)); |
| 139 | |
| 140 | // 2 low level intents should have been fetched - one of the |
| 141 | // high level intents is in error |
| 142 | assertThat(intents.length(), is(equalTo(2))); |
| 143 | |
| 144 | // Check that intent 0 is correct |
| 145 | final JSONObject intent0 = findIntent(intents, "1:2___0"); |
| 146 | assertThat(intent0, is(notNullValue())); |
| 147 | |
| 148 | // Check the values of the fields in low level intent 0 |
| 149 | assertThat(intent0.getString("id"), is(equalTo("1:2___0"))); |
| 150 | assertThat(intent0.getString("state"), is(equalTo("INST_REQ"))); |
| 151 | assertThat(intent0.getBoolean("pathFrozen"), is(equalTo(false))); |
| 152 | |
| 153 | // Check the path on intent 0 |
| 154 | final JSONArray path0 = intent0.getJSONArray("path"); |
| 155 | assertThat(path0, is(notNullValue())); |
| 156 | final JSONObject ports0 = path0.getJSONObject(0); |
| 157 | assertThat(ports0, is(notNullValue())); |
| 158 | final JSONObject dst0 = ports0.getJSONObject("dst"); |
| 159 | assertThat(dst0, is(notNullValue())); |
| 160 | final String dstPortNumber0 = dst0.getString("portNumber"); |
| 161 | assertThat(dstPortNumber0, is(equalTo("41"))); |
| 162 | final JSONObject src0 = ports0.getJSONObject("src"); |
| 163 | assertThat(src0, is(notNullValue())); |
| 164 | final String srcPortNumber0 = src0.getString("portNumber"); |
| 165 | assertThat(srcPortNumber0, is(equalTo("14"))); |
| 166 | |
| 167 | // Check that intent 1 is correct |
| 168 | final JSONObject intent1 = findIntent(intents, "1:3___0"); |
| 169 | assertThat(intent1, is(notNullValue())); |
| 170 | |
| 171 | // Check the values of the fields in low level intent 1 |
| 172 | assertThat(intent1.getString("id"), is(equalTo("1:3___0"))); |
| 173 | assertThat(intent1.getString("state"), is(equalTo("INST_REQ"))); |
| 174 | assertThat(intent1.getBoolean("pathFrozen"), is(equalTo(false))); |
| 175 | |
| 176 | // Check the path on intent 1 |
| 177 | final JSONArray path1 = intent1.getJSONArray("path"); |
| 178 | assertThat(path1, is(notNullValue())); |
| 179 | final JSONObject ports1 = path1.getJSONObject(0); |
| 180 | assertThat(ports1, is(notNullValue())); |
| 181 | final JSONObject dst1 = ports1.getJSONObject("dst"); |
| 182 | assertThat(dst1, is(notNullValue())); |
| 183 | final String dstPortNumber1 = dst1.getString("portNumber"); |
| 184 | assertThat(dstPortNumber1, is(equalTo("32"))); |
| 185 | final JSONObject src1 = ports1.getJSONObject("src"); |
| 186 | assertThat(src1, is(notNullValue())); |
| 187 | final String srcPortNumber1 = src1.getString("portNumber"); |
| 188 | assertThat(srcPortNumber1, is(equalTo("23"))); |
| 189 | } |
| 190 | |
| 191 | /** |
| 192 | * Test that the GET of a single Intent REST call returns the proper result |
| 193 | * when given a bad Intent id. The call to get the Intent should return a |
| 194 | * status of NOT_FOUND. |
| 195 | * |
| 196 | * @throws JSONException if a bad JSON object is returned for the error |
| 197 | */ |
| 198 | @Test |
| 199 | public void testFetchOfBadLowLevelIntent() throws JSONException { |
| 200 | |
| 201 | makeDefaultIntents(); |
| 202 | |
| 203 | final ClientResource client = new ClientResource(getLowRestIntentUrl() + "/2334"); |
| 204 | |
| 205 | try { |
| 206 | client.get(); |
| 207 | // The get operation should have thrown a ResourceException. |
| 208 | // Fail because the Exception was not seen. |
| 209 | Assert.fail("Invalid intent fetch did not cause an exception"); |
| 210 | } catch (ResourceException resourceError) { |
| 211 | // The HTTP status should be NOT FOUND |
| 212 | assertThat(client, hasStatusOf(Status.CLIENT_ERROR_NOT_FOUND)); |
| 213 | |
| 214 | // Check that the error entity is correct |
| 215 | final String responseErrorString = client.getResponse().getEntityAsText(); |
| 216 | final JSONObject responseError = new JSONObject(responseErrorString); |
| 217 | assertThat(responseError.getString("code"), |
| 218 | is(equalTo("INTENT_NOT_FOUND"))); |
| 219 | assertThat(responseError.getString("summary"), |
| 220 | is(equalTo("Intent not found"))); |
| 221 | assertThat(responseError.getString("formattedDescription"), |
| 222 | containsString("An intent with the identifier")); |
| 223 | } |
| 224 | } |
| 225 | |
| 226 | /** |
| 227 | * Test that the GET of a single Low Level Intent REST call returns the |
| 228 | * proper result for an existing Intent. The call to get the Low Level |
| 229 | * Intent should return a status of OK, and the data for the |
| 230 | * Low Level Intent should be correct. |
| 231 | * |
| 232 | * @throws JSONException if the JSON cannot be marshalled into an object. |
| 233 | */ |
| 234 | @Test |
| 235 | public void testFetchOfGoodLowLevelIntent() throws JSONException { |
| 236 | |
| 237 | makeDefaultIntents(); |
| 238 | |
| 239 | final ClientResource client = new ClientResource(getLowRestIntentUrl() + "/3___0"); |
| 240 | final JSONObject intent = getJSONObject(client); |
| 241 | |
| 242 | // HTTP status should be OK |
| 243 | assertThat(client, hasStatusOf(Status.SUCCESS_OK)); |
| 244 | |
| 245 | // Intent data should be correct |
| 246 | assertThat(intent, is(notNullValue())); |
| 247 | |
| 248 | assertThat(intent.getString("id"), is(equalTo("1:3___0"))); |
| 249 | assertThat(intent.getString("state"), is(equalTo("INST_REQ"))); |
| 250 | assertThat(intent.getBoolean("pathFrozen"), is(false)); |
| 251 | } |
| 252 | } |
| 253 | |