SLING-8303 osgi-mock: Pick highest-ranking services for mandatory unary references if multiple services present
diff --git a/core/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java b/core/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java
index a8ec9b7..a42a3c8 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java
@@ -152,8 +152,8 @@
if (reference.matchesTargetFilter(registration.getReference())) {
switch (reference.getCardinality()) {
case MANDATORY_UNARY:
- throw new ReferenceViolationException("Mandatory unary reference of type " + reference.getInterfaceType() + " already fulfilled "
- + "for service " + reference.getServiceClass().getName() + ", registration of new service with this interface failed.");
+ // nothing to do - reference is already set
+ break;
case MANDATORY_MULTIPLE:
case OPTIONAL_MULTIPLE:
case OPTIONAL_UNARY:
@@ -172,8 +172,8 @@
Reference reference = referenceInfo.getReference();
switch (reference.getCardinality()) {
case MANDATORY_UNARY:
- throw new ReferenceViolationException("Mandatory unary reference of type " + reference.getInterfaceType() + " already fulfilled "
- + "for service " + reference.getServiceClass().getName() + ", registration of new service with this interface failed.");
+ // nothing to do - reference is already set
+ break;
case MANDATORY_MULTIPLE:
case OPTIONAL_MULTIPLE:
case OPTIONAL_UNARY:
@@ -231,13 +231,10 @@
if (reference.matchesTargetFilter(registration.getReference())) {
switch (reference.getCardinality()) {
case MANDATORY_UNARY:
- throw new ReferenceViolationException("Reference of type " + reference.getInterfaceType() + " "
- + "for service " + reference.getServiceClass().getName() + " is mandatory unary, "
- + "unregistration of service with this interface failed.");
case MANDATORY_MULTIPLE:
case OPTIONAL_MULTIPLE:
case OPTIONAL_UNARY:
- // it is currently not checked if for a MANDATORY_MULTIPLE reference the last reference is removed
+ // it is currently not checked if for a MANDATORY_UNARY or MANDATORY_MULTIPLE reference the last reference is removed
OsgiServiceUtil.invokeUnbindMethod(reference, referenceInfo.getServiceRegistration().getService(),
new ServiceInfo(registration));
break;
@@ -253,9 +250,6 @@
Reference reference = referenceInfo.getReference();
switch (reference.getCardinality()) {
case MANDATORY_UNARY:
- throw new ReferenceViolationException("Reference of type " + reference.getInterfaceType() + " "
- + "for service " + reference.getServiceClass().getName() + " is mandatory unary, "
- + "unregistration of service with this interface failed.");
case MANDATORY_MULTIPLE:
case OPTIONAL_MULTIPLE:
case OPTIONAL_UNARY:
diff --git a/core/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java b/core/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java
index 488b4fe..8726f9d 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java
@@ -421,9 +421,9 @@
}
}
- // multiple references found? check if reference is not multiple
+ // multiple references found? inject only first one with highest ranking
if (matchingServices.size() > 1 && !reference.isCardinalityMultiple()) {
- throw new ReferenceViolationException("Multiple matches found for unary reference '" + reference.getName() + "' for class "+ targetClass.getName());
+ matchingServices = matchingServices.subList(0, 1);
}
// try to invoke bind method
diff --git a/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6Test.java b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6Test.java
index a23fd9a..a5da281 100644
--- a/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6Test.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6Test.java
@@ -40,7 +40,6 @@
import com.google.common.collect.ImmutableSet;
@RunWith(MockitoJUnitRunner.class)
-@SuppressWarnings("null")
public class MockBundleContextDynamicReferencesOsgiR6Test {
private BundleContext bundleContext;
@@ -104,13 +103,15 @@
assertDependency1Optional(dependency1bOptional);
}
- @Test(expected = ReferenceViolationException.class)
+ @Test
public void testAddMandatoryUnaryService_TooMany() {
+ // should not throw an exception although mandatory unary reference is already set
bundleContext.registerService(ServiceInterface1.class.getName(), dependency1b, null);
}
- @Test(expected = ReferenceViolationException.class)
+ @Test
public void testRemoveMandatoryUnaryService_TooMany() {
+ // this should check if the mandatory references is no longer set - but this is currently not implemented
reg1a.unregister();
}
diff --git a/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesTest.java b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesTest.java
index 5437e23..47b3c0c 100644
--- a/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesTest.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesTest.java
@@ -39,7 +39,6 @@
import com.google.common.collect.ImmutableSet;
@RunWith(MockitoJUnitRunner.class)
-@SuppressWarnings("null")
public class MockBundleContextDynamicReferencesTest {
private BundleContext bundleContext;
@@ -101,13 +100,15 @@
assertDependency1Optional(dependency1bOptional);
}
- @Test(expected = ReferenceViolationException.class)
+ @Test
public void testAddMandatoryUnaryService_TooMany() {
+ // should not throw an exception although mandatory unary reference is already set
bundleContext.registerService(ServiceInterface1.class.getName(), dependency1b, null);
}
- @Test(expected = ReferenceViolationException.class)
+ @Test
public void testRemoveMandatoryUnaryService_TooMany() {
+ // this should check if the mandatory references is no longer set - but this is currently not implemented
reg1a.unregister();
}
diff --git a/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextStaticGreedyReferencesTest.java b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextStaticGreedyReferencesTest.java
index 503b0c4..69b8765 100644
--- a/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextStaticGreedyReferencesTest.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextStaticGreedyReferencesTest.java
@@ -40,7 +40,6 @@
import com.google.common.collect.ImmutableSet;
@RunWith(MockitoJUnitRunner.class)
-@SuppressWarnings("null")
public class MockBundleContextStaticGreedyReferencesTest {
private BundleContext bundleContext;
@@ -101,8 +100,9 @@
assertDependency1Optional(dependency1bOptional);
}
- @Test(expected = ReferenceViolationException.class)
+ @Test
public void testAddMandatoryUnaryService_TooMany() {
+ // should not throw an exception although mandatory unary reference is already set
bundleContext.registerService(ServiceInterface1.class.getName(), dependency1b, null);
}
diff --git a/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceRegisterTest.java b/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceRegisterTest.java
index c751099..a206e7b 100644
--- a/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceRegisterTest.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceRegisterTest.java
@@ -19,13 +19,18 @@
package org.apache.sling.testing.mock.osgi;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.mockito.Mockito.mock;
import org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.Service2;
+import org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.Service3;
+import org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.ServiceInterface1;
import org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.ServiceInterface2;
import org.apache.sling.testing.mock.osgi.OsgiServiceUtilTest.ServiceInterface3;
import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
import org.junit.Rule;
import org.junit.Test;
+import org.osgi.framework.Constants;
public class OsgiServiceRegisterTest {
@@ -73,5 +78,22 @@
assertEquals(1, context.getServices(ServiceInterface2.class, null).length);
assertEquals(1, context.getServices(ServiceInterface3.class, null).length);
}
+
+ @Test
+ @SuppressWarnings("null")
+ public void testInjectMandatoryUnaryReferenceOutOfMultipleServices() {
+ context.registerService(ServiceInterface2.class, mock(ServiceInterface2.class));
+ ServiceInterface1 service1_ranking100 = mock(ServiceInterface1.class);
+ context.registerService(ServiceInterface1.class, service1_ranking100, Constants.SERVICE_RANKING, 100);
+ ServiceInterface1 service1_ranking200 = mock(ServiceInterface1.class);
+ context.registerService(ServiceInterface1.class, service1_ranking200, Constants.SERVICE_RANKING, 200);
+ ServiceInterface1 service1_ranking10 = mock(ServiceInterface1.class);
+ context.registerService(ServiceInterface1.class, service1_ranking10, Constants.SERVICE_RANKING, 10);
+
+ // register service with unary mandatory reference to ServiceInterface1
+ Service3 service3 = context.registerInjectActivateService(new Service3());
+ assertSame(service1_ranking200, service3.getReference1());
+ }
+
}