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