You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pd...@apache.org on 2017/05/29 07:28:24 UTC
svn commit: r1796580 - in
/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest:
./ .settings/ bin/ bin_test/ src/ src/org/ src/org/apache/
src/org/apache/felix/ src/org/apache/felix/dm/
src/org/apache/felix/dm/index/ src/org/ap...
Author: pderop
Date: Mon May 29 07:28:24 2017
New Revision: 1796580
URL: http://svn.apache.org/viewvc?rev=1796580&view=rev
Log:
FELIX-5619: MultiProperyFilterIndex memory consumption
FELIX-4028: Extensible filter index mechanism
Added a new integration test subproject for the above issues because filter indices are special and may mess around with org.apache.felix.dependencymanager.itest sub project.
Added:
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/.classpath (with props)
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/.gitignore
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/.project (with props)
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/.settings/
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/bin/
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/bin_test/
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/bnd.bnd
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/dynamic.customindex.bnd
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/dynamiccustomindex/
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/dynamiccustomindex/DynamicCustomFilterIndex.java
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/staticcustomindex/
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/staticcustomindex/StaticCustomFilterIndex.java
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/DynamicCustomIndexTest.java
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/Ensure.java
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/FELIX3008_FilterIndexStartupTest.java
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/FELIX3057_EmptyServiceReferenceArray.java
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/FilterIndexResourceAdapterTest.java
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/ResourceProvider.java
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/StaticCustomIndexTest.java
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/TestBase.java
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/static.customindex.bnd
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/test/
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/test/.gitignore
felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/tests.bnd
Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/.classpath
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/.classpath?rev=1796580&view=auto
==============================================================================
Binary file - no diff available.
Propchange: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/.classpath
------------------------------------------------------------------------------
svn:mime-type = application/xml
Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/.gitignore
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/.gitignore?rev=1796580&view=auto
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/.gitignore (added)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/.gitignore Mon May 29 07:28:24 2017
@@ -0,0 +1,3 @@
+/bin/
+/bin_test/
+/generated/
Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/.project
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/.project?rev=1796580&view=auto
==============================================================================
Binary file - no diff available.
Propchange: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/.project
------------------------------------------------------------------------------
svn:mime-type = application/xml
Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/bnd.bnd
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/bnd.bnd?rev=1796580&view=auto
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/bnd.bnd (added)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/bnd.bnd Mon May 29 07:28:24 2017
@@ -0,0 +1,56 @@
+#
+# 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.
+#
+-runbundles: \
+ org.apache.felix.metatype;version=1.0.4,\
+ org.apache.felix.gogo.runtime;version=0.10.0,\
+ org.apache.felix.log;version=1.0.1,\
+ org.apache.felix.configadmin;version=1.8.8,\
+ org.apache.felix.dependencymanager;version=latest,\
+ org.apache.felix.dependencymanager.shell;version=latest,\
+ biz.aQute.junit;version=3.0.0,\
+ org.apache.felix.gogo.command,\
+ org.apache.felix.gogo.shell,\
+ org.apache.felix.dependencymanager.index.itest.dynamic.customindex;version=latest,\
+ org.apache.felix.dependencymanager.index.itest.static.customindex;version=latest,\
+ org.apache.felix.dependencymanager.index.itest.tests;version=latest
+
+-runee: JavaSE-1.8
+-runvm: -ea
+-runfw: org.apache.felix.framework;version='[5.2.0,5.2.0]'
+-buildpath: \
+ osgi.core;version=4.2,\
+ osgi.cmpn;version=4.2,\
+ org.apache.felix.gogo.runtime;version=0.10,\
+ org.apache.felix.dependencymanager;version=latest,\
+ org.apache.felix.dependencymanager.shell;version=latest,\
+ ${junit}
+-runsystempackages: \
+ sun.reflect
+Test-Cases: \
+ ${classes;CONCRETE;EXTENDS;junit.framework.TestCase}
+-runproperties: \
+ org.apache.felix.dependencymanager.loglevel=2,\
+ org.apache.felix.log.maxSize=100000,\
+ org.apache.felix.log.storeDebug=true,\
+ gosh.args=--noshutdown,\
+ org.apache.felix.dependencymanager.filterindex=objectClass
+
+# we do not release this project in binary distribution.
+-releaserepo:
+-baseline:
+
+-sub: *.bnd
\ No newline at end of file
Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/dynamic.customindex.bnd
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/dynamic.customindex.bnd?rev=1796580&view=auto
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/dynamic.customindex.bnd (added)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/dynamic.customindex.bnd Mon May 29 07:28:24 2017
@@ -0,0 +1,24 @@
+#
+# 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.
+#
+Export-Package: \
+ org.apache.felix.dm.index.itest.dynamiccustomindex
+Private-Package: \
+ org.apache.felix.dm.impl.index.multiproperty
+Import-Package: *
+Bundle-Category: test
+Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
+Bundle-Vendor: The Apache Software Foundation
Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/dynamiccustomindex/DynamicCustomFilterIndex.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/dynamiccustomindex/DynamicCustomFilterIndex.java?rev=1796580&view=auto
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/dynamiccustomindex/DynamicCustomFilterIndex.java (added)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/dynamiccustomindex/DynamicCustomFilterIndex.java Mon May 29 07:28:24 2017
@@ -0,0 +1,54 @@
+/*
+ * 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.dm.index.itest.dynamiccustomindex;
+
+import org.apache.felix.dm.impl.index.multiproperty.MultiPropertyFilterIndex;
+import org.osgi.framework.BundleContext;
+
+/**
+ * A
+ * @author nxuser
+ *
+ */
+@SuppressWarnings("restriction")
+public class DynamicCustomFilterIndex extends MultiPropertyFilterIndex {
+
+ /**
+ * System property set to true when our DynamicCustomFilterIndex has been opened
+ */
+ private final static String OPENED = "org.apache.felix.dm.index.itest.dynamiccustomindex.CustomFilterIndex.opened";
+
+ public DynamicCustomFilterIndex(String configString) {
+ super(configString);
+ }
+
+ @Override
+ public void open(BundleContext context) {
+ super.open(context);
+ // indicate to our StaticCustomIndexTest that we have been used
+ System.setProperty(OPENED, "true");
+ }
+
+ @Override
+ public void close() {
+ super.close();
+ System.getProperties().remove(OPENED);
+ }
+
+}
Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/staticcustomindex/StaticCustomFilterIndex.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/staticcustomindex/StaticCustomFilterIndex.java?rev=1796580&view=auto
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/staticcustomindex/StaticCustomFilterIndex.java (added)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/staticcustomindex/StaticCustomFilterIndex.java Mon May 29 07:28:24 2017
@@ -0,0 +1,49 @@
+/*
+ * 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.dm.index.itest.staticcustomindex;
+
+import org.apache.felix.dm.impl.index.multiproperty.MultiPropertyFilterIndex;
+import org.osgi.framework.BundleContext;
+
+@SuppressWarnings("restriction")
+public class StaticCustomFilterIndex extends MultiPropertyFilterIndex {
+
+ /**
+ * System property set to true when our StaticCustomFilterIndex has been opened
+ */
+ private final static String OPENED = "org.apache.felix.dm.index.itest.staticcustomindex.StaticCustomFilterIndex.opened";
+
+ public StaticCustomFilterIndex(String configString) {
+ super(configString);
+ }
+
+ @Override
+ public void open(BundleContext context) {
+ super.open(context);
+ // indicate to our StaticCustomIndexTest that we have been used
+ System.setProperty(OPENED, "true");
+ }
+
+ @Override
+ public void close() {
+ super.close();
+ System.getProperties().remove(OPENED);
+ }
+
+}
Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/DynamicCustomIndexTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/DynamicCustomIndexTest.java?rev=1796580&view=auto
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/DynamicCustomIndexTest.java (added)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/DynamicCustomIndexTest.java Mon May 29 07:28:24 2017
@@ -0,0 +1,148 @@
+/*
+ * 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.dm.index.itest.tests;
+//import static org.ops4j.pax.exam.CoreOptions.waitForFrameworkStartupFor;
+//import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.vmOption;
+
+import java.util.function.Consumer;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.FilterIndex;
+import org.apache.felix.dm.index.itest.dynamiccustomindex.DynamicCustomFilterIndex;
+import org.junit.Assert;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class DynamicCustomIndexTest extends TestBase {
+
+ /**
+ * This system property is set to true when the DynamicCustomFilterIndex index has been opened.
+ */
+ private final static String OPENED = "org.apache.felix.dm.index.itest.dynamiccustomindex.CustomFilterIndex.opened";
+
+ private ServiceRegistration m_reg;
+
+ private String m_systemConf;
+
+ @SuppressWarnings("unchecked")
+ public void setUp() throws Exception {
+ System.setProperty(OPENED, "false");
+
+ // backup currently configured filter index
+ BundleContext context = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
+ m_systemConf = context.getProperty(DependencyManager.SERVICEREGISTRY_CACHE_INDICES);
+
+ // Reset filter indices
+ DependencyManager dm = new DependencyManager(context);
+ Consumer<String> reset = (Consumer<String>) System.getProperties().get("org.apache.felix.dependencymanager.filterindex.reset");
+ reset.accept(null); // clear filter index
+
+ // register our DynamicCustomFilterIndex service before calling super.setUp(). This will make
+ // the "getDM()" method return a DependencyManager that is using our DynamicCustomFilterIndex
+ m_reg = context.registerService(FilterIndex.class.getName(), new DynamicCustomFilterIndex("objectClass"), null);
+ super.setUp();
+ }
+
+ @SuppressWarnings("unchecked")
+ public void tearDown() throws Exception {
+ super.tearDown();
+ try {
+ m_reg.unregister();
+ } catch (IllegalStateException e) { // expected, normally we have already unregistered it
+ }
+ System.getProperties().remove(OPENED);
+ Consumer<String> reset = (Consumer<String>) System.getProperties().get("org.apache.felix.dependencymanager.filterindex.reset");
+ reset.accept(m_systemConf);
+ }
+
+ public void testUsingDynamicCustomIndex() throws Exception {
+ doTestUsingDynamicCustomIndex();
+
+ // Make sure our static custom index has been used
+ Assert.assertTrue(Boolean.getBoolean(OPENED));
+
+ // unregister our dynamic filter index
+ m_reg.unregister();
+
+ // clear the flag
+ System.setProperty(OPENED, "false");
+
+ // redo the test
+ doTestUsingDynamicCustomIndex();
+ Assert.assertFalse(Boolean.getBoolean(OPENED));
+ }
+
+ private void doTestUsingDynamicCustomIndex() throws Exception {
+ DependencyManager m = getDM();
+ // helper class that ensures certain steps get executed in sequence
+ Ensure e = new Ensure();
+ // create a provider
+ Provider provider = new Provider();
+ // activate it
+ Component p = m.createComponent()
+ .setInterface(Service.class.getName(), null)
+ .setImplementation(provider);
+
+ Client consumer = new Client(e);
+ Component c = m.createComponent()
+ .setImplementation(consumer)
+ .add(m.createServiceDependency()
+ .setService(Service.class)
+ .setRequired(true)
+ );
+
+ m.add(p);
+ m.add(c);
+ e.waitForStep(1, 5000);
+ m.remove(p);
+ e.waitForStep(2, 5000);
+ m.remove(c);
+ m.clear();
+ }
+
+ public static class Client {
+ volatile Service m_service;
+ private final Ensure m_ensure;
+
+ public Client(Ensure e) {
+ m_ensure = e;
+ }
+
+ public void start() {
+ System.out.println("start");
+ m_ensure.step(1);
+ }
+
+ public void stop() {
+ System.out.println("stop");
+ m_ensure.step(2);
+ }
+ }
+
+ public static interface Service {
+ }
+
+ public static class Provider implements Service {
+ }
+}
Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/Ensure.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/Ensure.java?rev=1796580&view=auto
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/Ensure.java (added)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/Ensure.java Mon May 29 07:28:24 2017
@@ -0,0 +1,174 @@
+/*
+ * 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.dm.index.itest.tests;
+
+import java.io.PrintStream;
+
+import org.junit.Assert;
+
+/**
+ * Helper class to make sure that steps in a test happen in the correct order. Instantiate
+ * this class and subsequently invoke <code>step(nr)</code> with steps starting at 1. You
+ * can also have threads wait until you arrive at a certain step.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Ensure {
+ private final boolean DEBUG;
+ private static long INSTANCE = 0;
+ private static final int RESOLUTION = 100;
+ private static PrintStream STREAM = System.out;
+ int step = 0;
+ private Throwable m_throwable;
+
+ public Ensure() {
+ this(true);
+ }
+
+ public Ensure(boolean debug) {
+ DEBUG = debug;
+ if (DEBUG) {
+ INSTANCE++;
+ }
+ }
+
+ public void setStream(PrintStream output) {
+ STREAM = output;
+ }
+
+ /**
+ * Mark this point as step <code>nr</code>.
+ *
+ * @param nr the step we are in
+ */
+ public synchronized void step(int nr) {
+ step++;
+ Assert.assertEquals(nr, step);
+ if (DEBUG) {
+ String info = getLineInfo(3);
+ STREAM.println("[Ensure " + INSTANCE + "] step " + step + " [" + currentThread() + "] " + info);
+ }
+ notifyAll();
+ }
+
+ private String getLineInfo(int depth) {
+ StackTraceElement[] trace = Thread.currentThread().getStackTrace();
+ String info = trace[depth].getClassName() + "." + trace[depth].getMethodName() + ":" + trace[depth].getLineNumber();
+ return info;
+ }
+
+ /**
+ * Mark this point as the next step.
+ */
+ public synchronized void step() {
+ step++;
+ if (DEBUG) {
+ String info = getLineInfo(3);
+ STREAM.println("[Ensure " + INSTANCE + "] next step " + step + " [" + currentThread() + "] " + info);
+ }
+ notifyAll();
+ }
+
+ /**
+ * Wait until we arrive at least at step <code>nr</code> in the process, or fail if that
+ * takes more than <code>timeout</code> milliseconds. If you invoke wait on a thread,
+ * you are effectively assuming some other thread will invoke the <code>step(nr)</code>
+ * method.
+ *
+ * @param nr the step to wait for
+ * @param timeout the number of milliseconds to wait
+ */
+ public synchronized void waitForStep(int nr, int timeout) {
+ final int initialTimeout = timeout;
+ if (DEBUG) {
+ String info = getLineInfo(3);
+ STREAM.println("[Ensure " + INSTANCE + "] waiting for step " + nr + " [" + currentThread() + "] " + info);
+ }
+ while (step < nr && timeout > 0) {
+ try {
+ wait(RESOLUTION);
+ timeout -= RESOLUTION;
+ }
+ catch (InterruptedException e) {}
+ }
+ if (step < nr) {
+ throw new IllegalStateException("Timed out waiting for " + initialTimeout + " ms for step " + nr + ", we are still at step " + step);
+ }
+ if (DEBUG) {
+ String info = getLineInfo(3);
+ STREAM.println("[Ensure " + INSTANCE + "] arrived at step " + nr + " [" + currentThread() + "] " + info);
+ }
+ }
+
+ private String currentThread() {
+ Thread thread = Thread.currentThread();
+ return thread.getId() + " " + thread.getName();
+ }
+
+ public static Runnable createRunnableStep(final Ensure ensure, final int nr) {
+ return new Runnable() { public void run() { ensure.step(nr); }};
+ }
+
+ public synchronized void steps(Steps steps) {
+ steps.next(this);
+ }
+
+ /**
+ * Helper class for naming a list of step numbers. If used with the steps(Steps) method
+ * you can define at which steps in time this point should be passed. That means you can
+ * check methods that will get invoked multiple times during a test.
+ */
+ public static class Steps {
+ private final int[] m_steps;
+ private int m_stepIndex;
+
+ /**
+ * Create a list of steps and initialize the step counter to zero.
+ */
+ public Steps(int... steps) {
+ m_steps = steps;
+ m_stepIndex = 0;
+ }
+
+ /**
+ * Ensure we're at the right step. Will throw an index out of bounds exception if we enter this step more often than defined.
+ */
+ public void next(Ensure ensure) {
+ ensure.step(m_steps[m_stepIndex++]);
+ }
+ }
+
+ /**
+ * Saves a thrown exception that occurred in a different thread. You can only save one exception
+ * at a time this way.
+ */
+ public synchronized void throwable(Throwable throwable) {
+ m_throwable = throwable;
+ }
+
+ /**
+ * Throws a <code>Throwable</code> if one occurred in a different thread and that thread saved it
+ * using the <code>throwable()</code> method.
+ */
+ public synchronized void ensure() throws Throwable {
+ if (m_throwable != null) {
+ throw m_throwable;
+ }
+ }
+}
Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/FELIX3008_FilterIndexStartupTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/FELIX3008_FilterIndexStartupTest.java?rev=1796580&view=auto
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/FELIX3008_FilterIndexStartupTest.java (added)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/FELIX3008_FilterIndexStartupTest.java Mon May 29 07:28:24 2017
@@ -0,0 +1,87 @@
+/*
+ * 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.dm.index.itest.tests;
+//import static org.ops4j.pax.exam.CoreOptions.waitForFrameworkStartupFor;
+//import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.vmOption;
+
+import org.junit.Assert;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.Bundle;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class FELIX3008_FilterIndexStartupTest extends TestBase {
+
+ public void testNormalStart() throws Exception {
+ DependencyManager m = getDM();
+ // helper class that ensures certain steps get executed in sequence
+ Ensure e = new Ensure();
+ // create a provider
+ Provider provider = new Provider();
+ // activate it
+ Component p = m.createComponent()
+ .setInterface(Service.class.getName(), null)
+ .setImplementation(provider);
+
+ Consumer consumer = new Consumer(e);
+ Component c = m.createComponent()
+ .setImplementation(consumer)
+ .add(m.createServiceDependency()
+ .setService(Service.class)
+ .setRequired(true)
+ );
+
+ m.add(p);
+ m.add(c);
+ e.waitForStep(1, 5000);
+ m.remove(p);
+ e.waitForStep(2, 5000);
+ m.remove(c);
+ m.clear();
+ Assert.assertEquals("Dependency manager bundle should be active.", Bundle.ACTIVE, context.getBundle().getState());
+ }
+
+ public static class Consumer {
+ volatile Service m_service;
+ private final Ensure m_ensure;
+
+ public Consumer(Ensure e) {
+ m_ensure = e;
+ }
+
+ public void start() {
+ System.out.println("start");
+ m_ensure.step(1);
+ }
+
+ public void stop() {
+ System.out.println("stop");
+ m_ensure.step(2);
+ }
+ }
+
+ public static interface Service {
+ }
+
+ public static class Provider implements Service {
+ }
+}
Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/FELIX3057_EmptyServiceReferenceArray.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/FELIX3057_EmptyServiceReferenceArray.java?rev=1796580&view=auto
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/FELIX3057_EmptyServiceReferenceArray.java (added)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/FELIX3057_EmptyServiceReferenceArray.java Mon May 29 07:28:24 2017
@@ -0,0 +1,68 @@
+/*
+ * 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.dm.index.itest.tests;
+//import static org.ops4j.pax.exam.CoreOptions.waitForFrameworkStartupFor;
+//import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.vmOption;
+
+import org.junit.Assert;
+
+import java.util.function.Consumer;
+
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class FELIX3057_EmptyServiceReferenceArray extends TestBase {
+
+ private String m_systemConf;
+
+ @SuppressWarnings("unchecked")
+ public void testWithoutIndex() throws Exception {
+ // backup currently configured filter index
+ BundleContext context = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
+ m_systemConf = context.getProperty(DependencyManager.SERVICEREGISTRY_CACHE_INDICES);
+
+ // Reset filter indices
+ Consumer<String> reset = (Consumer<String>) System.getProperties().get("org.apache.felix.dependencymanager.filterindex.reset");
+ reset.accept(null); // clear filter index
+
+ executeTest(context); // no filter index used
+
+ reset.accept(m_systemConf); // reset filer index configured in our bnd.bnd
+ }
+
+ public void testWithIndex() throws Exception {
+ executeTest(context); // SERVICEREGISTRY_CACHE_INDICES system property is configured in our bnd.bnd
+ }
+
+ private void executeTest(BundleContext context) throws InvalidSyntaxException {
+ DependencyManager m = new DependencyManager(context);
+ Assert.assertNull("Looking up a non-existing service should return null.", m.getBundleContext().getServiceReferences(Service.class.getName(), "(objectClass=*)"));
+ Assert.assertNull("Looking up a non-existing service should return null.", m.getBundleContext().getAllServiceReferences(Service.class.getName(), "(objectClass=*)"));
+ Assert.assertNull("Looking up a non-existing service should return null.", m.getBundleContext().getServiceReference(Service.class.getName()));
+ m.clear();
+ }
+
+ /** Dummy interface for lookup. */
+ public static interface Service {}
+}
Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/FilterIndexResourceAdapterTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/FilterIndexResourceAdapterTest.java?rev=1796580&view=auto
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/FilterIndexResourceAdapterTest.java (added)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/FilterIndexResourceAdapterTest.java Mon May 29 07:28:24 2017
@@ -0,0 +1,85 @@
+/*
+ * 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.dm.index.itest.tests;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.ResourceHandler;
+import org.junit.Assert;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class FilterIndexResourceAdapterTest extends TestBase {
+
+ public void testBasicResourceAdapter() throws Exception {
+ DependencyManager m = getDM(); // filter index is configured in our bnd.bnd file
+ // helper class that ensures certain steps get executed in sequence
+ Ensure e = new Ensure();
+ // create a resource provider
+ ResourceProvider provider = new ResourceProvider(context, new URL("file://localhost/path/to/file1.txt"));
+ // activate it
+ m.add(m.createComponent().setImplementation(provider).add(m.createServiceDependency().setService(ResourceHandler.class).setCallbacks("add", "remove")));
+ // create a resource adapter for our single resource
+ // note that we can provide an actual implementation instance here because there will be only one
+ // adapter, normally you'd want to specify a Class here
+ m.add(m.createResourceAdapterService("(&(path=/path/to/*.txt)(host=localhost))", false, null, "changed")
+ .setImplementation(new ResourceAdapter(e)));
+ // wait until the single resource is available
+ e.waitForStep(3, 5000);
+ // trigger a 'change' in our resource
+ provider.change();
+ // wait until the changed callback is invoked
+ e.waitForStep(4, 5000);
+ m.clear();
+ }
+
+ static class ResourceAdapter {
+ protected URL m_resource; // injected by reflection.
+ private Ensure m_ensure;
+
+ ResourceAdapter(Ensure e) {
+ m_ensure = e;
+ }
+
+ public void start() {
+ m_ensure.step(1);
+ Assert.assertNotNull("resource not injected", m_resource);
+ m_ensure.step(2);
+ try {
+ @SuppressWarnings("unused")
+ InputStream in = m_resource.openStream();
+ }
+ catch (FileNotFoundException e) {
+ m_ensure.step(3);
+ }
+ catch (IOException e) {
+ Assert.fail("We should not have gotten this exception.");
+ }
+ }
+
+ public void changed() {
+ m_ensure.step(4);
+ }
+ }
+}
Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/ResourceProvider.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/ResourceProvider.java?rev=1796580&view=auto
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/ResourceProvider.java (added)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/ResourceProvider.java Mon May 29 07:28:24 2017
@@ -0,0 +1,121 @@
+/*
+ * 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.dm.index.itest.tests;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.apache.felix.dm.ResourceHandler;
+import org.apache.felix.dm.ResourceUtil;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ResourceProvider {
+ final URL[] m_resources;
+ final BundleContext m_context;
+ final Map<ResourceHandler, Filter> m_handlers = new HashMap<>();
+
+ public ResourceProvider(BundleContext ctx, URL ... resources) {
+ m_context = ctx;
+ m_resources = resources;
+ }
+
+ public void change() {
+ for (int i = 0; i < m_resources.length; i++) {
+ change(i);
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ public void change(int resourceIndex) {
+ Map<ResourceHandler, Filter> handlers = new HashMap<>();
+ synchronized (m_handlers) {
+ handlers.putAll(m_handlers);
+ }
+ for (Map.Entry<ResourceHandler, Filter> e : handlers.entrySet()) {
+ ResourceHandler handler = e.getKey();
+ Filter filter = e.getValue();
+ if (filter == null || filter.match(ResourceUtil.createProperties(m_resources[resourceIndex]))) {
+ handler.changed(m_resources[resourceIndex]);
+ }
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ public void add(ServiceReference ref, ResourceHandler handler) {
+ String filterString = (String) ref.getProperty("filter");
+ Filter filter = null;
+ if (filterString != null) {
+ try {
+ filter = m_context.createFilter(filterString);
+ }
+ catch (InvalidSyntaxException e) {
+ Assert.fail("Could not create filter for resource handler: " + e);
+ return;
+ }
+ }
+ for (int i = 0; i < m_resources.length; i++) {
+ if (filter == null || filter.match(ResourceUtil.createProperties(m_resources[i]))) {
+ synchronized (m_handlers) {
+ m_handlers.put(handler, filter);
+ }
+ handler.added(m_resources[i]);
+ }
+ }
+ }
+
+ public void remove(ServiceReference ref, ResourceHandler handler) {
+ Filter filter;
+ synchronized (m_handlers) {
+ filter = (Filter) m_handlers.remove(handler);
+ }
+ if (filter != null) {
+ removeResources(handler, filter);
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ private void removeResources(ResourceHandler handler, Filter filter) {
+ for (int i = 0; i < m_resources.length; i++) {
+ if (filter == null || filter.match(ResourceUtil.createProperties(m_resources[i]))) {
+ handler.removed(m_resources[i]);
+ }
+ }
+ }
+
+ public void destroy() {
+ Map<ResourceHandler, Filter> handlers = new HashMap<>();
+ synchronized (m_handlers) {
+ handlers.putAll(m_handlers);
+ }
+
+ for (Map.Entry<ResourceHandler, Filter> e : handlers.entrySet()) {
+ ResourceHandler handler = e.getKey();
+ Filter filter = e.getValue();
+ removeResources(handler, filter);
+ }
+ }
+}
Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/StaticCustomIndexTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/StaticCustomIndexTest.java?rev=1796580&view=auto
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/StaticCustomIndexTest.java (added)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/StaticCustomIndexTest.java Mon May 29 07:28:24 2017
@@ -0,0 +1,121 @@
+/*
+ * 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.dm.index.itest.tests;
+//import static org.ops4j.pax.exam.CoreOptions.waitForFrameworkStartupFor;
+//import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.vmOption;
+
+import java.util.function.Consumer;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.junit.Assert;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class StaticCustomIndexTest extends TestBase {
+
+ /**
+ * This system property is set to true when the StaticCustomFilterIndex index has been opened.
+ */
+ private final static String OPENED = "org.apache.felix.dm.index.itest.staticcustomindex.StaticCustomFilterIndex.opened";
+
+ private String m_systemConf;
+
+ @SuppressWarnings("unchecked")
+ public void setUp() throws Exception {
+ System.setProperty(OPENED, "false");
+
+ // backup currently configured filter index
+ BundleContext context = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
+ m_systemConf = context.getProperty(DependencyManager.SERVICEREGISTRY_CACHE_INDICES);
+
+ // configure our filter index and use the special DM backdoor in order to reinitialize filter indices
+ Consumer<String> reset = (Consumer<String>) System.getProperties().get("org.apache.felix.dependencymanager.filterindex.reset");
+ reset.accept("org.apache.felix.dm.index.itest.staticcustomindex.StaticCustomFilterIndex:objectClass");
+
+ // now call super.setUp() method: the getDM() method will return a DependencyManager that will use the filter index.
+ super.setUp();
+ }
+
+ public void tearDown() throws Exception {
+ super.tearDown();
+ System.getProperties().remove(OPENED);
+ Consumer<String> reset = (Consumer<String>) System.getProperties().get("org.apache.felix.dependencymanager.filterindex.reset");
+ reset.accept(m_systemConf);
+ }
+
+ public void testUsingStaticCustomIndex() throws Exception {
+ DependencyManager m = getDM();
+ // helper class that ensures certain steps get executed in sequence
+ Ensure e = new Ensure();
+ // create a provider
+ Provider provider = new Provider();
+ // activate it
+ Component p = m.createComponent()
+ .setInterface(Service.class.getName(), null)
+ .setImplementation(provider);
+
+ Client consumer = new Client(e);
+ Component c = m.createComponent()
+ .setImplementation(consumer)
+ .add(m.createServiceDependency()
+ .setService(Service.class)
+ .setRequired(true)
+ );
+
+ m.add(p);
+ m.add(c);
+ e.waitForStep(1, 5000);
+ m.remove(p);
+ e.waitForStep(2, 5000);
+ m.remove(c);
+ m.clear();
+
+ // Make sure our static custom index has been used
+ Assert.assertTrue(Boolean.getBoolean(OPENED));
+ }
+
+ public static class Client {
+ volatile Service m_service;
+ private final Ensure m_ensure;
+
+ public Client(Ensure e) {
+ m_ensure = e;
+ }
+
+ public void start() {
+ System.out.println("start");
+ m_ensure.step(1);
+ }
+
+ public void stop() {
+ System.out.println("stop");
+ m_ensure.step(2);
+ }
+ }
+
+ public static interface Service {
+ }
+
+ public static class Provider implements Service {
+ }
+}
Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/TestBase.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/TestBase.java?rev=1796580&view=auto
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/TestBase.java (added)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/TestBase.java Mon May 29 07:28:24 2017
@@ -0,0 +1,365 @@
+/*
+ * 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.dm.index.itest.tests;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ComponentExecutorFactory;
+import org.apache.felix.dm.DependencyManager;
+import org.junit.Assert;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.log.LogService;
+
+import junit.framework.TestCase;
+
+/**
+ * Base class for all integration tests.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public abstract class TestBase extends TestCase implements LogService, FrameworkListener {
+ // Default OSGI log service level.
+ protected final static int LOG_LEVEL = LogService.LOG_WARNING;
+
+ // optional thread pool used by parallel dependency managers
+ protected volatile ForkJoinPool m_threadPool;
+
+ // flag used to check if the threadpool must be used for a given test.
+ protected volatile boolean m_parallel;
+
+ // Flag used to check if some errors have been logged during the execution of a given test.
+ private volatile boolean m_errorsLogged;
+
+ // We implement OSGI log service.
+ protected ServiceRegistration logService;
+
+ // Our bundle context
+ protected BundleContext context;
+
+ // Our dependency manager used to create test components.
+ protected volatile DependencyManager m_dm;
+
+ // The Registration for the DM threadpool.
+ private ServiceRegistration m_componentExecutorFactoryReg;
+
+ public TestBase() {
+ }
+
+ protected void setParallel() {
+ m_parallel = true;
+ }
+
+ public void setUp() throws Exception {
+ warn("Setting up test " + getClass().getName());
+ context = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
+ Hashtable<String, Object> props = new Hashtable<>();
+ props.put(Constants.SERVICE_RANKING, new Integer(Integer.MAX_VALUE));
+ logService = context.registerService(LogService.class.getName(), this, props);
+ context.addFrameworkListener(this);
+ m_dm = new DependencyManager(context);
+ if (m_parallel) {
+ warn("Using threadpool ...");
+ m_threadPool = new ForkJoinPool(Runtime.getRuntime().availableProcessors());
+ m_componentExecutorFactoryReg = context.registerService(ComponentExecutorFactory.class.getName(),
+ new ComponentExecutorFactory() {
+ @Override
+ public Executor getExecutorFor(Component component) {
+ return m_threadPool;
+ }
+ },
+ null);
+ }
+ }
+
+ public void tearDown() throws Exception {
+ warn("Tearing down test " + getClass().getName());
+ logService.unregister();
+ context.removeFrameworkListener(this);
+ clearComponents();
+
+ if (m_parallel && m_componentExecutorFactoryReg != null) {
+ m_componentExecutorFactoryReg.unregister();
+ m_threadPool.shutdown();
+ try {
+ m_threadPool.awaitTermination(60, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ }
+ }
+ Assert.assertFalse(errorsLogged());
+ }
+
+ protected DependencyManager getDM() {
+ return m_dm;
+ }
+
+ protected void clearComponents() {
+ m_dm.clear();
+ warn("All component cleared.");
+ }
+
+ /**
+ * Creates and provides an Ensure object with a name service property into the OSGi service registry.
+ */
+ protected ServiceRegistration register(Ensure e, String name) {
+ Hashtable<String, String> props = new Hashtable<String, String>();
+ props.put("name", name);
+ return context.registerService(Ensure.class.getName(), e, props);
+ }
+
+ /**
+ * Helper method used to stop a given bundle.
+ *
+ * @param symbolicName
+ * the symbolic name of the bundle to be stopped.
+ */
+ protected void stopBundle(String symbolicName) {
+ // Stop the test.annotation bundle
+ boolean found = false;
+ for (Bundle b : context.getBundles()) {
+ if (b.getSymbolicName().equals(symbolicName)) {
+ try {
+ found = true;
+ b.stop();
+ } catch (BundleException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ if (!found) {
+ throw new IllegalStateException("bundle " + symbolicName + " not found");
+ }
+ }
+
+ /**
+ * Helper method used to start a given bundle.
+ *
+ * @param symbolicName
+ * the symbolic name of the bundle to be started.
+ */
+ protected void startBundle(String symbolicName) {
+ // Stop the test.annotation bundle
+ boolean found = false;
+ for (Bundle b : context.getBundles()) {
+ if (b.getSymbolicName().equals(symbolicName)) {
+ try {
+ found = true;
+ b.start();
+ } catch (BundleException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ if (!found) {
+ throw new IllegalStateException("bundle " + symbolicName + " not found");
+ }
+ }
+
+ /**
+ * Helper method used to get a given bundle.
+ *
+ * @param symbolicName
+ * the symbolic name of the bundle to get.
+ */
+ protected Bundle getBundle(String symbolicName) {
+ for (Bundle b : context.getBundles()) {
+ if (b.getSymbolicName().equals(symbolicName)) {
+ return b;
+ }
+ }
+ throw new IllegalStateException("bundle " + symbolicName + " not found");
+ }
+
+ /**
+ * Suspend the current thread for a while.
+ *
+ * @param n
+ * the number of milliseconds to wait for.
+ */
+ protected void sleep(int ms) {
+ try {
+ Thread.sleep(ms);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ /**
+ * Helper method used to convert a dictionary which with untyped keys to a dictionary having a String key.
+ * (this method is useful when converting a Properties object into a compatible Dictionary<String, Object>
+ * object that is often needed in OSGI R6 API.
+ */
+ @SuppressWarnings("unchecked")
+ public static Dictionary<String, ?> toR6Dictionary(Dictionary<?,?> properties) {
+ return (Dictionary<String, ?>) properties;
+ }
+
+ public void log(int level, String message) {
+ checkError(level, null);
+ if (LOG_LEVEL >= level) {
+ System.out.println(getLevel(level) + " - " + Thread.currentThread().getName() + " : " + message);
+ }
+ }
+
+ public void log(int level, String message, Throwable exception) {
+ checkError(level, exception);
+ if (LOG_LEVEL >= level) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(getLevel(level) + " - " + Thread.currentThread().getName() + " : ");
+ sb.append(message);
+ parse(sb, exception);
+ System.out.println(sb.toString());
+ }
+ }
+
+ public void log(ServiceReference sr, int level, String message) {
+ checkError(level, null);
+ if (LOG_LEVEL >= level) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(getLevel(level) + " - " + Thread.currentThread().getName() + " : ");
+ sb.append(message);
+ System.out.println(sb.toString());
+ }
+ }
+
+ public void log(ServiceReference sr, int level, String message, Throwable exception) {
+ checkError(level, exception);
+ if (LOG_LEVEL >= level) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(getLevel(level) + " - " + Thread.currentThread().getName() + " : ");
+ sb.append(message);
+ parse(sb, exception);
+ System.out.println(sb.toString());
+ }
+ }
+
+ protected boolean errorsLogged() {
+ return m_errorsLogged;
+ }
+
+ private void parse(StringBuilder sb, Throwable t) {
+ if (t != null) {
+ sb.append(" - ");
+ StringWriter buffer = new StringWriter();
+ PrintWriter pw = new PrintWriter(buffer);
+ t.printStackTrace(pw);
+ sb.append(buffer.toString());
+ m_errorsLogged = true;
+ }
+ }
+
+ private String getLevel(int level) {
+ switch (level) {
+ case LogService.LOG_DEBUG :
+ return "DEBUG";
+ case LogService.LOG_ERROR :
+ return "ERROR";
+ case LogService.LOG_INFO :
+ return "INFO";
+ case LogService.LOG_WARNING :
+ return "WARN";
+ default :
+ return "";
+ }
+ }
+
+ private void checkError(int level, Throwable exception) {
+ if (level <= LOG_ERROR) {
+ m_errorsLogged = true;
+ }
+ if (exception != null) {
+ m_errorsLogged = true;
+ }
+ }
+
+ public void frameworkEvent(FrameworkEvent event) {
+ int eventType = event.getType();
+ String msg = getFrameworkEventMessage(eventType);
+ int level = (eventType == FrameworkEvent.ERROR) ? LOG_ERROR : LOG_WARNING;
+ if (msg != null) {
+ log(level, msg, event.getThrowable());
+ } else {
+ log(level, "Unknown fwk event: " + event);
+ }
+ }
+
+ 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;
+ }
+ }
+
+ protected void warn(String msg, Object ... params) {
+ if (LOG_LEVEL >= LogService.LOG_WARNING) {
+ log(LogService.LOG_WARNING, params.length > 0 ? String.format(msg, params) : msg);
+ }
+ }
+
+ @SuppressWarnings("unused")
+ protected void info(String msg, Object ... params) {
+ if (LOG_LEVEL >= LogService.LOG_INFO) {
+ log(LogService.LOG_INFO, params.length > 0 ? String.format(msg, params) : msg);
+ }
+ }
+
+ @SuppressWarnings("unused")
+ protected void debug(String msg, Object ... params) {
+ if (LOG_LEVEL >= LogService.LOG_DEBUG) {
+ log(LogService.LOG_DEBUG, params.length > 0 ? String.format(msg, params) : msg);
+ }
+ }
+
+ protected void error(String msg, Object ... params) {
+ log(LogService.LOG_ERROR, params.length > 0 ? String.format(msg, params) : msg);
+ }
+
+ protected void error(String msg, Throwable err, Object ... params) {
+ log(LogService.LOG_ERROR, params.length > 0 ? String.format(msg, params) : msg, err);
+ }
+
+ protected void error(Throwable err) {
+ log(LogService.LOG_ERROR, "error", err);
+ }
+}
Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/static.customindex.bnd
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/static.customindex.bnd?rev=1796580&view=auto
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/static.customindex.bnd (added)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/static.customindex.bnd Mon May 29 07:28:24 2017
@@ -0,0 +1,23 @@
+#
+# 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.
+#
+Private-Package: org.apache.felix.dm.index.itest.staticcustomindex
+Fragment-Host: org.apache.felix.dependencymanager
+Import-Package: !org.apache.felix.dm.*,*
+Bundle-Name: Apache Felix Dependency Manager integration tests Static Custom Index
+Bundle-Category: test
+Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
+Bundle-Vendor: The Apache Software Foundation
Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/test/.gitignore
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/test/.gitignore?rev=1796580&view=auto
==============================================================================
(empty)
Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/tests.bnd
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/tests.bnd?rev=1796580&view=auto
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/tests.bnd (added)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.index.itest/tests.bnd Mon May 29 07:28:24 2017
@@ -0,0 +1,21 @@
+#
+# 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.
+#
+Private-Package: org.apache.felix.dm.index.itest.tests
+Bundle-Name: Apache Felix Dependency Manager FilterIndex tests
+Bundle-Category: test
+Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
+Bundle-Vendor: The Apache Software Foundation