// Copyright (c) 2006 Dustin Sallings <dustin@spy.net> package net.spy.concurrent; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import junit.framework.TestCase; /** * Test the synchronization object. */ public class SynchronizationObjectTest extends TestCase { private Timer timer=null; SynchronizationObject<Long> so=null; @Override protected void setUp() { timer=new Timer(true); so=new SynchronizationObject<Long>(null); } @Override protected void tearDown() { timer.cancel(); } private void setToIn(final Long v, long delay) { timer.schedule(new TimerTask() { @Override public void run() { so.set(v); }}, delay); } public void testBasic() throws Exception { so.waitUntilEquals(null, 100, TimeUnit.MILLISECONDS); setToIn(13L, 100); assertNull(so.get()); so.waitUntilEquals(13L, 150, TimeUnit.MILLISECONDS); assertEquals(new Long(13), so.get()); try { so.waitUntilEquals(17L, 50, TimeUnit.MILLISECONDS); fail("Expected timeout waiting for 17, got " + so); } catch(TimeoutException e) { // Expected } } public void testWaitUntilNotNull() throws Exception { setToIn(13L, 100); assertNull(so.get()); so.waitUntilNotNull(150, TimeUnit.MILLISECONDS); } public void testInterrupt() throws Exception { final Thread t=Thread.currentThread(); timer.schedule(new TimerTask() { @Override public void run() { t.interrupt(); } }, 100); try { so.waitUntilEquals(19L, Long.MAX_VALUE-1, TimeUnit.MILLISECONDS); fail("value became 19 and you're still alive."); } catch(InterruptedException e) { // Expected } } public void testMultipleSets() throws Exception { setToIn(7L, 10); setToIn(13L, 15); setToIn(17L, 25); setToIn(19L, 40); so.waitUntilEquals(19L, 50, TimeUnit.MILLISECONDS); } public void testString() { so.set(42L); assertEquals("{SynchronizationObject obj=42}", so.toString()); } // This test fails on my macbook. The predicate is not evaluated for // every change. public void xtestFastSequenceSets() throws Exception { Thread t=new Thread() { @Override public void run() { try { Thread.sleep(500); } catch (InterruptedException e) { throw new RuntimeException(e); } for(int i=1; i<=100; i++) { Long old=so.set(new Long(i)); System.err.println(old + " -> " + i); // Thread.yield(); } } }; t.setDaemon(true); t.start(); SeqPred sp=new SeqPred(100); so.waitUntilTrue(sp, 30, TimeUnit.SECONDS); assertEquals(100, sp.updatesSeen); t.join(); } private class SeqPred implements SynchronizationObject.Predicate<Long> { public int updatesSeen=0; public long lastUpdate=0; private int expectedUpdates=0; public SeqPred(int exp) { super(); expectedUpdates=exp; } public boolean evaluate(Long o) { System.err.println("-- saw " + o); if(updatesSeen == 0) { assertNull("Expected first update to be null, was " + o, o); lastUpdate=0; } else { assertEquals(new Long(lastUpdate + 1), o); lastUpdate=o; } return ++updatesSeen == expectedUpdates; } } }