blob: 34fdd65af3a5d51d218bb9893b10e8564cf86c89 [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.resourceresolver.impl.providers;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.sling.api.resource.observation.ResourceChange;
import org.apache.sling.api.resource.path.Path;
import org.apache.sling.api.resource.path.PathSet;
import org.apache.sling.api.resource.runtime.dto.AuthType;
import org.apache.sling.api.resource.runtime.dto.RuntimeDTO;
import org.apache.sling.resourceresolver.impl.Fixture;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker.ChangeListener;
import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker.ObservationReporterGenerator;
import org.apache.sling.spi.resource.provider.ObservationReporter;
import org.apache.sling.spi.resource.provider.ObserverConfiguration;
import org.apache.sling.spi.resource.provider.ResourceProvider;
import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.osgi.service.event.EventAdmin;
public class ResourceProviderTrackerTest {
@Rule
public OsgiContext context = new OsgiContext();
private EventAdmin eventAdmin;
private ResourceProviderInfo rp2Info;
private Fixture fixture;
@Before
public void prepare() throws Exception {
eventAdmin = context.getService(EventAdmin.class);
fixture = new Fixture(context.bundleContext());
}
private ResourceProviderTracker registerDefaultResourceProviderTracker() throws Exception {
@SuppressWarnings("unchecked")
ResourceProvider<Object> rp = mock(ResourceProvider.class);
@SuppressWarnings("unchecked")
ResourceProvider<Object> rp2 = mock(ResourceProvider.class);
@SuppressWarnings("unchecked")
ResourceProvider<Object> rp3 = mock(ResourceProvider.class);
fixture.registerResourceProvider(rp, "/", AuthType.no);
rp2Info = fixture.registerResourceProvider(rp2, "/path", AuthType.lazy);
fixture.registerResourceProvider(rp3, "invalid", AuthType.no);
ResourceProviderTracker tracker = new ResourceProviderTracker();
tracker.setObservationReporterGenerator(new SimpleObservationReporterGenerator(new NoDothingObservationReporter()));
tracker.activate(context.bundleContext(), eventAdmin, new DoNothingChangeListener());
return tracker;
}
@Test
public void activate() throws Exception {
ResourceProviderTracker tracker = registerDefaultResourceProviderTracker();
// since the OSGi mocks are asynchronous we don't have to wait for the changes to propagate
assertEquals(2, tracker.getResourceProviderStorage().getAllHandlers().size());
fixture.unregisterResourceProvider(rp2Info);
assertEquals(1, tracker.getResourceProviderStorage().getAllHandlers().size());
}
@Test
public void deactivate() throws Exception {
ResourceProviderTracker tracker = registerDefaultResourceProviderTracker();
tracker.deactivate();
assertTrue(tracker.getResourceProviderStorage().getAllHandlers().isEmpty());
}
@Test
public void testActivationDeactivation() throws Exception {
final ResourceProviderTracker tracker = new ResourceProviderTracker();
tracker.setObservationReporterGenerator(new SimpleObservationReporterGenerator(new NoDothingObservationReporter()));
// create boolean markers for the listener
final AtomicBoolean addedCalled = new AtomicBoolean(false);
final AtomicBoolean removedCalled = new AtomicBoolean(false);
final ChangeListener listener = new ChangeListener() {
@Override
public void providerAdded() {
addedCalled.set(true);
}
@Override
public void providerRemoved(String name, String pid, boolean stateful, boolean used) {
removedCalled.set(true);
}
};
// activate and check that no listener is called yet
tracker.activate(context.bundleContext(), eventAdmin, listener);
assertFalse(addedCalled.get());
assertFalse(removedCalled.get());
// add a new resource provider
@SuppressWarnings("unchecked")
ResourceProvider<Object> rp = mock(ResourceProvider.class);
final ResourceProviderInfo info = fixture.registerResourceProvider(rp, "/", AuthType.no);
// check added is called but not removed
assertTrue(addedCalled.get());
assertFalse(removedCalled.get());
// verify a single provider
assertEquals(1, tracker.getResourceProviderStorage().getAllHandlers().size());
// reset boolean markers
addedCalled.set(false);
removedCalled.set(false);
// remove provider
fixture.unregisterResourceProvider(info);
// verify removed is called but not added
assertTrue(removedCalled.get());
assertFalse(addedCalled.get());
// no provider anymore
assertTrue(tracker.getResourceProviderStorage().getAllHandlers().isEmpty());
}
@Test
public void testReactivation() throws Exception {
final ResourceProviderTracker tracker = new ResourceProviderTracker();
tracker.setObservationReporterGenerator(new SimpleObservationReporterGenerator(new NoDothingObservationReporter()));
// create boolean markers for the listener
final AtomicBoolean addedCalled = new AtomicBoolean(false);
final AtomicBoolean removedCalled = new AtomicBoolean(false);
final ChangeListener listener = new ChangeListener() {
@Override
public void providerAdded() {
addedCalled.set(true);
}
@Override
public void providerRemoved(String name, String pid, boolean stateful, boolean used) {
removedCalled.set(true);
}
};
// activate and check that no listener is called yet
tracker.activate(context.bundleContext(), eventAdmin, listener);
assertFalse(addedCalled.get());
assertFalse(removedCalled.get());
// activate and check that no listener is called yet
@SuppressWarnings("unchecked")
ResourceProvider<Object> rp = mock(ResourceProvider.class);
final ResourceProviderInfo info = fixture.registerResourceProvider(rp, "/", AuthType.no);
// check added is called but not removed
assertTrue(addedCalled.get());
assertFalse(removedCalled.get());
// verify a single provider
assertEquals(1, tracker.getResourceProviderStorage().getAllHandlers().size());
// reset boolean markers
addedCalled.set(false);
removedCalled.set(false);
// add overlay provider with higher service ranking
@SuppressWarnings("unchecked")
ResourceProvider<Object> rp2 = mock(ResourceProvider.class);
final ResourceProviderInfo infoOverlay = fixture.registerResourceProvider(rp2, "/", AuthType.no, 1000);
// check added and removed is called
assertTrue(addedCalled.get());
assertTrue(removedCalled.get());
// verify a single provider
assertEquals(1, tracker.getResourceProviderStorage().getAllHandlers().size());
// reset boolean markers
addedCalled.set(false);
removedCalled.set(false);
// unregister overlay provider
fixture.unregisterResourceProvider(infoOverlay);
// check added and removed is called
assertTrue(addedCalled.get());
assertTrue(removedCalled.get());
// verify a single provider
assertEquals(1, tracker.getResourceProviderStorage().getAllHandlers().size());
// reset boolean markers
addedCalled.set(false);
removedCalled.set(false);
// unregister first provider
fixture.unregisterResourceProvider(info);
// check removed is called but not added
assertTrue(removedCalled.get());
assertFalse(addedCalled.get());
// verify no provider
assertTrue(tracker.getResourceProviderStorage().getAllHandlers().isEmpty());
}
@Test
public void fillDto() throws Exception {
ResourceProviderTracker tracker = registerDefaultResourceProviderTracker();
RuntimeDTO dto = new RuntimeDTO();
tracker.fill(dto);
assertEquals(2, dto.providers.length);
assertEquals(1, dto.failedProviders.length);
}
static final class NoDothingObservationReporter implements ObservationReporter {
@Override
public void reportChanges(Iterable<ResourceChange> changes, boolean distribute) {
}
@Override
public void reportChanges(ObserverConfiguration config, Iterable<ResourceChange> changes, boolean distribute) {
}
@Override
public List<ObserverConfiguration> getObserverConfigurations() {
return Collections.emptyList();
}
}
static final class SimpleObservationReporterGenerator implements ObservationReporterGenerator {
private final ObservationReporter reporter;
SimpleObservationReporterGenerator(ObservationReporter reporter) {
this.reporter = reporter;
}
@Override
public ObservationReporter createProviderReporter() {
return reporter;
}
@Override
public ObservationReporter create(Path path, PathSet excludes) {
return reporter;
}
}
static final class DoNothingChangeListener implements ChangeListener {
@Override
public void providerAdded() {
// TODO Auto-generated method stub
}
@Override
public void providerRemoved(String name, String pid, boolean stateful, boolean used) {
// TODO Auto-generated method stub
}
}
}