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