/* * Copyright 2009 Thomas Bocek * * Licensed 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 net.tomp2p.utils; import java.util.Iterator; import java.util.Map.Entry; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import org.junit.rules.TestWatcher; import org.junit.runner.Description; public class TestConcurrentCacheMap { @Rule public TestRule watcher = new TestWatcher() { protected void starting(Description description) { System.out.println("Starting test: " + description.getMethodName()); } }; @Test public void testCache() throws InterruptedException { ConcurrentCacheMap<String, String> test = new ConcurrentCacheMap<String, String>(1, 1024); test.put("hallo1", "test1"); Thread.sleep(500); test.put("hallo2", "test2"); test.put("hallo3", "test3"); Thread.sleep(600); Assert.assertEquals(2, test.size()); } @Test public void testCache2() throws InterruptedException { ConcurrentCacheMap<String, String> test = new ConcurrentCacheMap<String, String>(1, 1024); test.put("hallo0", "test0"); Thread.sleep(500); for (int i = 1; i < 800; i++) { test.put("hallo" + i, "test" + i); } Thread.sleep(500); Assert.assertEquals(800 - 1, test.size()); } @Test public void testCache3multi() throws InterruptedException { int max = 50; int successTest = 4; int currentSuccess = 0; for (int i = 0; i < max; i++) { if(testCache3()) { currentSuccess++; if(currentSuccess > successTest) { return; } } } } private boolean testCache3() throws InterruptedException { final ConcurrentCacheMap<String, String> test = new ConcurrentCacheMap<String, String>(3, 1024); test.put("hallo0", "test0"); Thread.sleep(1000); final long start = System.currentTimeMillis(); final AtomicBoolean failed = new AtomicBoolean(false); final AtomicInteger integer1 = new AtomicInteger(1); final AtomicInteger integer2 = new AtomicInteger(1); final AtomicLong long1 = new AtomicLong(); final CountDownLatch cdl = new CountDownLatch(799); for (int i = 1; i < 800; i++) { final int ii = i; new Thread(new Runnable() { @Override public void run() { Thread.currentThread().setName("test-cache1 " + ii); integer1.incrementAndGet(); test.put("hallo" + ii, "test" + ii); long seen = System.currentTimeMillis(); if (seen > long1.get()) long1.set(seen); integer2.incrementAndGet(); new Thread(new Runnable() { @Override public void run() { Thread.currentThread().setName("test-cache2 " + ii); String val = test.get("hallo" + ii); if (!("test" + ii).equals(val)) { failed.set(true); } cdl.countDown(); } }).start(); } }).start(); } cdl.await(3, TimeUnit.SECONDS); Assert.assertEquals(false, failed.get()); long waitfor = 2500 - (System.currentTimeMillis() - start); System.out.println("waitfor: " + waitfor); if(waitfor <= 0) { return false; } Thread.sleep(waitfor); //we are sure that we can finish the rest in 500ms System.out.println("TestCache: expected: " + (800 - 1) + ", got: " + test.size() + ", failed: " + failed.get() + " - expired " + test.expiredCounter() + ", inserts: " + integer1 + "/" + integer2 + ", threads: " + Thread.activeCount()); for (Thread t : Thread.getAllStackTraces().keySet()) { System.out.println(t.getName()); } Assert.assertEquals(800 - 1, test.size()); return true; } @Test public void testCache4() throws InterruptedException { String key = "hallo0"; ConcurrentCacheMap<String, String> test = new ConcurrentCacheMap<String, String>(1, 1024); test.put(key, "test0"); Thread.sleep(1100); test.put(key, "test1"); Thread.sleep(200); String val = test.get(key); Assert.assertEquals("test1", val); } @Test public void testCache5() throws InterruptedException { String key = "hallo0"; ConcurrentCacheMap<String, String> test = new ConcurrentCacheMap<String, String>(1, 1024); test.put(key, "test0"); Thread.sleep(1100); test.put(key, "test1"); Thread.sleep(1100); String val = test.get(key); Assert.assertEquals(null, val); } @Test public void testCache6() throws InterruptedException { String key = "hallo0"; ConcurrentCacheMap<String, String> test = new ConcurrentCacheMap<String, String>(1, 1024, false); test.put(key, "test0"); Thread.sleep(500); test.putIfAbsent(key, "test1"); Thread.sleep(800); String val = test.get(key); Assert.assertEquals(null, val); } @Test public void testCache7() throws InterruptedException { String key = "hallo0"; ConcurrentCacheMap<String, String> test = new ConcurrentCacheMap<String, String>(1, 1024, true); test.put(key, "test0"); Thread.sleep(500); test.putIfAbsent(key, "test1"); Thread.sleep(800); String val = test.get(key); // putIfAbsent will refresh test0 Assert.assertEquals("test0", val); } @Test public void testIteratorKey() { String key = "hallo0"; ConcurrentCacheMap<String, String> test = new ConcurrentCacheMap<String, String>(1, 1024, true); test.put(key, "test0"); Iterator<Entry<String, String>> iterator = test.entrySet().iterator(); while(iterator.hasNext()) { iterator.next(); iterator.remove(); } Assert.assertEquals(0, test.size()); } @Test public void testIteratorValue() { String key = "hallo0"; ConcurrentCacheMap<String, String> test = new ConcurrentCacheMap<String, String>(1, 1024, true); test.put(key, "test0"); Iterator<String> iterator = test.values().iterator(); while (iterator.hasNext()) { iterator.next(); try { iterator.remove(); Assert.fail(); } catch (UnsupportedOperationException u) { } } Assert.assertEquals(1, test.size()); } }