-
Notifications
You must be signed in to change notification settings - Fork 67
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
fix: deflake-ify ITSystemTest#queryWatch #107
fix: deflake-ify ITSystemTest#queryWatch #107
Conversation
queryWatch has been flaky because several things are happening in the single event stream. This fix splits up the different scenarios being tested into their own respective tests and updates the assertions to be more specific to the scenario as well as handling the semantics of the backend better.
Codecov Report
@@ Coverage Diff @@
## master #107 +/- ##
============================================
- Coverage 71.97% 71.56% -0.41%
+ Complexity 997 968 -29
============================================
Files 62 62
Lines 5323 5202 -121
Branches 599 579 -20
============================================
- Hits 3831 3723 -108
+ Misses 1304 1299 -5
+ Partials 188 180 -8
Continue to review full report at Codecov.
|
LGTM |
@schmidt-sebastian Can you get a quick review from you on this PR? |
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, this is much better than writing Perf (and pretty good in general). I think we could simplify the test a bit by relying on more deterministic ordering.
} | ||
|
||
/* | ||
Start a listener on a query with an empty result set |
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.
Please fix (here and everywhere).
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.
What fix would you like me to apply here? Turn this into a sentence?
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.
Sorry, I should have been more clear (or rather just "be clear"). Can you turn this into a JSDoc comment and prefix all lines with *
?
google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryWatchTest.java
Outdated
Show resolved
Hide resolved
that matches the query should result in an ADDED event | ||
*/ | ||
@Test | ||
public void emptyResults_newDocument_ADDED() |
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 name could use a sprinkle of the Java Style Guide :)
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 type of scenario is specifically called out in the style guide: http://go/java-style#s5.2.3-method-names
Underscores may appear in JUnit test method names to separate logical components of the name, with each component written in lowerCamelCase
Is your ask here for me to not use the upper enum names? i.e. s/ADDED/added/
?
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.
Interesting. I was going to suggest to use camel case throughout, but I withdraw my suggestion hereby.
google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryWatchTest.java
Outdated
Show resolved
Hide resolved
|
||
ListenerAssertions la = listener.assertions(); | ||
la.noError(); | ||
la.eventCountIsAnyOf(Range.closed(1, 2)); |
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.
If you wait for the initial empty event, the number of events is deterministic.
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.
Will update
match the query should result in an ADDED event | ||
*/ | ||
@Test | ||
public void emptyResults_modifiedDocument_ADDED() |
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.
Same comment regarding the style guide.
List<ListenerEvent> receivedEvents = listener.receivedEvents; | ||
ListenerRegistration registration = query.addSnapshotListener(listener); | ||
|
||
try { |
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 test would be easier to follow if you waited for the initial snapshot. Do you mind updating all tests?
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'll make sure all tests wait for the initial event
google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryWatchTest.java
Outdated
Show resolved
Hide resolved
google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryWatchTest.java
Outdated
Show resolved
Hide resolved
cdls = new EnumMap<>(DocumentChange.Type.class); | ||
cdls.put(DocumentChange.Type.ADDED, new CountDownLatch(addedInitial)); | ||
cdls.put(DocumentChange.Type.MODIFIED, new CountDownLatch(modifiedInitial)); | ||
cdls.put(DocumentChange.Type.REMOVED, new CountDownLatch(removedInitial)); |
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.
The way the Watch is used in this test (adding or modifying a document at a time) is actually deterministic. By splitting these updates across types, you add some complexity to the tests that I don't think you need.
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 tried removing the individual CountDownLatches here and ran into several tests becoming more flaky, so I'd like to leave this for now and spend more time digging into it later.
…on to facilitate diagnostics
@schmidt-sebastian I've pushed several commits that have addressed most of your comments. (I added some more debugging information to the assertions in the case that they fail to hopefully aid in diagnostics when we see failures. I've seen a few failures working on things, seemingly related to events taking longer than we allow the |
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.
@schmidt-sebastian I've pushed several commits that have addressed most of your comments. (I added some more debugging information to the assertions in the case that they fail to hopefully aid in diagnostics when we see failures. I've seen a few failures working on things, seemingly related to events taking longer than we allow the
await
to block. Is there a defined SLO for events being delivered?)
I was only able to find this internally: https://g3doc.corp.google.com/cloud/datastore/g3doc/SLO.md?cl=head
} | ||
|
||
/* | ||
Start a listener on a query with an empty result set |
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.
Sorry, I should have been more clear (or rather just "be clear"). Can you turn this into a JSDoc comment and prefix all lines with *
?
that matches the query should result in an ADDED event | ||
*/ | ||
@Test | ||
public void emptyResults_newDocument_ADDED() |
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.
Interesting. I was going to suggest to use camel case throughout, but I withdraw my suggestion hereby.
google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryWatchTest.java
Show resolved
Hide resolved
google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryWatchTest.java
Outdated
Show resolved
Hide resolved
google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryWatchTest.java
Outdated
Show resolved
Hide resolved
ListenerRegistration registration = query.addSnapshotListener(listener); | ||
|
||
try { | ||
randomColl.document("doc").set(map("foo", "bar")).get(5, TimeUnit.SECONDS); |
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.
Sounds good.
google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryWatchTest.java
Outdated
Show resolved
Hide resolved
google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryWatchTest.java
Outdated
Show resolved
Hide resolved
google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryWatchTest.java
Show resolved
Hide resolved
google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryWatchTest.java
Show resolved
Hide resolved
…pected for that type of event
@schmidt-sebastian I've taken care of all the nits, and I update the await conditions to be a multiple of the number of events rather than the firm 5 seconds. This will at least scale our tolerance in the test since. |
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 all the updates. Looking forward to non-flaky development on Firestore :)
/** | ||
* | ||
* | ||
* <ol> |
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.
Nit: Are the two empty lines above from code formatting?
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.
They are indeed. I wasn't able to figure out a way to remove them.
queryWatch has been flaky because several things are happening in the
single event stream. This fix splits up the different scenarios being
tested into their own respective tests and updates the assertions to be
more specific to the scenario as well as handling the semantics of the
backend better.