/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.waveprotocol.wave.model.util;
import junit.framework.TestCase;
import org.waveprotocol.wave.model.util.FuzzingBackOffScheduler.Builder;
import org.waveprotocol.wave.model.util.FuzzingBackOffScheduler.Cancellable;
import org.waveprotocol.wave.model.util.FuzzingBackOffScheduler.CollectiveScheduler;
import org.waveprotocol.wave.model.util.Scheduler.Command;
/**
* Tests for FuzzingBackOffScheduler
* @author zdwang@google.com (David Wang)
*/
public class FuzzingBackOffSchedulerTest extends TestCase {
private class FakeCancellable implements Cancellable {
boolean cancelled;
@Override
public void cancel() {
cancelled = true;
}
}
private class FakeNativeScheduler implements CollectiveScheduler {
Command command;
FakeCancellable cancellable;
int millisec;
@Override
public Cancellable schedule(Command command, int millisec, int window) {
this.millisec = millisec;
this.command = command;
this.cancellable = new FakeCancellable();
return this.cancellable;
}
}
private Command fakeComamnd;
private FakeNativeScheduler fakeNativeScheduler;
private Scheduler scheduler;
@Override
protected void setUp() {
fakeComamnd = new Command() {
@Override
public void execute() {
}
};
fakeNativeScheduler = new FakeNativeScheduler();
scheduler = new Builder(fakeNativeScheduler)
.setInitialBackOffMs(10)
.setMaxBackOffMs(100)
.setRandomisationFactor(0.5)
.build();
}
public void testSchedule() {
assertNull(fakeNativeScheduler.command);
scheduler.schedule(fakeComamnd);
assertNotNull(fakeNativeScheduler.command);
}
public void testScheduleMultiple() {
// Schedule for the first time.
scheduler.schedule(fakeComamnd);
int lastMillisec = fakeNativeScheduler.millisec;
FakeCancellable lastCancellable = fakeNativeScheduler.cancellable;
assertNotNull(fakeNativeScheduler.command);
assertFalse(fakeNativeScheduler.cancellable.cancelled);
assertTrue(lastMillisec != 0);
// Schedule again and check previous cancelled
for (int i = 0; i < 20; i++) {
scheduler.schedule(fakeComamnd);
assertNotNull(fakeNativeScheduler.command);
assertFalse(fakeNativeScheduler.cancellable.cancelled);
assertNotSame(lastCancellable, fakeNativeScheduler.cancellable);
assertTrue(lastCancellable.cancelled);
lastMillisec = fakeNativeScheduler.millisec;
lastCancellable = fakeNativeScheduler.cancellable;
}
// Check that the time have increased over time
assertTrue(lastMillisec >= 50);
}
public void testScheduleMaxTimes() {
int maxAttempts = 5;
scheduler = new Builder(fakeNativeScheduler)
.setInitialBackOffMs(10)
.setMaxBackOffMs(100)
.setRandomisationFactor(0.5)
.setMaxAttempts(maxAttempts)
.build();
for (int i = 0; i < maxAttempts; i++) {
assertTrue(scheduler.schedule(fakeComamnd));
}
assertFalse(scheduler.schedule(fakeComamnd));
}
public void testReset() {
// schedule something.
scheduler.schedule(fakeComamnd);
FakeCancellable lastTask = fakeNativeScheduler.cancellable;
assertNotNull(fakeNativeScheduler.cancellable);
// reset it and check the previous is cancelled.
scheduler.reset();
assertTrue(lastTask.cancelled);
scheduler.schedule(fakeComamnd);
assertNotNull(fakeNativeScheduler.command);
assertNotSame(lastTask, fakeNativeScheduler.command);
}
}