org.jboss.arquillian.drone.impl.DroneLifecycleManager Maven / Gradle / Ivy
The newest version!
/*
* JBoss, Home of Professional Open Source
* Copyright 2011, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* 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.jboss.arquillian.drone.impl;
import java.lang.annotation.Annotation;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import org.jboss.arquillian.config.descriptor.api.ArquillianDescriptor;
import org.jboss.arquillian.container.spi.event.container.AfterDeploy;
import org.jboss.arquillian.container.spi.event.container.BeforeUnDeploy;
import org.jboss.arquillian.core.api.Event;
import org.jboss.arquillian.core.api.Injector;
import org.jboss.arquillian.core.api.Instance;
import org.jboss.arquillian.core.api.InstanceProducer;
import org.jboss.arquillian.core.api.annotation.ApplicationScoped;
import org.jboss.arquillian.core.api.annotation.Inject;
import org.jboss.arquillian.core.api.annotation.Observes;
import org.jboss.arquillian.core.api.event.ManagerStarted;
import org.jboss.arquillian.drone.api.annotation.Default;
import org.jboss.arquillian.drone.configuration.ConfigurationMapper;
import org.jboss.arquillian.drone.spi.DroneConfiguration;
import org.jboss.arquillian.drone.spi.DroneContext;
import org.jboss.arquillian.drone.spi.DronePoint;
import org.jboss.arquillian.drone.spi.FilterableResult;
import org.jboss.arquillian.drone.spi.command.DestroyDrone;
import org.jboss.arquillian.drone.spi.command.PrepareDrone;
import org.jboss.arquillian.drone.spi.event.AfterDroneExtensionConfigured;
import org.jboss.arquillian.drone.spi.event.BeforeDroneExtensionConfigured;
import org.jboss.arquillian.drone.spi.filter.DeploymentFilter;
import org.jboss.arquillian.drone.spi.filter.LifecycleFilter;
import org.jboss.arquillian.test.spi.TestClass;
import org.jboss.arquillian.test.spi.event.suite.After;
import org.jboss.arquillian.test.spi.event.suite.AfterClass;
import org.jboss.arquillian.test.spi.event.suite.Before;
import org.jboss.arquillian.test.spi.event.suite.BeforeClass;
import org.jboss.arquillian.test.spi.event.suite.BeforeSuite;
public class DroneLifecycleManager {
public static final int CLASS_SCAN_PRECEDENCE = 75;
private static final Logger log = Logger.getLogger(DroneLifecycleManager.class.getName());
@Inject
private Instance injector;
@Inject
private Instance arquillianDescriptor;
@Inject
@ApplicationScoped
private InstanceProducer droneContext;
@Inject
@ApplicationScoped
private InstanceProducer deploymentDronePointsRegistry;
@Inject
private Event beforeDroneExtensionConfiguredEvent;
@Inject
private Event afterDroneExtensionConfiguredEvent;
@Inject
private Event createDroneConfigurationCommand;
@Inject
private Event destroyDroneCommand;
@Inject
private Instance testClassInstance;
public void managerStarted(@Observes ManagerStarted event) {
try {
DroneContext context = injector.get().inject(new DroneContextImpl());
droneContext.set(context);
} catch (TypeNotPresentException e) {
log.log(Level.SEVERE,
"Unable to create Drone Context due to missing services on classpath. Please make sure to use Arquillian Core 1.1.4.Final or later.");
throw new IllegalStateException(
"Unable to create Drone Context due to missing services on classpath. Please make sure to use Arquillian Core 1.1.4.Final or later.",
e);
}
}
public void configureDroneExtension(@Observes BeforeSuite event) {
DroneContext context = droneContext.get();
if (context.getGlobalDroneConfiguration(DroneConfiguration.class) != null) {
return;
}
beforeDroneExtensionConfiguredEvent.fire(new BeforeDroneExtensionConfigured());
if (context.getGlobalDroneConfiguration(DroneConfiguration.class) == null) {
GlobalDroneConfiguration configuration =
new GlobalDroneConfiguration().configure(arquillianDescriptor.get(), null);
context.setGlobalDroneConfiguration(configuration);
}
afterDroneExtensionConfiguredEvent.fire(new AfterDroneExtensionConfigured());
}
@SuppressWarnings("unused")
public void beforeClass(@Observes(precedence = CLASS_SCAN_PRECEDENCE) BeforeClass event) {
Class> testClass = event.getTestClass().getJavaClass();
Set> dronePoints = InjectionPoints.allInClass(droneContext.get(), testClass);
for (DronePoint> dronePoint : dronePoints) {
// The deployment-scoped drones are only registered and not prepared - should be prepared in AfterDeploy
if (dronePoint.getLifecycle() == DronePoint.Lifecycle.DEPLOYMENT) {
registerDeploymentDronePoint(dronePoint);
continue;
}
// We are not interested in method-scoped drones
if (dronePoint.getLifecycle() == DronePoint.Lifecycle.METHOD) {
continue;
}
createDroneConfigurationCommand.fire(new PrepareDrone(dronePoint));
}
}
private void registerDeploymentDronePoint(DronePoint dronePoint) {
if (deploymentDronePointsRegistry.get() == null) {
deploymentDronePointsRegistry.set(injector.get().inject(new DeploymentDronePointsRegistry()));
}
deploymentDronePointsRegistry.get().addDronePoint(dronePoint, null);
}
public void before(@Observes Before event) {
DronePoint>[] dronePoints = InjectionPoints.parametersInMethod(droneContext.get(), event.getTestMethod());
for (DronePoint> dronePoint : dronePoints) {
// We only need to prepare method-scoped drones - deployment-scoped drones should have been already prepared in AfterDeploy
if (dronePoint == null || dronePoint.getLifecycle() != DronePoint.Lifecycle.METHOD) {
continue;
}
createDroneConfigurationCommand.fire(new PrepareDrone(dronePoint));
}
}
public void afterDeploy(@Observes AfterDeploy afterDeploy) {
DeploymentDronePointsRegistry deplDronePoints = this.deploymentDronePointsRegistry.get();
if (deplDronePoints != null) {
String deplName = afterDeploy.getDeployment().getName();
Map, Object> filteredDronePoints = deplDronePoints.filterDeploymentDronePoints(deplName);
for (DronePoint dronePoint : filteredDronePoints.keySet()) {
if (!droneContext.get().get(dronePoint).hasFutureInstance()) {
createDroneConfigurationCommand.fire(new PrepareDrone(dronePoint));
}
// in case that deployment is done before the enrichment, then only prepare the DronePoint - Enrichment will be done later as a part of the standard process
Object testClass = filteredDronePoints.get(dronePoint);
if (testClass != null) {
// in case that deployment is done after the standard enrichment, we have to enrich the class manually
DroneTestEnricher droneTestEnricher = injector.get().inject(new DroneTestEnricher());
droneTestEnricher.enrichTestClass(testClassInstance.get().getJavaClass(), testClass, false);
}
}
}
}
public void after(@Observes After event) {
DroneContext context = droneContext.get();
LifecycleFilter lifecycleFilter = new LifecycleFilter(DronePoint.Lifecycle.METHOD);
FilterableResult