All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.zebrunner.agent.testng.listener.RunContextService Maven / Gradle / Ivy
package com.zebrunner.agent.testng.listener;
import com.zebrunner.agent.testng.core.FactoryInstanceHolder;
import com.zebrunner.agent.testng.core.TestInvocationContext;
import com.zebrunner.agent.testng.core.TestMethodContext;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.testng.ITestContext;
import org.testng.ITestNGMethod;
import org.testng.internal.ConstructorOrMethod;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class RunContextService {
private static final Map INVOCATION_CONTEXT_TO_TEST_IDS = new ConcurrentHashMap<>();
static int countInvocationContexts() {
return INVOCATION_CONTEXT_TO_TEST_IDS.size();
}
static void addInvocationContexts(Map contexts) {
contexts.entrySet()
.stream()
// filter out tests without invocation context
.filter(contextToTestId -> Objects.nonNull(contextToTestId.getKey()))
.forEach(contextToTestId -> RunContextService.INVOCATION_CONTEXT_TO_TEST_IDS.putIfAbsent(contextToTestId.getKey(), contextToTestId.getValue()));
}
public static void incrementMethodInvocationIndex(ITestNGMethod method, ITestContext context) {
RunContextService.getOrInitRunContext(method, context)
.incrementInvocationIndex();
}
public static int getMethodInvocationIndex(ITestNGMethod method, ITestContext context) {
return RunContextService.getOrInitRunContext(method, context)
.getCurrentInvocationIndex();
}
public static void setDataProviderIndicesForRerun(ITestNGMethod method, ITestContext context, Collection indices) {
RunContextService.getOrInitRunContext(method, context)
.setDataProviderIndicesForRerun(indices);
}
public static List getDataProviderIndicesForRerun(ITestNGMethod method, ITestContext context) {
return RunContextService.getMethodContext(method, context)
.map(TestMethodContext::getDataProviderIndicesForRerun)
.orElseGet(Collections::emptyList);
}
public static int getDataProviderSize(ITestNGMethod method, ITestContext context) {
return RunContextService.getOrInitRunContext(method, context)
.getDataProviderSize();
}
public static void setDataProviderData(ITestNGMethod method, ITestContext context, List dataProviderData) {
RunContextService.getOrInitRunContext(method, context)
.setDataProviderData(dataProviderData);
}
public static void setCurrentDataProviderIteratorIndex(ITestNGMethod method, ITestContext context, int currentDataProviderIteratorIndex) {
RunContextService.getOrInitRunContext(method, context)
.setCurrentDataProviderIteratorIndex(currentDataProviderIteratorIndex);
}
public static void setCurrentDataProviderData(ITestNGMethod method, ITestContext context, Object[] currentDataProviderData, int index) {
RunContextService.getOrInitRunContext(method, context)
.setCurrentDataProviderData(currentDataProviderData, index);
}
public static int getCurrentDataProviderIndex(ITestNGMethod method, ITestContext context, Object[] parameters) {
return RunContextService.getMethodContext(method, context)
.map(testMethodContext -> testMethodContext.getCurrentDataProviderIndex(parameters))
.orElse(-1);
}
private static TestMethodContext getOrInitRunContext(ITestNGMethod method, ITestContext context) {
return RunContextService.getMethodContext(method, context)
.orElseGet(() -> createEmptyRunContext(method, context));
}
private static Optional getMethodContext(ITestNGMethod method, ITestContext context) {
String uniqueNameByInstanceAndSignature = constructMethodUuid(method);
return Optional.ofNullable((TestMethodContext) context.getAttribute(uniqueNameByInstanceAndSignature));
}
private static TestMethodContext createEmptyRunContext(ITestNGMethod method, ITestContext context) {
TestMethodContext testMethodContext = new TestMethodContext();
String uniqueNameByInstanceAndSignature = constructMethodUuid(method);
context.setAttribute(uniqueNameByInstanceAndSignature, testMethodContext);
return testMethodContext;
}
/**
* Build unique method signature that ties specific method to specific class instance
*
* @param method test method
* @return method uuid in the following format: "fully-qualified-class-name.method-name(argType1,argType2)[instanceNumber]"
*/
private static String constructMethodUuid(ITestNGMethod method) {
String pattern = "%s.%s(%s)[%d]";
ConstructorOrMethod constructorOrMethod = method.getConstructorOrMethod();
String className = method.getTestClass().getName();
String methodName = constructorOrMethod.getName();
String argumentTypes = Arrays.stream(constructorOrMethod.getParameterTypes())
.map(Class::getName)
.collect(Collectors.joining(","));
int instanceIndex = FactoryInstanceHolder.getInstanceIndex(method);
return String.format(pattern, className, methodName, argumentTypes, instanceIndex);
}
/**
* Checks if provided test method has corresponding test invocation contexts eligible for rerun
*
* @param method test method to be checked
* @return list of test execution contexts that are eligible for rerun
*/
public static List findInvocationsForRerun(ITestNGMethod method) {
return INVOCATION_CONTEXT_TO_TEST_IDS.keySet()
.stream()
.filter(Objects::nonNull)
.filter(context -> belongsToMethod(context, method))
.filter(context -> belongsToTheSameFactoryInstance(context, method))
.collect(Collectors.toList());
}
public static Optional getZebrunnerTestIdOnRerun(ITestNGMethod method, Integer dataProviderIndex) {
return INVOCATION_CONTEXT_TO_TEST_IDS.keySet()
.stream()
.filter(Objects::nonNull)
.filter(context -> belongsToMethod(context, method))
.filter(context -> belongsToTheSameFactoryInstance(context, method))
.filter(context -> context.getDataProviderIndex() == dataProviderIndex)
.map(INVOCATION_CONTEXT_TO_TEST_IDS::get)
.findFirst();
}
public static boolean isEligibleForRerun(ITestNGMethod method) {
return INVOCATION_CONTEXT_TO_TEST_IDS.keySet()
.stream()
.filter(Objects::nonNull)
.anyMatch(context -> belongsToMethod(context, method) && belongsToTheSameFactoryInstance(context, method));
}
/**
* Checks if test execution context has the same method signature as test method provided
*/
private static boolean belongsToMethod(TestInvocationContext invocationContext, ITestNGMethod method) {
String contextParameters = String.join(", ", invocationContext.getParameterClassNames());
String methodParameters = String.join(", ", getMethodParameterNames(method));
return invocationContext.getClassName().equals(method.getTestClass().getName())
&& invocationContext.getMethodName().equals(method.getMethodName())
&& contextParameters.equals(methodParameters);
}
private static List getMethodParameterNames(ITestNGMethod method) {
return Arrays.stream(method.getConstructorOrMethod().getParameterTypes())
.map(Class::getName)
.collect(Collectors.toList());
}
private static boolean belongsToTheSameFactoryInstance(TestInvocationContext invocationContext, ITestNGMethod method) {
int index = FactoryInstanceHolder.getInstanceIndex(method);
return invocationContext.getInstanceIndex() == index;
}
}