This is an automated email from the ASF dual-hosted git repository.
chenhang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/bookkeeper.git
The following commit(s) were added to refs/heads/master by this push:
new f8b9e1886d Use LinkedHashMap instead of HashMap to fix flaky tests due
non-deterministic order (#3551)
f8b9e1886d is described below
commit f8b9e1886d1f6a806150e450cc525933f6c9063f
Author: Aditya Kumbhar <[email protected]>
AuthorDate: Sun Nov 13 19:24:16 2022 -0600
Use LinkedHashMap instead of HashMap to fix flaky tests due
non-deterministic order (#3551)
### Motivation
AuditorReplicasCheckTest has the following tests that are flaky, detected
using the [NonDex](https://github.com/TestingResearchIllinois/NonDex) tool.
testReplicasCheckForLedgersFoundHavingLessThanAQReplicasOfAnEntry()
testReplicasCheckForLedgersFoundHavingLessThanWQReplicasOfAnEntry()
testReplicasCheckForLedgersFoundHavingNoReplica()
testReplicasCheckForLedgersWithEmptySegments()
The tests fail due to non-deterministic ordering in the HashMap
`segmentEnsembles`
The following check fails in the `newEnsembleEntry()` method since it
assumes the ordering of `segmentEnsembles` to be deterministic:
```
checkArgument(ensembles.isEmpty() || firstEntry > ensembles.lastKey(),
"New entry must have a first entry greater than any
existing ensemble key");
```
Fixes #3550
Command to reproduce:
```
mvn -pl bookkeeper-server edu.illinois:nondex-maven-plugin:1.1.2:nondex
-Dtest=org.apache.bookkeeper.replication.AuditorReplicasCheckTest
```
### Changes
Changed the datatype of `segmentEnsembles` from HashMap to
[LinkedHashMap](https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html)
as it has a deterministic iteration order, while
[HashMap](https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html)
does not guarantee the order of its elements.
The tests pass with NonDex after making this change.
---
.../bookkeeper/replication/AuditorReplicasCheckTest.java | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/replication/AuditorReplicasCheckTest.java
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/replication/AuditorReplicasCheckTest.java
index 05c8ab3c2f..290e96644d 100644
---
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/replication/AuditorReplicasCheckTest.java
+++
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/replication/AuditorReplicasCheckTest.java
@@ -28,7 +28,7 @@ import java.net.URI;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
@@ -301,7 +301,7 @@ public class AuditorReplicasCheckTest extends
BookKeeperClusterTestCase {
* BookieHandleNotAvailableException so asyncGetListOfEntriesOfLedger
will
* return BookieHandleNotAvailableException.
*/
- Map<Long, List<BookieId>> segmentEnsembles = new HashMap<Long,
List<BookieId>>();
+ Map<Long, List<BookieId>> segmentEnsembles = new LinkedHashMap<Long,
List<BookieId>>();
segmentEnsembles.put(0L, bookieAddresses);
long ledgerId = 1L;
createClosedLedgerMetadata(lm, ledgerId, ensembleSize,
writeQuorumSize, ackQuorumSize, segmentEnsembles,
@@ -399,7 +399,7 @@ public class AuditorReplicasCheckTest extends
BookKeeperClusterTestCase {
* Empty one for all of the bookies, so this ledger would be counted in
* ledgersFoundHavingNoReplicaOfAnEntry .
*/
- Map<Long, List<BookieId>> segmentEnsembles = new HashMap<Long,
List<BookieId>>();
+ Map<Long, List<BookieId>> segmentEnsembles = new LinkedHashMap<Long,
List<BookieId>>();
segmentEnsembles.put(0L, bookieAddresses);
long ledgerId = 1L;
createClosedLedgerMetadata(lm, ledgerId, ensembleSize,
writeQuorumSize, ackQuorumSize, segmentEnsembles,
@@ -529,7 +529,7 @@ public class AuditorReplicasCheckTest extends
BookKeeperClusterTestCase {
* would be counted towards
* ledgersFoundHavingLessThanAQReplicasOfAnEntry.
*/
- Map<Long, List<BookieId>> segmentEnsembles = new HashMap<Long,
List<BookieId>>();
+ Map<Long, List<BookieId>> segmentEnsembles = new LinkedHashMap<Long,
List<BookieId>>();
int ensembleSize = 4;
int writeQuorumSize = 3;
int ackQuorumSize = 2;
@@ -682,7 +682,7 @@ public class AuditorReplicasCheckTest extends
BookKeeperClusterTestCase {
* for this ledger a copy of entry 3, so this ledger would be counted
* towards ledgersFoundHavingLessThanWQReplicasOfAnEntry.
*/
- Map<Long, List<BookieId>> segmentEnsembles = new HashMap<Long,
List<BookieId>>();
+ Map<Long, List<BookieId>> segmentEnsembles = new LinkedHashMap<Long,
List<BookieId>>();
int ensembleSize = 4;
int writeQuorumSize = 3;
int ackQuorumSize = 2;
@@ -837,7 +837,7 @@ public class AuditorReplicasCheckTest extends
BookKeeperClusterTestCase {
* numLedgersFoundHavingNoReplicaOfAnEntry/LessThanAQReplicasOfAnEntry
* /WQReplicasOfAnEntry.
*/
- Map<Long, List<BookieId>> segmentEnsembles = new HashMap<Long,
List<BookieId>>();
+ Map<Long, List<BookieId>> segmentEnsembles = new LinkedHashMap<Long,
List<BookieId>>();
int ensembleSize = 4;
int writeQuorumSize = 3;
int ackQuorumSize = 2;