blob: 81db63197302320300292a7e8412c64e4dd47f2d [file] [log] [blame]
Ray Milkeyf195b022015-02-03 15:13:11 -08001/*
2 * Copyright 2015 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
Thomas Vachuskaebf5e542015-02-03 19:38:13 -080018import com.eclipsesource.json.JsonArray;
19import com.eclipsesource.json.JsonObject;
20import com.google.common.collect.ImmutableList;
21import com.google.common.collect.ImmutableSet;
22import com.sun.jersey.api.client.WebResource;
Ray Milkeyf195b022015-02-03 15:13:11 -080023import org.hamcrest.Description;
24import org.hamcrest.TypeSafeMatcher;
25import org.junit.After;
26import org.junit.Before;
27import org.junit.Test;
28import org.onlab.osgi.ServiceDirectory;
29import org.onlab.osgi.TestServiceDirectory;
30import org.onlab.rest.BaseResource;
31import org.onosproject.app.ApplicationAdminService;
32import org.onosproject.app.ApplicationService;
33import org.onosproject.app.ApplicationState;
34import org.onosproject.codec.CodecService;
35import org.onosproject.codec.impl.ApplicationCodec;
36import org.onosproject.codec.impl.CodecManager;
37import org.onosproject.codec.impl.MockCodecContext;
38import org.onosproject.core.Application;
39import org.onosproject.core.ApplicationId;
40import org.onosproject.core.DefaultApplication;
41import org.onosproject.core.DefaultApplicationId;
42import org.onosproject.core.Version;
43
Thomas Vachuskaebf5e542015-02-03 19:38:13 -080044import java.io.InputStream;
45import java.net.URI;
46import java.util.Optional;
Ray Milkeyf195b022015-02-03 15:13:11 -080047
Thomas Vachuskaebf5e542015-02-03 19:38:13 -080048import static org.easymock.EasyMock.*;
Ray Milkeyf195b022015-02-03 15:13:11 -080049import static org.hamcrest.MatcherAssert.assertThat;
Yuta HIGUCHI293ede02015-02-05 00:08:41 -080050import static org.hamcrest.Matchers.containsString;
51import static org.hamcrest.Matchers.hasSize;
52import static org.hamcrest.Matchers.is;
53import static org.hamcrest.Matchers.notNullValue;
Ray Milkeyf195b022015-02-03 15:13:11 -080054
55/**
56 * Unit tests for applications REST APIs.
57 */
58
59public class ApplicationsResourceTest extends ResourceTest {
60
61 private static class MockCodecContextWithService extends MockCodecContext {
62 private ApplicationAdminService service;
63
64 MockCodecContextWithService(ApplicationAdminService service) {
65 this.service = service;
66 }
67
68 @Override
69 @SuppressWarnings("unchecked")
70 public <T> T get(Class<T> serviceClass) {
71 return (T) service;
72 }
73 }
74
75 private ApplicationAdminService service;
76 private ApplicationId id1 = new DefaultApplicationId(1, "app1");
77 private ApplicationId id2 = new DefaultApplicationId(2, "app2");
78 private ApplicationId id3 = new DefaultApplicationId(3, "app3");
79 private ApplicationId id4 = new DefaultApplicationId(4, "app4");
80
81 private static final URI FURL = URI.create("mvn:org.foo-features/1.2a/xml/features");
82 private static final Version VER = Version.version(1, 2, "a", null);
83
84 private Application app1 =
85 new DefaultApplication(id1, VER,
Thomas Vachuskaebf5e542015-02-03 19:38:13 -080086 "app1", "origin1", ImmutableSet.of(), Optional.of(FURL),
87 ImmutableList.of("My Feature"));
Ray Milkeyf195b022015-02-03 15:13:11 -080088 private Application app2 =
89 new DefaultApplication(id2, VER,
Thomas Vachuskaebf5e542015-02-03 19:38:13 -080090 "app2", "origin2", ImmutableSet.of(), Optional.of(FURL),
91 ImmutableList.of("My Feature"));
Ray Milkeyf195b022015-02-03 15:13:11 -080092 private Application app3 =
93 new DefaultApplication(id3, VER,
Thomas Vachuskaebf5e542015-02-03 19:38:13 -080094 "app3", "origin3", ImmutableSet.of(), Optional.of(FURL),
95 ImmutableList.of("My Feature"));
Ray Milkeyf195b022015-02-03 15:13:11 -080096 private Application app4 =
97 new DefaultApplication(id4, VER,
Thomas Vachuskaebf5e542015-02-03 19:38:13 -080098 "app4", "origin4", ImmutableSet.of(), Optional.of(FURL),
99 ImmutableList.of("My Feature"));
Ray Milkeyf195b022015-02-03 15:13:11 -0800100
101 /**
Ray Milkeyed0b1662015-02-05 09:34:29 -0800102 * Hamcrest matcher to check that an application representation in JSON matches
Ray Milkeyf195b022015-02-03 15:13:11 -0800103 * the actual device.
104 */
105 private static class AppJsonMatcher extends TypeSafeMatcher<JsonObject> {
106 private final Application app;
107 private String reason = "";
108
109 public AppJsonMatcher(Application appValue) {
110 app = appValue;
111 }
112
113 @Override
114 public boolean matchesSafely(JsonObject jsonApp) {
115 // check id
116 short jsonId = (short) jsonApp.get("id").asInt();
117 if (jsonId != app.id().id()) {
118 reason = "id " + app.id().id();
119 return false;
120 }
121
122 // check name
123 String jsonName = jsonApp.get("name").asString();
124 if (!jsonName.equals(app.id().name())) {
125 reason = "name " + app.id().name();
126 return false;
127 }
128
129 // check origin
130 String jsonOrigin = jsonApp.get("origin").asString();
131 if (!jsonOrigin.equals(app.origin())) {
132 reason = "manufacturer " + app.origin();
133 return false;
134 }
135
136 return true;
137 }
138
139 @Override
140 public void describeTo(Description description) {
141 description.appendText(reason);
142 }
143 }
144
145 /**
Ray Milkeyed0b1662015-02-05 09:34:29 -0800146 * Factory to allocate an application matcher.
Ray Milkeyf195b022015-02-03 15:13:11 -0800147 *
148 * @param app application object we are looking for
149 * @return matcher
150 */
151 private static AppJsonMatcher matchesApp(Application app) {
152 return new AppJsonMatcher(app);
153 }
154
Ray Milkeyed0b1662015-02-05 09:34:29 -0800155 /**
156 * Initializes test mocks and environment.
157 */
Ray Milkeyf195b022015-02-03 15:13:11 -0800158 @Before
Ray Milkeyed0b1662015-02-05 09:34:29 -0800159 public void setUpMocks() {
Ray Milkeyf195b022015-02-03 15:13:11 -0800160 service = createMock(ApplicationAdminService.class);
161
162 expect(service.getId("one"))
163 .andReturn(id1)
164 .anyTimes();
165 expect(service.getId("two"))
166 .andReturn(id2)
167 .anyTimes();
168 expect(service.getId("three"))
169 .andReturn(id3)
170 .anyTimes();
171 expect(service.getId("four"))
172 .andReturn(id4)
173 .anyTimes();
174
175 expect(service.getApplication(id3))
176 .andReturn(app3)
177 .anyTimes();
178 expect(service.getState(isA(ApplicationId.class)))
179 .andReturn(ApplicationState.ACTIVE)
180 .anyTimes();
181
182 // Register the services needed for the test
183 CodecManager codecService = new CodecManager();
184 codecService.activate();
185 ServiceDirectory testDirectory =
186 new TestServiceDirectory()
187 .add(ApplicationAdminService.class, service)
188 .add(ApplicationService.class, service)
189 .add(CodecService.class, codecService);
190
191 BaseResource.setServiceDirectory(testDirectory);
192 }
193
Ray Milkeyed0b1662015-02-05 09:34:29 -0800194 /**
195 * Verifies test mocks.
196 */
Ray Milkeyf195b022015-02-03 15:13:11 -0800197 @After
Ray Milkeyed0b1662015-02-05 09:34:29 -0800198 public void tearDownMocks() {
Ray Milkeyf195b022015-02-03 15:13:11 -0800199 verify(service);
200 }
201
202 /**
203 * Tests a GET of all applications when no applications are present.
204 */
205 @Test
206 public void getAllApplicationsEmpty() {
207 expect(service.getApplications())
208 .andReturn(ImmutableSet.of());
209 replay(service);
210
211 WebResource rs = resource();
212 String response = rs.path("applications").get(String.class);
213 assertThat(response, is("{\"applications\":[]}"));
214 }
215
216 /**
217 * Tests a GET of all applications with data.
218 */
219 @Test
220 public void getAllApplicationsPopulated() {
221 expect(service.getApplications())
222 .andReturn(ImmutableSet.of(app1, app2, app3, app4));
223 replay(service);
224
225 WebResource rs = resource();
226 String response = rs.path("applications").get(String.class);
227 assertThat(response, containsString("{\"applications\":["));
228
229 JsonObject result = JsonObject.readFrom(response);
230 assertThat(result, notNullValue());
231
232 assertThat(result.names(), hasSize(1));
233 assertThat(result.names().get(0), is("applications"));
234
235 JsonArray jsonApps = result.get("applications").asArray();
236 assertThat(jsonApps, notNullValue());
237 assertThat(jsonApps.size(), is(4));
238
239 assertThat(jsonApps.get(0).asObject(), matchesApp(app1));
240 assertThat(jsonApps.get(1).asObject(), matchesApp(app2));
241 assertThat(jsonApps.get(2).asObject(), matchesApp(app3));
242 assertThat(jsonApps.get(3).asObject(), matchesApp(app4));
243 }
244
245 /**
246 * Tests a GET of a single application.
247 */
248 @Test
249 public void getSingleApplication() {
250 replay(service);
251
252 WebResource rs = resource();
253 String response = rs.path("applications/three").get(String.class);
254
255 JsonObject result = JsonObject.readFrom(response);
256 assertThat(result, notNullValue());
257
258 assertThat(result, matchesApp(app3));
259 }
260
261 /**
262 * Tests a DELETE of a single application - this should
263 * attempt to uninstall it.
264 */
265 @Test
266 public void deleteApplication() {
267 service.uninstall(id3);
268 expectLastCall();
269
270 replay(service);
271
272 WebResource rs = resource();
273 rs.path("applications/three").delete();
274 }
275
276 /**
277 * Tests a DELETE of a single active application - this should
278 * attempt to uninstall it.
279 */
280 @Test
281 public void deleteActiveApplication() {
282 service.deactivate(id3);
283 expectLastCall();
284
285 replay(service);
286
287 WebResource rs = resource();
288 rs.path("applications/three/active").delete();
289 }
290
291 /**
292 * Tests a POST operation to the "active" URL. This should attempt to
293 * activate the application.
294 */
295 @Test
296 public void postActiveApplication() {
297 service.activate(id3);
298 expectLastCall();
299
300 replay(service);
301
302 WebResource rs = resource();
303 rs.path("applications/three/active").post();
304 }
305
306 /**
307 * Tests a POST operation. This should attempt to
308 * install the application.
309 */
310 @Test
311 public void postApplication() {
312 expect(service.install(isA(InputStream.class)))
313 .andReturn(app4)
314 .once();
315
316 replay(service);
317
318 ApplicationCodec codec = new ApplicationCodec();
319 String app4Json = codec.encode(app4,
320 new MockCodecContextWithService(service))
321 .asText();
322
323 WebResource rs = resource();
324 String response = rs.path("applications").post(String.class, app4Json);
325
326 JsonObject result = JsonObject.readFrom(response);
327 assertThat(result, notNullValue());
328
329 assertThat(result, matchesApp(app4));
330 }
331}