-
Notifications
You must be signed in to change notification settings - Fork 13.9k
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-9088: InternalProcessorContext mock builder [partial] #7933
Conversation
Call for review: @cadonna @mjsax @guozhangwang @vvcephei |
@cadonna could you take another look? |
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.
@pierDipi Thank you very much for this PR. This is how I envisioned the mock.
I did a first pass without looking too much to the unit tests.
streams/src/test/java/org/apache/kafka/test/InternalProcessorContextMock.java
Outdated
Show resolved
Hide resolved
streams/src/test/java/org/apache/kafka/test/InternalProcessorContextMock.java
Outdated
Show resolved
Hide resolved
streams/src/test/java/org/apache/kafka/test/InternalProcessorContextMock.java
Outdated
Show resolved
Hide resolved
streams/src/test/java/org/apache/kafka/test/InternalProcessorContextMock.java
Outdated
Show resolved
Hide resolved
streams/src/test/java/org/apache/kafka/test/InternalProcessorContextMock.java
Outdated
Show resolved
Hide resolved
streams/src/test/java/org/apache/kafka/test/InternalProcessorContextMock.java
Outdated
Show resolved
Hide resolved
streams/src/test/java/org/apache/kafka/test/InternalProcessorContextMock.java
Outdated
Show resolved
Hide resolved
streams/src/test/java/org/apache/kafka/test/InternalProcessorContextMock.java
Outdated
Show resolved
Hide resolved
stateStoreMap.put(storeCapture.getValue().name(), storeCapture.getValue()); | ||
return null; |
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.
Q: Do you think we need to implement this setter behaviour for this mock? Couldn't we not just pass a map of state stores at during the build specification with a method like stateStores(final Map<String, StateStore> stateStores)
and don't specify a behaviour for register()
?
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.
Hi @cadonna,
I didn't get the advantage of this.
I would point out that register()
is often called here: InMemoryWindowStore.java#L111
Anyway, I made all requested modifications except this one, could you take another look?
Thank you.
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.
@pierDipi Sorry for the late reply.
Actually, during our discussions, I thought we agreed to stop the EasyMock experiment because of the public API issue and we should try to do something like #7979 as proposed by @vvcephei. Sorry for the confusion.
Anyways, I would be really happy, if you could take #7979 and extend it to make it robust. Are you still interested?
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.
@cadonna Yes, I'm still interested, but I cannot guarantee when it will happen. I hope it will be done by the end of the next month.
Thanks for the follow-up, this looks cleaner than the last PR. I understand that part of the point here is to explore the EasyMock approach. Given what I said on the last PR, I'm sure it's not surprising if I state that I'm still concerned this is not the best approach. Because such concerns are often too high-level to be useful, I put together a small PR purely to demonstrate the alternative form this work could take: #7979 A couple of things to note:
I really want to underscore that I appreciate all the work you've both put into exploring the EasyMock approach, and that I don't have a particular beef with EasyMock. Just that EasyMock is highest leverage when used in small and localized ways. When you have to put together a builder for a mock, it indicates right away that the use case is not ideal for EasyMock. |
Thanks for the reviews. My first PR merged
Yes, of course.
If the comparison is based on LOC to change, IMHO, there is no way we will be able to find a solution based on
The builder uses it too.
This is a good point. |
First of all thank you very much for the discussion, @pierDipi and @vvcephei. I have now a much clearer picture about the implications of using EasyMock in this case. My original idea was to try to use EasyMock to mock InternalProcessorContext to let EasyMock handle call verification and get rid of our own call verification code. The goal was to have less code to maintain. @vvcephei, while I also think we should try to avoid unnecessary complexity, I also find that your LOC comparison is not completely fair for the following reasons:
Regarding readability, that would still need a couple of iterations of this PR. I cannot follow your reasoning about debuggability and traceability. While I see why it is important to debug a hand-crafted mock, I do not see why it is important to debug a mock created by an external library. Admittedly, there are for sure cases where this is needed, but they should be rare. Said that let's now move to my concerns that arose during our discussions. To really accomplish the goal to let EasyMock handle all call verifications and not introducing too much complexity, we would need to refactor also What do you think? @pierDipi Again, thank you both for the discussions. I learned a lot. |
Thanks @pierDipi and @cadonna , Just to clarify, although the LOC point may be invalid, it sounds like you basically in agreement that (at least for now), we can do something more like #7979 than an EasyMock builder. If so, then I'm (obviously) +1. As a side note, I do think that we should consider what is right for each test. For example, if the desire is just to provide a "dummy" context and verify the black-box behavior of a component (such as, "does this processor forward the right result for the given inputs?"), then the #7979 approach is preferable. However, if the goal is really to verify some specific interaction (like, "does this method get called exactly twice?"), then a mock can still be defined in situ, which we do in many tests mocking other components. IMHO, this strategy plays to the strengths of both approaches. Thanks again, |
test this please |
Hi @guozhangwang, We decided to go ahead with #7979 and therefore this PR can be closed. |
I made a simpler version of a builder for mocking
InternalProcessorContext
.ref: 7718
Committer Checklist (excluded from commit message)