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

dev.galasa.framework.spi.AbstractManager Maven / Gradle / Ivy

There is a newer version: 0.37.0
Show newest version
/*
 * Copyright contributors to the Galasa project
 *
 * SPDX-License-Identifier: EPL-2.0
 */
package dev.galasa.framework.spi;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;

import javax.validation.constraints.NotNull;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import dev.galasa.ManagerException;
import dev.galasa.framework.spi.language.GalasaMethod;
import dev.galasa.framework.spi.language.GalasaTest;

/**
 * An abstract manager which attempts to provide all the boilerplate code
 * necessary to write a Manager in Galasa.
 *
 *  
 *
 */
public abstract class AbstractManager implements IManager {

    private IFramework                   framework;
    private Class                     testClass;

    private final HashMap annotatedFields = new HashMap<>();

    private final Log                    logger          = LogFactory.getLog(getClass());

    /**
     * Register an Manager annotated field, for automatic filling during
     * fillAnnotatedFields()
     *
     * @param field The field to fill
     * @param value The
     */
    protected void registerAnnotatedField(Field field, Object value) {
        this.annotatedFields.put(field, value);
    }

    /**
     * Retrieve the generated object for an annotated field
     * 
     * @param field field to retrieve
     * @return the generated object or null if it has not been generated yet
     */
    protected Object getAnnotatedField(Field field) {
        return this.annotatedFields.get(field);
    }

    /**
     * 

* Helper method to obtain a list of annotated fields this manager is interested * in. *

* *

* This method will return a list of fields that has an annotation that is in * turn annotated with the managerAnnotation *

* * @param managerAnnotation - The annotation that other annotations are * annotated with. * @return A list of fields the manager should be interested in */ protected List findAnnotatedFields(Class managerAnnotation) { final ArrayList foundFields = new ArrayList<>(); // *** Work our way throw the class inheritance for (Class lookClass = this.testClass; lookClass != null; lookClass = lookClass.getSuperclass()) { // *** Go through the PUBLIC fields for (final Field field : lookClass.getFields()) { final ArrayList fieldAnnotations = new ArrayList<>(); // *** For saving valid annotations for (final Annotation annotation : field.getAnnotations()) { // *** If the annotation is annotated with the manager annotation, ie the // manager is interested in it if (annotation.annotationType().isAnnotationPresent(managerAnnotation)) { final ValidAnnotatedFields validClasses = annotation.annotationType() .getAnnotation(ValidAnnotatedFields.class); // *** If there is a Valid classes annotation, make sure the field is of a valid // type if (validClasses != null) { boolean found = false; for (final Class k : validClasses.value()) { if (k == field.getType()) { fieldAnnotations.add(annotation); found = true; break; } } if (!found) { this.logger.warn("Field " + field.getName() + " has an invalid type, ignoring"); } } else { fieldAnnotations.add(annotation); } } } if (!fieldAnnotations.isEmpty()) { foundFields.add(new AnnotatedField(field, fieldAnnotations)); } } } return foundFields; } /** * Will call {@link GenerateAnnotatedField} methods in the parent class to * generate instances for each of the Test Class fields * * The annotated methods in the parent class must: *
    *
  • be public *
  • return the interface of the field annotation *
  • have 2 parameters of {@link java.lang.reflect.Field} and {@link java.util.List} *
* * @param managerAnnotation The Annotation for those annotated fields we are * interested in * @throws ManagerException */ protected void generateAnnotatedFields(Class managerAnnotation) throws ResourceUnavailableException, ManagerException { final List foundAnnotatedFields = findAnnotatedFields(managerAnnotation); if (foundAnnotatedFields.isEmpty()) { // *** No point doing anything return; } for (final AnnotatedField entry : foundAnnotatedFields) { final Field field = entry.getField(); final List annotations = entry.getAnnotations(); // *** Check to see if it is already generated if (this.annotatedFields.containsKey(field)) { continue; } try { // *** work our way through the fields looking for @GenerateAnnotatedField for (final Method method : getClass().getMethods()) { final GenerateAnnotatedField genField = method.getAnnotation(GenerateAnnotatedField.class); if (genField != null) { boolean foundAnnotation = false; // *** See if the annotation is on the list of annotations for that field for (final Annotation annotation : annotations) { if (annotation.annotationType() == genField.annotation()) { foundAnnotation = true; break; } } if (foundAnnotation) { // *** Check the method returns the right type and can be passed the correct // types final Class[] parameterTypes = method.getParameterTypes(); if ((parameterTypes != null) && (parameterTypes.length == 2) && (parameterTypes[0] == Field.class) && (parameterTypes[1] == List.class) && (method.getReturnType() == field.getType())) { // *** Call it and save the value for fillAnnotatedFields try { final Object response = method.invoke(this, field, annotations); if (response != null) { this.annotatedFields.put(field, response); } } catch(InvocationTargetException e) { if (e.getTargetException() instanceof ResourceUnavailableException) { throw (ResourceUnavailableException)e.getTargetException(); } throw e; } } } } } } catch (final ResourceUnavailableException e) { throw e; } catch (final Throwable e) { throw new ManagerException("Problem generating Test Class fields", e); } } } /** * Used to locate the TAG names used in Annotations that indicate a dependency on a Manager. See ZosImageDependencyField as an example. * * Where ZosImageDependencyField is annotated on a Manager field annotation, zOS Manager will ask for the imageTag attribute value. zOS Manager * will then provision as appropriate for each of the returned tags, which means the means the tester does not need to code a ZosImage for every * image the test wants. For example CICSRegion(imageTag="a") will cause the zOS Manager to provision an image for tag "a" without the ZosImage(imageTag="a") * * @param managerAnnotation the dependency annotation * @param attributeName the name of the attribute on the annotation that returns a String only * @return the tags found from the dependency annotations and the attribute, uppercased */ @NotNull protected Set findProvisionDependentAnnotatedFieldTags(@NotNull Class managerAnnotation, @NotNull String attributeName) { HashSet foundTags = new HashSet<>(); // Locate all the fields and their annotations where the manager annotation is found final List foundAnnotatedFields = findAnnotatedFields(managerAnnotation); // Iterate through them all for(AnnotatedField annotatedField : foundAnnotatedFields) { List annotations = annotatedField.getAnnotations(); // Find the manager annotation we need for(Annotation annotation : annotations) { Class annotationType = annotation.annotationType(); // is this one our manager annotation if (annotationType.isAnnotationPresent(managerAnnotation)) { try { Method methodImageTag = annotation.getClass().getMethod(attributeName); String tag = (String) methodImageTag.invoke(annotation); if (tag != null) { tag = tag.trim(); if (!tag.isEmpty()) { foundTags.add(tag.toUpperCase()); } } } catch(Exception e) { logger.warn("Error processing a Manager dependency annotation on field " + annotatedField.getField().getName() + " for " + managerAnnotation.getName() + " attribute " + attributeName, e); } } } } return foundTags; } /* * (non-Javadoc) * * @see dev.galasa.framework.spi.IManager#extraBundles(dev.galasa.framework.spi. * IFramework) */ @Override public List extraBundles(@NotNull IFramework framework) throws ManagerException { return null; // NOSONAR } /* * (non-Javadoc) * * @see dev.galasa.framework.spi.IManager#initialise(dev.galasa.framework.spi. * IFramework, java.util.List, java.util.List, java.lang.Class) */ @Override public void initialise(@NotNull IFramework framework, @NotNull List allManagers, @NotNull List activeManagers, @NotNull GalasaTest galasaTest) throws ManagerException { this.framework = framework; if(galasaTest.isJava()) { this.testClass = galasaTest.getJavaTestClass(); } } /** * @return The Framework */ public IFramework getFramework() { return this.framework; } /** * @return The Test Class */ public Class getTestClass() { return this.testClass; } /* * (non-Javadoc) * * @see dev.galasa.framework.spi.IManager#youAreRequired(java.util.List, * java.util.List) */ @Override public void youAreRequired(@NotNull List allManagers, @NotNull List activeManagers, @NotNull GalasaTest galasaTest) throws ManagerException { } /* * (non-Javadoc) * * @see * dev.galasa.framework.spi.IManager#areYouProvisionalDependentOn(dev.galasa. * framework .spi.IManager) */ @Override public boolean areYouProvisionalDependentOn(@NotNull IManager otherManager) { return false; } /* * (non-Javadoc) * * @see dev.galasa.framework.spi.IManager#anyReasonTestClassShouldBeIgnored() */ @Override public String anyReasonTestClassShouldBeIgnored() throws ManagerException { return null; } /* * (non-Javadoc) * * @see dev.galasa.framework.spi.IManager#provisionGenerate() */ @Override public void provisionGenerate() throws ManagerException, ResourceUnavailableException { } /* * (non-Javadoc) * * @see dev.galasa.framework.spi.IManager#provisionBuild() */ @Override public void provisionBuild() throws ManagerException, ResourceUnavailableException { } /* * (non-Javadoc) * * @see dev.galasa.framework.spi.IManager#provisionStart() */ @Override public void provisionStart() throws ManagerException, ResourceUnavailableException { } /* * (non-Javadoc) * * @see dev.galasa.framework.spi.IManager#startOfTestClass() */ @Override public void startOfTestClass() throws ManagerException { } /* * (non-Javadoc) * * @see dev.galasa.framework.spi.IManager#fillAnnotatedFields() */ @Override public void fillAnnotatedFields(Object instanstiatedTestClass) throws ManagerException { for (final Entry annotatedField : this.annotatedFields.entrySet()) { final Field field = annotatedField.getKey(); final Object value = annotatedField.getValue(); try { field.set(instanstiatedTestClass, value); } catch (final Throwable e) { throw new ManagerException("Unable to fill Test Class field " + field.getName(), e); } } } /* * (non-Javadoc) * * @see * dev.galasa.framework.spi.IManager#anyReasonTestMethodShouldBeIgnored(java. * lang. reflect.Method) */ @Override public String anyReasonTestMethodShouldBeIgnored(@NotNull GalasaMethod galasaMethod) throws ManagerException { return null; } /* * (non-Javadoc) * * @see dev.galasa.framework.spi.IManager#startOfTestMethod() */ @Override public void startOfTestMethod(@NotNull GalasaMethod galasaMethod) throws ManagerException { } /* * (non-Javadoc) * * @see dev.galasa.framework.spi.IManager#endOfTestMethod(java.lang.String, * java.lang.Throwable) */ @Override public Result endOfTestMethod(@NotNull GalasaMethod galasaMethod, @NotNull Result currentResult, Throwable currentException) throws ManagerException { return null; } /* * (non-Javadoc) * * @see dev.galasa.framework.spi.IManager#testMethodResult(java.lang.String, * java.lang.Throwable) */ @Override public void testMethodResult(@NotNull String finalResult, Throwable finalException) throws ManagerException { } /* * (non-Javadoc) * * @see dev.galasa.framework.spi.IManager#endOfTestClass(java.lang.String, * java.lang.Throwable) */ @Override public Result endOfTestClass(@NotNull Result currentResult, Throwable currentException) throws ManagerException { return null; } /* * (non-Javadoc) * * @see dev.galasa.framework.spi.IManager#testClassResult(java.lang.String, * java.lang.Throwable) */ @Override public void testClassResult(@NotNull String finalResult, Throwable finalException) throws ManagerException { } /* * (non-Javadoc) * * @see dev.galasa.framework.spi.IManager#provisionStop() */ @Override public void provisionStop() { } /* * (non-Javadoc) * * @see dev.galasa.framework.spi.IManager#provisionDiscard() */ @Override public void provisionDiscard() { } /* * (non-Javadoc) * * @see dev.galasa.framework.spi.IManager#performFailureAnalysis() */ @Override public void performFailureAnalysis() { } /* * (non-Javadoc) * * @see dev.galasa.framework.spi.IManager#endOfTestRun() */ @Override public void endOfTestRun() { } /** * Helper method to find managers that implement an interface and tell them they * are required * * @param allManagers All available managers * @param activeManagers The currently active managers * @param dependentInterface The interface the manager needs to implement * @return * @throws ManagerException If the required manager can't be added to the active * list */ protected T addDependentManager(@NotNull List allManagers, @NotNull List activeManagers, @NotNull GalasaTest galasaTest, @NotNull Class dependentInterface) throws ManagerException { for (IManager manager : allManagers) { if (dependentInterface.isAssignableFrom(manager.getClass())) { manager.youAreRequired(allManagers, activeManagers, galasaTest); return dependentInterface.cast(manager); } } return null; } /** * null a String is if it is empty * * TODO Needs to be moved to a more appropriate place as non managers use this, * a stringutils maybe * * @param value * @return a trimmed String or a null if emtpy or null */ public static String nulled(String value) { if (value == null) { return null; } value = value.trim(); if (value.isEmpty()) { return null; } return value; } public static List split(String value) { ArrayList values = new ArrayList<>(); if (value == null) { return values; } String[] parts = value.split(","); for (String part : parts) { part = part.trim(); if (!part.isEmpty()) { values.add(part); } } return values; } public static String defaultString(String value, String defaultValue) { if (value == null) { return defaultValue; } value = value.trim(); if (value.isEmpty()) { return defaultValue; } return value; } public static List trim(String[] array) { ArrayList trimmed = new ArrayList<>(); for (String s : array) { if (s != null) { s = s.trim(); if (!s.isEmpty()) { trimmed.add(s); } } } return trimmed; } @Override public void shutdown() { } @Override public boolean doYouSupportSharedEnvironments() { return false; //*** Managers by default will not support shared environments } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy