Skip to content

Commit

Permalink
Add @Plugins annotation to clean up after plugins have been loaded in…
Browse files Browse the repository at this point in the history
… tests

This should help reduce the issues related to plugins not being unloaded after
PluginHandlerTestIT when tests are run locally with a UI -- the primary cause
of problems is the SDS plugin though.

git-svn-id: https://josm.openstreetmap.de/svn/trunk@19209 0c6e7542-c601-0410-84e7-c038aed88b3b
  • Loading branch information
taylor.smock committed Sep 5, 2024
1 parent d825ea6 commit 8803b53
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 0 deletions.
2 changes: 2 additions & 0 deletions test/unit/org/openstreetmap/josm/gui/MainApplicationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import org.openstreetmap.josm.testutils.annotations.HTTPS;
import org.openstreetmap.josm.testutils.annotations.Main;
import org.openstreetmap.josm.testutils.annotations.OsmApi;
import org.openstreetmap.josm.testutils.annotations.Plugins;
import org.openstreetmap.josm.testutils.annotations.Projection;
import org.openstreetmap.josm.tools.Logging;
import org.openstreetmap.josm.tools.PlatformManager;
Expand Down Expand Up @@ -170,6 +171,7 @@ void testParamType() {
* Test of {@link MainApplication#updateAndLoadEarlyPlugins} and {@link MainApplication#loadLatePlugins} methods.
* @throws PluginListParseException if an error occurs
*/
@Plugins
@Test
void testUpdateAndLoadPlugins() throws PluginListParseException {
final String old = System.getProperty("josm.plugins");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@
import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
import org.openstreetmap.josm.testutils.annotations.HTTPS;
import org.openstreetmap.josm.testutils.annotations.Main;
import org.openstreetmap.josm.testutils.annotations.Plugins;
import org.openstreetmap.josm.testutils.annotations.Projection;
import org.openstreetmap.josm.testutils.annotations.Territories;
import org.openstreetmap.josm.testutils.annotations.ThreadSync;
import org.openstreetmap.josm.tools.Destroyable;
import org.openstreetmap.josm.tools.Logging;
import org.openstreetmap.josm.tools.Utils;
Expand All @@ -57,6 +59,8 @@
@Projection
@Territories
@Timeout(value = 10, unit = TimeUnit.MINUTES)
@ThreadSync
@Plugins
public class PluginHandlerTestIT {

private static final List<String> errorsToIgnore = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.testutils.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.openstreetmap.josm.io.AbstractReader;
import org.openstreetmap.josm.io.OsmServerReadPostprocessor;
import org.openstreetmap.josm.plugins.PluginHandler;
import org.openstreetmap.josm.plugins.PluginInformation;
import org.openstreetmap.josm.tools.Destroyable;

/**
* Cleanup plugins if they've been loaded
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(Plugins.PluginExtension.class)
public @interface Plugins {
/**
* The extension to clean up after plugin installs
*/
class PluginExtension implements AfterEachCallback {

@Override
public void afterEach(ExtensionContext context) throws Exception {
// We want to clean up as much as possible using "standard" methods
for (PluginInformation plugin : PluginHandler.getPlugins()) {
Object root = PluginHandler.getPlugin(plugin.name);
if (root instanceof Destroyable) {
((Destroyable) root).destroy();
PluginHandler.removePlugins(Collections.singletonList(plugin));
}
}
final Field pluginListField = PluginHandler.class.getDeclaredField("pluginList");
final Field classLoadersField = PluginHandler.class.getDeclaredField("classLoaders");
final Field postprocessorsField = AbstractReader.class.getDeclaredField("postprocessors");
org.openstreetmap.josm.tools.ReflectionUtils.setObjectsAccessible(classLoadersField, postprocessorsField,
pluginListField);
((List<?>) pluginListField.get(null)).clear();
((Map<?, ?>) classLoadersField.get(null)).clear();
// Needed due to SDS
final Object postprocessors = postprocessorsField.get(null);
if (postprocessors instanceof Collection) {
for (OsmServerReadPostprocessor pp : new ArrayList<>((Collection<OsmServerReadPostprocessor>) postprocessors)) {
AbstractReader.deregisterPostprocessor(pp);
}
}
}
}
}

0 comments on commit 8803b53

Please sign in to comment.