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