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