This is an automated email from the ASF dual-hosted git repository. tjwatson pushed a commit to branch scrR8 in repository https://gitbox.apache.org/repos/asf/felix-dev.git
commit 6701c6cc5ed2d8eea91217ac31c487bf9a57bb43 Author: Thomas Watson <[email protected]> AuthorDate: Wed Feb 17 09:55:27 2021 -0600 Add Optional service injection tests If a reference uses an interface of java.lang.Optional then the injected object should be an Optional obtained as a service object --- .../scr/integration/ComponentOptionalTest.java | 76 +++++++++++++++++----- .../components/InjectOptionalComponent.java | 59 ++++++++++++++--- .../resources/integration_test_inject_optional.xml | 25 +++++++ 3 files changed, 136 insertions(+), 24 deletions(-) diff --git a/scr/src/test/java/org/apache/felix/scr/integration/ComponentOptionalTest.java b/scr/src/test/java/org/apache/felix/scr/integration/ComponentOptionalTest.java index efd13e7..0613c47 100644 --- a/scr/src/test/java/org/apache/felix/scr/integration/ComponentOptionalTest.java +++ b/scr/src/test/java/org/apache/felix/scr/integration/ComponentOptionalTest.java @@ -21,12 +21,15 @@ package org.apache.felix.scr.integration; import static org.junit.Assert.assertEquals; +import java.util.Optional; + import org.apache.felix.scr.integration.components.ConstructorSingleReference; import org.apache.felix.scr.integration.components.InjectOptionalComponent; import org.apache.felix.scr.integration.components.InjectOptionalComponent.Mode; import org.junit.Test; import org.junit.runner.RunWith; import org.ops4j.pax.exam.junit.PaxExam; +import org.osgi.framework.ServiceRegistration; import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO; @@ -60,14 +63,26 @@ public class ComponentOptionalTest extends ComponentTestBase cmp1.checkMode(mode, null); } - ComponentConfigurationDTO ref1DTO = getDisabledConfigurationAndEnable( - SINGLE_REFERENCE1, - mode.isDynamic() && !mode.isMandatory()// - ? ComponentConfigurationDTO.ACTIVE - : ComponentConfigurationDTO.SATISFIED); - ConstructorSingleReference ref1Service = getServiceFromConfiguration(ref1DTO, - ConstructorSingleReference.class); - + Object ref1Service; + ComponentConfigurationDTO ref1DTO; + ServiceRegistration<?> ref1Reg; + if (mode.isOptionalService()) + { + ref1Service = Optional.of("Test1"); + ref1DTO = null; + ref1Reg = bundleContext.registerService(Optional.class, + (Optional<?>) ref1Service, null); + } + else + { + ref1DTO = getDisabledConfigurationAndEnable( + SINGLE_REFERENCE1, mode.isDynamic() && !mode.isMandatory()// + ? ComponentConfigurationDTO.ACTIVE + : ComponentConfigurationDTO.SATISFIED); + ref1Service = getServiceFromConfiguration(ref1DTO, + ConstructorSingleReference.class); + ref1Reg = null; + } cc = findComponentConfigurationByName(componentname, mode.getSecondState()); InjectOptionalComponent cmp2 = this.getServiceFromConfiguration(cc, InjectOptionalComponent.class); @@ -86,12 +101,24 @@ public class ComponentOptionalTest extends ComponentTestBase cmp2.checkMode(mode, null); } - ComponentConfigurationDTO ref2DTO = getDisabledConfigurationAndEnable( - SINGLE_REFERENCE2, ComponentConfigurationDTO.SATISFIED); - - ConstructorSingleReference ref2Service = getServiceFromConfiguration(ref2DTO, - ConstructorSingleReference.class); - + Object ref2Service; + ComponentConfigurationDTO ref2DTO; + ServiceRegistration<?> ref2Reg; + if (mode.isOptionalService()) + { + ref2Service = Optional.of("Test2"); + ref2DTO = null; + ref2Reg = bundleContext.registerService(Optional.class, + (Optional<?>) ref2Service, null); + } + else + { + ref2DTO = getDisabledConfigurationAndEnable( + SINGLE_REFERENCE2, ComponentConfigurationDTO.SATISFIED); + ref2Service = getServiceFromConfiguration(ref2DTO, + ConstructorSingleReference.class); + ref2Reg = null; + } if (mode.isMandatory() || mode.isDynamic()) { cmp2.checkMode(mode, ref1Service); @@ -101,7 +128,14 @@ public class ComponentOptionalTest extends ComponentTestBase cmp2.checkMode(mode, null); } - disableAndCheck(ref1DTO); + if (ref1Reg != null) + { + ref1Reg.unregister(); + } + if (ref1DTO != null) + { + disableAndCheck(ref1DTO); + } if (mode.isDynamic()) { @@ -167,4 +201,16 @@ public class ComponentOptionalTest extends ComponentTestBase { doTest(Mode.CONSTRUCTOR_OPTIONAL); } + + @Test + public void test_field_static_mandatory_service_optional() throws Exception + { + doTest(Mode.FIELD_SERVICE_STATIC_MANDATORY); + } + + @Test + public void test_constructor_static_mandatory_service_optional() throws Exception + { + doTest(Mode.CONSTRUCTOR_SERVICE_STATIC_MANDATORY); + } } diff --git a/scr/src/test/java/org/apache/felix/scr/integration/components/InjectOptionalComponent.java b/scr/src/test/java/org/apache/felix/scr/integration/components/InjectOptionalComponent.java index 90cbd1d..86a15c8 100644 --- a/scr/src/test/java/org/apache/felix/scr/integration/components/InjectOptionalComponent.java +++ b/scr/src/test/java/org/apache/felix/scr/integration/components/InjectOptionalComponent.java @@ -22,7 +22,9 @@ package org.apache.felix.scr.integration.components; import java.util.Map; import java.util.Optional; +import org.osgi.framework.BundleContext; import org.osgi.service.component.ComponentConstants; +import org.osgi.service.component.ComponentContext; import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO; public class InjectOptionalComponent @@ -33,17 +35,25 @@ public class InjectOptionalComponent FIELD_DYNAMIC_MANDATORY(1, true, true), // FIELD_STATIC_OPTIONAL(1, false, false), // FIELD_DYNAMIC_OPTIONAL(1, true, false), // + FIELD_SERVICE_STATIC_MANDATORY(3, false, true, true), // CONSTRUCTOR_MANDATORY(2, false, true), // - CONSTRUCTOR_OPTIONAL(2, false, false); + CONSTRUCTOR_OPTIONAL(2, false, false), // + CONSTRUCTOR_SERVICE_STATIC_MANDATORY(4, false, true, true); final int initCount; final int initialState; final int secondState; final boolean isMandatory; final boolean isDynamic; + final boolean isOptionalService; Mode(int initCount, boolean isDynamic, boolean isMandatory) { + this(initCount, isDynamic, isMandatory, false); + } + + Mode(int initCount, boolean isDynamic, boolean isMandatory, boolean isOptionalService) + { this.initCount = initCount; this.initialState = isMandatory ? ComponentConfigurationDTO.UNSATISFIED_REFERENCE @@ -52,6 +62,7 @@ public class InjectOptionalComponent : ComponentConfigurationDTO.ACTIVE; this.isMandatory = isMandatory; this.isDynamic = isDynamic; + this.isOptionalService = isOptionalService; } public int getInitCount() @@ -79,6 +90,10 @@ public class InjectOptionalComponent return isDynamic; } + public final boolean isOptionalService() + { + return isOptionalService; + } } private final Mode mode; @@ -87,10 +102,30 @@ public class InjectOptionalComponent private Optional<ConstructorSingleReference> refFieldStatic = null; private volatile Optional<ConstructorSingleReference> refFieldDynamic = null; - public InjectOptionalComponent(Map<String, Object> props, Optional<ConstructorSingleReference> single) + private Optional<?> refServiceFieldStatic = Optional.empty(); + private final Optional<?> refServiceConstructor; + + private InjectOptionalComponent(Map<String, Object> props, ComponentContext cc, BundleContext bc, Optional<ConstructorSingleReference> single, Optional<?> optionalSerice) { this.mode = getMode(props); this.refConstructor = single; + this.refServiceConstructor = optionalSerice == null ? Optional.empty() + : optionalSerice; + } + + public InjectOptionalComponent(Map<String, Object> props, ComponentContext cc, BundleContext bc, Optional<?> optionalService) + { + this(props, cc, bc, null, optionalService); + } + + public InjectOptionalComponent(Map<String, Object> props, ComponentContext cc, BundleContext bc) + { + this(props, cc, bc, null, null); + } + + public InjectOptionalComponent(Map<String, Object> props, Optional<ConstructorSingleReference> single) + { + this(props, null, null, single, null); } public InjectOptionalComponent(Map<String, Object> props) @@ -103,17 +138,20 @@ public class InjectOptionalComponent return Mode.valueOf((String) props.get(ComponentConstants.COMPONENT_NAME)); } - public boolean checkMode(Mode mode, ConstructorSingleReference expected) + public boolean checkMode(Mode mode, Object expected) { if (this.mode != mode) { throw new AssertionError( "Wrong mode, expected \"" + mode + "\" but was\"" + this.mode); } - Optional<ConstructorSingleReference> optional = getOptional(); + + final Object fExpected = expected == null || !mode.isOptionalService ? expected + : ((Optional<?>) expected).orElseGet(null); + Optional<?> optional = getOptional(); if (expected != null) { - return optional.map((c) -> checkExpected(expected, c)).orElseGet( + return optional.map((c) -> checkExpected(fExpected, c)).orElseGet( () -> throwAssertionError( "FAILED - expected: " + expected + " but got empty optional.")); } @@ -130,30 +168,33 @@ public class InjectOptionalComponent throw new AssertionError(message); } - private boolean checkExpected(ConstructorSingleReference expected, - ConstructorSingleReference actual) + private boolean checkExpected(Object expected, Object actual) { if (expected == actual) { return true; } throw new AssertionError( - "FAILED - expected: " + expected + " bug got: " + actual); + "FAILED - expected: " + expected + " but got: " + actual); } - private Optional<ConstructorSingleReference> getOptional() + private Optional<?> getOptional() { switch (mode) { case CONSTRUCTOR_MANDATORY: case CONSTRUCTOR_OPTIONAL: return refConstructor; + case CONSTRUCTOR_SERVICE_STATIC_MANDATORY: + return refServiceConstructor; case FIELD_DYNAMIC_MANDATORY: case FIELD_DYNAMIC_OPTIONAL: return refFieldDynamic; case FIELD_STATIC_MANDATORY: case FIELD_STATIC_OPTIONAL: return refFieldStatic; + case FIELD_SERVICE_STATIC_MANDATORY: + return refServiceFieldStatic; default: throw new UnsupportedOperationException(String.valueOf(mode)); } diff --git a/scr/src/test/resources/integration_test_inject_optional.xml b/scr/src/test/resources/integration_test_inject_optional.xml index a40be9d..93f9b54 100644 --- a/scr/src/test/resources/integration_test_inject_optional.xml +++ b/scr/src/test/resources/integration_test_inject_optional.xml @@ -48,6 +48,20 @@ /> </scr:component> + <scr:component name="FIELD_SERVICE_STATIC_MANDATORY" enabled="false" + init="3"> + <implementation class="org.apache.felix.scr.integration.components.InjectOptionalComponent" /> + <service factory="false"> + <provide interface="org.apache.felix.scr.integration.components.InjectOptionalComponent"/> + </service> + <reference + name="refServiceFieldStatic" + interface="java.util.Optional" + field="refServiceFieldStatic" + cardinality="1..1" + /> + </scr:component> + <!-- Dynamic Field --> <scr:component name="FIELD_DYNAMIC_MANDATORY" enabled="false" init="1"> @@ -103,6 +117,17 @@ parameter="1"/> </scr:component> + <scr:component name="CONSTRUCTOR_SERVICE_STATIC_MANDATORY" enabled="false" + init="4"> + <implementation class="org.apache.felix.scr.integration.components.InjectOptionalComponent" /> + <service factory="false"> + <provide interface="org.apache.felix.scr.integration.components.InjectOptionalComponent"/> + </service> + <reference interface="java.util.Optional" + cardinality="1..1" + parameter="3"/> + </scr:component> + <scr:component name="SingleReference1" enabled="false" activate="activator"> <implementation class="org.apache.felix.scr.integration.components.ConstructorSingleReference" /> <service factory="false">
