/* * @(#)ActivationSuite.java 1.3 06/02/23 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package corba.timer ; import java.util.List ; import java.util.Iterator ; import java.util.Map ; import java.util.ArrayList ; import java.util.Set ; import java.util.HashSet ; import org.testng.TestNG ; import org.testng.Assert ; import org.testng.annotations.Test ; import org.testng.annotations.Configuration ; import org.testng.annotations.ExpectedExceptions ; import com.sun.corba.ee.spi.orbutil.newtimer.NamedBase ; import com.sun.corba.ee.spi.orbutil.newtimer.Controllable ; import com.sun.corba.ee.spi.orbutil.newtimer.LogEventHandler ; import com.sun.corba.ee.spi.orbutil.newtimer.Named ; import com.sun.corba.ee.spi.orbutil.newtimer.Statistics ; import com.sun.corba.ee.spi.orbutil.newtimer.StatsEventHandler ; import com.sun.corba.ee.spi.orbutil.newtimer.Timer ; import com.sun.corba.ee.spi.orbutil.newtimer.TimerEvent ; import com.sun.corba.ee.spi.orbutil.newtimer.TimerEventController ; import com.sun.corba.ee.spi.orbutil.newtimer.TimerEventHandler ; import com.sun.corba.ee.spi.orbutil.newtimer.TimerFactory ; import com.sun.corba.ee.spi.orbutil.newtimer.TimerFactoryBuilder ; import com.sun.corba.ee.spi.orbutil.newtimer.TimerGroup ; import com.sun.corba.ee.spi.orbutil.newtimer.NamedBase ; import com.sun.corba.ee.spi.orbutil.generic.Pair ; import static java.util.Arrays.asList ; public class ActivationSuite { // Test set up: //Timer groups: // ga contains gb, gc // gb contains gd // gc contains gd // gd contains ge // ge contains gc // // Timers (in groups) // ga contains t1 // gb contains t2, t3 // gc contains t4 // gd contains t5, t6 // ge contains t7, t8 // // All descriptions are the same as the names // private String tfName = "TFActivation" ; private List<Pair<String,List<String>>> data = asList( mkPair( "ga", "gb", "t1" ), mkPair( "gb", "gd", "t2", "t3" ), mkPair( "gc", "gd", "t4" ), mkPair( "gd", "ge", "t5", "t6" ), mkPair( "ge", "gc", "t7", "t8" ) ) ; private List<String> t1_t8 = asList( "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8" ) ; private List<String> t2_t8 = asList( "t2", "t3", "t4", "t5", "t6", "t7", "t8" ) ; private List<String> t4_t8 = asList( "t4", "t5", "t6", "t7", "t8" ) ; // List<Pair<List<String>,List<String>>> // for each element of list: // first is Controllables to enable, second is expected active set // private List<Pair<List<String>,List<String>>> testData = asList( mkPList( asList( "t1", "t3" ), asList( "t1", "t3" )), mkPList( asList( "ga" ), t1_t8 ), mkPList( asList( "gb" ), t2_t8 ), mkPList( asList( "gc" ), t4_t8 ), mkPList( asList( "gd" ), t4_t8 ), mkPList( asList( "ge" ), t4_t8 ), mkPList( asList( "ge", "t1", "t3" ), asList( "t1", "t3", "t4", "t5", "t6", "t7", "t8" )), mkPList( asList( "gb", "gc" ), t2_t8 )) ; private List<String> evIn = asList( "t1<10", "t1>120", "t2<13", "t3<15", "t1<21", "t1>4", "t3>34", "t2>27", "t1<12", "t1<23", "t1<31", "t1>24", "t1>8", "t1>91" ) ; // Timings: // t1 20 25 55 86 189 // t2 114 // t3 74 // private List<String> evOut = asList( "t1<", "t1>", "t3<", "t1<", "t1>", "t3>", "t1<", "t1<", "t1<", "t1>", "t1>", "t1>" ) ; private String controllerName = "TestController" ; private TimerFactory tf ; private List<Timer> timers ; private List<TimerGroup> timerGroups ; private MyTimerEventHandler h1 ; private MyTimerEventHandler h2 ; private TimerEventController controller ; private Pair<String,List<String>> mkPair( String key, String... values ) { return new Pair<String,List<String>>( key, asList( values ) ) ; } private Pair<List<String>,List<String>> mkPList( List<String> first, List<String> second ) { return new Pair<List<String>,List<String>>( first, second ) ; } private <T> Set<T> asSet( T... args ) { Set<T> result = new HashSet<T>() ; for (T t : args) result.add( t ) ; return result ; } private Controllable makeOrGetControllable( String str ) { if (str.charAt(0)=='g') { // Make a TimerGroup TimerGroup tg = tf.timerGroups().get( str ) ; if (tg == null) { tg = tf.makeTimerGroup( str, str ) ; timerGroups.add( tg ) ; } return tg ; } else if (str.charAt(0)=='t') { // Make a Timer Timer t = tf.timers().get( str ) ; if (t == null) { t = tf.makeTimer( str, str ) ; timers.add( t ) ; } return t ; } else { // error in test data Assert.fail( "Bad data string" ) ; return null ; } } private Controllable getControllable( String str ) { if (str.charAt(0)=='g') { // Get a TimerGroup TimerGroup tg = tf.timerGroups().get( str ) ; Assert.assertTrue( tg != null ) ; Assert.assertEquals( tg.name(), str ) ; return tg ; } else if (str.charAt(0)=='t') { // Get a Timer Timer t = tf.timers().get( str ) ; Assert.assertTrue( t != null ) ; Assert.assertEquals( t.name(), str ) ; return t ; } else { // error in test data Assert.fail( "Bad data string" ) ; return null ; } } @Configuration( beforeTest = true ) public void setUp() { tf = TimerFactoryBuilder.make( tfName, tfName ) ; timers = new ArrayList<Timer>() ; timerGroups = new ArrayList<TimerGroup>() ; timerGroups.add( tf ) ; for (Pair<String,List<String>> elem : data) { String head = elem.first() ; List<String> tail = elem.second() ; Controllable con = makeOrGetControllable( head ) ; Assert.assertTrue( con instanceof TimerGroup ) ; TimerGroup container = TimerGroup.class.cast( con ) ; for (String str : tail) { Controllable c2 = makeOrGetControllable( str ) ; container.add( c2 ) ; } } h1 = new MyTimerEventHandler( "h1" ) ; h2 = new MyTimerEventHandler( "h2" ) ; controller = tf.makeController( controllerName ) ; } private <T extends Controllable> void checkList( List<? extends T> list, Map<String,? extends T> map ) { Assert.assertEquals( list.size(), map.size() ) ; for (T t : list) { Assert.assertEquals( t, map.get( t.name() ) ) ; } } @Test() public void validate() { checkList( timers, tf.timers() ) ; checkList( timerGroups, tf.timerGroups() ) ; for (Pair<String,List<String>> elem : data) { String head = elem.first() ; List<String> tail = elem.second() ; Controllable con = getControllable( head ) ; Assert.assertTrue( con instanceof TimerGroup ) ; TimerGroup container = TimerGroup.class.cast( con ) ; Assert.assertTrue( container.contents().size() == tail.size() ) ; for (String str : tail) { Controllable c2 = getControllable( str ) ; Assert.assertTrue( container.contents().contains( c2 ) ) ; } } } private Set<Controllable> makeControllableSet( List<String> strs ) { Set<Controllable> result = new HashSet<Controllable>() ; for (String str : strs) { Controllable c = getControllable( str ) ; result.add( c ) ; } return result ; } private void enableControllables( Set<Controllable> cons ) { for (Controllable c : cons) c.enable() ; } private void disableAllControllables() { for (Controllable c : tf.contents()) c.disable() ; } @Test() public void testTimerEnable() { for (Pair<List<String>,List<String>> pair : testData) { disableAllControllables() ; Set<Controllable> tds = makeControllableSet( pair.first() ) ; Set<Controllable> ers = makeControllableSet( pair.second() ) ; enableControllables( tds ) ; Set<Timer> ars = tf.activeSet() ; Assert.assertTrue( ers.equals( ars ) ) ; } disableAllControllables() ; } private class MyTimerEventHandler extends NamedBase implements TimerEventHandler { List<TimerEvent> events ; public MyTimerEventHandler( String name ) { super( tf, name ) ; events = new ArrayList<TimerEvent>() ; } public void notify( TimerEvent event ) { events.add( event ) ; } public List<TimerEvent> events() { return events ; } } private Pair<Integer,Pair<Timer,TimerEvent.TimerEventType>> parseEventDescription( String str ) { if (str.length() < 3) Assert.fail() ; String tname = str.substring( 0, 2 ) ; char ch = str.charAt( 2 ) ; String timeStr = str.substring( 3 ) ; int delay = 0; if ((timeStr != null) && (timeStr.length() > 0)) delay = Integer.parseInt( timeStr ) ; Controllable c = getControllable( tname ) ; Assert.assertTrue( c != null && c instanceof Timer ) ; Timer t = Timer.class.cast( c ) ; TimerEvent.TimerEventType etype = null ; if (ch == '<') etype = TimerEvent.TimerEventType.ENTER ; else if (ch == '>') etype = TimerEvent.TimerEventType.EXIT ; else Assert.fail() ; Pair<Timer,TimerEvent.TimerEventType> res1 = new Pair<Timer,TimerEvent.TimerEventType>( t, etype ) ; Pair<Integer,Pair<Timer,TimerEvent.TimerEventType>> result = new Pair<Integer,Pair<Timer,TimerEvent.TimerEventType>>( delay, res1 ) ; return result ; } private void sleep( int time ) { if (time == 0) return ; try { Thread.sleep( time ) ; } catch (Exception exc) { // ignore this } } private void generateEvents( TimerEventController tec, List<String> ed ) { for (String str : ed ) { Pair<Integer,Pair<Timer,TimerEvent.TimerEventType>> p = parseEventDescription( str ) ; int delay = p.first() ; if (p.second().second() == TimerEvent.TimerEventType.ENTER) { tec.enter( p.second().first() ) ; sleep( delay ) ; } else { sleep( delay ) ; tec.exit( p.second().first() ) ; } } } // Test for correct event sequence with non-decreasing time stamps private void validateEvents( List<TimerEvent> elist, List<String> ed ) { Iterator<TimerEvent> teiter = elist.iterator() ; Iterator<String> editer = ed.iterator() ; long time = -1 ; while (teiter.hasNext() && editer.hasNext()) { TimerEvent te = teiter.next() ; String str = editer.next() ; Pair<Integer,Pair<Timer,TimerEvent.TimerEventType>> p = parseEventDescription( str ) ; Assert.assertEquals( te.timer(), p.second().first() ) ; Assert.assertEquals( te.type(), p.second().second() ) ; Assert.assertTrue( te.time() >= time ) ; time = te.time() ; } Assert.assertEquals( teiter.hasNext(), editer.hasNext() ) ; } private void displayStats( String msg, Statistics stats ) { System.out.println( msg ) ; System.out.println( "\tcount = " + stats.count() ) ; System.out.println( "\tmin = " + stats.min() ) ; System.out.println( "\tmax = " + stats.max() ) ; System.out.println( "\taverage = " + stats.average() ) ; System.out.println( "\tstandard deviation = " + stats.standardDeviation() ) ; } private void displayStatsMap( Map<Timer,Statistics> smap ) { for (Timer t : smap.keySet()) { displayStats( "Statistics for Timer " + t, smap.get(t) ) ; } } @Test() public void testStatsHandler() { List<String> elist = asList( "t1", "t2", "t3" ) ; Set<Controllable> cset = makeControllableSet( elist ) ; String shName = "Stats1" ; StatsEventHandler handler = tf.makeStatsEventHandler( shName ) ; controller.register( handler ) ; enableControllables( cset ) ; generateEvents( controller, evIn ) ; Map<Timer,Statistics> smap = handler.stats() ; displayStatsMap( smap ) ; handler.clear() ; smap = handler.stats() ; for (Timer timer : smap.keySet()) { Statistics stats = smap.get( timer ) ; Assert.assertTrue( stats.count() == 0 ) ; } } @Test() public void testTimerController() { List<String> elist = asList( "t1", "t3" ) ; Set<Controllable> cset = makeControllableSet( elist ) ; enableControllables( cset ) ; // Test for correct name and factory of controller Assert.assertEquals( controller.name(), controllerName ) ; Assert.assertEquals( controller.factory(), tf ) ; // Test registration of event handlers controller.register( h1 ) ; controller.register( h2 ) ; Set<TimerEventHandler> etecSet = asSet( (TimerEventHandler)h1, (TimerEventHandler)h2 ) ; Set<TimerEventHandler> atecSet = controller.handlers() ; Assert.assertEquals( etecSet, atecSet ) ; // Test event handler deregistration controller.deregister( h2 ) ; etecSet = asSet( (TimerEventHandler)h1 ) ; atecSet = controller.handlers() ; Assert.assertEquals( etecSet, atecSet ) ; // Test for correct generation of event sequence with // activated timers. controller.register( h2 ) ; generateEvents( controller, evIn ) ; List<TimerEvent> events1 = h1.events() ; List<TimerEvent> events2 = h2.events() ; Assert.assertEquals( events1, events2 ) ; validateEvents( h1.events(), evOut ) ; // clean up controller.deregister( h1 ) ; controller.deregister( h2 ) ; disableAllControllables() ; } @Configuration( afterTest = true ) public void tearDown() { TimerFactoryBuilder.destroy( tf ) ; } }