mirror of https://github.com/apache/lucene.git
SOLR-10109: harden up the assertions in SoftAutoCommitTest.testSoftAndHardCommitMaxTimeRapidAdds
This commit is contained in:
parent
19fd95b46c
commit
d8990db302
|
@ -17,6 +17,7 @@
|
|||
package org.apache.solr.update;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import static java.util.concurrent.TimeUnit.NANOSECONDS;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
|
@ -340,74 +341,85 @@ public class SoftAutoCommitTest extends AbstractSolrTestCase {
|
|||
hardTracker.setOpenSearcher(false);
|
||||
|
||||
// try to add 5 docs really fast
|
||||
long fast5start = System.nanoTime();
|
||||
|
||||
final long preFirstNanos = System.nanoTime();
|
||||
for( int i=0;i<5; i++ ) {
|
||||
assertU(adoc("id", ""+500 + i, "subject", "five fast docs"));
|
||||
}
|
||||
long fast5end = System.nanoTime() - TimeUnit.NANOSECONDS.convert(300, TimeUnit.MILLISECONDS); // minus a tad of slop
|
||||
long fast5time = 1 + TimeUnit.MILLISECONDS.convert(fast5end - fast5start, TimeUnit.NANOSECONDS);
|
||||
|
||||
// total time for all 5 adds determines the number of soft to expect
|
||||
long expectedSoft = (long)Math.ceil((double) fast5time / softCommitWaitMillis);
|
||||
long expectedHard = (long)Math.ceil((double) fast5time / hardCommitWaitMillis);
|
||||
final long postLastNanos = System.nanoTime();
|
||||
|
||||
expectedSoft = Math.max(1, expectedSoft);
|
||||
expectedHard = Math.max(1, expectedHard);
|
||||
monitor.assertSaneOffers();
|
||||
|
||||
// note: counting from 1 for multiplication
|
||||
for (int i = 1; i <= expectedSoft; i++) {
|
||||
// Wait for the soft commit with plenty of fudge to survive nasty envs
|
||||
Long soft = monitor.soft.poll(softCommitWaitMillis * 3, MILLISECONDS);
|
||||
if (soft != null || i == 1) {
|
||||
assertNotNull(i + ": soft wasn't fast enough", soft);
|
||||
monitor.assertSaneOffers();
|
||||
|
||||
// have to assume none of the docs were added until
|
||||
// very end of the add window
|
||||
long softMs = TimeUnit.MILLISECONDS.convert(soft - fast5end, TimeUnit.NANOSECONDS);
|
||||
assertTrue(i + ": soft occurred too fast: " +
|
||||
softMs + " < (" + softCommitWaitMillis + " * " + i + ")",
|
||||
softMs >= (softCommitWaitMillis * i));
|
||||
} else {
|
||||
// we may have guessed wrong and there were fewer commits
|
||||
assertNull("Got a soft commit we weren't expecting", monitor.soft.poll(2000, MILLISECONDS));
|
||||
}
|
||||
}
|
||||
|
||||
// note: counting from 1 for multiplication
|
||||
for (int i = 1; i <= expectedHard; i++) {
|
||||
// wait for the hard commit, shouldn't need any fudge given
|
||||
// other actions already taken
|
||||
Long hard = monitor.hard.poll(hardCommitWaitMillis, MILLISECONDS);
|
||||
assertNotNull(i + ": hard wasn't fast enough", hard);
|
||||
monitor.assertSaneOffers();
|
||||
|
||||
// have to assume none of the docs were added until
|
||||
// very end of the add window
|
||||
long hardMs = TimeUnit.MILLISECONDS.convert(hard - fast5end, TimeUnit.NANOSECONDS);
|
||||
assertTrue(i + ": hard occurred too fast: " +
|
||||
hardMs + " < (" + hardCommitWaitMillis + " * " + i + ")",
|
||||
hardMs >= (hardCommitWaitMillis * i));
|
||||
}
|
||||
final long maxTimeMillis = MILLISECONDS.convert(postLastNanos - preFirstNanos, NANOSECONDS);
|
||||
log.info("maxTimeMillis: {}ns - {}ns == {}ms", postLastNanos, preFirstNanos, maxTimeMillis);
|
||||
|
||||
// we are only guessing how many commits we may see, allow one extra of each
|
||||
monitor.soft.poll(softCommitWaitMillis + 200, MILLISECONDS);
|
||||
monitor.hard.poll(hardCommitWaitMillis + 200, MILLISECONDS);
|
||||
|
||||
// clear commits
|
||||
monitor.hard.clear();
|
||||
monitor.soft.clear();
|
||||
// NOTE: explicitly using truncated division of longs to round down
|
||||
// even if evenly divisible, need +1 to account for possible "last" commit triggered by "last" doc
|
||||
final long maxExpectedSoft = 1L + (maxTimeMillis / softCommitWaitMillis);
|
||||
final long maxExpectedHard = 1L + (maxTimeMillis / hardCommitWaitMillis);
|
||||
|
||||
log.info("maxExpectedSoft={}", maxExpectedSoft);
|
||||
log.info("maxExpectedHard={}", maxExpectedHard);
|
||||
|
||||
// do a loop pool over each monitor queue, asserting that:
|
||||
// - we get at least one commit
|
||||
// - we don't get more then the max possible commits expected
|
||||
// - any commit we do get doesn't happen "too fast" relative the previous commit
|
||||
// (or first doc added for the first commit)
|
||||
monitor.assertSaneOffers();
|
||||
assertRapidMultiCommitQueues("softCommit", preFirstNanos, softCommitWaitMillis,
|
||||
maxExpectedSoft, monitor.soft);
|
||||
monitor.assertSaneOffers();
|
||||
assertRapidMultiCommitQueues("hardCommit", preFirstNanos, hardCommitWaitMillis,
|
||||
maxExpectedHard, monitor.hard);
|
||||
|
||||
// now wait a bit...
|
||||
// w/o other action we shouldn't see any additional hard/soft commits
|
||||
|
||||
// wait a bit, w/o other action we shouldn't see any
|
||||
// new hard/soft commits
|
||||
assertNull("Got a hard commit we weren't expecting",
|
||||
monitor.hard.poll(1000, MILLISECONDS));
|
||||
monitor.hard.poll(1000, MILLISECONDS));
|
||||
assertNull("Got a soft commit we weren't expecting",
|
||||
monitor.soft.poll(0, MILLISECONDS));
|
||||
monitor.soft.poll(0, MILLISECONDS));
|
||||
|
||||
monitor.assertSaneOffers();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method
|
||||
* @see #testSoftAndHardCommitMaxTimeRapidAdds
|
||||
*/
|
||||
private static void assertRapidMultiCommitQueues
|
||||
(final String debug, final long startTimestampNanos, final long commitWaitMillis,
|
||||
final long maxNumCommits, final BlockingQueue<Long> queue) throws InterruptedException {
|
||||
|
||||
assert 0 < maxNumCommits;
|
||||
|
||||
// do all our math/comparisons in Nanos...
|
||||
final long commitWaitNanos = NANOSECONDS.convert(commitWaitMillis, MILLISECONDS);
|
||||
|
||||
// these will be modified in each iteration of our assertion loop
|
||||
long prevTimestampNanos = startTimestampNanos;
|
||||
int count = 1;
|
||||
Long commitNanos = queue.poll(commitWaitMillis * 3, MILLISECONDS);
|
||||
assertNotNull(debug + ": did not find a single commit", commitNanos);
|
||||
|
||||
while (null != commitNanos) {
|
||||
if (commitNanos < prevTimestampNanos + commitWaitMillis) {
|
||||
fail(debug + ": commit#" + count + " has TS too low relative to previous TS & commitWait: " +
|
||||
"commitNanos=" + commitNanos + ", prevTimestampNanos=" + prevTimestampNanos +
|
||||
", commitWaitMillis=" + commitWaitMillis);
|
||||
}
|
||||
if (maxNumCommits < count) {
|
||||
fail(debug + ": commit#" + count + " w/ commitNanos=" + commitNanos +
|
||||
", but maxNumCommits=" +maxNumCommits);
|
||||
}
|
||||
|
||||
prevTimestampNanos = commitNanos;
|
||||
count++;
|
||||
commitNanos = queue.poll(commitWaitMillis * 3, MILLISECONDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MockEventListener implements SolrEventListener {
|
||||
|
|
Loading…
Reference in New Issue