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();
+    }
+}


Reply via email to