source: josm/trunk/test/unit/org/openstreetmap/josm/testutils/annotations/OsmApi.java@ 18821

Last change on this file since 18821 was 18821, checked in by taylor.smock, 9 months ago

Fix #23140: RejectedExecutionException when MultiFetchServerObjectReader is cancelled while creating download jobs

This was caused by a race condition.
User starts a download, and cancels it as jobs are submitted to the thread pool.
The next job to be submitted will cause a RejectedExecutionException. In order
to fix this, we ensure that we shutdown the thread pool inside a synchronized
block, and add jobs to the executor inside a synchronized block.

File size: 3.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.testutils.annotations;
3
4import java.lang.annotation.ElementType;
5import java.lang.annotation.Retention;
6import java.lang.annotation.RetentionPolicy;
7import java.lang.annotation.Target;
8import java.util.Map;
9
10import org.junit.jupiter.api.extension.AfterEachCallback;
11import org.junit.jupiter.api.extension.BeforeAllCallback;
12import org.junit.jupiter.api.extension.BeforeEachCallback;
13import org.junit.jupiter.api.extension.ExtendWith;
14import org.junit.jupiter.api.extension.ExtensionContext;
15import org.junit.platform.commons.support.ReflectionSupport;
16import org.junit.runners.model.InitializationError;
17import org.openstreetmap.josm.io.OsmApiInitializationException;
18import org.openstreetmap.josm.io.OsmTransferCanceledException;
19import org.openstreetmap.josm.spi.preferences.Config;
20import org.openstreetmap.josm.testutils.FakeOsmApi;
21
22/**
23 * Used for setting the desired OsmApi type
24 */
25@BasicPreferences
26@ExtendWith(OsmApi.OsmApiExtension.class)
27@HTTP
28@LayerManager
29@Retention(RetentionPolicy.RUNTIME)
30@Target({ElementType.TYPE, ElementType.METHOD})
31public @interface OsmApi {
32 APIType value() default APIType.NONE;
33 enum APIType {
34 /** Don't use any API */
35 NONE,
36 /** Use the {@link org.openstreetmap.josm.testutils.FakeOsmApi} for testing. */
37 FAKE,
38 /** Enable the dev.openstreetmap.org API for this test. */
39 DEV
40 }
41
42 class OsmApiExtension implements BeforeAllCallback, BeforeEachCallback, AfterEachCallback {
43 @Override
44 public void afterEach(ExtensionContext context) throws Exception {
45 Config.getPref().put("osm-server.url", "http://invalid");
46 ((Map<?, ?>) ReflectionSupport.tryToReadFieldValue(
47 org.openstreetmap.josm.io.OsmApi.class.getDeclaredField("instances"), null)
48 .get()).clear();
49 }
50
51 @Override
52 public void beforeAll(ExtensionContext context) throws Exception {
53 this.beforeEach(context);
54 }
55
56 @Override
57 public void beforeEach(ExtensionContext context) throws Exception {
58 final APIType useAPI = AnnotationUtils.findFirstParentAnnotation(context, OsmApi.class)
59 .map(OsmApi::value).orElse(APIType.NONE);
60 // Set API
61 if (useAPI == APIType.DEV) {
62 Config.getPref().put("osm-server.url", "https://api06.dev.openstreetmap.org/api");
63 } else if (useAPI == APIType.FAKE) {
64 FakeOsmApi api = FakeOsmApi.getInstance();
65 Config.getPref().put("osm-server.url", api.getServerUrl());
66 } else {
67 Config.getPref().put("osm-server.url", "http://invalid");
68 }
69
70 // Initialize API
71 if (useAPI != APIType.NONE) {
72 try {
73 org.openstreetmap.josm.io.OsmApi.getOsmApi().initialize(null);
74 } catch (OsmTransferCanceledException | OsmApiInitializationException e) {
75 throw new InitializationError(e);
76 }
77 }
78 }
79 }
80}
Note: See TracBrowser for help on using the repository browser.