sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 01/02: Complete parameterized types in collections. Add documentation. Use longer timeout as a safety in case the test is executed on a busy CI system (this is only a maximal wait; the actual waiting time should be much shorter). IF the executor is not terminated after the test, it is a test failure because it would be a bug in our algorithm (because we already waited in Future.get()).
Date Wed, 03 Jun 2020 21:36:26 GMT
This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit e7ec5369d152e58f3ce4d3ef863d9f6bf7e6edfc
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Wed Jun 3 19:36:59 2020 +0200

    Complete parameterized types in collections. Add documentation.
    Use longer timeout as a safety in case the test is executed on a busy CI system
    (this is only a maximal wait; the actual waiting time should be much shorter).
    IF the executor is not terminated after the test, it is a test failure because
    it would be a bug in our algorithm (because we already waited in Future.get()).
---
 .../org/apache/sis/storage/DataStoresTest.java     | 85 ++++++++++++++--------
 1 file changed, 53 insertions(+), 32 deletions(-)

diff --git a/storage/sis-storage/src/test/java/org/apache/sis/storage/DataStoresTest.java
b/storage/sis-storage/src/test/java/org/apache/sis/storage/DataStoresTest.java
index b504611..ccae2ff 100644
--- a/storage/sis-storage/src/test/java/org/apache/sis/storage/DataStoresTest.java
+++ b/storage/sis-storage/src/test/java/org/apache/sis/storage/DataStoresTest.java
@@ -32,14 +32,15 @@ import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
-import static org.junit.Assert.*;
+import static org.apache.sis.test.Assert.*;
 
 
 /**
  * Tests {@link DataStores}.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @author  Alexis Manin (Geomatys)
+ * @version 1.1
  * @since   0.4
  * @module
  */
@@ -67,49 +68,69 @@ public final strictfp class DataStoresTest extends TestCase {
         assertFalse(store.getMetadata().getContacts().isEmpty());
     }
 
-
+    /**
+     * Fetches the providers in concurrent threads and verifies that all of them created
the same set of providers.
+     *
+     * @throws Exception if a thread has been interrupted or a timeout occurred.
+     */
     @Test
     public void datastore_registry_must_be_thread_safe() throws Exception {
-        final ExecutorService exec = Executors.newFixedThreadPool(6);
-        try {
-            List<Set> allResults = new ArrayList<>();
-            for (int i = 4; i <= 6; i++) allResults.addAll(collectProvidersConcurrently(i,
exec));
-
-            for (int i = 1; i < allResults.size() - 1; i++) {
-                assertEquals(
-                        "Index " + i,
-                        allResults.get(i - 1),
-                        allResults.get(i)
-                );
-            }
-            exec.shutdown();
-            exec.awaitTermination(1, TimeUnit.SECONDS);
-        } finally {
-            exec.shutdownNow();
+        final int maxNbWorkers = 6;
+        final ExecutorService exec = Executors.newFixedThreadPool(maxNbWorkers);
+        final List<Set<Class<?>>> allResults = new ArrayList<>();
+        for (int nbWorkers = 4; nbWorkers <= maxNbWorkers; nbWorkers++) {
+            allResults.addAll(collectProvidersConcurrently(nbWorkers, exec));
         }
+        exec.shutdown();
+        /*
+         * All sets shall have the same content. Arbitrarily compare each list element
+         * with the previous element, but any other combination should be equivalent.
+         */
+        for (int i = 1; i < allResults.size(); i++) {
+            assertSetEquals(allResults.get(i - 1), allResults.get(i));
+        }
+        exec.awaitTermination(10, TimeUnit.SECONDS);        // Wait will be much shorter
in practice.
+        assertTrue(exec.isTerminated());
     }
 
-    private List<Set<Class>> collectProvidersConcurrently(int nbWorkers, final
ExecutorService executor) throws Exception {
+    /**
+     * Starts the specified amount of worker threads where each thread ask for the set of
providers.
+     *
+     * @param  nbWorkers  number of concurrent threads.
+     * @param  executor   the executor to use for running the threads.
+     * @return the set of of providers found by each thread.
+     *         All sets should be equal, but that verification is not done by this method.
+     * @throws Exception if a thread has been interrupted or a timeout occurred.
+     */
+    private static List<Set<Class<?>>> collectProvidersConcurrently(final
int nbWorkers, final ExecutorService executor)
+            throws Exception
+    {
         final DataStoreRegistry dsr = new DataStoreRegistry(DataStoresTest.class.getClassLoader());
         final CyclicBarrier startSignal = new CyclicBarrier(nbWorkers);
-        Callable<Set> collectProviderClasses = () -> {
-            startSignal.await(1, TimeUnit.SECONDS);
-            Set<Class> result = new HashSet<>();
-            for (DataStoreProvider p : dsr.providers()) result.add(p.getClass());
+        final Callable<Set<Class<?>>> collectProviderClasses = () ->
{
+            final Set<Class<?>> result = new HashSet<>();
+            startSignal.await(10, TimeUnit.SECONDS);                        // Wait until
all workers are ready.
+            for (DataStoreProvider p : dsr.providers()) {                   // This is the
iteration to test.
+                result.add(p.getClass());
+            }
             return result;
         };
-
-        final List<Future<Set>> tasks = new ArrayList<>(nbWorkers);
+        /*
+         * All threads will execute the same task — `collectProviderClasses` — but a
separated list is created
+         * by each worker. A cyclic barrier is used for making sure that all threads start
their iterations in
+         * same time.
+         */
+        final List<Future<Set<Class<?>>>> tasks = new ArrayList<>(nbWorkers);
         for (int i = 0 ; i < nbWorkers ; i++) {
             tasks.add(executor.submit(collectProviderClasses));
         }
-
-        final List<Set<Class>> results = new ArrayList<>(nbWorkers);
-        for (int i = 0 ; i < nbWorkers ; i++) {
-            Set workerResult = tasks.get(i).get(2, TimeUnit.SECONDS);
-            results.add(workerResult);
+        /*
+         * Wait for each thread to finish its test and collect the results. Analysis will
be done by the caller.
+         */
+        final List<Set<Class<?>>> results = new ArrayList<>(nbWorkers);
+        for (final Future<Set<Class<?>>> workerResult : tasks) {
+            results.add(workerResult.get(10, TimeUnit.SECONDS));            // Wait will
be much shorter in practice.
         }
-
         return results;
     }
 }


Mime
View raw message