All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.thoughtworks.gauge.execution.MethodExecutor Maven / Gradle / Ivy

There is a newer version: 0.11.0
Show newest version
/*----------------------------------------------------------------
 *  Copyright (c) ThoughtWorks, Inc.
 *  Licensed under the Apache License, Version 2.0
 *  See LICENSE.txt in the project root for license information.
 *----------------------------------------------------------------*/
package com.thoughtworks.gauge.execution;

import com.thoughtworks.gauge.ClassInstanceManager;
import com.thoughtworks.gauge.ContinueOnFailure;
import com.thoughtworks.gauge.Util;
import com.thoughtworks.gauge.screenshot.ScreenshotFactory;
import gauge.messages.Spec;

import java.lang.reflect.Method;
import java.util.Set;

public class MethodExecutor {
    private ClassInstanceManager instanceManager;

    public MethodExecutor(ClassInstanceManager instanceManager) {
        this.instanceManager = instanceManager;
    }

    public Spec.ProtoExecutionResult execute(Method method, Object... args) {
        long startTime = System.currentTimeMillis();
        try {
            Object instance = instanceManager.get(method.getDeclaringClass());
            method.invoke(instance, args);
            long endTime = System.currentTimeMillis();
            return Spec.ProtoExecutionResult.newBuilder().setFailed(false).setExecutionTime(endTime - startTime).build();
        } catch (Throwable e) {
            boolean recoverable = method.isAnnotationPresent(ContinueOnFailure.class);
            Class[] continuableExceptions = new Class[]{};
            if (recoverable) {
                continuableExceptions = method.getAnnotation(ContinueOnFailure.class).value();
            }
            long endTime = System.currentTimeMillis();
            return createFailureExecResult(endTime - startTime, e, recoverable, continuableExceptions);
        }
    }

    private Spec.ProtoExecutionResult createFailureExecResult(long execTime, Throwable e, boolean recoverable, Class[] continuableExceptions) {
        Spec.ProtoExecutionResult.Builder builder = Spec.ProtoExecutionResult.newBuilder().setFailed(true);
        if (Util.shouldTakeFailureScreenshot()) {
            String screenshotFileName = new ScreenshotFactory(instanceManager).getScreenshotBytes();
            builder.setFailureScreenshotFile(screenshotFileName);
        }
        if (e.getCause() != null) {
            builder.setRecoverableError(false);
            for (Class c : continuableExceptions) {
                if (c.isAssignableFrom(e.getCause().getClass()) && recoverable) {
                    builder.setRecoverableError(true);
                    break;
                }
            }
            builder.setErrorMessage(e.getCause().toString());
            builder.setStackTrace(formatStackTrace(e.getCause().getStackTrace()));
        } else {
            builder.setRecoverableError(recoverable);
            builder.setErrorMessage(e.toString());
            builder.setStackTrace(formatStackTrace(e.getStackTrace()));
        }
        builder.setExecutionTime(execTime);
        return builder.build();
    }

    private String formatStackTrace(StackTraceElement[] stackTrace) {
        if (stackTrace == null) {
            return "";
        }
        StringBuilder output = new StringBuilder();
        for (StackTraceElement element : stackTrace) {
            if (element.getClassName().equals("sun.reflect.NativeMethodAccessorImpl")) {
                break;
            }
            output.append(element.toString()).append("\n");
        }
        return output.toString();
    }

    public Spec.ProtoExecutionResult executeMethods(Set methods, Object... args) {
        long totalExecutionTime = 0;
        for (Method method : methods) {
            Spec.ProtoExecutionResult result = execute(method, args);
            totalExecutionTime += result.getExecutionTime();
            if (result.getFailed()) {
                return result;
            }
        }
        return Spec.ProtoExecutionResult.newBuilder().setFailed(false).setExecutionTime(totalExecutionTime).build();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy