-
Notifications
You must be signed in to change notification settings - Fork 14.1k
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
KAFKA-17587 Refactor test infrastructure #18602
base: trunk
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mumrah thanks for this refactor. I run the command ./gradlew cleanTest test-common:test-common-runtime:test
and it results in some error below:
Gradle Test Run :test-common:test-common-runtime:test > Gradle Test Executor 109 > TestKitNodeTest > testSecurityProtocol(SecurityProtocol) > initializationError FAILED
java.lang.IllegalStateException: Please annotate test methods with @ClusterTemplate, @ClusterTest, or @ClusterTests when using the ClusterTestExtensions provider
at org.apache.kafka.common.test.junit.ClusterTestExtensions.provideTestTemplateInvocationContexts(ClusterTestExtensions.java:147)
at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:273)
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1708)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
@@ -1364,6 +1365,9 @@ project(':metadata') { | |||
testImplementation project(':raft').sourceSets.test.output | |||
testImplementation project(':server-common').sourceSets.test.output | |||
|
|||
testImplementation project(':test-common:test-common-api') | |||
testRuntimeOnly project(':test-common:test-common-runtime') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why only metadata
module declares test-common:test-common-runtime
as testRuntimeOnly
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was just done to illustrate the approach (and test it in the build). I'll revert this bit before merging
@@ -79,7 +79,7 @@ a JUnit extension called `ClusterTestExtensions` which knows how to process thes | |||
invocations. Test classes that wish to make use of these annotations need to explicitly register this extension: | |||
|
|||
```scala | |||
import org.apache.kafka.common.test.api.ClusterTestExtensions | |||
import org.apache.kafka.common.test.junit.ClusterTestExtensions | |||
|
|||
@ExtendWith(value = Array(classOf[ClusterTestExtensions])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't need it, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. I'll update these docs.
import org.apache.kafka.common.config.SaslConfigs | ||
import org.apache.kafka.common.config.internals.BrokerSecurityConfigs | ||
import org.apache.kafka.common.message.SaslHandshakeRequestData | ||
import org.apache.kafka.common.protocol.{ApiKeys, Errors} | ||
import org.apache.kafka.common.requests.{ApiVersionsRequest, ApiVersionsResponse, SaslHandshakeRequest, SaslHandshakeResponse} | ||
import org.apache.kafka.common.security.auth.SecurityProtocol | ||
import org.apache.kafka.common.test.ClusterInstance | ||
import org.apache.kafka.common.test.junit.ClusterTestExtensions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we remove @ExtendWith(value = Array(classOf[ClusterTestExtensions]))
from this class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, good catch 😄 I left this one here intentionally to make sure it still worked if people explicitly add the annotation in the future
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well this was a bad choice for a test since this one is disabled. I tried it locally on another test and verified keeping the annotation is harmless
@chia7712 I think this commit should fix the initialization issue. Since SPI is being used, it loads the extension for all tests. We need some additional filtering to not apply the ClusterTest logic to regular tests. |
Thanks for the PR. A couple of questions:
These questions will help validate the names we have chosen. |
I think that would make sense. There's quite a bit of utility test code that could be kept at Java 11. In this case we might consider
I was thinking |
Makes sense to use the The only open question for me is the |
Hm, yea.. I see what you mean. Here are some ideas for alternatives to test-common-api
|
Since you're calling one |
I like "internal-api" 👍 |
This patch reorganizes our test infrastructure into three Gradle modules:
":test-common:test-common-internal-api" is now a minimal dependency which exposes interfaces and annotations only. It has one project dependency on server-common to expose commonly used data classes (MetadataVersion, Feature, etc). Since this pulls in server-common, this module is Java 17+. It cannot be used by ":clients" or other Java 11 modules.
":test-common:test-common-util" includes the auto-quarantined JUnit extension. The
@Flaky
annotation has been moved here. Since this module has no project dependencies, we can add it to the Java 11 list so that ":clients" and others can utilize the@Flaky
annotation":test-common:test-common-runtime" now includes all of the test infrastructure code (TestKitNodes, etc). This module carries heavy dependencies (core, etc) and so it should not normally be included as a compile-time dependency.
In addition to this reorganization, this patch leverages JUnit SPI service discovery so that modules can utilize the integration test framework without depending on ":core". This will allow us to start moving integration tests out of core and into the appropriate sub-module. This is done by adding ":test-common:test-common-runtime" as a testRuntimeOnly dependency rather than as a testImplementation dependency. A trivial example was added to QuorumControllerTest to illustrate this.
This patch does not expose ClusterInstance through the SPI since it has many direct dependencies on core. A stripped-down version of ClusterInstance that can be used by non-core modules remains as future work.