blob: d7c288e1bb99e5b397050515871994ed5d49e79d [file] [log] [blame]
Ray Milkey2b217142014-12-15 09:24:24 -08001/*
2 * Copyright 2014 Open Networking Laboratory
3 *
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
18import java.util.Collection;
Sho SHIMIZUd7d18002015-01-21 14:37:14 -080019import java.util.Collections;
Ray Milkey2b217142014-12-15 09:24:24 -080020import java.util.HashSet;
21import java.util.concurrent.atomic.AtomicLong;
22
23import org.hamcrest.Description;
24import org.hamcrest.TypeSafeMatcher;
25import org.junit.After;
26import org.junit.Before;
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -080027import org.junit.Ignore;
Ray Milkey2b217142014-12-15 09:24:24 -080028import org.junit.Test;
29import org.onlab.osgi.ServiceDirectory;
30import org.onlab.osgi.TestServiceDirectory;
31import org.onlab.rest.BaseResource;
32import org.onosproject.codec.CodecService;
33import org.onosproject.codec.impl.CodecManager;
34import org.onosproject.core.ApplicationId;
35import org.onosproject.core.DefaultApplicationId;
36import org.onosproject.core.IdGenerator;
37import org.onosproject.net.NetworkResource;
38import org.onosproject.net.intent.Intent;
Ray Milkey2b217142014-12-15 09:24:24 -080039import org.onosproject.net.intent.IntentService;
Ray Milkeyf9af43c2015-02-09 16:45:48 -080040import org.onosproject.net.intent.Key;
Ray Milkey2b217142014-12-15 09:24:24 -080041
42import com.eclipsesource.json.JsonArray;
43import com.eclipsesource.json.JsonObject;
44import com.eclipsesource.json.JsonValue;
45import com.google.common.base.MoreObjects;
46import com.sun.jersey.api.client.UniformInterfaceException;
47import com.sun.jersey.api.client.WebResource;
Ray Milkey2b217142014-12-15 09:24:24 -080048
49import static org.easymock.EasyMock.createMock;
50import static org.easymock.EasyMock.expect;
51import static org.easymock.EasyMock.replay;
52import static org.easymock.EasyMock.verify;
53import static org.hamcrest.Matchers.containsString;
54import static org.hamcrest.Matchers.hasSize;
55import static org.hamcrest.Matchers.is;
56import static org.hamcrest.Matchers.notNullValue;
57import static org.junit.Assert.assertThat;
58import static org.junit.Assert.fail;
59
60/**
61 * Unit tests for Intents REST APIs.
62 */
Jonathan Hart4fd4ebb2015-02-04 17:38:48 -080063@Ignore
Ray Milkey9c3d3362015-01-28 10:39:56 -080064public class IntentsResourceTest extends ResourceTest {
Ray Milkey2b217142014-12-15 09:24:24 -080065 final IntentService mockIntentService = createMock(IntentService.class);
66 final HashSet<Intent> intents = new HashSet<>();
Thomas Vachuska02aeb032015-01-06 22:36:30 -080067 private static final ApplicationId APP_ID = new DefaultApplicationId(1, "test");
Ray Milkey2b217142014-12-15 09:24:24 -080068 private IdGenerator mockGenerator;
69
70 /**
71 * Mock ID generator. This should be refactored to share the one in
72 * the core/api tests.
73 */
74 public class MockIdGenerator implements IdGenerator {
75 private AtomicLong nextId = new AtomicLong(0);
76
77 @Override
78 public long getNewId() {
79 return nextId.getAndIncrement();
80 }
81 }
82
83 /**
84 * Mock compilable intent class.
85 */
86 private static class MockIntent extends Intent {
87
88 public MockIntent(Collection<NetworkResource> resources) {
89 super(APP_ID, resources);
90 }
91
92 @Override
93 public String toString() {
94 return MoreObjects.toStringHelper(getClass())
95 .add("id", id())
96 .add("appId", appId())
97 .toString();
98 }
99 }
100
101 private class MockResource implements NetworkResource {
102 int id;
103
104 MockResource(int id) {
105 this.id = id;
106 }
107
108 public String toString() {
109 return "Resource " + Integer.toString(id);
110 }
111 }
112
Ray Milkey2b217142014-12-15 09:24:24 -0800113 /**
114 * Hamcrest matcher to check that an intent representation in JSON matches
115 * the actual intent.
116 */
117 public static class IntentJsonMatcher extends TypeSafeMatcher<JsonObject> {
118 private final Intent intent;
119 private String reason = "";
120
121 public IntentJsonMatcher(Intent intentValue) {
122 intent = intentValue;
123 }
124
125 @Override
126 public boolean matchesSafely(JsonObject jsonIntent) {
127 // check id
128 final String jsonId = jsonIntent.get("id").asString();
129 if (!jsonId.equals(intent.id().toString())) {
130 reason = "id " + intent.id().toString();
131 return false;
132 }
133
134 // check application id
135 final String jsonAppId = jsonIntent.get("appId").asString();
136 if (!jsonAppId.equals(intent.appId().toString())) {
137 reason = "appId " + intent.appId().toString();
138 return false;
139 }
140
141 // check intent type
142 final String jsonType = jsonIntent.get("type").asString();
143 if (!jsonType.equals("MockIntent")) {
144 reason = "type MockIntent";
145 return false;
146 }
147
148 // check details field
149 final String jsonDetails = jsonIntent.get("details").asString();
150 if (!jsonDetails.equals(intent.toString())) {
151 reason = "details " + intent.toString();
152 return false;
153 }
154
155 // check resources array
156 final JsonArray jsonResources = jsonIntent.get("resources").asArray();
157 if (intent.resources() != null) {
158 if (intent.resources().size() != jsonResources.size()) {
159 reason = "resources array size of " + Integer.toString(intent.resources().size());
160 return false;
161 }
162 for (final NetworkResource resource : intent.resources()) {
163 boolean resourceFound = false;
164 final String resourceString = resource.toString();
165 for (int resourceIndex = 0; resourceIndex < jsonResources.size(); resourceIndex++) {
166 final JsonValue value = jsonResources.get(resourceIndex);
167 if (value.asString().equals(resourceString)) {
168 resourceFound = true;
169 }
170 }
171 if (!resourceFound) {
172 reason = "resource " + resourceString;
173 return false;
174 }
175 }
176 } else if (jsonResources.size() != 0) {
177 reason = "resources array empty";
178 return false;
179 }
180 return true;
181 }
182
183 @Override
184 public void describeTo(Description description) {
185 description.appendText(reason);
186 }
187 }
188
189 /**
190 * Factory to allocate an intent matcher.
191 *
192 * @param intent intent object we are looking for
193 * @return matcher
194 */
195 private static IntentJsonMatcher matchesIntent(Intent intent) {
196 return new IntentJsonMatcher(intent);
197 }
198
199 /**
200 * Hamcrest matcher to check that an intent is represented properly in a JSON
201 * array of intents.
202 */
203 public static class IntentJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
204 private final Intent intent;
205 private String reason = "";
206
207 public IntentJsonArrayMatcher(Intent intentValue) {
208 intent = intentValue;
209 }
210
211 @Override
212 public boolean matchesSafely(JsonArray json) {
213 boolean intentFound = false;
214 final int expectedAttributes = 5;
215 for (int jsonIntentIndex = 0; jsonIntentIndex < json.size();
216 jsonIntentIndex++) {
217
218 final JsonObject jsonIntent = json.get(jsonIntentIndex).asObject();
219
220 if (jsonIntent.names().size() != expectedAttributes) {
221 reason = "Found an intent with the wrong number of attributes";
222 return false;
223 }
224
225 final String jsonIntentId = jsonIntent.get("id").asString();
226 if (jsonIntentId.equals(intent.id().toString())) {
227 intentFound = true;
228
229 // We found the correct intent, check attribute values
230 assertThat(jsonIntent, matchesIntent(intent));
231 }
232 }
233 if (!intentFound) {
234 reason = "Intent with id " + intent.id().toString() + " not found";
235 return false;
236 } else {
237 return true;
238 }
239 }
240
241 @Override
242 public void describeTo(Description description) {
243 description.appendText(reason);
244 }
245 }
246
247 /**
248 * Factory to allocate an intent array matcher.
249 *
250 * @param intent intent object we are looking for
251 * @return matcher
252 */
253 private static IntentJsonArrayMatcher hasIntent(Intent intent) {
254 return new IntentJsonArrayMatcher(intent);
255 }
Ray Milkey4f5de002014-12-17 19:26:11 -0800256
Ray Milkeyed0b1662015-02-05 09:34:29 -0800257 /**
258 * Initializes test mocks and environment.
259 */
Ray Milkey2b217142014-12-15 09:24:24 -0800260 @Before
Ray Milkeyed0b1662015-02-05 09:34:29 -0800261 public void setUpTest() {
Ray Milkey2b217142014-12-15 09:24:24 -0800262 expect(mockIntentService.getIntents()).andReturn(intents).anyTimes();
263
264 // Register the services needed for the test
265 final CodecManager codecService = new CodecManager();
266 codecService.activate();
267 ServiceDirectory testDirectory =
268 new TestServiceDirectory()
269 .add(IntentService.class, mockIntentService)
270 .add(CodecService.class, codecService);
271
272 BaseResource.setServiceDirectory(testDirectory);
273
274 mockGenerator = new MockIdGenerator();
275 Intent.bindIdGenerator(mockGenerator);
276 }
277
Ray Milkeyed0b1662015-02-05 09:34:29 -0800278 /**
279 * Tears down and verifies test mocks and environment.
280 */
Ray Milkey2b217142014-12-15 09:24:24 -0800281 @After
Ray Milkeyed0b1662015-02-05 09:34:29 -0800282 public void tearDownTest() {
Ray Milkey2b217142014-12-15 09:24:24 -0800283 verify(mockIntentService);
284 Intent.unbindIdGenerator(mockGenerator);
285 }
286
287 /**
288 * Tests the result of the rest api GET when there are no intents.
289 */
290 @Test
291 public void testIntentsEmptyArray() {
292 replay(mockIntentService);
293 final WebResource rs = resource();
294 final String response = rs.path("intents").get(String.class);
295 assertThat(response, is("{\"intents\":[]}"));
296 }
297
298 /**
299 * Tests the result of the rest api GET when intents are defined.
300 */
301 @Test
302 public void testIntentsArray() {
303 replay(mockIntentService);
304
Sho SHIMIZUd7d18002015-01-21 14:37:14 -0800305 final Intent intent1 = new MockIntent(Collections.emptyList());
Ray Milkey2b217142014-12-15 09:24:24 -0800306 final HashSet<NetworkResource> resources = new HashSet<>();
307 resources.add(new MockResource(1));
308 resources.add(new MockResource(2));
309 resources.add(new MockResource(3));
310 final Intent intent2 = new MockIntent(resources);
311
312 intents.add(intent1);
313 intents.add(intent2);
314 final WebResource rs = resource();
315 final String response = rs.path("intents").get(String.class);
316 assertThat(response, containsString("{\"intents\":["));
317
318 final JsonObject result = JsonObject.readFrom(response);
319 assertThat(result, notNullValue());
320
321 assertThat(result.names(), hasSize(1));
322 assertThat(result.names().get(0), is("intents"));
323
324 final JsonArray jsonIntents = result.get("intents").asArray();
325 assertThat(jsonIntents, notNullValue());
326
327 assertThat(jsonIntents, hasIntent(intent1));
328 assertThat(jsonIntents, hasIntent(intent2));
329 }
330
331 /**
332 * Tests the result of a rest api GET for a single intent.
333 */
334 @Test
335 public void testIntentsSingle() {
336 final HashSet<NetworkResource> resources = new HashSet<>();
337 resources.add(new MockResource(1));
338 resources.add(new MockResource(2));
339 resources.add(new MockResource(3));
340 final Intent intent = new MockIntent(resources);
341
342 intents.add(intent);
343
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800344 expect(mockIntentService.getIntent(Key.of(0, APP_ID)))
Ray Milkey2b217142014-12-15 09:24:24 -0800345 .andReturn(intent)
346 .anyTimes();
347 replay(mockIntentService);
348
349 final WebResource rs = resource();
350 final String response = rs.path("intents/0").get(String.class);
351 final JsonObject result = JsonObject.readFrom(response);
352 assertThat(result, matchesIntent(intent));
353 }
354
355 /**
356 * Tests that a fetch of a non-existent intent object throws an exception.
357 */
358 @Test
359 public void testBadGet() {
360
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800361 expect(mockIntentService.getIntent(Key.of(0, APP_ID)))
Ray Milkey2b217142014-12-15 09:24:24 -0800362 .andReturn(null)
363 .anyTimes();
364 replay(mockIntentService);
365
366 WebResource rs = resource();
367 try {
368 rs.path("intents/0").get(String.class);
369 fail("Fetch of non-existent intent did not throw an exception");
370 } catch (UniformInterfaceException ex) {
371 assertThat(ex.getMessage(),
372 containsString("returned a response status of"));
373 }
374 }
375}