incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bdelacre...@apache.org
Subject svn commit: r884622 - in /sling/trunk/launchpad/base: ./ src/main/java/org/apache/sling/launchpad/base/impl/ src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/ src/test/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/
Date Thu, 26 Nov 2009 16:17:02 GMT
Author: bdelacretaz
Date: Thu Nov 26 16:17:01 2009
New Revision: 884622

URL: http://svn.apache.org/viewvc?rev=884622&view=rev
Log:
SLING-1101 - sling_bootstrap.txt: run-once command file for the BootstrapInstaller

Added:
    sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/
    sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/BootstrapCommandFile.java
  (with props)
    sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/Command.java
  (with props)
    sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/UninstallBundleCommand.java
  (with props)
    sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/
    sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/BootstrapCommandFileTest.java
  (with props)
    sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/UninstallBundleCommandTest.java
  (with props)
Modified:
    sling/trunk/launchpad/base/pom.xml
    sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/BootstrapInstaller.java

Modified: sling/trunk/launchpad/base/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/pom.xml?rev=884622&r1=884621&r2=884622&view=diff
==============================================================================
--- sling/trunk/launchpad/base/pom.xml (original)
+++ sling/trunk/launchpad/base/pom.xml Thu Nov 26 16:17:01 2009
@@ -190,6 +190,11 @@
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.jmock</groupId>
+            <artifactId>jmock-junit4</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
 </project>

Modified: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/BootstrapInstaller.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/BootstrapInstaller.java?rev=884622&r1=884621&r2=884622&view=diff
==============================================================================
--- sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/BootstrapInstaller.java
(original)
+++ sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/BootstrapInstaller.java
Thu Nov 26 16:17:01 2009
@@ -37,6 +37,7 @@
 import java.util.jar.Manifest;
 
 import org.apache.felix.framework.Logger;
+import org.apache.sling.launchpad.base.impl.bootstrapcommands.BootstrapCommandFile;
 import org.apache.sling.launchpad.base.shared.SharedConstants;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleActivator;
@@ -127,6 +128,11 @@
     private static final String DATA_FILE = "bootstrapinstaller.ser";
 
     /**
+     * The name of the bootstrap commands file
+     */
+    private static final String BOOTSTRAP_CMD_FILENAME = "sling_bootstrap.txt";
+
+    /**
      * The {@link Logger} use for logging messages during installation and
      * startup.
      */
@@ -193,6 +199,10 @@
         String slingHome = context.getProperty(SharedConstants.SLING_HOME);
         File slingStartupDir = getSlingStartupDir(slingHome);
 
+        // execute bootstrap commands, if needed
+        BootstrapCommandFile cmd = new BootstrapCommandFile(logger, new File(slingHome, BOOTSTRAP_CMD_FILENAME));
+        cmd.execute(context);
+
         if (!isAlreadyInstalled(context, slingStartupDir)) {
             // only run the deployment package stuff and war/jar copies when this war/jar
is new/changed
 
@@ -243,7 +253,7 @@
 
                 // done with copying at this point
             }
-
+            
             // get the set of all existing (installed) bundles by symbolic name
             Bundle[] bundles = context.getBundles();
             Map<String, Bundle> bySymbolicName = new HashMap<String, Bundle>();

Added: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/BootstrapCommandFile.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/BootstrapCommandFile.java?rev=884622&view=auto
==============================================================================
--- sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/BootstrapCommandFile.java
(added)
+++ sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/BootstrapCommandFile.java
Thu Nov 26 16:17:01 2009
@@ -0,0 +1,185 @@
+/*
+ * 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.launchpad.base.impl.bootstrapcommands;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.felix.framework.Logger;
+import org.osgi.framework.BundleContext;
+
+public class BootstrapCommandFile {
+    /** Name of file used to store our execution timestamp */
+    public static final String DATA_FILENAME = BootstrapCommandFile.class.getSimpleName()
+ "_timestamp.txt";
+    
+    /** Prefix for comments in command files */
+    public static final String COMMENT_PREFIX = "#";
+    
+    private final File commandFile;
+    private final Logger logger;
+    
+    private static final List<Command> commandPrototypes = new ArrayList<Command>();
+    static {
+        commandPrototypes.add(new UninstallBundleCommand());
+    }
+    
+    /** Will load our commands from specified file, if found */
+    public BootstrapCommandFile(Logger logger, File cmdFile) {
+        this.logger = logger;
+        this.commandFile = cmdFile;
+    }
+    
+    /** True if we have a command file that needs to be executed, based on its
+     *  file timestamp and stored timstamp
+     */
+    boolean anythingToExecute(BundleContext ctx) {
+        boolean result = false;
+        if(commandFile != null && commandFile.exists() && commandFile.canRead())
{
+            final long cmdTs = commandFile.lastModified();
+            long lastExecution = 0;
+            try {
+                lastExecution = loadTimestamp(ctx);
+            } catch(IOException ioe) {
+                logger.log(Logger.LOG_INFO, "IOException reading timestamp", ioe);
+            }
+            if(cmdTs > lastExecution) {
+                logger.log(Logger.LOG_INFO, 
+                        "Command file timestamp > stored timestamp, need to execute commands
(" 
+                        + commandFile.getAbsolutePath() + ")");
+                result = true;
+            }
+        }
+        if(!result) {
+            logger.log(Logger.LOG_INFO, 
+                    "Command file absent or older than last execution timestamp, nothing
to execute (" 
+                    + commandFile.getAbsolutePath() + ")");
+        }
+        return result;
+    }
+    
+    /** Execute commands if needed, and store execution timestamp 
+     *  @return number of commands executed */
+    public int execute(BundleContext ctx) throws IOException {
+        int count = 0;
+        if(anythingToExecute(ctx)) {
+            InputStream is = null;
+            try {
+                is = new FileInputStream(commandFile);
+                final List<Command> cmds = parse(is);
+                for(Command cmd : cmds) {
+                    try {
+                        logger.log(Logger.LOG_DEBUG, "Executing command: " + cmd);
+                        cmd.execute(logger, ctx);
+                        count++;
+                    } catch(Exception e) {
+                        logger.log(Logger.LOG_WARNING, "Exception in command execution ("
+ cmd + ") :" + e);
+                    }
+                }
+            } finally {
+                if(is != null) {
+                    try {
+                        is.close();
+                    } catch(IOException ignore) {
+                        // ignore
+                    }
+                }
+            }
+            
+            try {
+                storeTimestamp(ctx);
+            } catch(IOException ioe) {
+                logger.log(Logger.LOG_WARNING, "IOException while storing timestamp", ioe);
+            }
+        }
+        return count;
+    }
+    
+    /** Parse commands from supplied input stream.
+     *  Does not close the stream */
+    List<Command> parse(InputStream is) throws IOException {
+        final List<Command> result = new ArrayList<Command>();
+        final BufferedReader r = new BufferedReader(new InputStreamReader(is));
+        String line = null;
+        while( (line = r.readLine()) != null) {
+            line = line.trim();
+            if(line.length() > 0 && !line.startsWith(COMMENT_PREFIX)) {
+                Command toAdd = null;
+                for(Command proto : commandPrototypes) {
+                    toAdd = proto.parse(line);
+                    if(toAdd != null) {
+                        break;
+                    }
+                }
+                if(toAdd == null) {
+                    throw new Command.ParseException("Invalid command '" + line + "'");
+                } else {
+                    result.add(toAdd);
+                }
+            }
+        }
+        return result;
+    }
+
+    /** Return the data file to use for our timestamp */
+    private File getTimestampFile(BundleContext ctx) {
+        return ctx.getDataFile(DATA_FILENAME);
+    }
+    
+    /** Return our stored timestamp */
+    private long loadTimestamp(BundleContext ctx) throws IOException {
+        long result = 0;
+        final File f = getTimestampFile(ctx);
+        if(f.exists()) {
+            FileInputStream fis = null;
+            try {
+                fis = new FileInputStream(f);
+                byte[] bytes = new byte[20];
+                int len = fis.read(bytes);
+                if(len > 0) {
+                    result = Long.parseLong(new String(bytes, 0, len));
+                }
+            } finally {
+                if(fis != null) {
+                    fis.close();
+                }
+            }
+        }
+        return result;
+    }
+    
+    private void storeTimestamp(BundleContext ctx) throws IOException {
+        final File f = getTimestampFile(ctx);
+        FileOutputStream fos = null;
+        try {
+            fos = new FileOutputStream(f);
+            fos.write(String.valueOf(System.currentTimeMillis()).getBytes());
+        } finally {
+            if(fos != null) {
+                fos.close();
+            }
+        }
+    }
+}
\ No newline at end of file

Propchange: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/BootstrapCommandFile.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/BootstrapCommandFile.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/Command.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/Command.java?rev=884622&view=auto
==============================================================================
--- sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/Command.java
(added)
+++ sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/Command.java
Thu Nov 26 16:17:01 2009
@@ -0,0 +1,42 @@
+/*
+ * 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.launchpad.base.impl.bootstrapcommands;
+
+import java.io.IOException;
+
+import org.apache.felix.framework.Logger;
+import org.osgi.framework.BundleContext;
+
+interface Command {
+    @SuppressWarnings("serial")
+    static class ParseException extends IOException {
+        ParseException(String reason) {
+            super(reason);
+        }
+    };
+
+    /** Try to parse given command line
+     * @return null if we don't know the specified command
+     * @throws ParseException if we know the command but syntax is wrong
+     */
+    Command parse(String commandLine) throws ParseException;
+    
+    /** Execute this command */
+    void execute(Logger logger, BundleContext ctx) throws Exception;
+}

Propchange: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/Command.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/Command.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/UninstallBundleCommand.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/UninstallBundleCommand.java?rev=884622&view=auto
==============================================================================
--- sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/UninstallBundleCommand.java
(added)
+++ sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/UninstallBundleCommand.java
Thu Nov 26 16:17:01 2009
@@ -0,0 +1,84 @@
+/*
+ * 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.launchpad.base.impl.bootstrapcommands;
+
+import org.apache.felix.framework.Logger;
+import org.apache.felix.framework.util.VersionRange;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+/** A Command that uninstalls a bundle, see 
+ *  {@link UninstallBundleCommandTest} for examples
+ */
+class UninstallBundleCommand implements Command {
+    
+    public static String CMD_PREFIX = "uninstall ";
+    private final String bundleSymbolicName;
+    private final VersionRange versionRange;
+
+    /** Used to create a prototype object, for parsing */
+    UninstallBundleCommand() {
+        bundleSymbolicName = null;
+        versionRange = null;
+    }
+    
+    /** Used to create an actual command */
+    private UninstallBundleCommand(String bundleSymbolicName, String versionRangeStr) {
+        this.bundleSymbolicName = bundleSymbolicName;
+        
+        // If versionRangeStr is not a range, make it strict
+        if(!versionRangeStr.contains(",")) {
+            versionRangeStr = "[" + versionRangeStr + "," + versionRangeStr + "]";
+        }
+        this.versionRange = VersionRange.parse(versionRangeStr);
+    }
+    
+    public void execute(Logger logger, BundleContext ctx) throws Exception {
+        // Uninstall all instances of our bundle within our version range
+        for(Bundle b : ctx.getBundles()) {
+            if(b.getSymbolicName().equals(bundleSymbolicName)) {
+                if(versionRange.isInRange(b.getVersion())) {
+                    logger.log(Logger.LOG_INFO, 
+                            this + ": uninstalling bundle version " + b.getVersion());
+                    b.uninstall();
+                } else {
+                    logger.log(Logger.LOG_INFO, 
+                            this + ": bundle version (" + b.getVersion()+ " not in range,
ignored");
+                }
+            }
+        }
+    }
+
+    public Command parse(String commandLine) throws ParseException {
+        if(commandLine.startsWith(CMD_PREFIX)) {
+            final String [] s = commandLine.split(" ");
+            if(s.length == 3) {
+                return new UninstallBundleCommand(s[1].trim(), s[2].trim());
+            } else {
+                throw new Command.ParseException("Syntax error: '" + commandLine + "'");
+            }
+        }
+        return null;
+    }
+    
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + " " + bundleSymbolicName + " " + versionRange;
+    }
+}
\ No newline at end of file

Propchange: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/UninstallBundleCommand.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/UninstallBundleCommand.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/BootstrapCommandFileTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/BootstrapCommandFileTest.java?rev=884622&view=auto
==============================================================================
--- sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/BootstrapCommandFileTest.java
(added)
+++ sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/BootstrapCommandFileTest.java
Thu Nov 26 16:17:01 2009
@@ -0,0 +1,161 @@
+/*
+ * 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.launchpad.base.impl.bootstrapcommands;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.List;
+
+import org.apache.felix.framework.Logger;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Version;
+
+public class BootstrapCommandFileTest {
+    private final Logger logger = new Logger();
+    private final File nonExistentFile = new File("/nonexistent." + System.currentTimeMillis());
+    static final Mockery mockery = new Mockery();
+    private File dataFile;
+    private File cmdFile;
+    private BundleContext bundleContext;
+    
+    @Before
+    public void setUp() throws IOException,BundleException {
+        dataFile = File.createTempFile(getClass().getSimpleName(), "txt");
+        
+        final Bundle b1 = mockery.mock(Bundle.class);
+        mockery.checking(new Expectations() {{
+            allowing(b1).getSymbolicName();
+            will(returnValue("somebundle"));
+            allowing(b1).getVersion();
+            will(returnValue(new Version("1.0.0")));
+            allowing(b1).uninstall();
+        }});
+        final Bundle [] bundles = { b1 };
+        
+            
+        bundleContext = mockery.mock(BundleContext.class);
+        mockery.checking(new Expectations() {{
+            allowing(bundleContext).getDataFile(with(any(String.class)));
+            will(returnValue(dataFile));
+            allowing(bundleContext).getBundles();
+            will(returnValue(bundles));
+        }});
+        
+        cmdFile = File.createTempFile(getClass().getSimpleName(), "cmd");
+        final PrintWriter w = new PrintWriter(new FileWriter(cmdFile));
+        w.println("# Test command file, this is a comment");
+        w.println("uninstall somebundle 1.0");
+        w.println("#another comment");
+        w.println("uninstall otherbundle 1.0");
+        w.flush();
+        w.close();
+    }
+    
+    @After
+    public void tearDown() throws IOException {
+        dataFile.delete();
+        cmdFile.delete();
+    }
+
+    @Test
+    public void testNoFileNoExecution() {
+        final BootstrapCommandFile bcf = new BootstrapCommandFile(logger, nonExistentFile);
+        assertFalse("Expecting anythingToExecute false for non-existing file", 
+                bcf.anythingToExecute(bundleContext));
+    }
+    
+    @Test
+    public void testExecuteOnceOnly() throws IOException {
+        final BootstrapCommandFile bcf = new BootstrapCommandFile(logger, cmdFile);
+        assertTrue("Expecting anythingToExecute true for existing file", 
+                bcf.anythingToExecute(bundleContext));
+        assertEquals("Expecting two commands to be executed", 2, bcf.execute(bundleContext));
+        assertFalse("Expecting anythingToExecute false after execution", 
+                bcf.anythingToExecute(bundleContext));
+    }
+    
+    @Test
+    public void testParsing() throws IOException {
+        final BootstrapCommandFile bcf = new BootstrapCommandFile(logger, cmdFile);
+        final String cmdString = 
+            "# a comment\n"
+            + "uninstall symbolicname1 1.0\n"
+            + "\n"
+            + "# another comment\n"
+            + "uninstall symbolicname1 1.0\n"
+            ;
+        final List<Command> c = bcf.parse(new ByteArrayInputStream(cmdString.getBytes()));
+        assertEquals("Expecting two commands after parsing", 2, c.size());
+        int index = 0;
+        for(Command cmd : c) {
+            assertTrue("Expecting an UninstallBundleCommand at index " + index, 
+                    cmd instanceof UninstallBundleCommand);
+            index++;
+        }
+    }
+    
+    @Test
+    public void testSyntaxError() throws IOException {
+        final BootstrapCommandFile bcf = new BootstrapCommandFile(logger, cmdFile);
+        final String cmdString = 
+            "# a comment\n"
+            + "uninstall only_one_field\n"
+            + "\n"
+            + "# another comment\n"
+            + "uninstall symbolicname1 1.0\n"
+            ;
+        try {
+            bcf.parse(new ByteArrayInputStream(cmdString.getBytes()));
+            fail("Expecting IOException for syntax error");
+        } catch(IOException ioe) {
+            assertTrue("Exception message (" + ioe.getMessage() + ") should contain command
line", 
+                    ioe.getMessage().contains("only_one_field"));
+        }
+    }
+    
+    @Test
+    public void testInvalidCommand() throws IOException {
+        final BootstrapCommandFile bcf = new BootstrapCommandFile(logger, cmdFile);
+        final String cmdString = 
+            "foo\n"
+            ;
+        try {
+            bcf.parse(new ByteArrayInputStream(cmdString.getBytes()));
+            fail("Expecting IOException for invalid command");
+        } catch(IOException ioe) {
+            assertTrue("Exception message (" + ioe.getMessage() + ") should contain command
line", 
+                    ioe.getMessage().contains("foo"));
+        }
+    }
+}
\ No newline at end of file

Propchange: sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/BootstrapCommandFileTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/BootstrapCommandFileTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/UninstallBundleCommandTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/UninstallBundleCommandTest.java?rev=884622&view=auto
==============================================================================
--- sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/UninstallBundleCommandTest.java
(added)
+++ sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/UninstallBundleCommandTest.java
Thu Nov 26 16:17:01 2009
@@ -0,0 +1,94 @@
+/*
+ * 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.launchpad.base.impl.bootstrapcommands;
+
+import static org.junit.Assert.assertNotNull;
+
+import org.apache.felix.framework.Logger;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Version;
+
+/** Test the UninstallBundleCommand */
+public class UninstallBundleCommandTest {
+    static final Mockery mockery = new Mockery();
+    private BundleContext bundleContext;
+    private final Logger logger = new Logger();
+
+    @Before
+    public void setUp() throws Exception {
+        final Bundle [] b = new Bundle[3];
+        for(int i=0; i < b.length; i++) {
+            b[i] = mockery.mock(Bundle.class);
+        }
+
+        // b0 is in version range, will be uninstalled
+        mockery.checking(new Expectations() {{
+            allowing(b[0]).getSymbolicName();
+            will(returnValue("testbundle"));
+            allowing(b[0]).getVersion();
+            will(returnValue(new Version("1.0.0")));
+            exactly(1).of(b[0]).uninstall();
+        }});
+        
+        // b1 is not in version range, not uninstalled
+        mockery.checking(new Expectations() {{
+            allowing(b[1]).getSymbolicName();
+            will(returnValue("testbundle"));
+            allowing(b[1]).getVersion();
+            will(returnValue(new Version("2.0.0")));
+        }});
+        
+        // b2 has different symbolic name, not uninstalled
+        mockery.checking(new Expectations() {{
+            allowing(b[2]).getSymbolicName();
+            will(returnValue("otherbundle"));
+            allowing(b[2]).getVersion();
+            will(returnValue(new Version("1.0.0")));
+        }});
+        
+        bundleContext = mockery.mock(BundleContext.class);
+        mockery.checking(new Expectations() {{
+            allowing(bundleContext).getBundles();
+            will(returnValue(b));
+        }});
+    }
+    
+    @Test
+    public void testExplicitVersion() throws Exception {
+        final UninstallBundleCommand proto = new UninstallBundleCommand();
+        // v=1.0.0 should remove 1.0.0 only, not 2.0.0
+        final Command cmd = proto.parse("uninstall testbundle 1.0.0");
+        assertNotNull("Expecting parsing to succeed", cmd);
+        cmd.execute(logger, bundleContext);
+    }
+    
+    @Test
+    public void testVersionRange() throws Exception {
+        final UninstallBundleCommand proto = new UninstallBundleCommand();
+        final String from1Includedto2NotIncluded = "[1,2)";
+        final Command cmd = proto.parse("uninstall testbundle " + from1Includedto2NotIncluded);
+        assertNotNull("Expecting parsing to succeed", cmd);
+        cmd.execute(logger, bundleContext);
+    }
+}
\ No newline at end of file

Propchange: sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/UninstallBundleCommandTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/UninstallBundleCommandTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL



Mime
View raw message