This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to annotated tag org.apache.sling.testing.osgi-mock-2.1.0 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-osgi-mock.git
commit 8ec500da8cb1d3cc5b30914f13c1ac4ee5696df8 Author: Stefan Seifert <[email protected]> AuthorDate: Tue Sep 13 09:30:53 2016 +0000 SLING-6051 osgi-mock: Support passing map/dictionary properties with object vararg parameter git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/mocks/osgi-mock@1760503 13f79535-47bb-0310-9956-ffa450edef68 --- .../testing/mock/osgi/ComponentContextBuilder.java | 5 ++ .../mock/osgi/{MapUtil.java => MapMergeUtil.java} | 45 +++++------ .../apache/sling/testing/mock/osgi/MapUtil.java | 94 +++++++++++----------- .../sling/testing/mock/osgi/MockBundleContext.java | 2 +- .../apache/sling/testing/mock/osgi/MockOsgi.java | 56 ++++++++++++- .../testing/mock/osgi/context/OsgiContextImpl.java | 31 ++++++- .../testing/mock/osgi/context/package-info.java | 2 +- .../testing/mock/osgi/junit/package-info.java | 2 +- .../sling/testing/mock/osgi/package-info.java | 2 +- .../sling/testing/mock/osgi/MapUtilTest.java | 57 +++++++++++++ .../OsgiServiceUtilActivateDeactivateTest.java | 2 +- .../testing/mock/osgi/OsgiServiceUtilTest.java | 3 + .../mock/osgi/context/OsgiContextImplTest.java | 19 +++++ 13 files changed, 236 insertions(+), 84 deletions(-) diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/ComponentContextBuilder.java b/src/main/java/org/apache/sling/testing/mock/osgi/ComponentContextBuilder.java index 2e8916a..a87ed41 100644 --- a/src/main/java/org/apache/sling/testing/mock/osgi/ComponentContextBuilder.java +++ b/src/main/java/org/apache/sling/testing/mock/osgi/ComponentContextBuilder.java @@ -54,6 +54,11 @@ public final class ComponentContextBuilder { return this; } + public ComponentContextBuilder properties(Object... properties) { + this.properties = MapUtil.toDictionary(properties); + return this; + } + public ComponentContextBuilder usingBundle(Bundle usingBundle) { this.usingBundle = usingBundle; return this; diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/MapUtil.java b/src/main/java/org/apache/sling/testing/mock/osgi/MapMergeUtil.java similarity index 78% copy from src/main/java/org/apache/sling/testing/mock/osgi/MapUtil.java copy to src/main/java/org/apache/sling/testing/mock/osgi/MapMergeUtil.java index e53442b..246ecc5 100644 --- a/src/main/java/org/apache/sling/testing/mock/osgi/MapUtil.java +++ b/src/main/java/org/apache/sling/testing/mock/osgi/MapMergeUtil.java @@ -18,11 +18,12 @@ */ package org.apache.sling.testing.mock.osgi; +import static org.apache.sling.testing.mock.osgi.MapUtil.toDictionary; +import static org.apache.sling.testing.mock.osgi.MapUtil.toMap; + import java.io.IOException; import java.util.Dictionary; -import java.util.Enumeration; import java.util.HashMap; -import java.util.Hashtable; import java.util.Map; import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.OsgiMetadata; @@ -31,31 +32,25 @@ import org.osgi.service.cm.Configuration; import org.osgi.service.cm.ConfigurationAdmin; /** - * Map util methods. + * Map util merge methods. */ -final class MapUtil { +final class MapMergeUtil { - public static <T, U> Dictionary<T, U> toDictionary(Map<T, U> map) { - if (map == null) { - return null; - } - return new Hashtable<T, U>(map); + private MapMergeUtil() { + // static methods only } - - public static <T, U> Map<T, U> toMap(Dictionary<T, U> dictionary) { - if (dictionary == null) { - return null; - } - Map<T, U> map = new HashMap<T, U>(); - Enumeration<T> keys = dictionary.keys(); - while (keys.hasMoreElements()) { - T key = keys.nextElement(); - map.put(key, dictionary.get(key)); - } - return map; - } - - public static Dictionary<String, Object> propertiesMergeWithOsgiMetadata(Object target, + + /** + * Merge service properties from three sources (with this precedence): + * 1. Properties defined in calling unit test code + * 2. Properties from ConfigurationAdmin + * 3. Properties from OSGi SCR metadata + * @param target Target service + * @param configAdmin Configuration admin or null if none is registered + * @param properties Properties from unit test code or null if none where passed + * @return Merged properties + */ + static Dictionary<String, Object> propertiesMergeWithOsgiMetadata(Object target, ConfigurationAdmin configAdmin, Dictionary<String, Object> properties) { return toDictionary(propertiesMergeWithOsgiMetadata(target, configAdmin, toMap(properties))); @@ -71,7 +66,7 @@ final class MapUtil { * @param properties Properties from unit test code or null if none where passed * @return Merged properties */ - public static Map<String, Object> propertiesMergeWithOsgiMetadata(Object target, + static Map<String, Object> propertiesMergeWithOsgiMetadata(Object target, ConfigurationAdmin configAdmin, Map<String, Object> properties) { Map<String, Object> mergedProperties = new HashMap<String, Object>(); diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/MapUtil.java b/src/main/java/org/apache/sling/testing/mock/osgi/MapUtil.java index e53442b..c596fed 100644 --- a/src/main/java/org/apache/sling/testing/mock/osgi/MapUtil.java +++ b/src/main/java/org/apache/sling/testing/mock/osgi/MapUtil.java @@ -18,23 +18,28 @@ */ package org.apache.sling.testing.mock.osgi; -import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; import java.util.Dictionary; import java.util.Enumeration; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; -import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.OsgiMetadata; -import org.osgi.framework.Constants; -import org.osgi.service.cm.Configuration; -import org.osgi.service.cm.ConfigurationAdmin; - /** * Map util methods. */ -final class MapUtil { +public final class MapUtil { + + private MapUtil() { + // static methods only + } + /** + * Convert map to dictionary. + * @param map Map + * @return Dictionary + */ public static <T, U> Dictionary<T, U> toDictionary(Map<T, U> map) { if (map == null) { return null; @@ -42,6 +47,11 @@ final class MapUtil { return new Hashtable<T, U>(map); } + /** + * Convert Dictionary to map + * @param dictionary Dictionary + * @return Map + */ public static <T, U> Map<T, U> toMap(Dictionary<T, U> dictionary) { if (dictionary == null) { return null; @@ -55,55 +65,41 @@ final class MapUtil { return map; } - public static Dictionary<String, Object> propertiesMergeWithOsgiMetadata(Object target, - ConfigurationAdmin configAdmin, - Dictionary<String, Object> properties) { - return toDictionary(propertiesMergeWithOsgiMetadata(target, configAdmin, toMap(properties))); + /** + * Convert key/value pairs to dictionary + * @param args Key/value pairs + * @return Dictionary + */ + public static Dictionary<String, Object> toDictionary(Object... args) { + return toDictionary(toMap(args)); } /** - * Merge service properties from three sources (with this precedence): - * 1. Properties defined in calling unit test code - * 2. Properties from ConfigurationAdmin - * 3. Properties from OSGi SCR metadata - * @param target Target service - * @param configAdmin Configuration admin or null if none is registered - * @param properties Properties from unit test code or null if none where passed - * @return Merged properties + * Convert key/value pairs to map + * @param args Key/value pairs + * @return Map */ - public static Map<String, Object> propertiesMergeWithOsgiMetadata(Object target, - ConfigurationAdmin configAdmin, - Map<String, Object> properties) { - Map<String, Object> mergedProperties = new HashMap<String, Object>(); - - OsgiMetadata metadata = OsgiMetadataUtil.getMetadata(target.getClass()); - if (metadata != null) { - Map<String,Object> metadataProperties = metadata.getProperties(); - if (metadataProperties != null) { - mergedProperties.putAll(metadataProperties); - - // merge with configuration from config admin - if (configAdmin != null) { - Object pid = metadataProperties.get(Constants.SERVICE_PID); - if (pid != null) { - try { - Configuration config = configAdmin.getConfiguration(pid.toString()); - mergedProperties.putAll(toMap(config.getProperties())); - } - catch (IOException ex) { - throw new RuntimeException("Unable to read config for pid " + pid, ex); - } - } - } + @SuppressWarnings("unchecked") + public static Map<String, Object> toMap(Object... args) { + if (args == null || args.length == 0) { + return Collections.emptyMap(); + } + if (args.length == 1) { + if (args[0] instanceof Map) { + return (Map)args[0]; + } + else if (args[0] instanceof Dictionary) { + return toMap((Dictionary)args[0]); } } - - // merge with properties from calling unit test code - if (properties != null) { - mergedProperties.putAll(properties); + if (args.length % 2 != 0) { + throw new IllegalArgumentException("args must be an even number of name/values:" + Arrays.asList(args)); + } + final Map<String, Object> result = new HashMap<>(); + for (int i=0 ; i < args.length; i+=2) { + result.put(args[i].toString(), args[i+1]); } - - return mergedProperties; + return result; } } diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java b/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java index 827ef43..c57dcc6 100644 --- a/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java +++ b/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java @@ -112,7 +112,7 @@ class MockBundleContext implements BundleContext { @SuppressWarnings("unchecked") @Override public ServiceRegistration registerService(final String[] clazzes, final Object service, final Dictionary properties) { - Dictionary<String, Object> mergedPropertes = MapUtil.propertiesMergeWithOsgiMetadata(service, configAdmin, properties); + Dictionary<String, Object> mergedPropertes = MapMergeUtil.propertiesMergeWithOsgiMetadata(service, configAdmin, properties); MockServiceRegistration registration = new MockServiceRegistration(this.bundle, clazzes, service, mergedPropertes, this); handleRefsUpdateOnRegister(registration); this.registeredServices.add(registration); diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/MockOsgi.java b/src/main/java/org/apache/sling/testing/mock/osgi/MockOsgi.java index 4834647..a4e9923 100644 --- a/src/main/java/org/apache/sling/testing/mock/osgi/MockOsgi.java +++ b/src/main/java/org/apache/sling/testing/mock/osgi/MockOsgi.java @@ -18,7 +18,7 @@ */ package org.apache.sling.testing.mock.osgi; -import static org.apache.sling.testing.mock.osgi.MapUtil.propertiesMergeWithOsgiMetadata; +import static org.apache.sling.testing.mock.osgi.MapMergeUtil.propertiesMergeWithOsgiMetadata; import static org.apache.sling.testing.mock.osgi.MapUtil.toDictionary; import static org.apache.sling.testing.mock.osgi.MapUtil.toMap; @@ -82,6 +82,14 @@ public final class MockOsgi { } /** + * @param properties Properties + * @return Mocked {@link ComponentContext} instance + */ + public static ComponentContext newComponentContext(Object... properties) { + return componentContext().properties(properties).build(); + } + + /** * @param bundleContext Bundle context * @param properties Properties * @return Mocked {@link ComponentContext} instance @@ -96,7 +104,18 @@ public final class MockOsgi { * @param properties Properties * @return Mocked {@link ComponentContext} instance */ - public static ComponentContext newComponentContext(BundleContext bundleContext, Map<String, Object> properties) { + public static ComponentContext newComponentContext(BundleContext bundleContext, + Map<String, Object> properties) { + return componentContext().bundleContext(bundleContext).properties(properties).build(); + } + + /** + * @param bundleContext Bundle context + * @param properties Properties + * @return Mocked {@link ComponentContext} instance + */ + public static ComponentContext newComponentContext(BundleContext bundleContext, + Object... properties) { return componentContext().bundleContext(bundleContext).properties(properties).build(); } @@ -162,6 +181,17 @@ public final class MockOsgi { } /** + * Simulate activation of service instance. Invokes the @Activate annotated method. + * @param target Service instance. + * @param bundleContext Bundle context + * @param properties Properties + * @return true if activation method was called. False if no activate method is defined. + */ + public static boolean activate(Object target, BundleContext bundleContext, Object... properties) { + return activate(target, bundleContext, toDictionary(properties)); + } + + /** * Simulate deactivation of service instance. Invokes the @Deactivate annotated method. * @param target Service instance. * @param bundleContext Bundle context. @@ -196,6 +226,17 @@ public final class MockOsgi { } /** + * Simulate activation of service instance. Invokes the @Deactivate annotated method. + * @param target Service instance. + * @param bundleContext Bundle context + * @param properties Properties + * @return true if deactivation method was called. False if no deactivate method is defined. + */ + public static boolean deactivate(Object target, BundleContext bundleContext, Object... properties) { + return deactivate(target, bundleContext, toDictionary(properties)); + } + + /** * Simulate configuration modification of service instance. Invokes the @Modified annotated method. * @param target Service instance. * @param bundleContext Bundle context @@ -220,6 +261,17 @@ public final class MockOsgi { } /** + * Simulate configuration modification of service instance. Invokes the @Modified annotated method. + * @param target Service instance. + * @param bundleContext Bundle context + * @param properties Properties + * @return true if modified method was called. False if no modified method is defined. + */ + public static boolean modified(Object target, BundleContext bundleContext, Object... properties) { + return modified(target, bundleContext, toDictionary(properties)); + } + + /** * Deactivates all bundles registered in the mocked bundle context. * @param bundleContext Bundle context */ diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/context/OsgiContextImpl.java b/src/main/java/org/apache/sling/testing/mock/osgi/context/OsgiContextImpl.java index 5953fef..63b4b41 100644 --- a/src/main/java/org/apache/sling/testing/mock/osgi/context/OsgiContextImpl.java +++ b/src/main/java/org/apache/sling/testing/mock/osgi/context/OsgiContextImpl.java @@ -24,6 +24,7 @@ import java.util.Hashtable; import java.util.Map; import org.apache.commons.lang3.ArrayUtils; +import org.apache.sling.testing.mock.osgi.MapUtil; import org.apache.sling.testing.mock.osgi.MockEventAdmin; import org.apache.sling.testing.mock.osgi.MockOsgi; import org.osgi.annotation.versioning.ConsumerType; @@ -91,7 +92,7 @@ public class OsgiContextImpl { * @return Registered service instance */ public final <T> T registerService(final T service) { - return registerService(null, service, null); + return registerService(null, service, (Map<String,Object>)null); } /** @@ -102,7 +103,7 @@ public class OsgiContextImpl { * @return Registered service instance */ public final <T> T registerService(final Class<T> serviceClass, final T service) { - return registerService(serviceClass, service, null); + return registerService(serviceClass, service, (Map<String,Object>)null); } /** @@ -123,6 +124,18 @@ public class OsgiContextImpl { } /** + * Registers a service in the mocked OSGi environment. + * @param <T> Service type + * @param serviceClass Service class + * @param service Service instance + * @param properties Service properties (optional) + * @return Registered service instance + */ + public final <T> T registerService(final Class<T> serviceClass, final T service, final Object... properties) { + return registerService(serviceClass, service, MapUtil.toMap(properties)); + } + + /** * Injects dependencies, activates and registers a service in the mocked * OSGi environment. * @param <T> Service type @@ -130,7 +143,7 @@ public class OsgiContextImpl { * @return Registered service instance */ public final <T> T registerInjectActivateService(final T service) { - return registerInjectActivateService(service, null); + return registerInjectActivateService(service, (Map<String,Object>)null); } /** @@ -149,6 +162,18 @@ public class OsgiContextImpl { } /** + * Injects dependencies, activates and registers a service in the mocked + * OSGi environment. + * @param <T> Service type + * @param service Service instance + * @param properties Service properties (optional) + * @return Registered service instance + */ + public final <T> T registerInjectActivateService(final T service, final Object... properties) { + return registerInjectActivateService(service, MapUtil.toMap(properties)); + } + + /** * Lookup a single service * @param <ServiceType> Service type * @param serviceType The type (interface) of the service. diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/context/package-info.java b/src/main/java/org/apache/sling/testing/mock/osgi/context/package-info.java index c51be33..c54910f 100644 --- a/src/main/java/org/apache/sling/testing/mock/osgi/context/package-info.java +++ b/src/main/java/org/apache/sling/testing/mock/osgi/context/package-info.java @@ -19,5 +19,5 @@ /** * OSGi context implementation for unit tests. */ [email protected]("1.0.1") [email protected]("1.1") package org.apache.sling.testing.mock.osgi.context; diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/junit/package-info.java b/src/main/java/org/apache/sling/testing/mock/osgi/junit/package-info.java index b055517..eeb2980 100644 --- a/src/main/java/org/apache/sling/testing/mock/osgi/junit/package-info.java +++ b/src/main/java/org/apache/sling/testing/mock/osgi/junit/package-info.java @@ -19,5 +19,5 @@ /** * Rule for providing easy access to OSGi context in JUnit tests. */ [email protected]("1.0") [email protected]("1.1") package org.apache.sling.testing.mock.osgi.junit; diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/package-info.java b/src/main/java/org/apache/sling/testing/mock/osgi/package-info.java index 69c2fa1..b0f0eaf 100644 --- a/src/main/java/org/apache/sling/testing/mock/osgi/package-info.java +++ b/src/main/java/org/apache/sling/testing/mock/osgi/package-info.java @@ -19,5 +19,5 @@ /** * Mock implementation of selected OSGi APIs. */ [email protected]("3.0") [email protected]("3.1") package org.apache.sling.testing.mock.osgi; diff --git a/src/test/java/org/apache/sling/testing/mock/osgi/MapUtilTest.java b/src/test/java/org/apache/sling/testing/mock/osgi/MapUtilTest.java new file mode 100644 index 0000000..369abdf --- /dev/null +++ b/src/test/java/org/apache/sling/testing/mock/osgi/MapUtilTest.java @@ -0,0 +1,57 @@ +/* + * 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.sling.testing.mock.osgi; + +import static org.junit.Assert.assertEquals; + +import java.util.Dictionary; +import java.util.Map; + +import org.junit.Test; + +import com.google.common.collect.ImmutableMap; + +public class MapUtilTest { + + @Test + public void testMapDictionary() { + Map<String,Object> map = ImmutableMap.<String, Object>of("param1", "var1", "param2", 123, "param3", true); + + Dictionary<String, Object> dict = MapUtil.toDictionary(map); + Map<String,Object> convertedMap = MapUtil.toMap(dict); + + assertEquals(map, convertedMap); + } + + @Test + public void testMapObjectVarargs() { + Map<String, Object> convertedMap = MapUtil.toMap("param1", "var1", "param2", 123, "param3", true); + + assertEquals(ImmutableMap.<String, Object>of("param1", "var1", "param2", 123, "param3", true), convertedMap); + } + + @Test + public void testDictionaryObjectVarargs() { + Dictionary<String, Object> dict = MapUtil.toDictionary("param1", "var1", "param2", 123, "param3", true); + Map<String,Object> convertedMap = MapUtil.toMap(dict); + + assertEquals(ImmutableMap.<String, Object>of("param1", "var1", "param2", 123, "param3", true), convertedMap); + } + +} diff --git a/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilActivateDeactivateTest.java b/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilActivateDeactivateTest.java index 6974c01..6139710 100644 --- a/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilActivateDeactivateTest.java +++ b/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilActivateDeactivateTest.java @@ -58,7 +58,7 @@ public class OsgiServiceUtilActivateDeactivateTest { public void testService2() { Service2 service = new Service2(); - assertTrue(MockOsgi.activate(service, bundleContext, map)); + assertTrue(MockOsgi.activate(service, bundleContext, "prop1", "value1")); assertTrue(service.isActivated()); assertSame(bundleContext, service.getBundleContext()); diff --git a/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java b/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java index 8d086ad..26e6bba 100644 --- a/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java +++ b/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java @@ -121,6 +121,9 @@ public class OsgiServiceUtilTest { Dictionary<String,Object> newPropertiesDictonary = new Hashtable<String,Object>(newProperties); MockOsgi.modified(service3, bundleContext, newPropertiesDictonary); assertEquals(newProperties.get("prop3"), service3.getConfig().get("prop3")); + + MockOsgi.modified(service3, bundleContext, "prop3", "value4"); + assertEquals("value4", service3.getConfig().get("prop3")); } @Test diff --git a/src/test/java/org/apache/sling/testing/mock/osgi/context/OsgiContextImplTest.java b/src/test/java/org/apache/sling/testing/mock/osgi/context/OsgiContextImplTest.java index 1977258..65b7251 100644 --- a/src/test/java/org/apache/sling/testing/mock/osgi/context/OsgiContextImplTest.java +++ b/src/test/java/org/apache/sling/testing/mock/osgi/context/OsgiContextImplTest.java @@ -82,6 +82,17 @@ public class OsgiContextImplTest { } @Test + public void testRegisterServiceWithPropertiesVarargs() { + Set<String> myService = new HashSet<String>(); + context.registerService(Set.class, myService, "prop1", "value1"); + + ServiceReference<?> serviceReference = context.bundleContext().getServiceReference(Set.class.getName()); + Object serviceResult = context.bundleContext().getService(serviceReference); + assertSame(myService, serviceResult); + assertEquals("value1", serviceReference.getProperty("prop1")); + } + + @Test public void testRegisterMultipleServices() { Set<String> myService1 = new HashSet<String>(); context.registerService(Set.class, myService1); @@ -103,6 +114,14 @@ public class OsgiContextImplTest { context.registerInjectActivateService(new OsgiServiceUtilTest.Service3()); } + @Test + public void testRegisterInjectActivateWithProperties() { + context.registerService(ServiceInterface1.class, mock(ServiceInterface1.class)); + context.registerService(ServiceInterface2.class, mock(ServiceInterface2.class)); + OsgiServiceUtilTest.Service3 service = context.registerInjectActivateService(new OsgiServiceUtilTest.Service3(), "prop1", "value3"); + assertEquals("value3", service.getConfig().get("prop1")); + } + @Test(expected=RuntimeException.class) public void testRegisterInjectActivate_RefrenceMissing() { context.registerInjectActivateService(new OsgiServiceUtilTest.Service3()); -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
