felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pde...@apache.org
Subject svn commit: r1566541 - /felix/sandbox/marrs/dependencymanager-prototype/dm/test/test/SerialExecutorTest.java
Date Mon, 10 Feb 2014 09:32:20 GMT
Author: pderop
Date: Mon Feb 10 09:32:20 2014
New Revision: 1566541

URL: http://svn.apache.org/r1566541
Log:
Added SerialExecutor test.

Added:
    felix/sandbox/marrs/dependencymanager-prototype/dm/test/test/SerialExecutorTest.java

Added: felix/sandbox/marrs/dependencymanager-prototype/dm/test/test/SerialExecutorTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/marrs/dependencymanager-prototype/dm/test/test/SerialExecutorTest.java?rev=1566541&view=auto
==============================================================================
--- felix/sandbox/marrs/dependencymanager-prototype/dm/test/test/SerialExecutorTest.java (added)
+++ felix/sandbox/marrs/dependencymanager-prototype/dm/test/test/SerialExecutorTest.java Mon
Feb 10 09:32:20 2014
@@ -0,0 +1,129 @@
+package test;
+
+import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import dm.impl.Logger;
+import dm.impl.SerialExecutor;
+
+/**
+ * Validates SerialExecutor used by DM implementation.
+ */
+public class SerialExecutorTest {
+    final Random m_rnd = new Random();
+    public enum LogLevel { WARN, INFO, DEBUG, };
+    final static LogLevel m_level = LogLevel.DEBUG;
+    final int TESTS = 10000;
+
+    void debug(String msg) {
+        if (m_level.ordinal() >= LogLevel.DEBUG.ordinal()) {
+            System.out.println("[" + Thread.currentThread().getName() + "] " + msg);
+        }
+    }
+    
+    @Test
+    public void testSerialExecutor() {
+        System.out.println("Testing serial executor");
+        int cores = Math.max(10, Runtime.getRuntime().availableProcessors());
+        ExecutorService threadPool = null;
+
+        try {
+            threadPool = Executors.newFixedThreadPool(cores);
+            final SerialExecutor serial = new SerialExecutor(new Logger(null));
+
+            long timeStamp = System.currentTimeMillis();
+            for (int i = 0; i < TESTS; i++) {
+                final CountDownLatch latch = new CountDownLatch(cores * 2 /* each task reexecutes
itself one time */);
+                final SerialTask task = new SerialTask(serial, latch);
+                for (int j = 0; j < cores; j ++) {
+                    threadPool.execute(new Runnable() {
+                        public void run() {
+                            serial.execute(task);
+                        }
+                    });
+                }
+                Assert.assertTrue("Test " + i + " did not terminate timely", latch.await(20000,
TimeUnit.MILLISECONDS));
+            }
+            long now = System.currentTimeMillis();
+            System.out.println("Performed " + TESTS + " tests in " + (now - timeStamp) +
" ms.");
+            timeStamp = now;
+        }
+
+        catch (Throwable t) {
+            t.printStackTrace();
+            Assert.fail("Test failed: " + t.getMessage());
+        }
+        finally {
+            shutdown(threadPool);
+        }
+    }
+
+    void shutdown(ExecutorService exec) {
+        exec.shutdown();
+        try {
+            exec.awaitTermination(5, TimeUnit.SECONDS);
+        }
+        catch (InterruptedException e) {
+        }
+    }
+
+    class SerialTask implements Runnable {
+        final AtomicReference<Thread> m_executingThread = new AtomicReference<Thread>();
+        final CountDownLatch m_latch;
+        private boolean m_firstExecution;
+        private final SerialExecutor m_exec;          
+        
+        SerialTask(SerialExecutor exec, CountDownLatch latch) {
+            m_latch = latch;
+            m_exec = exec;
+            m_firstExecution = true;
+        }
+        
+        public void run() {
+            Thread self = Thread.currentThread();
+            if (m_firstExecution) {
+                // The first time we are executed, the previous executing thread stored in
our m_executingThread should be null
+                if (!m_executingThread.compareAndSet(null, self)) {
+                    System.out.println("detected concurrent call to SerialTask: currThread="
+ self
+                        + ", other executing thread=" + m_executingThread);
+                    return;
+                }
+            } else {
+                // The second time we are executed, the previous executing thread stored
in our m_executingThread should be 
+                // the current running thread.
+                if (m_executingThread.get() != self) {
+                    System.out.println("expect to execute reentrant tasks in same thread,
but current thread=" + self
+                        + ", while expected is " + m_executingThread);
+                    return;
+                }
+            }
+            
+            try {
+                Thread.sleep(m_rnd.nextInt(1));
+            }
+            catch (InterruptedException e) {
+            }
+            
+            if (m_firstExecution) {
+                m_firstExecution = false;
+                m_exec.execute(this); // Our run method must be called immediately
+            } else {
+                if (! m_executingThread.compareAndSet(self, null)) {
+                    System.out.println("detected concurrent call to SerialTask: currThread="
+ self
+                        + ", other executing thread=" + m_executingThread);
+                    return;                    
+                }
+                m_firstExecution = true;
+            }
+            
+            m_latch.countDown();
+        }
+    }
+}



Mime
View raw message