blob: e2ff8a0ccdeaec24a7681bc192bc7752b8c68b4c [file] [log] [blame]
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.rest;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Set;
import com.eclipsesource.json.Json;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeDiagnosingMatcher;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.osgi.TestServiceDirectory;
import org.onlab.rest.BaseResource;
import org.onosproject.codec.CodecService;
import org.onosproject.codec.impl.CodecManager;
import org.onosproject.net.ElementId;
import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.topology.PathService;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.google.common.collect.ImmutableSet;
import com.sun.jersey.api.client.WebResource;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.onosproject.net.NetTestTools.createPath;
import static org.onosproject.net.NetTestTools.did;
import static org.onosproject.net.NetTestTools.hid;
/**
* Unit tests for paths REST APIs.
*/
public class PathsResourceTest extends ResourceTest {
Path path1 = createPath("dev1", "dev2");
Path path2 = createPath("dev2", "dev3");
Set<Path> paths = ImmutableSet.of(path1, path2);
final PathService mockPathService = createMock(PathService.class);
/**
* Hamcrest matcher for a path and its JSON representation.
*/
private final class PathJsonMatcher extends TypeSafeDiagnosingMatcher<JsonObject> {
private final Path path;
/**
* Creates the matcher.
*
* @param pathValue the path object to match
*/
private PathJsonMatcher(Path pathValue) {
path = pathValue;
}
@Override
public boolean matchesSafely(JsonObject pathJson, Description description) {
double jsonCost = pathJson.get("cost").asDouble();
if (jsonCost != path.cost()) {
description.appendText("src device was " + jsonCost);
return false;
}
JsonArray jsonLinks = pathJson.get("links").asArray();
assertThat(jsonLinks.size(), is(path.links().size()));
for (int linkIndex = 0; linkIndex < jsonLinks.size(); linkIndex++) {
Link link = path.links().get(linkIndex);
JsonObject jsonLink = jsonLinks.get(0).asObject();
JsonObject jsonLinkSrc = jsonLink.get("src").asObject();
String srcDevice = jsonLinkSrc.get("device").asString();
if (!srcDevice.equals(link.src().deviceId().toString())) {
description.appendText("src device was " + jsonLinkSrc);
return false;
}
JsonObject jsonLinkDst = jsonLink.get("dst").asObject();
String dstDevice = jsonLinkDst.get("device").asString();
if (!dstDevice.equals(link.dst().deviceId().toString())) {
description.appendText("dst device was " + jsonLinkDst);
return false;
}
}
return true;
}
@Override
public void describeTo(Description description) {
description.appendText(path.toString());
}
}
/**
* Factory to allocate an connect point matcher.
*
* @param path path object we are looking for
* @return matcher
*/
private PathJsonMatcher matchesPath(Path path) {
return new PathJsonMatcher(path);
}
/**
* Initializes test mocks and environment.
*/
@Before
public void setUpTest() {
// Register the services needed for the test
CodecManager codecService = new CodecManager();
codecService.activate();
ServiceDirectory testDirectory =
new TestServiceDirectory()
.add(PathService.class, mockPathService)
.add(CodecService.class, codecService);
BaseResource.setServiceDirectory(testDirectory);
}
/**
* Tears down test mocks and environment.
*/
@After
public void tearDownTest() {
verify(mockPathService);
}
/**
* Tests a REST path GET for the given endpoints.
*
* @param srcElement source element of the path
* @param dstElement destination element of the path
*
* @throws UnsupportedEncodingException
*/
private void runTest(ElementId srcElement, ElementId dstElement)
throws UnsupportedEncodingException {
expect(mockPathService.getPaths(srcElement, dstElement))
.andReturn(paths)
.once();
replay(mockPathService);
String srcId = URLEncoder.encode(srcElement.toString(),
StandardCharsets.UTF_8.name());
String dstId = URLEncoder.encode(dstElement.toString(),
StandardCharsets.UTF_8.name());
String url = "paths/" + srcId + "/" + dstId;
WebResource rs = resource();
String response = rs.path(url).get(String.class);
assertThat(response, containsString("{\"paths\":["));
JsonObject result = Json.parse(response).asObject();
assertThat(result, notNullValue());
assertThat(result.names(), hasSize(1));
assertThat(result.names().get(0), is("paths"));
JsonArray jsonPaths = result.get("paths").asArray();
assertThat(jsonPaths, notNullValue());
assertThat(jsonPaths.size(), is(2));
JsonObject path1Json = jsonPaths.get(0).asObject();
assertThat(path1Json, matchesPath(path1));
JsonObject path2Json = jsonPaths.get(1).asObject();
assertThat(path2Json, matchesPath(path2));
}
/**
* Tests a path between two hosts.
*
* @throws UnsupportedEncodingException if UTF-8 not found
*/
@Test
public void hostToHost() throws UnsupportedEncodingException {
runTest(hid("01:23:45:67:89:AB/2"), hid("AB:89:67:45:23:01/4"));
}
/**
* Tests a path with a host as the source and a switch as the destination.
*
* @throws UnsupportedEncodingException if UTF-8 not found
*/
@Test
public void hostToDevice() throws UnsupportedEncodingException {
runTest(hid("01:23:45:67:89:AB/2"), did("switch1"));
}
/**
* Tests a path with a switch as the source and a host as the destination.
*
* @throws UnsupportedEncodingException if UTF-8 not found
*/
@Test
public void deviceToHost() throws UnsupportedEncodingException {
runTest(did("switch1"), hid("01:23:45:67:89:AB/2"));
}
/**
* Tests a path between two switches.
*
* @throws UnsupportedEncodingException if UTF-8 not found
*/
@Test
public void deviceToDevice() throws UnsupportedEncodingException {
runTest(did("switch1"), did("switch2"));
}
}