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

Execution stalls when using "use-global-thread-pool" #3028

Closed
2 of 7 tasks
krmahadevan opened this issue Dec 29, 2023 · 0 comments · Fixed by #3119
Closed
2 of 7 tasks

Execution stalls when using "use-global-thread-pool" #3028

krmahadevan opened this issue Dec 29, 2023 · 0 comments · Fixed by #3119

Comments

@krmahadevan
Copy link
Member

TestNG Version

Note: only the latest version is supported

7.9.0

Expected behaviour

The tests should run to completion.

Actual behaviour

Test execution stalls indefinitely.

Is the issue reproducible on runner?

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

Test case sample

Please, share the test case (as small as possible) which shows the issue

Below is a sample test class

import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class TestClassSample {

    @Test(dataProvider = "dp")
    public void a(int ignored) {
        log();
    }

    @Test(dataProvider = "dp")
    public void b(int ignored) {
        log();
    }

    private void log() {
        ITestResult itr = Reporter.getCurrentTestResult();
        long id = Thread.currentThread().getId();
        System.err.println("Running " + itr.toString() + " on Thread " + id);
    }

    @DataProvider(name = "dp", parallel = true)
    public Object[][] getData() {
        return new Object[][]{
                {1}, {2}, {3}, {4}, {5}
        };
    }

    @BeforeMethod
    public void beforeMethod() {
        System.err.println("[Commencing running] " + Reporter.getCurrentTestResult() + " on thread " + Thread.currentThread().getId());
    }

    @AfterMethod
    public void afterMethod() {
        System.err.println("[Completed running] " + Reporter.getCurrentTestResult() + " on thread " + Thread.currentThread().getId());

    }
}

Below is how the suite file looks like

<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.1.dtd">
<suite name="2980_suite" verbose="2" parallel="methods" thread-count="2" use-global-thread-pool="true">
    <test name="2980_test">
        <classes>
            <class name="com.rationaleemotions.dp.TestClassSample"/>
        </classes>
    </test>
</suite>

Analysis:

  • TestNG creates two objects of TestMethodWorker for each of the 2 tests.
  • Since each of the test is data driven in nature and since we have instructed TestNG to use a shared thread pool [ whose size has been configured to be 2 via thread-count attribute at the suite file], each of the TestMethodWorker internally ends up submitting 5 additional tasks to the existing thread pool's queue.
  • But the ThreadPoolExecutor has only 2 threads at its disposal.
  • Since the ThreadPoolExecutor already has submitted two tasks into the thread pool via each of the TestMethodWorker objects, it cannot submit any additional tasks.
  • Both the existing tasks cannot run to completion also, because they both are internally data driven tests and a data driven test is deemed to be executed ONLY after all its iterations have been completed.
  • Because of all this, we end up in a stalled state.
  • The only way to fix this would be to ensure that our threadpool has atleast 1 more additional thread for the data driven tests to run to completion (This is NOT going to be possible)

The long-term solution should be that TestNG should not create nested tasks via the TestMethodWorker, but it should basically expand all the iterations and then add them directly as individual tasks. So, in our example, TestNG would basically have to create 10 tasks instead of it creating 2 parent level tasks and each of the parent tasks creating tasks internally and adding it back to the same thread pool.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant