Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Config invocation order for inheritance #2503

Merged
merged 1 commit into from
Mar 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
Current
Fixes: GITHUB-2493: Avoid NPE from TextReporter execution when a dataprovider method provides null (baflQA)
Fixed: GITHUB-2489: Hierarchical base- and test-class @AfterClass methods out of order using groups (Krishnan Mahadevan)
Fixed: GITHUB-2493: Avoid NPE from TextReporter execution when a dataprovider method provides null (baflQA)
Fixed: GITHUB-2483: Asymmetric not equals (cdalexndr)
Fixed: GITHUB-2486: assertSame/assertNotSame broken after GITHUB-2296 (Vitalii Diravka)

Expand Down
14 changes: 7 additions & 7 deletions src/main/java/org/testng/TestClass.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class TestClass extends NoOpTestClass implements ITestClass, ITestClassConfigInf
private XmlClass xmlClass;
private final String m_errorMsgPrefix;

private Map<String, List<ITestNGMethod>> beforeClassConfig = new HashMap<>();
private final Map<String, List<ITestNGMethod>> beforeClassConfig = new HashMap<>();

@Override
public List<ITestNGMethod> getAllBeforeClassMethods() {
Expand Down Expand Up @@ -155,26 +155,26 @@ private void initMethods() {
testMethodFinder.getBeforeTestConfigurationMethods(m_testClass),
annotationFinder,
true,
instance);
instance, this.xmlTest);
m_afterTestConfMethods =
ConfigurationMethod.createTestConfigurationMethods(
testMethodFinder.getAfterTestConfigurationMethods(m_testClass),
annotationFinder,
false,
instance);
instance, this.xmlTest);
m_beforeClassMethods =
ConfigurationMethod.createClassConfigurationMethods(
testMethodFinder.getBeforeClassMethods(m_testClass),
annotationFinder,
true,
instance);
instance, xmlTest);
beforeClassConfig.put(instance.toString(), Arrays.asList(m_beforeClassMethods));
m_afterClassMethods =
ConfigurationMethod.createClassConfigurationMethods(
testMethodFinder.getAfterClassMethods(m_testClass),
annotationFinder,
false,
instance);
instance, xmlTest);
m_beforeGroupsMethods =
ConfigurationMethod.createBeforeConfigurationMethods(
testMethodFinder.getBeforeGroupsConfigurationMethods(m_testClass),
Expand All @@ -189,10 +189,10 @@ private void initMethods() {
instance);
m_beforeTestMethods =
ConfigurationMethod.createTestMethodConfigurationMethods(
testMethodFinder.getBeforeTestMethods(m_testClass), annotationFinder, true, instance);
testMethodFinder.getBeforeTestMethods(m_testClass), annotationFinder, true, instance, xmlTest);
m_afterTestMethods =
ConfigurationMethod.createTestMethodConfigurationMethods(
testMethodFinder.getAfterTestMethods(m_testClass), annotationFinder, false, instance);
testMethodFinder.getAfterTestMethods(m_testClass), annotationFinder, false, instance, xmlTest);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/testng/TestRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public class TestRunner
private final IResultMap m_failedButWithinSuccessPercentageTests = new ResultMap();
private final IResultMap m_skippedTests = new ResultMap();

private final RunInfo m_runInfo = new RunInfo();
private final RunInfo m_runInfo = new RunInfo(this::getCurrentXmlTest);

// The host where this test was run, or null if run locally
private String m_host;
Expand Down
30 changes: 18 additions & 12 deletions src/main/java/org/testng/internal/ConfigurationMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.testng.internal.annotations.IBeforeSuite;
import org.testng.internal.annotations.IBeforeTest;
import org.testng.log4testng.Logger;
import org.testng.xml.XmlTest;

public class ConfigurationMethod extends BaseTestMethod {

Expand Down Expand Up @@ -96,7 +97,8 @@ public ConfigurationMethod(
boolean isAfterMethod,
String[] beforeGroups,
String[] afterGroups,
Object instance) {
Object instance,
XmlTest xmlTest) {
this(
com,
annotationFinder,
Expand All @@ -112,6 +114,7 @@ public ConfigurationMethod(
afterGroups,
true,
instance);
setXmlTest(xmlTest);
}

private static ITestNGMethod[] createMethods(
Expand All @@ -125,7 +128,8 @@ private static ITestNGMethod[] createMethods(
boolean isAfterClass,
boolean isBeforeMethod,
boolean isAfterMethod,
Object instance) {
Object instance,
XmlTest xmlTest) {
List<ITestNGMethod> result = Lists.newArrayList();
for (ITestNGMethod method : methods) {
if (Modifier.isStatic(method.getConstructorOrMethod().getMethod().getModifiers())) {
Expand All @@ -148,7 +152,7 @@ private static ITestNGMethod[] createMethods(
isAfterMethod,
new String[0],
new String[0],
instance));
instance, xmlTest));
}

return result.toArray(new ITestNGMethod[0]);
Expand All @@ -171,14 +175,14 @@ public static ITestNGMethod[] createSuiteConfigurationMethods(
false,
false,
false,
instance);
instance, null);
}

public static ITestNGMethod[] createTestConfigurationMethods(
ITestNGMethod[] methods,
IAnnotationFinder annotationFinder,
boolean isBefore,
Object instance) {
Object instance, XmlTest xmlTest) {
return createMethods(
methods,
annotationFinder,
Expand All @@ -190,14 +194,14 @@ public static ITestNGMethod[] createTestConfigurationMethods(
false,
false,
false,
instance);
instance, xmlTest);
}

public static ITestNGMethod[] createClassConfigurationMethods(
ITestNGMethod[] methods,
IAnnotationFinder annotationFinder,
boolean isBefore,
Object instance) {
Object instance, XmlTest xmlTest) {
return createMethods(
methods,
annotationFinder,
Expand All @@ -209,7 +213,7 @@ public static ITestNGMethod[] createClassConfigurationMethods(
!isBefore,
false,
false,
instance);
instance, xmlTest);
}

public static ITestNGMethod[] createBeforeConfigurationMethods(
Expand All @@ -233,7 +237,7 @@ public static ITestNGMethod[] createBeforeConfigurationMethods(
false,
isBefore ? methods[i].getBeforeGroups() : new String[0],
new String[0],
instance);
instance, null);
}

return result;
Expand All @@ -259,14 +263,15 @@ public static ITestNGMethod[] createAfterConfigurationMethods(
false,
new String[0],
isBefore ? m.getBeforeGroups() : m.getAfterGroups(),
instance)).toArray(ITestNGMethod[]::new);
instance, null))
.toArray(ITestNGMethod[]::new);
}

public static ITestNGMethod[] createTestMethodConfigurationMethods(
ITestNGMethod[] methods,
IAnnotationFinder annotationFinder,
boolean isBefore,
Object instance) {
Object instance, XmlTest xmlTest) {
return createMethods(
methods,
annotationFinder,
Expand All @@ -278,7 +283,8 @@ public static ITestNGMethod[] createTestMethodConfigurationMethods(
false,
isBefore,
!isBefore,
instance);
instance,
xmlTest);
}

/** @return Returns the isAfterClassConfiguration. */
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/testng/internal/FactoryMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ private void init(Object instance, IAnnotationFinder annotationFinder, Construct
private static String[] getAllGroups(
Class<?> declaringClass, XmlTest xmlTest, IAnnotationFinder annotationFinder) {
// Find the groups of the factory => all groups of all test methods
ITestMethodFinder testMethodFinder = new TestNGMethodFinder(new RunInfo(), annotationFinder);
ITestMethodFinder testMethodFinder = new TestNGMethodFinder(new RunInfo(()-> xmlTest), annotationFinder);
ITestNGMethod[] testMethods = testMethodFinder.getTestMethods(declaringClass, xmlTest);
Set<String> groups = new HashSet<>();
for (ITestNGMethod method : testMethods) {
Expand Down
32 changes: 13 additions & 19 deletions src/main/java/org/testng/internal/MethodHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import java.util.regex.Pattern;

import java.util.stream.Collectors;
import org.testng.IInvokedMethod;
import org.testng.IMethodInstance;
import org.testng.ITestClass;
import org.testng.ITestNGMethod;
Expand All @@ -27,6 +26,7 @@
import org.testng.internal.annotations.IAnnotationFinder;
import org.testng.internal.collections.Pair;
import org.testng.util.TimeUtils;
import org.testng.xml.XmlTest;

/**
* Collection of helper methods to help sort and arrange methods.
Expand Down Expand Up @@ -263,7 +263,11 @@ private static Graph<ITestNGMethod> topologicalSort(

Map<Object, List<ITestNGMethod>> testInstances = sortMethodsByInstance(methods);

XmlTest xmlTest = null;
for (ITestNGMethod m : methods) {
if (xmlTest == null) {
xmlTest = m.getXmlTest();
}
result.addNode(m);

List<ITestNGMethod> predecessors = Lists.newArrayList();
Expand All @@ -289,12 +293,14 @@ private static Graph<ITestNGMethod> topologicalSort(
}
predecessors.addAll(Arrays.asList(methodsNamed));
}
String[] groupsDependedUpon = m.getGroupsDependedUpon();
if (groupsDependedUpon.length > 0) {
for (String group : groupsDependedUpon) {
ITestNGMethod[] methodsThatBelongToGroup =
MethodGroupsHelper.findMethodsThatBelongToGroup(m, methods, group);
predecessors.addAll(Arrays.asList(methodsThatBelongToGroup));
if (XmlTest.isGroupBasedExecution(xmlTest)) {
String[] groupsDependedUpon = m.getGroupsDependedUpon();
if (groupsDependedUpon.length > 0) {
for (String group : groupsDependedUpon) {
ITestNGMethod[] methodsThatBelongToGroup =
MethodGroupsHelper.findMethodsThatBelongToGroup(m, methods, group);
predecessors.addAll(Arrays.asList(methodsThatBelongToGroup));
}
}
}

Comment on lines -292 to 306

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is the reason why dependsOnGroup and dependsOnMethods is broken in #2664

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to propose a fix ;)

Expand Down Expand Up @@ -409,18 +415,6 @@ public static void fixMethodsWithClass(
}
}

public static List<ITestNGMethod> invokedMethodsToMethods(
Collection<IInvokedMethod> invokedMethods) {
List<ITestNGMethod> result = Lists.newArrayList();
for (IInvokedMethod im : invokedMethods) {
ITestNGMethod tm = im.getTestMethod();
tm.setDate(im.getDate());
result.add(tm);
}

return result;
}

public static List<IMethodInstance> methodsToMethodInstances(List<ITestNGMethod> sl) {
return sl.stream().map(MethodInstance::new).collect(Collectors.toList());
}
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/org/testng/internal/MethodInheritance.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@

import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import org.testng.ITestNGMethod;
import org.testng.collections.Lists;
import org.testng.collections.Maps;
import org.testng.xml.XmlTest;

public class MethodInheritance {

Expand Down Expand Up @@ -131,12 +131,13 @@ public static void fixMethodInheritance(ITestNGMethod[] methods, boolean before)
* that @BeforeClass methods in derived class depend on all @BeforeClass methods
* of base class. Vice versa for @AfterXXX methods
*/

for (int i = 0; i < l.size() - 1; i++) {
ITestNGMethod m1 = l.get(i);
for (int j = i + 1; j < l.size(); j++) {
ITestNGMethod m2 = l.get(j);
String[] groups = Optional.ofNullable(m2.getGroups()).orElse(new String[] {});
if (groups.length != 0) {
boolean groupMode = XmlTest.isGroupBasedExecution(m2.getXmlTest());
if (groupMode) {
//Do not resort to adding implicit depends-on if there are groups
continue;
}
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/org/testng/internal/RunInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

import java.util.Set;
import java.util.TreeSet;
import java.util.function.Supplier;
import org.testng.IMethodSelector;
import org.testng.IMethodSelectorContext;
import org.testng.ITestNGMethod;

import java.util.List;
import org.testng.xml.XmlTest;

/**
* This class contains all the information needed to determine what methods should be run. It gets
Expand All @@ -16,6 +18,15 @@
public class RunInfo {

private final Set<MethodSelectorDescriptor> m_methodSelectors = new TreeSet<>();
private final Supplier<XmlTest> xmlTest;

public RunInfo(Supplier<XmlTest> xmlTest) {
this.xmlTest = xmlTest;
}

public XmlTest getXmlTest() {
return xmlTest.get();
}

public void addMethodSelector(IMethodSelector selector, int priority) {
Utils.log("RunInfo", 3, "Adding method selector: " + selector + " priority: " + priority);
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/testng/internal/TestNGMethodFinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ private void addConfigurationMethod(
String[] afterGroups,
Object instance) {
if (method.getDeclaringClass().isAssignableFrom(clazz)) {
ITestNGMethod confMethod =
ConfigurationMethod confMethod =
new ConfigurationMethod(
new ConstructorOrMethod(method),
annotationFinder,
Expand All @@ -249,7 +249,7 @@ private void addConfigurationMethod(
isAfterTestMethod,
beforeGroups,
afterGroups,
instance);
instance, this.runInfo.getXmlTest());
results.add(confMethod);
}
}
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/org/testng/xml/XmlTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -665,4 +665,23 @@ public XmlGroups getXmlGroups() {
public boolean nameMatchesAny(List<String> names) {
return names.contains(getName());
}

/**
* @param xmlTest - The {@link XmlTest} that represents the current <code>test</code>
* @return - <code>true</code> if group based selection was employed and false otherwise.
*/
public static boolean isGroupBasedExecution(XmlTest xmlTest) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why static? why XmlTest as argument?

why not just xmlTest.isGroupBasedExecution()?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@martinaldrin - Any specific reasons behind adding comments on a PR that is already merged ?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just saw it when I tried to figure out the bug that I found in #2664

if (xmlTest == null) {
return false;
}
XmlGroups xmlGroups = xmlTest.getXmlGroups();
if (xmlGroups == null) {
return false;
}
XmlRun xmlRun = xmlGroups.getRun();
if (xmlRun == null) {
return false;
}
return !xmlRun.getIncludes().isEmpty();
}
}
3 changes: 2 additions & 1 deletion src/test/java/org/testng/internal/MethodHelperTest.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.testng.internal;

import org.testng.ITestNGMethod;
import org.testng.Reporter;
import org.testng.TestNGException;
import org.testng.annotations.Test;
import org.testng.internal.annotations.IAnnotationFinder;
Expand Down Expand Up @@ -30,7 +31,7 @@ public void findDependedUponMethods() throws NoSuchMethodException {
false,
new String[0],
new String[0],
testClass);
testClass, Reporter.getCurrentTestResult().getTestContext().getCurrentXmlTest());
method.addMethodDependedUpon("dummyDependsOnMethod");
ITestNGMethod[] methods = new ITestNGMethod[0];

Expand Down
Loading