felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pde...@apache.org
Subject svn commit: r1771399 - in /felix/trunk/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api: FELIX5426_OptionalCallbackNotCalledTest.java FELIX5426_OptionalChangeCallbackNotCalledTest.java
Date Fri, 25 Nov 2016 22:23:15 GMT
Author: pderop
Date: Fri Nov 25 22:23:15 2016
New Revision: 1771399

URL: http://svn.apache.org/viewvc?rev=1771399&view=rev
Log:
FELIX-4226: Added test cases for the issue. Notice that for FELIX5426_OptionalChangeCallbackNotCalledTest.java,
there is not actual bug, it's just
that this test was missing.


Added:
    felix/trunk/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5426_OptionalCallbackNotCalledTest.java
    felix/trunk/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5426_OptionalChangeCallbackNotCalledTest.java

Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5426_OptionalCallbackNotCalledTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5426_OptionalCallbackNotCalledTest.java?rev=1771399&view=auto
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5426_OptionalCallbackNotCalledTest.java
(added)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5426_OptionalCallbackNotCalledTest.java
Fri Nov 25 22:23:15 2016
@@ -0,0 +1,86 @@
+/*
+ * 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.itest.api;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.itest.util.Ensure;
+import org.apache.felix.dm.itest.util.TestBase;
+import org.junit.Assert;
+
+/**
+ * Validates that optional dependency callbacks are properly called in a special use case,
where
+ * a circular dependency exists between two components.
+ */
+public class FELIX5426_OptionalCallbackNotCalledTest extends TestBase {
+
+	final Ensure m_ensure = new Ensure();
+	
+	public void testCleanupDependenciesDuringComponentRemove() {
+		DependencyManager m = getDM();
+		
+		BookStore store = new BookStore();
+		Component bookStore = m.createComponent()
+				.setImplementation(store).setInterface(BookStore.class.getName(), null)
+				.add(m.createServiceDependency().setService(Book.class).setCallbacks("added", "removed").setRequired(false));
+
+		Component book1 = m.createComponent()
+				.setImplementation(new Book()).setInterface(Book.class.getName(), null)
+				.add(m.createServiceDependency().setService(BookStore.class).setRequired(true));
+
+		Component book2 = m.createComponent()
+				.setImplementation(new Book()).setInterface(Book.class.getName(), null)
+				.add(m.createServiceDependency().setService(BookStore.class).setRequired(true));		
+		
+		m.add(bookStore);
+		m.add(book1);
+		m.add(book2);
+		
+		m.remove(bookStore);		
+		Assert.assertEquals(0, store.getBooksCount());
+	}
+		
+	class BookStore {
+		final List<Book> m_books = new ArrayList<>();
+		
+		private void added(Book book) { // injected, optional
+			m_books.add(book);
+		}
+		
+		private void removed(Book book)  {
+			m_books.remove(book);
+		}
+		
+		public int getBooksCount() {
+			return m_books.size();
+		}
+	}
+	
+	class Book {
+		private BookStore m_shop; // injected, required
+		
+		public void start() {
+			Assert.assertNotNull(m_shop);
+		}
+	}
+
+}

Added: felix/trunk/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5426_OptionalChangeCallbackNotCalledTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5426_OptionalChangeCallbackNotCalledTest.java?rev=1771399&view=auto
==============================================================================
--- felix/trunk/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5426_OptionalChangeCallbackNotCalledTest.java
(added)
+++ felix/trunk/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5426_OptionalChangeCallbackNotCalledTest.java
Fri Nov 25 22:23:15 2016
@@ -0,0 +1,133 @@
+/*
+ * 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.itest.api;
+
+import java.util.Dictionary;
+import java.util.Properties;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ComponentState;
+import org.apache.felix.dm.ComponentStateListener;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.itest.util.Ensure;
+import org.apache.felix.dm.itest.util.TestBase;
+import org.junit.Assert;
+
+/**
+ * Use case:
+ * 
+ * - A depends on B (optional) and C (required). A has some "add/change/remove" callbacks
on B.
+ * - A started
+ * - A is stopping because C is lost, so A is called in A.unbind(B), A.stop()
+ * - then a ComponentStateListener is called and at this point, the listener is 
+ *   changing the service properties for B.
+ *   
+ * then since A.stop has been called, then A.changed(B b) should never be called.
+ */
+public class FELIX5426_OptionalChangeCallbackNotCalledTest extends TestBase {
+
+	final Ensure m_ensure = new Ensure();
+	
+	public void testCleanupDependenciesDuringComponentRemove() {
+		DependencyManager m = getDM();
+		
+		A aObject= new A();
+		
+		Component a = m.createComponent()
+				.setImplementation(aObject)
+				.add(m.createServiceDependency().setService(B.class).setRequired(false).setCallbacks("add",
"change", "remove"))
+				.add(m.createServiceDependency().setService(C.class).setRequired(true).setCallbacks("add",
"remove"));
+
+		Component b = m.createComponent()
+				.setImplementation(new B())
+				.setInterface(B.class.getName(), null);
+		
+		Component c = m.createComponent()
+				.setImplementation(new C())
+				.setInterface(C.class.getName(), null);
+
+		ComponentStateListener listenerA = (comp, state) -> {
+			if (state == ComponentState.STOPPED) {
+				Properties properties = new Properties();
+				b.setServiceProperties(properties);
+			}
+		};
+		
+		a.add(listenerA);
+		
+		m.add(a);
+		m.add(b);
+		m.add(c);
+		
+		m_ensure.waitForStep(2, 5000); // A started
+		
+		m.remove(c); // A is stopping, it should be called in A.remove(C), A.remove(B), but never
in A.change(B)
+		m_ensure.waitForStep(5, 5000);
+		
+		Assert.assertFalse(aObject.bChanged());
+	}
+		
+	class A {
+		boolean m_started;
+		boolean m_bChanged;
+		
+		void start() {
+			m_started = true;
+		}
+		
+		void stop() {
+			m_started = false;
+			m_ensure.step(4);
+		}
+		
+		void add(C c) {
+			m_ensure.step(1);
+		}		
+		
+		void add(B b) {
+			m_ensure.step(2);
+		}
+		
+		void remove(B b) {
+			m_ensure.step(3);
+		}
+		
+		void change(B b, Dictionary<String, Object> properties) {
+			m_bChanged = true; // should never be called
+			throw new RuntimeException("A.change() method called");
+		}
+		
+		boolean bChanged() {
+			return m_bChanged;
+		}
+		
+		void remove(C c) {
+			m_ensure.step(5);
+		}
+	}
+	
+	class B {
+		
+	}
+	
+	class C {
+		
+	}
+
+}



Mime
View raw message