Merge pull request #474 from zod/test-routeserver

Tests for RouteServer
This commit is contained in:
afischerdev 2022-11-10 13:07:10 +01:00 committed by GitHub
commit 78cd395ca1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 296 additions and 26 deletions

View file

@ -7,6 +7,7 @@ import org.junit.Test;
import java.io.File; import java.io.File;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
public class RoutingEngineTest { public class RoutingEngineTest {
@ -22,22 +23,36 @@ public class RoutingEngineTest {
@Test @Test
public void routeCrossingSegmentBorder() { public void routeCrossingSegmentBorder() {
String msg = calcRoute(8.720897, 50.002515, 8.723658, 49.997510, "testtrack"); String msg = calcRoute(8.720897, 50.002515, 8.723658, 49.997510, "testtrack", new RoutingContext());
// error message from router? // error message from router?
Assert.assertNull("routing failed: " + msg, msg); Assert.assertNull("routing failed: " + msg, msg);
// if the track didn't change, we expect the first alternative also // if the track didn't change, we expect the first alternative also
File a1 = new File(workingDir, "testtrack1.gpx"); File a1 = new File(workingDir, "testtrack1.gpx");
Assert.assertTrue("result content missmatch", a1.exists()); a1.deleteOnExit();
Assert.assertTrue("result content mismatch", a1.exists());
} }
@Test @Test
public void routeDestinationPointFarOff() { public void routeDestinationPointFarOff() {
String msg = calcRoute(8.720897, 50.002515, 16.723658, 49.997510, "notrack"); String msg = calcRoute(8.720897, 50.002515, 16.723658, 49.997510, "notrack", new RoutingContext());
Assert.assertTrue(msg, msg != null && msg.contains("not found")); Assert.assertTrue(msg, msg != null && msg.contains("not found"));
} }
private String calcRoute(double flon, double flat, double tlon, double tlat, String trackname) { @Test
public void overrideParam() {
RoutingContext rctx = new RoutingContext();
rctx.keyValues = new HashMap<>();
rctx.keyValues.put("avoid_unsafe", "1.0");
String msg = calcRoute(8.723037, 50.000491, 8.712737, 50.002899, "paramTrack", rctx);
Assert.assertNull("routing failed: " + msg, msg);
File trackFile = new File(workingDir, "paramTrack1.gpx");
trackFile.deleteOnExit();
Assert.assertTrue("result content mismatch", trackFile.exists());
}
private String calcRoute(double flon, double flat, double tlon, double tlat, String trackname, RoutingContext rctx) {
String wd = workingDir.getAbsolutePath(); String wd = workingDir.getAbsolutePath();
List<OsmNodeNamed> wplist = new ArrayList<>(); List<OsmNodeNamed> wplist = new ArrayList<>();
@ -54,7 +69,6 @@ public class RoutingEngineTest {
n.ilat = 90000000 + (int) (tlat * 1000000 + 0.5); n.ilat = 90000000 + (int) (tlat * 1000000 + 0.5);
wplist.add(n); wplist.add(n);
RoutingContext rctx = new RoutingContext();
rctx.localFunction = wd + "/../../../../misc/profiles2/trekking.brf"; rctx.localFunction = wd + "/../../../../misc/profiles2/trekking.brf";
RoutingEngine re = new RoutingEngine( RoutingEngine re = new RoutingEngine(

View file

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- track-length = 1902 filtered ascend = 0 plain-ascend = 0 cost=2753 energy=.0kwh time=5m 9s -->
<gpx
xmlns="http://www.topografix.com/GPX/1/1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"
creator="BRouter-1.6.3" version="1.1">
<trk>
<name>brouter_trekking_0</name>
<trkseg>
<trkpt lon="8.723027" lat="50.000499"></trkpt>
<trkpt lon="8.723285" lat="50.000610"></trkpt>
<trkpt lon="8.724003" lat="50.000939"></trkpt>
<trkpt lon="8.724437" lat="50.000856"></trkpt>
<trkpt lon="8.724590" lat="50.000810"></trkpt>
<trkpt lon="8.724778" lat="50.000741"></trkpt>
<trkpt lon="8.725133" lat="50.001318"></trkpt>
<trkpt lon="8.725379" lat="50.001518"></trkpt>
<trkpt lon="8.725365" lat="50.001683"></trkpt>
<trkpt lon="8.725388" lat="50.001830"></trkpt>
<trkpt lon="8.725421" lat="50.001903"></trkpt>
<trkpt lon="8.725492" lat="50.002032"></trkpt>
<trkpt lon="8.725642" lat="50.002152"></trkpt>
<trkpt lon="8.725847" lat="50.002262"></trkpt>
<trkpt lon="8.725994" lat="50.002570"></trkpt>
<trkpt lon="8.726143" lat="50.002754"></trkpt>
<trkpt lon="8.726166" lat="50.002864"></trkpt>
<trkpt lon="8.725143" lat="50.002880"></trkpt>
<trkpt lon="8.724635" lat="50.002851"></trkpt>
<trkpt lon="8.723968" lat="50.002840"></trkpt>
<trkpt lon="8.723534" lat="50.002821"></trkpt>
<trkpt lon="8.722486" lat="50.002697"></trkpt>
<trkpt lon="8.721892" lat="50.002631"></trkpt>
<trkpt lon="8.721836" lat="50.002624"></trkpt>
<trkpt lon="8.721209" lat="50.002553"></trkpt>
<trkpt lon="8.721118" lat="50.002538"></trkpt>
<trkpt lon="8.721021" lat="50.002493"></trkpt>
<trkpt lon="8.720994" lat="50.002509"></trkpt>
<trkpt lon="8.720960" lat="50.002518"></trkpt>
<trkpt lon="8.720888" lat="50.002517"></trkpt>
<trkpt lon="8.720853" lat="50.002586"></trkpt>
<trkpt lon="8.720782" lat="50.002704"></trkpt>
<trkpt lon="8.720554" lat="50.002937"></trkpt>
<trkpt lon="8.720469" lat="50.003004"></trkpt>
<trkpt lon="8.718899" lat="50.003724"></trkpt>
<trkpt lon="8.718254" lat="50.004051"></trkpt>
<trkpt lon="8.718123" lat="50.004087"></trkpt>
<trkpt lon="8.717543" lat="50.004244"></trkpt>
<trkpt lon="8.717181" lat="50.004357"></trkpt>
<trkpt lon="8.716729" lat="50.004515"></trkpt>
<trkpt lon="8.716463" lat="50.004600"></trkpt>
<trkpt lon="8.715713" lat="50.004799"></trkpt>
<trkpt lon="8.715490" lat="50.004843"></trkpt>
<trkpt lon="8.714977" lat="50.004918"></trkpt>
<trkpt lon="8.714539" lat="50.005012"></trkpt>
<trkpt lon="8.713784" lat="50.005136"></trkpt>
<trkpt lon="8.713582" lat="50.005177"></trkpt>
<trkpt lon="8.713316" lat="50.005086"></trkpt>
<trkpt lon="8.713067" lat="50.005001"></trkpt>
<trkpt lon="8.712848" lat="50.004896"></trkpt>
<trkpt lon="8.712781" lat="50.004859"></trkpt>
<trkpt lon="8.712667" lat="50.004765"></trkpt>
<trkpt lon="8.712563" lat="50.004683"></trkpt>
<trkpt lon="8.712154" lat="50.004321"></trkpt>
<trkpt lon="8.712066" lat="50.004245"></trkpt>
<trkpt lon="8.713422" lat="50.003599"></trkpt>
<trkpt lon="8.713452" lat="50.003572"></trkpt>
<trkpt lon="8.713592" lat="50.003347"></trkpt>
<trkpt lon="8.713620" lat="50.003326"></trkpt>
<trkpt lon="8.713956" lat="50.003142"></trkpt>
<trkpt lon="8.713468" lat="50.002781"></trkpt>
<trkpt lon="8.713293" lat="50.002684"></trkpt>
<trkpt lon="8.712770" lat="50.002929"></trkpt>
</trkseg>
</trk>
</gpx>

View file

@ -70,8 +70,6 @@ distributions {
} }
dependencies { dependencies {
testImplementation 'junit:junit:4.13.1'
implementation project(':brouter-codec') implementation project(':brouter-codec')
implementation project(':brouter-core') implementation project(':brouter-core')
implementation project(':brouter-expressions') implementation project(':brouter-expressions')
@ -79,4 +77,6 @@ dependencies {
implementation project(':brouter-mapaccess') implementation project(':brouter-mapaccess')
implementation project(':brouter-util') implementation project(':brouter-util')
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.json:json:20180813'
} }

View file

@ -81,7 +81,6 @@ public class RouteServer extends Thread implements Comparable<RouteServer> {
String agent = null; String agent = null;
String encodings = null; String encodings = null;
String xff = null; // X-Forwarded-For String xff = null; // X-Forwarded-For
String referer = null;
// more headers until first empty line // more headers until first empty line
for (; ; ) { for (; ; ) {
@ -108,12 +107,6 @@ public class RouteServer extends Thread implements Comparable<RouteServer> {
if (line.startsWith("x-forwarded-for: ")) { if (line.startsWith("x-forwarded-for: ")) {
xff = line.substring("x-forwarded-for: ".length()); xff = line.substring("x-forwarded-for: ".length());
} }
if (line.startsWith("Referer: ")) {
referer = line.substring("Referer: ".length());
}
if (line.startsWith("Referrer: ")) {
referer = line.substring("Referrer: ".length());
}
} }
InetAddress ip = clientSocket.getInetAddress(); InetAddress ip = clientSocket.getInetAddress();
@ -139,15 +132,6 @@ public class RouteServer extends Thread implements Comparable<RouteServer> {
} }
} }
if (referer != null && referer.indexOf("brouter.de/brouter-web") >= 0) {
if (getline.indexOf("%7C") >= 0 && getline.indexOf("%2C") >= 0) {
writeHttpHeader(bw, HTTP_STATUS_FORBIDDEN);
bw.write("Spam? please stop");
bw.flush();
return;
}
}
if (getline.startsWith("GET /favicon.ico")) { if (getline.startsWith("GET /favicon.ico")) {
writeHttpHeader(bw, HTTP_STATUS_NOT_FOUND); writeHttpHeader(bw, HTTP_STATUS_NOT_FOUND);
bw.flush(); bw.flush();

View file

@ -1,7 +1,7 @@
package btools.server.request; package btools.server.request;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import btools.router.OsmNodeNamed; import btools.router.OsmNodeNamed;
import btools.router.OsmTrack; import btools.router.OsmTrack;
@ -10,9 +10,9 @@ import btools.server.ServiceContext;
public abstract class RequestHandler { public abstract class RequestHandler {
protected ServiceContext serviceContext; protected ServiceContext serviceContext;
protected HashMap<String, String> params; protected Map<String, String> params;
public RequestHandler(ServiceContext serviceContext, HashMap<String, String> params) { public RequestHandler(ServiceContext serviceContext, Map<String, String> params) {
this.serviceContext = serviceContext; this.serviceContext = serviceContext;
this.params = params; this.params = params;
} }

View file

@ -0,0 +1,27 @@
package btools.server;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import java.util.HashMap;
import btools.router.RoutingContext;
import btools.server.request.ServerHandler;
public class RequestHandlerTest {
@Test
@Ignore("Parameters are currently handled by RouteServer, not RequestHandler")
public void parseParameters() {
HashMap<String, String> params = new HashMap<>();
params.put("lonlats", "8.799297,49.565883|8.811764,49.563606");
params.put("profile", "trekking");
params.put("alternativeidx", "0");
params.put("profile:test", "bar");
ServerHandler serverHandler = new ServerHandler(null, params);
RoutingContext routingContext = serverHandler.readRoutingContext();
Assert.assertEquals("trekking", routingContext.localFunction);
Assert.assertEquals("bar", routingContext.keyValues.get("test"));
}
}

View file

@ -0,0 +1,169 @@
package btools.server;
import org.json.JSONObject;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
public class RouteServerTest {
private static final String host = "localhost";
private static final String port = "17777";
private static final String baseUrl = "http://" + host + ":" + port + "/";
@ClassRule
public static TemporaryFolder profileDir = new TemporaryFolder();
@BeforeClass
public static void setupServer() throws IOException, InterruptedException {
File workingDir = new File(".").getCanonicalFile();
File segmentDir = new File(workingDir, "../brouter-map-creator/build/resources/test/tmp/segments");
File profileSourceDir = new File(workingDir, "../misc/profiles2");
// Copy required files to temporary dir because profile upload will create files
Files.copy(Paths.get(profileSourceDir.getAbsolutePath(), "lookups.dat"), Paths.get(profileDir.getRoot().getAbsolutePath(), "lookups.dat"));
Files.copy(Paths.get(profileSourceDir.getAbsolutePath(), "trekking.brf"), Paths.get(profileDir.getRoot().getAbsolutePath(), "trekking.brf"));
String customProfileDir = "custom";
Runnable runnable = () -> {
try {
RouteServer.main(new String[]{segmentDir.getAbsolutePath(), profileDir.getRoot().getAbsolutePath(), customProfileDir, port, "1"});
} catch (Exception e) {
e.printStackTrace();
}
};
Thread thread = new Thread(runnable);
thread.start();
// Busy-wait for server startup
URL requestUrl = new URL(baseUrl);
HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
for (int i = 20; i >= 0; i--) {
try {
httpConnection.setConnectTimeout(1000);
httpConnection.connect();
break;
} catch (ConnectException e) {
if (i == 0) {
throw e;
}
Thread.sleep(100);
}
}
}
@Test
public void defaultRouteTrekking() throws IOException {
URL requestUrl = new URL(baseUrl + "brouter?lonlats=8.723037,50.000491|8.712737,50.002899&nogos=&profile=trekking&alternativeidx=0&format=geojson");
HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
httpConnection.connect();
Assert.assertEquals(HttpURLConnection.HTTP_OK, httpConnection.getResponseCode());
InputStream inputStream = httpConnection.getInputStream();
JSONObject geoJson = new JSONObject(new String(inputStream.readAllBytes(), StandardCharsets.UTF_8));
Assert.assertEquals("1204", geoJson.query("/features/0/properties/track-length"));
}
@Test
public void overrideParameter() throws IOException {
URL requestUrl = new URL(baseUrl + "brouter?lonlats=8.723037,50.000491|8.712737,50.002899&nogos=&profile=trekking&alternativeidx=0&format=geojson&profile:avoid_unsafe=1");
HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
httpConnection.connect();
Assert.assertEquals(HttpURLConnection.HTTP_OK, httpConnection.getResponseCode());
InputStream inputStream = httpConnection.getInputStream();
JSONObject geoJson = new JSONObject(new String(inputStream.readAllBytes(), StandardCharsets.UTF_8));
Assert.assertEquals("1902", geoJson.query("/features/0/properties/track-length"));
}
@Test
public void uploadValidProfile() throws IOException {
URL requestUrl = new URL(baseUrl + "brouter/profile");
HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
httpConnection.setRequestMethod("POST");
httpConnection.setDoOutput(true);
String dummyProfile = "---context:global # following code refers to global config\n" +
"\n" +
"# this prevents suppression of unused tags, so they are visibly in the data tab\n" +
"assign processUnusedTags = true\n" +
"assign validForFoot = true\n" +
"\n" +
"---context:way # following code refers to way-tags\n" +
"\n" +
"assign costfactor\n" +
" switch and highway= not route=ferry 100000 1\n" +
"\n" +
"---context:node # following code refers to node tags\n" +
"assign initialcost = 0\n";
try (OutputStream outputStream = httpConnection.getOutputStream()) {
outputStream.write(dummyProfile.getBytes(StandardCharsets.UTF_8));
}
Assert.assertEquals(HttpURLConnection.HTTP_OK, httpConnection.getResponseCode());
InputStream inputStream = httpConnection.getInputStream();
String response = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
JSONObject jsonResponse = new JSONObject(response);
Assert.assertTrue(jsonResponse.query("/profileid").toString().startsWith("custom_"));
Assert.assertFalse(jsonResponse.has("error"));
}
@Test
public void uploadInvalidProfile() throws IOException {
URL requestUrl = new URL(baseUrl + "brouter/profile");
HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
httpConnection.setRequestMethod("POST");
httpConnection.setDoOutput(true);
String invalidProfile = "";
try (OutputStream outputStream = httpConnection.getOutputStream()) {
outputStream.write(invalidProfile.getBytes(StandardCharsets.UTF_8));
}
// It would be better if RouteServer would return "400 Bad Request"
Assert.assertEquals(HttpURLConnection.HTTP_OK, httpConnection.getResponseCode());
InputStream inputStream = httpConnection.getInputStream();
String response = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
JSONObject jsonResponse = new JSONObject(response);
// Returns profileid, but profile isn't valid
Assert.assertTrue(jsonResponse.query("/profileid").toString().startsWith("custom_"));
Assert.assertTrue(jsonResponse.has("error"));
}
@Test
public void robots() throws IOException {
URL requestUrl = new URL(baseUrl + "robots.txt");
HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
httpConnection.connect();
Assert.assertEquals(HttpURLConnection.HTTP_OK, httpConnection.getResponseCode());
String content = new String(httpConnection.getInputStream().readAllBytes(), StandardCharsets.UTF_8);
Assert.assertTrue(content.contains("Disallow: /"));
}
@Test
public void invalidUrl() throws IOException {
URL requestUrl = new URL(baseUrl + "invalid");
HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
httpConnection.connect();
Assert.assertEquals(HttpURLConnection.HTTP_NOT_FOUND, httpConnection.getResponseCode());
}
}