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

fix: deflake-ify ITSystemTest#queryWatch #107

Merged
merged 15 commits into from Mar 3, 2020
Merged

fix: deflake-ify ITSystemTest#queryWatch #107

merged 15 commits into from Mar 3, 2020

Conversation

BenWhitehead
Copy link
Collaborator

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.

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.
@googlebot googlebot added the cla: yes This human has signed the Contributor License Agreement. label Feb 13, 2020
@codecov
Copy link

codecov bot commented Feb 13, 2020

Codecov Report

Merging #107 into master will decrease coverage by 0.4%.
The diff coverage is n/a.

Impacted file tree graph

@@             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
Impacted Files Coverage Δ Complexity Δ
...cloud/firestore/collection/ImmutableSortedMap.java 13.95% <0%> (-1.96%) 1% <0%> (ø)
...oogle/cloud/firestore/v1beta1/FirestoreClient.java 54.63% <0%> (-1.56%) 25% <0%> (-6%)
.../java/com/google/cloud/firestore/Precondition.java 68.18% <0%> (-1.39%) 12% <0%> (-3%)
...com/google/cloud/firestore/v1/FirestoreClient.java 76.28% <0%> (-0.86%) 31% <0%> (-6%)
...loud/firestore/v1beta1/stub/GrpcFirestoreStub.java 93.67% <0%> (-0.57%) 16% <0%> (-1%)
...a/com/google/cloud/firestore/FirestoreOptions.java 36.44% <0%> (-0.54%) 7% <0%> (ø)
...loud/firestore/v1/stub/GrpcFirestoreAdminStub.java 94.32% <0%> (-0.46%) 15% <0%> (-1%)
...ain/java/com/google/cloud/firestore/FieldMask.java 87.09% <0%> (-0.41%) 13% <0%> (-2%)
.../firestore/v1beta1/stub/FirestoreStubSettings.java 79.26% <0%> (-0.38%) 22% <0%> (-1%)
...gle/cloud/firestore/v1/stub/GrpcFirestoreStub.java 96.04% <0%> (-0.36%) 19% <0%> (-1%)
... and 11 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update fcdbab3...7336a03. Read the comment docs.

@kolea2
Copy link
Collaborator

kolea2 commented Feb 18, 2020

LGTM

@BenWhitehead
Copy link
Collaborator Author

@schmidt-sebastian Can you get a quick review from you on this PR?

Copy link
Contributor

@schmidt-sebastian schmidt-sebastian left a 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
Copy link
Contributor

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).

Copy link
Collaborator Author

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?

Copy link
Contributor

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()
Copy link
Contributor

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 :)

Copy link
Collaborator Author

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/?

Copy link
Contributor

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.


ListenerAssertions la = listener.assertions();
la.noError();
la.eventCountIsAnyOf(Range.closed(1, 2));
Copy link
Contributor

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.

Copy link
Collaborator Author

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()
Copy link
Contributor

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 {
Copy link
Contributor

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?

Copy link
Collaborator Author

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

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));
Copy link
Contributor

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.

Copy link
Collaborator Author

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.

@BenWhitehead
Copy link
Collaborator Author

@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?)

Copy link
Contributor

@schmidt-sebastian schmidt-sebastian left a 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
Copy link
Contributor

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()
Copy link
Contributor

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.

ListenerRegistration registration = query.addSnapshotListener(listener);

try {
randomColl.document("doc").set(map("foo", "bar")).get(5, TimeUnit.SECONDS);
Copy link
Contributor

Choose a reason for hiding this comment

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

Sounds good.

@BenWhitehead
Copy link
Collaborator Author

@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.

Copy link
Contributor

@schmidt-sebastian schmidt-sebastian left a 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>
Copy link
Contributor

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?

Copy link
Collaborator Author

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.

@BenWhitehead BenWhitehead merged commit f701c67 into googleapis:master Mar 3, 2020
@BenWhitehead BenWhitehead deleted the deflake-queryWatch branch March 3, 2020 20:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes This human has signed the Contributor License Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants