checking in integration test  runner for felix plugin

git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@434148 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/tools/maven2/maven-felix-plugin/src/main/java/org/apache/felix/tools/maven/felix/plugin/FelixContainer.java b/tools/maven2/maven-felix-plugin/src/main/java/org/apache/felix/tools/maven/felix/plugin/FelixContainer.java
new file mode 100644
index 0000000..71d0eca
--- /dev/null
+++ b/tools/maven2/maven-felix-plugin/src/main/java/org/apache/felix/tools/maven/felix/plugin/FelixContainer.java
@@ -0,0 +1,41 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.felix.tools.maven.felix.plugin;
+
+
+import org.apache.felix.framework.Felix;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+
+
+public class FelixContainer extends Felix
+{
+    public Bundle[] getBundles()
+    {
+        return super.getBundles();
+    }
+
+    public Bundle getBundle( String location )
+    {
+        return super.getBundle( location );
+    }
+    
+    public BundleActivator getBundleActivator( Bundle bundle )
+    {
+        return super.getBundleActivator( bundle );
+    }
+}
diff --git a/tools/maven2/maven-felix-plugin/src/main/java/org/apache/felix/tools/maven/felix/plugin/FelixITestMojo.java b/tools/maven2/maven-felix-plugin/src/main/java/org/apache/felix/tools/maven/felix/plugin/FelixITestMojo.java
new file mode 100644
index 0000000..8e6c7dc
--- /dev/null
+++ b/tools/maven2/maven-felix-plugin/src/main/java/org/apache/felix/tools/maven/felix/plugin/FelixITestMojo.java
@@ -0,0 +1,379 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.felix.tools.maven.felix.plugin;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.felix.framework.util.MutablePropertyResolver;
+import org.apache.felix.framework.util.MutablePropertyResolverImpl;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+
+import org.codehaus.plexus.util.FileUtils;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+
+
+/**
+ * 
+ * @goal test
+ * @phase integration-test
+ */
+public class FelixITestMojo extends AbstractMojo
+{
+    /**
+     * The name of the test bundle activator.
+     * 
+     * @parameter expression=”${run.felix.test.activator}”
+     * @required
+     * @description the fqcn of the test activator
+     */
+    private String felixTestActivator;
+    
+    /**
+     * The name of the felix cache profile.
+     * 
+     * @parameter expression=”${run.felix.cache.profile}” default-value="test"
+     * @description the felix.cache.profile property value
+     */
+    private String felixCacheProfile;
+    
+    /**
+     * The location of the felix bundle cache directory.
+     * 
+     * @parameter expression=”${run.felix.cache.dir}” default-value="${basedir}/target/.felix"
+     * @description the felix.cache.dir property value
+     */
+    private File felixCacheDir;
+    
+    /**
+     * The location of the test bundle.
+     * 
+     * @parameter expression="${run.felix.test.bundle}" 
+     *            default-value="${basedir}/target/${project.artifactId}-${project.version}.jar"
+     */
+    private File felixTestBundle;
+
+    /**
+     * @parameter default-value="${project}"
+     */
+    private MavenProject project;
+
+    /**
+     * @parameter
+     */
+    private List exclusions;
+    
+
+    public void execute() throws MojoExecutionException, MojoFailureException
+    {
+        // -------------------------------------------------------------------
+        // Build the properties we will stuff into the resolver
+        // -------------------------------------------------------------------
+
+        Properties props = new Properties();
+        props.put( "felix.cache.dir", felixCacheDir.getAbsolutePath() );
+        props.put( "felix.cache.profile", felixCacheProfile );
+        props.put( "felix.embedded.execution", "true" );
+        props.put( "org.osgi.framework.system.packages", 
+            "org.osgi.framework; version=1.3.0, " +
+            "org.osgi.service.packageadmin; version=1.2.0, " +
+            "org.osgi.service.startlevel; version=1.0.0, " +
+            "org.osgi.service.url; version=1.0.0, " +
+            "${jre-${java.specification.version}}" );
+        try
+        {
+            props.put( "felix.auto.start.1", getAutoStart() );
+        }
+        catch ( MalformedURLException e )
+        {
+            e.printStackTrace();
+        }
+        
+        // -------------------------------------------------------------------
+        // Start up Felix with resolver and shut it down
+        // -------------------------------------------------------------------
+
+        System.out.println();
+        System.out.println( "-------------------------------------------------------" );
+        System.out.println( "   F E L I X   I N T E G R A T I O N   T E S T I N G" );
+        System.out.println( "-------------------------------------------------------" );
+        System.out.println( "Running " + felixTestActivator );
+        
+        boolean keepRunning = true;
+        int count = 0;
+        List testRuns = new ArrayList();
+        long startTime = System.currentTimeMillis();
+        int errors = 0;
+        int failures = 0; 
+        while ( keepRunning )
+        {
+            FelixContainer felixContainer = new FelixContainer();
+            
+            try
+            {
+                Thread.sleep( 1000 );
+            }
+            catch ( InterruptedException e )
+            {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+
+            
+            TestRun testRun = new TestRun();
+            testRuns.add( testRun );
+            testRun.setStartTime( System.currentTimeMillis() );
+            
+            // ---------------------------------------------------------------
+            // Clean out the old cache directory if it exists
+            // ---------------------------------------------------------------
+            
+            if ( felixCacheDir.exists() )
+            {
+                try
+                {
+                    FileUtils.forceDelete( felixCacheDir );
+                }
+                catch ( IOException e )
+                {
+                    testRun.setThrowable( e );
+                    testRun.setEndTime( System.currentTimeMillis() );
+                    testRun.setError( true );
+                    testRun.setFailure( false );
+                    felixContainer.shutdown();
+                    count++;
+                    errors++;
+                    e.printStackTrace();
+                    continue;
+                }
+            }
+
+            // ---------------------------------------------------------------
+            // Startup the Felix container and access our bundle
+            // ---------------------------------------------------------------
+            
+            MutablePropertyResolver resolver = new MutablePropertyResolverImpl(props);
+            felixContainer.start( resolver, new ArrayList() );
+            String artifactLocation = null;
+            try
+            {
+                artifactLocation = project.getArtifact().getFile().toURL().toString();
+            }
+            catch ( MalformedURLException e )
+            {
+                testRun.setThrowable( e );
+                testRun.setEndTime( System.currentTimeMillis() );
+                testRun.setError( true );
+                testRun.setFailure( false );
+                felixContainer.shutdown();
+                count++;
+                errors++;
+                e.printStackTrace();
+                continue;
+            }
+            Bundle bundle = felixContainer.getBundle( artifactLocation );
+
+            // ---------------------------------------------------------------
+            // Analyze methods of our Bundle's BundleActivator looking for 
+            // public nonstatic nonabstract methods that start with "test"
+            // ---------------------------------------------------------------
+            
+            List testMethods = new ArrayList();
+            try
+            {
+                Class clazz = bundle.loadClass( felixTestActivator );
+                Method[] methods = clazz.getMethods();
+                for ( int ii = 0; ii < methods.length; ii++ )
+                {
+                    int modifiers = methods[ii].getModifiers();
+                    boolean isPublic = Modifier.isPublic( modifiers );
+                    boolean isAbstract = Modifier.isAbstract( modifiers );
+                    boolean isStatic = Modifier.isStatic( modifiers );
+                    boolean startsWithTest = methods[ii].getName().startsWith( "test" );
+                    
+                    if ( isPublic && ! isAbstract && ! isStatic && startsWithTest )
+                    {
+                        testMethods.add( methods[ii] );
+                    }
+                }
+            }
+            catch ( ClassNotFoundException e )
+            {
+                testRun.setThrowable( e );
+                testRun.setEndTime( System.currentTimeMillis() );
+                testRun.setError( true );
+                testRun.setFailure( false );
+                felixContainer.shutdown();
+                count++;
+                errors++;
+                e.printStackTrace();
+                continue;
+            }
+            
+            if ( count > testMethods.size() -1 )
+            {
+                keepRunning = false;
+                continue;
+            }
+
+            // ---------------------------------------------------------------
+            // No test methods found in this bundle so we just exist the loop
+            // ---------------------------------------------------------------
+
+            if ( testMethods.size() < 0 )
+            {
+                felixContainer.shutdown();
+                count++;
+                break;
+            }
+
+            // ---------------------------------------------------------------
+            // Test methods found!  So let's get the method and invoke it
+            // ---------------------------------------------------------------
+
+            Method meth = ( Method ) testMethods.get( count );
+            System.out.println( "Running integration test method: " + meth.getName() + "()" );
+            try
+            {
+                BundleActivator activator = felixContainer.getBundleActivator( bundle );
+                System.out.println( "ACTIVATOR = " + activator );
+                meth.invoke( activator, new Object[] {} );
+            }
+            catch ( Exception e )
+            {
+                testRun.setThrowable( e );
+                testRun.setEndTime( System.currentTimeMillis() );
+                testRun.setError( true );
+                testRun.setFailure( false );
+                felixContainer.shutdown();
+                count++;
+                failures++;
+                e.printStackTrace();
+                continue;
+            }
+
+            felixContainer.shutdown();
+            count++;
+            if ( count > testMethods.size() -1 )
+            {
+                keepRunning = false;
+            }
+        }
+        
+        StringBuffer buf = new StringBuffer();
+        buf.append( "Tests run: " ).append( testRuns.size() );
+        buf.append( ", Failures: " ).append( failures );
+        buf.append( ", Errors: " ).append( errors );
+        buf.append( ", Skipped: 0, Time elapsed: ");
+        double timeElapsed = ( System.currentTimeMillis() - startTime );
+        timeElapsed = timeElapsed / 1000;
+        buf.append( timeElapsed );
+        buf.append( " sec" );
+        
+        System.out.println( buf.toString() );
+        
+        if ( errors + failures > 0 )
+        {
+            throw new MojoFailureException( "Errors and failures encountered during execution" );
+        }
+    }
+    
+
+    public String getAutoStart() throws MalformedURLException
+    {
+        List included = new ArrayList();
+        List excluded = new ArrayList();
+        if ( exclusions == null )
+        {
+            exclusions = Collections.EMPTY_LIST;
+        }
+        
+        StringBuffer buf = new StringBuffer();
+        StringBuffer keyBuf = new StringBuffer();
+        for ( Iterator ii = project.getDependencyArtifacts().iterator(); ii.hasNext(); /**/) 
+        {
+            Artifact dep = ( Artifact ) ii.next();
+            keyBuf.setLength( 0 );
+            keyBuf.append( dep.getGroupId() ).append( ":" ).append( dep.getArtifactId() );
+            String depKey = keyBuf.toString();
+            
+            // -------------------------------------------------------------------
+            // Add only provided dependent artifacts that have not been excluded
+            // -------------------------------------------------------------------
+            
+            if ( dep.getScope().equalsIgnoreCase( "provided" ) )
+            {
+                if ( dep.getArtifactId().equalsIgnoreCase( "org.osgi.core" ) ||
+                     exclusions.contains( depKey ) )
+                {
+                    excluded.add( depKey );
+                    continue;
+                }
+                
+                included.add( depKey );
+                buf.append( dep.getFile().toURL() );
+                buf.append( " " );
+            }
+        }
+        
+        keyBuf.setLength( 0 );
+        keyBuf.append( project.getGroupId() ).append( ":" ).append( project.getArtifactId() );
+        String depKey = keyBuf.toString();
+        included.add( depKey );
+        buf.append( felixTestBundle.toURL() );
+        
+        // -------------------------------------------------------------------
+        // Report what was included and what was excluded
+        // -------------------------------------------------------------------
+        
+        getLog().info( "" );
+        getLog().info( "\t\tJars/Bundles Included for Autostart" ); 
+        getLog().info( "\t\t-----------------------------------" );
+        getLog().info( "" );
+        for ( Iterator ii = included.iterator(); ii.hasNext(); /**/ )
+        {
+            getLog().info( "\t\t" + ( String ) ii.next() );
+        }
+        getLog().info( "" );
+        getLog().info( "" );
+        getLog().info( "\t\tJars/Bundles Excluded from Autostart" );
+        getLog().info( "\t\t------------------------------------" );
+        getLog().info( "" );
+        for ( Iterator ii = excluded.iterator(); ii.hasNext(); /**/ )
+        {
+            getLog().info( "\t\t" + ( String ) ii.next() );
+        }
+        getLog().info( "" );
+        getLog().info( "" );
+        return buf.toString();
+    }
+}
diff --git a/tools/maven2/maven-felix-plugin/src/main/java/org/apache/felix/tools/maven/felix/plugin/FelixRunMojo.java b/tools/maven2/maven-felix-plugin/src/main/java/org/apache/felix/tools/maven/felix/plugin/FelixRunMojo.java
index 538f1ff..584d352 100644
--- a/tools/maven2/maven-felix-plugin/src/main/java/org/apache/felix/tools/maven/felix/plugin/FelixRunMojo.java
+++ b/tools/maven2/maven-felix-plugin/src/main/java/org/apache/felix/tools/maven/felix/plugin/FelixRunMojo.java
@@ -1,3 +1,19 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.felix.tools.maven.felix.plugin;
 
 
diff --git a/tools/maven2/maven-felix-plugin/src/main/java/org/apache/felix/tools/maven/felix/plugin/TestRun.java b/tools/maven2/maven-felix-plugin/src/main/java/org/apache/felix/tools/maven/felix/plugin/TestRun.java
new file mode 100644
index 0000000..de88aab
--- /dev/null
+++ b/tools/maven2/maven-felix-plugin/src/main/java/org/apache/felix/tools/maven/felix/plugin/TestRun.java
@@ -0,0 +1,87 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed 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.felix.tools.maven.felix.plugin;
+
+
+public class TestRun
+{
+    private boolean isFailure;
+    private boolean isError;
+    private Throwable t;
+    private long startTime;
+    private long endTime;
+    
+    
+    public void setFailure( boolean isFailure )
+    {
+        this.isFailure = isFailure;
+    }
+    
+    
+    public boolean isFailure()
+    {
+        return isFailure;
+    }
+
+
+    public void setError( boolean isError )
+    {
+        this.isError = isError;
+    }
+
+
+    public boolean isError()
+    {
+        return isError;
+    }
+
+
+    public void setThrowable( Throwable t )
+    {
+        this.t = t;
+    }
+
+
+    public Throwable getThrowable()
+    {
+        return t;
+    }
+
+
+    public void setStartTime( long startTime )
+    {
+        this.startTime = startTime;
+    }
+
+
+    public long getStartTime()
+    {
+        return startTime;
+    }
+
+
+    public void setEndTime( long endTime )
+    {
+        this.endTime = endTime;
+    }
+
+
+    public long getEndTime()
+    {
+        return endTime;
+    }
+}