package org.couchbase.mock.memcached.errormap;
import junit.framework.TestCase;
import org.couchbase.mock.memcached.MemcachedServer.CommandLogEntry;
import org.couchbase.mock.memcached.protocol.ErrorCode;
import java.util.ArrayList;
import java.util.List;
/**
* Created by mnunberg on 4/13/17.
*/
public class VerifierTest extends TestCase {
public void testConstant() throws Exception {
// Get the spec
ErrorMap mm = ErrorMap.DEFAULT_ERRMAP;
int opcode = ErrorCode.DUMMY_RETRY_CONSTANT.value();
// Fill the log
List<CommandLogEntry> entries = new ArrayList<CommandLogEntry>();
// Fill up the entries with a simple timestamp..
for (int i = 0; i < 10; i++) {
entries.add(new CommandLogEntry(opcode, (long)i));
}
// Verify the spec!
ErrorMapEntry mmEntry = mm.getErrorEntry(opcode);
assertNotNull(mmEntry);
RetrySpec spec = mmEntry.getRetrySpec();
assertFalse(Verifier.verify(entries, spec, opcode));
// Test when we're all according to spec.
entries.clear();
// Represents the first error received..
entries.add(new CommandLogEntry(opcode, 0));
int curTime = spec.getAfter();
while (curTime < spec.getMaxDuration() + spec.getAfter()) {
entries.add(new CommandLogEntry(opcode, curTime));
curTime += spec.getInterval();
}
Verifier.verifyThrow(entries, spec, opcode);
}
public void testLinear() throws Exception {
ErrorMap mm = ErrorMap.DEFAULT_ERRMAP;
int opcode = ErrorCode.DUMMY_RETRY_LINEAR.value();
ErrorMapEntry mmEntry = mm.getErrorEntry(opcode);
assertNotNull(mmEntry);
RetrySpec spec = mmEntry.getRetrySpec();
List<CommandLogEntry> entries = new ArrayList<CommandLogEntry>();
// Verify with an empty command set
assertFalse(Verifier.verify(entries, spec, opcode));
for (int i = 0; i < 10; i++) {
entries.add(new CommandLogEntry(opcode, i));
}
assertFalse(Verifier.verify(entries, spec, opcode));
entries.clear();
// Try to actually do a "correct" retry
entries.add(new CommandLogEntry(opcode, 0));
int curTime = spec.getAfter();
int numAttempts = 0;
while (curTime < spec.getMaxDuration() + spec.getAfter()) {
// System.err.printf("Adding spec at %d\n", curTime);
entries.add(new CommandLogEntry(opcode, curTime));
numAttempts ++;
int incrBy = numAttempts * spec.getInterval();
if (spec.getCeil() > 0) {
incrBy = Math.min(incrBy, spec.getCeil());
}
// System.err.printf("Waiting %d\n", incrBy);
curTime += incrBy;
}
Verifier.verifyThrow(entries, spec, opcode);
}
public void testExponential() throws Exception {
ErrorMap mm = ErrorMap.DEFAULT_ERRMAP;
int opcode = ErrorCode.DUMMY_RETRY_EXPONENTIAL.value();
ErrorMapEntry mmEntry = mm.getErrorEntry(opcode);
assertNotNull(mmEntry);
RetrySpec spec = mmEntry.getRetrySpec();
assertNotNull(spec);
List<CommandLogEntry> entries = new ArrayList<CommandLogEntry>();
// Test with empty list. Should fail
assertFalse(Verifier.verify(entries, spec, opcode));
// Test with multiple entries (without proper waiting). Should fail
for (int i = 0; i < 10; i++) {
entries.add(new CommandLogEntry(opcode, i));
}
assertFalse(Verifier.verify(entries, spec, opcode));
entries.clear();
int numAttempts = 0;
entries.add(new CommandLogEntry(opcode, 0));
int curTime = spec.getAfter();
while (curTime < spec.getAfter() + spec.getMaxDuration()) {
entries.add(new CommandLogEntry(opcode, curTime));
numAttempts++;
int incrBy = (int)Math.pow(spec.getInterval(), numAttempts);
if (spec.getCeil() > 0) {
incrBy = Math.min(spec.getCeil(), incrBy);
}
curTime += incrBy;
}
Verifier.verifyThrow(entries, spec, opcode);
}
}