[FELIX-4188] Add an integration test

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1509795 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/Felix4188Test.java b/scr/src/test/java/org/apache/felix/scr/integration/Felix4188Test.java
new file mode 100644
index 0000000..6f111ba
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/integration/Felix4188Test.java
@@ -0,0 +1,146 @@
+/*
+ * 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.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.util.concurrent.CountDownLatch;
+
+import javax.inject.Inject;
+
+import junit.framework.TestCase;
+import org.apache.felix.scr.Component;
+import org.apache.felix.scr.integration.components.felix4188.Felix4188Component;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+
+import static org.ops4j.pax.tinybundles.core.TinyBundles.bundle;
+import static org.ops4j.pax.tinybundles.core.TinyBundles.withBnd;
+
+/**
+ * This test validates the FELIX-4188 issue.
+ */
+@RunWith(JUnit4TestRunner.class)
+public class Felix4188Test extends ComponentTestBase
+{
+
+    static
+    {
+        // uncomment to enable debugging of this test class
+        //        paxRunnerVmOption = DEBUG_VM_OPTION;
+        descriptorFile = "/integration_test_FELIX_4188.xml";
+        restrictedLogging = true;
+        //comment to get debug logging if the test fails.
+//        DS_LOGLEVEL = "warn";
+    }
+
+    @Inject
+    protected BundleContext bundleContext;
+
+    @Test
+    public void test_concurrent_deactivation() throws Exception
+    {
+        final Bundle bundle1 = installBundle("/integration_test_FELIX_4188_1.xml", "", "simplecomponent1");
+        bundle1.start();
+
+        final Bundle bundle2 = installBundle("/integration_test_FELIX_4188_2.xml", "", "simplecomponent2");
+        bundle2.start();
+
+        final Component aComp1 =
+                findComponentByName("org.apache.felix.scr.integration.components.Felix4188Component-1");
+        aComp1.enable();
+        final Object aInst1 = aComp1.getComponentInstance().getInstance();
+
+        final Component aComp2 =
+                findComponentByName("org.apache.felix.scr.integration.components.Felix4188Component-2");
+        aComp2.enable();
+        final Object aInst2 = aComp2.getComponentInstance().getInstance();
+
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        new Thread() {
+            public void run() {
+                Bundle scrBundle = scrTracker.getServiceReference().getBundle();
+                try {
+                    scrBundle.stop();
+                } catch (Throwable t) {
+                    t.printStackTrace();
+                } finally {
+                    latch.countDown();
+                }
+            }
+        }.start();
+        Thread.sleep(100);
+        long t0 = System.currentTimeMillis();
+        bundle1.stop();
+        bundle2.stop();
+        long t1 = System.currentTimeMillis();
+        TestCase.assertTrue(t1 - t0 > 1000);  // It should have taken more than a second
+
+        TestCase.assertNull(getField(aInst1, "throwable"));
+        TestCase.assertNull(getField(aInst2, "throwable"));
+
+        latch.await();
+
+        TestCase.assertNull(getField(aInst1, "throwable"));
+        TestCase.assertNull(getField(aInst2, "throwable"));
+    }
+
+    private Object getField(Object instance, String name) throws Exception {
+        Field field = instance.getClass().getField(name);
+        field.setAccessible(true);
+        return field.get(instance);
+    }
+
+    protected Bundle installBundle( final String descriptorFile, String componentPackage, String symbolicname ) throws BundleException
+    {
+        final InputStream bundleStream = bundle()
+                .add("OSGI-INF/components.xml", getClass().getResource(descriptorFile))
+                .add(Felix4188Component.class)
+
+                .set(Constants.BUNDLE_SYMBOLICNAME, symbolicname)
+                .set(Constants.BUNDLE_VERSION, "0.0.11")
+                .set(Constants.IMPORT_PACKAGE, componentPackage)
+                .set("Service-Component", "OSGI-INF/components.xml")
+                .build(withBnd());
+
+        try
+        {
+            final String location = "test:SimpleComponent/" + System.currentTimeMillis();
+            return bundleContext.installBundle( location, bundleStream );
+        }
+        finally
+        {
+            try
+            {
+                bundleStream.close();
+            }
+            catch ( IOException ioe )
+            {
+            }
+        }
+    }
+
+}
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/components/Felix4188Component.java b/scr/src/test/java/org/apache/felix/scr/integration/components/Felix4188Component.java
new file mode 100644
index 0000000..89bbc78
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/integration/components/Felix4188Component.java
@@ -0,0 +1,44 @@
+/*
+ * 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.components;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+
+public class Felix4188Component {
+
+    public BundleContext bundleContext;
+    public Throwable throwable;
+
+    void start()
+    {
+        bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
+    }
+
+    void stop()
+    {
+        try {
+            Thread.sleep(2000);
+            bundleContext.getBundle();
+        } catch (Throwable t) {
+            throwable = t;
+        }
+    }
+
+}
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/components/felix4188/Felix4188Component.java b/scr/src/test/java/org/apache/felix/scr/integration/components/felix4188/Felix4188Component.java
new file mode 100644
index 0000000..259568a
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/integration/components/felix4188/Felix4188Component.java
@@ -0,0 +1,46 @@
+/*
+ * 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.components.felix4188;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+
+public class Felix4188Component {
+
+    public Bundle bundle;
+    public Throwable throwable;
+    public int state;
+
+    void start()
+    {
+        bundle = FrameworkUtil.getBundle(getClass());
+    }
+
+    void stop()
+    {
+        try {
+            Thread.sleep(2000);
+            state = bundle.getState();
+            bundle.getBundleContext().getBundle();
+        } catch (Throwable t) {
+            throwable = t;
+        }
+    }
+
+}
diff --git a/scr/src/test/resources/integration_test_FELIX_4188.xml b/scr/src/test/resources/integration_test_FELIX_4188.xml
new file mode 100644
index 0000000..84c7168
--- /dev/null
+++ b/scr/src/test/resources/integration_test_FELIX_4188.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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. -->
+<components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
+</components>
diff --git a/scr/src/test/resources/integration_test_FELIX_4188_1.xml b/scr/src/test/resources/integration_test_FELIX_4188_1.xml
new file mode 100644
index 0000000..aa69698
--- /dev/null
+++ b/scr/src/test/resources/integration_test_FELIX_4188_1.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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. -->
+<components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
+	<scr:component xmlns:scr='http://www.osgi.org/xmlns/scr/v1.1.0'
+		name='org.apache.felix.scr.integration.components.Felix4188Component-1' activate='start' deactivate='stop'>
+        <implementation class="org.apache.felix.scr.integration.components.felix4188.Felix4188Component" />
+	</scr:component>
+</components>
diff --git a/scr/src/test/resources/integration_test_FELIX_4188_2.xml b/scr/src/test/resources/integration_test_FELIX_4188_2.xml
new file mode 100644
index 0000000..99eec1d
--- /dev/null
+++ b/scr/src/test/resources/integration_test_FELIX_4188_2.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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. -->
+<components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
+	<scr:component xmlns:scr='http://www.osgi.org/xmlns/scr/v1.1.0'
+		name='org.apache.felix.scr.integration.components.Felix4188Component-2' activate='start' deactivate='stop'>
+        <implementation class="org.apache.felix.scr.integration.components.felix4188.Felix4188Component" />
+	</scr:component>
+</components>