source: josm/trunk/test/unit/org/openstreetmap/josm/plugins/PluginHandlerTestIT.java@ 11241

Last change on this file since 11241 was 10988, checked in by Don-vip, 8 years ago

improve plugin integration test

File size: 7.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.plugins;
3
4import static org.junit.Assert.assertEquals;
5import static org.junit.Assert.assertFalse;
6import static org.junit.Assert.assertTrue;
7
8import java.util.Arrays;
9import java.util.Collection;
10import java.util.HashMap;
11import java.util.Iterator;
12import java.util.List;
13import java.util.Map;
14import java.util.Set;
15import java.util.function.Consumer;
16import java.util.stream.Collectors;
17
18import org.apache.commons.collections.MapUtils;
19import org.apache.commons.lang.exception.ExceptionUtils;
20import org.junit.BeforeClass;
21import org.junit.Rule;
22import org.junit.Test;
23import org.junit.rules.Timeout;
24import org.openstreetmap.josm.JOSMFixture;
25import org.openstreetmap.josm.Main;
26import org.openstreetmap.josm.data.gpx.GpxData;
27import org.openstreetmap.josm.data.osm.DataSet;
28import org.openstreetmap.josm.gui.layer.GpxLayer;
29import org.openstreetmap.josm.gui.layer.Layer;
30import org.openstreetmap.josm.gui.layer.OsmDataLayer;
31import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
32import org.openstreetmap.josm.plugins.PluginHandler.DynamicURLClassLoader;
33
34import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
35
36/**
37 * Integration tests of {@link PluginHandler} class.
38 */
39public class PluginHandlerTestIT {
40
41 /**
42 * Global timeout applied to all test methods.
43 */
44 @Rule
45 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
46 public Timeout globalTimeout = Timeout.seconds(10*60);
47
48 /**
49 * Setup test.
50 */
51 @BeforeClass
52 public static void setUp() {
53 JOSMFixture.createUnitTestFixture().init(true);
54 }
55
56 /**
57 * Test that available plugins rules can be loaded.
58 */
59 @Test
60 public void testValidityOfAvailablePlugins() {
61 // Download complete list of plugins
62 ReadRemotePluginInformationTask pluginInfoDownloadTask = new ReadRemotePluginInformationTask(
63 Main.pref.getOnlinePluginSites());
64 pluginInfoDownloadTask.run();
65 List<PluginInformation> plugins = pluginInfoDownloadTask.getAvailablePlugins();
66 System.out.println("Original plugin list contains " + plugins.size() + " plugins");
67 assertFalse(plugins.isEmpty());
68 PluginInformation info = plugins.get(0);
69 assertFalse(info.getName().isEmpty());
70 assertFalse(info.getClass().getName().isEmpty());
71
72 // Filter deprecated and unmaintained ones, or those not responsive enough to match our continuous integration needs
73 List<String> uncooperatingPlugins = Arrays.asList("ebdirigo", "scoutsigns");
74 Set<String> deprecatedPlugins = PluginHandler.getDeprecatedAndUnmaintainedPlugins();
75 for (Iterator<PluginInformation> it = plugins.iterator(); it.hasNext();) {
76 PluginInformation pi = it.next();
77 if (deprecatedPlugins.contains(pi.name) || uncooperatingPlugins.contains(pi.name)) {
78 System.out.println("Ignoring " + pi.name + " (deprecated, unmaintained, or uncooperative)");
79 it.remove();
80 }
81 }
82 System.out.println("Filtered plugin list contains " + plugins.size() + " plugins");
83
84 // Download plugins
85 downloadPlugins(plugins);
86
87 // Load early plugins
88 PluginHandler.loadEarlyPlugins(null, plugins, null);
89
90 // Load late plugins
91 PluginHandler.loadLatePlugins(null, plugins, null);
92
93 Map<String, Throwable> loadingExceptions = PluginHandler.pluginLoadingExceptions.entrySet().stream()
94 .collect(Collectors.toMap(e -> e.getKey(), e -> ExceptionUtils.getRootCause(e.getValue())));
95
96 // Add/remove layers twice to test basic plugin good behaviour
97 Map<String, Throwable> layerExceptions = new HashMap<>();
98 List<PluginInformation> loadedPlugins = PluginHandler.getPlugins();
99 for (int i = 0; i < 2; i++) {
100 OsmDataLayer layer = new OsmDataLayer(new DataSet(), "Layer "+i, null);
101 testPlugin(Main.getLayerManager()::addLayer, layer, layerExceptions, loadedPlugins);
102 testPlugin(Main.getLayerManager()::removeLayer, layer, layerExceptions, loadedPlugins);
103 }
104 for (int i = 0; i < 2; i++) {
105 GpxLayer layer = new GpxLayer(new GpxData());
106 testPlugin(Main.getLayerManager()::addLayer, layer, layerExceptions, loadedPlugins);
107 testPlugin(Main.getLayerManager()::removeLayer, layer, layerExceptions, loadedPlugins);
108 }
109
110 MapUtils.debugPrint(System.out, null, loadingExceptions);
111 MapUtils.debugPrint(System.out, null, layerExceptions);
112 String msg = Arrays.toString(loadingExceptions.entrySet().toArray()) + '\n' +
113 Arrays.toString(layerExceptions.entrySet().toArray());
114 assertTrue(msg, loadingExceptions.isEmpty() && layerExceptions.isEmpty());
115 }
116
117 void testPlugin(Consumer<Layer> consumer, Layer layer,
118 Map<String, Throwable> layerExceptions, Collection<PluginInformation> loadedPlugins) {
119 try {
120 consumer.accept(layer);
121 } catch (Exception | LinkageError t) {
122 Throwable root = ExceptionUtils.getRootCause(t);
123 root.printStackTrace();
124 layerExceptions.put(findFaultyPlugin(loadedPlugins, root), root);
125 }
126 }
127
128 private static String findFaultyPlugin(Collection<PluginInformation> plugins, Throwable root) {
129 DynamicURLClassLoader cl = PluginHandler.getPluginClassLoader();
130 for (PluginInformation p : plugins) {
131 try {
132 String pluginPackage = cl.loadClass(p.className).getPackage().getName();
133 for (StackTraceElement e : root.getStackTrace()) {
134 try {
135 String stackPackage = cl.loadClass(e.getClassName()).getPackage().getName();
136 if (stackPackage.startsWith(pluginPackage)) {
137 return p.name;
138 }
139 } catch (ClassNotFoundException ex) {
140 System.err.println(ex.getMessage());
141 continue;
142 }
143 }
144 } catch (ClassNotFoundException ex) {
145 System.err.println(ex.getMessage());
146 continue;
147 }
148 }
149 return "<unknown>";
150 }
151
152 /**
153 * Download plugins
154 * @param plugins plugins to download
155 */
156 public static void downloadPlugins(Collection<PluginInformation> plugins) {
157 // Update the locally installed plugins
158 PluginDownloadTask pluginDownloadTask = new PluginDownloadTask(NullProgressMonitor.INSTANCE, plugins, null);
159 // Increase default timeout to avoid random network errors on big jar files
160 int defTimeout = Main.pref.getInteger("socket.timeout.read", 30);
161 Main.pref.putInteger("socket.timeout.read", 2 * defTimeout);
162 pluginDownloadTask.run();
163 // Restore default timeout
164 Main.pref.putInteger("socket.timeout.read", defTimeout);
165 assertTrue(pluginDownloadTask.getFailedPlugins().toString(), pluginDownloadTask.getFailedPlugins().isEmpty());
166 assertEquals(plugins.size(), pluginDownloadTask.getDownloadedPlugins().size());
167
168 // Update Plugin info for downloaded plugins
169 PluginHandler.refreshLocalUpdatedPluginInfo(pluginDownloadTask.getDownloadedPlugins());
170 }
171}
Note: See TracBrowser for help on using the repository browser.