diff --git a/web/api/src/test/java/org/onosproject/rest/RegionsResourceTest.java b/web/api/src/test/java/org/onosproject/rest/RegionsResourceTest.java
new file mode 100644
index 0000000..620251d
--- /dev/null
+++ b/web/api/src/test/java/org/onosproject/rest/RegionsResourceTest.java
@@ -0,0 +1,470 @@
+/*
+ * 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;
+
+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 com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.WebResource;
+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 org.onosproject.rest.resources.CoreWebApplication;
+
+import javax.ws.rs.core.MediaType;
+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);
+
+    public RegionsResourceTest() {
+        super(CoreWebApplication.class);
+    }
+
+    /**
+     * 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 meter representation in JSON matches
+     * the actual meter.
+     */
+    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 WebResource rs = resource();
+        final String response = rs.path("regions").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 WebResource rs = resource();
+        final String response = rs.path("regions").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 WebResource rs = resource();
+        final String response = rs.path("regions/" + regionId1.toString()).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);
+
+        WebResource rs = resource();
+        InputStream jsonStream = MetersResourceTest.class
+                .getResourceAsStream("post-region.json");
+
+        ClientResponse response = rs.path("regions")
+                .type(MediaType.APPLICATION_JSON_TYPE)
+                .post(ClientResponse.class, 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);
+
+        WebResource rs = resource();
+        InputStream jsonStream = MetersResourceTest.class
+                .getResourceAsStream("post-region.json");
+
+        ClientResponse response = rs.path("regions/" + region1.id().toString())
+                .type(MediaType.APPLICATION_JSON_TYPE)
+                .put(ClientResponse.class, 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);
+
+        WebResource rs = resource();
+        ClientResponse response = rs.path("regions/" + region1.id().toString())
+                .delete(ClientResponse.class);
+        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 WebResource rs = resource();
+        final String response = rs.path("regions/" +
+                region1.id().toString() + "/devices").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);
+
+        WebResource rs = resource();
+        InputStream jsonStream = MetersResourceTest.class
+                .getResourceAsStream("region-deviceIds.json");
+
+        ClientResponse response = rs.path("regions/" +
+                region1.id().toString() + "/devices")
+                .type(MediaType.APPLICATION_JSON_TYPE)
+                .post(ClientResponse.class, 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);
+
+        WebResource rs = resource();
+        InputStream jsonStream = MetersResourceTest.class
+                .getResourceAsStream("region-deviceIds.json");
+
+        ClientResponse response = rs.path("regions/" +
+                region1.id().toString() + "/devices")
+                .type(MediaType.APPLICATION_JSON_TYPE)
+                .delete(ClientResponse.class, jsonStream);
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
+
+        verify(mockRegionAdminService);
+    }
+}
