/************************************************************************** * Copyright (c) 2001 by Acunia N.V. All rights reserved. * * * * This software is copyrighted by and is the sole property of Acunia N.V. * * and its licensors, if any. All rights, title, ownership, or other * * interests in the software remain the property of Acunia N.V. and its * * licensors, if any. * * * * This software may only be used in accordance with the corresponding * * license agreement. Any unauthorized use, duplication, transmission, * * distribution or disclosure of this software is expressly forbidden. * * * * This Copyright notice may not be removed or modified without prior * * written consent of Acunia N.V. * * * * Acunia N.V. reserves the right to modify this software without notice. * * * * Acunia N.V. * * Vanden Tymplestraat 35 info@acunia.com * * 3000 Leuven http://www.acunia.com * * Belgium - EUROPE * **************************************************************************/ package gnu.testlet.wonka.lang.ref.SoftReference; import gnu.testlet.Testlet; import gnu.testlet.TestHarness; import gnu.testlet.wonka.lang.ref.Reference.*; import java.util.*; import java.lang.ref.*; public class AcuniaSoftReferenceTest implements Testlet, GarbageListener { protected TestHarness th; private Runtime rt = Runtime.getRuntime(); private SoftReference sr; public void test (TestHarness harness) { th = harness; th.setclass("java.lang.ref.SoftReference"); //test_SoftReference(); test_get(); test_clear(); test_enqueue(); test_isEnqueued(); test_behaviour(); } /** * implemented. <br> * */ public void test_SoftReference(){ th.checkPoint("SoftReference(java.lang.Object)"); ReferenceQueue rq = new ReferenceQueue(); try { new SoftReference(null,rq); th.fail("should throw a NullPointerException -- 1"); } catch (NullPointerException np){ th.check(true , "correct exception was thrown -- 1"); } th.checkPoint("SoftReference(java.lang.Object,java.lang.ref.ReferenceQueue)"); try { new SoftReference(null,rq); th.fail("should throw a NullPointerException -- 1"); } catch (NullPointerException np){ th.check(true , "correct exception was thrown -- 1"); } try { new SoftReference(new Object(),null); th.fail("should throw a NullPointerException -- 2"); } catch (NullPointerException np){ th.check(true , "correct exception was thrown -- 2"); } } /** * implemented. <br> * */ public void test_get(){ th.checkPoint("get()java.lang.Object"); String msg = "check return value "; sr = new SoftReference(msg , new ReferenceQueue()); th.check(sr.get(), msg, msg+1); sr.clear(); th.check(sr.get(), null, msg+2); ReferenceQueue rq = new ReferenceQueue(); sr = new SoftReference(msg , rq); sr.enqueue(); rq.poll(); th.check(sr.get(), msg, msg+3); } /** * implemented. <br> * * Stress Test * * Objects reachable by Soft references should not be collected until we run low on memory. * However they may not cause OutOfMemoryError */ public void test_clear(){ th.checkPoint("clear()void"); ReferenceQueue rq = new ReferenceQueue(); HashSet hs = new HashSet(1000); // Assuming we have at least 1 MB free before SoftReferences start getting killed makeSoft(hs, rq, 1000000); // Yield CPU to allow queueing to happen try { Thread.sleep(1000); } catch (InterruptedException ie) {} th.check(rq.poll(), null , "no references should be collected"); for(int i=0 ; i < 250 ; i++){ makeSoft(hs, rq, 1000000); } // Yield CPU to allow queueing to happen try { Thread.sleep(1000); } catch (InterruptedException ie) {} Reference ref = rq.poll(); //there must be some references in the queue ... !!! th.check(ref != null, "some of the objects should be collected"); hs.remove(ref); int count=0; while(ref != null){ count++; hs.remove(ref); //th.debug(ref+"-->"+ref.get()); if(ref.get() != null){ th.fail("value was not cleared ..."); } ref = rq.poll(); } th.check(count > 100 , "there should be at least be 100 reference collected (got "+count+")"); /* THESE TEST FAIL ON WONKA HOWEVER it is not really specified it has to be that way. Iterator it = hs.iterator(); while(it.hasNext()){ ref = (Reference)it.next(); //th.debug(ref+"-->"+ref.get()); if(ref.get() == null && rq.poll() == null){ th.fail("value was cleared ..."); } } */ } /** * implemented. <br> * */ public void test_enqueue(){ th.checkPoint("enqueue()boolean"); String msg = "checking return value -- "; int i=1; ReferenceQueue rq = new ReferenceQueue(); sr = new SoftReference(msg, rq); th.check(sr.enqueue(), msg+(i++)); th.check(!sr.enqueue(), msg+(i++)); Reference ref = rq.poll(); th.check(ref, sr , "reference was put into the queue"); if(ref != null){ th.check(ref.get() , msg , "Object was not collected yet"); } th.check(!sr.enqueue(), msg+(i++)); sr.clear(); msg = "special case -- "; i=1; sr = new SoftReference(msg , rq); sr.clear(); th.check(!sr.isEnqueued(), msg+(i++)); th.check(sr.enqueue(), msg+(i++)); th.check(!sr.enqueue(), msg+(i++)); th.check(rq.poll(), sr , "reference was put into the queue"); th.check(!sr.enqueue(), msg+(i++)); msg = "not registred to a queue -- "; i=1; sr = new SoftReference(msg); th.check(!sr.isEnqueued(), msg+(i++)); th.check(!sr.enqueue(), msg+(i++)); th.check(!sr.isEnqueued(), msg+(i++)); } /** * implemented. <br> * */ public void test_isEnqueued(){ th.checkPoint("isEnqueued()boolean"); String msg = "checking return value -- "; int i=1; ReferenceQueue rq = new ReferenceQueue(); sr = new SoftReference(msg , rq); th.check(!sr.isEnqueued(), msg+(i++)); th.check(sr.enqueue(), msg+(i++)); th.check(sr.isEnqueued(), msg+(i++)); th.check(rq.poll(), sr , "reference was put into the queue"); th.check(!sr.isEnqueued(), msg+(i++)); sr.clear(); } /** * implemented. <br> * */ public void test_behaviour(){ th.checkPoint("SoftReference(java.lang.Object,java.lang.ref.ReferenceQueue)"); ReferenceQueue rq = new ReferenceQueue(); Garbage gb = new Garbage(this, null, 1); gb = new Garbage(this, gb, 2); sr = new SoftReference(gb, rq); gb = null; Garbage gb3 = new Garbage(this, null, 3); sr = new SoftReference(gb3, rq); while(!got1 && !got2){ System.gc(); System.runFinalization(); try { Thread.sleep(100); } catch(InterruptedException ie){} } th.check(rq.poll(), null, "SoftReference got collected --> nothing put in the queue"); gb = new Garbage(this, null, 4); got2 = false; new SoftReference(new Garbage(this, gb, 2), rq); while(!got2){ System.gc(); System.runFinalization(); try { Thread.sleep(100); } catch(InterruptedException ie){} } done = true; sr = null; } private boolean got1; private boolean got2; private boolean done; public void reportFinalize(int id){ if (id == 2 && !got2){ got2 = true; th.check(true , "collecting Garbage object 2"); } else if (id == 1 && !got1){ got1 = true; th.check(true , "collecting Garbage object 1"); } else if (!done) { th.fail("collected wrong object (id = "+id+")"); } } private void makeSoft(HashSet hs,ReferenceQueue rq, int size){ hs.add(new SoftReference(new byte[size], rq)); long mem = rt.totalMemory() - rt.freeMemory(); //th.debug("constructed SoftReference Memory used is "+mem); } }