blob: eeac8867738a139a3da660c9033237fc9766e86e [file] [log] [blame]
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.rest;
import com.eclipsesource.json.Json;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.sun.jersey.api.client.WebResource;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.osgi.TestServiceDirectory;
import org.onlab.rest.BaseResource;
import org.onosproject.app.ApplicationAdminService;
import org.onosproject.app.ApplicationService;
import org.onosproject.app.ApplicationState;
import org.onosproject.codec.CodecService;
import org.onosproject.codec.impl.ApplicationCodec;
import org.onosproject.codec.impl.CodecManager;
import org.onosproject.codec.impl.MockCodecContext;
import org.onosproject.core.Application;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.ApplicationRole;
import org.onosproject.core.DefaultApplication;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.core.Version;
import java.io.InputStream;
import java.net.URI;
import java.util.Optional;
import static org.easymock.EasyMock.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
/**
* Unit tests for applications REST APIs.
*/
public class ApplicationsResourceTest extends ResourceTest {
private static class MockCodecContextWithService extends MockCodecContext {
private ApplicationAdminService service;
MockCodecContextWithService(ApplicationAdminService service) {
this.service = service;
}
@Override
@SuppressWarnings("unchecked")
public <T> T getService(Class<T> serviceClass) {
return (T) service;
}
}
private ApplicationAdminService service;
private ApplicationId id1 = new DefaultApplicationId(1, "app1");
private ApplicationId id2 = new DefaultApplicationId(2, "app2");
private ApplicationId id3 = new DefaultApplicationId(3, "app3");
private ApplicationId id4 = new DefaultApplicationId(4, "app4");
private static final URI FURL = URI.create("mvn:org.foo-features/1.2a/xml/features");
private static final Version VER = Version.version(1, 2, "a", null);
private Application app1 =
new DefaultApplication(id1, VER,
"app1", "origin1", ApplicationRole.ADMIN, ImmutableSet.of(), Optional.of(FURL),
ImmutableList.of("My Feature"), ImmutableList.of());
private Application app2 =
new DefaultApplication(id2, VER,
"app2", "origin2", ApplicationRole.ADMIN, ImmutableSet.of(), Optional.of(FURL),
ImmutableList.of("My Feature"), ImmutableList.of());
private Application app3 =
new DefaultApplication(id3, VER,
"app3", "origin3", ApplicationRole.ADMIN, ImmutableSet.of(), Optional.of(FURL),
ImmutableList.of("My Feature"), ImmutableList.of());
private Application app4 =
new DefaultApplication(id4, VER,
"app4", "origin4", ApplicationRole.ADMIN, ImmutableSet.of(), Optional.of(FURL),
ImmutableList.of("My Feature"), ImmutableList.of());
/**
* Hamcrest matcher to check that an application representation in JSON matches
* the actual device.
*/
private static class AppJsonMatcher extends TypeSafeMatcher<JsonObject> {
private final Application app;
private String reason = "";
public AppJsonMatcher(Application appValue) {
app = appValue;
}
@Override
public boolean matchesSafely(JsonObject jsonApp) {
// check id
short jsonId = (short) jsonApp.get("id").asInt();
if (jsonId != app.id().id()) {
reason = "id " + app.id().id();
return false;
}
// check name
String jsonName = jsonApp.get("name").asString();
if (!jsonName.equals(app.id().name())) {
reason = "name " + app.id().name();
return false;
}
// check origin
String jsonOrigin = jsonApp.get("origin").asString();
if (!jsonOrigin.equals(app.origin())) {
reason = "manufacturer " + app.origin();
return false;
}
return true;
}
@Override
public void describeTo(Description description) {
description.appendText(reason);
}
}
/**
* Factory to allocate an application matcher.
*
* @param app application object we are looking for
* @return matcher
*/
private static AppJsonMatcher matchesApp(Application app) {
return new AppJsonMatcher(app);
}
/**
* Initializes test mocks and environment.
*/
@Before
public void setUpMocks() {
service = createMock(ApplicationAdminService.class);
expect(service.getId("one"))
.andReturn(id1)
.anyTimes();
expect(service.getId("two"))
.andReturn(id2)
.anyTimes();
expect(service.getId("three"))
.andReturn(id3)
.anyTimes();
expect(service.getId("four"))
.andReturn(id4)
.anyTimes();
expect(service.getApplication(id3))
.andReturn(app3)
.anyTimes();
expect(service.getState(isA(ApplicationId.class)))
.andReturn(ApplicationState.ACTIVE)
.anyTimes();
// Register the services needed for the test
CodecManager codecService = new CodecManager();
codecService.activate();
ServiceDirectory testDirectory =
new TestServiceDirectory()
.add(ApplicationAdminService.class, service)
.add(ApplicationService.class, service)
.add(CodecService.class, codecService);
BaseResource.setServiceDirectory(testDirectory);
}
/**
* Verifies test mocks.
*/
@After
public void tearDownMocks() {
verify(service);
}
/**
* Tests a GET of all applications when no applications are present.
*/
@Test
public void getAllApplicationsEmpty() {
expect(service.getApplications())
.andReturn(ImmutableSet.of());
replay(service);
WebResource rs = resource();
String response = rs.path("applications").get(String.class);
assertThat(response, is("{\"applications\":[]}"));
}
/**
* Tests a GET of all applications with data.
*/
@Test
public void getAllApplicationsPopulated() {
expect(service.getApplications())
.andReturn(ImmutableSet.of(app1, app2, app3, app4));
replay(service);
WebResource rs = resource();
String response = rs.path("applications").get(String.class);
assertThat(response, containsString("{\"applications\":["));
JsonObject result = Json.parse(response).asObject();
assertThat(result, notNullValue());
assertThat(result.names(), hasSize(1));
assertThat(result.names().get(0), is("applications"));
JsonArray jsonApps = result.get("applications").asArray();
assertThat(jsonApps, notNullValue());
assertThat(jsonApps.size(), is(4));
assertThat(jsonApps.get(0).asObject(), matchesApp(app1));
assertThat(jsonApps.get(1).asObject(), matchesApp(app2));
assertThat(jsonApps.get(2).asObject(), matchesApp(app3));
assertThat(jsonApps.get(3).asObject(), matchesApp(app4));
}
/**
* Tests a GET of a single application.
*/
@Test
public void getSingleApplication() {
replay(service);
WebResource rs = resource();
String response = rs.path("applications/three").get(String.class);
JsonObject result = Json.parse(response).asObject();
assertThat(result, notNullValue());
assertThat(result, matchesApp(app3));
}
/**
* Tests a DELETE of a single application - this should
* attempt to uninstall it.
*/
@Test
public void deleteApplication() {
service.uninstall(id3);
expectLastCall();
replay(service);
WebResource rs = resource();
rs.path("applications/three").delete();
}
/**
* Tests a DELETE of a single active application - this should
* attempt to uninstall it.
*/
@Test
public void deleteActiveApplication() {
service.deactivate(id3);
expectLastCall();
replay(service);
WebResource rs = resource();
rs.path("applications/three/active").delete();
}
/**
* Tests a POST operation to the "active" URL. This should attempt to
* activate the application.
*/
@Test
public void postActiveApplication() {
service.activate(id3);
expectLastCall();
replay(service);
WebResource rs = resource();
rs.path("applications/three/active").post();
}
/**
* Tests a POST operation. This should attempt to
* install the application.
*/
@Test
public void postApplication() {
expect(service.install(isA(InputStream.class)))
.andReturn(app4)
.once();
replay(service);
ApplicationCodec codec = new ApplicationCodec();
String app4Json = codec.encode(app4,
new MockCodecContextWithService(service))
.asText();
WebResource rs = resource();
String response = rs.path("applications").post(String.class, app4Json);
JsonObject result = Json.parse(response).asObject();
assertThat(result, notNullValue());
assertThat(result, matchesApp(app4));
}
}