FELIX-3557 more circular ref tests, for b 0..1 to A

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1371290 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/CircularReferenceTest.java b/scr/src/test/java/org/apache/felix/scr/integration/CircularReferenceTest.java
index eabc57e..38e4d8d 100644
--- a/scr/src/test/java/org/apache/felix/scr/integration/CircularReferenceTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/integration/CircularReferenceTest.java
@@ -189,4 +189,125 @@
         assertEquals( 1, b1.getAs().size() );
 
     }
+    /**
+     * A > 1.1 > B > 0..1 > A Both should start (A first), but B should not have an A reference.
+     */
+    @Test
+    public void test_A11_B01_immediate_A_first()
+    {
+        String componentNameA = "5.A.1.1.dynamic";
+        final Component componentA = findComponentByName( componentNameA );
+        TestCase.assertNotNull( componentA );
+        TestCase.assertEquals( Component.STATE_ACTIVE, componentA.getState() );
+        A a = ( A ) componentA.getComponentInstance().getInstance();
+        assertEquals( 1, a.getBs().size());
+
+        String componentNameB = "5.B.0.1.dynamic";
+        final Component componentB = findComponentByName( componentNameB );
+        TestCase.assertNotNull( componentB );
+        TestCase.assertEquals( Component.STATE_ACTIVE, componentB.getState() );
+        B b = ( B ) componentB.getComponentInstance().getInstance();
+        assertEquals( 0, b.getAs().size() );
+    }
+    /**
+     * A > 1.1 > B > 0..1 > A Both should start (B first), and B should have an A reference.
+     */
+    @Test
+    public void test_A11_B01_immediate_B_first()
+    {
+        String componentNameA = "6.A.1.1.dynamic";
+        final Component componentA = findComponentByName( componentNameA );
+        TestCase.assertNotNull( componentA );
+        TestCase.assertEquals( Component.STATE_ACTIVE, componentA.getState() );
+        A a = ( A ) componentA.getComponentInstance().getInstance();
+        assertEquals( 1, a.getBs().size());
+
+        String componentNameB = "6.B.0.1.dynamic";
+        final Component componentB = findComponentByName( componentNameB );
+        TestCase.assertNotNull( componentB );
+        TestCase.assertEquals( Component.STATE_ACTIVE, componentB.getState() );
+        B b = ( B ) componentB.getComponentInstance().getInstance();
+        assertEquals( 1, b.getAs().size() );
+    }
+    /**
+     * A > 1.1 > B > 0..1 > A Both should start, but B should not have an A reference.
+     */
+    @Test
+    public void test_A11_B01_delayed_A_first() throws InvalidSyntaxException
+    {
+        String componentNameA = "7.A.1.1.dynamic";
+        final Component componentA = findComponentByName( componentNameA );
+        TestCase.assertNotNull( componentA );
+        TestCase.assertEquals( Component.STATE_REGISTERED, componentA.getState() );
+
+        String componentNameB = "7.B.0.1.dynamic";
+        final Component componentB = findComponentByName( componentNameB );
+        TestCase.assertNotNull( componentB );
+        TestCase.assertEquals( Component.STATE_REGISTERED, componentB.getState() );
+
+        ServiceReference[] serviceReferences = bundleContext.getServiceReferences( A.class.getName(), "(service.pid=" + componentNameA + ")" );
+        TestCase.assertEquals( 1, serviceReferences.length );
+        ServiceReference serviceReference = serviceReferences[0];
+        Object service = bundleContext.getService( serviceReference );
+        assertNotNull( service );
+
+
+        A a = ( A ) componentA.getComponentInstance().getInstance();
+        assertEquals( 1, a.getBs().size() );
+        B b = ( B ) componentB.getComponentInstance().getInstance();
+        assertEquals( 0, b.getAs().size() );
+    }
+    /**
+     * A > 1.1 > B > 0..1 > A Both should start, but B should not have an A reference.
+     */
+    @Test
+    public void test_A11_B01_delayed_B_first() throws InvalidSyntaxException
+    {
+        String componentNameA = "7.A.1.1.dynamic";
+        final Component componentA = findComponentByName( componentNameA );
+        TestCase.assertNotNull( componentA );
+        TestCase.assertEquals( Component.STATE_REGISTERED, componentA.getState() );
+
+        String componentNameB = "7.B.0.1.dynamic";
+        final Component componentB = findComponentByName( componentNameB );
+        TestCase.assertNotNull( componentB );
+        TestCase.assertEquals( Component.STATE_REGISTERED, componentB.getState() );
+
+        ServiceReference[] serviceReferencesB = bundleContext.getServiceReferences( B.class.getName(), "(service.pid=" + componentNameB + ")" );
+        TestCase.assertEquals( 1, serviceReferencesB.length );
+        ServiceReference serviceReferenceB = serviceReferencesB[0];
+        Object serviceB = bundleContext.getService( serviceReferenceB );
+        assertNotNull( serviceB );
+
+        ServiceReference[] serviceReferencesA = bundleContext.getServiceReferences( A.class.getName(), "(service.pid=" + componentNameA + ")" );
+        TestCase.assertEquals( 1, serviceReferencesA.length );
+        ServiceReference serviceReferenceA = serviceReferencesA[0];
+        Object serviceA = bundleContext.getService( serviceReferenceA );
+        assertNotNull( serviceA );
+
+
+        A a = ( A ) componentA.getComponentInstance().getInstance();
+        assertEquals( 1, a.getBs().size() );
+        B b = ( B ) componentB.getComponentInstance().getInstance();
+        assertEquals( 0, b.getAs().size() );
+
+
+        //disabling (removing the A service registration) and re-enabling will
+        //result in a service event to B, so B will bind A.
+        componentA.disable();
+        delay();
+        componentA.enable();
+        delay();
+        ServiceReference[] serviceReferencesA1 = bundleContext.getServiceReferences( A.class.getName(), "(service.pid=" + componentNameA + ")" );
+        TestCase.assertEquals( 1, serviceReferencesA1.length );
+        ServiceReference serviceReferenceA1 = serviceReferencesA1[0];
+        Object serviceA1 = bundleContext.getService( serviceReferenceA1 );
+        assertNotNull( serviceA1 );
+
+        A a1 = ( A ) componentA.getComponentInstance().getInstance();
+        assertEquals( 1, a1.getBs().size() );
+        B b1 = ( B ) componentB.getComponentInstance().getInstance();
+        assertEquals( 1, b1.getAs().size() );
+
+    }
 }
diff --git a/scr/src/test/resources/integration_test_circular.xml b/scr/src/test/resources/integration_test_circular.xml
index 2a408c8..280182e 100644
--- a/scr/src/test/resources/integration_test_circular.xml
+++ b/scr/src/test/resources/integration_test_circular.xml
@@ -178,4 +178,125 @@
     </scr:component>
 
 
+    <!-- A 1.1 dynamic. B 0..1 dynamic  both immediate.  Both should start (A first) and B should have no reference to A -->
+    <scr:component name="5.A.1.1.dynamic"
+        enabled="true"
+        immediate="true"
+        configuration-policy="ignore">
+        <implementation class="org.apache.felix.scr.integration.components.circular.A" />
+        <service>
+            <provide interface="org.apache.felix.scr.integration.components.circular.A" />
+        </service>
+        <reference
+            name="b"
+            interface="org.apache.felix.scr.integration.components.circular.B"
+            cardinality="1..1"
+            policy="dynamic"
+            bind="setB"
+            unbind="unsetB"
+            target="(service.pid=5.B.0.1.dynamic)"
+        />
+        <property name="service.pid" value="5.A.1.1.dynamic" />
+    </scr:component>
+    <scr:component name="5.B.0.1.dynamic"
+        enabled="true"
+        immediate="true"
+        configuration-policy="ignore">
+        <implementation class="org.apache.felix.scr.integration.components.circular.B" />
+        <service>
+            <provide interface="org.apache.felix.scr.integration.components.circular.B" />
+        </service>
+        <reference
+            name="a"
+            interface="org.apache.felix.scr.integration.components.circular.A"
+            cardinality="0..1"
+            policy="dynamic"
+            bind="setA"
+            unbind="unsetA"
+            target="(service.pid=5.A.1.1.dynamic)"
+        />
+        <property name="service.pid" value="5.B.0.1.dynamic" />
+    </scr:component>
+
+    <!-- A 1.1 dynamic. B 0..1 dynamic  both immediate.  Both should start (B first) and B should have a reference to A -->
+    <scr:component name="6.B.0.1.dynamic"
+        enabled="true"
+        immediate="true"
+        configuration-policy="ignore">
+        <implementation class="org.apache.felix.scr.integration.components.circular.B" />
+        <service>
+            <provide interface="org.apache.felix.scr.integration.components.circular.B" />
+        </service>
+        <reference
+            name="a"
+            interface="org.apache.felix.scr.integration.components.circular.A"
+            cardinality="0..1"
+            policy="dynamic"
+            bind="setA"
+            unbind="unsetA"
+            target="(service.pid=6.A.1.1.dynamic)"
+        />
+        <property name="service.pid" value="6.B.0.1.dynamic" />
+    </scr:component>
+    <scr:component name="6.A.1.1.dynamic"
+        enabled="true"
+        immediate="true"
+        configuration-policy="ignore">
+        <implementation class="org.apache.felix.scr.integration.components.circular.A" />
+        <service>
+            <provide interface="org.apache.felix.scr.integration.components.circular.A" />
+        </service>
+        <reference
+            name="b"
+            interface="org.apache.felix.scr.integration.components.circular.B"
+            cardinality="1..1"
+            policy="dynamic"
+            bind="setB"
+            unbind="unsetB"
+            target="(service.pid=6.B.0.1.dynamic)"
+        />
+        <property name="service.pid" value="6.A.1.1.dynamic" />
+    </scr:component>
+
+    <!-- A 1.1 dynamic. B 0..1 dynamic  both delayed.  Both should start and B should have no reference to A -->
+    <scr:component name="7.A.1.1.dynamic"
+        enabled="true"
+        immediate="false"
+        configuration-policy="ignore">
+        <implementation class="org.apache.felix.scr.integration.components.circular.A" />
+        <service>
+            <provide interface="org.apache.felix.scr.integration.components.circular.A" />
+        </service>
+        <reference
+            name="b"
+            interface="org.apache.felix.scr.integration.components.circular.B"
+            cardinality="1..1"
+            policy="dynamic"
+            bind="setB"
+            unbind="unsetB"
+            target="(service.pid=7.B.0.1.dynamic)"
+        />
+        <property name="service.pid" value="7.A.1.1.dynamic" />
+    </scr:component>
+    <scr:component name="7.B.0.1.dynamic"
+        enabled="true"
+        immediate="false"
+        configuration-policy="ignore">
+        <implementation class="org.apache.felix.scr.integration.components.circular.B" />
+        <service>
+            <provide interface="org.apache.felix.scr.integration.components.circular.B" />
+        </service>
+        <reference
+            name="a"
+            interface="org.apache.felix.scr.integration.components.circular.A"
+            cardinality="0..1"
+            policy="dynamic"
+            bind="setA"
+            unbind="unsetA"
+            target="(service.pid=7.A.1.1.dynamic)"
+        />
+        <property name="service.pid" value="7.B.0.1.dynamic" />
+    </scr:component>
+
+
 </components>