KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > test > compliance > timer > TimerTest


1 /*
2  * JBoss, the OpenSource J2EE webOS
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7
8 package test.compliance.timer;
9
10 import junit.framework.TestCase;
11
12 import java.util.ArrayList;
13 import java.util.Date;
14
15 import javax.management.MBeanServer;
16 import javax.management.MBeanServerFactory;
17 import javax.management.Notification;
18 import javax.management.NotificationListener;
19 import javax.management.ObjectName;
20 import javax.management.timer.TimerNotification;
21
22 /**
23  * Basic timer test.<p>
24  *
25  * The aim of these tests is to check the most common uses of the timer
26  * service.
27  *
28  * @author <a HREF="mailto:Adrian.Brock@HappeningTimes.com">Adrian Brock</a>.
29  */

30 public class TimerTest
31   extends TestCase
32   implements NotificationListener
33 {
34 /**
35  * The period for a timer notification. This needs to be small so the tests * don't take too long. * The wait needs to be long enough to be sure the monitor has enough time * to send the notification and switch the context to the handler. */

36 public static final long PERIOD = 100;
37 public static final long WAIT = 10000;
38 /**
39  * The number of repeats for occurances tests */

40  public static final long REPEATS = 2;
41
42   // Attributes ----------------------------------------------------------------
43

44   /**
45    * The object name of the timer service
46    */

47   ObjectName timerName;
48
49   /**
50    * The MBean server
51    */

52   MBeanServer server;
53
54   /**
55    * The received notifications
56    */

57   ArrayList receivedNotifications = new ArrayList();
58
59   // Constructor ---------------------------------------------------------------
60

61   public TimerTest(String s)
62   {
63     super(s);
64   }
65
66   // Tests ---------------------------------------------------------------------
67

68   /**
69    * Test a single notification works.
70    */

71   public void testSingleNotification()
72      throws Exception
73   {
74     try
75     {
76       startTimerService();
77
78       Integer id = addNotification("test", "hello", "data", calcTime(PERIOD),
79                                    0, 1);
80       expectNotifications(1);
81
82 // TODO
83
// if (getNotificationType(id) != null)
84
// fail("Single notification still registered");
85
}
86     finally
87     {
88       stopTimerService();
89     }
90   }
91
92   /**
93    * Test a repeated notification works.
94    */

95   public void testRepeatedNotification()
96      throws Exception
97   {
98     try
99     {
100       startTimerService();
101       Integer id = addNotification("test", "hello", "data", calcTime(PERIOD),
102                                    PERIOD, REPEATS);
103       expectNotifications(1);
104       expectNotifications(2);
105
106 // TODO
107
// if (getNotificationType(id) != null)
108
// fail("Repeated notification still registered");
109
}
110     finally
111     {
112       stopTimerService();
113     }
114   }
115
116   /**
117    * Test infinite notification works.
118    */

119   public void testInfiniteNotification()
120      throws Exception
121   {
122     try
123     {
124       startTimerService();
125
126       Integer id = addNotification("test", "hello", "data", calcTime(PERIOD),
127                                    PERIOD, 0);
128       expectNotifications(1);
129       expectNotifications(2);
130
131       if (getNotificationType(id) == null)
132         fail("Infinite notification not registered");
133     }
134     finally
135     {
136       stopTimerService();
137     }
138   }
139
140    /**
141     * Test two infinite notification works.
142     */

143    public void testTwoNotificationProducers()
144       throws Exception
145    {
146       try
147       {
148          startTimerService();
149          long lTimeOne = 5 * 1000;
150          long lTimeTwo = 12 * 1000;
151          long lWait = 2 * lTimeTwo;
152          long lStart = calcTime( lTimeOne );
153          Integer lIdOne = addNotification( "test-2", "hello", "data", lStart + lTimeOne,
154                                            lTimeOne, 0);
155          Integer lIdTwo = addNotification( "test-2", "hello", "data", lStart + lTimeTwo,
156                                            lTimeTwo, 0);
157          
158          expectNotifications( 1, lWait );
159          expectNotifications( 2, lWait );
160          // Check time differences which should be around TIME ONE
161
TimerNotification lNotificationOne = (TimerNotification) receivedNotifications.get( 0 );
162          TimerNotification lNotificationTwo = (TimerNotification) receivedNotifications.get( 1 );
163          checkNotificationID( lNotificationOne, lIdOne );
164          checkNotificationID( lNotificationTwo, lIdOne );
165          checkTimeDifference( lNotificationOne, lNotificationTwo, lTimeOne );
166          
167          expectNotifications( 3, lWait );
168          lNotificationOne = lNotificationTwo;
169          lNotificationTwo = (TimerNotification) receivedNotifications.get( 2 );
170          checkNotificationID( lNotificationTwo, lIdTwo );
171          checkTimeDifference( lNotificationOne, lNotificationTwo, ( lTimeTwo - ( 2 * lTimeOne ) ) );
172          
173          expectNotifications( 4, lWait );
174          lNotificationOne = lNotificationTwo;
175          lNotificationTwo = (TimerNotification) receivedNotifications.get( 3 );
176          checkNotificationID( lNotificationTwo, lIdOne );
177          checkTimeDifference( lNotificationOne, lNotificationTwo, ( ( 3 * lTimeOne ) - lTimeTwo ) );
178          
179          expectNotifications( 5, lWait );
180          lNotificationOne = lNotificationTwo;
181          lNotificationTwo = (TimerNotification) receivedNotifications.get( 4 );
182          checkNotificationID( lNotificationTwo, lIdOne );
183          checkTimeDifference( lNotificationOne, lNotificationTwo, lTimeOne );
184          
185          expectNotifications( 6, lWait );
186          lNotificationOne = lNotificationTwo;
187          lNotificationTwo = (TimerNotification) receivedNotifications.get( 5 );
188          checkNotificationID( lNotificationTwo, lIdTwo );
189          checkTimeDifference( lNotificationOne, lNotificationTwo, ( ( 2 * lTimeTwo ) - ( 4 * lTimeOne ) ) );
190       }
191       finally
192       {
193          stopTimerService();
194       }
195    }
196
197   // Support functions ---------------------------------------------------------
198

199   /**
200    * Get an MBeanServer, install the timer service and a notification
201    * listener.
202    */

203   private void startTimerService()
204     throws Exception
205   {
206     server = MBeanServerFactory.createMBeanServer("Timer");
207
208     timerName = new ObjectName("Timer:type=TimerService");
209     server.createMBean("javax.management.timer.Timer", timerName,
210                        new Object[0], new String[0]);
211     server.invoke(timerName, "start", new Object[0], new String[0]);
212
213     receivedNotifications.clear();
214     server.addNotificationListener(timerName, this, null, null);
215   }
216
217   /**
218    * Remove everything used by this test. Cannot report failures because
219    * the test might have failed earlier. All notifications are removed,
220    * the RI hangs otherwise.
221    */

222   private void stopTimerService()
223   {
224     try
225     {
226       server.invoke(timerName, "removeAllNotifications", new Object[0], new String[0]);
227       server.invoke(timerName, "stop", new Object[0], new String[0]);
228       server.unregisterMBean(timerName);
229       MBeanServerFactory.releaseMBeanServer(server);
230     }
231     catch (Exception ignored) {}
232   }
233
234   /**
235    * Handle a notification, just add it to the list
236    *
237    * @param notification the notification received
238    * @param handback not used
239    */

240   public void handleNotification(Notification notification, Object handback)
241   {
242     synchronized (receivedNotifications)
243     {
244       receivedNotifications.add(notification);
245       receivedNotifications.notifyAll();
246     }
247   }
248
249   /**
250    * Wait for the timer notification and see if we have the correct number
251    * hopefully this should synchronize this test with the timer thread.
252    *
253    * @param expected the number of notifications expected
254    * @throws Exception when the notifications are incorrect
255    */

256   public void expectNotifications(int expected)
257     throws Exception
258   {
259      expectNotifications( expected, WAIT );
260   }
261
262   /**
263    * Wait for the timer notification and see if we have the correct number
264    * hopefully this should synchronize this test with the timer thread.
265    *
266    * @param expected the number of notifications expected
267    * @param wait time in milli seconds to wait for the notification
268    * @throws Exception when the notifications are incorrect
269    */

270   public void expectNotifications(int expected, long wait)
271     throws Exception
272   {
273      synchronized (receivedNotifications)
274      {
275        if (receivedNotifications.size() > expected)
276          fail("too many notifications");
277        if (receivedNotifications.size() < expected)
278        {
279          receivedNotifications.wait( wait );
280        }
281        assertEquals(expected, receivedNotifications.size());
282      }
283   }
284
285   /**
286    * Checks if the given Notification ID is the same as the
287    * one of the given Notification
288    *
289    * @param pNotification Notification to be tested
290    * @param pNotificationID Id the Notification should have
291    **/

292    public void checkNotificationID( TimerNotification pNotification, Integer pNotificationID ) {
293       if( pNotification == null ) {
294          fail( "Notification is null" );
295       }
296       if( !pNotification.getNotificationID().equals( pNotificationID ) ) {
297          fail( "Wrong Notification ID received: " + pNotification.getNotificationID() +
298             ", expected: " + pNotificationID );
299       }
300   }
301   
302   /**
303    * Checks if the time between the two Notification is in a
304    * +- 10% limit
305    *
306    * @param pNotificationOne First Notification to be tested
307    * @param pNotificationTwo Second Notification to be tested
308    * @param pTimeDiffernce Expected Time Difference
309    **/

310    public void checkTimeDifference(
311       TimerNotification pNotificationOne,
312       TimerNotification pNotificationTwo,
313       long pTimeDiffernce
314    ) {
315       long lDiff = pNotificationTwo.getTimeStamp() - pNotificationOne.getTimeStamp();
316       if( lDiff < ( pTimeDiffernce - ( pTimeDiffernce / 10 ) ) ||
317          lDiff > ( pTimeDiffernce + ( pTimeDiffernce / 10 ) )
318       ) {
319          fail( "Time between first two notification is too small or too big: " + pTimeDiffernce );
320       }
321    }
322
323   /**
324    * Add a timer notification
325    *
326    * @param type the type of the notification
327    * @param message the message
328    * @param data the user data
329    * @param time the time of the notification
330    * @param period the period of notification
331    * @param occurs the number of occurances
332    * @return the id of the notfication
333    */

334   private Integer addNotification(String type, String message, String data,
335                                   long time, long period, long occurs)
336     throws Exception
337   {
338     return (Integer) server.invoke(timerName, "addNotification",
339       new Object[] { type, message, data, new Date(time), new Long(period),
340                      new Long(occurs) },
341       new String[] { "java.lang.String", "java.lang.String", "java.lang.Object",
342                      "java.util.Date", "long", "long" } );
343   }
344
345   /**
346    * Get the notification type for an id
347    *
348    * @param id the id of the notification
349    * @return the type of the notification
350    */

351   private String getNotificationType(Integer id)
352     throws Exception
353   {
354     // This is called after the last expected notification
355
// The timer thread has notified us, but hasn't had time
356
// to remove the notification, give it chance, before
357
// checking for correct behaviour.
358
Thread.yield();
359     
360     return (String) server.invoke(timerName, "getNotificationType",
361       new Object[] { id },
362       new String[] { "java.lang.Integer" });
363   }
364
365   /**
366    * Calculate the time using an offset from the current time.
367    * @param offset the offset from the current time
368    * @return the calculated time
369    */

370   private long calcTime(long offset)
371   {
372     return System.currentTimeMillis() + offset;
373   }
374 }
375
Popular Tags