blob: 86beb1bcbe238b9eb6d0293cab684958f09b6ab0 [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()));
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