You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 10:20:41 UTC

[sling-org-apache-sling-testing-rules] annotated tag org.apache.sling.testing.rules-1.0.0 created (now 56caef1)

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a change to annotated tag org.apache.sling.testing.rules-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-rules.git.


      at 56caef1  (tag)
 tagging 4d67a6a7d50a6aa2e1447b573de457df1a9878f9 (commit)
      by Andrei Dulvac
      on Mon Sep 19 14:40:12 2016 +0000

- Log -----------------------------------------------------------------
org.apache.sling.testing.rules-1.0.0
-----------------------------------------------------------------------

This annotated tag includes the following new commits:

     new cfb4095  SLING-5703 - new junit/rules module, extracted and enhanced from testing/tools. Contributed by Andrei Dulvac, thanks!
     new eecf890  README.md enhancements provided by Andrei Dulvac, thanks!
     new a699de1  SLING-5727 Remove o.a.s.testing.tools dependency in o.a.s.testing.serversetup and adapt http code
     new 5c3d905  SLING-5803 FilterRuleExcludeCategoryIgnoreIfTest fails on Jenkins * Added an assumption that the system property is still there for test
     new 16ce500  SLING-5803 FilterRuleExcludeCategoryIgnoreIfTest fails on Jenkins * Removed flaky test
     new b1cc7e9  SLING-5803 - FilterRuleExcludeCategoryIgnoreIfTest fails on Jenkins
     new 21f933c  Removed unused import in testing rules
     new 7990f95  temporarily updated dep to org.apache.sling.testing.clients
     new 9391cad  [maven-release-plugin] prepare release org.apache.sling.testing.rules-1.0.0
     new 8d97d12  temporarily updated dep to org.apache.sling.testing.clients
     new dda01e5  [maven-release-plugin] prepare release org.apache.sling.testing.rules-1.0.0
     new d5d8b3f  temporarily updated dep to org.apache.sling.testing.clients
     new f59a383  [maven-release-plugin] prepare release org.apache.sling.testing.rules-1.0.0
     new 4d67a6a  [maven-release-plugin] copy for tag org.apache.sling.testing.rules-1.0.0

The 14 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


-- 
To stop receiving notification emails like this one, please contact
['"commits@sling.apache.org" <co...@sling.apache.org>'].

[sling-org-apache-sling-testing-rules] 08/14: temporarily updated dep to org.apache.sling.testing.clients

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.rules-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-rules.git

commit 7990f9592393cd30aff0aa976b961fea963ccee2
Author: Andrei Dulvac <du...@apache.org>
AuthorDate: Mon Sep 19 14:30:17 2016 +0000

    temporarily updated dep to org.apache.sling.testing.clients
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/junit/rules@1761453 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/pom.xml b/pom.xml
index 7f99b59..e3278c3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -72,12 +72,12 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.testing.clients</artifactId>
-            <version>0.1.0-SNAPSHOT</version>
+            <version>1.0.0</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.testing.serversetup</artifactId>
-            <version>0.1.0-SNAPSHOT</version>
+            <version>1.0.0</version>
             <exclusions>
                 <exclusion>
                     <groupId>org.apache.sling</groupId>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-testing-rules] 13/14: [maven-release-plugin] prepare release org.apache.sling.testing.rules-1.0.0

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.rules-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-rules.git

commit f59a383d95ec077605e827f7d3adfd9fe6cdf31d
Author: Andrei Dulvac <du...@apache.org>
AuthorDate: Mon Sep 19 14:39:59 2016 +0000

    [maven-release-plugin] prepare release org.apache.sling.testing.rules-1.0.0
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/junit/rules@1761458 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/pom.xml b/pom.xml
index 0fe57be..cf348c4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,7 +28,7 @@
     </parent>
 
     <artifactId>org.apache.sling.testing.rules</artifactId>
-    <version>1.0.0-SNAPSHOT</version>
+    <version>1.0.0</version>
     <packaging>bundle</packaging>
 
     <name>Apache Sling Testing Rules</name>
@@ -37,9 +37,9 @@
     </description>
     
     <scm>
-        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/testing/junit/rules</connection>
-        <developerConnection> scm:svn:https://svn.apache.org/repos/asf/sling/trunk/testing/junit/rules</developerConnection>
-        <url>http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules</url>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/tags/org.apache.sling.testing.rules-1.0.0</connection>
+        <developerConnection> scm:svn:https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.testing.rules-1.0.0</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/tags/org.apache.sling.testing.rules-1.0.0</url>
     </scm>
 
     <build>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-testing-rules] 14/14: [maven-release-plugin] copy for tag org.apache.sling.testing.rules-1.0.0

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.rules-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-rules.git

commit 4d67a6a7d50a6aa2e1447b573de457df1a9878f9
Author: Andrei Dulvac <du...@apache.org>
AuthorDate: Mon Sep 19 14:40:12 2016 +0000

    [maven-release-plugin] copy for tag org.apache.sling.testing.rules-1.0.0
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.testing.rules-1.0.0@1761459 13f79535-47bb-0310-9956-ffa450edef68

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-testing-rules] 05/14: SLING-5803 FilterRuleExcludeCategoryIgnoreIfTest fails on Jenkins * Removed flaky test

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.rules-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-rules.git

commit 16ce500ec634e0508d910b7748ad3a3707428b61
Author: Andrei Dulvac <du...@apache.org>
AuthorDate: Tue Jul 12 16:14:20 2016 +0000

    SLING-5803 FilterRuleExcludeCategoryIgnoreIfTest fails on Jenkins
    * Removed flaky test
    
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/junit/rules@1752312 13f79535-47bb-0310-9956-ffa450edef68
---
 .../rules/util/filterrule/FilterRuleExcludeCategoryTest.java | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryTest.java b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryTest.java
index ddc2de4..6d0b47e 100644
--- a/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryTest.java
+++ b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryTest.java
@@ -72,17 +72,7 @@ public class FilterRuleExcludeCategoryTest {
     public void testIgnoreIfPropExixtsandExcludedCategoryNotExists() {
         Assert.assertTrue("Test should be Run", true);
     }
-
-    /*
-     * System prop is set for excluding a category only Setup: a test is annotated with @Category which is excluded
-     * Result: The test is skipped
-     */
-    @Test
-    @Category(Issue.class)
-    public void testExcludedCategoryExists() {
-        Assume.assumeTrue(System.getProperty(FilterRule.CATEGORY_PROPERTY).equals("Issue"));
-        Assert.fail("Test should be Ignored");
-    }
+    
 
     /*
      * System prop is set for excluding a category only Setup: a test is annotated with @Category which is not

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-testing-rules] 04/14: SLING-5803 FilterRuleExcludeCategoryIgnoreIfTest fails on Jenkins * Added an assumption that the system property is still there for test

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.rules-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-rules.git

commit 5c3d905fe9917da887c4c979afd0818fa5291acc
Author: Andrei Dulvac <du...@apache.org>
AuthorDate: Tue Jul 12 12:07:27 2016 +0000

    SLING-5803 FilterRuleExcludeCategoryIgnoreIfTest fails on Jenkins
    * Added an assumption that the system property is still there for test
    
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/junit/rules@1752284 13f79535-47bb-0310-9956-ffa450edef68
---
 .../rules/util/filterrule/FilterRuleExcludeCategoryIgnoreIfTest.java   | 3 +++
 .../junit/rules/util/filterrule/FilterRuleExcludeCategoryTest.java     | 2 ++
 .../rules/util/filterrule/FilterRuleIncludeCategoryIgnoreIfTest.java   | 2 +-
 3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryIgnoreIfTest.java b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryIgnoreIfTest.java
index 360ca6b..a542b84 100644
--- a/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryIgnoreIfTest.java
+++ b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryIgnoreIfTest.java
@@ -23,11 +23,13 @@ import org.apache.sling.testing.junit.rules.category.FailingTest;
 import org.apache.sling.testing.junit.rules.category.SlowRunningTest;
 import org.apache.sling.testing.junit.rules.util.IgnoreTestsConfig;
 import org.junit.Assert;
+import org.junit.Assume;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.junit.rules.TestName;
 
+//TODO use a better way to test this
 public class FilterRuleExcludeCategoryIgnoreIfTest {
 
     @Rule
@@ -92,6 +94,7 @@ public class FilterRuleExcludeCategoryIgnoreIfTest {
     @Test
     @Category(Issue.class)
     public void testExcludedCategoryExists() {
+        Assume.assumeTrue(System.getProperty(FilterRule.CATEGORY_PROPERTY).equals("Issue,SlowRunningTest"));
         Assert.fail("Test should be Ignored");
     }
 
diff --git a/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryTest.java b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryTest.java
index a2bdb87..ddc2de4 100644
--- a/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryTest.java
+++ b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryTest.java
@@ -22,6 +22,7 @@ import org.apache.sling.testing.junit.rules.annotation.Issue;
 import org.apache.sling.testing.junit.rules.category.FailingTest;
 import org.apache.sling.testing.junit.rules.util.IgnoreTestsConfig;
 import org.junit.Assert;
+import org.junit.Assume;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
@@ -79,6 +80,7 @@ public class FilterRuleExcludeCategoryTest {
     @Test
     @Category(Issue.class)
     public void testExcludedCategoryExists() {
+        Assume.assumeTrue(System.getProperty(FilterRule.CATEGORY_PROPERTY).equals("Issue"));
         Assert.fail("Test should be Ignored");
     }
 
diff --git a/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleIncludeCategoryIgnoreIfTest.java b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleIncludeCategoryIgnoreIfTest.java
index 3060fcb..84591a2 100644
--- a/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleIncludeCategoryIgnoreIfTest.java
+++ b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleIncludeCategoryIgnoreIfTest.java
@@ -70,7 +70,7 @@ public class FilterRuleIncludeCategoryIgnoreIfTest {
     @Test
     @IgnoreIfProperty(name = "test.filterrule.a", value = "a")
     @Category(FailingTest.class)
-    public void testIgnoreIfPropExixtsandIncludedCategoryNotExists() {
+    public void testIgnoreIfPropExistsandIncludedCategoryNotExists() {
         Assert.fail("Test should be Ignored");
     }
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-testing-rules] 09/14: [maven-release-plugin] prepare release org.apache.sling.testing.rules-1.0.0

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.rules-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-rules.git

commit 9391cad5dc8077f228b14c74e7833dc3b355e679
Author: Andrei Dulvac <du...@apache.org>
AuthorDate: Mon Sep 19 14:30:54 2016 +0000

    [maven-release-plugin] prepare release org.apache.sling.testing.rules-1.0.0
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/junit/rules@1761454 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/pom.xml b/pom.xml
index e3278c3..9a3794b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,7 +28,7 @@
     </parent>
 
     <artifactId>org.apache.sling.testing.rules</artifactId>
-    <version>0.1.0-SNAPSHOT</version>
+    <version>1.0.0</version>
     <packaging>bundle</packaging>
 
     <name>Apache Sling Testing Rules</name>
@@ -37,9 +37,9 @@
     </description>
     
     <scm>
-        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/testing/http/rules</connection>
-        <developerConnection> scm:svn:https://svn.apache.org/repos/asf/sling/trunk/testing/http/rules</developerConnection>
-        <url>http://svn.apache.org/viewvc/sling/trunk/testing/http/rules</url>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/tags/org.apache.sling.testing.rules-1.0.0</connection>
+        <developerConnection> scm:svn:https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.testing.rules-1.0.0</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/tags/org.apache.sling.testing.rules-1.0.0</url>
     </scm>
     
     <build>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-testing-rules] 02/14: README.md enhancements provided by Andrei Dulvac, thanks!

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.rules-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-rules.git

commit eecf890db2d0e2348d340bc0829128acb6ab242a
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Tue May 3 08:20:23 2016 +0000

    README.md enhancements provided by Andrei Dulvac, thanks!
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/junit/rules@1742067 13f79535-47bb-0310-9956-ffa450edef68
---
 README.md | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..999dedc
--- /dev/null
+++ b/README.md
@@ -0,0 +1,61 @@
+# Sling Http Testing Rules
+The Sling Http Testing Rules allow writing integration tests easily. They are primarily meant to be used for tests that use http against 
+a Sling instance and make use of the `org.apache.sling.testing.clients` which offer a simple, immutable and extendable way of working 
+with specialized http clients.
+
+The junit rules incorporate boiler-plate logic that is shared in tests and take the modern approach of using junit rules rather than 
+inheritance. The `SlingRule` (for methods) or `SlingClassRule` are base rules, chaining other rules like `TestTimeoutRule`, 
+`TestDescriptionRule`, `FilterRule`. The `SlingInstanceRule` extends that and starts a Sling instance if needed and also allows 
+instantiating a `SlingClient` pointing to the instance - base url, credentials, etc.
+    
+
+## <a name="starting"></a> Starting an Integration Test
+Starting an integration is very simple out of the box, but is very extendable, both by combining or configuring the junit rules and by 
+using the versatile `SlingClient` (which can be extended or adapted by calling `adaptTo(MyClient.class)` without losing the client 
+configuration)
+ 
+### Simple Example using SlingInstanceRule
+
+```java   
+    public class MySimpleIT {
+    
+        @ClassRule
+        public static SlingInstanceRule instanceRule = new SlingInstanceRule();
+    
+        @Rule
+        public SlingRule methodRule = new SlingRule(); // will configure test timeout, description, etc.
+    
+        @Test
+        public void testChangeOSGiConfig() {
+           SlingClient client = instanceRule.getAdminClient();
+           client.createNode("/content/myNode", "nt:unstructured");
+           Assert.assertTrue("Node should be there", client.exists("/content/myNode"));
+        }
+            
+    } 
+```
+ 
+### Example using SlingInstanceRule and the clients
+
+```java   
+    public class MyOSGiIT {
+        @ClassRule
+        public static SlingInstanceRule instanceRule = new SlingInstanceRule();
+    
+        @Rule
+        public SlingRule methodRule = new SlingRule(); // will configure test timeout, description, etc.
+    
+        @Test
+        public void testChangeOSGiConfig() {
+           OsgiConsoleClient osgiClient = instanceRule.getAdminClient(OsgiConsoleClient.class);
+           // Save osgi config for pid (to be restored later) 
+           InstanceConfig osgiConfig = new OsgiInstanceConfig(osgiClient, "MYPID").save();
+           // edit the config for this test
+           osgiClient.editConfigurationWithWait(20, "MYPID", null, myMap);
+           SlingHttpResponse response = osgiClient.adaptTo(MyClient.class).myClientMethod();
+           response.checkContentContains("my expected content");
+           osgiConfig.restore();
+        }
+            
+    } 
+```
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-testing-rules] 03/14: SLING-5727 Remove o.a.s.testing.tools dependency in o.a.s.testing.serversetup and adapt http code

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.rules-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-rules.git

commit a699de10b84f003078aca2104ec76f94c3f7ccf8
Author: Andrei Dulvac <du...@apache.org>
AuthorDate: Wed Jun 15 15:00:53 2016 +0000

    SLING-5727 Remove o.a.s.testing.tools dependency in o.a.s.testing.serversetup and adapt http code
    
    
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/junit/rules@1748593 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                                      | 12 ++++++------
 .../apache/sling/testing/junit/rules/SlingInstanceRule.java  |  6 +++---
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/pom.xml b/pom.xml
index d7596a4..7f99b59 100644
--- a/pom.xml
+++ b/pom.xml
@@ -73,10 +73,15 @@
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.testing.clients</artifactId>
             <version>0.1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.serversetup</artifactId>
+            <version>0.1.0-SNAPSHOT</version>
             <exclusions>
                 <exclusion>
                     <groupId>org.apache.sling</groupId>
-                    <artifactId>org.apache.sling.testing.tools</artifactId>
+                    <artifactId>org.apache.sling.testing.clients</artifactId>
                 </exclusion>
             </exclusions>
         </dependency>
@@ -111,10 +116,5 @@
             <version>4.12</version>
             <scope>compile</scope>
         </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.testing.tools</artifactId>
-            <version>1.0.12</version>
-        </dependency>
     </dependencies>
 </project>
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/SlingInstanceRule.java b/src/main/java/org/apache/sling/testing/junit/rules/SlingInstanceRule.java
index 0e8439f..80d33a4 100644
--- a/src/main/java/org/apache/sling/testing/junit/rules/SlingInstanceRule.java
+++ b/src/main/java/org/apache/sling/testing/junit/rules/SlingInstanceRule.java
@@ -22,7 +22,7 @@ import org.apache.sling.testing.clients.SlingClient;
 import org.apache.sling.testing.clients.instance.InstanceConfiguration;
 import org.apache.sling.testing.junit.rules.instance.ExistingInstance;
 import org.apache.sling.testing.junit.rules.instance.Instance;
-import org.apache.sling.testing.tools.sling.SlingTestBase;
+import org.apache.sling.testing.serversetup.instance.SlingTestBase;
 import org.junit.rules.RuleChain;
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
@@ -36,6 +36,7 @@ import java.net.URI;
  * Junit Rule that allows access to a Sling instance.
  * It is wrapped by a {@link SlingClassRule}
  */
+@SuppressWarnings("ALL")
 public class SlingInstanceRule implements TestRule {
 
     // Until we extract this logic from SlingTestBase, we can just reuse it here
@@ -53,8 +54,7 @@ public class SlingInstanceRule implements TestRule {
     /** ExistingInstance for default instance */
     public final Instance defaultInstance = new ExistingInstance().withRunMode("default").orDefault(DEFAULT_INSTANCE);
 
-    protected TestRule ruleChain = RuleChain.outerRule(slingClassRule)
-            .around(defaultInstance);
+    protected TestRule ruleChain = RuleChain.outerRule(slingClassRule).around(defaultInstance);
 
 
     public <T extends SlingClient> T getAdminClient(Class<T> clientClass) {

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-testing-rules] 12/14: temporarily updated dep to org.apache.sling.testing.clients

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.rules-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-rules.git

commit d5d8b3f0f492abe1e42297073b451e8ce1d86fb6
Author: Andrei Dulvac <du...@apache.org>
AuthorDate: Mon Sep 19 14:39:31 2016 +0000

    temporarily updated dep to org.apache.sling.testing.clients
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/junit/rules@1761457 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/pom.xml b/pom.xml
index 9a3794b..0fe57be 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,7 +28,7 @@
     </parent>
 
     <artifactId>org.apache.sling.testing.rules</artifactId>
-    <version>1.0.0</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>bundle</packaging>
 
     <name>Apache Sling Testing Rules</name>
@@ -37,11 +37,11 @@
     </description>
     
     <scm>
-        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/tags/org.apache.sling.testing.rules-1.0.0</connection>
-        <developerConnection> scm:svn:https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.testing.rules-1.0.0</developerConnection>
-        <url>http://svn.apache.org/viewvc/sling/tags/org.apache.sling.testing.rules-1.0.0</url>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/testing/junit/rules</connection>
+        <developerConnection> scm:svn:https://svn.apache.org/repos/asf/sling/trunk/testing/junit/rules</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules</url>
     </scm>
-    
+
     <build>
         <plugins>
            <plugin>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-testing-rules] 11/14: [maven-release-plugin] prepare release org.apache.sling.testing.rules-1.0.0

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.rules-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-rules.git

commit dda01e5f258500068e24a95715ae27549cd34251
Author: Andrei Dulvac <du...@apache.org>
AuthorDate: Mon Sep 19 14:35:23 2016 +0000

    [maven-release-plugin] prepare release org.apache.sling.testing.rules-1.0.0
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/junit/rules@1761456 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 5806fa2..9a3794b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,7 +28,7 @@
     </parent>
 
     <artifactId>org.apache.sling.testing.rules</artifactId>
-    <version>1.0.0-SNAPSHOT</version>
+    <version>1.0.0</version>
     <packaging>bundle</packaging>
 
     <name>Apache Sling Testing Rules</name>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-testing-rules] 10/14: temporarily updated dep to org.apache.sling.testing.clients

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.rules-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-rules.git

commit 8d97d12e444d1ef5eba6fafe091175cd6580a134
Author: Andrei Dulvac <du...@apache.org>
AuthorDate: Mon Sep 19 14:34:42 2016 +0000

    temporarily updated dep to org.apache.sling.testing.clients
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/junit/rules@1761455 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 9a3794b..5806fa2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,7 +28,7 @@
     </parent>
 
     <artifactId>org.apache.sling.testing.rules</artifactId>
-    <version>1.0.0</version>
+    <version>1.0.0-SNAPSHOT</version>
     <packaging>bundle</packaging>
 
     <name>Apache Sling Testing Rules</name>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-testing-rules] 07/14: Removed unused import in testing rules

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.rules-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-rules.git

commit 21f933c44ed6b7b7fec8c5e9ce739a713880a567
Author: Andrei Dulvac <du...@apache.org>
AuthorDate: Thu Jul 21 08:25:11 2016 +0000

    Removed unused import in testing rules
    
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/junit/rules@1753648 13f79535-47bb-0310-9956-ffa450edef68
---
 .../junit/rules/util/filterrule/FilterRuleExcludeCategoryTest.java       | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryTest.java b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryTest.java
index 6d0b47e..ce366b1 100644
--- a/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryTest.java
+++ b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryTest.java
@@ -22,7 +22,6 @@ import org.apache.sling.testing.junit.rules.annotation.Issue;
 import org.apache.sling.testing.junit.rules.category.FailingTest;
 import org.apache.sling.testing.junit.rules.util.IgnoreTestsConfig;
 import org.junit.Assert;
-import org.junit.Assume;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-testing-rules] 06/14: SLING-5803 - FilterRuleExcludeCategoryIgnoreIfTest fails on Jenkins

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.rules-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-rules.git

commit b1cc7e9d8d1ba2c1f21d7774683cf4ea8826b674
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Tue Jul 19 12:14:06 2016 +0000

    SLING-5803 - FilterRuleExcludeCategoryIgnoreIfTest fails on Jenkins
    
    @Ignore FilterRuleExcludeCategoryTest.testExcludedCategoryExists as it
    consistently fails on Jenkins.
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/junit/rules@1753373 13f79535-47bb-0310-9956-ffa450edef68
---
 .../rules/util/filterrule/FilterRuleExcludeCategoryIgnoreIfTest.java    | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryIgnoreIfTest.java b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryIgnoreIfTest.java
index a542b84..0588dde 100644
--- a/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryIgnoreIfTest.java
+++ b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryIgnoreIfTest.java
@@ -24,6 +24,7 @@ import org.apache.sling.testing.junit.rules.category.SlowRunningTest;
 import org.apache.sling.testing.junit.rules.util.IgnoreTestsConfig;
 import org.junit.Assert;
 import org.junit.Assume;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
@@ -93,6 +94,7 @@ public class FilterRuleExcludeCategoryIgnoreIfTest {
      */
     @Test
     @Category(Issue.class)
+    @Ignore("SLING-5803")
     public void testExcludedCategoryExists() {
         Assume.assumeTrue(System.getProperty(FilterRule.CATEGORY_PROPERTY).equals("Issue,SlowRunningTest"));
         Assert.fail("Test should be Ignored");

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-testing-rules] 01/14: SLING-5703 - new junit/rules module, extracted and enhanced from testing/tools. Contributed by Andrei Dulvac, thanks!

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.testing.rules-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-rules.git

commit cfb4095df59ee3b2e16807191e6f95c0df7a6ff7
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Fri Apr 29 14:04:50 2016 +0000

    SLING-5703 - new junit/rules module, extracted and enhanced from testing/tools. Contributed by Andrei Dulvac, thanks!
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/junit/rules@1741634 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            | 120 ++++++++++++++++
 .../sling/testing/junit/rules/Condition.java       |  22 +++
 .../sling/testing/junit/rules/FilterRule.java      | 156 +++++++++++++++++++++
 .../testing/junit/rules/InstanceConfigRule.java    |  86 ++++++++++++
 .../sling/testing/junit/rules/RunOnceRule.java     |  55 ++++++++
 .../sling/testing/junit/rules/SlingClassRule.java  |  40 ++++++
 .../testing/junit/rules/SlingInstanceRule.java     |  72 ++++++++++
 .../sling/testing/junit/rules/SlingRule.java       |  53 +++++++
 .../testing/junit/rules/TestDescriptionRule.java   |  41 ++++++
 .../testing/junit/rules/TestStickyCookieRule.java  |  49 +++++++
 .../sling/testing/junit/rules/TestTimeout.java     |  50 +++++++
 .../testing/junit/rules/annotation/IgnoreIf.java   |  33 +++++
 .../junit/rules/annotation/IgnoreIfProperties.java |  31 ++++
 .../junit/rules/annotation/IgnoreIfProperty.java   |  33 +++++
 .../testing/junit/rules/annotation/Issue.java      |  38 +++++
 .../testing/junit/rules/annotation/Issues.java     |  36 +++++
 .../junit/rules/category/ClusterAwareTest.java     |  24 ++++
 .../testing/junit/rules/category/FailingTest.java  |  23 +++
 .../junit/rules/category/FastRunningTest.java      |  24 ++++
 .../junit/rules/category/SlowRunningTest.java      |  24 ++++
 .../testing/junit/rules/category/SmokeTest.java    |  23 +++
 .../junit/rules/instance/AbstractInstance.java     |  56 ++++++++
 .../junit/rules/instance/ExistingInstance.java     |  50 +++++++
 .../rules/instance/ExistingInstanceStatement.java  | 119 ++++++++++++++++
 .../testing/junit/rules/instance/Instance.java     |  35 +++++
 .../rules/instance/util/ConfigurationPool.java     | 131 +++++++++++++++++
 .../rules/instance/util/ContextPathAllocator.java  |  62 ++++++++
 .../rules/instance/util/DirectoryAllocator.java    |  43 ++++++
 .../testing/junit/rules/instance/util/Options.java | 105 ++++++++++++++
 .../sling/testing/junit/rules/util/Action.java     |  21 +++
 .../junit/rules/util/IgnoreTestsConfig.java        | 129 +++++++++++++++++
 .../sling/testing/junit/rules/util/Match.java      |  40 ++++++
 .../testing/junit/rules/util/RunOnceRuleTest.java  |  63 +++++++++
 .../testing/junit/rules/util/UniquePathsTest.java  |  76 ++++++++++
 .../filterrule/FilterRuleAsteriskMatchTest.java    |  66 +++++++++
 .../util/filterrule/FilterRuleDefaultTest.java     |  67 +++++++++
 .../FilterRuleExcludeCategoryIgnoreIfTest.java     | 117 ++++++++++++++++
 .../filterrule/FilterRuleExcludeCategoryTest.java  | 104 ++++++++++++++
 .../filterrule/FilterRuleIgnorelistSkipTest.java   |  47 +++++++
 .../util/filterrule/FilterRuleIgnorelistTest.java  |  51 +++++++
 .../FilterRuleIncludeCategoryIgnoreIfTest.java     | 106 ++++++++++++++
 .../filterrule/FilterRuleIncludeCategoryTest.java  | 117 ++++++++++++++++
 .../rules/util/filterrule/FilterRuleTest.java      | 116 +++++++++++++++
 .../util/instanceconfig/DebugInstanceConfig.java   |  46 ++++++
 .../instanceconfig/InstanceConfigRuleTest.java     |  48 +++++++
 .../rules/util/poller/AbstractPollerTest.java      | 107 ++++++++++++++
 46 files changed, 2955 insertions(+)

diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..d7596a4
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+    
+    http://www.apache.org/licenses/LICENSE-2.0
+    
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>26</version>
+        <relativePath />
+    </parent>
+
+    <artifactId>org.apache.sling.testing.rules</artifactId>
+    <version>0.1.0-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <name>Apache Sling Testing Rules</name>
+    <description>
+        Sling testing junit rules and utils
+    </description>
+    
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/testing/http/rules</connection>
+        <developerConnection> scm:svn:https://svn.apache.org/repos/asf/sling/trunk/testing/http/rules</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/trunk/testing/http/rules</url>
+    </scm>
+    
+    <build>
+        <plugins>
+           <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+             <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Export-Package>
+                            org.apache.sling.testing.rules.*
+                        </Export-Package>
+                        <Import-Package>
+                            org.apache.commons.exec.*; resolution:=optional,
+                            org.apache.sling.testing.clients.*,
+                            *
+                        </Import-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.clients</artifactId>
+            <version>0.1.0-SNAPSHOT</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.sling</groupId>
+                    <artifactId>org.apache.sling.testing.tools</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+       <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.scr.annotations</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-exec</artifactId>
+            <version>1.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.7.5</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <version>1.7.5</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.tools</artifactId>
+            <version>1.0.12</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/Condition.java b/src/main/java/org/apache/sling/testing/junit/rules/Condition.java
new file mode 100644
index 0000000..1518e57
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/Condition.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules;
+
+public interface Condition {
+    boolean satisfy();
+    String description();
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/FilterRule.java b/src/main/java/org/apache/sling/testing/junit/rules/FilterRule.java
new file mode 100644
index 0000000..11b66b3
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/FilterRule.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules;
+
+import org.apache.sling.testing.junit.rules.annotation.IgnoreIf;
+import org.apache.sling.testing.junit.rules.annotation.IgnoreIfProperties;
+import org.apache.sling.testing.junit.rules.annotation.IgnoreIfProperty;
+import org.apache.sling.testing.junit.rules.util.Match;
+import org.apache.sling.testing.junit.rules.util.IgnoreTestsConfig;
+import org.junit.AssumptionViolatedException;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.junit.rules.TestRule;
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class FilterRule implements TestRule {
+    private static final Logger LOG = LoggerFactory.getLogger(FilterRule.class);
+    public static final String CATEGORY_PROPERTY = "filterCategory";
+    public static final String INCLUDE_CATEGORY_PROPERTY = "runOnlyFilteredCategories";
+    private List<String> defaultCategories = new ArrayList<String>();
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+
+        // get the annotations in order and skip the tests accordingly
+
+        // IgnoreIf
+        IgnoreIf ignoreIf = description.getAnnotation(IgnoreIf.class);
+        if (null != ignoreIf) {
+            for (Class condClass : Arrays.asList(ignoreIf.value())) {
+                try {
+                    Constructor<? extends Condition> constructor = condClass.getConstructor();
+                    Condition cond = constructor.newInstance();
+                    if (cond.satisfy()) {
+                        return emptyStatement("IgnoreIf condition met to skip: " + cond.description());
+                    }
+                } catch (Exception e) {
+                    LOG.error("Error getting condition object", e);
+                }
+            }
+        }
+
+        // IgnoreIfProperties
+        List<IgnoreIfProperty> ignoreIfPropertyList = new ArrayList<IgnoreIfProperty>();
+        IgnoreIfProperties ignoreIfProperties = description.getAnnotation(IgnoreIfProperties.class);
+        if (null != ignoreIfProperties) {
+            ignoreIfPropertyList.addAll(Arrays.asList(ignoreIfProperties.value()));
+        }
+
+        // IgnoreIfProperty
+        IgnoreIfProperty ignoreIfProperty = description.getAnnotation(IgnoreIfProperty.class);
+        if (null != ignoreIfProperty) {
+            ignoreIfPropertyList.add(ignoreIfProperty);
+        }
+        // Process the ignoreIfProperties
+        for (IgnoreIfProperty ignoreIfProp : ignoreIfPropertyList) {
+            if (null != System.getProperty(ignoreIfProp.name())
+                    && System.getProperty(ignoreIfProp.name()).equals(ignoreIfProp.value())) {
+                return emptyStatement("IgnoreIfProperty condition met to skip: system property '" + ignoreIfProp.name()
+                        + "' is equal to '" + ignoreIfProp.value() + "'.");
+            }
+        }
+
+        // Filter using IgnoreTestsConfig
+        String fqdn = description.getClassName();
+        String methodName = description.getMethodName();
+        if (null != methodName) {
+            fqdn += "#" + methodName;
+        }
+
+        Match match = IgnoreTestsConfig.get().match(fqdn);
+        if (match.isIgnored()) {
+            return emptyStatement(match.getReason());
+        }
+
+       // filterCategory processing
+        List<String> filteredCategories;
+        if (System.getProperty(CATEGORY_PROPERTY) != null) {
+            filteredCategories = Arrays.asList(System.getProperty(CATEGORY_PROPERTY).split(","));
+        } else {
+            filteredCategories = defaultCategories;
+        }
+
+        Category testCategory = description.getAnnotation(Category.class);
+        Class[] testCategories = new Class[0];
+        if (testCategory != null) {
+            testCategories = testCategory.value();
+        }
+        /*
+         * Category annotation exists and the -DfilterCategory property is also set. If test category exists
+         * in -DfilterCategory list & -DrunOnlyFilteredCategories is NOT set, then the test is skipped If test
+         * category exists in -DfilterCategory & -DrunOnlyFilteredCategories is set, then the test is included
+         */
+        if ((System.getProperty(INCLUDE_CATEGORY_PROPERTY) == null)) {
+            // Skip Tests from CATEGORY_PROPERTY
+            for (Class<?> category : testCategories) {
+                if (filteredCategories.contains(category.getSimpleName())) {
+                    return emptyStatement("Excluding category: " + category.getSimpleName());
+                }
+            }
+        } else {
+            // Run only Tests from CATEGORY_PROPERTY
+            boolean categorySelected = false;
+            for (Class<?> category : testCategories) {
+                if ((filteredCategories.contains(category.getSimpleName()))) {
+                    categorySelected = true;
+                }
+            }
+
+            if (!categorySelected) {
+                // No @Category from Test is in CATEGORY_PROPERTY (which should be executed), so skip
+                return emptyStatement("Test has no category in (" + INCLUDE_CATEGORY_PROPERTY + "=true): '" + filteredCategories + "'");
+            }
+        }
+
+        // No Filter excluded this test, so execute
+        return base;
+    }
+
+    private Statement emptyStatement(final String reason) {
+        return new Statement() {
+
+            @Override
+            public void evaluate() throws Throwable {
+                throw new AssumptionViolatedException("Test was ignored by FilterRule: " + reason);
+            }
+        };
+    }
+
+    public FilterRule addDefaultIgnoreCategories(Class... ignoredCategories) {
+        for (Class c : ignoredCategories) {
+            this.defaultCategories.add(c.getSimpleName());
+        }
+        return this;
+    }
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/InstanceConfigRule.java b/src/main/java/org/apache/sling/testing/junit/rules/InstanceConfigRule.java
new file mode 100644
index 0000000..fc81b04
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/InstanceConfigRule.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules;
+
+import org.apache.sling.testing.junit.rules.util.Action;
+import org.apache.sling.testing.clients.util.config.InstanceConfig;
+import org.apache.sling.testing.clients.util.config.impl.EmptyInstanceConfig;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class InstanceConfigRule implements TestRule {
+    public static final Logger LOG = LoggerFactory.getLogger(InstanceConfigRule.class);
+    
+    private final boolean withRestore;
+    private InstanceConfig instanceConfig;
+    private List<Action> actions;
+
+    public <T extends InstanceConfig> InstanceConfigRule(T instanceConfig, boolean withRestore) {
+        this.instanceConfig = instanceConfig;
+        this.withRestore = withRestore;
+        this.actions = new ArrayList<Action>();
+    }
+
+    public <T extends InstanceConfig> InstanceConfigRule(T instanceConfig) {
+        this(instanceConfig, true);
+    }
+
+    /**
+     * Uses an EmptyInstanceConfig (e.g. does nothing)
+     */
+    public InstanceConfigRule() {
+        this(new EmptyInstanceConfig(), true);
+    }
+
+    public <T extends Action> InstanceConfigRule withAction(T action) {
+        this.actions.add(action);
+        return this;
+    }
+
+    public Statement apply(final Statement base, Description description) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                // save the instance config
+                LOG.debug("Saving instance config {}", instanceConfig.getClass());
+                instanceConfig.save();
+                
+                // Call any actions if any
+                for (Action action : actions) {
+                    LOG.debug("Calling action {}", action.getClass());
+                    action.call();
+                }
+                
+                // run the base statement
+                LOG.debug("Running base statement");
+                base.evaluate();
+                
+                if (withRestore) {
+                    LOG.debug("Restoring instance config {}", instanceConfig.getClass());
+                    instanceConfig.restore();
+                }
+            }
+        };
+    }
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/RunOnceRule.java b/src/main/java/org/apache/sling/testing/junit/rules/RunOnceRule.java
new file mode 100644
index 0000000..79f0277
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/RunOnceRule.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Allows wrapping a junit {@link TestRule} that will be run only once.
+ * Once means once per class RunOnceRule being loaded 
+ */
+public class RunOnceRule implements TestRule {
+    private static final Logger LOG = LoggerFactory.getLogger(RunOnceRule.class);
+    private static AtomicBoolean run = new AtomicBoolean(false);
+    private final TestRule rule;
+
+    /**
+     * Constructor*
+     * @param rule The rule to wrap and run once per classloader load
+     * @param <T> The class of the TestRule
+     */
+    public <T extends TestRule> RunOnceRule(T rule) {
+        this.rule = rule;
+    }
+
+    @Override
+    public Statement apply(final Statement base, final Description description) {
+        // if not done yet
+        if (!RunOnceRule.run.getAndSet(true)) {
+            LOG.debug("Applying {} once", rule.getClass());
+            return rule.apply(base, description);
+        } else {
+            return base;
+        }
+    }
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/SlingClassRule.java b/src/main/java/org/apache/sling/testing/junit/rules/SlingClassRule.java
new file mode 100644
index 0000000..a748307
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/SlingClassRule.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules;
+
+import org.apache.sling.testing.junit.rules.category.FailingTest;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Sling Rule that wraps all the ClassRules, useful when running a Sling Integration Test.
+ * Can be used in any junit test class using @ClassRule annotation
+ */
+public class SlingClassRule implements TestRule {
+    /** Rule to filter tests at class level */
+    public final FilterRule filterRule = new FilterRule().addDefaultIgnoreCategories(FailingTest.class);
+
+    /** Main RuleChain describing the order of execution of all the rules */
+    protected TestRule ruleChain = RuleChain.outerRule(filterRule);
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+        return ruleChain.apply(base, description);
+    }
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/SlingInstanceRule.java b/src/main/java/org/apache/sling/testing/junit/rules/SlingInstanceRule.java
new file mode 100644
index 0000000..0e8439f
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/SlingInstanceRule.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.testing.junit.rules;
+
+import org.apache.sling.testing.clients.SlingClient;
+import org.apache.sling.testing.clients.instance.InstanceConfiguration;
+import org.apache.sling.testing.junit.rules.instance.ExistingInstance;
+import org.apache.sling.testing.junit.rules.instance.Instance;
+import org.apache.sling.testing.tools.sling.SlingTestBase;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.URI;
+
+/**
+ * Junit Rule that allows access to a Sling instance.
+ * It is wrapped by a {@link SlingClassRule}
+ */
+public class SlingInstanceRule implements TestRule {
+
+    // Until we extract this logic from SlingTestBase, we can just reuse it here
+    // #getServerBaseUrl() starts the instance if needed, internally.
+    private static final SlingTestBase S = new SlingTestBase();
+
+    public static final InstanceConfiguration DEFAULT_INSTANCE =
+            new InstanceConfiguration(URI.create(S.getServerBaseUrl()), "default");
+    private static final Logger LOG = LoggerFactory.getLogger(SlingInstanceRule.class);
+
+    /** Sling rules to be executed at class level */
+    public final SlingClassRule slingClassRule = new SlingClassRule();
+
+
+    /** ExistingInstance for default instance */
+    public final Instance defaultInstance = new ExistingInstance().withRunMode("default").orDefault(DEFAULT_INSTANCE);
+
+    protected TestRule ruleChain = RuleChain.outerRule(slingClassRule)
+            .around(defaultInstance);
+
+
+    public <T extends SlingClient> T getAdminClient(Class<T> clientClass) {
+        return defaultInstance.getClient(clientClass, S.getServerUsername(), S.getServerPassword());
+    }
+
+    public SlingClient getAdminClient() {
+        return getAdminClient(SlingClient.class);
+    }
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+        return ruleChain.apply(base, description);
+    }
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/SlingRule.java b/src/main/java/org/apache/sling/testing/junit/rules/SlingRule.java
new file mode 100644
index 0000000..34fd6f8
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/SlingRule.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules;
+
+import org.apache.sling.testing.junit.rules.category.FailingTest;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Sling Rule that wraps all the Rules (at method level) useful when running a Sling Integration Test.
+ * Can be used in any junit test using the @Rule annotation
+ * I chains: {@link TestTimeout}, {@link TestDescriptionRule}, {@link TestStickyCookieRule}, {@link FilterRule}
+ */
+public class SlingRule implements TestRule {
+    /** Rule to define the max timeout for all the tests */
+    public final TestTimeout testTimeoutRule = new TestTimeout();
+
+    /** Rule to add a Sticky Session Cookie for requests */
+    public final TestStickyCookieRule testStickySessionRule = new TestStickyCookieRule();
+
+    /** Rule to filter tests per method name */
+    public final FilterRule filterRule = new FilterRule().addDefaultIgnoreCategories(FailingTest.class);
+
+    /** Rule to send in every request a header with the test name */
+    public final TestDescriptionRule testDescriptionRule = new TestDescriptionRule();
+
+    /** Main RuleChain describing the order of execution of all the rules */
+    protected TestRule ruleChain = RuleChain.outerRule(testTimeoutRule)
+            .around(testStickySessionRule)
+            .around(filterRule)
+            .around(testDescriptionRule);
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+        return ruleChain.apply(base, description);
+    }
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/TestDescriptionRule.java b/src/main/java/org/apache/sling/testing/junit/rules/TestDescriptionRule.java
new file mode 100644
index 0000000..080e423
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/TestDescriptionRule.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.testing.junit.rules;
+
+import org.apache.sling.testing.clients.interceptors.TestDescriptionHolder;
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+
+/**
+ * Junit rule which exposes the description of the current executing test as a thread local instance
+ */
+public class TestDescriptionRule extends TestWatcher {
+
+
+    @Override
+    protected void finished(Description description) {
+        TestDescriptionHolder.setClassName(description.getClassName());
+        TestDescriptionHolder.setMethodName(description.getMethodName());
+    }
+
+    @Override
+    protected void starting (Description description) {
+        TestDescriptionHolder.removeMethodName();
+        TestDescriptionHolder.removeClassName();
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/TestStickyCookieRule.java b/src/main/java/org/apache/sling/testing/junit/rules/TestStickyCookieRule.java
new file mode 100644
index 0000000..7a7c9b9
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/TestStickyCookieRule.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules;
+
+import org.apache.sling.testing.clients.interceptors.StickyCookieHolder;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+public class TestStickyCookieRule implements TestRule {
+
+    @Override
+    public Statement apply(final Statement base, final Description description) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+
+                starting(description);
+                try {
+                    base.evaluate();
+                } finally {
+                    finished(description);
+                }
+            }
+        };
+    }
+
+    protected void starting(Description description) {
+        StickyCookieHolder.setTestStickySessionCookie(null);
+    }
+
+    protected void finished(Description description) {
+        StickyCookieHolder.remove();
+    }
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/TestTimeout.java b/src/main/java/org/apache/sling/testing/junit/rules/TestTimeout.java
new file mode 100644
index 0000000..3a63fa0
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/TestTimeout.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules;
+
+import org.junit.internal.runners.statements.FailOnTimeout;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Rule to timeout a test.
+ */
+public class TestTimeout implements TestRule {
+    private int fMillis;
+    private static final int DEFAULT_TIMEOUT = Integer.getInteger("test.timeout.milliseconds", 0);
+
+    public TestTimeout(int fMillis) {
+        this.fMillis = fMillis;
+    }
+
+    /**
+     * Constructor: reads the default timeout value from the "test.timeout.milliseconds" property.
+     * If the property doesn't exist or has the value "0", the statement won't timeout.
+     */
+    public TestTimeout() {
+        this.fMillis = DEFAULT_TIMEOUT;
+    }
+
+    public Statement apply(Statement base, Description description) {
+        if (fMillis > 0) {
+            return new FailOnTimeout(base, fMillis);
+        } else {
+            return base;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIf.java b/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIf.java
new file mode 100644
index 0000000..742d5fc
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIf.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.annotation;
+
+
+import org.apache.sling.testing.junit.rules.Condition;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+
+@java.lang.annotation.Retention(value = RUNTIME)
+@java.lang.annotation.Target(value = {METHOD, TYPE})
+public @interface IgnoreIf {
+    Class <? extends Condition>[] value();
+}
+
+
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIfProperties.java b/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIfProperties.java
new file mode 100644
index 0000000..cc0c8e1
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIfProperties.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.annotation;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Ignores the test at runtime if ANY of the system properties defined
+ * by {@link IgnoreIfProperty} is defined
+ */
+@java.lang.annotation.Retention(value = RUNTIME)
+@java.lang.annotation.Target(value = {METHOD, TYPE})
+public @interface IgnoreIfProperties {
+    IgnoreIfProperty[] value();
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIfProperty.java b/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIfProperty.java
new file mode 100644
index 0000000..4bbf238
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIfProperty.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.annotation;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+
+/**
+ * Ignores the test at runtime if the system property {@code name}
+ * equals {@code value}
+ */
+@java.lang.annotation.Retention(value = RUNTIME)
+@java.lang.annotation.Target(value = {METHOD, TYPE})
+public @interface IgnoreIfProperty {
+    String name();
+    String value() default "";
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/annotation/Issue.java b/src/main/java/org/apache/sling/testing/junit/rules/annotation/Issue.java
new file mode 100644
index 0000000..edb302a
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/annotation/Issue.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.sling.testing.junit.rules.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Use this annotation to document that an issue is related to a test class or method. Useful to attach issue
+ * information to failing tests.
+ */
+
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.TYPE, ElementType.METHOD})
+public @interface Issue {
+
+    String value();
+
+    String description() default "";
+
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/annotation/Issues.java b/src/main/java/org/apache/sling/testing/junit/rules/annotation/Issues.java
new file mode 100644
index 0000000..6220259
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/annotation/Issues.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.sling.testing.junit.rules.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Use this annotation to document that issues are related to a test class or method. Useful to attach issue information
+ * to failing tests.
+ */
+
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.TYPE, ElementType.METHOD})
+public @interface Issues {
+
+    Issue[] value();
+
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/category/ClusterAwareTest.java b/src/main/java/org/apache/sling/testing/junit/rules/category/ClusterAwareTest.java
new file mode 100644
index 0000000..c111fed
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/category/ClusterAwareTest.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.category;
+
+/**
+ * Interface used to mark a JUnit test which has the ability to run in parallel with other tests against the same instance instance.
+ * The definition of a parallelizable test is defined externally.
+ */
+public interface ClusterAwareTest {
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/category/FailingTest.java b/src/main/java/org/apache/sling/testing/junit/rules/category/FailingTest.java
new file mode 100644
index 0000000..c2ee0f3
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/category/FailingTest.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.category;
+
+/**
+ * Marker interface for the tests that fail independently of the Java version or other environment settings
+ */
+public interface FailingTest {
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/category/FastRunningTest.java b/src/main/java/org/apache/sling/testing/junit/rules/category/FastRunningTest.java
new file mode 100644
index 0000000..95bed50
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/category/FastRunningTest.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.category;
+
+/**
+ * Interface used to mark a JUnit test as FAST running
+ * The definition of a fast running test is defined externally
+ */
+public interface FastRunningTest {
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/category/SlowRunningTest.java b/src/main/java/org/apache/sling/testing/junit/rules/category/SlowRunningTest.java
new file mode 100644
index 0000000..9a177fa
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/category/SlowRunningTest.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.category;
+
+/**
+ * Interface used to mark a JUnit test as SLOW running
+ * The definition of a slow running test is defined externally
+ */
+public @interface SlowRunningTest {
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/category/SmokeTest.java b/src/main/java/org/apache/sling/testing/junit/rules/category/SmokeTest.java
new file mode 100644
index 0000000..9a83a98
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/category/SmokeTest.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.category;
+
+/**
+ * Marker interface for the tests that should be run as smoke tests after a new build
+ */
+public interface SmokeTest {
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/instance/AbstractInstance.java b/src/main/java/org/apache/sling/testing/junit/rules/instance/AbstractInstance.java
new file mode 100644
index 0000000..f04d557
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/instance/AbstractInstance.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.instance;
+
+
+import org.apache.sling.testing.clients.SlingClient;
+import org.apache.sling.testing.clients.instance.InstanceConfiguration;
+
+import java.lang.reflect.Constructor;
+import java.net.URI;
+
+public abstract class AbstractInstance implements Instance {
+
+    @Override
+    public <T extends SlingClient> T getClient(Class<T> clientClass, String user, String pass) {
+        InstanceConfiguration configuration = getConfiguration();
+
+        Constructor<T> constructor;
+
+        try {
+            constructor = clientClass.getConstructor(URI.class, String.class, String.class);
+        } catch (NoSuchMethodException e) {
+            return null;
+        }
+
+        T client;
+
+        try {
+            client = constructor.newInstance(configuration.getUrl(), user, pass);
+        } catch (Exception e) {
+            return null;
+        }
+
+        return client;
+    }
+
+    @Override
+    public <T extends SlingClient> T getAdminClient(Class<T> clientClass) {
+        return getClient(clientClass, "admin", "admin");
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/instance/ExistingInstance.java b/src/main/java/org/apache/sling/testing/junit/rules/instance/ExistingInstance.java
new file mode 100644
index 0000000..dc9074d
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/instance/ExistingInstance.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.instance;
+
+import org.apache.sling.testing.clients.instance.InstanceConfiguration;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+public class ExistingInstance extends AbstractInstance {
+
+    private String runMode;
+
+    private ExistingInstanceStatement statement;
+    private InstanceConfiguration defaultConfiguration;
+
+    public Instance withRunMode(String runMode) {
+        this.runMode = runMode;
+        return this;
+    }
+
+    @Override
+    public Instance orDefault(InstanceConfiguration instanceConfiguration) {
+        this.defaultConfiguration = instanceConfiguration;
+        return this;
+    }
+
+    public InstanceConfiguration getConfiguration() {
+        return statement.getConfiguration();
+    }
+
+    public Statement apply(Statement base, Description description) {
+        this.statement = new ExistingInstanceStatement(description, base, runMode, defaultConfiguration);
+        return this.statement;
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/instance/ExistingInstanceStatement.java b/src/main/java/org/apache/sling/testing/junit/rules/instance/ExistingInstanceStatement.java
new file mode 100644
index 0000000..953d60c
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/instance/ExistingInstanceStatement.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.instance;
+
+import org.apache.sling.testing.junit.rules.instance.util.ConfigurationPool;
+import org.apache.sling.testing.clients.instance.InstanceConfiguration;
+import org.junit.Assume;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+class ExistingInstanceStatement extends Statement {
+
+    private final Logger logger = LoggerFactory.getLogger(ExistingInstanceStatement.class);
+
+    private final ConfigurationPool configurationPool = new ConfigurationPool();
+
+    private final Description description;
+
+    private final Statement statement;
+
+    private final String runMode;
+
+    private Integer index;
+
+    private InstanceConfiguration configuration;
+
+    private final InstanceConfiguration defaultConfiguration;
+
+    public ExistingInstanceStatement(Description description, Statement statement,
+                                     String runMode, InstanceConfiguration defaultConfiguration) {
+        this.description = description;
+        this.statement = statement;
+        this.runMode = runMode;
+        this.defaultConfiguration = defaultConfiguration;
+    }
+
+    @Override
+    public void evaluate() throws Throwable {
+        takeMatchingQuickstart();
+
+        assumeMatchingQuickstartIsFound();
+
+        try {
+            statement.evaluate();
+        } finally {
+            returnQuickstart();
+        }
+    }
+
+    private void assumeMatchingQuickstartIsFound() {
+        if (this.index == null) {
+            Assume.assumeNotNull(this.defaultConfiguration);
+            this.configuration = defaultConfiguration;
+            logger.info("Using default InstanceConfiguration provided (URL: {}, runmode: {}) for test {}",
+                    configuration.getUrl(), configuration.getRunmode(), description);
+        }
+    }
+
+    private void takeMatchingQuickstart() {
+        List<InstanceConfiguration> configurations = configurationPool.getConfigurations();
+
+        for (int i = 0; i < configurations.size(); i++) {
+            InstanceConfiguration configuration = configurations.get(i);
+
+            // Does the configuration match the requested run mode?
+            if (!runMode.equals(configuration.getRunmode())) {
+                continue;
+            }
+
+            // Is the configuration already used by the current test?
+            if (configurationPool.isTaken(i)) {
+                continue;
+            }
+
+            // The configuration is valid, save the index
+            logger.info("InstanceConfiguration (URL: {}, runmode: {}) found for test {}", configuration.getUrl(), runMode, description);
+
+            takeQuickstart(i);
+
+            return;
+        }
+    }
+
+    private void takeQuickstart(Integer index) {
+        this.configuration = configurationPool.takeConfiguration(description, index);
+        this.index = index;
+    }
+
+    private void returnQuickstart() {
+        if (index == null) {
+            return;
+        }
+        configurationPool.returnConfiguration(description, index);
+        index = null;
+    }
+
+    public InstanceConfiguration getConfiguration() {
+        return configuration;
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/instance/Instance.java b/src/main/java/org/apache/sling/testing/junit/rules/instance/Instance.java
new file mode 100644
index 0000000..7747158
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/instance/Instance.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.instance;
+
+import org.apache.sling.testing.clients.SlingClient;
+import org.apache.sling.testing.clients.instance.InstanceConfiguration;
+import org.junit.rules.TestRule;
+
+public interface Instance extends TestRule {
+
+    Instance withRunMode(String runMode);
+
+    Instance orDefault(InstanceConfiguration instanceConfiguration);
+
+    InstanceConfiguration getConfiguration();
+
+    <T extends SlingClient> T getClient(Class<T> clientClass, String user, String pass);
+
+    <T extends SlingClient> T getAdminClient(Class<T> clientClass);
+
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/instance/util/ConfigurationPool.java b/src/main/java/org/apache/sling/testing/junit/rules/instance/util/ConfigurationPool.java
new file mode 100644
index 0000000..98fadf0
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/instance/util/ConfigurationPool.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.instance.util;
+
+import org.apache.sling.testing.clients.instance.InstanceConfiguration;
+import org.apache.sling.testing.clients.instance.InstanceSetup;
+import org.junit.runner.Description;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+public class ConfigurationPool {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ConfigurationPool.class);
+
+    private static final List<InstanceConfiguration> configurations = initialConfigurations();
+
+    private static final Set<Integer> takenConfigurations = new HashSet<Integer>();
+
+    private static final Map<Description, Set<Integer>> takenConfigurationsByDescription = new HashMap<Description, Set<Integer>>();
+
+    private static List<InstanceConfiguration> initialConfigurations() {
+
+        LOG.info("Reading initial configurations from the system properties");
+
+        List<InstanceConfiguration> configurationsFromPlugin = InstanceSetup.get().getConfigurations();
+
+        if (!configurationsFromPlugin.isEmpty()) {
+
+            LOG.info("Found {} instance configuration(s) from the system properties", configurationsFromPlugin.size());
+
+            return configurationsFromPlugin;
+        }
+
+        LOG.info("No instance configurations found from the system properties");
+
+        List<InstanceConfiguration> configurations = new ArrayList<InstanceConfiguration>();
+
+        return configurations;
+    }
+
+    public List<InstanceConfiguration> getConfigurations() {
+        return new ArrayList<InstanceConfiguration>(configurations);
+    }
+
+    public boolean isTaken(int configurationIndex) {
+        synchronized (ConfigurationPool.class) {
+            return takenConfigurations.contains(configurationIndex);
+        }
+    }
+
+    public InstanceConfiguration takeConfiguration(Description description, int configurationIndex) {
+        synchronized (ConfigurationPool.class) {
+            if (isTaken(configurationIndex)) {
+                throw new IllegalStateException("Requested configuration is already taken");
+            }
+
+            Set<Integer> indices = takenConfigurationsByDescription.get(description);
+
+            if (indices == null) {
+                indices = new HashSet<Integer>();
+            }
+
+            indices.add(configurationIndex);
+
+            LOG.debug("Test {} took configuration with index {}", description, configurationIndex);
+
+            takenConfigurationsByDescription.put(description, indices);
+
+            takenConfigurations.add(configurationIndex);
+
+            return configurations.get(configurationIndex);
+        }
+    }
+
+    public void returnConfiguration(Description description, int configurationIndex) {
+        synchronized (ConfigurationPool.class) {
+            if (!isTaken(configurationIndex)) {
+                throw new IllegalStateException("Returned configuration is not taken by anyone");
+            }
+
+            Set<Integer> indices = takenConfigurationsByDescription.get(description);
+
+            if (indices == null) {
+                throw new IllegalStateException("The test didn't take any configuration");
+            }
+
+            if (!indices.contains(configurationIndex)) {
+                throw new IllegalStateException("The returned configuration was not taken by the test");
+            }
+
+            indices.remove(configurationIndex);
+
+            LOG.debug("Test {} returned configuration with index {}", description, configurationIndex);
+
+            if (indices.isEmpty()) {
+                takenConfigurationsByDescription.remove(description);
+            }
+
+            takenConfigurations.remove(configurationIndex);
+        }
+    }
+
+    public Integer addAndTakeConfiguration(Description description, InstanceConfiguration configuration) {
+        synchronized (ConfigurationPool.class) {
+            configurations.add(configuration);
+
+            Integer index = configurations.size() - 1;
+
+            takeConfiguration(description, index);
+
+            return index;
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/instance/util/ContextPathAllocator.java b/src/main/java/org/apache/sling/testing/junit/rules/instance/util/ContextPathAllocator.java
new file mode 100644
index 0000000..cd7b70a
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/instance/util/ContextPathAllocator.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.instance.util;
+
+import java.util.HashSet;
+import java.util.Random;
+import java.util.Set;
+
+public class ContextPathAllocator {
+
+    private static Set<String> allocatedContextPaths;
+
+    static {
+        allocatedContextPaths = new HashSet<String>();
+    }
+
+    public String allocateContextPath() {
+        while (true) {
+            String contextPath = generateContextPath();
+
+            boolean contextPathAdded = checkAndAdd(contextPath);
+
+            if (contextPathAdded) {
+                return "/" + contextPath;
+            }
+        }
+    }
+
+    public String generateContextPath() {
+        int start = (int) 'a', end = (int) 'z';
+
+        String contextPath = "";
+
+        Random random = new Random();
+
+        for (int i = 0; i < 8; i++) {
+            int next = start + random.nextInt(end - start);
+            contextPath += Character.toString((char) next);
+        }
+
+        return contextPath;
+    }
+
+    public synchronized boolean checkAndAdd(String contextPath) {
+        return allocatedContextPaths.add(contextPath);
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/instance/util/DirectoryAllocator.java b/src/main/java/org/apache/sling/testing/junit/rules/instance/util/DirectoryAllocator.java
new file mode 100644
index 0000000..94c5b9d
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/instance/util/DirectoryAllocator.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.instance.util;
+
+import java.io.File;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class DirectoryAllocator {
+
+    private static AtomicInteger counter;
+
+    static {
+        counter = new AtomicInteger(1);
+    }
+
+    public File allocateDirectory(File root, String basename) {
+        while (true) {
+            File folder = new File(root, basename + "-" + counter.getAndIncrement());
+
+            if (folder.exists()) {
+                continue;
+            }
+
+            folder.mkdirs();
+
+            return folder;
+        }
+    }
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/instance/util/Options.java b/src/main/java/org/apache/sling/testing/junit/rules/instance/util/Options.java
new file mode 100644
index 0000000..82a8280
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/instance/util/Options.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.instance.util;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public enum Options {
+
+    JAR("instance.jar.file"),
+    JVM_ARGUMENTS("instance.vm.args"),
+    QUICKSTART_OPTIONS("instance.options"),
+    INSTALLATIONS("instance.installations"),
+    START_TIMEOUT("instance.timeout");
+
+    private String name;
+
+    Options(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public boolean isSpecified() {
+        return System.getProperty(name) != null;
+    }
+
+    public boolean isNotSpecified() {
+        return !isSpecified();
+    }
+
+    public String asString() {
+        return System.getProperty(name);
+    }
+
+    public String asPath() {
+        String value = asString();
+
+        if (value == null) {
+            return null;
+        }
+
+        return new File(value).getAbsolutePath();
+    }
+
+    public File asFile() {
+        String path = asPath();
+
+        if (path == null) {
+            return null;
+        }
+
+        return new File(path);
+    }
+
+    public List<String> asList() {
+        List<String> result = new ArrayList<String>();
+
+        String values = asString();
+
+        if (values == null) {
+            return result;
+        }
+
+        String[] array = values.trim().split("\\s");
+
+        for (String element : array) {
+            String trimmed = element.trim();
+
+            if (!trimmed.isEmpty()) {
+                result.add(trimmed);
+            }
+        }
+
+        return result;
+    }
+
+    public Integer asInteger(int defaultValue) {
+        String string  = asString();
+
+        if (string == null) {
+            return defaultValue;
+        }
+
+        return new Integer(asString());
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/util/Action.java b/src/main/java/org/apache/sling/testing/junit/rules/util/Action.java
new file mode 100644
index 0000000..3e5dde0
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/util/Action.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.util;
+
+public interface Action {
+    void call() throws Throwable;
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/util/IgnoreTestsConfig.java b/src/main/java/org/apache/sling/testing/junit/rules/util/IgnoreTestsConfig.java
new file mode 100644
index 0000000..655f9de
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/util/IgnoreTestsConfig.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.util;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.testing.clients.Constants;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+public class IgnoreTestsConfig {
+
+    public static final String IGNORE_LIST_PROP = Constants.CONFIG_PROP_PREFIX + "ignorelist";
+    public static final String RUN_IGNORE_LIST_PROP = Constants.CONFIG_PROP_PREFIX + "ignorelist.run";
+
+    private final int numberOfIgnoreLists = 3;
+    private final boolean runIgnoreList;
+    private static IgnoreTestsConfig INSTANCE;
+    private Map<String, String> ignoreTokens = new HashMap<String, String>();
+
+
+    /**
+     * @return the singleton config object.
+     */
+    public static IgnoreTestsConfig get() {
+        if (INSTANCE == null) {
+            INSTANCE = new IgnoreTestsConfig();
+        }
+        return INSTANCE;
+    }
+
+    /**
+     * Recreate the singleton config object.
+     */
+    public static void reCreate() {
+        INSTANCE = new IgnoreTestsConfig();
+    }
+
+    private IgnoreTestsConfig() {
+        for (int i = 0; i <= numberOfIgnoreLists; i++) {
+            StringTokenizer st = new StringTokenizer(System.getProperty(IGNORE_LIST_PROP, ""), ",");
+            while (st.hasMoreElements()) {
+                String token = st.nextToken();
+                String[] pair = token.split(":");
+
+                // Split by ":" and get the ignore (partial) java FQDN and a reason
+                // Ex: org.apache.sling.tests.*:SLING-4242
+                //     org.apache.sling.tests.MyTest:SLING-555
+                String ignoreToken = (pair.length > 0) ? pair[0] : "";
+                String reason = (pair.length > 1) ? pair[1] : "";
+
+                // Add to ignore token map
+                ignoreTokens.put(ignoreToken.trim(), reason.trim());
+            }
+        }
+        this.runIgnoreList = System.getProperty(RUN_IGNORE_LIST_PROP) != null;
+    }
+
+    public Match match(String fqdn) {
+        if (null == fqdn || "".equals(fqdn)) {
+            throw new IllegalArgumentException("The ignore class/method String must not be null or empty");
+        }
+        String className = StringUtils.substringBefore(fqdn, "#");
+        Match match = matchToken(fqdn);
+        if (!match.isIgnored() && (fqdn.indexOf('#') > 0)) {
+            return matchToken(className);
+        } else {
+            return match;
+        }
+    }
+
+    private Match matchToken(String matchToken) {
+        if (!runIgnoreList ) {
+            // run the tests that are not in the ignorelist
+            for (String ignoreToken : ignoreTokens.keySet()) {
+                if (asteriskMatch(ignoreToken, matchToken)) {
+                    return new Match(true, ignoreTokens.get(ignoreToken));
+                }
+            }
+            return new Match(false);
+        } else {
+            // run only the ignore list, so reverse logic.
+            for (String ignoreToken : ignoreTokens.keySet()) {
+                if (asteriskMatch(ignoreToken, matchToken)) {
+                    return new Match(false, ignoreTokens.get(ignoreToken));
+                }
+            }
+            return new Match(true, "Running tests in ignorelist only");
+        }
+    }
+
+
+    private static String createRegexFromGlob(String glob) {
+        String out = "^";
+        for(int i = 0; i < glob.length(); ++i) {
+            final char c = glob.charAt(i);
+            switch(c) {
+                case '*': out += ".*"; break;
+                case '?': out += '.'; break;
+                case '.': out += "\\."; break;
+                case '\\': out += "\\\\"; break;
+                default: out += c;
+            }
+        }
+        out += '$';
+        return out;
+    }
+
+    public static boolean asteriskMatch(String pattern, String text) {
+        return text.matches(createRegexFromGlob(pattern));
+    }
+
+
+}
diff --git a/src/main/java/org/apache/sling/testing/junit/rules/util/Match.java b/src/main/java/org/apache/sling/testing/junit/rules/util/Match.java
new file mode 100644
index 0000000..2dd431d
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/junit/rules/util/Match.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.util;
+
+public class Match {
+    private final boolean matched;
+    private final String reason;
+
+    public Match(boolean matched, String reason) {
+        this.matched = matched;
+        this.reason = reason;
+    }
+
+    public Match(boolean matched) {
+        this.matched = matched;
+        reason = "";
+    }
+
+    public boolean isIgnored() {
+        return matched;
+    }
+
+    public String getReason() {
+        return reason;
+    }
+}
diff --git a/src/test/java/org/apache/sling/testing/junit/rules/util/RunOnceRuleTest.java b/src/test/java/org/apache/sling/testing/junit/rules/util/RunOnceRuleTest.java
new file mode 100644
index 0000000..6b89e5c
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/junit/rules/util/RunOnceRuleTest.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.util;
+
+import org.apache.sling.testing.junit.rules.RunOnceRule;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RunOnceRuleTest {
+    private static final Logger LOG = LoggerFactory.getLogger(RunOnceRule.class);
+    public static int count = 0;
+    
+    @Rule
+    public RunOnceRule roc = new RunOnceRule(new TestRule() {
+        @Override
+        public Statement apply(Statement base, Description description) {
+            count ++;
+            LOG.debug("Run {} times", count);
+            return base;
+        }
+    });
+    
+    @Test
+    public void test1() {
+        Assert.assertEquals("Should have run only once", 1, count);
+    }
+
+    @Test
+    public void test2() {
+        Assert.assertEquals("Should have run only once", 1, count);
+    }
+
+    @Test
+    public void test3() {
+        Assert.assertEquals("Should have run only once", 1, count);
+    }
+
+    @Test
+    public void test4() {
+        Assert.assertEquals("Should have run only once", 1, count);
+    }
+    
+}
diff --git a/src/test/java/org/apache/sling/testing/junit/rules/util/UniquePathsTest.java b/src/test/java/org/apache/sling/testing/junit/rules/util/UniquePathsTest.java
new file mode 100644
index 0000000..d1907db
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/junit/rules/util/UniquePathsTest.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.util;
+
+import org.apache.sling.testing.clients.util.UniquePaths;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.lang.reflect.Field;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static org.junit.Assert.assertEquals;
+
+public class UniquePathsTest {
+
+    @Before
+    public void setup() throws Exception {
+        // Set known startTime and counter values for tests
+        {
+            final Field f = UniquePaths.class.getDeclaredField("startTime");
+            f.setAccessible(true);
+            f.set(UniquePaths.class, 1234L);
+        }
+        {
+            final Field f = UniquePaths.class.getDeclaredField("counter");
+            f.setAccessible(true);
+            f.set(UniquePaths.class, new AtomicLong(9362L));
+        }
+    }
+    
+    @Test
+    public void testNoUPattern() {
+        assertEquals("/tmp/UniquePathsTest_1234_9363", UniquePaths.get(this, "/tmp/"));
+        assertEquals("/bar/UniquePathsTest_1234_9364", UniquePaths.get(this, "/bar/"));
+    }
+    
+    @Test
+    public void testSingleUPattern() {
+        assertEquals("/tmp/UniquePathsTest_1234_9363/foo", UniquePaths.get(this, "/tmp/_UNIQ_/foo"));
+    }
+    
+    @Test
+    public void testMultipleUPattern() {
+        assertEquals(
+                "/tmp/UniquePathsTest_1234_9363/foo/UniquePathsTest_1234_9363.html", 
+                UniquePaths.get(this, "/tmp/_UNIQ_/foo/_UNIQ_.html"));
+    }
+    
+    @Test
+    public void testNullPattern() {
+        assertEquals(
+                "UniquePathsTest_1234_9363", 
+                UniquePaths.get(this, null));
+    }
+    
+    @Test
+    public void testNoPattern() {
+        assertEquals(
+                "UniquePathsTest_1234_9363", 
+                UniquePaths.get(this));
+    }
+}
diff --git a/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleAsteriskMatchTest.java b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleAsteriskMatchTest.java
new file mode 100644
index 0000000..26a5cc2
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleAsteriskMatchTest.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.util.filterrule;
+
+import org.apache.sling.testing.junit.rules.util.IgnoreTestsConfig;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+public class FilterRuleAsteriskMatchTest {
+
+
+
+    private final String pattern;
+    private final String text;
+    private final boolean match;
+
+    public FilterRuleAsteriskMatchTest(String pattern, String text, boolean match) {
+        this.pattern = pattern;
+        this.text = text;
+        this.match = match;
+    }
+
+    @Parameterized.Parameters
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] {
+                {"a.b.c", "a.b.c", true},
+                {"a.b.c.*", "a.b.c.d", true},
+                {"*.c", "a.b.c", true},
+                {"*", "a.b.c.MyTest", true},
+                {"*.MyTest", "a.b.c.MyTest", true},
+                {"a.b.*.c", "a.b.x.y.c", true},
+                {"a.b.*.c.*", "a.b.x.y.c.MyTest", true},
+
+                {"a.b.*.c", "a.b.x.y.c.NotMyTest", false},
+                {"*.MyTest", "a.b.c.NotMyTest", false},
+                {"*.c", "a.b.c.d", false},
+                {"a.b.c", "x", false},
+                {"", "x", false},
+        });
+    }
+
+    @Test
+    public void testAsteriskMatch() {
+        Assert.assertEquals(this.match, IgnoreTestsConfig.asteriskMatch(this.pattern, this.text));
+    }
+}
diff --git a/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleDefaultTest.java b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleDefaultTest.java
new file mode 100644
index 0000000..55e1f05
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleDefaultTest.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.util.filterrule;
+
+import org.apache.sling.testing.junit.rules.FilterRule;
+import org.apache.sling.testing.junit.rules.annotation.IgnoreIfProperty;
+import org.apache.sling.testing.junit.rules.category.FailingTest;
+import org.apache.sling.testing.junit.rules.category.SlowRunningTest;
+import org.junit.*;
+import org.junit.experimental.categories.Category;
+
+@IgnoreIfProperty(name = "test.filterrule.a", value = "x")
+public class FilterRuleDefaultTest {
+    @ClassRule
+    public static FilterRule testFilterRuleClass = new FilterRule().addDefaultIgnoreCategories(FailingTest.class);
+
+    @Rule
+    public FilterRule testFilterRule = new FilterRule().addDefaultIgnoreCategories(FailingTest.class);
+
+    @BeforeClass
+    public static void beforeClass() {
+        System.out.println("BeforeClass");
+        System.clearProperty(FilterRule.CATEGORY_PROPERTY);
+        System.clearProperty(FilterRule.INCLUDE_CATEGORY_PROPERTY);
+    }
+
+    @Before
+    public void before() {
+        System.out.println("Before");
+    }
+
+    @After
+    public void after() {
+        System.out.println("After");
+    }
+
+    @Test
+    public void testWithoutShouldRun() {
+        // Should pass
+    }
+
+    @Test
+    @Category(SlowRunningTest.class)
+    public void testSingleShouldRun() {
+        // Should pass
+    }
+
+    @Test
+    @Category(FailingTest.class)
+    public void testSingleShouldSkip() {
+        Assert.fail("Test should be Ignored");
+    }
+}
diff --git a/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryIgnoreIfTest.java b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryIgnoreIfTest.java
new file mode 100644
index 0000000..360ca6b
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryIgnoreIfTest.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.util.filterrule;
+
+import org.apache.sling.testing.junit.rules.annotation.IgnoreIfProperty;
+import org.apache.sling.testing.junit.rules.annotation.Issue;
+import org.apache.sling.testing.junit.rules.FilterRule;
+import org.apache.sling.testing.junit.rules.category.FailingTest;
+import org.apache.sling.testing.junit.rules.category.SlowRunningTest;
+import org.apache.sling.testing.junit.rules.util.IgnoreTestsConfig;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TestName;
+
+public class FilterRuleExcludeCategoryIgnoreIfTest {
+
+    @Rule
+    public FilterRule testFilterRule = new FilterRule();
+
+    @Rule
+    public TestName name = new TestName();
+
+    static {
+        System.setProperty(FilterRule.CATEGORY_PROPERTY, "Issue,SlowRunningTest");
+        System.setProperty("test.filterrule.a", "a");
+        IgnoreTestsConfig.reCreate();
+    }
+
+    /*
+     * System prop is set for ignoring tests and also for excluding a category Setup: a test is annotated with just
+     * the @IgnoreIf Result: The test is skipped
+     */
+    @Test
+    @IgnoreIfProperty(name = "test.filterrule.a", value = "a")
+    public void testIgnoreIfOnly() {
+        Assert.fail("Test should be Ignored");
+    }
+
+    /*
+     * System prop is set for ignoring tests and also for excluding a category Setup: a test is annotated with
+     * @IgnoreIf and @Category which is excluded Result: The test is skipped
+     */
+    @Test
+    @IgnoreIfProperty(name = "test.filterrule.a", value = "a")
+    @Category(Issue.class)
+    public void testIgnoreIfPropExistsandExcludedCategoryExists() {
+        Assert.fail("Test should be Ignored");
+    }
+
+    /*
+     * System prop is set for ignoring tests and also for excluding a category Setup: a test is annotated with
+     * @IgnoreIf and @Category which is excluded Result: The test is skipped
+     */
+    @Test
+    @IgnoreIfProperty(name = "test.filterrule.a", value = "a")
+    @Category(SlowRunningTest.class)
+    public void testIgnoreIfPropExistsandExcludedCategoryExists_2() {
+        Assert.fail("Test should be Ignored");
+    }
+
+    /*
+     * System prop is set for ignoring tests and also for excluding a category Setup: a test is annotated with
+     * @IgnoreIf and @Category which is not excluded Result: The test is skipped
+     */
+    @Test
+    @IgnoreIfProperty(name = "test.filterrule.a", value = "a")
+    @Category(FailingTest.class)
+    public void testIgnoreIfPropExixtsandExcludedCategoryNotExists() {
+        Assert.fail("Test should be Ignored");
+    }
+
+    /*
+     * System prop is set for ignoring tests and also for excluding a category Setup: a test is annotated with
+     * @Category which is excluded Result: The test is skipped
+     */
+    @Test
+    @Category(Issue.class)
+    public void testExcludedCategoryExists() {
+        Assert.fail("Test should be Ignored");
+    }
+
+    /*
+     * System prop is set for ignoring tests and also for excluding a category Setup: a test is annotated with
+     * @Category which is not excluded Result: The test is not skipped
+     */
+    @Test
+    @Category(FailingTest.class)
+    public void testExcludedCategoryNotExists() {
+        Assert.assertTrue("Test should be Run", true);
+    }
+
+    /*
+     * System prop is set for ignoring tests and also for excluding a category Setup: a test is not annotated with
+     * @Category & @IgnoreIf Result: The test is not skipped
+     */
+    @Test
+    public void testNoAnnotationsExists() {
+        Assert.assertTrue("Test should be Run", true);
+    }
+
+}
diff --git a/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryTest.java b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryTest.java
new file mode 100644
index 0000000..a2bdb87
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryTest.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.util.filterrule;
+
+import org.apache.sling.testing.junit.rules.FilterRule;
+import org.apache.sling.testing.junit.rules.annotation.IgnoreIfProperty;
+import org.apache.sling.testing.junit.rules.annotation.Issue;
+import org.apache.sling.testing.junit.rules.category.FailingTest;
+import org.apache.sling.testing.junit.rules.util.IgnoreTestsConfig;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TestName;
+
+public class FilterRuleExcludeCategoryTest {
+
+    @Rule
+    public FilterRule testFilterRule = new FilterRule();
+
+    @Rule
+    public TestName name = new TestName();
+
+    static {
+        System.setProperty(FilterRule.CATEGORY_PROPERTY, "Issue");
+        IgnoreTestsConfig.reCreate();
+    }
+
+    /*
+     * System prop is set for excluding a category only Setup: a test is annotated with just the @IgnoreIf Result: The
+     * test is executed
+     */
+    @Test
+    @IgnoreIfProperty(name = "test.filterrule.a", value = "a")
+    public void testIgnoreIfOnly() {
+        Assert.assertTrue("Test should be Run", true);
+    }
+
+    /*
+     * System prop is set for excluding a category only Setup: a test is annotated with @IgnoreIf and @Category which
+     * is excluded Result: The test is skipped
+     */
+    @Test
+    @IgnoreIfProperty(name = "test.filterrule.a", value = "a")
+    @Category(Issue.class)
+    public void testIgnoreIfPropExistsandExcludedCategoryExists() {
+        Assert.fail("Test should be Ignored");
+    }
+
+    /*
+     * System prop is set for excluding a category only Setup: a test is annotated with @IgnoreIf and @Category which
+     * is not excluded Result: The test is skipped
+     */
+    @Test
+    @IgnoreIfProperty(name = "test.filterrule.a", value = "a")
+    @Category(FailingTest.class)
+    public void testIgnoreIfPropExixtsandExcludedCategoryNotExists() {
+        Assert.assertTrue("Test should be Run", true);
+    }
+
+    /*
+     * System prop is set for excluding a category only Setup: a test is annotated with @Category which is excluded
+     * Result: The test is skipped
+     */
+    @Test
+    @Category(Issue.class)
+    public void testExcludedCategoryExists() {
+        Assert.fail("Test should be Ignored");
+    }
+
+    /*
+     * System prop is set for excluding a category only Setup: a test is annotated with @Category which is not
+     * excluded Result: The test is executed
+     */
+    @Test
+    @Category(FailingTest.class)
+    public void testExcludedCategoryNotExists() {
+        Assert.assertTrue("Test should be Run", true);
+    }
+
+    /*
+     * System prop is set for ignoring tests and also for excluding a category Setup: a test is not annotated with
+     * @Category & @IgnoreIf Result: The test is skipped
+     */
+    @Test
+    public void testNoAnnotationsExists() {
+        Assert.assertTrue("Test should be Run", true);
+    }
+
+}
diff --git a/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleIgnorelistSkipTest.java b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleIgnorelistSkipTest.java
new file mode 100644
index 0000000..853dcf8
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleIgnorelistSkipTest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.util.filterrule;
+
+import org.apache.sling.testing.junit.rules.FilterRule;
+import org.apache.sling.testing.junit.rules.util.IgnoreTestsConfig;
+import org.junit.*;
+
+// TODO use ParallelComputer in junit and make these classes into one test?
+public class FilterRuleIgnorelistSkipTest {
+
+    @ClassRule
+    public static FilterRule classRule = new FilterRule();
+    @Rule
+    public FilterRule methodRule = new FilterRule();
+
+    static {
+        System.clearProperty(IgnoreTestsConfig.IGNORE_LIST_PROP);
+        System.setProperty(IgnoreTestsConfig.IGNORE_LIST_PROP, "*.notmypackage.*, *.FilterRuleIgnorelistSkipTest#shouldSkip:WTF-9999");
+        IgnoreTestsConfig.reCreate();
+    }
+
+    @AfterClass
+    public static void clearIgnoreList() {
+        System.clearProperty(IgnoreTestsConfig.IGNORE_LIST_PROP);
+    }
+
+    @Test
+    public void shouldSkip() {
+        Assert.fail("Test should be skipped");
+    }
+
+}
diff --git a/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleIgnorelistTest.java b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleIgnorelistTest.java
new file mode 100644
index 0000000..8c5bbc1
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleIgnorelistTest.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.util.filterrule;
+
+import org.apache.sling.testing.junit.rules.FilterRule;
+import org.apache.sling.testing.junit.rules.util.IgnoreTestsConfig;
+import org.junit.*;
+
+public class FilterRuleIgnorelistTest {
+
+    @ClassRule
+    public static FilterRule classRule = new FilterRule();
+    @Rule
+    public FilterRule methodRule = new FilterRule();
+
+    static {
+        System.clearProperty(IgnoreTestsConfig.IGNORE_LIST_PROP);
+        System.setProperty(IgnoreTestsConfig.IGNORE_LIST_PROP, "*.FilterRuleIgnorelistTest#shouldSkip:WTF-9999, *.notmypackage.*");
+        IgnoreTestsConfig.reCreate();
+    }
+
+    @AfterClass
+    public static void clearIgnoreList() {
+        System.clearProperty(IgnoreTestsConfig.IGNORE_LIST_PROP);
+    }
+
+    @Test
+    public void shouldSkip() {
+        Assert.fail("Test should be skipped");
+    }
+
+    @Test
+    public void shouldPass() {
+
+    }
+
+}
diff --git a/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleIncludeCategoryIgnoreIfTest.java b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleIncludeCategoryIgnoreIfTest.java
new file mode 100644
index 0000000..3060fcb
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleIncludeCategoryIgnoreIfTest.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.util.filterrule;
+
+import org.apache.sling.testing.junit.rules.FilterRule;
+import org.apache.sling.testing.junit.rules.annotation.IgnoreIfProperty;
+import org.apache.sling.testing.junit.rules.annotation.Issue;
+import org.apache.sling.testing.junit.rules.category.FailingTest;
+import org.apache.sling.testing.junit.rules.util.IgnoreTestsConfig;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TestName;
+
+public class FilterRuleIncludeCategoryIgnoreIfTest {
+
+    @Rule
+    public FilterRule testFilterRule = new FilterRule();
+
+    @Rule
+    public TestName name = new TestName();
+
+    static {
+        System.setProperty(FilterRule.CATEGORY_PROPERTY, "Issue");
+        System.setProperty(FilterRule.INCLUDE_CATEGORY_PROPERTY, "");
+        System.setProperty("test.filterrule.a", "a");
+        IgnoreTestsConfig.reCreate();
+    }
+
+    /*
+     * System prop is set for ignoring tests and for including a category Setup: a test is annotated with just the
+     * @IgnoreIf Result: The test is skipped
+     */
+    @Test
+    @IgnoreIfProperty(name = "test.filterrule.a", value = "a")
+    public void testIgnoreIfOnly() {
+        Assert.fail("Test should be Ignored");
+    }
+
+    /*
+     * System prop is set for ignoring tests and for including a category Setup: a test is annotated with @IgnoreIf
+     * and @Category which is included Result: The test is skipped
+     */
+    @Test
+    @IgnoreIfProperty(name = "test.filterrule.a", value = "a")
+    @Category(Issue.class)
+    public void testIgnoreIfPropExistsandIncludedCategoryExists() {
+        Assert.fail("Test should be Ignored");
+    }
+
+    /*
+     * System prop is set for ignoring tests and for including a category Setup: a test is annotated with @IgnoreIf
+     * and @Category which is not included Result: The test is skipped
+     */
+    @Test
+    @IgnoreIfProperty(name = "test.filterrule.a", value = "a")
+    @Category(FailingTest.class)
+    public void testIgnoreIfPropExixtsandIncludedCategoryNotExists() {
+        Assert.fail("Test should be Ignored");
+    }
+
+    /*
+     * System prop is set for ignoring tests and for including a category Setup: a test is annotated with @Category
+     * which is not included Result: The test is skipped
+     */
+    @Test
+    @Category(FailingTest.class)
+    public void testIncludedCategoryNotExists() {
+        Assert.fail("Test should be Ignored");
+    }
+
+    /*
+     * System prop is set for ignoring tests and for including a category Setup: a test is annotated with @Category
+     * which is included Result: The test is executed
+     */
+    @Test
+    @Category(Issue.class)
+    public void testIncludedCategoryExists() {
+        Assert.assertTrue("Test should be Run", true);
+    }
+
+    /*
+     * System prop is set for ignoring tests and for including a category Setup: a test is not annotated with
+     * @Category & @IgnoreIf Result: The test is skipped
+     */
+    @Test
+    public void testNoAnnotationsExists() {
+        Assert.fail("Test should be Ignored");
+    }
+
+}
diff --git a/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleIncludeCategoryTest.java b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleIncludeCategoryTest.java
new file mode 100644
index 0000000..8b4b564
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleIncludeCategoryTest.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.util.filterrule;
+
+import org.apache.sling.testing.junit.rules.annotation.IgnoreIfProperty;
+import org.apache.sling.testing.junit.rules.FilterRule;
+import org.apache.sling.testing.junit.rules.annotation.Issue;
+import org.apache.sling.testing.junit.rules.category.FailingTest;
+import org.apache.sling.testing.junit.rules.category.SlowRunningTest;
+import org.apache.sling.testing.junit.rules.util.IgnoreTestsConfig;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TestName;
+
+public class FilterRuleIncludeCategoryTest {
+
+    @Rule
+    public FilterRule testFilterRule = new FilterRule();
+
+    @Rule
+    public TestName name = new TestName();
+
+    static {
+        System.setProperty(FilterRule.CATEGORY_PROPERTY, "Issue,SlowRunningTest");
+        System.setProperty(FilterRule.INCLUDE_CATEGORY_PROPERTY, "");
+        IgnoreTestsConfig.reCreate();
+    }
+
+    /*
+     * System prop is set for including a category only Setup: a test is annotated with just the @IgnoreIf Result: The
+     * test is skipped
+     */
+    @Test
+    @IgnoreIfProperty(name = "test.filterrule.a", value = "a")
+    public void testIgnoreIfOnly() {
+        Assert.fail("Test should be Ignored");
+    }
+
+    /*
+     * System prop is set for including a category only Setup: a test is annotated with @IgnoreIf and @Category which
+     * is included Result: The test is executed
+     */
+    @Test
+    @IgnoreIfProperty(name = "test.filterrule.a", value = "a")
+    @Category(Issue.class)
+    public void testIgnoreIfPropExistsandIncludedCategoryExists() {
+        Assert.assertTrue("Test should be Run", true);
+    }
+
+    /*
+     * System prop is set for including a category only Setup: a test is annotated with @IgnoreIf and @Category which
+     * is included Result: The test is executed
+     */
+    @Test
+    @IgnoreIfProperty(name = "test.filterrule.a", value = "a")
+    @Category(SlowRunningTest.class)
+    public void testIgnoreIfPropExistsandIncludedCategoryExists_2() {
+        Assert.assertTrue("Test should be Run", true);
+    }
+
+    /*
+     * System prop is set for including a category only Setup: a test is annotated with @IgnoreIf and @Category which
+     * is not included Result: The test is skipped
+     */
+    @Test
+    @IgnoreIfProperty(name = "test.filterrule.a", value = "a")
+    @Category(FailingTest.class)
+    public void testIgnoreIfPropExixtsandIncludedCategoryNotExists() {
+        Assert.fail("Test should be Ignored");
+    }
+
+    /*
+     * System prop is set for including a category only Setup: a test is annotated with @Category which is not
+     * included Result: The test is skipped
+     */
+    @Test
+    @Category(FailingTest.class)
+    public void testIncludedCategoryNotExists() {
+        Assert.fail("Test should be Ignored");
+    }
+
+    /*
+     * System prop is set for including a category only Setup: a test is annotated with @Category which is included
+     * Result: The test is executed
+     */
+    @Test
+    @Category(Issue.class)
+    public void testIncludedCategoryExists() {
+        Assert.assertTrue("Test should be Run", true);
+    }
+
+    /*
+     * System prop is set for ignoring tests and also for excluding a category Setup: a test is not annotated with
+     * @Category & @IgnoreIf Result: The test is skipped
+     */
+    @Test
+    public void testNoAnnotationsExists() {
+        Assert.fail("Test should be Ignored");
+    }
+
+}
diff --git a/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleTest.java b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleTest.java
new file mode 100644
index 0000000..60f93cc
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleTest.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.util.filterrule;
+
+import org.apache.sling.testing.junit.rules.annotation.IgnoreIfProperty;
+import org.apache.sling.testing.junit.rules.FilterRule;
+import org.apache.sling.testing.junit.rules.annotation.IgnoreIfProperties;
+import org.junit.*;
+
+@IgnoreIfProperty(name = "test.filterrule.a", value = "x")
+public class FilterRuleTest {
+    @ClassRule
+    public static FilterRule testFilterRuleClass = new FilterRule();
+
+    @Rule
+    public FilterRule testFilterRule = new FilterRule();
+
+    @BeforeClass
+    public static void beforeClass() {
+        System.out.println("BeforeClass");
+    }
+
+    @Before
+    public void before() {
+        System.out.println("Before");
+    }
+
+    @After
+    public void after() {
+        System.out.println("After");
+    }
+
+    static {
+        System.clearProperty(FilterRule.CATEGORY_PROPERTY);
+        System.clearProperty(FilterRule.INCLUDE_CATEGORY_PROPERTY);
+
+        System.setProperty("test.filterrule.a", "a");
+        System.setProperty("test.filterrule.b", "b");
+        System.setProperty("test.filterrule.c", "");
+    }
+
+    @Test
+    public void testWithoutShouldRun() {
+        // Should pass
+    }
+
+    @Test
+    @IgnoreIfProperty(name = "test.filterrule.a", value = "x")
+    public void testSingleShouldRun() {
+        // Should pass
+    }
+
+    @Test
+    @IgnoreIfProperty(name = "test.filterrule.a", value = "a")
+    public void testSingleShouldSkip() {
+        Assert.fail("Test should be Ignored");
+    }
+
+    @Test
+    @IgnoreIfProperty(name = "test.filterrule.c")
+    public void testSingleDefaultShouldSkip() {
+        Assert.fail("Test should be Ignored");
+    }
+
+    @Test
+    @IgnoreIfProperties({@IgnoreIfProperty(name = "test.filterrule.a", value = "a"),
+            @IgnoreIfProperty(name = "test.filterrule.noexist")})
+    public void testMultipleShouldSkip() {
+        Assert.fail("Test should be Ignored");
+    }
+
+    @Test
+    @IgnoreIfProperties({@IgnoreIfProperty(name = "test.filterrule.noexist1", value = "a"),
+            @IgnoreIfProperty(name = "test.filterrule.noexist2")})
+    public void testMultipleShouldPass() {
+        // Should pass
+    }
+
+    @Test
+    @IgnoreIfProperties({@IgnoreIfProperty(name = "test.filterrule.noexist1", value = "a"),
+            @IgnoreIfProperty(name = "test.filterrule.noexist2")})
+    @IgnoreIfProperty(name = "test.filterrule.noexist3")
+    public void testBothShouldPass() {
+        // Should pass
+    }
+
+    @Test
+    @IgnoreIfProperties({@IgnoreIfProperty(name = "test.filterrule.noexist1", value = "a"),
+            @IgnoreIfProperty(name = "test.filterrule.c")})
+    @IgnoreIfProperty(name = "test.filterrule.noexist3")
+    public void testBothShouldSkip1() {
+        Assert.fail("Test should be Ignored");
+    }
+
+    @Test
+    @IgnoreIfProperties({@IgnoreIfProperty(name = "test.filterrule.noexist1", value = "a"),
+            @IgnoreIfProperty(name = "test.filterrule.noexist2")})
+    @IgnoreIfProperty(name = "test.filterrule.b", value = "b")
+    public void testBothShouldSkip2() {
+        Assert.fail("Test should be Ignored");
+    }
+}
diff --git a/src/test/java/org/apache/sling/testing/junit/rules/util/instanceconfig/DebugInstanceConfig.java b/src/test/java/org/apache/sling/testing/junit/rules/util/instanceconfig/DebugInstanceConfig.java
new file mode 100644
index 0000000..c3f41ec
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/junit/rules/util/instanceconfig/DebugInstanceConfig.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.util.instanceconfig;
+
+import org.apache.sling.testing.clients.util.config.InstanceConfig;
+import org.apache.sling.testing.clients.util.config.InstanceConfigException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DebugInstanceConfig implements InstanceConfig {
+    private static final Logger LOG = LoggerFactory.getLogger(DebugInstanceConfig.class);
+    private int value = 0;
+
+    @Override
+    public InstanceConfig save() throws InstanceConfigException {
+        this.value = 1;
+        LOG.debug("Saved 1");
+        return this;
+    }
+
+    @Override
+    public InstanceConfig restore() throws InstanceConfigException {
+        this.value = 2;
+        LOG.debug("Restored 2");
+        return this;
+    }
+
+
+    public int getValue() {
+        return value;
+    }
+}
diff --git a/src/test/java/org/apache/sling/testing/junit/rules/util/instanceconfig/InstanceConfigRuleTest.java b/src/test/java/org/apache/sling/testing/junit/rules/util/instanceconfig/InstanceConfigRuleTest.java
new file mode 100644
index 0000000..a9ba61d
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/junit/rules/util/instanceconfig/InstanceConfigRuleTest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.util.instanceconfig;
+
+import org.apache.sling.testing.junit.rules.InstanceConfigRule;
+import org.apache.sling.testing.junit.rules.util.Action;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+
+// TODO: Use a junit processor to test this
+public class InstanceConfigRuleTest {
+    public boolean actionCalled = false;
+    
+    class DebugAction implements Action {
+        @Override
+        public void call() throws Throwable {
+            actionCalled = true;
+        }
+    }
+    
+    DebugInstanceConfig dic = new DebugInstanceConfig();
+    
+    @Rule
+    public InstanceConfigRule myInstanceConfig = new InstanceConfigRule(dic).withAction(new DebugAction());
+    
+    @Test
+    public void myTest() {
+        Assert.assertEquals("Value should be the one set on save: 1", 1, dic.getValue());
+        Assert.assertTrue(actionCalled);
+    }
+
+
+}
diff --git a/src/test/java/org/apache/sling/testing/junit/rules/util/poller/AbstractPollerTest.java b/src/test/java/org/apache/sling/testing/junit/rules/util/poller/AbstractPollerTest.java
new file mode 100644
index 0000000..9b0de33
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/junit/rules/util/poller/AbstractPollerTest.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.junit.rules.util.poller;
+
+import org.apache.sling.testing.clients.util.poller.AbstractPoller;
+import org.junit.Assert;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AbstractPollerTest {
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractPollerTest.class);
+
+    @Test
+    public void testCallAndWaitSuccess() throws InterruptedException {
+        AbstractPoller poller = new AbstractPoller(100, 5) {
+            int callNumber = 0;
+
+            @Override
+            public boolean call() {
+                return true;
+            }
+
+            @Override
+            public boolean condition() {
+                callNumber += 1;
+                LOG.debug("Call nr " + callNumber);
+                if (callNumber == 4) {
+                    return true;
+                }
+                return false;
+            }
+        };
+        Assert.assertTrue(poller.callAndWait());
+    }
+
+    @Test
+    public void testCallAndWaitFailure() throws InterruptedException {
+        AbstractPoller poller = new AbstractPoller(100, 5) {
+            @Override
+            public boolean call() {
+                return true;
+            }
+
+            @Override
+            public boolean condition() {
+                return false;
+            }
+        };
+        Assert.assertFalse(poller.callAndWait());
+    }
+
+    @Test
+    public void testCallUntilSuccess() throws InterruptedException {
+        AbstractPoller poller = new AbstractPoller(100, 5) {
+            int callNumber = 0;
+
+            @Override
+            public boolean call() {
+                callNumber += 1;
+                LOG.debug("Call nr " + callNumber);
+                return true;
+            }
+
+            @Override
+            public boolean condition() {
+                if (callNumber == 4) {
+                    return true;
+                }
+                return false;
+            }
+        };
+        Assert.assertTrue(poller.callUntilCondition());
+    }
+
+    @Test
+    public void testCallUntilFailure() throws InterruptedException {
+        AbstractPoller poller = new AbstractPoller(100, 5) {
+            @Override
+            public boolean call() {
+                return true;
+            }
+
+            @Override
+            public boolean condition() {
+                return false;
+            }
+        };
+        Assert.assertFalse(poller.callUntilCondition());
+    }
+
+
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.