/**
*
*/
package net.objectlab.kit.collections;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
/**
* @author Benoit Xhenseval
*
*/
public class ReadOnlyExpiringHashSetTest implements SetLoader<String>, TimeProvider {
private int reloadCount;
private long time;
@Before
public void reset() {
reloadCount = 0;
time = System.currentTimeMillis();
}
@Test
public void basicConstructorNoReload() {
final ReadOnlyExpiringHashSetBuilder<String> builder = new ReadOnlyExpiringHashSetBuilder<>(this);
builder.expiryTimeoutMilliseconds(1000);
builder.loadOnFirstAccess(true);
builder.reloadOnExpiry(false);
builder.reloadWhenExpired(false);
builder.timeProvider(this);
builder.id("Greetings");
final ReadOnlyExpiringSet<String> ims = new ReadOnlyExpiringHashSet<>(builder);
assertEquals("Should not call load until called", 0, reloadCount);
assertFalse(ims.isEmpty());
assertEquals(1, ims.size());
assertEquals(1, reloadCount);
assertFalse("diff key", ims.contains("Hi"));
assertTrue("Correct key", ims.contains("Hello"));
time += 100; // simulate 100 ms
// second call
assertFalse(ims.isEmpty());
assertEquals(1, ims.size());
assertEquals(1, reloadCount);
assertFalse("diff key", ims.contains("Hi"));
assertTrue("Correct key", ims.contains("Hello"));
time += 901;
// should be gone
assertTrue(ims.isEmpty());
assertEquals(0, ims.size());
assertEquals(1, reloadCount);
assertFalse("diff key", ims.contains("Hi"));
assertFalse("Correct key", ims.contains("Hello"));
}
@Test
public void basicConstructorWithReloadWhenCalled() {
final ReadOnlyExpiringHashSetBuilder<String> builder = new ReadOnlyExpiringHashSetBuilder<>(this);
builder.expiryTimeoutMilliseconds(1000);
builder.loadOnFirstAccess(true);
builder.reloadOnExpiry(false);
builder.reloadWhenExpired(true);
builder.timeProvider(this);
builder.id("Greetings");
final ReadOnlyExpiringSet<String> ims = new ReadOnlyExpiringHashSet<>(builder);
assertEquals("Should not call load until called", 0, reloadCount);
assertFalse(ims.isEmpty());
assertEquals(1, ims.size());
assertEquals(1, reloadCount);
assertFalse("diff key", ims.contains("Hi"));
assertTrue("Correct key", ims.contains("Hello"));
time += 100; // simulate 100 ms
// second call
assertFalse(ims.isEmpty());
assertEquals(1, ims.size());
assertEquals(1, reloadCount);
assertFalse("diff key", ims.contains("Hi"));
assertTrue("Correct key", ims.contains("Hello"));
time += 901; // simulate 901 ms
assertEquals("Should NOT have reloaded until called!", 1, reloadCount);
// should be gone
assertFalse(ims.isEmpty());
assertEquals("Now it should have called the reload", 2, reloadCount);
assertEquals(1, ims.size());
assertFalse("diff key", ims.contains("Hi"));
assertTrue("Correct key", ims.contains("Hello"));
}
@Test
public void basicConstructorWithImmediateLoadAndWhenExpired() {
final ReadOnlyExpiringHashSetBuilder<String> builder = new ReadOnlyExpiringHashSetBuilder<>(this);
builder.expiryTimeoutMilliseconds(1000);
builder.loadOnFirstAccess(false);
builder.reloadOnExpiry(false);
builder.reloadWhenExpired(true);
builder.timeProvider(this);
builder.id("Greetings");
final ReadOnlyExpiringSet<String> ims = new ReadOnlyExpiringHashSet<>(builder);
assertEquals("Should call load immediately", 1, reloadCount);
assertFalse(ims.isEmpty());
assertEquals(1, reloadCount);
assertEquals(1, ims.size());
assertEquals(1, reloadCount);
assertFalse("diff key", ims.contains("Hi"));
assertTrue("Correct key", ims.contains("Hello"));
time += 100; // simulate 100 ms
// second call
assertFalse(ims.isEmpty());
assertEquals(1, ims.size());
assertEquals(1, reloadCount);
assertFalse("diff key", ims.contains("Hi"));
assertTrue("Correct key", ims.contains("Hello"));
time += 901; // simulate 901 ms
assertEquals("Should NOT have reloaded until called!", 1, reloadCount);
// should be gone
assertFalse(ims.isEmpty());
assertEquals("Now it should have called the reload", 2, reloadCount);
assertEquals(1, ims.size());
assertFalse("diff key", ims.contains("Hi"));
assertTrue("Correct key", ims.contains("Hello"));
}
@Test
public void basicConstructorWithReloadOnExpiry() {
final ReadOnlyExpiringHashSetBuilder<String> builder = new ReadOnlyExpiringHashSetBuilder<>(this);
builder.expiryTimeoutMilliseconds(1000);
builder.loadOnFirstAccess(false);
builder.reloadOnExpiry(true);
builder.reloadWhenExpired(false); // but does not matter
builder.timeProvider(this);
builder.id("Greetings");
final ReadOnlyExpiringSet<String> ims = new ReadOnlyExpiringHashSet<>(builder);
assertEquals("Should have called load immediately", 1, reloadCount);
assertFalse(ims.isEmpty());
assertEquals(1, ims.size());
assertEquals(1, reloadCount);
assertFalse("diff key", ims.contains("Hi"));
assertTrue("Correct key", ims.contains("Hello"));
time += 101;
// second call
assertFalse(ims.isEmpty());
assertEquals(1, ims.size());
assertEquals(1, reloadCount);
assertFalse("diff key", ims.contains("Hi"));
assertTrue("Correct key", ims.contains("Hello"));
time += 901; // simulate 901 ms
try {
Thread.sleep(1500); // ensure that the timer can catch up.
} catch (final InterruptedException e) {
}
assertEquals("Should have reloaded until called!", 2, reloadCount);
// should be gone
assertFalse(ims.isEmpty());
assertEquals("Now it should have called the reload", 2, reloadCount);
assertEquals(1, ims.size());
assertFalse("diff key", ims.contains("Hi"));
assertTrue("Correct key", ims.contains("Hello"));
}
@Override
public void load(final SetBuilder<String> builder) {
assertEquals("Greetings", builder.getId());
builder.add("Hello");
reloadCount++;
}
@Override
public long getCurrentTimeMillis() {
return time;
}
}