blob: 4f1300cab84294341212f42ad3b12235b274bf98 [file] [log] [blame]
/**
* Licensed 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.aries.cdi.test.cases.base;
import static java.util.Optional.ofNullable;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.osgi.test.common.filter.Filters.format;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Supplier;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.Any;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.junit.jupiter.api.extension.TestWatcher;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.wiring.BundleWire;
import org.osgi.framework.wiring.BundleWiring;
import org.osgi.namespace.extender.ExtenderNamespace;
import org.osgi.service.cdi.CDIConstants;
import org.osgi.service.cdi.runtime.CDIComponentRuntime;
import org.osgi.service.cdi.runtime.dto.ContainerDTO;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.test.common.annotation.InjectBundleContext;
import org.osgi.test.common.annotation.InjectBundleInstaller;
import org.osgi.test.common.annotation.InjectService;
import org.osgi.test.common.install.BundleInstaller;
import org.osgi.test.junit5.context.BundleContextExtension;
import org.osgi.test.junit5.service.ServiceExtension;
import org.osgi.util.promise.PromiseFactory;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
@ExtendWith({BundleContextExtension.class, ServiceExtension.class})
public abstract class BaseTestCase {
public static final long timeout = 500;
public Bundle cdiBundle;
public Bundle servicesBundle;
public static final PromiseFactory promiseFactory = new PromiseFactory(null);
@InjectBundleContext
public BundleContext bundleContext;
@InjectBundleInstaller
public BundleInstaller bundleInstaller;
@InjectService
public CDIComponentRuntime ccr;
@InjectService
public ConfigurationAdmin car;
//@RegisterExtension
public static BeforeEachCallback beforeEachCallback = (ExtensionContext context) -> {
System.out.printf("--------- TEST: %s [%s]%n", context.getUniqueId(), "STARTING");
};
@RegisterExtension
public static TestWatcher watchman = new TestWatcher() {
@Override
public void testDisabled(ExtensionContext context, Optional<String> reason) {
System.out.printf("--------- TEST: %s [%s] Reason: %s%n", context.getUniqueId(), "DISABLED", reason.orElse(""));
}
@Override
public void testFailed(ExtensionContext context, Throwable cause) {
System.out.printf("--------- TEST: %s [%s]%n", context.getUniqueId(), "FAILED");
}
@Override
public void testSuccessful(ExtensionContext context) {
System.out.printf("--------- TEST: %s [%s]%n", context.getUniqueId(), "PASSED");
}
};
@BeforeEach
public void setUp() throws Exception {
servicesBundle = bundleInstaller.installBundle("services-one.jar", false);
servicesBundle.start();
cdiBundle = bundleInstaller.installBundle("basic-beans.jar", false);
cdiBundle.start();
}
@AfterEach
public void tearDown() throws Exception {
cdiBundle.uninstall();
servicesBundle.uninstall();
}
public void assertBeanExists(Class<?> clazz, BeanManager beanManager) {
Set<Bean<?>> beans = beanManager.getBeans(clazz, Any.Literal.INSTANCE);
assertFalse(beans.isEmpty());
Iterator<Bean<?>> iterator = beans.iterator();
Bean<?> bean = iterator.next();
assertTrue(clazz.isAssignableFrom(bean.getBeanClass()));
assertFalse(iterator.hasNext());
bean = beanManager.resolve(beans);
CreationalContext<?> ctx = beanManager.createCreationalContext(bean);
Object pojo = clazz.cast(beanManager.getReference(bean, clazz, ctx));
assertNotNull(pojo);
}
public Bundle getCdiExtenderBundle() {
BundleWiring bundleWiring = cdiBundle.adapt(BundleWiring.class);
List<BundleWire> requiredWires = bundleWiring.getRequiredWires(ExtenderNamespace.EXTENDER_NAMESPACE);
for (BundleWire wire : requiredWires) {
Map<String, Object> attributes = wire.getCapability().getAttributes();
String extender = (String)attributes.get(ExtenderNamespace.EXTENDER_NAMESPACE);
if (CDIConstants.CDI_CAPABILITY_NAME.equals(extender)) {
return wire.getProvider().getBundle();
}
}
return null;
}
public ContainerDTO getContainerDTO(Bundle bundle) {
Iterator<ContainerDTO> iterator;
ContainerDTO containerDTO = null;
int attempts = 50;
while (--attempts > 0) {
iterator = ccr.getContainerDTOs(bundle).iterator();
if (iterator.hasNext()) {
containerDTO = iterator.next();
if (containerDTO != null) {
break;
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
assertNotNull(containerDTO);
return containerDTO;
}
public <S,T> CloseableTracker<S, T> track(Filter filter) {
CloseableTracker<S, T> tracker = new CloseableTracker<>(bundleContext, filter);
tracker.open();
return tracker;
}
public <S,T> CloseableTracker<S, T> track(String pattern, Object... objects) {
return track(format(pattern, objects));
}
public <S> CloseableTracker<S, ServiceReference<S>> trackSR(String pattern, Object... objects) {
return trackSR(format(pattern, objects));
}
public <S> CloseableTracker<S, ServiceReference<S>> trackSR(Filter filter) {
CloseableTracker<S, ServiceReference<S>> tracker = new CloseableTracker<>(bundleContext, filter, new ServiceTrackerCustomizer<S, ServiceReference<S>>() {
@Override
public ServiceReference<S> addingService(ServiceReference<S> reference) {
return reference;
}
@Override
public void modifiedService(ServiceReference<S> reference, ServiceReference<S> service) {
}
@Override
public void removedService(ServiceReference<S> reference, ServiceReference<S> service) {
}
});
tracker.open();
return tracker;
}
public BeanManager getBeanManager(Bundle bundle) throws Exception {
return trackBM(bundle.getBundleId()).waitForService(timeout);
}
public BeanManager getBeanManager(long bundleId) throws Exception {
return trackBM(bundleId).waitForService(timeout);
}
public CloseableTracker<BeanManager, BeanManager> trackBM(long bundleId) throws Exception {
CloseableTracker<BeanManager, BeanManager> serviceTracker = new CloseableTracker<>(
bundleContext,
format(
"(&(objectClass=%s)(service.bundleid=%d))",
BeanManager.class.getName(),
bundleId),
null);
serviceTracker.open();
return serviceTracker;
}
public long getChangeCount(ServiceReference<?> reference) {
return ofNullable(
reference.getProperty("service.changecount")
).map(
Long.class::cast
).orElseGet(
() -> Long.valueOf(-1)
).longValue();
}
public static <T> T tccl(ClassLoader classLoader, Supplier<T> supplier) {
Thread currentThread = Thread.currentThread();
ClassLoader original = currentThread.getContextClassLoader();
try {
currentThread.setContextClassLoader(classLoader);
return supplier.get();
}
finally {
currentThread.setContextClassLoader(original);
}
}
}