You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2016/04/29 16:04:51 UTC

svn commit: r1741634 [1/2] - in /sling/trunk/testing/junit/rules: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/sling/ src/main/java/org/apache/sling/testing/ src/main/java/org/apache/sling/testi...

Author: bdelacretaz
Date: Fri Apr 29 14:04:50 2016
New Revision: 1741634

URL: http://svn.apache.org/viewvc?rev=1741634&view=rev
Log:
SLING-5703 - new junit/rules module, extracted and enhanced from testing/tools. Contributed by Andrei Dulvac, thanks!

Added:
    sling/trunk/testing/junit/rules/   (with props)
    sling/trunk/testing/junit/rules/pom.xml
    sling/trunk/testing/junit/rules/src/
    sling/trunk/testing/junit/rules/src/main/
    sling/trunk/testing/junit/rules/src/main/java/
    sling/trunk/testing/junit/rules/src/main/java/org/
    sling/trunk/testing/junit/rules/src/main/java/org/apache/
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/Condition.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/FilterRule.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/InstanceConfigRule.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/RunOnceRule.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/SlingClassRule.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/SlingInstanceRule.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/SlingRule.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/TestDescriptionRule.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/TestStickyCookieRule.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/TestTimeout.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIf.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIfProperties.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIfProperty.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/Issue.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/Issues.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/ClusterAwareTest.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/FailingTest.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/FastRunningTest.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/SlowRunningTest.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/SmokeTest.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/AbstractInstance.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/ExistingInstance.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/ExistingInstanceStatement.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/Instance.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/util/
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/util/ConfigurationPool.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/util/ContextPathAllocator.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/util/DirectoryAllocator.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/util/Options.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/util/
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/util/Action.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/util/IgnoreTestsConfig.java
    sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/util/Match.java
    sling/trunk/testing/junit/rules/src/test/
    sling/trunk/testing/junit/rules/src/test/java/
    sling/trunk/testing/junit/rules/src/test/java/org/
    sling/trunk/testing/junit/rules/src/test/java/org/apache/
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/testing/
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/testing/junit/
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/testing/junit/rules/
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/testing/junit/rules/util/
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/testing/junit/rules/util/RunOnceRuleTest.java
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/testing/junit/rules/util/UniquePathsTest.java
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleAsteriskMatchTest.java
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleDefaultTest.java
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryIgnoreIfTest.java
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleExcludeCategoryTest.java
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleIgnorelistSkipTest.java
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleIgnorelistTest.java
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleIncludeCategoryIgnoreIfTest.java
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleIncludeCategoryTest.java
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/testing/junit/rules/util/filterrule/FilterRuleTest.java
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/testing/junit/rules/util/instanceconfig/
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/testing/junit/rules/util/instanceconfig/DebugInstanceConfig.java
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/testing/junit/rules/util/instanceconfig/InstanceConfigRuleTest.java
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/testing/junit/rules/util/poller/
    sling/trunk/testing/junit/rules/src/test/java/org/apache/sling/testing/junit/rules/util/poller/AbstractPollerTest.java

Propchange: sling/trunk/testing/junit/rules/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Fri Apr 29 14:04:50 2016
@@ -0,0 +1,19 @@
+target
+sling
+bin
+logs
+jackrabbit-repository
+derby.log
+*.iml
+*.ipr
+*.iws
+.settings
+.project
+.classpath
+.externalToolBuilders
+maven-eclipse.xml
+jackrabbit
+
+
+
+

Added: sling/trunk/testing/junit/rules/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/pom.xml?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/pom.xml (added)
+++ sling/trunk/testing/junit/rules/pom.xml Fri Apr 29 14:04:50 2016
@@ -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>

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/Condition.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/Condition.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/Condition.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/Condition.java Fri Apr 29 14:04:50 2016
@@ -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();
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/FilterRule.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/FilterRule.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/FilterRule.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/FilterRule.java Fri Apr 29 14:04:50 2016
@@ -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;
+    }
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/InstanceConfigRule.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/InstanceConfigRule.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/InstanceConfigRule.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/InstanceConfigRule.java Fri Apr 29 14:04:50 2016
@@ -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();
+                }
+            }
+        };
+    }
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/RunOnceRule.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/RunOnceRule.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/RunOnceRule.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/RunOnceRule.java Fri Apr 29 14:04:50 2016
@@ -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;
+        }
+    }
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/SlingClassRule.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/SlingClassRule.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/SlingClassRule.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/SlingClassRule.java Fri Apr 29 14:04:50 2016
@@ -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);
+    }
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/SlingInstanceRule.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/SlingInstanceRule.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/SlingInstanceRule.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/SlingInstanceRule.java Fri Apr 29 14:04:50 2016
@@ -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);
+    }
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/SlingRule.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/SlingRule.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/SlingRule.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/SlingRule.java Fri Apr 29 14:04:50 2016
@@ -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);
+    }
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/TestDescriptionRule.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/TestDescriptionRule.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/TestDescriptionRule.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/TestDescriptionRule.java Fri Apr 29 14:04:50 2016
@@ -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();
+    }
+
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/TestStickyCookieRule.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/TestStickyCookieRule.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/TestStickyCookieRule.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/TestStickyCookieRule.java Fri Apr 29 14:04:50 2016
@@ -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();
+    }
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/TestTimeout.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/TestTimeout.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/TestTimeout.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/TestTimeout.java Fri Apr 29 14:04:50 2016
@@ -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

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIf.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIf.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIf.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIf.java Fri Apr 29 14:04:50 2016
@@ -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();
+}
+
+

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIfProperties.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIfProperties.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIfProperties.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIfProperties.java Fri Apr 29 14:04:50 2016
@@ -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();
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIfProperty.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIfProperty.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIfProperty.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/IgnoreIfProperty.java Fri Apr 29 14:04:50 2016
@@ -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 "";
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/Issue.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/Issue.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/Issue.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/Issue.java Fri Apr 29 14:04:50 2016
@@ -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 "";
+
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/Issues.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/Issues.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/Issues.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/annotation/Issues.java Fri Apr 29 14:04:50 2016
@@ -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();
+
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/ClusterAwareTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/ClusterAwareTest.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/ClusterAwareTest.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/ClusterAwareTest.java Fri Apr 29 14:04:50 2016
@@ -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 {
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/FailingTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/FailingTest.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/FailingTest.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/FailingTest.java Fri Apr 29 14:04:50 2016
@@ -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 {
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/FastRunningTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/FastRunningTest.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/FastRunningTest.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/FastRunningTest.java Fri Apr 29 14:04:50 2016
@@ -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 {
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/SlowRunningTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/SlowRunningTest.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/SlowRunningTest.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/SlowRunningTest.java Fri Apr 29 14:04:50 2016
@@ -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 {
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/SmokeTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/SmokeTest.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/SmokeTest.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/category/SmokeTest.java Fri Apr 29 14:04:50 2016
@@ -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 {
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/AbstractInstance.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/AbstractInstance.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/AbstractInstance.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/AbstractInstance.java Fri Apr 29 14:04:50 2016
@@ -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");
+    }
+
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/ExistingInstance.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/ExistingInstance.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/ExistingInstance.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/ExistingInstance.java Fri Apr 29 14:04:50 2016
@@ -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;
+    }
+
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/ExistingInstanceStatement.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/ExistingInstanceStatement.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/ExistingInstanceStatement.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/ExistingInstanceStatement.java Fri Apr 29 14:04:50 2016
@@ -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;
+    }
+
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/Instance.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/Instance.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/Instance.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/Instance.java Fri Apr 29 14:04:50 2016
@@ -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);
+
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/util/ConfigurationPool.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/util/ConfigurationPool.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/util/ConfigurationPool.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/util/ConfigurationPool.java Fri Apr 29 14:04:50 2016
@@ -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;
+        }
+    }
+
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/util/ContextPathAllocator.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/util/ContextPathAllocator.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/util/ContextPathAllocator.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/util/ContextPathAllocator.java Fri Apr 29 14:04:50 2016
@@ -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);
+    }
+
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/util/DirectoryAllocator.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/util/DirectoryAllocator.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/util/DirectoryAllocator.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/util/DirectoryAllocator.java Fri Apr 29 14:04:50 2016
@@ -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;
+        }
+    }
+}

Added: sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/util/Options.java
URL: http://svn.apache.org/viewvc/sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/util/Options.java?rev=1741634&view=auto
==============================================================================
--- sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/util/Options.java (added)
+++ sling/trunk/testing/junit/rules/src/main/java/org/apache/sling/testing/junit/rules/instance/util/Options.java Fri Apr 29 14:04:50 2016
@@ -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());
+    }
+
+}