blob: 5b12dbce962b9b2240e6413fb5f6bd60753a3541 [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.felix.dm.tracker;
import static org.junit.Assert.assertArrayEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.apache.felix.dm.DependencyManager;
import org.apache.felix.dm.tracker.ServiceTracker.Tracked;
import org.junit.Test;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceReference;
/**
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
@SuppressWarnings("rawtypes")
public class TrackedTest {
@Test
public void testSetInitialHideAspects() {
System.out.println("testSetInitialHideAspects");
TestCustomizer customizer = new TestCustomizer();
ServiceTracker tracker = new TestTracker(customizer);
tracker.open();
Tracked tracked = tracker.getTracked();
Object[] initialReferences = new Object[] {
createServiceReference(1L),
createServiceReference(2L, 1L, 10),
createServiceReference(3L),
createServiceReference(4L, 1L, 5),
createServiceReference(5L, 3L, 5),
};
tracked.setInitial(initialReferences);
tracked.trackInitial();
tracked.getExecutor().execute();
assertArrayEquals(new Long[] { 2L, 5L }, customizer.getServiceReferenceIds());
}
@Test
public void testUnHideAspect() {
System.out.println("testUnhideAspect");
TestCustomizer customizer = new TestCustomizer();
ServiceTracker tracker = new TestTracker(customizer);
tracker.open();
Tracked tracked = tracker.getTracked();
ServiceReference<?>[] initialReferences = new ServiceReference[] {
createServiceReference(1L),
createServiceReference(2L, 1L, 10),
createServiceReference(3L),
createServiceReference(4L, 1L, 5),
createServiceReference(5L, 3L, 5),
};
tracked.setInitial(initialReferences);
tracked.trackInitial();
tracked.getExecutor().execute();
assertArrayEquals(new Long[] { 2L, 5L }, customizer.getServiceReferenceIds());
// create a service event that unregisters service with id 2, we would expect it to be swapped with 4.
ServiceEvent event = new ServiceEvent(ServiceEvent.UNREGISTERING, initialReferences[1]);
tracked.serviceChanged(event);
assertArrayEquals(new Long[] { 5L, 4L }, customizer.getServiceReferenceIds());
// create a service event that unregisters service with id 4, we would expect it to be swapped with 1.
event = new ServiceEvent(ServiceEvent.UNREGISTERING, initialReferences[3]);
tracked.serviceChanged(event);
assertArrayEquals(new Long[] { 5L, 1L }, customizer.getServiceReferenceIds());
}
@Test
public void testHideAspect() {
System.out.println("testHideAspect");
TestCustomizer customizer = new TestCustomizer();
ServiceTracker tracker = new TestTracker(customizer);
tracker.open();
Tracked tracked = tracker.getTracked();
ServiceReference<?>[] initialReferences = new ServiceReference[] {
createServiceReference(1L),
createServiceReference(2L, 1L, 10),
createServiceReference(3L),
createServiceReference(4L, 1L, 5),
createServiceReference(5L, 3L, 5),
};
tracked.setInitial(initialReferences);
tracked.trackInitial();
tracked.getExecutor().execute();
assertArrayEquals(new Long[] { 2L, 5L }, customizer.getServiceReferenceIds());
// create a service event that registers another but lower ranked aspect for service with id 1.
ServiceReference<?> newReference = createServiceReference(6L, 1L, 8);
ServiceEvent event = new ServiceEvent(ServiceEvent.REGISTERED, newReference);
tracked.serviceChanged(event);
assertArrayEquals(new Long[] { 2L, 5L }, customizer.getServiceReferenceIds());
// create a service event that unregisters service with id 2, we would expect it to be swapped with 6.
event = new ServiceEvent(ServiceEvent.UNREGISTERING, initialReferences[1]);
tracked.serviceChanged(event);
assertArrayEquals(new Long[] { 5L, 6L }, customizer.getServiceReferenceIds());
// create a service event that unregisters service with id 6, we would expect it to be swapped with 4.
event = new ServiceEvent(ServiceEvent.UNREGISTERING, newReference);
tracked.serviceChanged(event);
assertArrayEquals(new Long[] { 5L, 4L }, customizer.getServiceReferenceIds());
// create a service event that registers a higher ranked aspect for service with id 1.
ServiceReference<?> higherRankedReference = createServiceReference(7L, 1L, 15);
ServiceEvent addHigherRankedEvent = new ServiceEvent(ServiceEvent.REGISTERED, higherRankedReference);
tracked.serviceChanged(addHigherRankedEvent);
assertArrayEquals(new Long[] { 5L, 7L }, customizer.getServiceReferenceIds());
}
@Test
public void testSetInitialTrackAspects() {
System.out.println("testSetInitialTrackAspects");
TestCustomizer customizer = new TestCustomizer();
ServiceTracker tracker = new TestTracker(customizer);
tracker.open(false, true);
Tracked tracked = tracker.getTracked();
Object[] initialReferences = new Object[] {
createServiceReference(1L),
createServiceReference(2L, 1L, 10),
createServiceReference(3L, 1L, 5)
};
tracked.setInitial(initialReferences);
tracked.trackInitial();
tracked.getExecutor().execute();
assertArrayEquals(new Long[] { 1L, 2L, 3L }, customizer.getServiceReferenceIds());
}
private static BundleContext createBundleContext() {
BundleContext context = mock(BundleContext.class);
when(context.getProperty(Constants.FRAMEWORK_VERSION)).thenReturn(null);
return context;
}
private ServiceReference<?> createServiceReference(Long serviceId) {
return createServiceReference(serviceId, null, null);
}
private ServiceReference<?> createServiceReference(Long serviceId, Long aspectId, Integer ranking) {
return new TestServiceReference(serviceId, aspectId, ranking);
}
class TestTracker extends ServiceTracker {
public TestTracker(ServiceTrackerCustomizer customizer) {
super(createBundleContext(), "(objectClass=*)", customizer);
}
}
class TestCustomizer implements ServiceTrackerCustomizer {
List<ServiceReference<?>> serviceReferences = new ArrayList<>();
@Override
public Object addingService(ServiceReference reference) {
System.out.println("adding service: " + reference);
return new Object();
}
@Override
public void addedService(ServiceReference reference, Object service) {
System.out.println("added service: " + reference);
serviceReferences.add(reference);
}
@Override
public void modifiedService(ServiceReference reference, Object service) {
System.out.println("modified service: " + reference);
}
@Override
public void swappedService(ServiceReference reference, Object service,
ServiceReference newReference, Object newService) {
System.out.println("swapped service: " + reference);
serviceReferences.remove(reference);
serviceReferences.add(newReference);
}
@Override
public void removedService(ServiceReference reference, Object service) {
System.out.println("removed service: " + reference);
serviceReferences.remove(reference);
}
public Long[] getServiceReferenceIds() {
Long[] ids = new Long[serviceReferences.size()];
for (int i = 0; i < serviceReferences.size(); i++) {
ids[i] = (Long) serviceReferences.get(i).getProperty(Constants.SERVICE_ID);
}
return ids;
}
}
class TestServiceReference implements ServiceReference {
Properties props = new Properties();
public TestServiceReference(Long serviceId, Long aspectId,
Integer ranking) {
props.put(Constants.SERVICE_ID, serviceId);
if (aspectId != null) {
props.put(DependencyManager.ASPECT, aspectId);
}
if (ranking != null) {
props.put(Constants.SERVICE_RANKING, ranking);
}
}
@Override
public Object getProperty(String key) {
return props.get(key);
}
@Override
public String[] getPropertyKeys() {
return props.keySet().toArray(new String[]{});
}
@Override
public Bundle getBundle() {
return null;
}
@Override
public Bundle[] getUsingBundles() {
return null;
}
@Override
public boolean isAssignableTo(Bundle bundle, String className) {
return false;
}
@Override
public int compareTo(Object reference) // Kindly borrowed from the Apache Felix ServiceRegistrationImpl.ServiceReferenceImpl
{
ServiceReference other = (ServiceReference) reference;
Long id = (Long) getProperty(Constants.SERVICE_ID);
Long otherId = (Long) other.getProperty(Constants.SERVICE_ID);
if (id.equals(otherId))
{
return 0; // same service
}
Object rankObj = getProperty(Constants.SERVICE_RANKING);
Object otherRankObj = other.getProperty(Constants.SERVICE_RANKING);
// If no rank, then spec says it defaults to zero.
rankObj = (rankObj == null) ? new Integer(0) : rankObj;
otherRankObj = (otherRankObj == null) ? new Integer(0) : otherRankObj;
// If rank is not Integer, then spec says it defaults to zero.
Integer rank = (rankObj instanceof Integer)
? (Integer) rankObj : new Integer(0);
Integer otherRank = (otherRankObj instanceof Integer)
? (Integer) otherRankObj : new Integer(0);
// Sort by rank in ascending order.
if (rank.compareTo(otherRank) < 0)
{
return -1; // lower rank
}
else if (rank.compareTo(otherRank) > 0)
{
return 1; // higher rank
}
// If ranks are equal, then sort by service id in descending order.
return (id.compareTo(otherId) < 0) ? 1 : -1;
}
@Override
public String toString() {
return "TestServiceReference [props=" + props + "]";
}
}
}