-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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 flaky tests in multiple modules due to non-deterministic specification of HashSet and JSON objects #15418
Conversation
@yashdeep97 Could you and the other folks working with the https://github.com/TestingResearchIllinois/NonDex raise a single PR with the changes to the module. |
Hi @cryptoe, |
ac7d6a4
to
c56e856
Compare
c56e856
to
e763047
Compare
38ede59
to
73929cb
Compare
3f4261e
to
9d5f403
Compare
…st and FlattenSpecParquetReaderTest Co-authored-by: lakkidi2 <lakkidi2@fa23-cs527-035.cs.illinois.edu> Co-authored-by: lxb007981 <lxb007981@hotmail.com> Co-authored-by: Prathyush Reddy Lakkidi <prathyushreddylakkidi@Prathyushs-MacBook-Air.local>
…ns, indexing-service modules
Hi @cryptoe, |
Merged changes from the following PRs: |
@@ -39,6 +39,7 @@ | |||
class BaseParquetReaderTest extends InitializedNullHandlingTest | |||
{ | |||
ObjectWriter DEFAULT_JSON_WRITER = new ObjectMapper().writerWithDefaultPrettyPrinter(); | |||
protected final ObjectMapper objectMapper = new ObjectMapper(); |
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: you can use the object mapper created on line 42 for line 41 and remove the inline instantiation of the object mapper.
expectedJsonBinary, | ||
DEFAULT_JSON_WRITER.writeValueAsString(sampledAsBinary.get(0).getRawValues()) | ||
); | ||
objectMapper.readTree(expectedJsonBinary), |
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.
Create a json test utils and then use that to do the assert everywhere.
You can put that class in druid core I think.
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 @cryptoe, Thanks for your feedback, I'll work on making these changes over this weekend
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 @cryptoe, I'm unable to figure out where to place this new class that does assert after converting it to JSON tree, should I place it under the druid-testing-tools module in extensions-core? (I did not understand what druid core refers to)
"mediumBroker", ImmutableList.of(), | ||
"coldBroker", ImmutableList.of("coldHost1:8080", "coldHost2:8080"), | ||
"hotBroker", ImmutableList.of("hotHost:8080") | ||
"mediumBroker", ImmutableSet.of(), |
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 is this change required ?
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.
So, it uses servers
which is a ConcurrentHashMap
to create the list of Hostnames.
druid/services/src/main/java/org/apache/druid/server/router/TieredBrokerHostSelector.java
Line 63 in e373f62
private final ConcurrentHashMap<String, NodesHolder> servers = new ConcurrentHashMap<>(); |
And ConcurrentHashMap does not preserve the the ordering of the keys, which can result in the order of servers being different that what is expected in the Assert.
For example: we might get ImmutableList.of("coldHost2:8080", "coldHost1:8080") instead of ImmutableList.of("coldHost1:8080", "coldHost2:8080") which will result in the test failing.
Thus, the code incorrectly assumes deterministic ordering of the keys in ConcurrentHashMap.
Can you also include #15268 if not included already. |
Have all of these tests been reported as flaky by Druid users/devs? I am not sure if that is really the case. These changes seem to be using sets instead of lists in a lot of places and changing equality assertions of json strings to JsonNode objects. Are these changes really needed? If there is indeed a flaky test, please share links in the PR description to one or more builds where these tests actually failed. For cases where there is a flake, we should try to figure out exactly what is causing the flakiness and update tests only when we fully understand the intent of the original test. cc: @yashdeep97 , @cryptoe |
This pull request has been marked as stale due to 60 days of inactivity. |
This pull request/issue has been closed due to lack of activity. If you think that |
I found some flaky tests using the NonDex Plugin for maven in various modules.
Description
Fixed the following flaky tests:
processing
module:services
module:indexing-service
module:extensions-core/parquet-extensions
module:server
module:Problem:
The above mentioned tests have been reported as flaky (tests assuming deterministic implementation of a non-deterministic specification ) when ran against the NonDex tool.
The tests contain assertions that compare strings created from JSON objects and lists created from HashSets and HashMaps.
However, HashSet does not guarantee the ordering of elements and thus resulting in these flaky tests that assume deterministic implementation of HashSet. Also, some tests check for a specific ordering of elements in JSON strings. JSON objects are equal even if the ordering of the elements in the JSON strings are not equal. This results in flakiness as the Jackson ObjectMapper does not guarantee consistent ordering of the JSON keys.
Thus, when the NonDex tool shuffles the HashSet elements and the JSON keys, it results in test failures:
Errors can be found in this Github issue: #15471
To reproduce run:
Fix:
For the tests failing due to inequality in ordering of objects in lists that were created from HashSets or HashMaps, first convert the arraylists to hashSets and then compare the 2 HashSets using assertEquals().
For all the tests failing due to inequality in ordering of keys in JSON strings, first create the JSON node trees and then compare the two trees using assertEquals().
Made these fixes in collaboration with - @same8891, @Rette66, @prathyushreddylpr, @lxb007981
Key changed/added classes in this PR
org.apache.druid.segment.nested.NestedDataColumnSupplierV4Test
org.apache.druid.segment.nested.NestedDataColumnSupplierTest
org.apache.druid.segment.virtual.ExpressionVirtualColumnTest
org.apache.druid.java.util.emitter.core.ParametrizedUriEmitterTest
org.apache.druid.server.router.TieredBrokerHostSelectorTest
org.apache.druid.indexing.overlord.TaskLockboxTest
org.apache.druid.data.input.parquet.WikiParquetReaderTest
org.apache.druid.data.input.parquet.NestedColumnParquetReaderTest
org.apache.druid.data.input.parquet.CompatParquetReaderTest
org.apache.druid.data.input.parquet.FlattenSpecParquetReaderTest
org.apache.druid.data.input.parquet.TimestampsParquetReaderTest
org.apache.druid.discovery.BaseNodeRoleWatcherTest
org.apache.druid.indexing.overlord.supervisor.SupervisorStatusTest
org.apache.druid.metadata.input.SqlEntityTest
This PR has: