Embedder.java
- package org.jbehave.core.embedder;
- import java.io.File;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Properties;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.ThreadPoolExecutor;
- import org.apache.commons.lang3.StringUtils;
- import org.apache.commons.lang3.builder.ToStringBuilder;
- import org.apache.commons.lang3.builder.ToStringStyle;
- import org.jbehave.core.ConfigurableEmbedder;
- import org.jbehave.core.Embeddable;
- import org.jbehave.core.configuration.Configuration;
- import org.jbehave.core.configuration.MostUsefulConfiguration;
- import org.jbehave.core.embedder.MetaFilter.MetaMatcher;
- import org.jbehave.core.embedder.StoryTimeouts.TimeoutParser;
- import org.jbehave.core.embedder.executors.FixedThreadExecutors;
- import org.jbehave.core.failures.BatchFailures;
- import org.jbehave.core.failures.FailingUponPendingStep;
- import org.jbehave.core.junit.AnnotatedEmbedderRunner;
- import org.jbehave.core.junit.AnnotatedEmbedderUtils;
- import org.jbehave.core.model.Story;
- import org.jbehave.core.model.StoryMaps;
- import org.jbehave.core.reporters.ReportsCount;
- import org.jbehave.core.reporters.StepdocReporter;
- import org.jbehave.core.reporters.StoryReporterBuilder;
- import org.jbehave.core.reporters.ViewGenerator;
- import org.jbehave.core.steps.CandidateSteps;
- import org.jbehave.core.steps.InjectableStepsFactory;
- import org.jbehave.core.steps.ProvidedStepsFactory;
- import org.jbehave.core.steps.StepFinder;
- import org.jbehave.core.steps.Stepdoc;
- /**
- * The Embedder is a facade allowing all functionality to be embedded into other
- * run contexts, such as IDEs (e.g. via JUnit support) or CLIs (via Ant or
- * Maven).
- */
- public class Embedder {
- protected StoryMapper storyMapper;
- protected EmbedderMonitor embedderMonitor;
- protected EmbedderClassLoader classLoader;
- protected EmbedderControls embedderControls;
- protected EmbedderFailureStrategy embedderFailureStrategy;
- protected Configuration configuration;
- protected InjectableStepsFactory stepsFactory;
- protected List<String> metaFilters;
- protected Map<String,MetaMatcher> metaMatchers;
- protected Properties systemProperties;
- protected ExecutorService executorService;
- protected boolean executorServiceCreated;
- protected PerformableTree performableTree;
- protected StoryManager storyManager;
- protected TimeoutParser[] timeoutParsers;
- public Embedder() {
- this(new PrintStreamEmbedderMonitor());
- }
- public Embedder(EmbedderMonitor embedderMonitor) {
- this(new StoryMapper(), new PerformableTree(), embedderMonitor);
- }
- public Embedder(StoryMapper storyMapper, PerformableTree performableTree, EmbedderMonitor embedderMonitor) {
- this.storyMapper = storyMapper;
- this.performableTree = performableTree;
- this.embedderMonitor = embedderMonitor;
- }
- public void mapStoriesAsPaths(List<String> storyPaths) {
- EmbedderControls embedderControls = embedderControls();
- embedderMonitor.usingControls(embedderControls);
- if (embedderControls.skip()) {
- embedderMonitor.storiesSkipped(storyPaths);
- return;
- }
- processSystemProperties();
- StoryManager storyManager = storyManager();
- for (String storyPath : storyPaths) {
- Story story = storyManager.storyOfPath(storyPath);
- embedderMonitor.mappingStory(storyPath, metaFilters());
- storyMapper.map(story, new MetaFilter("", embedderMonitor));
- for (String filter : metaFilters) {
- storyMapper.map(story, new MetaFilter(filter, embedderMonitor));
- }
- }
- generateMapsView(storyMapper.getStoryMaps());
- }
- private void generateMapsView(StoryMaps storyMaps) {
- Configuration configuration = configuration();
- StoryReporterBuilder builder = configuration.storyReporterBuilder();
- File outputDirectory = builder.outputDirectory();
- Properties viewResources = builder.viewResources();
- ViewGenerator viewGenerator = configuration.viewGenerator();
- try {
- embedderMonitor.generatingMapsView(outputDirectory, storyMaps, viewResources);
- viewGenerator.generateMapsView(outputDirectory, storyMaps, viewResources);
- } catch (RuntimeException e) {
- embedderMonitor.mapsViewGenerationFailed(outputDirectory, storyMaps, viewResources, e);
- throw new ViewGenerationFailed(outputDirectory, storyMaps, viewResources, e);
- }
- }
- public void runAsEmbeddables(List<String> classNames) {
- EmbedderControls embedderControls = embedderControls();
- embedderMonitor.usingControls(embedderControls);
- if (embedderControls.skip()) {
- embedderMonitor.embeddablesSkipped(classNames);
- return;
- }
- BatchFailures failures = new BatchFailures(embedderControls.verboseFailures());
- for (Embeddable embeddable : embeddables(classNames, classLoader())) {
- String name = embeddable.getClass().getName();
- try {
- embedderMonitor.runningEmbeddable(name);
- embeddable.useEmbedder(this);
- embeddable.run();
- } catch (Throwable e) {
- if (embedderControls.batch()) {
- // collect and postpone decision to throw exception
- failures.put(name, e);
- } else {
- if (ignoreFailure(embedderControls)) {
- embedderMonitor.embeddableFailed(name, e);
- } else {
- throw new RunningEmbeddablesFailed(name, e);
- }
- }
- }
- }
- if (embedderControls.batch() && failures.size() > 0) {
- if (ignoreFailure(embedderControls)) {
- embedderMonitor.batchFailed(failures);
- } else {
- throw new RunningEmbeddablesFailed(failures);
- }
- }
- }
- private boolean ignoreFailure(EmbedderControls embedderControls) {
- boolean ignore = embedderControls.ignoreFailureInStories();
- if (embedderControls.generateViewAfterStories()) {
- ignore = ignore && embedderControls.ignoreFailureInView();
- }
- return ignore;
- }
- private List<Embeddable> embeddables(List<String> classNames, EmbedderClassLoader classLoader) {
- List<Embeddable> embeddables = new ArrayList<>();
- for (String className : classNames) {
- if (!classLoader.isAbstract(className)) {
- embeddables.add(classLoader.newInstance(Embeddable.class, className));
- }
- }
- return embeddables;
- }
- public void runStoriesWithAnnotatedEmbedderRunner(List<String> classNames) {
- EmbedderClassLoader classLoader = classLoader();
- for (String className : classNames) {
- embedderMonitor.runningWithAnnotatedEmbedderRunner(className);
- AnnotatedEmbedderRunner runner = AnnotatedEmbedderUtils.annotatedEmbedderRunner(className, classLoader);
- try {
- Object annotatedInstance = runner.createTest();
- if (annotatedInstance instanceof Embeddable) {
- ((Embeddable) annotatedInstance).run();
- } else {
- embedderMonitor.annotatedInstanceNotOfType(annotatedInstance, Embeddable.class);
- }
- } catch (Throwable e) {
- throw new AnnotatedEmbedderRunFailed(runner, e);
- }
- }
- }
- public void runStoriesAsPaths(List<String> storyPaths) {
- processSystemProperties();
- EmbedderControls embedderControls = embedderControls();
- embedderMonitor.usingControls(embedderControls);
- if (embedderControls.skip()) {
- embedderMonitor.storiesSkipped(storyPaths);
- return;
- }
- try {
- // set up run context
- StoryManager storyManager = storyManager();
- MetaFilter filter = metaFilter();
- BatchFailures failures = new BatchFailures(embedderControls.verboseFailures());
- // run stories
- storyManager.runStoriesAsPaths(storyPaths, filter, failures);
- // handle any failures
- handleFailures(failures);
- } finally {
- // generate reports view regardless of failures in running stories
- // (if configured to do so)
- try {
- if (embedderControls.generateViewAfterStories()) {
- generateReportsView();
- }
- } finally {
- // shutdown regardless of failures in reports view
- shutdownExecutorService();
- // reset story manager as executor service is shutdown
- storyManager = null;
- }
- }
- }
- private void handleFailures(BatchFailures failures) {
- if (failures.size() > 0) {
- if (embedderControls().ignoreFailureInStories()) {
- embedderMonitor.batchFailed(failures);
- } else {
- embedderFailureStrategy().handleFailures(failures);
- }
- }
- }
- private void handleFailures(ReportsCount count) {
- boolean failed = count.failed();
- if (configuration().pendingStepStrategy() instanceof FailingUponPendingStep) {
- failed = failed || count.pending();
- }
- if (failed) {
- if (embedderControls().ignoreFailureInView()) {
- embedderMonitor.reportsViewFailures(count);
- } else {
- embedderFailureStrategy().handleFailures(count);
- }
- }
- }
- public void generateReportsView() {
- StoryReporterBuilder builder = configuration().storyReporterBuilder();
- File outputDirectory = builder.outputDirectory();
- List<String> formatNames = builder.formatNames(true);
- generateReportsView(outputDirectory, formatNames, builder.viewResources());
- }
- public void generateReportsView(File outputDirectory, List<String> formats, Properties viewResources) {
- if (embedderControls().skip()) {
- embedderMonitor.reportsViewNotGenerated();
- return;
- }
- ViewGenerator viewGenerator = configuration().viewGenerator();
- try {
- embedderMonitor.generatingReportsView(outputDirectory, formats, viewResources);
- viewGenerator.generateReportsView(outputDirectory, formats, viewResources);
- } catch (RuntimeException e) {
- embedderMonitor.reportsViewGenerationFailed(outputDirectory, formats, viewResources, e);
- throw new ViewGenerationFailed(outputDirectory, formats, viewResources, e);
- }
- ReportsCount count = viewGenerator.getReportsCount();
- embedderMonitor.reportsViewGenerated(count);
- handleFailures(count);
- }
- public void generateSurefireReport() {
- StoryReporterBuilder builder = configuration().storyReporterBuilder();
- if (builder.hasSurefireReporter()) {
- builder.surefireReporter().generate(storyManager().performableRoot(), builder.outputDirectory());
- }
- }
- public void reportStepdocs() {
- reportStepdocs(configuration(), stepsFactory().createCandidateSteps());
- }
- public void reportStepdocs(Configuration configuration, List<CandidateSteps> candidateSteps) {
- StepFinder finder = configuration.stepFinder();
- StepdocReporter reporter = configuration.stepdocReporter();
- List<Object> stepsInstances = finder.stepsInstances(candidateSteps);
- reporter.stepdocs(finder.stepdocs(candidateSteps), stepsInstances);
- }
- public void reportStepdocsAsEmbeddables(List<String> classNames) {
- EmbedderControls embedderControls = embedderControls();
- if (embedderControls.skip()) {
- embedderMonitor.embeddablesSkipped(classNames);
- return;
- }
- for (Embeddable embeddable : embeddables(classNames, classLoader())) {
- if (embeddable instanceof ConfigurableEmbedder) {
- ConfigurableEmbedder configurableEmbedder = (ConfigurableEmbedder) embeddable;
- Embedder configuredEmbedder = configurableEmbedder.configuredEmbedder();
- List<CandidateSteps> steps = configuredEmbedder.stepsFactory().createCandidateSteps();
- reportStepdocs(configuredEmbedder.configuration(), steps);
- } else {
- embedderMonitor.embeddableNotConfigurable(embeddable.getClass().getName());
- }
- }
- }
- public void reportMatchingStepdocs(String stepAsString) {
- Configuration configuration = configuration();
- List<CandidateSteps> candidateSteps = stepsFactory().createCandidateSteps();
- StepFinder finder = configuration.stepFinder();
- StepdocReporter reporter = configuration.stepdocReporter();
- List<Stepdoc> matching = finder.findMatching(stepAsString, candidateSteps);
- List<Object> stepsInstances = finder.stepsInstances(candidateSteps);
- reporter.stepdocsMatching(stepAsString, matching, stepsInstances);
- }
- public void processSystemProperties() {
- Properties properties = systemProperties();
- embedderMonitor.processingSystemProperties(properties);
- if (!properties.isEmpty()) {
- for (Object key : properties.keySet()) {
- String name = (String) key;
- String value = properties.getProperty(name);
- System.setProperty(name, value);
- embedderMonitor.systemPropertySet(name, value);
- }
- }
- }
- public EmbedderClassLoader classLoader() {
- if (classLoader == null) {
- this.classLoader = new EmbedderClassLoader(this.getClass().getClassLoader());
- }
- return classLoader;
- }
- public Configuration configuration() {
- if (configuration == null) {
- this.configuration = new MostUsefulConfiguration();
- }
- configureThreads(configuration, embedderControls().threads());
- return configuration;
- }
- public InjectableStepsFactory stepsFactory() {
- if (stepsFactory == null) {
- stepsFactory = new ProvidedStepsFactory();
- }
- return stepsFactory;
- }
- public EmbedderControls embedderControls() {
- if (embedderControls == null) {
- embedderControls = new EmbedderControls();
- }
- return embedderControls;
- }
- public EmbedderMonitor embedderMonitor() {
- return embedderMonitor;
- }
- public EmbedderFailureStrategy embedderFailureStrategy() {
- if (embedderFailureStrategy == null) {
- this.embedderFailureStrategy = new ThrowingRunningStoriesFailed();
- }
- return embedderFailureStrategy;
- }
- public boolean hasExecutorService() {
- return executorService != null;
- }
- public ExecutorService executorService() {
- if (executorService == null) {
- executorService = createExecutorService();
- executorServiceCreated = true;
- }
- return executorService;
- }
- /**
- * Creates a {@link ThreadPoolExecutor} using the number of threads defined
- * in the {@link EmbedderControls#threads()}
- *
- * @return An ExecutorService
- */
- private ExecutorService createExecutorService() {
- return new FixedThreadExecutors().create(embedderControls());
- }
- /**
- * Shuts down executor service, if it was created by Embedder.
- * ExecutorServices provided by the
- * {@link #useExecutorService(ExecutorService)} need to be managed by the
- * provider.
- */
- protected void shutdownExecutorService() {
- if (executorServiceCreated) {
- executorService.shutdownNow();
- executorService = null;
- executorServiceCreated = false;
- }
- }
- public StoryManager storyManager() {
- if (storyManager == null) {
- storyManager = createStoryManager();
- }
- return storyManager;
- }
- private StoryManager createStoryManager() {
- return new StoryManager(configuration(), stepsFactory(), embedderControls(), embedderMonitor(),
- executorService(), performableTree(), timeoutParsers());
- }
- protected void configureThreads(Configuration configuration, int threads) {
- StoryReporterBuilder reporterBuilder = configuration.storyReporterBuilder();
- reporterBuilder.withMultiThreading(threads > 1);
- configuration.useStoryReporterBuilder(reporterBuilder);
- }
- public List<String> metaFilters() {
- if (metaFilters == null) {
- metaFilters = new ArrayList<>();
- }
- return metaFilters;
- }
- public Map<String,MetaMatcher> metaMatchers() {
- if (metaMatchers == null) {
- metaMatchers = new HashMap<>();
- }
- return metaMatchers;
- }
-
- public MetaFilter metaFilter() {
- return new MetaFilter(StringUtils.join(metaFilters(), " "), embedderMonitor, metaMatchers());
- }
- public PerformableTree performableTree() {
- return performableTree;
- }
- public Properties systemProperties() {
- if (systemProperties == null) {
- systemProperties = new Properties();
- }
- return systemProperties;
- }
-
- public TimeoutParser[] timeoutParsers() {
- if (timeoutParsers == null) {
- timeoutParsers = new TimeoutParser[]{};
- }
- return timeoutParsers;
- }
- public void useClassLoader(EmbedderClassLoader classLoader) {
- this.classLoader = classLoader;
- }
- public void useConfiguration(Configuration configuration) {
- this.configuration = configuration;
- }
- public void useStepsFactory(InjectableStepsFactory stepsFactory) {
- this.stepsFactory = stepsFactory;
- }
- public void useEmbedderControls(EmbedderControls embedderControls) {
- this.embedderControls = embedderControls;
- }
- public void useEmbedderFailureStrategy(EmbedderFailureStrategy failureStategy) {
- this.embedderFailureStrategy = failureStategy;
- }
- public void useEmbedderMonitor(EmbedderMonitor embedderMonitor) {
- this.embedderMonitor = embedderMonitor;
- }
- public void useExecutorService(ExecutorService executorService) {
- this.executorService = executorService;
- embedderMonitor.usingExecutorService(executorService);
- }
- public void useMetaFilters(List<String> metaFilters) {
- this.metaFilters = metaFilters;
- }
- public void useMetaMatchers(Map<String,MetaMatcher> metaMatchers) {
- this.metaMatchers = metaMatchers;
- }
- public void usePerformableTree(PerformableTree performableTree) {
- this.performableTree = performableTree;
- }
- public void useSystemProperties(Properties systemProperties) {
- this.systemProperties = systemProperties;
- }
- public void useTimeoutParsers(TimeoutParser... timeoutParsers) {
- this.timeoutParsers = timeoutParsers;
- }
-
- @Override
- public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
- }
- public static interface EmbedderFailureStrategy {
- void handleFailures(BatchFailures failures);
- void handleFailures(ReportsCount count);
- }
- public static class ThrowingRunningStoriesFailed implements EmbedderFailureStrategy {
- @Override
- public void handleFailures(BatchFailures failures) {
- throw new RunningStoriesFailed(failures);
- }
- @Override
- public void handleFailures(ReportsCount count) {
- throw new RunningStoriesFailed(count);
- }
- }
- @SuppressWarnings("serial")
- public static class AnnotatedEmbedderRunFailed extends RuntimeException {
- public AnnotatedEmbedderRunFailed(AnnotatedEmbedderRunner runner, Throwable cause) {
- super("Annotated embedder run failed with runner " + runner.toString(), cause);
- }
- }
- @SuppressWarnings("serial")
- public static class RunningEmbeddablesFailed extends RuntimeException {
- public RunningEmbeddablesFailed(String name, Throwable failure) {
- super("Failure in running embeddable: " + name, failure);
- }
- public RunningEmbeddablesFailed(BatchFailures failures) {
- super("Failures in running embeddables: " + failures);
- }
- }
- @SuppressWarnings("serial")
- public static class RunningStoriesFailed extends RuntimeException {
- public RunningStoriesFailed(ReportsCount reportsCount) {
- super("Failures in running stories: " + reportsCount);
- }
- public RunningStoriesFailed(BatchFailures failures) {
- super("Failures in running stories: " + failures);
- }
- }
- @SuppressWarnings("serial")
- public static class ViewGenerationFailed extends RuntimeException {
- public ViewGenerationFailed(File outputDirectory, List<String> formats, Properties viewResources,
- RuntimeException cause) {
- super("View generation failed to " + outputDirectory + " for formats " + formats + " and resources "
- + viewResources, cause);
- }
- public ViewGenerationFailed(File outputDirectory, StoryMaps storyMaps, Properties viewResources,
- RuntimeException cause) {
- super("View generation failed to " + outputDirectory + " for story maps " + storyMaps + " for resources "
- + viewResources, cause);
- }
- }
- }