kopia lustrzana https://github.com/JOSM/MapWithAI
DataConflationSender: Add initial tests
Signed-off-by: Taylor Smock <tsmock@fb.com>pull/1/head
rodzic
99f4de5dd4
commit
9f424eaaa2
|
@ -1,6 +1,12 @@
|
|||
// License: GPL. For details, see LICENSE file.
|
||||
package org.openstreetmap.josm.plugins.mapwithai.backend;
|
||||
|
||||
import javax.json.Json;
|
||||
import javax.json.JsonException;
|
||||
import javax.json.JsonObject;
|
||||
import javax.json.JsonValue;
|
||||
import javax.json.stream.JsonParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -13,12 +19,6 @@ import java.util.TreeMap;
|
|||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.json.Json;
|
||||
import javax.json.JsonException;
|
||||
import javax.json.JsonObject;
|
||||
import javax.json.JsonValue;
|
||||
import javax.json.stream.JsonParser;
|
||||
|
||||
import org.openstreetmap.josm.data.Bounds;
|
||||
import org.openstreetmap.josm.data.coor.LatLon;
|
||||
import org.openstreetmap.josm.io.CachedFile;
|
||||
|
@ -157,8 +157,7 @@ public class DataAvailability {
|
|||
* @return the unique instance
|
||||
*/
|
||||
public static DataAvailability getInstance() {
|
||||
if (instance == null || COUNTRIES.isEmpty()
|
||||
|| MapWithAIPreferenceHelper.getMapWithAIUrl().isEmpty()) {
|
||||
if (instance == null || COUNTRIES.isEmpty() || MapWithAIPreferenceHelper.getMapWithAIUrl().isEmpty()) {
|
||||
instance = new DataAvailability();
|
||||
}
|
||||
return instance;
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.openstreetmap.josm.io.OsmWriterFactory;
|
|||
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAICategory;
|
||||
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAIConflationCategory;
|
||||
import org.openstreetmap.josm.tools.Logging;
|
||||
import org.openstreetmap.josm.tools.Utils;
|
||||
|
||||
/**
|
||||
* Conflate data with a third party server
|
||||
|
@ -66,39 +67,41 @@ public class DataConflationSender implements RunnableFuture<DataSet> {
|
|||
@Override
|
||||
public void run() {
|
||||
String url = MapWithAIConflationCategory.conflationUrlFor(category);
|
||||
this.client = HttpClients.createDefault();
|
||||
try (CloseableHttpClient currentClient = this.client) {
|
||||
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
|
||||
if (osm != null) {
|
||||
if (!Utils.isBlank(url)) {
|
||||
this.client = HttpClients.createDefault();
|
||||
try (CloseableHttpClient currentClient = this.client) {
|
||||
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
|
||||
if (osm != null) {
|
||||
StringWriter output = new StringWriter();
|
||||
try (OsmWriter writer = OsmWriterFactory.createOsmWriter(new PrintWriter(output), true, "0.6")) {
|
||||
writer.write(osm);
|
||||
multipartEntityBuilder.addTextBody("openstreetmap", output.toString(),
|
||||
ContentType.APPLICATION_XML);
|
||||
}
|
||||
}
|
||||
// We need to reset the writers to avoid writing previous streams
|
||||
StringWriter output = new StringWriter();
|
||||
try (OsmWriter writer = OsmWriterFactory.createOsmWriter(new PrintWriter(output), true, "0.6")) {
|
||||
writer.write(osm);
|
||||
multipartEntityBuilder.addTextBody("openstreetmap", output.toString(), ContentType.APPLICATION_XML);
|
||||
writer.write(external);
|
||||
multipartEntityBuilder.addTextBody("external", output.toString(), ContentType.APPLICATION_XML);
|
||||
}
|
||||
}
|
||||
// We need to reset the writers to avoid writing previous streams
|
||||
StringWriter output = new StringWriter();
|
||||
try (OsmWriter writer = OsmWriterFactory.createOsmWriter(new PrintWriter(output), true, "0.6")) {
|
||||
writer.write(external);
|
||||
multipartEntityBuilder.addTextBody("external", output.toString(), ContentType.APPLICATION_XML);
|
||||
}
|
||||
HttpEntity postData = multipartEntityBuilder.build();
|
||||
HttpUriRequest request = RequestBuilder.post(url).setEntity(postData).build();
|
||||
HttpEntity postData = multipartEntityBuilder.build();
|
||||
HttpUriRequest request = RequestBuilder.post(url).setEntity(postData).build();
|
||||
|
||||
HttpResponse response = currentClient.execute(request);
|
||||
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
|
||||
conflatedData = OsmReader.parseDataSet(response.getEntity().getContent(), NullProgressMonitor.INSTANCE,
|
||||
OsmReader.Options.SAVE_ORIGINAL_ID);
|
||||
} else {
|
||||
conflatedData = null;
|
||||
HttpResponse response = currentClient.execute(request);
|
||||
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
|
||||
conflatedData = OsmReader.parseDataSet(response.getEntity().getContent(),
|
||||
NullProgressMonitor.INSTANCE, OsmReader.Options.SAVE_ORIGINAL_ID);
|
||||
} else {
|
||||
conflatedData = null;
|
||||
}
|
||||
ProtocolVersion protocolVersion = response.getStatusLine().getProtocolVersion();
|
||||
Logging.info(request.getMethod() + ' ' + url + " -> " + protocolVersion.getProtocol() + '/'
|
||||
+ protocolVersion.getMajor() + '.' + protocolVersion.getMinor() + ' '
|
||||
+ response.getStatusLine().getStatusCode());
|
||||
} catch (IOException | UnsupportedOperationException | IllegalDataException e) {
|
||||
Logging.error(e);
|
||||
}
|
||||
ProtocolVersion protocolVersion = response.getStatusLine().getProtocolVersion();
|
||||
Logging.info(new StringBuilder(request.getMethod()).append(' ').append(url).append(" -> ")
|
||||
.append(protocolVersion.getProtocol()).append('/').append(protocolVersion.getMajor()).append('.')
|
||||
.append(protocolVersion.getMinor()).append(' ').append(response.getStatusLine().getStatusCode())
|
||||
.toString());
|
||||
} catch (IOException | UnsupportedOperationException | IllegalDataException e) {
|
||||
Logging.error(e);
|
||||
}
|
||||
this.done = true;
|
||||
synchronized (this) {
|
||||
|
|
|
@ -3,6 +3,9 @@ package org.openstreetmap.josm.plugins.mapwithai.data.mapwithai;
|
|||
|
||||
import static org.openstreetmap.josm.tools.I18n.tr;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
@ -20,9 +23,6 @@ import java.util.concurrent.ForkJoinPool;
|
|||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import org.openstreetmap.gui.jmapviewer.tilesources.TileSourceInfo;
|
||||
import org.openstreetmap.josm.actions.ExpertToggleAction;
|
||||
import org.openstreetmap.josm.data.Preferences;
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
// License: GPL. For details, see LICENSE file.
|
||||
package org.openstreetmap.josm.plugins.mapwithai.backend;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.api.function.ThrowingSupplier;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.openstreetmap.josm.data.coor.LatLon;
|
||||
import org.openstreetmap.josm.data.osm.DataSet;
|
||||
import org.openstreetmap.josm.data.osm.Node;
|
||||
import org.openstreetmap.josm.gui.MainApplication;
|
||||
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAICategory;
|
||||
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAIConflationCategory;
|
||||
import org.openstreetmap.josm.plugins.mapwithai.testutils.annotations.MapWithAISources;
|
||||
import org.openstreetmap.josm.plugins.mapwithai.testutils.annotations.Wiremock;
|
||||
import org.openstreetmap.josm.testutils.JOSMTestRules;
|
||||
import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
|
||||
import org.openstreetmap.josm.testutils.annotations.BasicWiremock;
|
||||
|
||||
import com.github.tomakehurst.wiremock.WireMockServer;
|
||||
import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder;
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
|
||||
|
||||
import mockit.Invocation;
|
||||
import mockit.Mock;
|
||||
import mockit.MockUp;
|
||||
|
||||
/**
|
||||
* Test class for {@link DataConflationSender}
|
||||
*
|
||||
* @author Taylor Smock
|
||||
*/
|
||||
@BasicPreferences
|
||||
@Wiremock
|
||||
@MapWithAISources
|
||||
class DataConflationSenderTest {
|
||||
// Needed for HTTP factory
|
||||
@RegisterExtension
|
||||
JOSMTestRules josmTestRules = new JOSMTestRules();
|
||||
|
||||
@BasicWiremock
|
||||
WireMockServer wireMockServer;
|
||||
|
||||
static class MapWithAIConflationCategoryMock extends MockUp<MapWithAIConflationCategory> {
|
||||
static String url;
|
||||
|
||||
@Mock
|
||||
public static String conflationUrlFor(final Invocation invocation, final MapWithAICategory category) {
|
||||
if (url == null) {
|
||||
return invocation.proceed(category);
|
||||
} else {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
MapWithAIConflationCategoryMock.url = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEmptyUrl() {
|
||||
MapWithAIConflationCategoryMock.url = "";
|
||||
new MapWithAIConflationCategoryMock();
|
||||
|
||||
final DataSet external = new DataSet(new Node(LatLon.NORTH_POLE));
|
||||
final DataSet openstreetmap = new DataSet(new Node(LatLon.ZERO));
|
||||
final DataConflationSender dataConflationSender = new DataConflationSender(MapWithAICategory.OTHER,
|
||||
openstreetmap, external);
|
||||
dataConflationSender.run();
|
||||
assertNull(assertDoesNotThrow((ThrowingSupplier<DataSet>) dataConflationSender::get));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWorkingUrl() {
|
||||
MapWithAIConflationCategoryMock.url = wireMockServer.baseUrl() + "/conflate";
|
||||
final StubMapping stubMapping = wireMockServer
|
||||
.stubFor(WireMock.post("/conflate").willReturn(WireMock.aResponse().withBody(
|
||||
"<?xml version='1.0' encoding='UTF-8'?><osm version='0.6' generator='DataConflationSenderTest#testWorkingUrl'><node id='1' version='1' visible='true' lat='89.0' lon='0.1' /></osm>")));
|
||||
new MapWithAIConflationCategoryMock();
|
||||
|
||||
final DataSet external = new DataSet(new Node(LatLon.NORTH_POLE));
|
||||
final DataSet openstreetmap = new DataSet(new Node(LatLon.ZERO));
|
||||
final DataConflationSender dataConflationSender = new DataConflationSender(MapWithAICategory.OTHER,
|
||||
openstreetmap, external);
|
||||
dataConflationSender.run();
|
||||
final DataSet conflated = assertDoesNotThrow((ThrowingSupplier<DataSet>) dataConflationSender::get);
|
||||
assertNotNull(conflated);
|
||||
assertEquals(1, conflated.allPrimitives().size());
|
||||
assertEquals(1, conflated.getNodes().size());
|
||||
final Node conflatedNode = conflated.getNodes().iterator().next();
|
||||
assertEquals(new LatLon(89, 0.1), conflatedNode.getCoor());
|
||||
assertEquals(1, wireMockServer.getAllServeEvents().stream()
|
||||
.filter(serveEvent -> stubMapping.equals(serveEvent.getStubMapping())).count());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWorkingUrlTimeout() {
|
||||
MapWithAIConflationCategoryMock.url = wireMockServer.baseUrl() + "/conflate";
|
||||
final StubMapping stubMapping = wireMockServer.stubFor(WireMock.post("/conflate")
|
||||
.willReturn(WireMock.aResponse().withBody(
|
||||
"<?xml version='1.0' encoding='UTF-8'?><osm version='0.6' generator='DataConflationSenderTest#testWorkingUrl'><node id='1' version='1' visible='true' lat='89.0' lon='0.1' /></osm>")
|
||||
.withFixedDelay(500)));
|
||||
new MapWithAIConflationCategoryMock();
|
||||
|
||||
final DataSet external = new DataSet(new Node(LatLon.NORTH_POLE));
|
||||
final DataSet openstreetmap = new DataSet(new Node(LatLon.ZERO));
|
||||
final DataConflationSender dataConflationSender = new DataConflationSender(MapWithAICategory.OTHER,
|
||||
openstreetmap, external);
|
||||
MainApplication.worker.execute(dataConflationSender);
|
||||
final DataSet conflated = assertDoesNotThrow(() -> dataConflationSender.get(1, TimeUnit.MILLISECONDS));
|
||||
assertNotNull(conflated);
|
||||
assertEquals(1, conflated.allPrimitives().size());
|
||||
assertEquals(1, conflated.getNodes().size());
|
||||
final Node conflatedNode = conflated.getNodes().iterator().next();
|
||||
assertEquals(new LatLon(89, 0.1), conflatedNode.getCoor());
|
||||
assertEquals(1, wireMockServer.getAllServeEvents().stream()
|
||||
.filter(serveEvent -> stubMapping.equals(serveEvent.getStubMapping())).count());
|
||||
}
|
||||
|
||||
static Stream<Arguments> testNonWorkingUrl() {
|
||||
return Stream.of(Arguments.of(WireMock.noContent()), Arguments.of(WireMock.notFound()),
|
||||
Arguments.of(WireMock.forbidden()), Arguments.of(WireMock.serverError()),
|
||||
Arguments.of(WireMock.unauthorized()));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void testNonWorkingUrl(final ResponseDefinitionBuilder response) {
|
||||
MapWithAIConflationCategoryMock.url = wireMockServer.baseUrl() + "/conflate";
|
||||
final StubMapping stubMapping = wireMockServer.stubFor(WireMock.post("/conflate").willReturn(response));
|
||||
new MapWithAIConflationCategoryMock();
|
||||
|
||||
final DataSet external = new DataSet(new Node(LatLon.NORTH_POLE));
|
||||
final DataSet openstreetmap = new DataSet(new Node(LatLon.ZERO));
|
||||
final DataConflationSender dataConflationSender = new DataConflationSender(MapWithAICategory.OTHER,
|
||||
openstreetmap, external);
|
||||
dataConflationSender.run();
|
||||
final DataSet conflated = assertDoesNotThrow((ThrowingSupplier<DataSet>) dataConflationSender::get);
|
||||
assertNull(conflated);
|
||||
assertEquals(1, wireMockServer.getAllServeEvents().stream()
|
||||
.filter(serveEvent -> stubMapping.equals(serveEvent.getStubMapping())).count());
|
||||
}
|
||||
}
|
|
@ -6,10 +6,10 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import javax.swing.JCheckBox;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.openstreetmap.josm.data.Bounds;
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.openstreetmap.josm.testutils.annotations.BasicWiremock;
|
|||
import org.openstreetmap.josm.testutils.annotations.HTTP;
|
||||
|
||||
import com.github.tomakehurst.wiremock.WireMockServer;
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import com.github.tomakehurst.wiremock.common.FileSource;
|
||||
import com.github.tomakehurst.wiremock.extension.Parameters;
|
||||
import com.github.tomakehurst.wiremock.extension.ResponseTransformer;
|
||||
|
@ -71,6 +72,7 @@ public @interface Wiremock {
|
|||
@Override
|
||||
public Response transform(Request request, Response response, FileSource files, Parameters parameters) {
|
||||
if (!request.getUrl().endsWith("/capabilities")
|
||||
&& response.getHeaders().getContentTypeHeader().mimeTypePart() != null
|
||||
&& !response.getHeaders().getContentTypeHeader().mimeTypePart().contains("application/zip")) {
|
||||
String origBody = response.getBodyAsString();
|
||||
String newBody = origBody.replaceAll("https?://.*?/",
|
||||
|
@ -152,6 +154,7 @@ public @interface Wiremock {
|
|||
public String getMapWithAIPaintStyle() {
|
||||
return replaceUrl(getWiremock(this.context), MapWithAIUrls.getInstance().getMapWithAIPaintStyle());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeAll(ExtensionContext context) throws Exception {
|
||||
super.beforeAll(context);
|
||||
|
@ -171,10 +174,20 @@ public @interface Wiremock {
|
|||
@Override
|
||||
public void beforeEach(ExtensionContext context) throws Exception {
|
||||
final Optional<Wiremock> annotation = AnnotationUtils.findFirstParentAnnotation(context, Wiremock.class);
|
||||
this.context = context;
|
||||
if (annotation.isPresent()) {
|
||||
this.beforeAll(context);
|
||||
}
|
||||
final WireMockServer wireMockServer = getWiremock(context);
|
||||
|
||||
super.beforeEach(context);
|
||||
|
||||
if (wireMockServer.getStubMappings().stream().filter(mapping -> mapping.getRequest().getUrl() != null)
|
||||
.noneMatch(mapping -> mapping.getRequest().getUrl()
|
||||
.equals("/JOSM_MapWithAI/json/conflation_servers.json"))) {
|
||||
wireMockServer.stubFor(WireMock.get("/JOSM_MapWithAI/json/conflation_servers.json")
|
||||
.willReturn(WireMock.aResponse().withBody("{}")).atPriority(-5));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -189,6 +202,10 @@ public @interface Wiremock {
|
|||
MapWithAIConfig.setUrlsProvider(new InvalidMapWithAIUrls());
|
||||
}
|
||||
}
|
||||
|
||||
public WireMockServer getWireMockServer() {
|
||||
return getWiremock(context);
|
||||
}
|
||||
}
|
||||
|
||||
class InvalidMapWithAIUrls implements IMapWithAIUrls {
|
||||
|
|
Ładowanie…
Reference in New Issue