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-1.8.0 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-osgi-mock.git
commit 29207e030a22ad4234d7bdd9fb76c2a2a307c666 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/branches/testing/mocks/osgi-mock-1.x@1760503 13f79535-47bb-0310-9956-ffa450edef68 --- .../testing/mock/osgi/ComponentContextBuilder.java | 5 ++ .../mock/osgi/{MapUtil.java => MapMergeUtil.java} | 31 ++------ .../apache/sling/testing/mock/osgi/MapUtil.java | 93 ++++++++++------------ .../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, 223 insertions(+), 82 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 83% 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 45d7a31..c6dccb7 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,28 +32,12 @@ import org.osgi.service.cm.Configuration; import org.osgi.service.cm.ConfigurationAdmin; /** - * Map util methods. + * Map merge util methods. */ -final class MapUtil { - - public static <T, U> Dictionary<T, U> toDictionary(Map<T, U> map) { - if (map == null) { - return null; - } - return new Hashtable<T, U>(map); - } - - 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; +final class MapMergeUtil { + + private MapMergeUtil() { + // static methods only } public static Dictionary<String, Object> propertiesMergeWithOsgiMetadata(Object target, 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 45d7a31..0f0775c 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,56 +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 */ @SuppressWarnings("unchecked") - 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); - } - } - } + 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<String, Object>(); + 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 003a304..ce94c04 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 @@ -109,7 +109,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 a189fda..4e04921 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(); } @@ -202,6 +221,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. * @return true if deactivation method was called. False if no deactivate method is defined. @@ -276,6 +306,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 @@ -299,6 +340,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, toMap(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 4847a2d..ab160ac 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.framework.BundleContext; @@ -92,7 +93,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); } /** @@ -103,7 +104,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); } /** @@ -124,6 +125,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 @@ -131,7 +144,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); } /** @@ -150,6 +163,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 1ac49a4..debaa88 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") [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 dd18eb6..83cd0a8 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 fe5f126..1d3d622 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]("2.4") [email protected]("2.5") 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 d848fe2..efd898d 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 f8b9a73..253b401 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 7086325..2ab6bd8 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); @@ -101,6 +112,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]>.
