blob: 2d9cdeb6db80024d2ca886d70ab0f25395f053b0 [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 Milkey1f95bd32014-12-10 11:11:00 -080070 @Before
71 public void setUp() {
72 expect(mockHostService.getHosts()).andReturn(hosts).anyTimes();
73
74 // Register the services needed for the test
75 final CodecManager codecService = new CodecManager();
76 codecService.activate();
77 ServiceDirectory testDirectory =
78 new TestServiceDirectory()
79 .add(HostService.class, mockHostService)
80 .add(CodecService.class, codecService);
81
82 BaseResource.setServiceDirectory(testDirectory);
83 }
84
85 @After
86 public void tearDown() throws Exception {
87 super.tearDown();
88 verify(mockHostService);
89 }
90
91 /**
92 * Hamcrest matcher to check that a host representation in JSON matches
93 * the actual host.
94 */
95 public static class HostJsonMatcher extends TypeSafeMatcher<JsonObject> {
96 private final Host host;
97 private String reason = "";
98
99 public HostJsonMatcher(Host hostValue) {
100 host = hostValue;
101 }
102
103 @Override
104 public boolean matchesSafely(JsonObject jsonHost) {
105 // Check id
106 final String jsonId = jsonHost.get("id").asString();
107 if (!jsonId.equals(host.id().toString())) {
108 reason = "id " + host.id().toString();
109 return false;
110 }
111
112 // Check vlan id
113 final String jsonVlanId = jsonHost.get("vlan").asString();
114 if (!jsonVlanId.equals(host.vlan().toString())) {
115 reason = "vlan id " + host.vlan().toString();
116 return false;
117 }
118
119 // Check mac address
120 final String jsonMacAddress = jsonHost.get("mac").asString();
121 if (!jsonMacAddress.equals(host.mac().toString())) {
122 reason = "mac address " + host.mac().toString();
123 return false;
124 }
125
126 // Check location element id
127 final JsonObject jsonLocation = jsonHost.get("location").asObject();
128 final String jsonLocationElementId = jsonLocation.get("elementId").asString();
129 if (!jsonLocationElementId.equals(host.location().elementId().toString())) {
130 reason = "location element id " + host.location().elementId().toString();
131 return false;
132 }
133
134 // Check location port number
135 final String jsonLocationPortNumber = jsonLocation.get("port").asString();
136 if (!jsonLocationPortNumber.equals(host.location().port().toString())) {
137 reason = "location portNumber " + host.location().port().toString();
138 return false;
139 }
140
141 // Check Ip Addresses
142 final JsonArray jsonHostIps = jsonHost.get("ipAddresses").asArray();
143 final Set<IpAddress> expectedHostIps = host.ipAddresses();
144 if (jsonHostIps.size() != expectedHostIps.size()) {
145 reason = "IP address arrays differ in size";
146 return false;
147 }
148
149 return true;
150 }
151
152 @Override
153 public void describeTo(Description description) {
154 description.appendText(reason);
155 }
156 }
157
158 /**
159 * Factory to allocate a host array matcher.
160 *
161 * @param host host object we are looking for
162 * @return matcher
163 */
164 private static HostJsonMatcher matchesHost(Host host) {
165 return new HostJsonMatcher(host);
166 }
167
168 /**
169 * Hamcrest matcher to check that a host is represented properly in a JSON
170 * array of hosts.
171 */
172 public static class HostJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
173 private final Host host;
174 private String reason = "";
175
176 public HostJsonArrayMatcher(Host hostValue) {
177 host = hostValue;
178 }
179
180 @Override
181 public boolean matchesSafely(JsonArray json) {
182 boolean hostFound = false;
183 final int expectedAttributes = 5;
184 for (int jsonHostIndex = 0; jsonHostIndex < json.size();
185 jsonHostIndex++) {
186
187 final JsonObject jsonHost = json.get(jsonHostIndex).asObject();
188
189 if (jsonHost.names().size() != expectedAttributes) {
190 reason = "Found a host with the wrong number of attributes";
191 return false;
192 }
193
194 final String jsonHostId = jsonHost.get("id").asString();
195 if (jsonHostId.equals(host.id().toString())) {
196 hostFound = true;
197
198 // We found the correct host, check attribute values
199 assertThat(jsonHost, matchesHost(host));
200 }
201 }
202 if (!hostFound) {
203 reason = "Host with id " + host.id().toString() + " not found";
204 return false;
205 } else {
206 return true;
207 }
208 }
209
210 @Override
211 public void describeTo(Description description) {
212 description.appendText(reason);
213 }
214 }
215
216 /**
217 * Factory to allocate a host array matcher.
218 *
219 * @param host host object we are looking for
220 * @return matcher
221 */
222 private static HostJsonArrayMatcher hasHost(Host host) {
223 return new HostJsonArrayMatcher(host);
224 }
225
226 /**
227 * Tests the result of the rest api GET when there are no hosts.
228 */
229 @Test
230 public void testHostsEmptyArray() {
231 replay(mockHostService);
232 WebResource rs = resource();
233 String response = rs.path("hosts").get(String.class);
234 assertThat(response, is("{\"hosts\":[]}"));
235 }
236
237 /**
238 * Tests the result of the rest api GET when hosts are defined.
239 */
240 @Test
241 public void testHostsArray() {
242 replay(mockHostService);
243 final ProviderId pid = new ProviderId("of", "foo");
244 final MacAddress mac1 = MacAddress.valueOf("00:00:11:00:00:01");
245 final Set<IpAddress> ips1 = ImmutableSet.of(IpAddress.valueOf("1111:1111:1111:1::"));
246 final Host host1 =
247 new DefaultHost(pid, HostId.hostId(mac1), valueOf(1), vlanId((short) 1),
248 new HostLocation(DeviceId.deviceId("1"), portNumber(11), 1),
249 ips1);
250 final MacAddress mac2 = MacAddress.valueOf("00:00:11:00:00:02");
251 final Set<IpAddress> ips2 = ImmutableSet.of(
252 IpAddress.valueOf("2222:2222:2222:1::"),
253 IpAddress.valueOf("2222:2222:2222:2::"));
254 final Host host2 =
255 new DefaultHost(pid, HostId.hostId(mac2), valueOf(2), vlanId((short) 2),
256 new HostLocation(DeviceId.deviceId("2"), portNumber(22), 2),
257 ips2);
258 hosts.add(host1);
259 hosts.add(host2);
260 WebResource rs = resource();
261 String response = rs.path("hosts").get(String.class);
262 assertThat(response, containsString("{\"hosts\":["));
263
264 final JsonObject result = JsonObject.readFrom(response);
265 assertThat(result, notNullValue());
266
267 assertThat(result.names(), hasSize(1));
268 assertThat(result.names().get(0), is("hosts"));
269
270 final JsonArray hosts = result.get("hosts").asArray();
271 assertThat(hosts, notNullValue());
272
273 assertThat(hosts, hasHost(host1));
274 assertThat(hosts, hasHost(host2));
275 }
276
277 /**
278 * Tests fetch of one host by Id.
279 */
280 @Test
281 public void testSingleHostByIdFetch() {
282 final ProviderId pid = new ProviderId("of", "foo");
283 final MacAddress mac1 = MacAddress.valueOf("00:00:11:00:00:01");
284 final Set<IpAddress> ips1 = ImmutableSet.of(IpAddress.valueOf("1111:1111:1111:1::"));
285 final Host host1 =
286 new DefaultHost(pid, HostId.hostId(mac1), valueOf(1), vlanId((short) 1),
287 new HostLocation(DeviceId.deviceId("1"), portNumber(11), 1),
288 ips1);
289
290 hosts.add(host1);
291
292 expect(mockHostService.getHost(HostId.hostId("00:00:11:00:00:01/1")))
293 .andReturn(host1)
294 .anyTimes();
295 replay(mockHostService);
296
297 WebResource rs = resource();
298 String response = rs.path("hosts/00:00:11:00:00:01%2F1").get(String.class);
299 final JsonObject result = JsonObject.readFrom(response);
300 assertThat(result, matchesHost(host1));
301 }
302
303 /**
304 * Tests fetch of one host by mac and vlan.
305 */
306 @Test
307 public void testSingleHostByMacAndVlanFetch() {
308 final ProviderId pid = new ProviderId("of", "foo");
309 final MacAddress mac1 = MacAddress.valueOf("00:00:11:00:00:01");
310 final Set<IpAddress> ips1 = ImmutableSet.of(IpAddress.valueOf("1111:1111:1111:1::"));
311 final Host host1 =
312 new DefaultHost(pid, HostId.hostId(mac1), valueOf(1), vlanId((short) 1),
313 new HostLocation(DeviceId.deviceId("1"), portNumber(11), 1),
314 ips1);
315
316 hosts.add(host1);
317
318 expect(mockHostService.getHost(HostId.hostId("00:00:11:00:00:01/1")))
319 .andReturn(host1)
320 .anyTimes();
321 replay(mockHostService);
322
323 WebResource rs = resource();
324 String response = rs.path("hosts/00:00:11:00:00:01/1").get(String.class);
325 final JsonObject result = JsonObject.readFrom(response);
326 assertThat(result, matchesHost(host1));
327 }
328
Ray Milkey02f446b2014-12-11 20:19:43 -0800329 /**
330 * Tests that a fetch of a non-existent object throws an exception.
331 */
332 @Test
333 public void testBadGet() {
334
335 expect(mockHostService.getHost(HostId.hostId("00:00:11:00:00:01/1")))
336 .andReturn(null)
337 .anyTimes();
338 replay(mockHostService);
339
340 WebResource rs = resource();
341 try {
342 rs.path("hosts/00:00:11:00:00:01/1").get(String.class);
343 fail("Fetch of non-existent host did not throw an exception");
344 } catch (UniformInterfaceException ex) {
345 assertThat(ex.getMessage(),
346 containsString("returned a response status of"));
347 }
348 }
349
Ray Milkey1f95bd32014-12-10 11:11:00 -0800350}
351