blob: e2ff8a0ccdeaec24a7681bc192bc7752b8c68b4c [file] [log] [blame]
Ray Milkey19ffea32015-01-28 10:03:06 -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.io.UnsupportedEncodingException;
19import java.net.URLEncoder;
20import java.nio.charset.StandardCharsets;
21import java.util.Set;
22
Jian Li80cfe452016-01-14 16:04:58 -080023import com.eclipsesource.json.Json;
Ray Milkey19ffea32015-01-28 10:03:06 -080024import org.hamcrest.Description;
25import org.hamcrest.TypeSafeDiagnosingMatcher;
26import org.junit.After;
27import org.junit.Before;
28import org.junit.Test;
29import org.onlab.osgi.ServiceDirectory;
30import org.onlab.osgi.TestServiceDirectory;
31import org.onlab.rest.BaseResource;
32import org.onosproject.codec.CodecService;
33import org.onosproject.codec.impl.CodecManager;
34import org.onosproject.net.ElementId;
35import org.onosproject.net.Link;
36import org.onosproject.net.Path;
37import org.onosproject.net.topology.PathService;
38
39import com.eclipsesource.json.JsonArray;
40import com.eclipsesource.json.JsonObject;
41import com.google.common.collect.ImmutableSet;
42import com.sun.jersey.api.client.WebResource;
43
44import static org.easymock.EasyMock.createMock;
45import static org.easymock.EasyMock.expect;
46import static org.easymock.EasyMock.replay;
47import static org.easymock.EasyMock.verify;
48import static org.hamcrest.Matchers.containsString;
49import static org.hamcrest.Matchers.hasSize;
50import static org.hamcrest.Matchers.is;
51import static org.hamcrest.Matchers.notNullValue;
52import static org.junit.Assert.assertThat;
53import static org.onosproject.net.NetTestTools.createPath;
54import static org.onosproject.net.NetTestTools.did;
55import static org.onosproject.net.NetTestTools.hid;
56
57/**
58 * Unit tests for paths REST APIs.
59 */
60public class PathsResourceTest extends ResourceTest {
61 Path path1 = createPath("dev1", "dev2");
62 Path path2 = createPath("dev2", "dev3");
63 Set<Path> paths = ImmutableSet.of(path1, path2);
64
65 final PathService mockPathService = createMock(PathService.class);
66
67 /**
68 * Hamcrest matcher for a path and its JSON representation.
69 */
70 private final class PathJsonMatcher extends TypeSafeDiagnosingMatcher<JsonObject> {
71
72 private final Path path;
73
74 /**
75 * Creates the matcher.
76 *
77 * @param pathValue the path object to match
78 */
79 private PathJsonMatcher(Path pathValue) {
80 path = pathValue;
81 }
82
83 @Override
84 public boolean matchesSafely(JsonObject pathJson, Description description) {
85
86 double jsonCost = pathJson.get("cost").asDouble();
87 if (jsonCost != path.cost()) {
88 description.appendText("src device was " + jsonCost);
89 return false;
90 }
91
92 JsonArray jsonLinks = pathJson.get("links").asArray();
93 assertThat(jsonLinks.size(), is(path.links().size()));
94
95 for (int linkIndex = 0; linkIndex < jsonLinks.size(); linkIndex++) {
96 Link link = path.links().get(linkIndex);
97 JsonObject jsonLink = jsonLinks.get(0).asObject();
98
99 JsonObject jsonLinkSrc = jsonLink.get("src").asObject();
100 String srcDevice = jsonLinkSrc.get("device").asString();
101 if (!srcDevice.equals(link.src().deviceId().toString())) {
102 description.appendText("src device was " + jsonLinkSrc);
103 return false;
104 }
105
106 JsonObject jsonLinkDst = jsonLink.get("dst").asObject();
107 String dstDevice = jsonLinkDst.get("device").asString();
108 if (!dstDevice.equals(link.dst().deviceId().toString())) {
109 description.appendText("dst device was " + jsonLinkDst);
110 return false;
111 }
112 }
113
114 return true;
115 }
116
117 @Override
118 public void describeTo(Description description) {
119 description.appendText(path.toString());
120 }
121 }
122
123 /**
124 * Factory to allocate an connect point matcher.
125 *
126 * @param path path object we are looking for
127 * @return matcher
128 */
129 private PathJsonMatcher matchesPath(Path path) {
130 return new PathJsonMatcher(path);
131 }
132
Ray Milkeyed0b1662015-02-05 09:34:29 -0800133 /**
134 * Initializes test mocks and environment.
135 */
Ray Milkey19ffea32015-01-28 10:03:06 -0800136 @Before
Ray Milkeyed0b1662015-02-05 09:34:29 -0800137 public void setUpTest() {
Ray Milkey19ffea32015-01-28 10:03:06 -0800138
139 // Register the services needed for the test
140 CodecManager codecService = new CodecManager();
141 codecService.activate();
142 ServiceDirectory testDirectory =
143 new TestServiceDirectory()
144 .add(PathService.class, mockPathService)
145 .add(CodecService.class, codecService);
146
147 BaseResource.setServiceDirectory(testDirectory);
148 }
149
Ray Milkeyed0b1662015-02-05 09:34:29 -0800150 /**
151 * Tears down test mocks and environment.
152 */
Ray Milkey19ffea32015-01-28 10:03:06 -0800153 @After
Ray Milkeyed0b1662015-02-05 09:34:29 -0800154 public void tearDownTest() {
Ray Milkey19ffea32015-01-28 10:03:06 -0800155 verify(mockPathService);
156 }
157
158 /**
159 * Tests a REST path GET for the given endpoints.
160 *
161 * @param srcElement source element of the path
162 * @param dstElement destination element of the path
163 *
164 * @throws UnsupportedEncodingException
165 */
166 private void runTest(ElementId srcElement, ElementId dstElement)
167 throws UnsupportedEncodingException {
168 expect(mockPathService.getPaths(srcElement, dstElement))
169 .andReturn(paths)
170 .once();
171 replay(mockPathService);
172
173 String srcId = URLEncoder.encode(srcElement.toString(),
174 StandardCharsets.UTF_8.name());
175 String dstId = URLEncoder.encode(dstElement.toString(),
176 StandardCharsets.UTF_8.name());
177
178 String url = "paths/" + srcId + "/" + dstId;
179 WebResource rs = resource();
180 String response = rs.path(url).get(String.class);
181 assertThat(response, containsString("{\"paths\":["));
182
Jian Li80cfe452016-01-14 16:04:58 -0800183 JsonObject result = Json.parse(response).asObject();
Ray Milkey19ffea32015-01-28 10:03:06 -0800184 assertThat(result, notNullValue());
185
186 assertThat(result.names(), hasSize(1));
187 assertThat(result.names().get(0), is("paths"));
188
189 JsonArray jsonPaths = result.get("paths").asArray();
190 assertThat(jsonPaths, notNullValue());
191 assertThat(jsonPaths.size(), is(2));
192
193 JsonObject path1Json = jsonPaths.get(0).asObject();
194 assertThat(path1Json, matchesPath(path1));
195
196 JsonObject path2Json = jsonPaths.get(1).asObject();
197 assertThat(path2Json, matchesPath(path2));
198 }
199
200 /**
201 * Tests a path between two hosts.
202 *
203 * @throws UnsupportedEncodingException if UTF-8 not found
204 */
205 @Test
206 public void hostToHost() throws UnsupportedEncodingException {
207 runTest(hid("01:23:45:67:89:AB/2"), hid("AB:89:67:45:23:01/4"));
208 }
209
210 /**
211 * Tests a path with a host as the source and a switch as the destination.
212 *
213 * @throws UnsupportedEncodingException if UTF-8 not found
214 */
215 @Test
216 public void hostToDevice() throws UnsupportedEncodingException {
217 runTest(hid("01:23:45:67:89:AB/2"), did("switch1"));
218 }
219
220 /**
221 * Tests a path with a switch as the source and a host as the destination.
222 *
223 * @throws UnsupportedEncodingException if UTF-8 not found
224 */
225 @Test
226 public void deviceToHost() throws UnsupportedEncodingException {
227 runTest(did("switch1"), hid("01:23:45:67:89:AB/2"));
228 }
229
230 /**
231 * Tests a path between two switches.
232 *
233 * @throws UnsupportedEncodingException if UTF-8 not found
234 */
235 @Test
236 public void deviceToDevice() throws UnsupportedEncodingException {
237 runTest(did("switch1"), did("switch2"));
238 }
239}