You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by gr...@apache.org on 2019/06/03 17:53:44 UTC
[kudu] 01/06: [java] Deflake TestKuduScanner.testDiffScan
This is an automated email from the ASF dual-hosted git repository.
granthenke pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git
commit 072260b6f91989128cb3284b17cefc506dec38a4
Author: Will Berkeley <wd...@gmail.com>
AuthorDate: Sun Jun 2 21:41:09 2019 -0700
[java] Deflake TestKuduScanner.testDiffScan
I noticed a funny failure in TestKuduScanner.testDiffScan:
21:55:41.681 [DEBUG - New I/O worker #13] (AsyncKuduScanner.java:556) Can not open scanner
org.apache.kudu.client.NonRecoverableException: snapshot scan start timestamp is earlier than the ancient history mark. Consider increasing the value of the configuration parameter --tablet_history_max_age_sec. Snapshot timestamp: P: 0 usec, L: 0 Ancient History Mark: P: 1558907741677535 usec, L: 0 Physical time difference: -1558907741.678s
The client logs the request it sent, which indeed has a
'snap_start_timestamp' of 0. This timestamp is supposed to come from
incrementing the propagated timestamp received from the client after
some random inserts and mutations. Fortunately, this test has nice
logging: it logs the operations it did and the timestamp:
21:55:40.874 [INFO - Time-limited test] (TestKuduScanner.java:250) Before: {}
21:55:40.874 [INFO - Time-limited test] (TestKuduScanner.java:255) startHT: 0
'generateMutationOperations' could generate 0 mutations, causing this
test to fail. This requires the random number generator to generate 0 3
times in a row when sampling uniformly from {0, 1, 2, 3, 4}, so the odds
of failure due to this defect in the test were only 1/125. I fixed this
by adjusting the number of initial inserts generated so it is always at
least 1.
I ran the test 1250 times with the fix and saw zero failures. Without
the fix, I saw 9/1250 failures.
Change-Id: Iadb46e5dae71724aa8ff88d04c40ef4eaf1ddd2a
Reviewed-on: http://gerrit.cloudera.org:8080/13495
Tested-by: Will Berkeley <wd...@gmail.com>
Reviewed-by: Alexey Serbin <as...@cloudera.com>
---
.../org/apache/kudu/client/TestKuduScanner.java | 34 +++++++++++++---------
.../java/org/apache/kudu/test/RandomUtils.java | 12 ++++++++
2 files changed, 32 insertions(+), 14 deletions(-)
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduScanner.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduScanner.java
index fcc744f..911f98e 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduScanner.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduScanner.java
@@ -242,10 +242,13 @@ public class TestKuduScanner {
KuduTable table = client.createTable(tableName, schema, getBasicCreateTableOptions());
- // Generate some rows before the start time.
+ // Generate some rows before the start time. Ensure there's at least one insert.
int beforeBounds = 5;
- List<Operation> beforeOps = generateMutationOperations(table, random.nextInt(beforeBounds),
- random.nextInt(beforeBounds), random.nextInt(beforeBounds));
+ int numInserts = RandomUtils.nextIntInRange(random, 1, beforeBounds);
+ int numUpdates = random.nextInt(beforeBounds);
+ int numDeletes = random.nextInt(beforeBounds);
+ List<Operation> beforeOps =
+ generateMutationOperations(table, numInserts, numUpdates, numDeletes);
Map<Integer, ChangeType> before = applyOperations(beforeOps);
LOG.info("Before: {}", before);
@@ -254,13 +257,13 @@ public class TestKuduScanner {
long startHT = client.getLastPropagatedTimestamp() + 1;
LOG.info("startHT: {}", startHT);
- // Generate row mutations.
+ // Generate row mutations. The mutations performed here are what should be seen by the diff scan.
int mutationBounds = 10;
- int numInserts = random.nextInt(mutationBounds);
- int numUpdates = random.nextInt(mutationBounds);
- int numDeletes = random.nextInt(mutationBounds);
+ int expectedNumInserts = random.nextInt(mutationBounds);
+ int expectedNumUpdates = random.nextInt(mutationBounds);
+ int expectedNumDeletes = random.nextInt(mutationBounds);
List<Operation> operations =
- generateMutationOperations(table, numInserts, numUpdates, numDeletes);
+ generateMutationOperations(table, expectedNumInserts, expectedNumUpdates, expectedNumDeletes);
Map<Integer, ChangeType> mutations = applyOperations(operations);
LOG.info("Mutations: {}", mutations);
@@ -269,10 +272,13 @@ public class TestKuduScanner {
long endHT = client.getLastPropagatedTimestamp() + 1;
LOG.info("endHT: {}", endHT);
- // Generate Some Rows after the end time.
+ // Generate some rows after the end time.
int afterBounds = 5;
- List<Operation> afterOps = generateMutationOperations(table, random.nextInt(afterBounds),
- random.nextInt(afterBounds), random.nextInt(afterBounds));
+ numInserts = random.nextInt(afterBounds);
+ numUpdates = random.nextInt(afterBounds);
+ numDeletes = random.nextInt(afterBounds);
+ List<Operation> afterOps =
+ generateMutationOperations(table, numInserts, numUpdates, numDeletes);
Map<Integer, ChangeType> after = applyOperations(afterOps);
LOG.info("After: {}", after);
@@ -328,9 +334,9 @@ public class TestKuduScanner {
resultExtra++;
}
}
- assertEquals(numInserts, resultNumInserts);
- assertEquals(numUpdates, resultNumUpdates);
- assertEquals(numDeletes, resultNumDeletes);
+ assertEquals(expectedNumInserts, resultNumInserts);
+ assertEquals(expectedNumUpdates, resultNumUpdates);
+ assertEquals(expectedNumDeletes, resultNumDeletes);
assertEquals(0, resultExtra);
}
diff --git a/java/kudu-test-utils/src/main/java/org/apache/kudu/test/RandomUtils.java b/java/kudu-test-utils/src/main/java/org/apache/kudu/test/RandomUtils.java
index 0328e15..a6490df 100644
--- a/java/kudu-test-utils/src/main/java/org/apache/kudu/test/RandomUtils.java
+++ b/java/kudu-test-utils/src/main/java/org/apache/kudu/test/RandomUtils.java
@@ -16,6 +16,7 @@
// under the License.
package org.apache.kudu.test;
+import com.google.common.base.Preconditions;
import org.apache.yetus.audience.InterfaceAudience;
import org.apache.yetus.audience.InterfaceStability;
import org.slf4j.Logger;
@@ -46,4 +47,15 @@ public class RandomUtils {
LOG.info("Using random seed: {}", seed);
return new Random(seed);
}
+
+ /*
+ * Return the next pseudorandom integer generated by 'random' in the range [start, end).
+ * 'start' must be strictly less than 'end'.
+ */
+ public static int nextIntInRange(Random random, int start, int end) {
+ Preconditions.checkArgument(
+ start < end,
+ String.format("start must be strictly less than end (%d < %d)", start, end));
+ return start + random.nextInt(end - start);
+ }
}