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

Null Pointer occurs when a Retried test has an exception in DataProvider #2157

Closed
3 of 7 tasks
OstapJ opened this issue Sep 30, 2019 · 1 comment · Fixed by #2159
Closed
3 of 7 tasks

Null Pointer occurs when a Retried test has an exception in DataProvider #2157

OstapJ opened this issue Sep 30, 2019 · 1 comment · Fixed by #2159
Assignees
Milestone

Comments

@OstapJ
Copy link

OstapJ commented Sep 30, 2019

TestNG Version

7.0.0

Also reproducible on:
6.14.3, 7.0.0beta1

Expected behavior

The test should be in Skipped status.
A checked exception occurred in DataProvider should be handled.

Actual behavior

java.lang.NullPointerException
	at java.util.Objects.requireNonNull(Objects.java:203)
	at org.testng.internal.TestInvoker.retryFailed(TestInvoker.java:192)
	at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:58)
	at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:804)
	at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:145)
	at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
	at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
	at java.util.ArrayList.forEach(ArrayList.java:1255)
	at org.testng.TestRunner.privateRun(TestRunner.java:770)
	at org.testng.TestRunner.run(TestRunner.java:591)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:402)
	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:396)
	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:355)
	at org.testng.SuiteRunner.run(SuiteRunner.java:304)
	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1180)
	at org.testng.TestNG.runSuitesLocally(TestNG.java:1102)
	at org.testng.TestNG.runSuites(TestNG.java:1032)
	at org.testng.TestNG.run(TestNG.java:1000)
	at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.runTests(TestNGTestClassProcessor.java:139)
	at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.stop(TestNGTestClassProcessor.java:89)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
	at com.sun.proxy.$Proxy2.stop(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:131)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:155)
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:137)
	at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
	at java.lang.Thread.run(Thread.java:748)

Is the issue reproductible on runner?

  • Shell
  • Maven
  • Gradle
  • Ant
  • Eclipse
  • IntelliJ
  • NetBeans

Test case sample

The test case is implemented in the project below.
https://github.com/OstapJ/testng-issue-retry-dataprovider

The test with Retry and DataProvider

import org.testng.annotations.Test;

import java.util.concurrent.atomic.AtomicInteger;

public class RetryTest {
    private AtomicInteger counter = new AtomicInteger();

    @Test(description = "Nullpointer occurs when Retried test has exception is DataProvider",
            dataProviderClass = DP.class, dataProvider = "dpWithException",
            groups = {"issue"}, retryAnalyzer = RetryImpl.class
    )
    void testExample(String value) {
        counter.getAndIncrement();

        if(counter.get() == 1){
            assert value.isEmpty();
        }
        if(counter.get() == 2){
            assert value.isEmpty();
        }
    }
}

DataProvider with exception

import org.testng.annotations.DataProvider;

import java.util.concurrent.atomic.AtomicInteger;

public class DP {
    private static AtomicInteger counter = new AtomicInteger();
    
    @DataProvider
    public static Object[][] dpWithException() {
        return new Object[][]{
            {foo()},
        };
    }

    private static String foo(){
        counter.getAndIncrement();

        if(counter.get() == 1){
            return "First";
        }
        if(counter.get() == 2){
            return "Second";
        }
        throw new RuntimeException("TestNG doesn't handle an exception");
    }
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;

import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

public class RetryImpl implements IRetryAnalyzer {
    private static final Logger LOG = LoggerFactory.getLogger(RetryImpl.class);
    private final Map<Integer, AtomicInteger> counts = new ConcurrentHashMap<>();

    private AtomicInteger getCount(ITestResult result) {
        int id = Arrays.hashCode((result.getTestClass().getName() + result.getName() + result.getMethod().getParameterInvocationCount()).getBytes());

        AtomicInteger count = counts.get(id);
        if (count == null) {
            count = new AtomicInteger(3);
            counts.put(id, count);
        }
        return count;
    }

    @Override
    public boolean retry(ITestResult result) {
        int retriesRemaining = getCount(result).getAndDecrement();
        return retriesRemaining > 0;

    }
}
krmahadevan added a commit to krmahadevan/testng that referenced this issue Oct 1, 2019
@krmahadevan krmahadevan added this to the 7.1 milestone Oct 1, 2019
@krmahadevan krmahadevan self-assigned this Oct 1, 2019
krmahadevan added a commit to krmahadevan/testng that referenced this issue Oct 1, 2019
krmahadevan added a commit to krmahadevan/testng that referenced this issue Oct 2, 2019
krmahadevan added a commit that referenced this issue Oct 2, 2019
@DzmitryHumianiuk
Copy link

krmahadevan added a commit to krmahadevan/testng that referenced this issue Mar 17, 2023
Closes testng-team#2884

When a data driven test fails, then ensure that 
we don’t call the data provider once again when 
retrying the test (we seem to invoke the data 
provider multiple times, but ignore the value)

As part of fixing this, getting rid of the test for
testng-team#2157.

testng-team#2157 - deals with null pointer exceptions arising
Out of data provider that was re-invoked as a result
Of us retrying a failed test.

But now since a data provider is NOT going to be 
re-invoked the changes for testng-team#2157 become irrelevant.
krmahadevan added a commit that referenced this issue Mar 20, 2023
Closes #2884

When a data driven test fails, then ensure that 
we don’t call the data provider once again when 
retrying the test (we seem to invoke the data 
provider multiple times, but ignore the value)

As part of fixing this, getting rid of the test for
#2157.

#2157 - deals with null pointer exceptions arising
Out of data provider that was re-invoked as a result
Of us retrying a failed test.

But now since a data provider is NOT going to be 
re-invoked the changes for #2157 become irrelevant.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants