SLING-1963 - use ThreadLocal to pass context to TestAllPaths

git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1074568 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/sling/junit/scriptable/ScriptableTestsProvider.java b/src/main/java/org/apache/sling/junit/scriptable/ScriptableTestsProvider.java
index a13490e..6e5db15 100644
--- a/src/main/java/org/apache/sling/junit/scriptable/ScriptableTestsProvider.java
+++ b/src/main/java/org/apache/sling/junit/scriptable/ScriptableTestsProvider.java
@@ -61,6 +61,24 @@
     public static final String SLING_TEST_NODETYPE = "sling:Test";
     public static final String TEST_CLASS_NAME = ScriptableTestsProvider.class.getName();
     
+    /** Context that's passed to TestAllPaths */
+    static class TestContext {
+        final List<String> testPaths;
+        final SlingRequestProcessor requestProcessor;
+        final ResourceResolver resourceResolver;
+
+        TestContext(List<String> p, SlingRequestProcessor rp, ResourceResolver rr) {
+            testPaths = p;
+            requestProcessor = rp;
+            resourceResolver = rr;
+        }
+    }
+    
+    /** Need a ThreadLocal to pass context, as it's JUnit who instantiates the
+     *  test classes, we can't easily decorate them (AFAIK).
+     */
+    static final ThreadLocal<TestContext> testContext = new ThreadLocal<TestContext>(); 
+    
     /** We only consider test resources under the search path
      *  of the JCR resource resolver. These paths are supposed 
      *  to be secured, as they contain other admin stuff anyway, 
@@ -147,9 +165,7 @@
         if(testPaths.size() == 0) {
             return ExplainTests.class;
         } else {
-            TestAllPaths.testPaths = testPaths;
-            TestAllPaths.requestProcessor = requestProcessor;
-            TestAllPaths.resolver = resolver;
+            testContext.set(new TestContext(testPaths, requestProcessor, resolver));
             return TestAllPaths.class;
         }
     }
@@ -206,4 +222,8 @@
     public long lastModified() {
         return lastModified;
     }
+    
+    static TestContext getTestContext() {
+        return testContext.get();
+    }
 }
diff --git a/src/main/java/org/apache/sling/junit/scriptable/TestAllPaths.java b/src/main/java/org/apache/sling/junit/scriptable/TestAllPaths.java
index 328f1f4..dac2976 100644
--- a/src/main/java/org/apache/sling/junit/scriptable/TestAllPaths.java
+++ b/src/main/java/org/apache/sling/junit/scriptable/TestAllPaths.java
@@ -23,12 +23,8 @@
 import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.List;
 
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.engine.SlingRequestProcessor;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
+import org.apache.sling.junit.scriptable.ScriptableTestsProvider.TestContext;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -38,40 +34,19 @@
 @RunWith(Parameterized.class)
 public class TestAllPaths {
 
-    private String path;
-    private static boolean executing = false;
+    private final String path;
     public static final String TEST_URL_SUFFIX = ".test.txt";
     public static final String PASSED = "TEST_PASSED";
     
-    // TODO can we do better than this to inject our environment here?
-    static List<String> testPaths;
-    static SlingRequestProcessor requestProcessor;
-    static ResourceResolver resolver;
-
     public TestAllPaths(String path) {
         this.path = path;
     }
     
-    // Due to our use of static context, only one instance of this test can
-    // execute at any given time.
-    @BeforeClass
-    public static void checkConcurrency() {
-        if(executing) {
-            fail("Concurrent execution detected, not supported by this class");
-        }
-        executing = true;
-    }
-
-    @AfterClass
-    public static void cleanup() {
-        executing = false;
-    }
-
     /** Let JUnit run this all on our paths */
     @Parameters
     public static Collection<Object[]> data() {
         Collection<Object[]> data = new ArrayList<Object[]>();
-        for(String path : testPaths) {
+        for(String path : ScriptableTestsProvider.getTestContext().testPaths) {
             data.add(new Object[] { path + TEST_URL_SUFFIX });
         }
         return data;
@@ -79,11 +54,12 @@
 
     @Test
     public void verifyContent() throws Exception {
+        final TestContext ctx = ScriptableTestsProvider.getTestContext();
         
         // Get content via internal Sling request
         final HttpRequest req = new HttpRequest(path);
         final HttpResponse resp = new HttpResponse();
-        requestProcessor.processRequest(req, resp, resolver);
+        ctx.requestProcessor.processRequest(req, resp, ctx.resourceResolver);
         final String content = resp.getContent();
         assertEquals("Expecting HTTP status 200 for path " + path, 200, resp.getStatus());
         
@@ -106,5 +82,4 @@
             }
         }
     }
-}
-
+}
\ No newline at end of file