/*
* JBoss, Home of Professional Open Source
* Copyright 2009 Red Hat Inc. and/or its affiliates and other
* contributors as indicated by the @author tags. All rights reserved.
* See the copyright.txt in the distribution for a full listing of
* individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.infinispan.container;
import org.infinispan.container.entries.ImmortalCacheEntry;
import org.infinispan.container.entries.InternalCacheEntry;
import org.infinispan.container.entries.MortalCacheEntry;
import org.infinispan.container.entries.TransientCacheEntry;
import org.infinispan.container.entries.TransientMortalCacheEntry;
import org.infinispan.test.AbstractInfinispanTest;
import org.infinispan.util.Immutables;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import static org.testng.AssertJUnit.assertEquals;
@Test(groups = "unit", testName = "container.SimpleDataContainerTest")
public class SimpleDataContainerTest extends AbstractInfinispanTest {
DataContainer dc;
@BeforeMethod
public void setUp() {
dc = createContainer();
}
@AfterMethod
public void tearDown() {
dc = null;
}
protected DataContainer createContainer() {
DefaultDataContainer dc = new DefaultDataContainer(16);
dc.initialize(null, null, new InternalEntryFactoryImpl());
return dc;
}
public void testExpiredData() throws InterruptedException {
dc.put("k", "v", null, -1, 6000000);
Thread.sleep(100);
InternalCacheEntry entry = dc.get("k", null);
assert entry.getClass().equals(transienttype());
assert entry.getLastUsed() <= System.currentTimeMillis();
long entryLastUsed = entry.getLastUsed();
Thread.sleep(100);
entry = dc.get("k", null);
assert entry.getLastUsed() > entryLastUsed;
dc.put("k", "v", null, -1, 0);
dc.purgeExpired();
dc.put("k", "v", null, 6000000, -1);
Thread.sleep(100);
assert dc.size(null) == 1;
entry = dc.get("k", null);
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", null, 0, -1);
Thread.sleep(10);
assert dc.get("k", null) == null;
assert dc.size(null) == 0;
dc.put("k", "v", null, 0, -1);
Thread.sleep(100);
assert dc.size(null) == 1;
dc.purgeExpired();
assert dc.size(null) == 0;
}
public void testResetOfCreationTime() throws Exception {
long now = System.currentTimeMillis();
dc.put("k", "v", null, 1000000, -1);
long created1 = dc.get("k", null).getCreated();
assert created1 >= now;
Thread.sleep(100);
dc.put("k", "v", null, 1000000, -1);
long created2 = dc.get("k", null).getCreated();
assert created2 > created1 : "Expected " + created2 + " to be greater than " + created1;
}
public void testUpdatingLastUsed() throws Exception {
long idle = 600000;
dc.put("k", "v", null, -1, -1);
InternalCacheEntry ice = dc.get("k", null);
assert ice.getClass().equals(immortaltype());
assert ice.getExpiryTime() == -1;
assert ice.getMaxIdle() == -1;
assert ice.getLifespan() == -1;
dc.put("k", "v", null, -1, idle);
long oldTime = System.currentTimeMillis();
Thread.sleep(100); // for time calc granularity
ice = dc.get("k", null);
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) != 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();
}
protected Class<? extends InternalCacheEntry> mortaltype() {
return MortalCacheEntry.class;
}
protected Class<? extends InternalCacheEntry> immortaltype() {
return ImmortalCacheEntry.class;
}
protected Class<? extends InternalCacheEntry> transienttype() {
return TransientCacheEntry.class;
}
protected Class<? extends InternalCacheEntry> transientmortaltype() {
return TransientMortalCacheEntry.class;
}
public void testExpirableToImmortalAndBack() {
String value = "v";
dc.put("k", value, null, 6000000, -1);
assertContainerEntry(mortaltype(), value);
value = "v2";
dc.put("k", value, null, -1, -1);
assertContainerEntry(immortaltype(), value);
value = "v3";
dc.put("k", value, null, -1, 6000000);
assertContainerEntry(transienttype(), value);
value = "v4";
dc.put("k", value, null, 6000000, 6000000);
assertContainerEntry(transientmortaltype(), value);
value = "v41";
dc.put("k", value, null, 6000000, 6000000);
assertContainerEntry(transientmortaltype(), value);
value = "v5";
dc.put("k", value, null, 6000000, -1);
assertContainerEntry(mortaltype(), value);
}
private void assertContainerEntry(Class<? extends InternalCacheEntry> type,
String expectedValue) {
assert dc.containsKey("k", null);
InternalCacheEntry entry = dc.get("k", null);
assertEquals(type, entry.getClass());
assertEquals(expectedValue, entry.getValue());
}
public void testKeySet() {
dc.put("k1", "v", null, 6000000, -1);
dc.put("k2", "v", null, -1, -1);
dc.put("k3", "v", null, -1, 6000000);
dc.put("k4", "v", null, 6000000, 6000000);
Set expected = new HashSet();
expected.add("k1");
expected.add("k2");
expected.add("k3");
expected.add("k4");
for (Object o : dc.keySet(null)) assert expected.remove(o);
assert expected.isEmpty() : "Did not see keys " + expected + " in iterator!";
}
public void testContainerIteration() {
dc.put("k1", "v", null, 6000000, -1);
dc.put("k2", "v", null, -1, -1);
dc.put("k3", "v", null, -1, 6000000);
dc.put("k4", "v", null, 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 testKeys() {
dc.put("k1", "v1", null, 6000000, -1);
dc.put("k2", "v2", null, -1, -1);
dc.put("k3", "v3", null, -1, 6000000);
dc.put("k4", "v4", null, 6000000, 6000000);
Set expected = new HashSet();
expected.add("k1");
expected.add("k2");
expected.add("k3");
expected.add("k4");
for (Object o : dc.keySet(null)) assert expected.remove(o);
assert expected.isEmpty() : "Did not see keys " + expected + " in iterator!";
}
public void testValues() {
dc.put("k1", "v1", null, 6000000, -1);
dc.put("k2", "v2", null, -1, -1);
dc.put("k3", "v3", null, -1, 6000000);
dc.put("k4", "v4", null, 6000000, 6000000);
Set expected = new HashSet();
expected.add("v1");
expected.add("v2");
expected.add("v3");
expected.add("v4");
for (Object o : dc.values(null)) assert expected.remove(o);
assert expected.isEmpty() : "Did not see keys " + expected + " in iterator!";
}
public void testEntrySet() {
dc.put("k1", "v1", null, 6000000, -1);
dc.put("k2", "v2", null, -1, -1);
dc.put("k3", "v3", null, -1, 6000000);
dc.put("k4", "v4", null, 6000000, 6000000);
Set expected = new HashSet();
expected.add(Immutables.immutableInternalCacheEntry(dc.get("k1", null)));
expected.add(Immutables.immutableInternalCacheEntry(dc.get("k2", null)));
expected.add(Immutables.immutableInternalCacheEntry(dc.get("k3", null)));
expected.add(Immutables.immutableInternalCacheEntry(dc.get("k4", null)));
Set actual = new HashSet();
for (Map.Entry o : dc.entrySet(null)) actual.add(o);
assert actual.equals(expected) : "Expected to see keys " + expected + " but only saw " + actual;
}
public void testGetDuringKeySetLoop() {
for (int i = 0; i < 10; i++) dc.put(i, "value", null, -1, -1);
int i = 0;
for (Object key : dc.keySet(null)) {
dc.peek(key, null); // 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;
}
}