-
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-15913: Migrate async consumer tests to mocks #14930
Conversation
1531135
to
cb624ef
Compare
3d59e41
to
6377a9d
Compare
clients/src/main/java/org/apache/kafka/clients/consumer/internals/AsyncKafkaConsumer.java
Outdated
Show resolved
Hide resolved
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.
Thanks for the PR, @lucasbru !
Here my feedback.
clients/src/test/java/org/apache/kafka/clients/consumer/internals/AsyncKafkaConsumerTest.java
Outdated
Show resolved
Hide resolved
clients/src/test/java/org/apache/kafka/clients/consumer/internals/AsyncKafkaConsumerTest.java
Outdated
Show resolved
Hide resolved
clients/src/test/java/org/apache/kafka/clients/consumer/internals/AsyncKafkaConsumerTest.java
Outdated
Show resolved
Hide resolved
clients/src/test/java/org/apache/kafka/clients/consumer/internals/AsyncKafkaConsumerTest.java
Outdated
Show resolved
Hide resolved
(short) 1, | ||
Errors.NONE).responseBody()); | ||
} | ||
private void mockCommitApplicationEventException(Exception ex) { |
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.
I think calling this method (and its siblings) something like completeCommitApplicationEventExceptionally()
(completeCommitApplicationEventSuccessfully()
for the good case) would make the code better readable.
assertDoesNotThrow(() -> consumer.commitAsync()); | ||
future.completeExceptionally(Errors.FENCED_INSTANCE_ID.exception()); | ||
} |
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.
Isn't here something missing? The next call to consumer.commitAsync()
should throw, right? Shouldn't we verify that?
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.
Good point. There were a couple of poor tests and I didn't feel like fixing it all, but this one is a good one to fix. Done
verify(applicationEventHandler).add(ArgumentMatchers.isA(FetchCommittedOffsetsApplicationEvent.class)); | ||
} | ||
assertDoesNotThrow(() -> consumer.committed(topicPartitionOffsets.keySet(), Duration.ofMillis(1000))); | ||
verify(applicationEventHandler).addAndGet(ArgumentMatchers.isA(FetchCommittedOffsetsApplicationEvent.class), any()); |
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.
I am missing the verification of the return value of committed()
.
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.
Also didn't have it before but I fixed it.
@@ -482,6 +497,47 @@ private void process(final GroupMetadataUpdateEvent event) { | |||
requestManagersSupplier); | |||
} | |||
|
|||
// auxiliary interface for testing | |||
interface ApplicationEventHandlerSupplier { |
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.
It is nor clear to me why we need a supplier here. Could you elaborate?
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.
I want to inject a custom implementation of the applicationEventHandler. It needs to work for both prod and testing so that we can actually test the code we are running. The instantiation for prod depends on arguments that are created inside the constructor of AsyncKafkaConsumer. If I do not define this supplier, I cannot inject the constructor of the "real" ApplicationEventHandler for prod.
clients/src/test/java/org/apache/kafka/clients/consumer/internals/AsyncKafkaConsumerTest.java
Show resolved
Hide resolved
// Visible for testing | ||
SubscriptionState subscriptions() { | ||
return subscriptions; | ||
} |
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.
Is there a way to avoid this?
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.
- I can add callback to the constructor that registers the SubscriptionState with the calling context (the test)
- I can add another factory to inject our own instance of SubscriptionState
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.
LGTM!
We can work on the open test-specific questions in a follow-up PR. Now it is important to get a first version of the spy-free unit tests merged.
Thanks, @lucasbru !
make fenced exception test more unflaky. assert( ... instanceof ... ) -> assertIsInstanceOf(...)
Use mocks to test the AsyncKafkaConsumer Eliminate the use of ConsumerTestBuilder Mock all resources that were previously retrieved via leaking the background thread with mockito spys Always use the default constructor of AsyncKafkaConsumer as much as possible, inject mocks via factories. Timeouts are mocked directly by timeout exceptions instead of waiting for futures to time out. I did not port the autocommit mocking code, because it was mostly testing the integration of foreground and background thread (or making the spy's work which broke during the autocommit on close) and is currently being reimplemented anyway. New test runs 10x faster. Reviewers: Bruno Cadonna <[email protected]>
Use mocks to test the AsyncKafkaConsumer Eliminate the use of ConsumerTestBuilder Mock all resources that were previously retrieved via leaking the background thread with mockito spys Always use the default constructor of AsyncKafkaConsumer as much as possible, inject mocks via factories. Timeouts are mocked directly by timeout exceptions instead of waiting for futures to time out. I did not port the autocommit mocking code, because it was mostly testing the integration of foreground and background thread (or making the spy's work which broke during the autocommit on close) and is currently being reimplemented anyway. New test runs 10x faster. Reviewers: Bruno Cadonna <[email protected]>
Use mocks to test the AsyncKafkaConsumer Eliminate the use of ConsumerTestBuilder Mock all resources that were previously retrieved via leaking the background thread with mockito spys Always use the default constructor of AsyncKafkaConsumer as much as possible, inject mocks via factories. Timeouts are mocked directly by timeout exceptions instead of waiting for futures to time out. I did not port the autocommit mocking code, because it was mostly testing the integration of foreground and background thread (or making the spy's work which broke during the autocommit on close) and is currently being reimplemented anyway. New test runs 10x faster. Reviewers: Bruno Cadonna <[email protected]>
Use mocks to test the AsyncKafkaConsumer Eliminate the use of ConsumerTestBuilder Mock all resources that were previously retrieved via leaking the background thread with mockito spys Always use the default constructor of AsyncKafkaConsumer as much as possible, inject mocks via factories. Timeouts are mocked directly by timeout exceptions instead of waiting for futures to time out. I did not port the autocommit mocking code, because it was mostly testing the integration of foreground and background thread (or making the spy's work which broke during the autocommit on close) and is currently being reimplemented anyway. New test runs 10x faster. Reviewers: Bruno Cadonna <[email protected]>
Use mocks to test the AsyncKafkaConsumer Eliminate the use of ConsumerTestBuilder Mock all resources that were previously retrieved via leaking the background thread with mockito spys Always use the default constructor of AsyncKafkaConsumer as much as possible, inject mocks via factories. Timeouts are mocked directly by timeout exceptions instead of waiting for futures to time out. I did not port the autocommit mocking code, because it was mostly testing the integration of foreground and background thread (or making the spy's work which broke during the autocommit on close) and is currently being reimplemented anyway. New test runs 10x faster. Reviewers: Bruno Cadonna <[email protected]>
Use mocks to test the AsyncKafkaConsumer Eliminate the use of ConsumerTestBuilder Mock all resources that were previously retrieved via leaking the background thread with mockito spys Always use the default constructor of AsyncKafkaConsumer as much as possible, inject mocks via factories. Timeouts are mocked directly by timeout exceptions instead of waiting for futures to time out. I did not port the autocommit mocking code, because it was mostly testing the integration of foreground and background thread (or making the spy's work which broke during the autocommit on close) and is currently being reimplemented anyway. New test runs 10x faster. Reviewers: Bruno Cadonna <[email protected]>
The purpose of this PR is to remove ConsumerTestBuilder.java since it is no longer needed. The following PRs have eliminated the use of ConsumerTestBuilder: #14930 #16140 #16200 #16312 Reviewers: Chia-Ping Tsai <[email protected]>
Use mocks to test the AsyncKafkaConsumer
the background thread with mockito spys
much as possible, inject mocks via factories.
of waiting for futures to time out.
I did not port the autocommit mocking code, because it was mostly
testing the integration of foreground and background thread (or
making the spy's work which broke during the autocommit on close)
and is currently being reimplemented anyway.
New test runs 10x faster.
Committer Checklist (excluded from commit message)