FELIX-1825 Deactivate component instances of delayed components which
are not referenced any more

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@830970 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/ServiceComponentTest.java b/scr/src/test/java/org/apache/felix/scr/integration/ServiceComponentTest.java
index c5393c0..9f1c240 100644
--- a/scr/src/test/java/org/apache/felix/scr/integration/ServiceComponentTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/integration/ServiceComponentTest.java
@@ -26,6 +26,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 
 
@@ -84,4 +85,89 @@
                 && !propKey.startsWith( "." ) );
         }
     }
+
+
+    @Test
+    public void test_DelayedSimpleComponent_service_single_use()
+    {
+        final String pid = "DelayedServiceComponent";
+
+        // one single component exists without configuration
+        final Component component = findComponentByName( pid );
+        TestCase.assertNotNull( component );
+        TestCase.assertEquals( Component.STATE_DISABLED, component.getState() );
+
+        component.enable();
+        delay();
+
+        // the delayed service is expected to only be registered before use
+        TestCase.assertEquals( Component.STATE_REGISTERED, component.getState() );
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+
+        // get the service
+        ServiceReference reference = bundleContext.getServiceReference( "java.lang.Object" );
+        TestCase.assertNotNull( reference );
+        try
+        {
+            final Object theService = bundleContext.getService( reference );
+
+            // service must now be active
+            TestCase.assertEquals( Component.STATE_ACTIVE, component.getState() );
+
+            // and of course we expect the instance
+            TestCase.assertEquals( SimpleComponent.INSTANCE, theService );
+        }
+        finally
+        {
+            bundleContext.ungetService( reference );
+        }
+
+        // service is not used anymore, ensure REGISTERED state and INSTANCE==null
+        TestCase.assertEquals( Component.STATE_REGISTERED, component.getState() );
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+    }
+
+
+    @Test
+    public void test_DelayedSimpleComponent_service_multi_use()
+    {
+        final String pid = "DelayedServiceComponent";
+
+        // one single component exists without configuration
+        final Component component = findComponentByName( pid );
+        TestCase.assertNotNull( component );
+        TestCase.assertEquals( Component.STATE_DISABLED, component.getState() );
+
+        component.enable();
+        delay();
+
+        // the delayed service is expected to only be registered before use
+        TestCase.assertEquals( Component.STATE_REGISTERED, component.getState() );
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+
+        // get the service once
+        final ServiceReference reference1 = bundleContext.getServiceReference( "java.lang.Object" );
+        TestCase.assertNotNull( reference1 );
+        bundleContext.getService( reference1 );
+        TestCase.assertEquals( Component.STATE_ACTIVE, component.getState() );
+        TestCase.assertNotNull( SimpleComponent.INSTANCE );
+
+        // get the service a second time
+        final BundleContext bundleContext2 = bundle.getBundleContext();
+        final ServiceReference reference2 = bundleContext2.getServiceReference( "java.lang.Object" );
+        TestCase.assertNotNull( reference2 );
+        bundleContext2.getService( reference2 );
+        TestCase.assertEquals( Component.STATE_ACTIVE, component.getState() );
+        TestCase.assertNotNull( SimpleComponent.INSTANCE );
+
+        // unget the service once -- must still be active !
+        bundleContext2.ungetService( reference2 );
+        TestCase.assertEquals( Component.STATE_ACTIVE, component.getState() );
+        TestCase.assertNotNull( SimpleComponent.INSTANCE );
+
+        // unget the service second time -- must be registered and null now
+        bundleContext.ungetService( reference1 );
+        TestCase.assertEquals( Component.STATE_REGISTERED, component.getState() );
+        TestCase.assertNull( SimpleComponent.INSTANCE );
+    }
 }
diff --git a/scr/src/test/resources/integration_test_simple_components.xml b/scr/src/test/resources/integration_test_simple_components.xml
index dcca586..25e5c36 100644
--- a/scr/src/test/resources/integration_test_simple_components.xml
+++ b/scr/src/test/resources/integration_test_simple_components.xml
@@ -58,7 +58,7 @@
         <property name="service.pid" value="FactoryConfigurationComponent" />
     </scr:component>
 
-    <!-- component is a stupid service to verify non-use of private props -->
+    <!-- component is a simple service to verify non-use of private props -->
     <scr:component name="ServiceComponent"
         enabled="false" immediate="true"
         configuration-policy="ignore" >
@@ -71,6 +71,17 @@
         </service>
     </scr:component>
 
+    <!-- component is a simple service to verify deactivation when not being used any longer -->
+    <scr:component name="DelayedServiceComponent"
+        enabled="false" immediate="false"
+        configuration-policy="ignore" >
+        <implementation class="org.apache.felix.scr.integration.components.SimpleComponent" />
+        <property name="service.pid" value="ServiceComponent" />
+        <service>
+            <provide interface="java.lang.Object" />
+        </service>
+    </scr:component>
+
     <!-- Component Factory Instances -->
     <scr:component name="factory.component"
         enabled="false"