SLING-4728 - run mode support + tests added

git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1685071 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/sling/crankstart/launcher/BundlesInstaller.java b/src/main/java/org/apache/sling/crankstart/launcher/BundlesInstaller.java
index 929ca41..2436ca2 100644
--- a/src/main/java/org/apache/sling/crankstart/launcher/BundlesInstaller.java
+++ b/src/main/java/org/apache/sling/crankstart/launcher/BundlesInstaller.java
@@ -19,6 +19,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
+import java.util.Arrays;
 
 import org.apache.sling.provisioning.model.Artifact;
 import org.apache.sling.provisioning.model.ArtifactGroup;
@@ -36,9 +37,11 @@
 public class BundlesInstaller {
     private final Logger log = LoggerFactory.getLogger(getClass());
     private final Model model;
+    private final RunModeFilter rmFilter;
     
-    public BundlesInstaller(Model m) {
+    public BundlesInstaller(Model m, RunModeFilter rmFilter) {
         model = m;
+        this.rmFilter = rmFilter;
     }
     
     public void installBundles(BundleContext ctx, FeatureFilter filter) throws IOException, BundleException {
@@ -50,6 +53,10 @@
             
             log.info("Processing feature: {}", f.getName());
             for(RunMode rm : f.getRunModes()) {
+                if(!rmFilter.runModeActive(rm)) {
+                    log.info("RunMode is not active, ignored: {}", Arrays.asList(rm.getNames()));
+                    continue;
+                }
                 for(ArtifactGroup g : rm.getArtifactGroups()) {
                     final int startLevel = g.getStartLevel();
                     for(Artifact a : g) {
diff --git a/src/main/java/org/apache/sling/crankstart/launcher/Configurations.java b/src/main/java/org/apache/sling/crankstart/launcher/Configurations.java
index a0edf96..6da4b45 100644
--- a/src/main/java/org/apache/sling/crankstart/launcher/Configurations.java
+++ b/src/main/java/org/apache/sling/crankstart/launcher/Configurations.java
@@ -18,6 +18,7 @@
 
 import java.io.Closeable;
 import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
 import java.util.Dictionary;
 
 import org.apache.sling.provisioning.model.Configuration;
@@ -34,6 +35,7 @@
     private final Logger log = LoggerFactory.getLogger(getClass());
     public static final String CONFIG_ADMIN_CLASS = "org.osgi.service.cm.ConfigurationAdmin";
     private final Model model;
+    private final RunModeFilter rmFilter;
     private final ServiceTracker tracker;
     private ConfigAdminProxy proxy; 
     
@@ -78,8 +80,9 @@
         }
     }
     
-    public Configurations(BundleContext ctx, Model m) {
+    public Configurations(BundleContext ctx, Model m, RunModeFilter rmFilter) {
         model = m;
+        this.rmFilter = rmFilter;
         tracker = new ServiceTracker(ctx, CONFIG_ADMIN_CLASS, null);
         tracker.open();
     }
@@ -107,6 +110,10 @@
         log.info("Activating configurations from provisioning model");
         for(Feature f : model.getFeatures()) {
             for(RunMode r : f.getRunModes()) {
+                if(!rmFilter.runModeActive(r)) {
+                    log.info("RunMode is not active, ignored: {}", Arrays.asList(r.getNames()));
+                    continue;
+                }
                 for(Configuration c : r.getConfigurations()) {
                     try {
                         setConfig(c);
diff --git a/src/main/java/org/apache/sling/crankstart/launcher/FrameworkSetup.java b/src/main/java/org/apache/sling/crankstart/launcher/FrameworkSetup.java
index 456b8ba..d01f08e 100644
--- a/src/main/java/org/apache/sling/crankstart/launcher/FrameworkSetup.java
+++ b/src/main/java/org/apache/sling/crankstart/launcher/FrameworkSetup.java
@@ -58,12 +58,15 @@
         final FrameworkFactory factory = (FrameworkFactory)getClass().getClassLoader().loadClass("org.apache.felix.framework.FrameworkFactory").newInstance();
         final Framework framework = factory.newFramework(fprops);
         framework.start();
-        final Configurations cfg = new Configurations(framework.getBundleContext(), model);
+        
+        final RunModeFilter rmFilter = new RunModeFilter();
+        
+        final Configurations cfg = new Configurations(framework.getBundleContext(), model, rmFilter);
         setShutdownHook(framework, new Closeable[] { cfg });
         log.info("OSGi framework started");
         
         log.info("Installing bundles from provisioning model");
-        final BundlesInstaller bi = new BundlesInstaller(model);
+        final BundlesInstaller bi = new BundlesInstaller(model, rmFilter);
         final BundleContext bc = framework.getBundleContext();
         bi.installBundles(bc, Launcher.NOT_CRANKSTART_FILTER);
         cfg.maybeConfigure();
diff --git a/src/main/java/org/apache/sling/crankstart/launcher/RunModeFilter.java b/src/main/java/org/apache/sling/crankstart/launcher/RunModeFilter.java
new file mode 100644
index 0000000..bdd0a80
--- /dev/null
+++ b/src/main/java/org/apache/sling/crankstart/launcher/RunModeFilter.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.crankstart.launcher;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.sling.provisioning.model.RunMode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RunModeFilter {
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private final List<String> activeRunModes;
+    public static final String SLING_RUN_MODES = "sling.run.modes";
+
+    RunModeFilter() {
+        final String sysProp = System.getProperty(SLING_RUN_MODES, "");
+        activeRunModes = new ArrayList<String>(Arrays.asList(sysProp.split(",")));
+        log.info("Active run modes: {}", activeRunModes);
+    }
+    
+    public boolean runModeActive(RunMode m) {
+        // A RunMode is active if all its names are active
+        final String [] names = m.getNames();
+        if(names == null || names.length == 0) {
+            return true;
+        }
+        
+        boolean active = true;
+        for(String name : names) {
+            active &= activeRunModes.contains(name);
+        }
+        return active;
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/crankstart/launcher/RunModeATest.java b/src/test/java/org/apache/sling/crankstart/launcher/RunModeATest.java
index 8bb1e54..6b87871 100644
--- a/src/test/java/org/apache/sling/crankstart/launcher/RunModeATest.java
+++ b/src/test/java/org/apache/sling/crankstart/launcher/RunModeATest.java
@@ -27,7 +27,7 @@
     
     @BeforeClass
     public static void setupClass() throws IOException {
-        System.setProperty(U.SLING_RUN_MODES, RUN_MODES);
+        System.setProperty(RunModeFilter.SLING_RUN_MODES, RUN_MODES);
         C.setup();
         osgiConsole = new WebconsoleClient(C.getBaseUrl(), U.ADMIN, U.ADMIN);
     }
@@ -39,7 +39,7 @@
     
     @AfterClass
     public static void cleanupClass() {
-        System.clearProperty(U.SLING_RUN_MODES);
+        System.clearProperty(RunModeFilter.SLING_RUN_MODES);
     }
     
     @Test
@@ -54,8 +54,7 @@
         U.setAdminCredentials(client);
         U.assertHttpGet(C, client,
                 "/test/config/runmode.test", 
-                "runmode.test#mode=(String)That's B#service.pid=(String)runmode.test##EOC#");
-                // TODO should be "runmode.test#mode=(String)This is A##EOC#");
+                "runmode.test#mode=(String)This is A#service.pid=(String)runmode.test##EOC#");
     }
     
 }
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/crankstart/launcher/RunModeBTest.java b/src/test/java/org/apache/sling/crankstart/launcher/RunModeBTest.java
new file mode 100644
index 0000000..412c60b
--- /dev/null
+++ b/src/test/java/org/apache/sling/crankstart/launcher/RunModeBTest.java
@@ -0,0 +1,60 @@
+package org.apache.sling.crankstart.launcher;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.sling.commons.testing.junit.Retry;
+import org.apache.sling.commons.testing.junit.RetryRule;
+import org.apache.sling.testing.tools.osgi.WebconsoleClient;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+
+/** Test our run modes support */ 
+public class RunModeBTest {
+    
+    private static CrankstartSetup C = new CrankstartSetup();
+    private static WebconsoleClient osgiConsole;
+    private DefaultHttpClient client;
+    private static final String RUN_MODES = "bala,B,laika,another";
+    
+    @Rule
+    public final RetryRule retryRule = new RetryRule();
+    
+    @BeforeClass
+    public static void setupClass() throws IOException {
+        System.setProperty(RunModeFilter.SLING_RUN_MODES, RUN_MODES);
+        C.setup();
+        osgiConsole = new WebconsoleClient(C.getBaseUrl(), U.ADMIN, U.ADMIN);
+    }
+    
+    @Before
+    public void setup() throws IOException {
+        client = new DefaultHttpClient();
+    }
+    
+    @AfterClass
+    public static void cleanupClass() {
+        System.clearProperty(RunModeFilter.SLING_RUN_MODES);
+    }
+    
+    @Test
+    @Retry(timeoutMsec=U.LONG_TIMEOUT_MSEC, intervalMsec=U.STD_INTERVAL)
+    public void testSlingApiVersionA() throws Exception {
+        assertEquals("2.0.6", osgiConsole.getBundleVersion(U.SLING_API_BUNDLE));
+    }
+    
+    @Test
+    @Retry(timeoutMsec=U.LONG_TIMEOUT_MSEC, intervalMsec=U.STD_INTERVAL)
+    public void testConfigA() throws Exception {
+        U.setAdminCredentials(client);
+        U.assertHttpGet(C, client,
+                "/test/config/runmode.test", 
+                "runmode.test#mode=(String)That's B + another#service.pid=(String)runmode.test##EOC#");
+    }
+    
+}
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/crankstart/launcher/U.java b/src/test/java/org/apache/sling/crankstart/launcher/U.java
index 42c6d94..626acc2 100644
--- a/src/test/java/org/apache/sling/crankstart/launcher/U.java
+++ b/src/test/java/org/apache/sling/crankstart/launcher/U.java
@@ -23,11 +23,10 @@
 public class U {
     
     public static final String ADMIN = "admin";
-    public static final int LONG_TIMEOUT_SECONDS = 10;
+    public static final int LONG_TIMEOUT_SECONDS = 2; // TODO 10
     public static final int LONG_TIMEOUT_MSEC = LONG_TIMEOUT_SECONDS * 1000;
     public static final int STD_INTERVAL = 250;
     public static final String SLING_API_BUNDLE = "org.apache.sling.api";
-    public static final String SLING_RUN_MODES = "sling.run.modes";
     
     static void setAdminCredentials(DefaultHttpClient c) {
         c.getCredentialsProvider().setCredentials(
diff --git a/src/test/resources/provisioning-model/crankstart-tests.txt b/src/test/resources/provisioning-model/crankstart-tests.txt
index e186d7f..b43499e 100644
--- a/src/test/resources/provisioning-model/crankstart-tests.txt
+++ b/src/test/resources/provisioning-model/crankstart-tests.txt
@@ -35,9 +35,9 @@
 [artifacts runModes=B]
   org.apache.sling/org.apache.sling.api/2.0.6
 
-[configurations runModes=B]
+[configurations runModes=B,another]
   runmode.test
-    mode="That's B"
+    mode="That's B + another"
 
 [configurations]
   org.apache.sling.crankstart.testservices.SingleConfigServlet