blob: a13c75dcfba27cffb1e8a4f9c2921c78f2a65f5e [file] [log] [blame]
Ray Milkey213e56a2014-06-23 10:45:45 -07001package net.onrc.onos.api.rest;
2
3
4import com.google.common.net.InetAddresses;
5import net.onrc.onos.core.intent.IntentOperation;
6import net.onrc.onos.core.intent.IntentOperationList;
7import net.onrc.onos.core.intent.ShortestPathIntent;
8import net.onrc.onos.core.intent.runtime.PathCalcRuntimeModule;
9import org.json.JSONArray;
10import org.json.JSONException;
11import org.json.JSONObject;
12import org.junit.After;
13import org.junit.Assert;
14import org.junit.Before;
15import org.junit.Test;
16import org.junit.runner.RunWith;
17import org.powermock.core.classloader.annotations.PrepareForTest;
18import org.powermock.modules.junit4.PowerMockRunner;
19import org.restlet.data.Status;
20import org.restlet.resource.ClientResource;
21import org.restlet.resource.ResourceException;
22
23import static net.onrc.onos.api.rest.ClientResourceStatusMatcher.hasStatusOf;
24import static org.hamcrest.MatcherAssert.assertThat;
25import static org.hamcrest.Matchers.containsString;
26import static org.hamcrest.Matchers.equalTo;
27import static org.hamcrest.Matchers.is;
28import 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)
35public 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()));
Pavlin Radoslavov5cf1fe02014-07-03 22:52:25 -0700160 final String dstDpid0 = dst0.getString("dpid");
161 assertThat(dstDpid0, is(equalTo("00:00:00:00:00:00:00:04")));
162 int dstPortNumber0 = dst0.getInt("portNumber");
163 assertThat(dstPortNumber0, is(equalTo(41)));
Ray Milkey213e56a2014-06-23 10:45:45 -0700164 final JSONObject src0 = ports0.getJSONObject("src");
165 assertThat(src0, is(notNullValue()));
Pavlin Radoslavov5cf1fe02014-07-03 22:52:25 -0700166 final String srcDpid0 = src0.getString("dpid");
167 assertThat(srcDpid0, is(equalTo("00:00:00:00:00:00:00:01")));
168 int srcPortNumber0 = src0.getInt("portNumber");
169 assertThat(srcPortNumber0, is(equalTo(14)));
Ray Milkey213e56a2014-06-23 10:45:45 -0700170
171 // Check that intent 1 is correct
172 final JSONObject intent1 = findIntent(intents, "1:3___0");
173 assertThat(intent1, is(notNullValue()));
174
175 // Check the values of the fields in low level intent 1
176 assertThat(intent1.getString("id"), is(equalTo("1:3___0")));
177 assertThat(intent1.getString("state"), is(equalTo("INST_REQ")));
178 assertThat(intent1.getBoolean("pathFrozen"), is(equalTo(false)));
179
180 // Check the path on intent 1
181 final JSONArray path1 = intent1.getJSONArray("path");
182 assertThat(path1, is(notNullValue()));
183 final JSONObject ports1 = path1.getJSONObject(0);
184 assertThat(ports1, is(notNullValue()));
185 final JSONObject dst1 = ports1.getJSONObject("dst");
186 assertThat(dst1, is(notNullValue()));
Pavlin Radoslavov5cf1fe02014-07-03 22:52:25 -0700187 final String dstDpid1 = dst1.getString("dpid");
188 assertThat(dstDpid1, is(equalTo("00:00:00:00:00:00:00:03")));
189 int dstPortNumber1 = dst1.getInt("portNumber");
190 assertThat(dstPortNumber1, is(equalTo(32)));
Ray Milkey213e56a2014-06-23 10:45:45 -0700191 final JSONObject src1 = ports1.getJSONObject("src");
192 assertThat(src1, is(notNullValue()));
Pavlin Radoslavov5cf1fe02014-07-03 22:52:25 -0700193 final String srcDpid1 = src1.getString("dpid");
194 assertThat(srcDpid1, is(equalTo("00:00:00:00:00:00:00:02")));
195 int srcPortNumber1 = src1.getInt("portNumber");
196 assertThat(srcPortNumber1, is(equalTo(23)));
Ray Milkey213e56a2014-06-23 10:45:45 -0700197 }
198
199 /**
200 * Test that the GET of a single Intent REST call returns the proper result
201 * when given a bad Intent id. The call to get the Intent should return a
202 * status of NOT_FOUND.
203 *
204 * @throws JSONException if a bad JSON object is returned for the error
205 */
206 @Test
207 public void testFetchOfBadLowLevelIntent() throws JSONException {
208
209 makeDefaultIntents();
210
211 final ClientResource client = new ClientResource(getLowRestIntentUrl() + "/2334");
212
213 try {
214 client.get();
215 // The get operation should have thrown a ResourceException.
216 // Fail because the Exception was not seen.
217 Assert.fail("Invalid intent fetch did not cause an exception");
218 } catch (ResourceException resourceError) {
219 // The HTTP status should be NOT FOUND
220 assertThat(client, hasStatusOf(Status.CLIENT_ERROR_NOT_FOUND));
221
222 // Check that the error entity is correct
223 final String responseErrorString = client.getResponse().getEntityAsText();
224 final JSONObject responseError = new JSONObject(responseErrorString);
225 assertThat(responseError.getString("code"),
226 is(equalTo("INTENT_NOT_FOUND")));
227 assertThat(responseError.getString("summary"),
228 is(equalTo("Intent not found")));
229 assertThat(responseError.getString("formattedDescription"),
230 containsString("An intent with the identifier"));
231 }
232 }
233
234 /**
235 * Test that the GET of a single Low Level Intent REST call returns the
236 * proper result for an existing Intent. The call to get the Low Level
237 * Intent should return a status of OK, and the data for the
238 * Low Level Intent should be correct.
239 *
240 * @throws JSONException if the JSON cannot be marshalled into an object.
241 */
242 @Test
243 public void testFetchOfGoodLowLevelIntent() throws JSONException {
244
245 makeDefaultIntents();
246
247 final ClientResource client = new ClientResource(getLowRestIntentUrl() + "/3___0");
248 final JSONObject intent = getJSONObject(client);
249
250 // HTTP status should be OK
251 assertThat(client, hasStatusOf(Status.SUCCESS_OK));
252
253 // Intent data should be correct
254 assertThat(intent, is(notNullValue()));
255
256 assertThat(intent.getString("id"), is(equalTo("1:3___0")));
257 assertThat(intent.getString("state"), is(equalTo("INST_REQ")));
258 assertThat(intent.getBoolean("pathFrozen"), is(false));
259 }
260}
261