blob: 3307d20cd8ec0a65e51f030ce398bc33b99b6f31 [file] [log] [blame]
Ray Milkey2b217142014-12-15 09:24:24 -08001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 Open Networking Laboratory
Ray Milkey2b217142014-12-15 09:24:24 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.rest;
17
Sho SHIMIZUd7d18002015-01-21 14:37:14 -080018import java.util.Collections;
Ray Milkey2b217142014-12-15 09:24:24 -080019import java.util.HashSet;
Ray Milkey2b217142014-12-15 09:24:24 -080020
21import org.hamcrest.Description;
22import org.hamcrest.TypeSafeMatcher;
23import org.junit.After;
24import org.junit.Before;
25import org.junit.Test;
26import org.onlab.osgi.ServiceDirectory;
27import org.onlab.osgi.TestServiceDirectory;
28import org.onlab.rest.BaseResource;
29import org.onosproject.codec.CodecService;
30import org.onosproject.codec.impl.CodecManager;
31import org.onosproject.core.ApplicationId;
Ayaka Koshibec06c89b2015-02-10 19:25:41 -080032import org.onosproject.core.CoreService;
Ray Milkey2b217142014-12-15 09:24:24 -080033import org.onosproject.core.DefaultApplicationId;
34import org.onosproject.core.IdGenerator;
35import org.onosproject.net.NetworkResource;
36import org.onosproject.net.intent.Intent;
Ray Milkey2b217142014-12-15 09:24:24 -080037import org.onosproject.net.intent.IntentService;
Ray Milkeyf9af43c2015-02-09 16:45:48 -080038import org.onosproject.net.intent.Key;
Ray Milkey43a28222015-02-23 13:57:58 -080039import org.onosproject.net.intent.MockIdGenerator;
Ray Milkey2b217142014-12-15 09:24:24 -080040
41import com.eclipsesource.json.JsonArray;
42import com.eclipsesource.json.JsonObject;
43import com.eclipsesource.json.JsonValue;
Ray Milkey2b217142014-12-15 09:24:24 -080044import com.sun.jersey.api.client.UniformInterfaceException;
45import com.sun.jersey.api.client.WebResource;
Ray Milkey2b217142014-12-15 09:24:24 -080046
47import static org.easymock.EasyMock.createMock;
48import static org.easymock.EasyMock.expect;
49import static org.easymock.EasyMock.replay;
50import static org.easymock.EasyMock.verify;
51import static org.hamcrest.Matchers.containsString;
52import static org.hamcrest.Matchers.hasSize;
53import static org.hamcrest.Matchers.is;
54import static org.hamcrest.Matchers.notNullValue;
55import static org.junit.Assert.assertThat;
56import static org.junit.Assert.fail;
Ray Milkey43a28222015-02-23 13:57:58 -080057import static org.onosproject.net.intent.IntentTestsMocks.MockIntent;
Ray Milkey2b217142014-12-15 09:24:24 -080058
59/**
60 * Unit tests for Intents REST APIs.
61 */
Ray Milkey9c3d3362015-01-28 10:39:56 -080062public class IntentsResourceTest extends ResourceTest {
Ray Milkey2b217142014-12-15 09:24:24 -080063 final IntentService mockIntentService = createMock(IntentService.class);
Ayaka Koshibec06c89b2015-02-10 19:25:41 -080064 final CoreService mockCoreService = createMock(CoreService.class);
Ray Milkey2b217142014-12-15 09:24:24 -080065 final HashSet<Intent> intents = new HashSet<>();
Thomas Vachuska02aeb032015-01-06 22:36:30 -080066 private static final ApplicationId APP_ID = new DefaultApplicationId(1, "test");
Ray Milkey2b217142014-12-15 09:24:24 -080067 private IdGenerator mockGenerator;
68
Ray Milkey2b217142014-12-15 09:24:24 -080069 private class MockResource implements NetworkResource {
70 int id;
71
72 MockResource(int id) {
73 this.id = id;
74 }
75
Ayaka Koshibec06c89b2015-02-10 19:25:41 -080076 @Override
Ray Milkey2b217142014-12-15 09:24:24 -080077 public String toString() {
78 return "Resource " + Integer.toString(id);
79 }
80 }
81
Ray Milkey2b217142014-12-15 09:24:24 -080082 /**
83 * Hamcrest matcher to check that an intent representation in JSON matches
84 * the actual intent.
85 */
86 public static class IntentJsonMatcher extends TypeSafeMatcher<JsonObject> {
87 private final Intent intent;
88 private String reason = "";
89
90 public IntentJsonMatcher(Intent intentValue) {
91 intent = intentValue;
92 }
93
94 @Override
95 public boolean matchesSafely(JsonObject jsonIntent) {
96 // check id
97 final String jsonId = jsonIntent.get("id").asString();
98 if (!jsonId.equals(intent.id().toString())) {
99 reason = "id " + intent.id().toString();
100 return false;
101 }
102
103 // check application id
104 final String jsonAppId = jsonIntent.get("appId").asString();
105 if (!jsonAppId.equals(intent.appId().toString())) {
106 reason = "appId " + intent.appId().toString();
107 return false;
108 }
109
110 // check intent type
111 final String jsonType = jsonIntent.get("type").asString();
112 if (!jsonType.equals("MockIntent")) {
113 reason = "type MockIntent";
114 return false;
115 }
116
117 // check details field
118 final String jsonDetails = jsonIntent.get("details").asString();
119 if (!jsonDetails.equals(intent.toString())) {
120 reason = "details " + intent.toString();
121 return false;
122 }
123
124 // check resources array
125 final JsonArray jsonResources = jsonIntent.get("resources").asArray();
126 if (intent.resources() != null) {
127 if (intent.resources().size() != jsonResources.size()) {
128 reason = "resources array size of " + Integer.toString(intent.resources().size());
129 return false;
130 }
131 for (final NetworkResource resource : intent.resources()) {
132 boolean resourceFound = false;
133 final String resourceString = resource.toString();
134 for (int resourceIndex = 0; resourceIndex < jsonResources.size(); resourceIndex++) {
135 final JsonValue value = jsonResources.get(resourceIndex);
136 if (value.asString().equals(resourceString)) {
137 resourceFound = true;
138 }
139 }
140 if (!resourceFound) {
141 reason = "resource " + resourceString;
142 return false;
143 }
144 }
145 } else if (jsonResources.size() != 0) {
146 reason = "resources array empty";
147 return false;
148 }
149 return true;
150 }
151
152 @Override
153 public void describeTo(Description description) {
154 description.appendText(reason);
155 }
156 }
157
158 /**
159 * Factory to allocate an intent matcher.
160 *
161 * @param intent intent object we are looking for
162 * @return matcher
163 */
164 private static IntentJsonMatcher matchesIntent(Intent intent) {
165 return new IntentJsonMatcher(intent);
166 }
167
168 /**
169 * Hamcrest matcher to check that an intent is represented properly in a JSON
170 * array of intents.
171 */
172 public static class IntentJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
173 private final Intent intent;
174 private String reason = "";
175
176 public IntentJsonArrayMatcher(Intent intentValue) {
177 intent = intentValue;
178 }
179
180 @Override
181 public boolean matchesSafely(JsonArray json) {
182 boolean intentFound = false;
183 final int expectedAttributes = 5;
184 for (int jsonIntentIndex = 0; jsonIntentIndex < json.size();
185 jsonIntentIndex++) {
186
187 final JsonObject jsonIntent = json.get(jsonIntentIndex).asObject();
188
189 if (jsonIntent.names().size() != expectedAttributes) {
190 reason = "Found an intent with the wrong number of attributes";
191 return false;
192 }
193
194 final String jsonIntentId = jsonIntent.get("id").asString();
195 if (jsonIntentId.equals(intent.id().toString())) {
196 intentFound = true;
197
198 // We found the correct intent, check attribute values
199 assertThat(jsonIntent, matchesIntent(intent));
200 }
201 }
202 if (!intentFound) {
203 reason = "Intent with id " + intent.id().toString() + " not found";
204 return false;
205 } else {
206 return true;
207 }
208 }
209
210 @Override
211 public void describeTo(Description description) {
212 description.appendText(reason);
213 }
214 }
215
216 /**
217 * Factory to allocate an intent array matcher.
218 *
219 * @param intent intent object we are looking for
220 * @return matcher
221 */
222 private static IntentJsonArrayMatcher hasIntent(Intent intent) {
223 return new IntentJsonArrayMatcher(intent);
224 }
Ray Milkey4f5de002014-12-17 19:26:11 -0800225
Ray Milkeyed0b1662015-02-05 09:34:29 -0800226 /**
227 * Initializes test mocks and environment.
228 */
Ray Milkey2b217142014-12-15 09:24:24 -0800229 @Before
Ray Milkeyed0b1662015-02-05 09:34:29 -0800230 public void setUpTest() {
Ray Milkey2b217142014-12-15 09:24:24 -0800231 expect(mockIntentService.getIntents()).andReturn(intents).anyTimes();
Ray Milkey2b217142014-12-15 09:24:24 -0800232 // Register the services needed for the test
233 final CodecManager codecService = new CodecManager();
234 codecService.activate();
235 ServiceDirectory testDirectory =
236 new TestServiceDirectory()
237 .add(IntentService.class, mockIntentService)
Ayaka Koshibec06c89b2015-02-10 19:25:41 -0800238 .add(CodecService.class, codecService)
239 .add(CoreService.class, mockCoreService);
Ray Milkey2b217142014-12-15 09:24:24 -0800240
241 BaseResource.setServiceDirectory(testDirectory);
242
243 mockGenerator = new MockIdGenerator();
244 Intent.bindIdGenerator(mockGenerator);
245 }
246
Ray Milkeyed0b1662015-02-05 09:34:29 -0800247 /**
248 * Tears down and verifies test mocks and environment.
249 */
Ray Milkey2b217142014-12-15 09:24:24 -0800250 @After
Ray Milkeyed0b1662015-02-05 09:34:29 -0800251 public void tearDownTest() {
Ray Milkey2b217142014-12-15 09:24:24 -0800252 verify(mockIntentService);
253 Intent.unbindIdGenerator(mockGenerator);
254 }
255
256 /**
257 * Tests the result of the rest api GET when there are no intents.
258 */
259 @Test
260 public void testIntentsEmptyArray() {
261 replay(mockIntentService);
262 final WebResource rs = resource();
263 final String response = rs.path("intents").get(String.class);
264 assertThat(response, is("{\"intents\":[]}"));
265 }
266
267 /**
268 * Tests the result of the rest api GET when intents are defined.
269 */
270 @Test
271 public void testIntentsArray() {
272 replay(mockIntentService);
273
Ray Milkey43a28222015-02-23 13:57:58 -0800274 final Intent intent1 = new MockIntent(1L, Collections.emptyList());
Ray Milkey2b217142014-12-15 09:24:24 -0800275 final HashSet<NetworkResource> resources = new HashSet<>();
276 resources.add(new MockResource(1));
277 resources.add(new MockResource(2));
278 resources.add(new MockResource(3));
Ray Milkey43a28222015-02-23 13:57:58 -0800279 final Intent intent2 = new MockIntent(2L, resources);
Ray Milkey2b217142014-12-15 09:24:24 -0800280
281 intents.add(intent1);
282 intents.add(intent2);
283 final WebResource rs = resource();
284 final String response = rs.path("intents").get(String.class);
285 assertThat(response, containsString("{\"intents\":["));
286
287 final JsonObject result = JsonObject.readFrom(response);
288 assertThat(result, notNullValue());
289
290 assertThat(result.names(), hasSize(1));
291 assertThat(result.names().get(0), is("intents"));
292
293 final JsonArray jsonIntents = result.get("intents").asArray();
294 assertThat(jsonIntents, notNullValue());
295
296 assertThat(jsonIntents, hasIntent(intent1));
297 assertThat(jsonIntents, hasIntent(intent2));
298 }
299
300 /**
301 * Tests the result of a rest api GET for a single intent.
302 */
303 @Test
304 public void testIntentsSingle() {
305 final HashSet<NetworkResource> resources = new HashSet<>();
306 resources.add(new MockResource(1));
307 resources.add(new MockResource(2));
308 resources.add(new MockResource(3));
Ray Milkey43a28222015-02-23 13:57:58 -0800309 final Intent intent = new MockIntent(3L, resources);
Ray Milkey2b217142014-12-15 09:24:24 -0800310
311 intents.add(intent);
312
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800313 expect(mockIntentService.getIntent(Key.of(0, APP_ID)))
Ray Milkey2b217142014-12-15 09:24:24 -0800314 .andReturn(intent)
315 .anyTimes();
Ayaka Koshibec06c89b2015-02-10 19:25:41 -0800316 expect(mockIntentService.getIntent(Key.of("0", APP_ID)))
317 .andReturn(intent)
318 .anyTimes();
Ray Milkey2b217142014-12-15 09:24:24 -0800319 replay(mockIntentService);
Ayaka Koshibec06c89b2015-02-10 19:25:41 -0800320 expect(mockCoreService.getAppId(APP_ID.id()))
321 .andReturn(APP_ID).anyTimes();
322 replay(mockCoreService);
Ray Milkey2b217142014-12-15 09:24:24 -0800323 final WebResource rs = resource();
Ayaka Koshibec06c89b2015-02-10 19:25:41 -0800324 final String response = rs.path("intents/1/0").get(String.class);
Ray Milkey2b217142014-12-15 09:24:24 -0800325 final JsonObject result = JsonObject.readFrom(response);
326 assertThat(result, matchesIntent(intent));
327 }
328
329 /**
330 * Tests that a fetch of a non-existent intent object throws an exception.
331 */
332 @Test
333 public void testBadGet() {
334
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800335 expect(mockIntentService.getIntent(Key.of(0, APP_ID)))
Ray Milkey2b217142014-12-15 09:24:24 -0800336 .andReturn(null)
337 .anyTimes();
338 replay(mockIntentService);
339
340 WebResource rs = resource();
341 try {
342 rs.path("intents/0").get(String.class);
343 fail("Fetch of non-existent intent did not throw an exception");
344 } catch (UniformInterfaceException ex) {
345 assertThat(ex.getMessage(),
346 containsString("returned a response status of"));
347 }
348 }
349}