Author: marrs
Date: Wed Jul 11 08:16:04 2012
New Revision: 1360054
URL: http://svn.apache.org/viewvc?rev=1360054&view=rev
Log:
Added the deployment itest.
Added:
ace/sandbox/marrs/org.apache.ace.deployment.itest/
ace/sandbox/marrs/org.apache.ace.deployment.itest/.classpath
ace/sandbox/marrs/org.apache.ace.deployment.itest/.project
ace/sandbox/marrs/org.apache.ace.deployment.itest/.settings/
ace/sandbox/marrs/org.apache.ace.deployment.itest/.settings/org.eclipse.jdt.core.prefs
ace/sandbox/marrs/org.apache.ace.deployment.itest/bnd.bnd
ace/sandbox/marrs/org.apache.ace.deployment.itest/build.xml
ace/sandbox/marrs/org.apache.ace.deployment.itest/src/
ace/sandbox/marrs/org.apache.ace.deployment.itest/src/org/
ace/sandbox/marrs/org.apache.ace.deployment.itest/src/org/apache/
ace/sandbox/marrs/org.apache.ace.deployment.itest/src/org/apache/ace/
ace/sandbox/marrs/org.apache.ace.deployment.itest/src/org/apache/ace/it/
ace/sandbox/marrs/org.apache.ace.deployment.itest/src/org/apache/ace/it/deployment/
ace/sandbox/marrs/org.apache.ace.deployment.itest/src/org/apache/ace/it/deployment/DeploymentIntegrationTest.java
ace/sandbox/marrs/org.apache.ace.deployment.itest/test/
Added: ace/sandbox/marrs/org.apache.ace.deployment.itest/.classpath
URL:
http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.deployment.itest/.classpath?rev=1360054&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.deployment.itest/.classpath (added)
+++ ace/sandbox/marrs/org.apache.ace.deployment.itest/.classpath Wed Jul 11
08:16:04 2012
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" output="bin_test" path="test"/>
+ <classpathentry kind="con"
path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
Added: ace/sandbox/marrs/org.apache.ace.deployment.itest/.project
URL:
http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.deployment.itest/.project?rev=1360054&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.deployment.itest/.project (added)
+++ ace/sandbox/marrs/org.apache.ace.deployment.itest/.project Wed Jul 11
08:16:04 2012
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.apache.ace.deployment.itest</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>bndtools.core.bndbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>bndtools.core.bndnature</nature>
+ </natures>
+</projectDescription>
Added:
ace/sandbox/marrs/org.apache.ace.deployment.itest/.settings/org.eclipse.jdt.core.prefs
URL:
http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.deployment.itest/.settings/org.eclipse.jdt.core.prefs?rev=1360054&view=auto
==============================================================================
---
ace/sandbox/marrs/org.apache.ace.deployment.itest/.settings/org.eclipse.jdt.core.prefs
(added)
+++
ace/sandbox/marrs/org.apache.ace.deployment.itest/.settings/org.eclipse.jdt.core.prefs
Wed Jul 11 08:16:04 2012
@@ -0,0 +1,81 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.6
Added: ace/sandbox/marrs/org.apache.ace.deployment.itest/bnd.bnd
URL:
http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.deployment.itest/bnd.bnd?rev=1360054&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.deployment.itest/bnd.bnd (added)
+++ ace/sandbox/marrs/org.apache.ace.deployment.itest/bnd.bnd Wed Jul 11
08:16:04 2012
@@ -0,0 +1,50 @@
+Test-Cases: ${classes;CONCRETE;EXTENDS;org.apache.ace.it.IntegrationTestBase}
+-buildpath: junit.osgi,\
+ osgi.core,\
+ osgi.cmpn,\
+ org.apache.ace.util;version=latest,\
+ org.apache.felix.dependencymanager,\
+ org.apache.ace.itest;version=latest,\
+ org.apache.ace.log;version=latest,\
+ org.apache.ace.httplistener;version=latest,\
+ org.apache.ace.discovery.api;version=latest,\
+ org.apache.ace.discovery.property;version=latest,\
+ org.apache.ace.identification.api;version=latest,\
+ org.apache.ace.identification.property;version=latest,\
+ org.apache.ace.server.log.store;version=latest,\
+ javax.servlet,\
+ org.apache.ace.scheduler.api;version=latest,\
+ org.apache.ace.deployment.servlet;version=latest,\
+ org.apache.ace.deployment.provider.filebased;version=latest
+-runfw: org.apache.felix.framework;version='[4,5)'
+-runbundles:
org.apache.ace.itest;resolution=file:/Users/marcel/dev/ace-bndtools/org.apache.ace.itest/generated/org.apache.ace.itest.jar;version=latest,\
+
org.apache.felix.dependencymanager;resolution=file:/Users/marcel/dev/ace-bndtools/cnf/repo/org.apache.felix.dependencymanager/org.apache.felix.dependencymanager-3.1.0.jar;version='[3.1.0,3.1.1)',\
+
org.apache.felix.configadmin;resolution=http://bundles.bndtools.org.s3.amazonaws.com/org.apache.felix.configadmin/org.apache.felix.configadmin-1.2.8.jar;version='[1.2.8,1.2.9)',\
+
org.apache.ace.httplistener;resolution=file:/Users/marcel/dev/ace-bndtools/org.apache.ace.httplistener/generated/org.apache.ace.httplistener.jar;version=latest,\
+
osgi.cmpn;resolution=http://bundles.bndtools.org.s3.amazonaws.com/osgi.cmpn/osgi.cmpn-4.2.1.jar;version='[4.2.1,4.2.2)',\
+
org.apache.felix.eventadmin;resolution=file:/Users/marcel/dev/ace-bndtools/cnf/repo/org.apache.felix.eventadmin/org.apache.felix.eventadmin-1.2.14.jar;version='[1.2.14,1.2.15)',\
+ org.apache.felix.http.jetty,\
+ org.apache.felix.shell,\
+ org.apache.felix.shell.tui,\
+ org.apache.felix.dependencymanager.shell,\
+ org.apache.felix.deploymentadmin,\
+ org.apache.ace.authentication.api;version=latest,\
+ org.apache.ace.connectionfactory;version=latest,\
+ org.apache.ace.scheduler;version=latest,\
+ org.apache.ace.scheduler.api;version=latest,\
+ org.apache.ace.deployment.provider.api;version=latest,\
+ org.apache.ace.deployment.provider.filebased;version=latest,\
+ org.apache.ace.discovery.api;version=latest,\
+ org.apache.ace.discovery.property;version=latest,\
+ org.apache.ace.identification.api;version=latest,\
+ org.apache.ace.identification.property;version=latest,\
+ org.apache.ace.deployment.api;version=latest,\
+ org.apache.ace.deployment.deploymentadmin;version=latest,\
+ org.apache.ace.deployment.servlet;version=latest,\
+ org.apache.ace.deployment.task;version=latest,\
+ org.apache.ace.deployment.task.base;version=latest,\
+ org.apache.ace.deployment.streamgenerator;version=latest,\
+ org.apache.ace.deployment.provider.base;version=latest,\
+ org.apache.ace.util;version=latest
+Private-Package: org.apache.ace.it.deployment
+-runvm: -Dorg.osgi.service.http.port=9000 -ea
\ No newline at end of file
Added: ace/sandbox/marrs/org.apache.ace.deployment.itest/build.xml
URL:
http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.deployment.itest/build.xml?rev=1360054&view=auto
==============================================================================
--- ace/sandbox/marrs/org.apache.ace.deployment.itest/build.xml (added)
+++ ace/sandbox/marrs/org.apache.ace.deployment.itest/build.xml Wed Jul 11
08:16:04 2012
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="project" default="build">
+ <import file="../cnf/build.xml"/>
+</project>
Added:
ace/sandbox/marrs/org.apache.ace.deployment.itest/src/org/apache/ace/it/deployment/DeploymentIntegrationTest.java
URL:
http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.deployment.itest/src/org/apache/ace/it/deployment/DeploymentIntegrationTest.java?rev=1360054&view=auto
==============================================================================
---
ace/sandbox/marrs/org.apache.ace.deployment.itest/src/org/apache/ace/it/deployment/DeploymentIntegrationTest.java
(added)
+++
ace/sandbox/marrs/org.apache.ace.deployment.itest/src/org/apache/ace/it/deployment/DeploymentIntegrationTest.java
Wed Jul 11 08:16:04 2012
@@ -0,0 +1,383 @@
+/*
+ * 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.ace.it.deployment;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.ace.deployment.provider.ArtifactData;
+import org.apache.ace.deployment.provider.impl.ArtifactDataImpl;
+import org.apache.ace.discovery.property.constants.DiscoveryConstants;
+import org.apache.ace.http.listener.constants.HttpConstants;
+import
org.apache.ace.identification.property.constants.IdentificationConstants;
+import org.apache.ace.it.IntegrationTestBase;
+import org.apache.ace.scheduler.constants.SchedulerConstants;
+import org.apache.ace.test.constants.TestConstants;
+import org.apache.ace.test.utils.deployment.BundleStreamGenerator;
+import org.apache.felix.dm.Component;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.deploymentadmin.DeploymentAdmin;
+import org.osgi.service.deploymentadmin.DeploymentException;
+import org.osgi.service.deploymentadmin.DeploymentPackage;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventConstants;
+import org.osgi.service.event.EventHandler;
+import org.osgi.service.http.HttpService;
+
+public class DeploymentIntegrationTest extends IntegrationTestBase implements
BundleListener, EventHandler {
+
+// @org.ops4j.pax.exam.junit.Configuration
+// public Option[] configuration() {
+// return options(
+// systemProperty("org.osgi.service.http.port").value("" +
TestConstants.PORT),
+// new VMOption("-ea"),
+// junitBundles(),
+// provision(
+// wrappedBundle(maven("org.apache.ace",
"org.apache.ace.deployment.provider.base")), // necessary since we use an impl
class here...
+// Ace.util(),
+// Osgi.compendium(),
+// Felix.dependencyManager(),
+// jetty(),
+// Felix.configAdmin(),
+// Felix.eventAdmin(),
+// Felix.deploymentAdmin(),
+// Ace.authenticationApi(),
+// Ace.connectionFactory(),
+// Ace.scheduler(),
+// Ace.deploymentProviderApi(),
+// Ace.deploymentProviderFilebased(),
+// Ace.discoveryApi(),
+// Ace.discoveryProperty(),
+// Ace.identificationApi(),
+// Ace.identificationProperty(),
+// Ace.httplistener(),
+// Ace.deploymentApi(),
+// Ace.deploymentDeploymentAdmin(),
+// Ace.deploymentServlet(),
+// Ace.deploymentTaskBase(),
+// Ace.deploymentTask(),
+// Ace.deploymentStreamgenerator()
+// )
+// );
+// }
+
+ protected void before() throws IOException {
+ m_tempDir = File.createTempFile("test", "");
+ m_tempDir.delete();
+ m_tempDir.mkdir();
+ }
+
+ protected Component[] getDependencies() {
+ return new Component[] {
+ createComponent()
+ .setImplementation(this)
+
.add(createServiceDependency().setService(HttpService.class).setRequired(true))
+
.add(createServiceDependency().setService(ConfigurationAdmin.class).setRequired(true))
+
.add(createServiceDependency().setService(DeploymentAdmin.class).setRequired(true)),
+ };
+ }
+
+ public static final String HOST = "localhost";
+ public static final String GWID = "gw-id";
+ public static final String POLL_INTERVAL = "1000";
+ private volatile ConfigurationAdmin m_config;
+ private volatile DeploymentAdmin m_deployment;
+ private volatile File m_tempDir;
+ private final Semaphore m_semaphore = new Semaphore(0);
+ Map<Integer, List<Bundle>> m_events = new HashMap<Integer, List<Bundle>>();
+ private ServiceRegistration m_deploymentAdminProxyRegistration;
+
+ @Override
+ protected void after() throws Exception {
+ deleteDirOrFile(m_tempDir);
+ }
+
+ private void deleteDirOrFile(File root) {
+ if (root.isDirectory()) {
+ for (File file : root.listFiles()) {
+ deleteDirOrFile(file);
+ }
+ }
+ root.delete();
+ }
+
+ public void testDeployVersionSeries() throws Exception {
+ Bundle[] start = m_bundleContext.getBundles();
+
+ // Test deploy initial version 1.0.0 with 3 bundles in version 1.0.0
+ String[] versions = new String[] { "bundle1", "bundle2", "bundle3" };
+ generateBundles(createVersion("1.0.0"), versions, 0, versions.length,
"1.0.0");
+ executeTest();
+ // start + versions bundles may be present
+ assertState(start, m_bundleContext.getBundles(), versions);
+ assert m_events.get(BundleEvent.STARTED).size() == versions.length :
"Received unexpected amount of starting events.";
+ assert m_events.get(BundleEvent.STOPPED) == null : "Received
unexpected amount of stopping events";
+ m_events.clear();
+
+ // Test correct presence of deployment packages in deployment admin
+ assert m_deployment.listDeploymentPackages().length == 1 : "Deployment
admin reports unexpected number of deployment packages";
+ assert m_deployment.getDeploymentPackage(GWID) != null : "Deployment
admin did not return the expected deployment package";
+ Bundle[] bundles = m_bundleContext.getBundles();
+ Bundle bundle = null;
+ for (int i = 0; i < bundles.length; i++) {
+ if("bundle1".equals(bundles[i].getSymbolicName())) {
+ bundle = bundles[i];
+ break;
+ }
+ }
+ assert m_deployment.getDeploymentPackage(bundle) != null : "Deployment
admin did not return the expected deployment package";
+
+ // Test deploy a version 1.1.0 on top of the previous 1.0.0 with one
new bundle and one updated to version 1.1.0 (i.e., two fix-package bundles)
+ versions = new String[] { "bundle1", "bundle2", "bundle3", "bundle4" };
+ File version = createVersion("1.1.0");
+ generateBundle(new File(version, "0.jar"), versions[0], "1.1.0");
+ generateBundles(version, versions, 1, versions.length, "1.0.0");
+ executeTest();
+ // start + versions bundles may be present
+ assertState(start, m_bundleContext.getBundles(), versions);
+ assert m_events.get(BundleEvent.UPDATED).size() == 1 : "Received
unexpected amount of updated events.";
+ assert
m_events.get(BundleEvent.UPDATED).get(0).getSymbolicName().equals(versions[0])
: "Received unexpected update event.";
+ assert m_events.get(BundleEvent.STOPPED).size() == versions.length - 1
: "Received unexpected amount of stopped events.";
+ assert m_events.get(BundleEvent.STARTED).size() == versions.length :
"Received unexpected amount of started events: expected " + versions.length +
", received " + m_events.get(BundleEvent.STARTED).size() + ".";
+ m_events.clear();
+
+ // Test to deploy an empty version 2.0.0, but break the stream which
should cancel the deployment
+ createVersion("2.0.0");
+ executeTestWithFailingStream();
+ m_events.clear();
+
+ // Test to deploy an empty version 2.0.0 which should remove all the
previously installed bundles
+ executeTest();
+
+ // only start bundles may be present
+ assertState(start, m_bundleContext.getBundles(), new String[0]);
+ assert m_events.get(BundleEvent.INSTALLED) == null : "Received
unexpected amount of installed events.";
+ assert m_events.get(BundleEvent.STARTED) == null : "Received
unexpected amount of starting events.";
+ assert m_events.get(BundleEvent.UNINSTALLED).size() == versions.length
: "Received unexpected amount of uninstalled events: " +
m_events.get(BundleEvent.UNINSTALLED).size() + " instead of " + versions.length;
+ assert m_events.get(BundleEvent.STOPPED).size() == versions.length :
"Received unexpected amount of stopped events: " +
m_events.get(BundleEvent.STOPPED).size() + " instead of " + versions.length;
+ m_events.clear();
+
+ }
+
+ public void bundleChanged(BundleEvent event) {
+ synchronized (m_events) {
+ if (!m_events.containsKey(Integer.valueOf(event.getType()))) {
+ m_events.put(Integer.valueOf(event.getType()), new
ArrayList<Bundle>());
+ }
+
m_events.get(Integer.valueOf(event.getType())).add(event.getBundle());
+ }
+ }
+
+ public void handleEvent(Event event) {
+ System.out.println("Event: " + event);
+ m_semaphore.release();
+ }
+
+ private void generateBundles(File dir, String[] versions, int off, int
len, String version) throws Exception {
+ for (int i = off; i < len; i++) {
+ generateBundle(new File(dir, i + ".jar"), versions[i], version);
+ }
+ }
+
+ private void assertState(Bundle[] start, Bundle[] current, String[]
versions) {
+ assert (start.length + versions.length) == current.length : "System
has " + (((start.length + versions.length) < current.length) ? "more" : "less")
+ " bundes then expected: expected " + (start.length + versions.length) + ",
found " + current.length;
+ for (int i = 0; i < start.length; i++) {
+ assert
current[i].getSymbolicName().equals(start[i].getSymbolicName()) : "Bundle names
do not match: " + current[i].getSymbolicName() + " v.s. " + start[i];
+ }
+ List<String> index = Arrays.asList(versions);
+ for (int i = start.length; i < current.length; i++) {
+ assert index.contains(current[i].getSymbolicName()) : "Bundle
names do not match: " + current[i].getSymbolicName();
+ }
+ }
+
+ private File createVersion(String version) {
+ File versionFile = new File(new File(m_tempDir, GWID), version);
+ versionFile.mkdirs();
+ return versionFile;
+ }
+
+ @SuppressWarnings("serial")
+ private void executeTest() throws IOException, InterruptedException {
+ m_bundleContext.addBundleListener(this);
+ ServiceRegistration reg =
m_bundleContext.registerService(EventHandler.class.getName(), this, new
Properties() {
+ {
+ put(EventConstants.EVENT_TOPIC,
"org/osgi/service/deployment/COMPLETE");
+ put(EventConstants.EVENT_FILTER, "(successful=true)");
+ }
+ });
+ configureTarget();
+ configureServer();
+ assert m_semaphore.tryAcquire(8, TimeUnit.SECONDS) : "Timed out while
waiting for deployment to complete.";
+ unconfigureServer();
+ unconfigureTarget();
+ reg.unregister();
+ m_bundleContext.removeBundleListener(this);
+ }
+
+ private void executeTestWithFailingStream() throws IOException,
InterruptedException {
+ m_bundleContext.addBundleListener(this);
+ registerDeploymentAdminProxy(new FailingDeploymentAdmin(m_deployment,
50));
+ configureTarget();
+ configureServer();
+ assert m_semaphore.tryAcquire(8, TimeUnit.SECONDS) : "Timed out while
waiting for deployment to abort.";
+ unconfigureServer();
+ unconfigureTarget();
+ unregisterDeploymentAdminProxy();
+ m_bundleContext.removeBundleListener(this);
+ }
+
+ /**
+ * Input stream wrapper that creates an input stream that breaks after N
bytes. When it
+ * breaks, it will throw an IO exception and sends a notification to the
semaphore that
+ * allows the overall test to continue.
+ */
+ private class BrokenInputStream extends InputStream {
+ private final InputStream m_normalStream;
+ private int m_bytesUntilBreakdown;
+ private boolean m_isBroken;
+
+ public BrokenInputStream(InputStream normalStream, int
bytesUntilBreakdown) {
+ m_normalStream = normalStream;
+ m_bytesUntilBreakdown = bytesUntilBreakdown;
+ }
+
+ private synchronized void breakStream() throws IOException {
+ if (!m_isBroken) {
+ m_isBroken = true;
+
+ // release the semaphore to continue the test
+ m_semaphore.release();
+ }
+ throw new IOException("Stream broken.");
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (m_bytesUntilBreakdown-- < 1) {
+ breakStream();
+ }
+ return m_normalStream.read();
+ }
+
+ @Override
+ public void close() throws IOException {
+ m_normalStream.close();
+ breakStream();
+ }
+
+ }
+
+ /**
+ * Wrapper around the deployment admin that will fail once, after N bytes.
+ */
+ private class FailingDeploymentAdmin implements DeploymentAdmin {
+ private final DeploymentAdmin m_deploymentAdmin;
+ private boolean m_wasBroken;
+ private final int m_failAfterBytes;
+
+ public FailingDeploymentAdmin(DeploymentAdmin deploymentAdmin, int
failAfterBytes) {
+ m_deploymentAdmin = deploymentAdmin;
+ m_failAfterBytes = failAfterBytes;
+ }
+
+ public boolean cancel() {
+ return m_deploymentAdmin.cancel();
+ }
+
+ public DeploymentPackage getDeploymentPackage(String symbName) {
+ return m_deploymentAdmin.getDeploymentPackage(symbName);
+ }
+
+ public DeploymentPackage getDeploymentPackage(Bundle bundle) {
+ return m_deploymentAdmin.getDeploymentPackage(bundle);
+ }
+
+ public DeploymentPackage installDeploymentPackage(InputStream in)
throws DeploymentException {
+ synchronized (this) {
+ if (!m_wasBroken) {
+ m_wasBroken = true;
+ in = new BrokenInputStream(in, m_failAfterBytes);
+ }
+ }
+ return m_deploymentAdmin.installDeploymentPackage(in);
+ }
+
+ public DeploymentPackage[] listDeploymentPackages() {
+ return m_deploymentAdmin.listDeploymentPackages();
+ }
+ }
+
+ private void configureTarget() throws IOException {
+ // configure discovery bundle
+ configure(DiscoveryConstants.DISCOVERY_PID,
DiscoveryConstants.DISCOVERY_URL_KEY, "http://" + HOST + ":" +
TestConstants.PORT);
+ // configure identification bundle
+ configure(IdentificationConstants.IDENTIFICATION_PID,
IdentificationConstants.IDENTIFICATION_TARGETID_KEY, GWID);
+ // configure scheduler
+ configure(SchedulerConstants.SCHEDULER_PID,
+ "org.apache.ace.target.auditlog.task.AuditLogSyncTask",
POLL_INTERVAL,
+ "org.apache.ace.deployment.task.DeploymentUpdateTask",
POLL_INTERVAL);
+ }
+
+ private void unconfigureTarget() throws IOException {
+ m_config.getConfiguration(DiscoveryConstants.DISCOVERY_PID,
null).delete();
+ m_config.getConfiguration(IdentificationConstants.IDENTIFICATION_PID,
null).delete();
+ m_config.getConfiguration(SchedulerConstants.SCHEDULER_PID,
null).delete();
+ }
+
+ private void unconfigureServer() throws IOException {
+ m_config.getConfiguration("org.apache.ace.deployment.servlet",
null).delete();
+
m_config.getConfiguration("org.apache.ace.deployment.provider.filebased",
null).delete();
+ }
+
+ private void configureServer() throws IOException {
+ // configure data bundle
+ configure(org.apache.ace.deployment.servlet.Activator.PID,
HttpConstants.ENDPOINT, "/deployment", "authentication.enabled", "false");
+ // configure file based backend
+ configure(org.apache.ace.deployment.provider.filebased.Activator.PID,
"BaseDirectoryName", m_tempDir.getAbsolutePath());
+ }
+
+ private ArtifactData generateBundle(File file, String symbolicName, String
version) throws Exception {
+ ArtifactData bundle = new ArtifactDataImpl(file.getName(),
symbolicName, version, file.toURI().toURL(), false);
+ BundleStreamGenerator.generateBundle(bundle);
+ return bundle;
+ }
+
+ private void registerDeploymentAdminProxy(DeploymentAdmin proxy) {
+ Properties props = new Properties();
+ props.put(org.osgi.framework.Constants.SERVICE_RANKING, 1);
+ m_deploymentAdminProxyRegistration =
m_bundleContext.registerService(DeploymentAdmin.class.getName(), proxy, props);
+ }
+
+ private void unregisterDeploymentAdminProxy() {
+ m_deploymentAdminProxyRegistration.unregister();
+ }
+}