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