blob: 1804fe12366ea4abe28305d8ca2a3e7ac65bcd6a [file] [log] [blame]
Ray Milkey8fd68ca2015-01-27 15:19:09 -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
18import java.util.List;
19
Jian Li80cfe452016-01-14 16:04:58 -080020import com.eclipsesource.json.Json;
Ray Milkey8fd68ca2015-01-27 15:19:09 -080021import org.hamcrest.Description;
22import org.hamcrest.TypeSafeMatcher;
23import org.junit.After;
24import org.junit.Before;
25import org.junit.Test;
26import org.onlab.osgi.ServiceDirectory;
27import org.onlab.osgi.TestServiceDirectory;
28import org.onlab.rest.BaseResource;
29import org.onosproject.codec.CodecService;
30import org.onosproject.codec.impl.CodecManager;
31import org.onosproject.net.DefaultPort;
32import org.onosproject.net.Device;
33import org.onosproject.net.DeviceId;
34import org.onosproject.net.MastershipRole;
35import org.onosproject.net.Port;
36import org.onosproject.net.device.DeviceService;
37
38import com.eclipsesource.json.JsonArray;
39import com.eclipsesource.json.JsonObject;
40import com.google.common.collect.ImmutableList;
41import com.sun.jersey.api.client.UniformInterfaceException;
42import com.sun.jersey.api.client.WebResource;
Ray Milkey8fd68ca2015-01-27 15:19:09 -080043
44import static org.easymock.EasyMock.createMock;
45import static org.easymock.EasyMock.expect;
46import static org.easymock.EasyMock.isA;
47import static org.easymock.EasyMock.replay;
48import static org.easymock.EasyMock.verify;
49import static org.hamcrest.Matchers.containsString;
50import static org.hamcrest.Matchers.equalTo;
51import static org.hamcrest.Matchers.hasSize;
52import static org.hamcrest.Matchers.is;
53import static org.hamcrest.Matchers.notNullValue;
54import static org.junit.Assert.assertThat;
55import static org.junit.Assert.fail;
56import static org.onosproject.net.NetTestTools.device;
57import static org.onosproject.net.NetTestTools.did;
58import static org.onosproject.net.PortNumber.portNumber;
59
60/**
61 * Unit tests for devices REST APIs.
62 */
Ray Milkey9c3d3362015-01-28 10:39:56 -080063public class DevicesResourceTest extends ResourceTest {
Ray Milkey8fd68ca2015-01-27 15:19:09 -080064 DeviceService mockDeviceService;
65
66 /**
Ray Milkey8fd68ca2015-01-27 15:19:09 -080067 * Hamcrest matcher to check that an device representation in JSON matches
68 * the actual device.
69 */
70 public static class DeviceJsonMatcher extends TypeSafeMatcher<JsonObject> {
71 private final Device device;
72 private String reason = "";
73
74 public DeviceJsonMatcher(Device deviceValue) {
75 device = deviceValue;
76 }
77
78 @Override
79 public boolean matchesSafely(JsonObject jsonDevice) {
80 // check id
81 String jsonId = jsonDevice.get("id").asString();
82 if (!jsonId.equals(device.id().toString())) {
83 reason = "id " + device.id().toString();
84 return false;
85 }
86
87 // check type
88 String jsonType = jsonDevice.get("type").asString();
89 if (!jsonType.equals(device.type().toString())) {
90 reason = "appId " + device.type().toString();
91 return false;
92 }
93
94 // check manufacturer
95 String jsonManufacturer = jsonDevice.get("mfr").asString();
96 if (!jsonManufacturer.equals(device.manufacturer())) {
97 reason = "manufacturer " + device.manufacturer();
98 return false;
99 }
100
101 // check HW version field
102 String jsonHwVersion = jsonDevice.get("hw").asString();
103 if (!jsonHwVersion.equals(device.hwVersion())) {
104 reason = "hw Version " + device.hwVersion();
105 return false;
106 }
107
108 // check SW version field
109 String jsonSwVersion = jsonDevice.get("sw").asString();
110 if (!jsonSwVersion.equals(device.swVersion())) {
111 reason = "sw Version " + device.swVersion();
112 return false;
113 }
114
115 // check serial number field
116 String jsonSerialNumber = jsonDevice.get("serial").asString();
117 if (!jsonSerialNumber.equals(device.serialNumber())) {
118 reason = "serial number " + device.serialNumber();
119 return false;
120 }
121
122 // check chassis id field
123 String jsonChassisId = jsonDevice.get("chassisId").asString();
124 if (!jsonChassisId.equals(device.chassisId().toString())) {
125 reason = "Chassis id " + device.chassisId().toString();
126 return false;
127 }
128
129 return true;
130 }
131
132 @Override
133 public void describeTo(Description description) {
134 description.appendText(reason);
135 }
136 }
137
138 /**
139 * Factory to allocate an device matcher.
140 *
141 * @param device device object we are looking for
142 * @return matcher
143 */
144 private static DeviceJsonMatcher matchesDevice(Device device) {
145 return new DeviceJsonMatcher(device);
146 }
147
148 /**
149 * Hamcrest matcher to check that an device is represented properly in a JSON
150 * array of devices.
151 */
152 private static class DeviceJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
153 private final Device device;
154 private String reason = "";
155
156 public DeviceJsonArrayMatcher(Device deviceValue) {
157 device = deviceValue;
158 }
159
160 @Override
161 public boolean matchesSafely(JsonArray json) {
162 final int minExpectedAttributes = 9;
163 final int maxExpectedAttributes = 10;
164
165 boolean deviceFound = false;
166
167 for (int jsonDeviceIndex = 0; jsonDeviceIndex < json.size();
168 jsonDeviceIndex++) {
169
170 JsonObject jsonDevice = json.get(jsonDeviceIndex).asObject();
171
172 if (jsonDevice.names().size() < minExpectedAttributes ||
173 jsonDevice.names().size() > maxExpectedAttributes) {
174 reason = "Found a device with the wrong number of attributes";
175 return false;
176 }
177
178 String jsonDeviceId = jsonDevice.get("id").asString();
179 if (jsonDeviceId.equals(device.id().toString())) {
180 deviceFound = true;
181
182 // We found the correct device, check attribute values
183 assertThat(jsonDevice, matchesDevice(device));
184 }
185 }
186 if (!deviceFound) {
187 reason = "Device with id " + device.id().toString() + " not found";
188 return false;
189 } else {
190 return true;
191 }
192 }
193
194 @Override
195 public void describeTo(Description description) {
196 description.appendText(reason);
197 }
198 }
199
200 /**
201 * Factory to allocate an device array matcher.
202 *
203 * @param device device object we are looking for
204 * @return matcher
205 */
206 private static DeviceJsonArrayMatcher hasDevice(Device device) {
207 return new DeviceJsonArrayMatcher(device);
208 }
209
Ray Milkeyed0b1662015-02-05 09:34:29 -0800210 /**
211 * Initializes test mocks and environment.
212 */
Ray Milkey8fd68ca2015-01-27 15:19:09 -0800213 @Before
Ray Milkeyed0b1662015-02-05 09:34:29 -0800214 public void setUpMocks() {
Ray Milkey8fd68ca2015-01-27 15:19:09 -0800215 mockDeviceService = createMock(DeviceService.class);
216
217 expect(mockDeviceService.isAvailable(isA(DeviceId.class)))
218 .andReturn(true)
219 .anyTimes();
220 expect(mockDeviceService.getRole(isA(DeviceId.class)))
221 .andReturn(MastershipRole.MASTER)
222 .anyTimes();
223
224 // Register the services needed for the test
225 CodecManager codecService = new CodecManager();
226 codecService.activate();
227 ServiceDirectory testDirectory =
228 new TestServiceDirectory()
229 .add(DeviceService.class, mockDeviceService)
230 .add(CodecService.class, codecService);
231
232 BaseResource.setServiceDirectory(testDirectory);
Ray Milkey8fd68ca2015-01-27 15:19:09 -0800233 }
234
Ray Milkeyed0b1662015-02-05 09:34:29 -0800235 /**
236 * Verifies test mocks.
237 */
Ray Milkey8fd68ca2015-01-27 15:19:09 -0800238 @After
Ray Milkeyed0b1662015-02-05 09:34:29 -0800239 public void tearDownMocks() {
Ray Milkey8fd68ca2015-01-27 15:19:09 -0800240 verify(mockDeviceService);
241 }
242
243 /**
244 * Tests the result of the rest api GET when there are no devices.
245 */
246 @Test
247 public void testDevicesEmptyArray() {
248 expect(mockDeviceService.getDevices()).andReturn(ImmutableList.of());
249 replay(mockDeviceService);
250
251 WebResource rs = resource();
252 String response = rs.path("devices").get(String.class);
253 assertThat(response, is("{\"devices\":[]}"));
254 }
255
256 /**
257 * Tests the result of the rest api GET when there are devices present.
258 */
259 @Test
260 public void testDevices() {
261 Device device1 = device("dev1");
262 Device device2 = device("dev2");
263 Device device3 = device("dev3");
264
265 expect(mockDeviceService.getDevices())
266 .andReturn(ImmutableList.of(device1, device2, device3))
267 .anyTimes();
268
269 replay(mockDeviceService);
270
271 WebResource rs = resource();
272 String response = rs.path("devices").get(String.class);
273 assertThat(response, containsString("{\"devices\":["));
274
Jian Li80cfe452016-01-14 16:04:58 -0800275 JsonObject result = Json.parse(response).asObject();
Ray Milkey8fd68ca2015-01-27 15:19:09 -0800276 assertThat(result, notNullValue());
277
278 assertThat(result.names(), hasSize(1));
279 assertThat(result.names().get(0), is("devices"));
280
281 JsonArray jsonDevices = result.get("devices").asArray();
282 assertThat(jsonDevices, notNullValue());
283 assertThat(jsonDevices.size(), is(3));
284
285 assertThat(jsonDevices, hasDevice(device1));
286 assertThat(jsonDevices, hasDevice(device2));
287 assertThat(jsonDevices, hasDevice(device3));
288 }
289
290 /**
291 * Tests the result of a rest api GET for a single device.
292 */
293 @Test
294 public void testDevicesSingle() {
295
296 String deviceIdString = "testdevice";
297 DeviceId deviceId = did(deviceIdString);
298 Device device = device(deviceIdString);
299
300 expect(mockDeviceService.getDevice(deviceId))
301 .andReturn(device)
302 .once();
303 replay(mockDeviceService);
304
305 WebResource rs = resource();
306 String response = rs.path("devices/" + deviceId).get(String.class);
Jian Li80cfe452016-01-14 16:04:58 -0800307 JsonObject result = Json.parse(response).asObject();
Ray Milkey8fd68ca2015-01-27 15:19:09 -0800308 assertThat(result, matchesDevice(device));
309 }
310
311 /**
312 * Tests the result of a rest api GET for the ports of a single device.
313 */
314 @Test
315 public void testDeviceAndPorts() {
316
317 String deviceIdString = "testdevice";
318 DeviceId deviceId = did(deviceIdString);
319 Device device = device(deviceIdString);
320
321 Port port1 = new DefaultPort(device, portNumber(1), true);
322 Port port2 = new DefaultPort(device, portNumber(2), true);
323 Port port3 = new DefaultPort(device, portNumber(3), true);
324 List<Port> ports = ImmutableList.of(port1, port2, port3);
325
326 expect(mockDeviceService.getDevice(deviceId))
327 .andReturn(device)
328 .once();
329
330 expect(mockDeviceService.getPorts(deviceId))
331 .andReturn(ports)
332 .once();
333 replay(mockDeviceService);
334
335 WebResource rs = resource();
336 String response =
337 rs.path("devices/" + deviceId + "/ports")
338 .get(String.class);
Jian Li80cfe452016-01-14 16:04:58 -0800339 JsonObject result = Json.parse(response).asObject();
Ray Milkey8fd68ca2015-01-27 15:19:09 -0800340 assertThat(result, matchesDevice(device));
341
342 JsonArray jsonPorts = result.get("ports").asArray();
343 assertThat(jsonPorts.size(), is(3));
344 for (int portIndex = 0; portIndex < jsonPorts.size(); portIndex++) {
345 JsonObject jsonPort = jsonPorts.get(portIndex).asObject();
346
Ray Milkey8fd68ca2015-01-27 15:19:09 -0800347 assertThat(jsonPort.get("port").asString(),
348 is(Integer.toString(portIndex + 1)));
349 assertThat(jsonPort.get("isEnabled").asBoolean(),
350 is(true));
351 assertThat(jsonPort.get("type").asString(),
352 equalTo("copper"));
353 assertThat(jsonPort.get("portSpeed").asLong(),
354 is(1000L));
355 }
356 }
357
358 /**
359 * Tests that a fetch of a non-existent device object throws an exception.
360 */
361 @Test
362 public void testBadGet() {
363
364 expect(mockDeviceService.getDevice(isA(DeviceId.class)))
365 .andReturn(null)
366 .anyTimes();
367 replay(mockDeviceService);
368
369 WebResource rs = resource();
370 try {
371 rs.path("devices/0").get(String.class);
372 fail("Fetch of non-existent device did not throw an exception");
373 } catch (UniformInterfaceException ex) {
374 assertThat(ex.getMessage(),
375 containsString("returned a response status of"));
376 }
377 }
378}