Move all REST test related files into org.onosproject.rest.resources
Move all REST test case classes under org.onosproject.rest.resources
package in a way to improve naming consistency.
Change-Id: I0a154fe492b90aa426e6af38a3c08d7c1ee8d031
diff --git a/web/api/src/test/java/org/onosproject/rest/resources/RegionsResourceTest.java b/web/api/src/test/java/org/onosproject/rest/resources/RegionsResourceTest.java
new file mode 100644
index 0000000..fdc69a1
--- /dev/null
+++ b/web/api/src/test/java/org/onosproject/rest/resources/RegionsResourceTest.java
@@ -0,0 +1,467 @@
+/*
+ * Copyright 2016 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.resources;
+
+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.google.common.collect.Sets;
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
+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.cluster.NodeId;
+import org.onosproject.codec.CodecService;
+import org.onosproject.codec.impl.CodecManager;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.region.Region;
+import org.onosproject.net.region.RegionAdminService;
+import org.onosproject.net.region.RegionId;
+import org.onosproject.net.region.RegionService;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.util.List;
+import java.util.Set;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Unit tests for region REST APIs.
+ */
+public class RegionsResourceTest extends ResourceTest {
+
+ final RegionService mockRegionService = createMock(RegionService.class);
+ final RegionAdminService mockRegionAdminService = createMock(RegionAdminService.class);
+
+ final RegionId regionId1 = RegionId.regionId("1");
+ final RegionId regionId2 = RegionId.regionId("2");
+ final RegionId regionId3 = RegionId.regionId("3");
+
+ final MockRegion region1 = new MockRegion(regionId1, "r1", Region.Type.RACK);
+ final MockRegion region2 = new MockRegion(regionId2, "r2", Region.Type.ROOM);
+ final MockRegion region3 = new MockRegion(regionId3, "r3", Region.Type.CAMPUS);
+
+ /**
+ * Mock class for a region.
+ */
+ private static class MockRegion implements Region {
+
+ private final RegionId id;
+ private final String name;
+ private final Type type;
+ private final List<Set<NodeId>> masters;
+
+ public MockRegion(RegionId id, String name, Type type) {
+ this.id = id;
+ this.name = name;
+ this.type = type;
+
+ final NodeId nodeId1 = NodeId.nodeId("1");
+ final NodeId nodeId2 = NodeId.nodeId("2");
+ final NodeId nodeId3 = NodeId.nodeId("3");
+ final NodeId nodeId4 = NodeId.nodeId("4");
+
+ Set<NodeId> nodeIds1 = ImmutableSet.of(nodeId1);
+ Set<NodeId> nodeIds2 = ImmutableSet.of(nodeId1, nodeId2);
+ Set<NodeId> nodeIds3 = ImmutableSet.of(nodeId1, nodeId2, nodeId3);
+ Set<NodeId> nodeIds4 = ImmutableSet.of(nodeId1, nodeId2, nodeId3, nodeId4);
+
+ this.masters = ImmutableList.of(nodeIds1, nodeIds2, nodeIds3, nodeIds4);
+ }
+
+ @Override
+ public RegionId id() {
+ return this.id;
+ }
+
+ @Override
+ public String name() {
+ return this.name;
+ }
+
+ @Override
+ public Type type() {
+ return this.type;
+ }
+
+ @Override
+ public List<Set<NodeId>> masters() {
+ return this.masters;
+ }
+ }
+
+ /**
+ * Sets up the global values for all the tests.
+ */
+ @Before
+ public void setupTest() {
+ final CodecManager codecService = new CodecManager();
+ codecService.activate();
+ ServiceDirectory testDirectory =
+ new TestServiceDirectory()
+ .add(RegionService.class, mockRegionService)
+ .add(RegionAdminService.class, mockRegionAdminService)
+ .add(CodecService.class, codecService);
+ BaseResource.setServiceDirectory(testDirectory);
+ }
+
+ /**
+ * Hamcrest matcher to check that a region representation in JSON matches
+ * the actual region.
+ */
+ public static class RegionJsonMatcher extends TypeSafeMatcher<JsonObject> {
+ private final Region region;
+ private String reason = "";
+
+ public RegionJsonMatcher(Region regionValue) {
+ this.region = regionValue;
+ }
+
+ @Override
+ protected boolean matchesSafely(JsonObject jsonRegion) {
+
+ // check id
+ String jsonRegionId = jsonRegion.get("id").asString();
+ String regionId = region.id().toString();
+ if (!jsonRegionId.equals(regionId)) {
+ reason = "region id was " + jsonRegionId;
+ return false;
+ }
+
+ // check type
+ String jsonType = jsonRegion.get("type").asString();
+ String type = region.type().toString();
+ if (!jsonType.equals(type)) {
+ reason = "type was " + jsonType;
+ return false;
+ }
+
+ // check name
+ String jsonName = jsonRegion.get("name").asString();
+ String name = region.name();
+ if (!jsonName.equals(name)) {
+ reason = "name was " + jsonName;
+ return false;
+ }
+
+ // check size of master array
+ JsonArray jsonMasters = jsonRegion.get("masters").asArray();
+ if (jsonMasters.size() != region.masters().size()) {
+ reason = "masters size was " + jsonMasters.size();
+ return false;
+ }
+
+ // check master
+ for (Set<NodeId> set : region.masters()) {
+ boolean masterFound = false;
+ for (int masterIndex = 0; masterIndex < jsonMasters.size(); masterIndex++) {
+ masterFound = checkEquality(jsonMasters.get(masterIndex).asArray(), set);
+ }
+
+ if (!masterFound) {
+ reason = "master not found " + set.toString();
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText(reason);
+ }
+
+ private Set<NodeId> jsonToSet(JsonArray nodes) {
+ final Set<NodeId> nodeIds = Sets.newHashSet();
+ nodes.forEach(node -> nodeIds.add(NodeId.nodeId(node.asString())));
+ return nodeIds;
+ }
+
+ private boolean checkEquality(JsonArray nodes, Set<NodeId> nodeIds) {
+ Set<NodeId> jsonSet = jsonToSet(nodes);
+ if (jsonSet.size() == nodes.size()) {
+ return jsonSet.containsAll(nodeIds);
+ }
+ return false;
+ }
+ }
+
+ private static RegionJsonMatcher matchesRegion(Region region) {
+ return new RegionJsonMatcher(region);
+ }
+
+ /**
+ * Hamcrest matcher to check that a region is represented properly in a JSON
+ * array of regions.
+ */
+ public static class RegionJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
+ private final Region region;
+ private String reason = "";
+
+ public RegionJsonArrayMatcher(Region regionValue) {
+ this.region = regionValue;
+ }
+
+ @Override
+ protected boolean matchesSafely(JsonArray json) {
+ boolean regionFound = false;
+ for (int jsonRegionIndex = 0; jsonRegionIndex < json.size(); jsonRegionIndex++) {
+ final JsonObject jsonRegion = json.get(jsonRegionIndex).asObject();
+
+ final String regionId = region.id().toString();
+ final String jsonRegionId = jsonRegion.get("id").asString();
+ if (jsonRegionId.equals(regionId)) {
+ regionFound = true;
+ assertThat(jsonRegion, matchesRegion(region));
+ }
+ }
+
+ if (!regionFound) {
+ reason = "Region with id " + region.id().toString() + " not found";
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText(reason);
+ }
+ }
+
+ /**
+ * Factory to allocate a region array matcher.
+ *
+ * @param region region object we are looking for
+ * @return matcher
+ */
+ private static RegionJsonArrayMatcher hasRegion(Region region) {
+ return new RegionJsonArrayMatcher(region);
+ }
+
+ @Test
+ public void testRegionEmptyArray() {
+ expect(mockRegionService.getRegions()).andReturn(ImmutableSet.of()).anyTimes();
+ replay((mockRegionService));
+ final WebTarget wt = target();
+ final String response = wt.path("regions").request().get(String.class);
+ assertThat(response, is("{\"regions\":[]}"));
+
+ verify(mockRegionService);
+ }
+
+ /**
+ * Tests the results of the REST API GET when there are active regions.
+ */
+ @Test
+ public void testRegionsPopulatedArray() {
+ final Set<Region> regions = ImmutableSet.of(region1, region2, region3);
+ expect(mockRegionService.getRegions()).andReturn(regions).anyTimes();
+ replay(mockRegionService);
+
+ final WebTarget wt = target();
+ final String response = wt.path("regions").request().get(String.class);
+ final JsonObject result = Json.parse(response).asObject();
+ assertThat(result, notNullValue());
+
+ assertThat(result.names(), hasSize(1));
+ assertThat(result.names().get(0), is("regions"));
+ final JsonArray jsonRegions = result.get("regions").asArray();
+ assertThat(jsonRegions, notNullValue());
+ assertThat(jsonRegions, hasRegion(region1));
+ assertThat(jsonRegions, hasRegion(region2));
+ assertThat(jsonRegions, hasRegion(region3));
+
+ verify(mockRegionService);
+
+ }
+
+ /**
+ * Tests the result of a REST API GET for a region with region id.
+ */
+ @Test
+ public void testGetRegionById() {
+ expect(mockRegionService.getRegion(anyObject())).andReturn(region1).anyTimes();
+ replay(mockRegionService);
+
+ final WebTarget wt = target();
+ final String response = wt.path("regions/" + regionId1.toString()).request().get(String.class);
+ final JsonObject result = Json.parse(response).asObject();
+ assertThat(result, notNullValue());
+ assertThat(result, matchesRegion(region1));
+
+ verify(mockRegionService);
+ }
+
+ /**
+ * Tests creating a region with POST.
+ */
+ @Test
+ public void testRegionPost() {
+ mockRegionAdminService.createRegion(anyObject(), anyObject(),
+ anyObject(), anyObject());
+ expectLastCall().andReturn(region2).anyTimes();
+ replay(mockRegionAdminService);
+
+ WebTarget wt = target();
+ InputStream jsonStream = RegionsResourceTest.class
+ .getResourceAsStream("post-region.json");
+
+ Response response = wt.path("regions")
+ .request(MediaType.APPLICATION_JSON_TYPE)
+ .post(Entity.json(jsonStream));
+ assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
+
+ verify(mockRegionAdminService);
+ }
+
+ /**
+ * Tests updating a region with PUT.
+ */
+ @Test
+ public void testRegionPut() {
+ mockRegionAdminService.updateRegion(anyObject(), anyObject(),
+ anyObject(), anyObject());
+ expectLastCall().andReturn(region1).anyTimes();
+ replay(mockRegionAdminService);
+
+ WebTarget wt = target();
+ InputStream jsonStream = RegionsResourceTest.class
+ .getResourceAsStream("post-region.json");
+
+ Response response = wt.path("regions/" + region1.id().toString())
+ .request(MediaType.APPLICATION_JSON_TYPE)
+ .put(Entity.json(jsonStream));
+ assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
+
+ verify(mockRegionAdminService);
+ }
+
+ /**
+ * Tests deleting a region with DELETE.
+ */
+ @Test
+ public void testRegionDelete() {
+ mockRegionAdminService.removeRegion(anyObject());
+ expectLastCall();
+ replay(mockRegionAdminService);
+
+ WebTarget wt = target();
+ Response response = wt.path("regions/" + region1.id().toString())
+ .request().delete();
+ assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
+
+ verify(mockRegionAdminService);
+ }
+
+ /**
+ * Tests retrieving device ids that are associated with the given region.
+ */
+ @Test
+ public void testGetRegionDevices() {
+ final DeviceId deviceId1 = DeviceId.deviceId("1");
+ final DeviceId deviceId2 = DeviceId.deviceId("2");
+ final DeviceId deviceId3 = DeviceId.deviceId("3");
+
+ final Set<DeviceId> deviceIds = ImmutableSet.of(deviceId1, deviceId2, deviceId3);
+
+ expect(mockRegionService.getRegionDevices(anyObject()))
+ .andReturn(deviceIds).anyTimes();
+ replay(mockRegionService);
+
+ final WebTarget wt = target();
+ final String response = wt.path("regions/" +
+ region1.id().toString() + "/devices").request().get(String.class);
+ final JsonObject result = Json.parse(response).asObject();
+ assertThat(result, notNullValue());
+
+ assertThat(result.names(), hasSize(1));
+ assertThat(result.names().get(0), is("deviceIds"));
+ final JsonArray jsonDeviceIds = result.get("deviceIds").asArray();
+ assertThat(jsonDeviceIds.size(), is(3));
+ assertThat(jsonDeviceIds.get(0).asString(), is("1"));
+ assertThat(jsonDeviceIds.get(1).asString(), is("2"));
+ assertThat(jsonDeviceIds.get(2).asString(), is("3"));
+
+ verify(mockRegionService);
+ }
+
+ /**
+ * Tests adding a set of devices in region with POST.
+ */
+ @Test
+ public void testAddDevicesPost() {
+ mockRegionAdminService.addDevices(anyObject(), anyObject());
+ expectLastCall();
+ replay(mockRegionAdminService);
+
+ WebTarget wt = target();
+ InputStream jsonStream = RegionsResourceTest.class
+ .getResourceAsStream("region-deviceIds.json");
+
+ Response response = wt.path("regions/" +
+ region1.id().toString() + "/devices")
+ .request(MediaType.APPLICATION_JSON_TYPE)
+ .post(Entity.json(jsonStream));
+ assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
+
+ verify(mockRegionAdminService);
+ }
+
+ /**
+ * Tests deleting a set of devices contained in the given region with DELETE.
+ */
+ @Test
+ public void testRemoveDevicesDelete() {
+ mockRegionAdminService.removeDevices(anyObject(), anyObject());
+ expectLastCall();
+ replay(mockRegionAdminService);
+
+
+ WebTarget wt = target();
+ InputStream jsonStream = RegionsResourceTest.class
+ .getResourceAsStream("region-deviceIds.json");
+
+ // FIXME: need to consider whether to use jsonStream for entry deletion
+ Response response = wt.path("regions/" +
+ region1.id().toString() + "/devices")
+ .request(MediaType.APPLICATION_JSON_TYPE)
+ .delete();
+ // assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
+ // verify(mockRegionAdminService);
+ }
+}