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

Support suite level thread pools for data provider #2982

Merged
merged 1 commit into from
Nov 28, 2023

Conversation

krmahadevan
Copy link
Member

Closes #2980

We can now configure TestNG such that it uses a
Suite level thread pool when running data driven
Tests in parallel.

This can be enabled via the configuration

“-shareThreadPoolForDataProviders”
with a value of “true”

Alternatively one can also use the suite level
attribute “share-thread-pool-for-data-providers”

Fixes #2980 .

Did you remember to?

  • Add test case(s)
  • Update CHANGES.txt
  • Auto applied styling via ./gradlew autostyleApply

We encourage pull requests that:

  • Add new features to TestNG (or)
  • Fix bugs in TestNG

If your pull request involves fixing SonarQube issues then we would suggest that you please discuss this with the
TestNG-dev before you spend time working on it.

Note: For more information on contribution guidelines please make sure you refer our Contributing section for detailed set of steps.

Copy link
Member

@juherr juherr left a comment

Choose a reason for hiding this comment

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

The change is ok except the new public api and the dtd which should be upgraded

@@ -73,6 +75,7 @@ Cedric Beust & Alexandru Popescu
time-out CDATA #IMPLIED
skipfailedinvocationcounts (true | false) "false"
data-provider-thread-count CDATA "10"
share-thread-pool-for-data-providers (true | false) "false"
Copy link
Member

Choose a reason for hiding this comment

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

We should release a new version of the dtd.

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure. Can you please guide me on the following?

  1. When do we release a new dtd version? That way we have a process that we can follow whenever there are dtd changes.
  2. Assuming that we have the process defined, how do we go about deploying the new dtd.
  3. Since a user can still have their suite xml dtd point to the newer one, how would the new dtd publishing help?

Copy link
Member

Choose a reason for hiding this comment

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

DTD (or XSD) is a contract like an interface.
If you want to modify it, you should release a new version and be able to manage all versions in the XML reader.

Copy link
Member Author

Choose a reason for hiding this comment

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

@juherr - Sure. I understand the intent of the DTD/XSD. But what purpose does this solve for TestNG is what I am trying to understand. Our users are mostly going to be on the same XSD (asking them to go update all the suite files with pointing it to a newer version is kind of like a sub-optimal user experience for me). The XSD exists only because we would like to validate our xml schema and it really doesn't serve any functional purpose from the user's perspective. So why would they want to update. So eventually what benefit does TestNG have by doing this? On the other hand, if we just go and update the same XSD with newer attributes, a user would just need to update to the newer TestNG version that is aware of the newer attributes and this will just work for a user. This is what my concern is.

testng-core-api/src/main/java/org/testng/IObjectBag.java Outdated Show resolved Hide resolved
IObjectBag objectBag = context.getSuite().getObjectBag();
boolean sharedThreadPool = context.getSuite().getXmlSuite().isShareThreadPoolForDataProviders();

@SuppressWarnings("unchecked")
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand why the warning cannot be fixed

Copy link
Member Author

Choose a reason for hiding this comment

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

Any suggestions on how to fix this? I am basically trying to figure out how to push in a PoolService<List<ITestResult>> using generics. I can only replace PoolService with T. I am not sure how to represent the List<ITestResult> here.

Copy link
Member

Choose a reason for hiding this comment

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

Try replacing the diamond operators with the real value.
The inference is maybe not working as expected here.
And maybe it is a javac issue you should try to reproduce in its own independent context and write an issue ;)

Copy link
Member Author

Choose a reason for hiding this comment

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

This is now removed.

Copy link
Member

Choose a reason for hiding this comment

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

I'm still seing it 😉

Copy link
Member Author

Choose a reason for hiding this comment

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

The @SuppressWarnings cannot be removed because the ObjectBag stores objects and I cannot make it store specific types. I did this because I hope to use the ObjectBag as a generic bean bag sort of place.

public Object[][] getSuiteFileNames() {
return new Object[][] {
{
"src/test/resources/2980_with_shared_threadpool_enabled.xml",
Copy link
Member

Choose a reason for hiding this comment

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

Be careful. It only works because resources are not filtered. Otherwise they should be taken from the build context.

Copy link
Member Author

Choose a reason for hiding this comment

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

Can you please tell me how to do this via the build context?

Copy link
Member Author

Choose a reason for hiding this comment

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

Also I think this is the usual convention being followed for the other tests that have existed in the codebase. Would we need filtering on test resources? I thought that made sense when we apply filtering on main resources.

Copy link
Member

Choose a reason for hiding this comment

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

The resources are supposed to be copied into the target folder by the resource plugin which can modify them during the operation.
I prefer to read resources from the target folder then.

Copy link
Member Author

Choose a reason for hiding this comment

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

@juherr - I am not sure why would the resource plugin have to filter out resources (I don't see a use case for having to do this).
There are many tests that just load resources from the file system and work with it. So trying to understand as to why do we need to complicate things by having it loaded from a class path as a stream and then translate that to a file before working with it.

@juherr
Copy link
Member

juherr commented Sep 22, 2023

@krmahadevan Please, let me few days to elaborate my answers

@krmahadevan
Copy link
Member Author

Sure @juherr i will wait to hear back from you.

@dr29bart
Copy link
Contributor

dr29bart commented Sep 22, 2023

@krmahadevan

  1. how -dataproviderthreadcount will affect thread pool size with -shareThreadPoolForDataProviders=true?
  2. Does it make sense to use enum for the pool type similar to FailurePolicy? It will be something like threadPoolForDataProviders
    1. ISOLATED\LEGACY - there will be a separate thread pool for each test with a data provider(parallel=true)
    2. COMMON - there will be an extra thread pool for all tests with a data provider (parallel=true)
    3. SHARED - all (with and without data provider) tests will share the same thread pool

@krmahadevan
Copy link
Member Author

krmahadevan commented Sep 23, 2023

@krmahadevan

  1. how -dataproviderthreadcount will affect thread pool size with -shareThreadPoolForDataProviders=true?

This will cause the entire suite to share a common data provider thread pool for all data driven tests within a <suite>. So going by your enum proposition, it now supports the notion of COMMON

  1. Does it make sense to use enum for the pool type similar to FailurePolicy? It will be something like threadPoolForDataProviders

    1. ISOLATED\LEGACY - there will be a separate thread pool for each test with a data provider(parallel=true)
    2. COMMON - there will be an extra thread pool for all tests with a data provider (parallel=true)
    3. SHARED - all (with and without data provider) tests will share the same thread pool

The current implementation does that but without using an enum. The enum approach is lucrative. We could consider exploring it.

Now with respect to SHARED, its going to be a bit more trickier because we are trying to merge two types of thread pools. The regular test method thread pool basically owners the directed acyclic graph that TestNG creates for test dependencies and the one that data provider uses, it doesn't take into account all of that because this would just be one of the nodes in the DAG. Merging them would require a bit more closer look at the codebase.

@krmahadevan
Copy link
Member Author

@juherr - ping!

@krmahadevan
Copy link
Member Author

@juherr - Please take a look. I have revamped the approach.

Closes testng-team#2980

We can now configure TestNG such that it uses a
Suite level thread pool when running data driven
Tests in parallel.

This can be enabled via the configuration 

“-shareThreadPoolForDataProviders” 
with a value of “true”

Alternatively one can also use the suite level 
attribute “share-thread-pool-for-data-providers”
Copy link
Member

@juherr juherr left a comment

Choose a reason for hiding this comment

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

Lgtm with some risks on dtd

@@ -123,6 +124,9 @@ public String toString() {
private String m_parentModule = "";
private String m_guiceStage = "";

/** Represents a unique id for this suite. Can be used for uniquely identifying the xml suite. */
public final UUID SUITE_ID = UUID.randomUUID();
Copy link
Member

Choose a reason for hiding this comment

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

As not static, in camelCase

Copy link
Member Author

Choose a reason for hiding this comment

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

I wanted this to stand out as if it is a constant. That was why I intentionally broke the naming conventions and used all CAPS

@krmahadevan krmahadevan merged commit 7357104 into testng-team:master Nov 28, 2023
8 of 9 checks passed
@krmahadevan krmahadevan deleted the global_threadpool_2980 branch November 28, 2023 08:25
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 this pull request may close these issues.

Data Provider Threads configuration in the suite don't match the documentation
3 participants