blob: a5c4b77acfac2158c02a0d87b564c8291cb36758 [file] [log] [blame]
Ray Milkey1f95bd32014-12-10 11:11:00 -08001/*
2 * Copyright 2014 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
18
19import java.util.HashSet;
20import java.util.Set;
21
22import org.hamcrest.Description;
23import org.hamcrest.TypeSafeMatcher;
24import org.junit.After;
25import org.junit.Before;
26import org.junit.Test;
27import org.onlab.osgi.ServiceDirectory;
28import org.onlab.osgi.TestServiceDirectory;
29import org.onlab.packet.IpAddress;
30import org.onlab.packet.MacAddress;
31import org.onlab.rest.BaseResource;
32import org.onosproject.codec.CodecService;
33import org.onosproject.codec.impl.CodecManager;
34import org.onosproject.net.DefaultHost;
35import org.onosproject.net.DeviceId;
36import org.onosproject.net.Host;
37import org.onosproject.net.HostId;
38import org.onosproject.net.HostLocation;
39import org.onosproject.net.host.HostService;
40import org.onosproject.net.provider.ProviderId;
41
42import com.eclipsesource.json.JsonArray;
43import com.eclipsesource.json.JsonObject;
44import com.google.common.collect.ImmutableSet;
Ray Milkey02f446b2014-12-11 20:19:43 -080045import com.sun.jersey.api.client.UniformInterfaceException;
Ray Milkey1f95bd32014-12-10 11:11:00 -080046import com.sun.jersey.api.client.WebResource;
Ray Milkey1f95bd32014-12-10 11:11:00 -080047
48import static org.easymock.EasyMock.createMock;
49import static org.easymock.EasyMock.expect;
50import static org.easymock.EasyMock.replay;
51import static org.easymock.EasyMock.verify;
52import static org.hamcrest.Matchers.containsString;
53import static org.hamcrest.Matchers.hasSize;
54import static org.hamcrest.Matchers.is;
55import static org.hamcrest.Matchers.notNullValue;
56import static org.junit.Assert.assertThat;
Ray Milkey02f446b2014-12-11 20:19:43 -080057import static org.junit.Assert.fail;
Ray Milkey1f95bd32014-12-10 11:11:00 -080058import static org.onlab.packet.MacAddress.valueOf;
59import static org.onlab.packet.VlanId.vlanId;
60import static org.onosproject.net.PortNumber.portNumber;
61
62/**
63 * Simple example on how to write a JAX-RS unit test using Jersey test framework.
64 * A base class should/will be created to provide further assistance for testing.
65 */
Ray Milkey9c3d3362015-01-28 10:39:56 -080066public class HostResourceTest extends ResourceTest {
Ray Milkey1f95bd32014-12-10 11:11:00 -080067 final HostService mockHostService = createMock(HostService.class);
68 final HashSet<Host> hosts = new HashSet<>();
69
Ray Milkeyed0b1662015-02-05 09:34:29 -080070 /**
71 * Initializes test mocks and environment.
72 */
Ray Milkey1f95bd32014-12-10 11:11:00 -080073 @Before
Ray Milkeyed0b1662015-02-05 09:34:29 -080074 public void setUpTest() {
Ray Milkey1f95bd32014-12-10 11:11:00 -080075 expect(mockHostService.getHosts()).andReturn(hosts).anyTimes();
76
77 // Register the services needed for the test
78 final CodecManager codecService = new CodecManager();
79 codecService.activate();
80 ServiceDirectory testDirectory =
81 new TestServiceDirectory()
82 .add(HostService.class, mockHostService)
83 .add(CodecService.class, codecService);
84
85 BaseResource.setServiceDirectory(testDirectory);
86 }
87
Ray Milkeyed0b1662015-02-05 09:34:29 -080088 /**
89 * Verifies mocks.
90 */
Ray Milkey1f95bd32014-12-10 11:11:00 -080091 @After
Ray Milkeyed0b1662015-02-05 09:34:29 -080092 public void tearDownTest() {
Ray Milkey1f95bd32014-12-10 11:11:00 -080093 verify(mockHostService);
94 }
95
96 /**
97 * Hamcrest matcher to check that a host representation in JSON matches
98 * the actual host.
99 */
100 public static class HostJsonMatcher extends TypeSafeMatcher<JsonObject> {
101 private final Host host;
102 private String reason = "";
103
104 public HostJsonMatcher(Host hostValue) {
105 host = hostValue;
106 }
107
108 @Override
109 public boolean matchesSafely(JsonObject jsonHost) {
110 // Check id
111 final String jsonId = jsonHost.get("id").asString();
112 if (!jsonId.equals(host.id().toString())) {
113 reason = "id " + host.id().toString();
114 return false;
115 }
116
117 // Check vlan id
118 final String jsonVlanId = jsonHost.get("vlan").asString();
119 if (!jsonVlanId.equals(host.vlan().toString())) {
120 reason = "vlan id " + host.vlan().toString();
121 return false;
122 }
123
124 // Check mac address
125 final String jsonMacAddress = jsonHost.get("mac").asString();
126 if (!jsonMacAddress.equals(host.mac().toString())) {
127 reason = "mac address " + host.mac().toString();
128 return false;
129 }
130
131 // Check location element id
132 final JsonObject jsonLocation = jsonHost.get("location").asObject();
133 final String jsonLocationElementId = jsonLocation.get("elementId").asString();
134 if (!jsonLocationElementId.equals(host.location().elementId().toString())) {
135 reason = "location element id " + host.location().elementId().toString();
136 return false;
137 }
138
139 // Check location port number
140 final String jsonLocationPortNumber = jsonLocation.get("port").asString();
141 if (!jsonLocationPortNumber.equals(host.location().port().toString())) {
142 reason = "location portNumber " + host.location().port().toString();
143 return false;
144 }
145
146 // Check Ip Addresses
147 final JsonArray jsonHostIps = jsonHost.get("ipAddresses").asArray();
148 final Set<IpAddress> expectedHostIps = host.ipAddresses();
149 if (jsonHostIps.size() != expectedHostIps.size()) {
150 reason = "IP address arrays differ in size";
151 return false;
152 }
153
154 return true;
155 }
156
157 @Override
158 public void describeTo(Description description) {
159 description.appendText(reason);
160 }
161 }
162
163 /**
164 * Factory to allocate a host array matcher.
165 *
166 * @param host host object we are looking for
167 * @return matcher
168 */
169 private static HostJsonMatcher matchesHost(Host host) {
170 return new HostJsonMatcher(host);
171 }
172
173 /**
174 * Hamcrest matcher to check that a host is represented properly in a JSON
175 * array of hosts.
176 */
177 public static class HostJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
178 private final Host host;
179 private String reason = "";
180
181 public HostJsonArrayMatcher(Host hostValue) {
182 host = hostValue;
183 }
184
185 @Override
186 public boolean matchesSafely(JsonArray json) {
187 boolean hostFound = false;
188 final int expectedAttributes = 5;
189 for (int jsonHostIndex = 0; jsonHostIndex < json.size();
190 jsonHostIndex++) {
191
192 final JsonObject jsonHost = json.get(jsonHostIndex).asObject();
193
194 if (jsonHost.names().size() != expectedAttributes) {
195 reason = "Found a host with the wrong number of attributes";
196 return false;
197 }
198
199 final String jsonHostId = jsonHost.get("id").asString();
200 if (jsonHostId.equals(host.id().toString())) {
201 hostFound = true;
202
203 // We found the correct host, check attribute values
204 assertThat(jsonHost, matchesHost(host));
205 }
206 }
207 if (!hostFound) {
208 reason = "Host with id " + host.id().toString() + " not found";
209 return false;
210 } else {
211 return true;
212 }
213 }
214
215 @Override
216 public void describeTo(Description description) {
217 description.appendText(reason);
218 }
219 }
220
221 /**
222 * Factory to allocate a host array matcher.
223 *
224 * @param host host object we are looking for
225 * @return matcher
226 */
227 private static HostJsonArrayMatcher hasHost(Host host) {
228 return new HostJsonArrayMatcher(host);
229 }
230
231 /**
232 * Tests the result of the rest api GET when there are no hosts.
233 */
234 @Test
235 public void testHostsEmptyArray() {
236 replay(mockHostService);
237 WebResource rs = resource();
238 String response = rs.path("hosts").get(String.class);
239 assertThat(response, is("{\"hosts\":[]}"));
240 }
241
242 /**
243 * Tests the result of the rest api GET when hosts are defined.
244 */
245 @Test
246 public void testHostsArray() {
247 replay(mockHostService);
248 final ProviderId pid = new ProviderId("of", "foo");
249 final MacAddress mac1 = MacAddress.valueOf("00:00:11:00:00:01");
250 final Set<IpAddress> ips1 = ImmutableSet.of(IpAddress.valueOf("1111:1111:1111:1::"));
251 final Host host1 =
252 new DefaultHost(pid, HostId.hostId(mac1), valueOf(1), vlanId((short) 1),
253 new HostLocation(DeviceId.deviceId("1"), portNumber(11), 1),
254 ips1);
255 final MacAddress mac2 = MacAddress.valueOf("00:00:11:00:00:02");
256 final Set<IpAddress> ips2 = ImmutableSet.of(
257 IpAddress.valueOf("2222:2222:2222:1::"),
258 IpAddress.valueOf("2222:2222:2222:2::"));
259 final Host host2 =
260 new DefaultHost(pid, HostId.hostId(mac2), valueOf(2), vlanId((short) 2),
261 new HostLocation(DeviceId.deviceId("2"), portNumber(22), 2),
262 ips2);
263 hosts.add(host1);
264 hosts.add(host2);
265 WebResource rs = resource();
266 String response = rs.path("hosts").get(String.class);
267 assertThat(response, containsString("{\"hosts\":["));
268
269 final JsonObject result = JsonObject.readFrom(response);
270 assertThat(result, notNullValue());
271
272 assertThat(result.names(), hasSize(1));
273 assertThat(result.names().get(0), is("hosts"));
274
275 final JsonArray hosts = result.get("hosts").asArray();
276 assertThat(hosts, notNullValue());
277
278 assertThat(hosts, hasHost(host1));
279 assertThat(hosts, hasHost(host2));
280 }
281
282 /**
283 * Tests fetch of one host by Id.
284 */
285 @Test
286 public void testSingleHostByIdFetch() {
287 final ProviderId pid = new ProviderId("of", "foo");
288 final MacAddress mac1 = MacAddress.valueOf("00:00:11:00:00:01");
289 final Set<IpAddress> ips1 = ImmutableSet.of(IpAddress.valueOf("1111:1111:1111:1::"));
290 final Host host1 =
291 new DefaultHost(pid, HostId.hostId(mac1), valueOf(1), vlanId((short) 1),
292 new HostLocation(DeviceId.deviceId("1"), portNumber(11), 1),
293 ips1);
294
295 hosts.add(host1);
296
297 expect(mockHostService.getHost(HostId.hostId("00:00:11:00:00:01/1")))
298 .andReturn(host1)
299 .anyTimes();
300 replay(mockHostService);
301
302 WebResource rs = resource();
303 String response = rs.path("hosts/00:00:11:00:00:01%2F1").get(String.class);
304 final JsonObject result = JsonObject.readFrom(response);
305 assertThat(result, matchesHost(host1));
306 }
307
308 /**
309 * Tests fetch of one host by mac and vlan.
310 */
311 @Test
312 public void testSingleHostByMacAndVlanFetch() {
313 final ProviderId pid = new ProviderId("of", "foo");
314 final MacAddress mac1 = MacAddress.valueOf("00:00:11:00:00:01");
315 final Set<IpAddress> ips1 = ImmutableSet.of(IpAddress.valueOf("1111:1111:1111:1::"));
316 final Host host1 =
317 new DefaultHost(pid, HostId.hostId(mac1), valueOf(1), vlanId((short) 1),
318 new HostLocation(DeviceId.deviceId("1"), portNumber(11), 1),
319 ips1);
320
321 hosts.add(host1);
322
323 expect(mockHostService.getHost(HostId.hostId("00:00:11:00:00:01/1")))
324 .andReturn(host1)
325 .anyTimes();
326 replay(mockHostService);
327
328 WebResource rs = resource();
329 String response = rs.path("hosts/00:00:11:00:00:01/1").get(String.class);
330 final JsonObject result = JsonObject.readFrom(response);
331 assertThat(result, matchesHost(host1));
332 }
333
Ray Milkey02f446b2014-12-11 20:19:43 -0800334 /**
335 * Tests that a fetch of a non-existent object throws an exception.
336 */
337 @Test
338 public void testBadGet() {
339
340 expect(mockHostService.getHost(HostId.hostId("00:00:11:00:00:01/1")))
341 .andReturn(null)
342 .anyTimes();
343 replay(mockHostService);
344
345 WebResource rs = resource();
346 try {
347 rs.path("hosts/00:00:11:00:00:01/1").get(String.class);
348 fail("Fetch of non-existent host did not throw an exception");
349 } catch (UniformInterfaceException ex) {
350 assertThat(ex.getMessage(),
351 containsString("returned a response status of"));
352 }
353 }
354
Ray Milkey1f95bd32014-12-10 11:11:00 -0800355}
356