Added: 
felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds.itest/src/org/apache/felix/scr/integration/ComponentConfigurationTest.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds.itest/src/org/apache/felix/scr/integration/ComponentConfigurationTest.java?rev=1689973&view=auto
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds.itest/src/org/apache/felix/scr/integration/ComponentConfigurationTest.java
 (added)
+++ 
felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds.itest/src/org/apache/felix/scr/integration/ComponentConfigurationTest.java
 Wed Jul  8 22:10:14 2015
@@ -0,0 +1,588 @@
+/*
+ * 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.felix.scr.integration;
+
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.apache.felix.scr.integration.components.SimpleComponent;
+import org.apache.felix.scr.integration.components.SimpleServiceImpl;
+import org.junit.Test;
+import org.osgi.framework.Constants;
+import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO;
+
+import junit.framework.TestCase;
+
+
+public class ComponentConfigurationTest extends ComponentTestBase
+{
+    @Test
+    public void test_SimpleComponent_configuration_ignore() throws Exception
+    {
+        final String pid = "SimpleComponent.configuration.ignore";
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+
+        deleteConfig( pid );
+        delay();
+
+        ComponentConfigurationDTO cc = getDisabledConfigurationAndEnable(pid, 
ComponentConfigurationDTO.ACTIVE);
+        
+        TestCase.assertNotNull( SimpleComponent.INSTANCE );
+        TestCase.assertNull( SimpleComponent.INSTANCE.getProperty( PROP_NAME ) 
);
+
+        configure( pid );
+        delay();
+
+        findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.ACTIVE);
+        TestCase.assertNotNull( SimpleComponent.INSTANCE );
+        TestCase.assertNull( SimpleComponent.INSTANCE.getProperty( PROP_NAME ) 
);
+
+        deleteConfig( pid );
+        delay();
+
+        findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.ACTIVE);
+        TestCase.assertNotNull( SimpleComponent.INSTANCE );
+        TestCase.assertNull( SimpleComponent.INSTANCE.getProperty( PROP_NAME ) 
);
+
+        disableAndCheck( cc );
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+    }
+
+
+    @Test
+    public void test_SimpleComponent_configuration_optional() throws Exception
+    {
+        final String pid = "SimpleComponent.configuration.optional";
+        ComponentConfigurationDTO cc = getDisabledConfigurationAndEnable(pid, 
ComponentConfigurationDTO.ACTIVE);
+
+        final SimpleComponent firstInstance = SimpleComponent.INSTANCE;
+        TestCase.assertNotNull( firstInstance );
+        TestCase.assertNull( firstInstance.getProperty( PROP_NAME ) );
+
+        configure( pid );
+        delay();
+
+        final SimpleComponent secondInstance = SimpleComponent.INSTANCE;
+        findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.ACTIVE);
+        TestCase.assertNotNull( secondInstance );
+        TestCase.assertEquals( PROP_NAME, secondInstance.getProperty( 
PROP_NAME ) );
+
+        deleteConfig( pid );
+        delay();
+
+        final SimpleComponent thirdInstance = SimpleComponent.INSTANCE;
+        findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.ACTIVE);
+        TestCase.assertNotNull( thirdInstance );
+        TestCase.assertNull( thirdInstance.getProperty( PROP_NAME ) );
+
+        TestCase.assertNotSame( "Expect new instance object after 
reconfiguration", firstInstance, secondInstance );
+        TestCase.assertNotSame( "Expect new instance object after 
configuration deletion (1)", firstInstance,
+            thirdInstance );
+        TestCase.assertNotSame( "Expect new instance object after 
configuration deletion (2)", secondInstance,
+            thirdInstance );
+
+        disableAndCheck( cc );
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+    }
+
+
+    @Test
+    public void test_SimpleComponent_configuration_require() throws Exception
+    {
+        final String pid = "SimpleComponent.configuration.require";
+
+        deleteConfig( pid );
+        delay();
+        
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+
+        getConfigurationsDisabledThenEnable(pid, 0, 
ComponentConfigurationDTO.UNSATISFIED_REFERENCE);
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+
+        configure( pid );
+        delay();
+
+        ComponentConfigurationDTO cc = findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.ACTIVE);
+        TestCase.assertNotNull( SimpleComponent.INSTANCE );
+        TestCase.assertEquals( PROP_NAME, 
SimpleComponent.INSTANCE.getProperty( PROP_NAME ) );
+
+        deleteConfig( pid );
+        delay();
+
+        checkConfigurationCount(pid, 0, -1);
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+
+        disableAndCheck( cc );
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+    }
+
+    /**
+     * same as test_SimpleComponent_configuration_require except configuration 
is present when component is enabled.
+     */
+    @Test
+    public void test_SimpleComponent_configuration_require_initialize() throws 
Exception
+    {
+        final String pid = "SimpleComponent.configuration.require";
+
+        deleteConfig( pid );
+        configure( pid );
+        delay();
+        
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+
+        ComponentConfigurationDTO cc = 
getConfigurationsDisabledThenEnable(pid, 1, 
ComponentConfigurationDTO.ACTIVE).iterator().next();
+
+        TestCase.assertNotNull( SimpleComponent.INSTANCE );
+        TestCase.assertEquals( PROP_NAME, 
SimpleComponent.INSTANCE.getProperty( PROP_NAME ) );
+
+        deleteConfig( pid );
+        delay();
+
+        checkConfigurationCount(pid, 0, -1);
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+
+        disableAndCheck( cc );
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+    }
+
+
+    @Test
+    public void test_SimpleComponent_dynamic_configuration() throws Exception
+    {
+        final String pid = "DynamicConfigurationComponent";
+        boolean pre13 = true;
+        boolean recreateOnDelete = true;
+        dynamicConfigTest(pid, pre13, recreateOnDelete);
+    }
+
+    @Test
+    public void test_SimpleComponent_dynamic_configuration_13() throws 
Exception
+    {
+        final String pid = "DynamicConfigurationComponent13";
+        boolean pre13 = false;
+        boolean recreateOnDelete = false;
+        dynamicConfigTest(pid, pre13, recreateOnDelete);
+    }
+    
+    @Test
+    public void test_SimpleComponent_dynamic_configuration_flag() throws 
Exception
+    {
+        final String pid = "DynamicConfigurationComponentFlag";
+        boolean pre13 = true;
+        boolean recreateOnDelete = false;
+        dynamicConfigTest(pid, pre13, recreateOnDelete);
+    }
+
+
+       private void dynamicConfigTest(final String pid, boolean pre13, boolean 
recreateOnDelete)  throws Exception
+       {
+           Object pidWithout;
+           Object pidWith;
+           if (pre13)
+           {
+               pidWithout = pid + ".description";
+               pidWith = pid;
+           }
+           else 
+           {
+               pidWithout = pid + ".description";
+               pidWith = Arrays.asList(new String[] {pid + ".description", 
pid});
+           }
+        deleteConfig( pid );
+        delay();
+
+        ComponentConfigurationDTO cc = getDisabledConfigurationAndEnable(pid, 
ComponentConfigurationDTO.ACTIVE);
+
+        TestCase.assertNotNull( SimpleComponent.INSTANCE );
+        TestCase.assertNull( SimpleComponent.INSTANCE.getProperty( PROP_NAME ) 
);
+        TestCase.assertEquals(pidWithout, 
SimpleComponent.INSTANCE.getProperty(Constants.SERVICE_PID));
+
+        final SimpleComponent instance = SimpleComponent.INSTANCE;
+
+        configure( pid );
+        delay();
+
+        findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.ACTIVE);
+        TestCase.assertEquals( instance, SimpleComponent.INSTANCE );
+        TestCase.assertEquals( PROP_NAME, 
SimpleComponent.INSTANCE.getProperty( PROP_NAME ) );
+        TestCase.assertEquals(pidWith, 
SimpleComponent.INSTANCE.getProperty(Constants.SERVICE_PID));
+
+        deleteConfig( pid );
+        delay();
+
+        findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.ACTIVE);
+        if (recreateOnDelete)
+        {
+            TestCase.assertNotSame( instance, SimpleComponent.INSTANCE );
+        }
+        else
+        {
+            TestCase.assertSame( instance, SimpleComponent.INSTANCE );
+        }
+        TestCase.assertNull( SimpleComponent.INSTANCE.getProperty( PROP_NAME ) 
);
+        TestCase.assertEquals(pidWithout, 
SimpleComponent.INSTANCE.getProperty(Constants.SERVICE_PID));
+
+        disableAndCheck( cc );
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+       }
+
+
+    @Test
+    public void 
test_SimpleComponent_dynamic_optional_configuration_with_required_service() 
throws Exception
+    {
+        final String targetProp = "ref.target";
+        final String filterProp = "required";
+        final SimpleServiceImpl service = SimpleServiceImpl.create( 
bundleContext, "sample" ).setFilterProperty( filterProp );
+        try
+        {
+            final String pid = 
"DynamicConfigurationComponentWithRequiredReference";
+            deleteConfig( pid );
+            delay();
+
+            // mandatory ref missing --> component unsatisfied
+            ComponentConfigurationDTO cc = 
getDisabledConfigurationAndEnable(pid, 
ComponentConfigurationDTO.UNSATISFIED_REFERENCE);
+
+            // dynamically configure without the correct target
+            configure( pid );
+            delay();
+
+            // mandatory ref missing --> component unsatisfied
+            findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.UNSATISFIED_REFERENCE);
+
+            // dynamically configure with correct target
+            theConfig.put( targetProp, "(filterprop=" + filterProp + ")" );
+            configure( pid );
+            delay();
+
+            findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.ACTIVE);
+            TestCase.assertNotNull( SimpleComponent.INSTANCE );
+            TestCase.assertEquals( PROP_NAME, 
SimpleComponent.INSTANCE.getProperty( PROP_NAME ) );
+            TestCase.assertEquals( pid, SimpleComponent.INSTANCE.getProperty( 
Constants.SERVICE_PID ) );
+
+            final SimpleComponent instance = SimpleComponent.INSTANCE;
+
+            configure( pid );
+            delay();
+
+            // same instance after reconfiguration
+            findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.ACTIVE);
+            TestCase.assertEquals( instance, SimpleComponent.INSTANCE );
+            TestCase.assertEquals( PROP_NAME, 
SimpleComponent.INSTANCE.getProperty( PROP_NAME ) );
+            TestCase.assertEquals( pid, SimpleComponent.INSTANCE.getProperty( 
Constants.SERVICE_PID ) );
+            TestCase.assertNotNull( SimpleComponent.INSTANCE.m_singleRef );
+
+            // reconfigure without target --> unsatisifed
+            theConfig.remove( targetProp );
+            configure( pid );
+            delay();
+
+            // mandatory ref missing --> component unsatisfied
+            findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.UNSATISFIED_REFERENCE);
+
+            deleteConfig( pid );
+            delay();
+
+            // mandatory ref missing --> component unsatisfied
+            findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.UNSATISFIED_REFERENCE);
+
+            disableAndCheck(cc);
+            TestCase.assertNull( SimpleComponent.INSTANCE );
+        }
+        finally
+        {
+            theConfig.remove( targetProp );
+            if ( service != null )
+            {
+                service.drop();
+            }
+        }
+    }
+
+    /**
+     * FELIX-3902.  Start with filter matching two services, remove one, then 
change the filter
+     * to (still) match the other one.  2nd service should remain bound.
+     */
+    @Test
+    public void 
test_SimpleComponent_dynamic_optional_configuration_with_required_service2() 
throws Exception
+    {
+        final String targetProp = "ref.target";
+        final String filterProp1 = "one";
+        final String filterProp2 = "two";
+        final SimpleServiceImpl service1 = SimpleServiceImpl.create( 
bundleContext, "one", 1 ).setFilterProperty( filterProp1 );
+        final SimpleServiceImpl service2 = SimpleServiceImpl.create( 
bundleContext, "two", 2 ).setFilterProperty( filterProp2 );
+        try
+        {
+            final String pid = 
"DynamicConfigurationComponentWithRequiredReference";
+            deleteConfig( pid );
+            delay();
+
+            // mandatory ref missing --> component unsatisfied
+            ComponentConfigurationDTO cc = 
getDisabledConfigurationAndEnable(pid, 
ComponentConfigurationDTO.UNSATISFIED_REFERENCE);
+
+            // dynamically configure without the correct target
+            configure( pid );
+            delay();
+
+            // mandatory ref missing --> component unsatisfied
+            findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.UNSATISFIED_REFERENCE);
+
+            // dynamically configure with correct target
+            theConfig.put( targetProp, "(|(filterprop=" + filterProp1 + 
")(filterprop=" + filterProp2 + "))" );
+            configure( pid );
+            delay();
+
+            findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.ACTIVE);
+            TestCase.assertNotNull( SimpleComponent.INSTANCE );
+            TestCase.assertEquals( PROP_NAME, 
SimpleComponent.INSTANCE.getProperty( PROP_NAME ) );
+            TestCase.assertEquals( pid, SimpleComponent.INSTANCE.getProperty( 
Constants.SERVICE_PID ) );
+
+            final SimpleComponent instance = SimpleComponent.INSTANCE;
+
+            configure( pid );
+            delay();
+
+            //remove higher ranked service
+            if (service2 != null)
+            {
+                service2.drop();
+            }
+             // same instance after reconfiguration
+            findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.ACTIVE);
+            TestCase.assertEquals( instance, SimpleComponent.INSTANCE );
+            TestCase.assertEquals( PROP_NAME, 
SimpleComponent.INSTANCE.getProperty( PROP_NAME ) );
+            TestCase.assertEquals( pid, SimpleComponent.INSTANCE.getProperty( 
Constants.SERVICE_PID ) );
+            TestCase.assertNotNull( SimpleComponent.INSTANCE.m_singleRef );
+
+            // reconfigure with new filter --> active
+            theConfig.put( targetProp, "(filterprop=" + filterProp1 + ")" );
+            configure( pid );
+            delay();
+
+            // same instance after reconfiguration
+            findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.ACTIVE);
+            TestCase.assertEquals( instance, SimpleComponent.INSTANCE );
+            TestCase.assertEquals( PROP_NAME, 
SimpleComponent.INSTANCE.getProperty( PROP_NAME ) );
+            TestCase.assertEquals( pid, SimpleComponent.INSTANCE.getProperty( 
Constants.SERVICE_PID ) );
+            TestCase.assertNotNull( SimpleComponent.INSTANCE.m_singleRef );
+
+            deleteConfig( pid );
+            delay();
+
+            // mandatory ref missing --> component unsatisfied
+            findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.UNSATISFIED_REFERENCE);
+
+            disableAndCheck(cc);
+            TestCase.assertNull( SimpleComponent.INSTANCE );
+        }
+        finally
+        {
+            theConfig.remove( targetProp );
+            if ( service1 != null )
+            {
+                service1.drop();
+            }
+        }
+    }
+
+    @Test
+    public void 
test_SimpleComponent_dynamic_optional_configuration_with_optional_service() 
throws Exception
+    {
+        final String targetProp = "ref.target";
+        final String filterProp = "required";
+        final SimpleServiceImpl service = SimpleServiceImpl.create( 
bundleContext, "sample" ).setFilterProperty( filterProp );
+        try
+        {
+            final String pid = 
"DynamicConfigurationComponentWithOptionalReference";
+            deleteConfig( pid );
+            delay();
+
+            // optional ref missing --> component active
+            ComponentConfigurationDTO cc = 
getDisabledConfigurationAndEnable(pid, ComponentConfigurationDTO.ACTIVE);
+
+            TestCase.assertNotNull( SimpleComponent.INSTANCE );
+            final SimpleComponent instance = SimpleComponent.INSTANCE;
+
+            // dynamically configure without the correct target
+            configure( pid );
+            delay();
+
+            // optional ref missing --> component active
+            findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.ACTIVE);
+            TestCase.assertEquals( instance, SimpleComponent.INSTANCE );
+            TestCase.assertNull( SimpleComponent.INSTANCE.m_singleRef );
+
+            // dynamically configure with correct target
+            theConfig.put( targetProp, "(filterprop=" + filterProp + ")" );
+            configure( pid );
+            delay();
+
+            findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.ACTIVE);
+            TestCase.assertEquals( instance, SimpleComponent.INSTANCE );
+            TestCase.assertEquals( PROP_NAME, 
SimpleComponent.INSTANCE.getProperty( PROP_NAME ) );
+            TestCase.assertEquals( pid, SimpleComponent.INSTANCE.getProperty( 
Constants.SERVICE_PID ) );
+            TestCase.assertNotNull( SimpleComponent.INSTANCE.m_singleRef );
+
+            configure( pid );
+            delay();
+
+            // same instance after reconfiguration
+            findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.ACTIVE);
+            TestCase.assertEquals( instance, SimpleComponent.INSTANCE );
+            TestCase.assertEquals( PROP_NAME, 
SimpleComponent.INSTANCE.getProperty( PROP_NAME ) );
+            TestCase.assertEquals( pid, SimpleComponent.INSTANCE.getProperty( 
Constants.SERVICE_PID ) );
+            TestCase.assertNotNull( SimpleComponent.INSTANCE.m_singleRef );
+
+            // reconfigure without target --> active
+            theConfig.remove( targetProp );
+            configure( pid );
+            delay();
+
+            // optional ref missing --> component active
+            findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.ACTIVE);
+            TestCase.assertEquals( instance, SimpleComponent.INSTANCE );
+            TestCase.assertNull( SimpleComponent.INSTANCE.m_singleRef );
+
+            deleteConfig( pid );
+            delay();
+
+            // optional ref missing --> component active
+            findComponentConfigurationByName(pid, 
ComponentConfigurationDTO.ACTIVE);
+            TestCase.assertNotSame( instance, SimpleComponent.INSTANCE );
+            TestCase.assertNull( SimpleComponent.INSTANCE.m_singleRef );
+
+            disableAndCheck(cc);
+            TestCase.assertNull( SimpleComponent.INSTANCE );
+        }
+        finally
+        {
+//            Thread.sleep( 60000 );
+            theConfig.remove( targetProp );
+            if ( service != null )
+            {
+                service.drop();
+            }
+        }
+    }
+
+
+    @Test
+    public void test_SimpleComponent_factory_configuration() throws Exception
+    {
+        final String factoryPid = "FactoryConfigurationComponent";
+
+        deleteFactoryConfigurations( factoryPid );
+        delay();
+
+        Collection<ComponentConfigurationDTO> confs = 
getConfigurationsDisabledThenEnable(factoryPid, 0, -1);
+        TestCase.assertTrue( SimpleComponent.INSTANCES.isEmpty() );
+
+        // create two factory configurations expecting two components
+        final String pid0 = createFactoryConfiguration( factoryPid );
+        final String pid1 = createFactoryConfiguration( factoryPid );
+        delay();
+
+        // expect two active components, //TODO WTF?? only first is active, 
second is disabled
+        checkConfigurationCount(factoryPid, 2, 
ComponentConfigurationDTO.ACTIVE);
+        // delete a configuration
+        deleteConfig( pid0 );
+        delay();
+
+        // expect one component
+        checkConfigurationCount(factoryPid, 1, 
ComponentConfigurationDTO.ACTIVE);
+
+        // delete second configuration
+        deleteConfig( pid1 );
+        delay();
+
+        checkConfigurationCount(factoryPid, 0, 
ComponentConfigurationDTO.ACTIVE);
+        disableAndCheck(confs);
+    }
+
+    /**
+     * same as test_SimpleComponent_factory_configuration except 
configurations are present before 
+     * component is enabled to test initialization.
+     */
+    @Test
+    public void test_SimpleComponent_factory_configuration_initialize() throws 
Exception
+    {
+        final String factoryPid = "FactoryConfigurationComponent";
+
+        deleteFactoryConfigurations( factoryPid );
+
+        // create two factory configurations expecting two components
+        final String pid0 = createFactoryConfiguration( factoryPid );
+        final String pid1 = createFactoryConfiguration( factoryPid );
+        delay();
+
+        Collection<ComponentConfigurationDTO> confs = 
getConfigurationsDisabledThenEnable(factoryPid, 2, 
ComponentConfigurationDTO.ACTIVE);
+
+        // delete a configuration
+        deleteConfig( pid0 );
+        delay();
+
+        // expect one component
+        checkConfigurationCount(factoryPid, 1, 
ComponentConfigurationDTO.ACTIVE);
+
+        // delete second configuration
+        deleteConfig( pid1 );
+        delay();
+
+        checkConfigurationCount(factoryPid, 0, 
ComponentConfigurationDTO.ACTIVE);
+        disableAndCheck(confs);
+    }
+
+    @Test
+    public void test_SimpleComponent_factory_configuration_enabled() throws 
Exception
+    {
+        final String factoryPid = "FactoryConfigurationComponent_enabled";
+
+        deleteFactoryConfigurations( factoryPid );
+        delay();
+
+        checkConfigurationCount(factoryPid, 0, 
ComponentConfigurationDTO.ACTIVE);
+        // no component config exists without configuration
+
+        // create two factory configurations expecting two components
+        final String pid0 = createFactoryConfiguration( factoryPid );
+        final String pid1 = createFactoryConfiguration( factoryPid );
+        delay();
+
+        // expect two components, all active
+        checkConfigurationCount(factoryPid, 2, 
ComponentConfigurationDTO.ACTIVE);
+
+        // disable the name component
+        disableAndCheck( factoryPid );
+        delay();
+
+
+        // create a configuration
+        final String pid3 = createFactoryConfiguration( factoryPid );
+        delay();
+
+        Collection<ComponentConfigurationDTO> confs = 
getConfigurationsDisabledThenEnable(factoryPid, 3, 
ComponentConfigurationDTO.ACTIVE);
+        deleteFactoryConfigurations( factoryPid );
+        for (ComponentConfigurationDTO conf : confs) {
+            disableAndCheck(conf);
+        }
+    }
+
+
+}

Added: 
felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds.itest/src/org/apache/felix/scr/integration/ComponentDisposeTest.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds.itest/src/org/apache/felix/scr/integration/ComponentDisposeTest.java?rev=1689973&view=auto
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds.itest/src/org/apache/felix/scr/integration/ComponentDisposeTest.java
 (added)
+++ 
felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds.itest/src/org/apache/felix/scr/integration/ComponentDisposeTest.java
 Wed Jul  8 22:10:14 2015
@@ -0,0 +1,77 @@
+/*
+ * 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.felix.scr.integration;
+
+
+import java.util.Collection;
+
+import org.apache.felix.scr.integration.components.SimpleComponent;
+import org.junit.Test;
+import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+
+public class ComponentDisposeTest extends ComponentTestBase
+{
+    @Test
+    public void test_SimpleComponent_factory_configuration() throws Exception
+    {
+        final String factoryPid = "FactoryConfigurationComponent";
+
+        deleteFactoryConfigurations( factoryPid );
+        delay();
+
+        Collection<ComponentConfigurationDTO> confs = 
getConfigurationsDisabledThenEnable(factoryPid, 0, 
ComponentConfigurationDTO.ACTIVE);//there should be none
+
+        // create two factory configurations expecting two components
+        final String pid0 = createFactoryConfiguration( factoryPid );
+        final String pid1 = createFactoryConfiguration( factoryPid );
+        delay();
+
+        Collection<ComponentConfigurationDTO> ccs = 
findComponentConfigurationsByName(factoryPid, ComponentConfigurationDTO.ACTIVE);
+               Assert.assertEquals(2, ccs.size());
+        // expect two components, only first is active, second is disabled
+        TestCase.assertEquals( 2, SimpleComponent.INSTANCES.size() );
+        for (ComponentConfigurationDTO cc: ccs)
+        {
+               
TestCase.assertTrue(SimpleComponent.INSTANCES.containsKey(cc.id));
+        }
+
+        // dispose an instance
+        final SimpleComponent anInstance = SimpleComponent.INSTANCE;
+        TestCase.assertNotNull( anInstance );
+        TestCase.assertNotNull( anInstance.m_activateContext );
+        anInstance.m_activateContext.getComponentInstance().dispose();
+        delay();
+
+        // expect one component
+        ComponentConfigurationDTO cc = 
findComponentConfigurationByName(factoryPid, ComponentConfigurationDTO.ACTIVE);
+
+        TestCase.assertEquals( 1, SimpleComponent.INSTANCES.size() );
+       TestCase.assertTrue(SimpleComponent.INSTANCES.containsKey(cc.id));
+
+        final SimpleComponent instance = 
SimpleComponent.INSTANCES.values().iterator().next();
+        disableAndCheck(confs);
+        deleteFactoryConfigurations(factoryPid);
+    }
+
+
+}

Added: 
felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds.itest/src/org/apache/felix/scr/integration/ComponentEnableTest.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds.itest/src/org/apache/felix/scr/integration/ComponentEnableTest.java?rev=1689973&view=auto
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds.itest/src/org/apache/felix/scr/integration/ComponentEnableTest.java
 (added)
+++ 
felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds.itest/src/org/apache/felix/scr/integration/ComponentEnableTest.java
 Wed Jul  8 22:10:14 2015
@@ -0,0 +1,59 @@
+/*
+ * 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.felix.scr.integration;
+
+
+import org.apache.felix.scr.integration.components.EnableComponent;
+import org.apache.felix.scr.integration.components.SimpleComponent;
+import org.junit.Test;
+import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO;
+
+import junit.framework.TestCase;
+
+
+public class ComponentEnableTest extends ComponentTestBase
+{
+    public ComponentEnableTest()
+    {
+        super("/resource/integration_test_enable.xml");
+    }
+
+    @Test
+    public void test_Component_Enable() throws Exception
+    {
+        final String enable = 
"org.apache.felix.scr.integration.components.enable";
+        final String name = 
"org.apache.felix.scr.integration.components.SimpleComponent";
+        
+        ComponentConfigurationDTO dto = 
findComponentConfigurationByName(enable, ComponentConfigurationDTO.SATISFIED);
+        
+        EnableComponent ec = getServiceFromConfiguration(dto, 
EnableComponent.class);
+        
+        TestCase.assertEquals(0, SimpleComponent.INSTANCES.size());
+
+        ec.enable(name);
+        delay();
+        TestCase.assertEquals(1, SimpleComponent.INSTANCES.size());
+        ec.enable(name);
+        delay();
+        TestCase.assertEquals(1, SimpleComponent.INSTANCES.size());
+
+    }
+
+
+}

Added: 
felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds.itest/src/org/apache/felix/scr/integration/ComponentFactoryTest.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds.itest/src/org/apache/felix/scr/integration/ComponentFactoryTest.java?rev=1689973&view=auto
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds.itest/src/org/apache/felix/scr/integration/ComponentFactoryTest.java
 (added)
+++ 
felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds.itest/src/org/apache/felix/scr/integration/ComponentFactoryTest.java
 Wed Jul  8 22:10:14 2015
@@ -0,0 +1,434 @@
+/*
+ * 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.felix.scr.integration;
+
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
+import java.util.Hashtable;
+
+import org.apache.felix.scr.integration.components.SimpleComponent;
+import org.apache.felix.scr.integration.components.SimpleService;
+import org.apache.felix.scr.integration.components.SimpleServiceImpl;
+import org.junit.Test;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.component.ComponentException;
+import org.osgi.service.component.ComponentFactory;
+import org.osgi.service.component.ComponentInstance;
+import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO;
+import org.osgi.service.log.LogService;
+
+import junit.framework.TestCase;
+
+
+public class ComponentFactoryTest extends ComponentTestBase
+{
+    public ComponentFactoryTest() 
+    {
+        super("/resource/integration_test_simple_factory_components.xml");
+        ignoredWarnings = new String[] {
+          "ComponentFactoryTest: Bound Services=\\[SimpleServiceImpl: 
value=service2, filterprop=match\\]",
+          "\\[factory.component.*\\] The activate method has thrown an 
exception\\njava.lang.RuntimeException: Requested Failure",
+          "\\[factory.component.*\\] Failed creating the component instance; 
see log for reason"
+        };
+    }
+
+    @Test
+    public void test_component_factory() throws Exception
+    {
+        final String componentname = "factory.component";
+        final String componentfactory = "factory.component.factory";
+
+        Collection<ComponentConfigurationDTO> confs = 
getConfigurationsDisabledThenEnable(componentname, 0, -1);
+
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+
+        final ComponentInstance instance = 
createFactoryComponentInstance(componentfactory);
+
+        // check registered components
+        checkConfigurationCount(componentname, 1, 
ComponentConfigurationDTO.ACTIVE);
+
+        instance.dispose();
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+        TestCase.assertNull( instance.getInstance() ); // SCR 112.12.6.2
+        
+        checkConfigurationCount(componentname, 0, 
ComponentConfigurationDTO.ACTIVE);
+        disableAndCheck(confs);        
+    }
+
+
+    @Test
+    public void test_component_factory_disable_factory() throws Exception
+    {
+        // tests components remain alive after factory has been disabled
+
+        final String componentname = "factory.component";
+        final String componentfactory = "factory.component.factory";
+
+        Collection<ComponentConfigurationDTO> confs = 
getConfigurationsDisabledThenEnable(componentname, 0, -1);
+
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+
+        final ComponentInstance instance = 
createFactoryComponentInstance(componentfactory);
+
+        checkConfigurationCount(componentname, 1, 
ComponentConfigurationDTO.ACTIVE);
+
+        // disable the factory
+        disableAndCheck(componentname);
+        delay();
+
+        // factory is disabled but the instance is still alive
+        TestCase.assertNotNull( SimpleComponent.INSTANCE );
+
+        instance.dispose();
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+        TestCase.assertNull( instance.getInstance() ); // SCR 112.12.6.2
+        disableAndCheck(confs);        
+    }
+
+
+    @Test
+    public void test_component_factory_newInstance_failure() throws Exception
+    {
+        final String componentname = "factory.component";
+        final String componentfactory = "factory.component.factory";
+
+        Collection<ComponentConfigurationDTO> confs = 
getConfigurationsDisabledThenEnable(componentname, 0, -1);
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+
+        try
+        {
+            Hashtable<String, String> props = new Hashtable<String, String>();
+            props.put( PROP_NAME_FACTORY, PROP_NAME_FACTORY );
+            props.put( SimpleComponent.PROP_ACTIVATE_FAILURE, "Requested 
Failure" );
+            createFactoryComponentInstance(componentfactory, props);
+            TestCase.fail( "Expected newInstance method to fail with 
ComponentException" );
+        }
+        catch ( ComponentException ce )
+        {
+            // this is expected !
+        }
+
+        checkConfigurationCount(componentname, 0, 
ComponentConfigurationDTO.ACTIVE);
+        disableAndCheck(confs);
+    }
+
+
+    @Test
+    public void test_component_factory_require_configuration() throws Exception
+    {
+        final String componentname = "factory.component.configuration";
+        final String componentfactory = 
"factory.component.factory.configuration";
+
+        testConfiguredFactory(componentname, componentfactory, false, false);  
      
+    }
+
+    @Test
+    public void test_component_factory_require_configuration_obsolete() throws 
Exception
+    {
+        final String componentname = 
"factory.component.configuration.obsolete";
+
+        TestCase.assertNull(SimpleComponent.INSTANCE);
+
+        createFactoryConfiguration(componentname);
+        delay();
+        Collection<ComponentConfigurationDTO> confs = 
getConfigurationsDisabledThenEnable(componentname, 1, 
ComponentConfigurationDTO.ACTIVE);
+        TestCase.assertEquals(PROP_NAME, 
SimpleComponent.INSTANCE.getProperty(PROP_NAME));
+        disableAndCheck(confs);
+        deleteFactoryConfigurations(componentname);
+    }
+
+    @Test
+    public void test_component_factory_optional_configuration() throws 
Exception
+    {
+        final String componentname = 
"factory.component.configuration.optional";
+        final String componentfactory = 
"factory.component.factory.configuration.optional";
+
+        testConfiguredFactory(componentname, componentfactory, true, false);
+    }
+
+    @Test
+    public void test_component_factory_optional_configuration_13() throws 
Exception
+    {
+        final String componentname = 
"factory.component.configuration.optional.13";
+        final String componentfactory = 
"factory.component.factory.configuration.optional.13";
+
+        testConfiguredFactory(componentname, componentfactory, true, true);
+    }
+
+    @Test
+    public void test_component_factory_optional_configuration_nomodify() 
throws Exception
+    {
+        final String componentname = 
"factory.component.configuration.optional.nomodify";
+        final String componentfactory = 
"factory.component.factory.configuration.optional.nomodify";
+
+        testConfiguredFactory(componentname, componentfactory, true, false);
+    }
+
+
+    private void testConfiguredFactory(final String componentname,
+        final String componentfactory, boolean optional, boolean 
expectComponent) throws InvocationTargetException,
+        InterruptedException, InvalidSyntaxException
+    {
+        // ensure there is no configuration for the component
+        deleteConfig( componentname );
+        delay();
+
+        Collection<ComponentConfigurationDTO> confs = 
getConfigurationsDisabledThenEnable(componentname, 0, -1);
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+
+        // At this point, since we don't have created the configuration, then 
the ComponentFactory
+        // should not be available.
+        
+        checkFactory(componentfactory, optional);
+        
+        // supply configuration now and ensure active
+        configure( componentname );
+        delay();        
+
+        checkConfigurationCount(componentname, 0, 
ComponentConfigurationDTO.ACTIVE);
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+
+        // get the component factory service
+        final ComponentInstance instance = 
createFactoryComponentInstance(componentfactory);
+
+        final Object instanceObject = instance.getInstance();
+        TestCase.assertNotNull( instanceObject );
+        TestCase.assertEquals( SimpleComponent.INSTANCE, instanceObject );
+        TestCase.assertEquals( PROP_NAME_FACTORY, 
SimpleComponent.INSTANCE.getProperty( PROP_NAME_FACTORY ) );
+        TestCase.assertEquals( PROP_NAME, 
SimpleComponent.INSTANCE.getProperty( PROP_NAME ) );                        
+
+        checkConfigurationCount(componentname, 1, 
ComponentConfigurationDTO.ACTIVE);
+
+        // delete config, ensure factory is not active anymore and component 
instance gone 
+        //(configuration required >> dispose of instance.  Also for pre-1.3 
components, removing config unconditionally
+        //deactivates component.
+        deleteConfig( componentname );
+        delay();
+
+        checkFactory(componentfactory, optional);
+
+        if (expectComponent) 
+        {
+            TestCase.assertNotNull( instance.getInstance() );
+            TestCase.assertNotNull( SimpleComponent.INSTANCE );
+
+            // with removal of the factory, the created instance should also 
be removed
+            checkConfigurationCount(componentname, 1, 
ComponentConfigurationDTO.ACTIVE);            
+        }
+        else
+        {
+            TestCase.assertNull( instance.getInstance() );
+            TestCase.assertNull( SimpleComponent.INSTANCE );
+
+            // with removal of the factory, the created instance should also 
be removed
+            checkConfigurationCount(componentname, 0, 
ComponentConfigurationDTO.ACTIVE);            
+        }
+        disableAndCheck(confs);
+        instance.dispose();
+    }
+
+
+    @Test
+    public void test_component_factory_reference() throws Exception
+    {
+        final String componentname = "factory.component.reference";
+        final String componentfactory = "factory.component.factory.reference";
+
+        SimpleServiceImpl simpleService = SimpleServiceImpl.create( 
bundleContext, "ignored" ).setFilterProperty( "ignored" );
+
+        Collection<ComponentConfigurationDTO> confs = 
getConfigurationsDisabledThenEnable(componentname, 0, -1);
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+
+        // register a service : filterprop=match
+        SimpleServiceImpl match = SimpleServiceImpl.create( bundleContext, 
"required" ).setFilterProperty( "required" );
+        delay();
+
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+
+        final ComponentInstance instance = 
createFactoryComponentInstance(componentfactory);
+        TestCase.assertEquals( 1, SimpleComponent.INSTANCE.m_multiRef.size() );
+        TestCase.assertTrue( SimpleComponent.INSTANCE.m_multiRef.contains( 
match ) );
+
+        // check registered components
+        checkConfigurationCount(componentname, 1, 
ComponentConfigurationDTO.ACTIVE);
+
+        instance.dispose();
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+        TestCase.assertNull( instance.getInstance() ); // SCR 112.12.6.2
+        checkConfigurationCount(componentname, 0, 
ComponentConfigurationDTO.ACTIVE);
+
+
+        // overwritten filterprop
+        Hashtable<String, String> propsNonMatch = new Hashtable<String, 
String>();
+        propsNonMatch.put( PROP_NAME_FACTORY, PROP_NAME_FACTORY );
+        propsNonMatch.put( "ref.target", "(filterprop=nomatch)" );
+        ComponentFactory factory = getComponentFactory(componentfactory);
+        try
+        {
+            factory.newInstance( propsNonMatch );
+            TestCase.fail( "Missing reference must fail instance creation" );
+        }
+        catch ( ComponentException ce )
+        {
+            // expected
+        }
+
+        final SimpleServiceImpl noMatch = SimpleServiceImpl.create( 
bundleContext, "nomatch" ).setFilterProperty(
+            "nomatch" );
+        delay();
+
+        final ComponentInstance instanceNonMatch = factory.newInstance( 
propsNonMatch );
+
+        TestCase.assertNotNull( instanceNonMatch );
+
+        TestCase.assertNotNull( instanceNonMatch.getInstance() );
+        TestCase.assertEquals( SimpleComponent.INSTANCE, 
instanceNonMatch.getInstance() );
+        TestCase.assertEquals( PROP_NAME_FACTORY, 
SimpleComponent.INSTANCE.getProperty( PROP_NAME_FACTORY ) );
+
+        TestCase.assertEquals( 1, SimpleComponent.INSTANCE.m_multiRef.size() );
+        TestCase.assertTrue( SimpleComponent.INSTANCE.m_multiRef.contains( 
noMatch ) );
+
+        // check registered components
+        checkConfigurationCount(componentname, 1, 
ComponentConfigurationDTO.ACTIVE);
+
+        match.getRegistration().unregister();
+        delay();
+
+        // check registered components (ComponentFactory aint no longer)
+        checkConfigurationCount(componentname, 1, 
ComponentConfigurationDTO.ACTIVE);
+
+        //it has already been deactivated.... this should cause an exception?
+        noMatch.getRegistration().unregister();
+        delay();
+
+        // check registered components (ComponentFactory aint no longer)
+        checkConfigurationCount(componentname, 0, 
ComponentConfigurationDTO.ACTIVE);
+
+        // deactivated due to unsatisfied reference
+        TestCase.assertNull( instanceNonMatch.getInstance() );
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+
+        //Check that calling dispose on a deactivated instance has no effect
+        instanceNonMatch.dispose();
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+        TestCase.assertNull( instanceNonMatch.getInstance() ); // SCR 
112.12.6.2
+        disableAndCheck(confs);
+        simpleService.drop();
+    }
+
+    @Test
+    public void test_component_factory_referredTo() throws Exception
+    {
+        //set up the component that refers to the service the factory will 
create.
+        final String referringComponentName = 
"ComponentReferringToFactoryObject";
+        Collection<ComponentConfigurationDTO> confs = 
getConfigurationsDisabledThenEnable(referringComponentName, 1, 
ComponentConfigurationDTO.UNSATISFIED_REFERENCE);
+
+        final String componentname = "factory.component.referred";
+        final String componentfactory = "factory.component.factory.referred";
+
+        getConfigurationsDisabledThenEnable(componentname, 0, -1);
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+
+        Hashtable<String, String> props = new Hashtable<String, String>();
+        props.put( "service.pid", "myFactoryInstance" );
+        final ComponentFactory factory = getComponentFactory(componentfactory);
+
+        final ComponentInstance instance = factory.newInstance( props );
+        TestCase.assertNotNull( instance );
+
+        TestCase.assertNotNull( instance.getInstance() );
+        TestCase.assertTrue( instance.getInstance() instanceof SimpleService );
+        //The referring service should now be active
+        checkConfigurationCount(referringComponentName, 1, 
ComponentConfigurationDTO.ACTIVE);
+
+        instance.dispose();
+        TestCase.assertNull( instance.getInstance() ); // SCR 112.12.6.2
+
+        //make sure it's unsatisfied (service is no longer available)
+        checkConfigurationCount(referringComponentName, 1, 
ComponentConfigurationDTO.UNSATISFIED_REFERENCE);
+        disableAndCheck(confs);
+    }
+
+    @Test
+    public void test_component_factory_with_target_filters() throws Exception
+    {
+        final String componentfactory = 
"factory.component.reference.targetfilter";
+        Collection<ComponentConfigurationDTO> confs = 
getConfigurationsDisabledThenEnable(componentfactory, 0, -1);
+
+        SimpleServiceImpl s1 = SimpleServiceImpl.create(bundleContext, 
"service1");
+        SimpleServiceImpl s2 = SimpleServiceImpl.create(bundleContext, 
"service2");
+
+        // supply configuration now and ensure active
+        Configuration conf = configure( componentfactory );
+        delay();        
+
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+        
+        Hashtable<String, String> props = new Hashtable<String, String>();
+        props.put( PROP_NAME_FACTORY, PROP_NAME_FACTORY );
+        props.put("ref.target", "(value=service2)");
+        final ComponentInstance instance = 
createFactoryComponentInstance(componentfactory, props);
+
+        log.log(LogService.LOG_WARNING, "ComponentFactoryTest: Bound 
Services=" +  SimpleComponent.INSTANCE.m_multiRef);
+        TestCase.assertFalse( SimpleComponent.INSTANCE.m_multiRef.contains( s1 
) );
+        TestCase.assertTrue( SimpleComponent.INSTANCE.m_multiRef.contains( s2 
) );
+
+        instance.dispose();
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+        TestCase.assertNull( instance.getInstance() ); // SCR 112.12.6.2
+        
+        s2.drop();
+        s1.drop();
+        conf.delete();
+        disableAndCheck(confs);
+    }
+    
+    @Test
+    public void test_component_factory_set_bundle_location_null() throws 
Exception
+    {
+        final String componentfactory = 
"factory.component.reference.targetfilter";
+        Collection<ComponentConfigurationDTO> confs = 
getConfigurationsDisabledThenEnable(componentfactory, 0, -1);
+        SimpleServiceImpl s1 = SimpleServiceImpl.create(bundleContext, 
"service1");
+
+        ConfigurationAdmin ca = getConfigurationAdmin();
+        org.osgi.service.cm.Configuration config = ca.getConfiguration( 
componentfactory, null );
+        config.setBundleLocation( null );
+        delay();
+        if ( isAtLeastR5() )
+        {
+            //check that ConfigurationSupport got a Location changed event and 
set the bundle location
+            TestCase.assertNotNull( config.getBundleLocation() );
+        } 
+        // supply configuration now and ensure active
+        configure( componentfactory );
+        delay();        
+
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+        
+        final ComponentFactory factory = getComponentFactory(componentfactory);
+        
+        disableAndCheck(confs);
+        s1.drop();
+        config.delete();
+    }
+    
+}

Added: 
felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds.itest/src/org/apache/felix/scr/integration/ComponentTestBase.java
URL: 
http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds.itest/src/org/apache/felix/scr/integration/ComponentTestBase.java?rev=1689973&view=auto
==============================================================================
--- 
felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds.itest/src/org/apache/felix/scr/integration/ComponentTestBase.java
 (added)
+++ 
felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds.itest/src/org/apache/felix/scr/integration/ComponentTestBase.java
 Wed Jul  8 22:10:14 2015
@@ -0,0 +1,1098 @@
+/*
+ * 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.felix.scr.integration;
+
+
+import static java.lang.System.err;
+import static java.lang.System.out;
+
+import java.io.BufferedOutputStream;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import org.apache.felix.scr.integration.components.Felix4350Component;
+import org.apache.felix.scr.integration.components.SimpleComponent;
+import org.junit.After;
+import org.junit.Before;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.namespace.extender.ExtenderNamespace;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.component.ComponentConstants;
+import org.osgi.service.component.ComponentFactory;
+import org.osgi.service.component.ComponentInstance;
+import org.osgi.service.component.runtime.ServiceComponentRuntime;
+import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO;
+import org.osgi.service.component.runtime.dto.ComponentDescriptionDTO;
+import org.osgi.service.log.LogService;
+import org.osgi.util.tracker.ServiceTracker;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+public abstract class ComponentTestBase extends TestCase
+{
+    // Injected
+    protected BundleContext bundleContext;
+    
+    // Our integration test bundle
+    protected Bundle bundle;
+    
+    protected ServiceTracker<ServiceComponentRuntime, ServiceComponentRuntime> 
scrTracker;
+
+    protected ServiceTracker<ConfigurationAdmin, ConfigurationAdmin> 
configAdminTracker;
+
+    // the name of the system property providing the bundle file to be 
installed and tested
+    protected static final String BUNDLE_JAR_SYS_PROP = "project.bundle.file";
+
+    // the default bundle jar file name
+    protected static final String BUNDLE_JAR_DEFAULT = "target/scr.jar";
+
+    protected static final String PROP_NAME = "theValue";
+    protected static final Hashtable<String, Object> theConfig = new 
Hashtable<>();
+
+    // the JVM option to set to enable remote debugging
+    protected static final String DEBUG_VM_OPTION = 
"-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=30303";
+
+    // the actual JVM option set, extensions may implement a static
+    // initializer overwriting this value to have the configuration()
+    // method include it when starting the OSGi framework JVM
+    protected static String paxRunnerVmOption = null;
+
+    protected String DS_LOGLEVEL = "warn";
+
+    protected static String bsnVersionUniqueness = "single";
+
+    // the descriptor file to use for the installed test bundle
+    protected String descriptorFile = 
"/resource/integration_test_simple_components.xml";
+    protected String COMPONENT_PACKAGE = 
"org.apache.felix.scr.integration.components";
+
+
+    protected static boolean NONSTANDARD_COMPONENT_FACTORY_BEHAVIOR = false;
+    protected volatile Log log;
+
+    private ServiceRegistration<?> logService;
+
+    private final Set<ServiceReference> existingServices = new HashSet<>();
+    private final Set<Configuration> existingConfigurations = new HashSet<>();
+
+       protected String[] ignoredWarnings; //null unless you need it.
+
+    //set to true to only get last 1000 lines of log.
+    protected boolean restrictedLogging;
+
+    protected static String felixCaVersion = System.getProperty( 
"felix.ca.version" );
+
+    protected static final String PROP_NAME_FACTORY = 
ComponentTestBase.PROP_NAME + ".factory";
+
+
+    public ComponentTestBase()
+    {
+        // Will use by default this.descriptorFile and this.COMPONENT_PACKAGE
+    }
+
+    public ComponentTestBase(String descriptorFile) 
+    {
+        this.descriptorFile = descriptorFile;
+        // Will use by default this.COMPONENT_PACKAGE
+    }
+
+    public ComponentTestBase(String descriptorFile, String componentPackage)
+    {
+        this.descriptorFile = descriptorFile;
+        this.COMPONENT_PACKAGE = COMPONENT_PACKAGE + "." + componentPackage;
+    }
+
+    @Before
+    public void setUp() throws BundleException, IOException
+    {
+        bundleContext = 
FrameworkUtil.getBundle(this.getClass()).getBundleContext();
+        init();
+
+        log = new Log(restrictedLogging, ignoredWarnings);
+        log.start();
+        bundleContext.addFrameworkListener( log );
+        logService = bundleContext.registerService( 
LogService.class.getName(), log, null );
+
+        scrTracker = new ServiceTracker<ServiceComponentRuntime, 
ServiceComponentRuntime>( bundleContext, ServiceComponentRuntime.class, null );
+        scrTracker.open();
+        configAdminTracker = new ServiceTracker<ConfigurationAdmin, 
ConfigurationAdmin>( bundleContext, ConfigurationAdmin.class, null );
+        configAdminTracker.open();
+        
+        out.println("Running " + getClass().getName() + "." + super.getName());
+        bundle = installBundle( descriptorFile, COMPONENT_PACKAGE );
+        bundle.start();
+
+        recordExistingConfigurations();
+    }
+
+
+    @After
+    public void tearDown() throws BundleException, InterruptedException
+    {
+        boolean foundWarnings = false;
+        try
+        {
+            // Check if the bundle has cleaned of configuration it may have 
created.
+            checkConfigurationCleaned();
+
+            if ( bundle != null && bundle.getState() != Bundle.UNINSTALLED )
+            {
+                bundle.stop();
+                bundle.uninstall();
+                bundle = null;
+            }
+            
+            Bundle scrBundle = scrTracker.getServiceReference().getBundle();
+            scrBundle.stop();
+            scrBundle.start();
+
+            configAdminTracker.close();
+            configAdminTracker = null;
+            scrTracker.close();
+            scrTracker = null;
+            logService.unregister();
+            bundleContext.removeFrameworkListener( log );
+        }
+        finally
+        {
+            foundWarnings = log.stop();
+        }
+        
+        if (foundWarnings)
+        {
+            TestCase.fail("Test failed (see previous warnings).");
+        }        
+
+    }
+
+    protected Collection<ComponentDescriptionDTO> getComponentDescriptions()
+    {
+        ServiceComponentRuntime scr = scrTracker.getService();
+        if ( scr == null )
+        {
+               TestCase.fail("no ServiceComponentRuntime");
+        }
+            return scr.getComponentDescriptionDTOs();
+    }
+
+
+    protected ComponentDescriptionDTO findComponentDescriptorByName( String 
name )
+    {
+        ServiceComponentRuntime scr = scrTracker.getService();
+        if ( scr == null )
+        {
+               TestCase.fail("no ServiceComponentRuntime");
+        }
+            return scr.getComponentDescriptionDTO(bundle, name);
+    }
+
+
+    protected Collection<ComponentConfigurationDTO> 
findComponentConfigurationsByName( Bundle b, String name, int expected )
+    {
+        ServiceComponentRuntime scr = scrTracker.getService();
+        if ( scr == null )
+        {
+               TestCase.fail("no ServiceComponentRuntime");
+        }
+        ComponentDescriptionDTO cd = scr.getComponentDescriptionDTO(b, name);
+        Collection<ComponentConfigurationDTO> ccs = 
scr.getComponentConfigurationDTOs(cd);
+        if (expected != -1)
+        {
+               for (ComponentConfigurationDTO cc: ccs)
+               {
+                       Assert.assertEquals( "for ComponentConfiguration name: 
" + cc.description.name + " properties" + cc.properties + "Expected state " + 
STATES.get(expected) + " but was " + STATES.get(cc.state), expected, cc.state);
+               }
+        }
+        return ccs;
+    }
+
+    protected Collection<ComponentConfigurationDTO> 
findComponentConfigurationsByName( String name, int expected )
+    {
+       return findComponentConfigurationsByName(bundle, name, expected);
+    }
+
+    protected ComponentConfigurationDTO findComponentConfigurationByName( 
Bundle b, String name, int expected )
+    {
+       Collection<ComponentConfigurationDTO> ccs = 
findComponentConfigurationsByName( b, name, expected);
+       Assert.assertEquals(1, ccs.size());
+       return ccs.iterator().next();
+    }
+
+    protected ComponentConfigurationDTO findComponentConfigurationByName( 
String name, int expected )
+    {
+       return findComponentConfigurationByName( bundle, name, expected );
+    }
+
+    static final Map<Integer, String> STATES = new HashMap<Integer, String>();
+
+    static {
+       STATES.put(ComponentConfigurationDTO.UNSATISFIED_REFERENCE, 
"Unsatisfied (" + ComponentConfigurationDTO.UNSATISFIED_REFERENCE + ")" );
+       STATES.put(ComponentConfigurationDTO.SATISFIED, "Satisified (" + 
ComponentConfigurationDTO.SATISFIED + ")" );
+       STATES.put(ComponentConfigurationDTO.ACTIVE, "Active (" + 
ComponentConfigurationDTO.ACTIVE + ")" );
+    }
+
+    protected ComponentConfigurationDTO getDisabledConfigurationAndEnable( 
Bundle b, String name, int initialState ) throws InvocationTargetException, 
InterruptedException
+    {
+       int count = 1;
+        Collection<ComponentConfigurationDTO> ccs = 
getConfigurationsDisabledThenEnable(
+                               b, name, count, initialState);
+               ComponentConfigurationDTO cc = ccs.iterator().next();
+       return cc;
+    }
+
+    protected ComponentConfigurationDTO getDisabledConfigurationAndEnable( 
String name, int initialState ) throws InvocationTargetException, 
InterruptedException
+    {
+       return getDisabledConfigurationAndEnable( bundle, name, initialState );
+    }
+
+    protected Collection<ComponentConfigurationDTO> 
getConfigurationsDisabledThenEnable( Bundle b, String name, int count, int 
initialState) throws InvocationTargetException, InterruptedException
+    {
+               ServiceComponentRuntime scr = scrTracker.getService();
+        if ( scr == null )
+        {
+               TestCase.fail("no ServiceComponentRuntime");
+        }
+       ComponentDescriptionDTO cd = scr.getComponentDescriptionDTO(b, name);
+       Assert.assertFalse("Expected component disabled", 
scr.isComponentEnabled(cd));
+       scr.enableComponent(cd).getValue();
+       Assert.assertTrue("Expected component enabled", 
scr.isComponentEnabled(cd));
+
+       Collection<ComponentConfigurationDTO> ccs = 
scr.getComponentConfigurationDTOs(cd);
+       Assert.assertEquals(count, ccs.size());
+       for (ComponentConfigurationDTO cc: ccs) {
+                       Assert.assertEquals("Expected state " + 
STATES.get(initialState)
+                                       + " but was " + STATES.get(cc.state), 
initialState,
+                                       cc.state);
+               }
+               return ccs;
+       }
+
+    protected Collection<ComponentConfigurationDTO> 
getConfigurationsDisabledThenEnable( String name, int count, int initialState) 
throws InvocationTargetException, InterruptedException
+    {
+       return getConfigurationsDisabledThenEnable(bundle, name, count, 
initialState);
+    }
+
+    protected ComponentDescriptionDTO checkConfigurationCount( Bundle b, 
String name, int count, int expectedState )
+    {
+       ServiceComponentRuntime scr = scrTracker.getService();
+       if ( scr == null )
+       {
+               TestCase.fail("no ServiceComponentRuntime");
+       }
+       ComponentDescriptionDTO cd = scr.getComponentDescriptionDTO(b, name);
+       Assert.assertTrue("Expected component enabled", 
scr.isComponentEnabled(cd));
+
+       Collection<ComponentConfigurationDTO> ccs = 
scr.getComponentConfigurationDTOs(cd);
+       Assert.assertEquals(count, ccs.size());
+       if (expectedState != -1)
+       {
+               for (ComponentConfigurationDTO cc: ccs)
+               {
+                       Assert.assertEquals("Expected state " + 
STATES.get(expectedState)
+                                       + " but was " + STATES.get(cc.state), 
expectedState,
+                                       cc.state);
+               }
+       }
+       return cd;
+    }
+
+    protected ComponentDescriptionDTO checkConfigurationCount( String name, 
int count, int expectedState )
+    {
+       return checkConfigurationCount(bundle, name, count, expectedState);
+    }
+
+    protected <S> S getServiceFromConfiguration( ComponentConfigurationDTO 
dto, Class<S> clazz )
+    {
+        long id = dto.id;
+        String filter = "(component.id=" + id + ")";
+        Collection<ServiceReference<S>> srs;
+        try {
+            srs = bundleContext.getServiceReferences(clazz, filter);
+            Assert.assertEquals(1, srs.size());
+            ServiceReference<S> sr = srs.iterator().next();
+            S s = bundleContext.getService(sr);
+            Assert.assertNotNull(s);
+            return s;
+        } catch (InvalidSyntaxException e) {
+            TestCase.fail(e.getMessage());
+            return null;//unreachable in fact
+        }
+    }
+    
+    protected <S> void ungetServiceFromConfiguration( 
ComponentConfigurationDTO dto, Class<S> clazz )
+    {
+        long id = dto.id;
+        String filter = "(component.id=" + id + ")";
+        Collection<ServiceReference<S>> srs;
+        try {
+            srs = bundleContext.getServiceReferences(clazz, filter);
+            Assert.assertEquals(1, srs.size());
+            ServiceReference<S> sr = srs.iterator().next();
+            bundleContext.ungetService(sr);
+        } catch (InvalidSyntaxException e) {
+            TestCase.fail(e.getMessage());
+        }
+    }
+
+    
+    @SuppressWarnings({ "unchecked" })
+    protected <S> ServiceReference<S> findServiceByPid(BundleContext ctx, 
String type, String filter)
+    {
+        try
+        {
+            ServiceReference<S>[] refs = (ServiceReference<S>[]) 
ctx.getServiceReferences(type, filter);
+            return refs != null ? refs[0] : null;
+        }
+        catch (InvalidSyntaxException e)
+        {
+            throw new IllegalStateException("Could not get service using 
filter " + filter);
+        }        
+    }
+
+    protected void enableAndCheck( ComponentDescriptionDTO cd ) throws 
InvocationTargetException, InterruptedException
+    {
+        ServiceComponentRuntime scr = scrTracker.getService();
+        if ( scr != null )
+        {
+            scr.enableComponent(cd).getValue();
+               Assert.assertTrue("Expected component enabled", 
scr.isComponentEnabled(cd));
+        }
+        else
+        {
+               throw new NullPointerException("no ServiceComponentRuntime");
+        }
+
+    }
+
+       protected void disableAndCheck(ComponentDescriptionDTO cd) throws 
InvocationTargetException, InterruptedException {
+               ServiceComponentRuntime scr = scrTracker.getService();
+        if ( scr != null )
+        {
+               scr.disableComponent(cd).getValue();
+               Assert.assertFalse("Expected component disabled", 
scr.isComponentEnabled(cd));
+        }
+        else
+        {
+               throw new NullPointerException("no ServiceComponentRuntime");
+        }
+       }
+
+       protected void disableAndCheck(Collection<ComponentConfigurationDTO> 
confs) throws InvocationTargetException, InterruptedException {
+        if (confs != null) {
+            for (ComponentConfigurationDTO conf : confs) {
+                disableAndCheck(conf);
+            }
+        }
+    }
+
+    protected void disableAndCheck( ComponentConfigurationDTO cc ) throws 
InvocationTargetException, InterruptedException
+    {
+        ComponentDescriptionDTO cd = cc.description;
+        disableAndCheck(cd);
+    }
+
+       protected void disableAndCheck(String name) throws 
InvocationTargetException, InterruptedException {
+               ComponentDescriptionDTO cd = 
findComponentDescriptorByName(name);
+               disableAndCheck(cd);
+       }
+
+    protected static void delay()
+    {
+        delay(300);
+    }
+
+    protected static void delay(int millis)
+    {
+        try
+        {
+            Thread.sleep(millis);
+        }
+        catch (InterruptedException ie)
+        {
+        }
+    }
+
+
+    protected ConfigurationAdmin getConfigurationAdmin()
+    {
+        ConfigurationAdmin ca = configAdminTracker.getService();
+        if ( ca == null )
+        {
+            TestCase.fail( "Missing ConfigurationAdmin service" );
+        }
+        return ca;
+    }
+
+    protected org.osgi.service.cm.Configuration configure( String pid )
+    {
+        return configure( pid, null );
+
+    }
+
+    protected org.osgi.service.cm.Configuration configure( String pid, String 
bundleLocation )
+    {
+        return configure(pid, bundleLocation, theConfig);
+    }
+
+    protected org.osgi.service.cm.Configuration configure(String pid,
+        String bundleLocation, Dictionary<String, Object> props)
+    {
+        ConfigurationAdmin ca = getConfigurationAdmin();
+        try
+        {
+            org.osgi.service.cm.Configuration config = ca.getConfiguration( 
pid, null );
+            if (bundleLocation != null)
+            {
+                config.setBundleLocation( bundleLocation );
+            }
+            config.update( props );
+            return config;
+        }
+        catch ( IOException ioe )
+        {
+            TestCase.fail( "Failed updating configuration " + pid + ": " + 
ioe.toString() );
+        }
+        return null;
+    }
+
+
+    protected void deleteConfig( String pid )
+    {
+        ConfigurationAdmin ca = getConfigurationAdmin();
+        try
+        {
+            org.osgi.service.cm.Configuration config = ca.getConfiguration( 
pid );
+            config.delete();
+        }
+        catch ( IOException ioe )
+        {
+            TestCase.fail( "Failed deleting configuration " + pid + ": " + 
ioe.toString() );
+        }
+    }
+
+
+    protected String createFactoryConfiguration( String factoryPid )
+    {
+        ConfigurationAdmin ca = getConfigurationAdmin();
+        try
+        {
+            org.osgi.service.cm.Configuration config = 
ca.createFactoryConfiguration( factoryPid, null );
+            config.update( theConfig );
+            return config.getPid();
+        }
+        catch ( IOException ioe )
+        {
+            TestCase.fail( "Failed updating factory configuration " + 
factoryPid + ": " + ioe.toString() );
+            return null;
+        }
+    }
+
+
+    protected void deleteFactoryConfigurations( String factoryPid )
+    {
+        ConfigurationAdmin ca = getConfigurationAdmin();
+        try
+        {
+            final String filter = "(service.factoryPid=" + factoryPid + ")";
+            org.osgi.service.cm.Configuration[] configs = 
ca.listConfigurations( filter );
+            if ( configs != null )
+            {
+                for ( org.osgi.service.cm.Configuration configuration : 
configs )
+                {
+                    configuration.delete();
+                }
+            }
+        }
+        catch ( InvalidSyntaxException ise )
+        {
+            // unexpected
+        }
+        catch ( IOException ioe )
+        {
+            TestCase.fail( "Failed deleting configurations " + factoryPid + ": 
" + ioe.toString() );
+        }
+    }
+
+    //component factory test helper methods
+    protected ComponentFactory getComponentFactory(final String 
componentfactory)
+        throws InvalidSyntaxException
+    {
+        final ServiceReference[] refs = bundleContext.getServiceReferences( 
ComponentFactory.class.getName(), "("
+            + ComponentConstants.COMPONENT_FACTORY + "=" + componentfactory + 
")" );
+        TestCase.assertNotNull( refs );
+        TestCase.assertEquals( 1, refs.length );
+        final ComponentFactory factory = ( ComponentFactory ) 
bundleContext.getService( refs[0] );
+        TestCase.assertNotNull( factory );
+        return factory;
+    }
+
+
+    protected void checkFactory(final String componentfactory, boolean 
expectFactoryPresent)
+        throws InvalidSyntaxException
+    {
+        ServiceReference[] refs = bundleContext.getServiceReferences( 
ComponentFactory.class.getName(), "("
+            + ComponentConstants.COMPONENT_FACTORY + "=" + componentfactory + 
")" );
+        if ( expectFactoryPresent )
+        {
+            TestCase.assertNotNull( refs );
+            TestCase.assertEquals(1, refs.length);
+
+        }
+        else
+        {
+            TestCase.assertNull( refs );
+        }
+    }
+
+    protected ComponentInstance createFactoryComponentInstance(final String 
componentfactory)
+        throws InvalidSyntaxException
+    {
+        Hashtable<String, String> props = new Hashtable<String, String>();
+        props.put( PROP_NAME_FACTORY, PROP_NAME_FACTORY );
+
+        return createFactoryComponentInstance(componentfactory, props);
+    }
+
+
+    protected ComponentInstance createFactoryComponentInstance(
+        final String componentfactory, Hashtable<String, String> props)
+        throws InvalidSyntaxException
+    {
+        final ComponentFactory factory = getComponentFactory(componentfactory);
+
+        final ComponentInstance instance = factory.newInstance( props );
+        TestCase.assertNotNull( instance );
+
+        TestCase.assertNotNull( instance.getInstance() );
+        TestCase.assertEquals( SimpleComponent.INSTANCE, 
instance.getInstance() );
+        TestCase.assertEquals( PROP_NAME_FACTORY, 
SimpleComponent.INSTANCE.getProperty( PROP_NAME_FACTORY ) );
+        return instance;
+    }
+
+
+
+
+    protected static Class<?> getType( Object object, String desiredName )
+    {
+        Class<?> ccImpl = object.getClass();
+        while ( ccImpl != null && !desiredName.equals( ccImpl.getSimpleName() 
) )
+        {
+            ccImpl = ccImpl.getSuperclass();
+        }
+        if ( ccImpl == null )
+        {
+            TestCase.fail( "ComponentContext " + object + " is not a " + 
desiredName );
+        }
+
+        return ccImpl;
+    }
+
+
+    protected static Object getFieldValue( Object object, String fieldName )
+    {
+        try
+        {
+            final Field m_componentsField = getField( object.getClass(), 
fieldName );
+            return m_componentsField.get( object );
+        }
+        catch ( Throwable t )
+        {
+            TestCase.fail( "Cannot get " + fieldName + " from " + object + ": 
" + t );
+            return null; // keep the compiler happy
+        }
+    }
+
+    protected Object getComponentManagerFromComponentInstance( Object instance 
)
+    {
+        Object cc = getFieldValue( instance, "m_componentContext");
+        return getFieldValue( cc, "m_componentManager" );
+    }
+
+
+    protected static Field getField( Class<?> type, String fieldName ) throws 
NoSuchFieldException
+    {
+        Class<?> clazz = type;
+        while (clazz != null)
+        {
+            Field[] fields = clazz.getDeclaredFields();
+            for (int i = 0; i < fields.length; i++)
+            {
+                Field field = fields[i];
+                if (field.getName().equals(fieldName))
+                {
+                    field.setAccessible( true );
+                    return field;
+                }
+            }
+            clazz = clazz.getSuperclass();
+        }
+        throw new NoSuchFieldException(fieldName);
+    }
+
+    protected Bundle installBundle( final String descriptorFile, String 
componentPackage ) throws BundleException, IOException
+    {
+        return installBundle(descriptorFile, componentPackage, 
"simplecomponent", "0.0.11", null);
+    }
+
+    protected Bundle installBundle( final String descriptorFile, String 
componentPackage, String symbolicName, String version, String location ) throws 
BundleException, IOException
+    {
+        BundleGenerator generator = new BundleGenerator();
+                
+        try(InputStream bundleStream =         
+             generator
+                .add("OSGI-INF/components.xml", 
bundleContext.getBundle().getEntry(descriptorFile))
+                .set(Constants.BUNDLE_SYMBOLICNAME, symbolicName)
+                .set(Constants.BUNDLE_VERSION, version)
+                .set(Constants.IMPORT_PACKAGE, componentPackage)
+                .set("Service-Component", "OSGI-INF/components.xml")
+                .set(Constants.REQUIRE_CAPABILITY, 
ExtenderNamespace.EXTENDER_NAMESPACE + 
";filter:=\"(&(osgi.extender=osgi.component)(version>=1.3)(!(version>=2.0)))\"")
+                .buildWithBnd()) {
+
+            if ( location == null )
+            {
+                location = "test:SimpleComponent/" + 
System.currentTimeMillis();
+            }
+            return bundleContext.installBundle( location, bundleStream );
+        }
+    }
+
+    protected boolean isAtLeastR5()
+    {
+        try
+        {
+            Method m = 
org.osgi.service.cm.Configuration.class.getDeclaredMethod( "getChangeCount");
+            return true;
+        }
+        catch ( SecurityException e )
+        {
+            throw new RuntimeException(e);
+        }
+        catch ( NoSuchMethodException e )
+        {
+            return false;
+        }
+    }
+    
+    /**
+     * Reset some integration test components and some configurations before 
running a test.
+     */
+    private void init() {
+        theConfig.clear();
+        theConfig.put( PROP_NAME, PROP_NAME );
+        SimpleComponent.INSTANCES.clear();
+        SimpleComponent.PREVIOUS_INSTANCES.clear();  
+        Felix4350Component.init();
+    }
+    
+    /**
+     * Record all existing services and configuration.
+     */
+    protected void recordExistingConfigurations() {
+        Configuration[] confs = getAllConfigurations();
+        existingConfigurations.addAll(Arrays.asList(confs));        
+    }
+
+    private Configuration[] getAllConfigurations() {
+        ConfigurationAdmin ca = getConfigurationAdmin();
+        try
+        {
+            Configuration[] confs = ca.listConfigurations( null );
+            return confs == null ? new Configuration[0] : confs;
+        }
+        catch ( Throwable ignored )
+        {
+            return null;
+        }
+    }
+
+    /**
+     * Check if the test has removed all its resources (services, 
configurations).
+     */
+    private void checkConfigurationCleaned() {
+        Configuration[] confs = getAllConfigurations();
+        for (Configuration conf : confs) {
+            if (! existingConfigurations.contains(conf)) {
+                log.log(LogService.LOG_ERROR, "Tested ended but did not 
unregister " + conf);
+                Assert.fail("Tested ended but did not unregister configuration 
" + conf);
+            }
+        }
+        
+        existingServices.clear();
+        existingConfigurations.clear();
+    }
+    
+    public static class LogEntry
+    {
+        private final String m_msg;
+        private final int m_level;
+        private final Throwable m_err;
+        private final long m_time;
+        private final Thread m_thread;
+
+
+        LogEntry( int level, String msg, Throwable t )
+        {
+            m_level = level;
+            m_msg = msg;
+            m_err = t;
+            m_time = System.currentTimeMillis();
+            m_thread = Thread.currentThread();
+        }
+
+
+        @Override
+        public String toString()
+        {
+            return m_msg;
+        }
+
+
+        public int getLevel()
+        {
+            return m_level;
+        }
+
+
+        public String getMessage()
+        {
+            return m_msg;
+        }
+
+
+        public Throwable getError()
+        {
+            return m_err;
+        }
+
+
+        public long getTime()
+        {
+            return m_time;
+        }
+
+
+        public Thread getThread()
+        {
+            return m_thread;
+        }
+    }
+
+    public class Log implements LogService, FrameworkListener, Runnable
+    {
+        private static final int RESTRICTED_LOG_SIZE = 1000;
+        private final SimpleDateFormat m_sdf = new SimpleDateFormat( 
"HH:mm:ss,S" );
+        private final PrintStream m_out = new PrintStream( new 
BufferedOutputStream( new FileOutputStream(
+            FileDescriptor.err ), 128 ) );
+        private final List<String> m_warnings = Collections.synchronizedList( 
new ArrayList<String>() );
+        private LinkedBlockingQueue<LogEntry> m_logQueue = new 
LinkedBlockingQueue<LogEntry>();
+        private volatile Thread m_logThread;
+        private String[] ignoredWarnings; // Format is : log message 
[:exception message]
+
+        protected Throwable firstFrameworkThrowable;
+
+        private final boolean restrictedLogging;
+        private final String[] log = new String[1000];
+        private int i = 0;
+
+        public Log( boolean restrictedLogging, String[] ignoredWarnings )
+        {
+            this.restrictedLogging = restrictedLogging;
+            this.ignoredWarnings = ignoredWarnings;
+        }
+
+        public void start()
+        {
+            m_logThread = new Thread( this );
+            m_logThread.start();
+        }
+
+
+        public boolean stop()
+        {
+            // Make sure logging threads is done.
+            m_logThread.interrupt();
+            try
+            {
+                m_logThread.join();
+            }
+            catch ( InterruptedException e )
+            {
+            }
+
+            if ( restrictedLogging )
+            {
+                for (int j = 0; j < RESTRICTED_LOG_SIZE; j++)
+                {
+                    if ( log[i] != null )
+                    {
+                        err.println(log[i]);
+                    }
+                    i ++;
+                    if (i == RESTRICTED_LOG_SIZE) 
+                    {
+                        i = 0;
+                    }                   
+                }
+            }
+            else
+            {
+                m_out.flush();
+            }
+            boolean foundWarning = m_warnings.size() > 0;
+            m_warnings.clear();
+            m_logThread.interrupt();
+            return foundWarning;
+        }
+
+
+        List<String> foundWarnings()
+        {
+            return m_warnings;
+        }
+
+        Throwable getFirstFrameworkThrowable()
+        {
+            return firstFrameworkThrowable;
+        }
+
+
+
+        public void run()
+        {
+            try
+            {
+                LogEntry entry = null;
+                while ( true )
+                {
+                    entry = m_logQueue.take();
+                    boolean acceptedWarning = false;
+                    if ( entry.getLevel() <= 2 )
+                    {
+                        if (acceptWarning( entry))
+                        {
+                            acceptedWarning = true;
+                            if ( m_warnings.size() < 1024 )
+                            {
+                                m_warnings.add( entry.getMessage() );
+                            }
+                            else
+                            {
+                                // Avoid out of memory ...
+                                m_warnings.set( 1023, "Unexpected errors 
logged. Please look at previous logs" );
+                            }
+                        }
+                    }
+
+                    StringWriter sw = new StringWriter();
+                    sw.append( "L=" + entry.getLevel() );
+                    sw.append( " D=" );
+                    sw.append( m_sdf.format( new Date( entry.getTime() ) ) );
+                    sw.append( " T=\"" + entry.getThread().getName() + "\"");
+                    sw.append((entry.getLevel() <= 2 && ! acceptedWarning) ? " 
(log expected)" : " (log Unexpected)");
+                    sw.append( ": " );
+                    sw.append( entry.getMessage() );
+                    if ( entry.getLevel() <= 2 && entry.getError() != null)
+                    {
+                        PrintWriter pw = new PrintWriter( sw );
+                        sw.append( System.getProperty( "line.separator" ) );
+                        if (acceptWarning(entry)) 
+                        {
+                            entry.getError().printStackTrace( pw );
+                        } 
+                        else 
+                        {
+                            pw.print(entry.getError().toString());
+                        }
+                        pw.flush();
+                    }
+                    // We really want to log to stdout warnings that are 
ignored by the test.
+                    if ( restrictedLogging && (entry.getLevel() <= 2 && 
acceptedWarning))
+                    {
+                        log[i++] = sw.toString();
+                        if ( i == RESTRICTED_LOG_SIZE ) i = 0;
+                    }
+                    else
+                    {
+                        m_out.println( sw.toString() );
+                        m_out.flush();
+                    }
+                }
+            }
+            catch ( InterruptedException e )
+            {
+                return;
+            }
+        }
+
+
+        // ------------- FrameworkListener 
-----------------------------------------------------------
+
+        private boolean acceptWarning(LogEntry entry) {
+               if ( ignoredWarnings != null )
+               {
+                               for (String ignore : ignoredWarnings) {
+                                   if (entry.getError() == null) {
+                                       if (entry.getMessage().matches(ignore)) 
{
+                                           return false;
+                                       }
+                                   } else {
+                                       String msg = entry.getMessage() + 
System.getProperty( "line.separator" ) + entry.getError().toString(); 
+                        if (msg.matches(ignore)) {
+                            return false;
+                        }
+                                   }
+                               }
+                       }
+                       return true;
+               }
+
+               public void frameworkEvent( final FrameworkEvent event )
+        {
+            int eventType = event.getType();
+            String msg = getFrameworkEventMessage( eventType );
+            int level = ( eventType == FrameworkEvent.ERROR ) ? 
LogService.LOG_ERROR : LogService.LOG_INFO;
+            log( level, msg, event.getThrowable() );
+            if (event.getThrowable() != null && firstFrameworkThrowable == 
null)
+            {
+                firstFrameworkThrowable = event.getThrowable();
+            }
+        }
+
+
+        // ------------ LogService 
----------------------------------------------------------------
+
+        public void log( int level, String message )
+        {
+            log( level, message, null );
+        }
+
+
+        public void log( int level, String message, Throwable exception )
+        {
+            if ( level > getEnabledLogLevel() )
+            {
+                return;
+            }
+            m_logQueue.offer( new LogEntry( level, message, exception ) );
+        }
+
+
+        public void log( ServiceReference sr, int osgiLevel, String message )
+        {
+            log( sr, osgiLevel, message, null );
+        }
+
+
+        public void log( ServiceReference sr, int level, String msg, Throwable 
exception )
+        {
+            if ( sr != null )
+            {
+                StringBuilder sb = new StringBuilder();
+                Object serviceId = sr.getProperty( Constants.SERVICE_ID );
+                if ( serviceId != null )
+                {
+                    sb.append( "[" + serviceId.toString() + "] " );
+                }
+                sb.append( msg );
+                log( level, sb.toString(), exception );
+            }
+            else
+            {
+                log( level, msg, exception );
+            }
+        }
+
+
+        private int getEnabledLogLevel()
+        {
+            if ( DS_LOGLEVEL.regionMatches( true, 0, "err", 0, "err".length() 
) )
+            {
+                return LogService.LOG_ERROR;
+            }
+            else if ( DS_LOGLEVEL.regionMatches( true, 0, "warn", 0, 
"warn".length() ) )
+            {
+                return LogService.LOG_WARNING;
+            }
+            else if ( DS_LOGLEVEL.regionMatches( true, 0, "info", 0, 
"info".length() ) )
+            {
+                return LogService.LOG_INFO;
+            }
+            else
+            {
+                return LogService.LOG_DEBUG;
+            }
+        }
+
+
+        private String getFrameworkEventMessage( int event )
+        {
+            switch ( event )
+            {
+                case FrameworkEvent.ERROR:
+                    return "FrameworkEvent: ERROR";
+                case FrameworkEvent.INFO:
+                    return "FrameworkEvent INFO";
+                case FrameworkEvent.PACKAGES_REFRESHED:
+                    return "FrameworkEvent: PACKAGE REFRESHED";
+                case FrameworkEvent.STARTED:
+                    return "FrameworkEvent: STARTED";
+                case FrameworkEvent.STARTLEVEL_CHANGED:
+                    return "FrameworkEvent: STARTLEVEL CHANGED";
+                case FrameworkEvent.WARNING:
+                    return "FrameworkEvent: WARNING";
+                default:
+                    return null;
+            }
+        }
+    }
+}


Reply via email to