blob: 1f5497a06ad172cf6818eefadf97f0cc9a3f7194 [file] [log] [blame]
/*
* 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 static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import com.google.common.collect.ImmutableMap;
@SuppressWarnings("null")
public class OsgiServiceUtilTest {
private BundleContext bundleContext = MockOsgi.newBundleContext();
private Service1 service1;
private Service2 service2;
@Before
public void setUp() {
service1 = new Service1();
service2 = new Service2();
bundleContext.registerService(ServiceInterface1.class.getName(), service1, null);
bundleContext.registerService(ServiceInterface2.class.getName(), service2, null);
}
@After
public void tearDown() {
MockOsgi.shutdown(bundleContext);
}
@Test
public void testService3() {
Service3 service3 = new Service3();
assertTrue(MockOsgi.injectServices(service3, bundleContext));
Dictionary<String, Object> service3Config = new Hashtable<String, Object>();
service3Config.put("prop1", "value1");
assertTrue(MockOsgi.activate(service3, bundleContext, service3Config));
assertNotNull(service3.getComponentContext());
assertEquals(service3Config.get("prop1"), service3.getComponentContext().getProperties().get("prop1"));
assertSame(service1, service3.getReference1());
List<ServiceInterface2> references2 = service3.getReferences2();
assertEquals(1, references2.size());
assertSame(service2, references2.get(0));
List<ServiceSuperInterface3> references3 = service3.getReferences3();
assertEquals(1, references3.size());
assertSame(service2, references3.get(0));
List<Map<String, Object>> reference3Configs = service3.getReference3Configs();
assertEquals(1, reference3Configs.size());
assertEquals(200, reference3Configs.get(0).get(Constants.SERVICE_RANKING));
assertTrue(MockOsgi.deactivate(service3, bundleContext));
assertNull(service3.getComponentContext());
}
@Test
public void testService3_Config() {
BundleContext bundleContext = MockOsgi.newBundleContext();
Map<String,Object> initialProperites = ImmutableMap.<String, Object>of("prop1", "value1");
Service3 service3 = new Service3();
MockOsgi.activate(service3, bundleContext, initialProperites);
assertEquals(initialProperites.get("prop1"), service3.getConfig().get("prop1"));
Map<String,Object> newProperties = ImmutableMap.<String, Object>of("prop2", "value2");
MockOsgi.modified(service3, bundleContext, newProperties);
assertEquals(newProperties.get("prop2"), service3.getConfig().get("prop2"));
newProperties = ImmutableMap.<String, Object>of("prop3", "value3");
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
public void testService4() {
Service4 service4 = new Service4();
assertTrue(MockOsgi.injectServices(service4, bundleContext));
assertFalse(MockOsgi.activate(service4, bundleContext));
assertSame(service1, service4.getReference1());
}
@Test(expected=NoScrMetadataException.class)
public void testInjectServicesNoMetadata() {
MockOsgi.injectServices(new Object(), MockOsgi.newBundleContext());
}
@Test(expected=NoScrMetadataException.class)
public void testActivateNoMetadata() {
MockOsgi.activate(new Object(), bundleContext);
}
@Test(expected=NoScrMetadataException.class)
public void testDeactivateNoMetadata() {
MockOsgi.deactivate(new Object(), bundleContext);
}
@Test(expected=NoScrMetadataException.class)
public void testModifiedNoMetadata() {
MockOsgi.modified(new Object(), MockOsgi.newBundleContext(), ImmutableMap.<String,Object>of());
}
@Test
public void testMockedService() {
Service5 service5 = Mockito.spy(new Service5());
Mockito.doReturn(true).when(service5).doRemoteThing();
MockOsgi.injectServices(service5, bundleContext);
MockOsgi.activate(service5, bundleContext, (Dictionary<String, Object>) null);
bundleContext.registerService(ServiceInterface5.class.getName(), service5, null);
assertSame(service5, bundleContext.getService(
bundleContext.getServiceReference(ServiceInterface5.class.getName())));
assertEquals(true, service5.doRemoteThing());
}
@Test
public void testServiceFactoryViaScr() {
ServiceFactory1 serviceFactory1 = new ServiceFactory1();
MockOsgi.injectServices(serviceFactory1, bundleContext);
MockOsgi.activate(serviceFactory1, bundleContext, (Dictionary<String, Object>) null);
bundleContext.registerService(ServiceFactory1.class.getName(), serviceFactory1, null);
assertSame(serviceFactory1, bundleContext.getService(
bundleContext.getServiceReference(ServiceFactory1.class.getName())));
}
@Test
public void testServiceFactoryViaManualRegistration() {
final ServiceFactory1 serviceFactory1 = new ServiceFactory1();
bundleContext.registerService(ServiceFactory1.class.getName(), new ServiceFactory() {
@Override
public Object getService(Bundle bundle, ServiceRegistration registration) {
return serviceFactory1;
}
@Override
public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
// nothing to do
}
}, null);
assertSame(serviceFactory1, bundleContext.getService(
bundleContext.getServiceReference(ServiceFactory1.class.getName())));
}
public interface ServiceInterface1 {
// no methods
}
public interface ServiceInterface1Optional {
// no methods
}
public interface ServiceInterface2 {
// no methods
}
public interface ServiceInterface3 extends ServiceSuperInterface3 {
// no methods
}
public interface ServiceSuperInterface3 {
// no methods
}
@Component(service = ServiceInterface1.class,
property = Constants.SERVICE_RANKING + ":Integer=100")
public static class Service1 implements ServiceInterface1 {
// dummy interface
}
@Component(service = { ServiceInterface2.class, ServiceInterface3.class },
property = Constants.SERVICE_RANKING + ":Integer=200")
public static class Service2 implements ServiceInterface2, ServiceInterface3 {
// dummy interface
}
@Component(reference = { @Reference(name = "reference2", service = ServiceInterface2.class, cardinality = ReferenceCardinality.AT_LEAST_ONE,
bind="bindReference2", unbind="unbindReference2") })
public static class Service3 {
@Reference(bind="bindReference1", unbind="unbindReference1")
private ServiceInterface1 reference1;
@Reference(cardinality = ReferenceCardinality.OPTIONAL, bind="bindReference1Optional", unbind="unbindReference1Optional")
private ServiceInterface1Optional reference1Optional;
private List<ServiceReference> references2 = new ArrayList<ServiceReference>();
@Reference(name = "reference3", service = ServiceInterface3.class, cardinality = ReferenceCardinality.MULTIPLE,
bind="bindReference3", unbind="unbindReference3")
private List<ServiceSuperInterface3> references3 = new ArrayList<ServiceSuperInterface3>();
private List<Map<String, Object>> reference3Configs = new ArrayList<Map<String, Object>>();
private ComponentContext componentContext;
private Map<String, Object> config;
@Activate
private void activate(ComponentContext ctx) {
this.componentContext = ctx;
this.config = MapUtil.toMap(ctx.getProperties());
}
@Deactivate
private void deactivate(ComponentContext ctx) {
this.componentContext = null;
}
@Modified
private void modified(Map<String,Object> newConfig) {
this.config = newConfig;
}
public ServiceInterface1 getReference1() {
return this.reference1;
}
public ServiceInterface1Optional getReference1Optional() {
return this.reference1Optional;
}
public List<ServiceInterface2> getReferences2() {
List<ServiceInterface2> services = new ArrayList<ServiceInterface2>();
for (ServiceReference<?> serviceReference : references2) {
services.add((ServiceInterface2)componentContext.getBundleContext().getService(serviceReference));
}
return services;
}
public List<ServiceSuperInterface3> getReferences3() {
return this.references3;
}
public List<Map<String, Object>> getReference3Configs() {
return this.reference3Configs;
}
public ComponentContext getComponentContext() {
return this.componentContext;
}
public Map<String, Object> getConfig() {
return config;
}
protected void bindReference1Optional(ServiceInterface1Optional service) {
reference1Optional = service;
}
protected void unbindReference1Optional(ServiceInterface1Optional service) {
reference1Optional = null;
}
protected void bindReference1(ServiceInterface1 service) {
reference1 = service;
}
protected void unbindReference1(ServiceInterface1 service) {
reference1 = null;
}
protected void bindReference2(ServiceReference serviceReference) {
references2.add(serviceReference);
}
protected void unbindReference2(ServiceReference serviceReference) {
references2.remove(serviceReference);
}
protected void bindReference3(ServiceSuperInterface3 service, Map<String, Object> serviceConfig) {
references3.add(service);
reference3Configs.add(serviceConfig);
}
protected void unbindReference3(ServiceSuperInterface3 service, Map<String, Object> serviceConfig) {
references3.remove(service);
reference3Configs.remove(serviceConfig);
}
}
public static class Service3OsgiR6 {
private ServiceInterface1 reference1;
private ServiceInterface1Optional reference1Optional;
private List<ServiceReference> references2;
private List<ServiceSuperInterface3> references3;
private List<ServiceSuperInterface3> references3Filtered;
private ServiceSuperInterface3 reference3DynamicFiltered;
private ComponentContext componentContext;
private Map<String, Object> config;
@Activate
private void activate(ComponentContext ctx) {
this.componentContext = ctx;
this.config = MapUtil.toMap(ctx.getProperties());
}
@Deactivate
private void deactivate(ComponentContext ctx) {
this.componentContext = null;
}
@Modified
private void modified(Map<String,Object> newConfig) {
this.config = newConfig;
}
public ServiceInterface1 getReference1() {
return this.reference1;
}
public ServiceInterface1Optional getReference1Optional() {
return this.reference1Optional;
}
public List<ServiceInterface2> getReferences2() {
List<ServiceInterface2> services = new ArrayList<ServiceInterface2>();
for (ServiceReference<?> serviceReference : references2) {
services.add((ServiceInterface2)componentContext.getBundleContext().getService(serviceReference));
}
return services;
}
public List<ServiceSuperInterface3> getReferences3() {
return this.references3;
}
public List<ServiceSuperInterface3> getReferences3Filtered() {
return this.references3Filtered;
}
public ServiceSuperInterface3 getReference3DynamicFiltered() {
return this.reference3DynamicFiltered;
}
public ComponentContext getComponentContext() {
return this.componentContext;
}
public Map<String, Object> getConfig() {
return config;
}
}
@Component(reference = { @Reference(name = "reference2", service = ServiceInterface2.class, cardinality = ReferenceCardinality.AT_LEAST_ONE,
bind="bindReference2", unbind="unbindReference2") })
public static class Service3StaticGreedy {
@Reference(bind="bindReference1", unbind="unbindReference1")
private ServiceInterface1 reference1;
@Reference(cardinality = ReferenceCardinality.OPTIONAL, bind="bindReference1Optional", unbind="unbindReference1Optional")
private ServiceInterface1Optional reference1Optional;
private List<ServiceReference> references2 = new ArrayList<ServiceReference>();
@Reference(name = "reference3", service = ServiceInterface3.class, cardinality = ReferenceCardinality.MULTIPLE,
bind="bindReference3", unbind="unbindReference3")
private List<ServiceSuperInterface3> references3 = new ArrayList<ServiceSuperInterface3>();
private List<Map<String, Object>> reference3Configs = new ArrayList<Map<String, Object>>();
private ComponentContext componentContext;
private Map<String, Object> config;
@Activate
private void activate(ComponentContext ctx) {
this.componentContext = ctx;
this.config = MapUtil.toMap(ctx.getProperties());
}
@Deactivate
private void deactivate(ComponentContext ctx) {
this.componentContext = null;
}
@Modified
private void modified(Map<String,Object> newConfig) {
this.config = newConfig;
}
public ServiceInterface1 getReference1() {
return this.reference1;
}
public ServiceInterface1Optional getReference1Optional() {
return this.reference1Optional;
}
public List<ServiceInterface2> getReferences2() {
List<ServiceInterface2> services = new ArrayList<ServiceInterface2>();
for (ServiceReference<?> serviceReference : references2) {
services.add((ServiceInterface2)componentContext.getBundleContext().getService(serviceReference));
}
return services;
}
public List<ServiceSuperInterface3> getReferences3() {
return this.references3;
}
public List<Map<String, Object>> getReference3Configs() {
return this.reference3Configs;
}
public ComponentContext getComponentContext() {
return this.componentContext;
}
public Map<String, Object> getConfig() {
return config;
}
protected void bindReference1Optional(ServiceInterface1Optional service) {
reference1Optional = service;
}
protected void unbindReference1Optional(ServiceInterface1Optional service) {
reference1Optional = null;
}
protected void bindReference1(ServiceInterface1 service) {
reference1 = service;
}
protected void unbindReference1(ServiceInterface1 service) {
reference1 = null;
}
protected void bindReference2(ServiceReference serviceReference) {
references2.add(serviceReference);
}
protected void unbindReference2(ServiceReference serviceReference) {
references2.remove(serviceReference);
}
protected void bindReference3(ServiceSuperInterface3 service, Map<String, Object> serviceConfig) {
references3.add(service);
reference3Configs.add(serviceConfig);
}
protected void unbindReference3(ServiceSuperInterface3 service, Map<String, Object> serviceConfig) {
references3.remove(service);
reference3Configs.remove(serviceConfig);
}
}
@Component(reference = @Reference(service = ServiceInterface1.class, name = "customName", bind = "customBind", unbind = "customUnbind"))
public static class Service4 {
private ServiceInterface1 reference1;
public ServiceInterface1 getReference1() {
return this.reference1;
}
protected void customBind(ServiceInterface1 service) {
reference1 = service;
}
protected void customUnbind(ServiceInterface1 service) {
reference1 = null;
}
}
@Component(service = { ServiceInterface5.class })
public static class Service5 implements ServiceInterface5 {
@Override
public boolean doRemoteThing() {
return false;
}
}
public interface ServiceInterface5 {
boolean doRemoteThing();
}
@Component(service = ServiceFactory1.class, servicefactory = true)
public static class ServiceFactory1 {
}
}