public void testExpiredData() throws InterruptedException {
    dc.put("k", "v", -1, 6000000);
    Thread.sleep(100);

    InternalCacheEntry entry = dc.get("k");
    assert entry.getClass().equals(transienttype());
    assert entry.getLastUsed() <= System.currentTimeMillis();
    long entryLastUsed = entry.getLastUsed();
    Thread.sleep(100);
    entry = dc.get("k");
    assert entry.getLastUsed() > entryLastUsed;
    dc.put("k", "v", -1, 0);
    dc.purgeExpired();

    dc.put("k", "v", 6000000, -1);
    Thread.sleep(100);
    assert dc.size() == 1;

    entry = dc.get("k");
    assert entry != null : "Entry should not be null!";
    assert entry.getClass().equals(mortaltype())
        : "Expected " + mortaltype() + ", was " + entry.getClass().getSimpleName();
    assert entry.getCreated() <= System.currentTimeMillis();

    dc.put("k", "v", 0, -1);
    Thread.sleep(10);
    assert dc.get("k") == null;
    assert dc.size() == 0;

    dc.put("k", "v", 0, -1);
    Thread.sleep(100);
    assert dc.size() == 1;
    dc.purgeExpired();
    assert dc.size() == 0;
  }
  public void testUpdatingLastUsed() throws Exception {
    long idle = 600000;
    dc.put("k", "v", -1, -1);
    InternalCacheEntry ice = dc.get("k");
    assert ice.getClass().equals(immortaltype());
    assert ice.getExpiryTime() == -1;
    assert ice.getMaxIdle() == -1;
    assert ice.getLifespan() == -1;
    dc.put("k", "v", -1, idle);
    long oldTime = System.currentTimeMillis();
    Thread.sleep(100); // for time calc granularity
    ice = dc.get("k");
    assert ice.getClass().equals(transienttype());
    assert ice.getExpiryTime() > -1;
    assert ice.getLastUsed() > oldTime;
    Thread.sleep(100); // for time calc granularity
    assert ice.getLastUsed() < System.currentTimeMillis();
    assert ice.getMaxIdle() == idle;
    assert ice.getLifespan() == -1;

    oldTime = System.currentTimeMillis();
    Thread.sleep(100); // for time calc granularity
    assert dc.get("k") != null;

    // check that the last used stamp has been updated on a get
    assert ice.getLastUsed() > oldTime;
    Thread.sleep(100); // for time calc granularity
    assert ice.getLastUsed() < System.currentTimeMillis();
  }
  public void testValues() {
    dc.put("k1", "v1", 6000000, -1);
    dc.put("k2", "v2", -1, -1);
    dc.put("k3", "v3", -1, 6000000);
    dc.put("k4", "v4", 6000000, 6000000);

    Set expected = new HashSet();
    expected.add("v1");
    expected.add("v2");
    expected.add("v3");
    expected.add("v4");

    for (Object o : dc.values()) assert expected.remove(o);

    assert expected.isEmpty() : "Did not see keys " + expected + " in iterator!";
  }
  public void testEntrySet() {
    dc.put("k1", "v1", 6000000, -1);
    dc.put("k2", "v2", -1, -1);
    dc.put("k3", "v3", -1, 6000000);
    dc.put("k4", "v4", 6000000, 6000000);

    Set expected = new HashSet();
    expected.add(Immutables.immutableInternalCacheEntry(dc.get("k1")));
    expected.add(Immutables.immutableInternalCacheEntry(dc.get("k2")));
    expected.add(Immutables.immutableInternalCacheEntry(dc.get("k3")));
    expected.add(Immutables.immutableInternalCacheEntry(dc.get("k4")));

    Set actual = new HashSet();
    for (Map.Entry o : dc.entrySet()) actual.add(o);

    assert actual.equals(expected) : "Expected to see keys " + expected + " but only saw " + actual;
  }
  public void testContainerIteration() {
    dc.put("k1", "v", 6000000, -1);
    dc.put("k2", "v", -1, -1);
    dc.put("k3", "v", -1, 6000000);
    dc.put("k4", "v", 6000000, 6000000);

    Set expected = new HashSet();
    expected.add("k1");
    expected.add("k2");
    expected.add("k3");
    expected.add("k4");

    for (InternalCacheEntry ice : dc) {
      assert expected.remove(ice.getKey());
    }

    assert expected.isEmpty() : "Did not see keys " + expected + " in iterator!";
  }
  public void testGetDuringKeySetLoop() {
    for (int i = 0; i < 10; i++) dc.put(i, "value", -1, -1);

    int i = 0;
    for (Object key : dc.keySet()) {
      dc.peek(key); // calling get in this situations will result on corruption the iteration.
      i++;
    }

    assert i == 10 : "Expected the loop to run 10 times, only ran " + i;
  }
  public void testExpirableToImmortalAndBack() {
    String value = "v";
    dc.put("k", value, 6000000, -1);
    assertContainerEntry(mortaltype(), value);

    value = "v2";
    dc.put("k", value, -1, -1);
    assertContainerEntry(immortaltype(), value);

    value = "v3";
    dc.put("k", value, -1, 6000000);
    assertContainerEntry(transienttype(), value);

    value = "v4";
    dc.put("k", value, 6000000, 6000000);
    assertContainerEntry(transientmortaltype(), value);

    value = "v41";
    dc.put("k", value, 6000000, 6000000);
    assertContainerEntry(transientmortaltype(), value);

    value = "v5";
    dc.put("k", value, 6000000, -1);
    assertContainerEntry(mortaltype(), value);
  }