Ticket #12030: testParallelAccess.patch

File testParallelAccess.patch, 4.8 KB (added by simon04, 5 years ago)
  • new file test/unit/org/openstreetmap/josm/tools/ShortcutTest.java

    diff --git a/test/unit/org/openstreetmap/josm/tools/ShortcutTest.java b/test/unit/org/openstreetmap/josm/tools/ShortcutTest.java
    new file mode 100644
    index 0000000..30cc636
    - +  
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.tools;
     3
     4import java.io.File;
     5import java.io.IOException;
     6import java.lang.reflect.Modifier;
     7import java.net.URL;
     8import java.util.ArrayList;
     9import java.util.Collection;
     10import java.util.Enumeration;
     11import java.util.concurrent.Callable;
     12import java.util.concurrent.ExecutorService;
     13import java.util.concurrent.Executors;
     14import java.util.concurrent.Future;
     15
     16import org.junit.BeforeClass;
     17import org.junit.Test;
     18import org.openstreetmap.josm.JOSMFixture;
     19import org.openstreetmap.josm.actions.JosmAction;
     20
     21public class ShortcutTest {
     22
     23    /**
     24     * Setup test.
     25     */
     26    @BeforeClass
     27    public static void setUpBeforeClass() {
     28        JOSMFixture.createUnitTestFixture().init(true);
     29    }
     30
     31    @Test
     32    public void testParallelAccess() throws Exception {
     33        final Collection<Class> classes = getClasses(JosmAction.class.getPackage().getName());
     34        final Collection<Callable<Object>> instantiations = new ArrayList<>(classes.size());
     35        final Collection<Future<?>> results = new ArrayList<>(classes.size());
     36        for (final Class i : classes) {
     37            if (!Modifier.isAbstract(i.getModifiers())) {
     38                try {
     39                    //noinspection unchecked
     40                    i.getConstructor().isAccessible(); // ignore return value
     41                } catch (NoSuchMethodException | SecurityException ignore) {
     42                    // ignore
     43                    continue;
     44                }
     45                instantiations.add(new Callable<Object>() {
     46                    @Override
     47                    public Object call() throws Exception {
     48                        System.out.println(System.currentTimeMillis() + " " + i);
     49                        return i.newInstance();
     50                    }
     51                });
     52            }
     53        }
     54        final ExecutorService executor = Executors.newFixedThreadPool(classes.size());
     55        System.out.println("Initializing " + instantiations.size() + " actions");
     56        for (Callable<Object> i : instantiations) {
     57            results.add(executor.submit(i));
     58        }
     59        for (Future<?> i : results) {
     60            i.get();
     61        }
     62        executor.shutdown();
     63    }
     64
     65    /**
     66     * Scans all classes accessible from the context class loader which belong to the given package and subpackages.
     67     *
     68     * @param packageName The base package
     69     * @return The classes
     70     * @throws ClassNotFoundException
     71     * @throws IOException
     72     */
     73    private static Collection<Class> getClasses(String packageName) throws ClassNotFoundException, IOException {
     74        // from https://dzone.com/articles/get-all-classes-within-package
     75        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
     76        assert classLoader != null;
     77        String path = packageName.replace('.', '/');
     78        Enumeration<URL> resources = classLoader.getResources(path);
     79        Collection<File> dirs = new ArrayList<>();
     80        while (resources.hasMoreElements()) {
     81            URL resource = resources.nextElement();
     82            dirs.add(new File(resource.getFile()));
     83        }
     84        Collection<Class> classes = new ArrayList<>();
     85        for (File directory : dirs) {
     86            classes.addAll(findClasses(directory, packageName));
     87        }
     88        return classes;
     89    }
     90
     91    /**
     92     * Recursive method used to find all classes in a given directory and subdirs.
     93     *
     94     * @param directory   The base directory
     95     * @param packageName The package name for classes found inside the base directory
     96     * @return The classes
     97     * @throws ClassNotFoundException
     98     */
     99    private static Collection<Class> findClasses(File directory, String packageName) throws ClassNotFoundException {
     100        // from https://dzone.com/articles/get-all-classes-within-package
     101        Collection<Class> classes = new ArrayList<>();
     102        if (!directory.exists()) {
     103            return classes;
     104        }
     105        File[] files = directory.listFiles();
     106        assert files != null;
     107        for (File file : files) {
     108            if (file.isDirectory()) {
     109                assert !file.getName().contains(".");
     110                classes.addAll(findClasses(file, packageName + "." + file.getName()));
     111            } else if (file.getName().endsWith(".class")) {
     112                classes.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6)));
     113            }
     114        }
     115        return classes;
     116    }
     117}