KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > test > jmx > compliance > timer > TimerTest


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.test.jmx.compliance.timer;
23
24 import java.util.ArrayList JavaDoc;
25 import java.util.Date JavaDoc;
26
27 import javax.management.MBeanServer JavaDoc;
28 import javax.management.MBeanServerFactory JavaDoc;
29 import javax.management.Notification JavaDoc;
30 import javax.management.NotificationListener JavaDoc;
31 import javax.management.ObjectName JavaDoc;
32 import javax.management.timer.TimerNotification JavaDoc;
33
34 import junit.framework.TestCase;
35
36 /**
37  * Basic timer test.<p>
38  *
39  * The aim of these tests is to check the most common uses of the timer
40  * service.
41  *
42  * @author <a HREF="mailto:Adrian.Brock@HappeningTimes.com">Adrian Brock</a>.
43  */

44 public class TimerTest
45   extends TestCase
46   implements NotificationListener JavaDoc
47 {
48 /**
49  * 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. */

50 public static final long PERIOD = 100;
51 public static final long WAIT = 10000;
52 /**
53  * The number of repeats for occurances tests */

54  public static final long REPEATS = 2;
55
56   // Attributes ----------------------------------------------------------------
57

58   /**
59    * The object name of the timer service
60    */

61   ObjectName JavaDoc timerName;
62
63   /**
64    * The MBean server
65    */

66   MBeanServer JavaDoc server;
67
68   /**
69    * The received notifications
70    */

71   ArrayList JavaDoc receivedNotifications = new ArrayList JavaDoc();
72
73   // Constructor ---------------------------------------------------------------
74

75   public TimerTest(String JavaDoc s)
76   {
77     super(s);
78   }
79
80   // Tests ---------------------------------------------------------------------
81

82   /**
83    * Test a single notification works.
84    */

85   public void testSingleNotification()
86      throws Exception JavaDoc
87   {
88     try
89     {
90       startTimerService();
91
92       addNotification("test", "hello", "data", calcTime(PERIOD),
93                                    0, 1);
94       expectNotifications(1);
95
96 // TODO
97
// if (getNotificationType(id) != null)
98
// fail("Single notification still registered");
99
}
100     finally
101     {
102       stopTimerService();
103     }
104   }
105
106   /**
107    * Test a repeated notification works.
108    */

109   public void testRepeatedNotification()
110      throws Exception JavaDoc
111   {
112     try
113     {
114       startTimerService();
115       addNotification("test", "hello", "data", calcTime(PERIOD),
116                                    PERIOD, REPEATS);
117       expectNotifications(1);
118       expectNotifications(2);
119
120 // TODO
121
// if (getNotificationType(id) != null)
122
// fail("Repeated notification still registered");
123
}
124     finally
125     {
126       stopTimerService();
127     }
128   }
129
130   /**
131    * Test infinite notification works.
132    */

133   public void testInfiniteNotification()
134      throws Exception JavaDoc
135   {
136     try
137     {
138       startTimerService();
139
140       Integer JavaDoc id = addNotification("test", "hello", "data", calcTime(PERIOD),
141                                    PERIOD, 0);
142       expectNotifications(1);
143       expectNotifications(2);
144
145       if (getNotificationType(id) == null)
146         fail("Infinite notification not registered");
147     }
148     finally
149     {
150       stopTimerService();
151     }
152   }
153
154    /**
155     * Test two infinite notification works.
156     */

157    public void testTwoNotificationProducers()
158       throws Exception JavaDoc
159    {
160       try
161       {
162          startTimerService();
163          long lTimeOne = 5 * 1000;
164          long lTimeTwo = 12 * 1000;
165          long lWait = 2 * lTimeTwo;
166          long lStart = calcTime( lTimeOne );
167          Integer JavaDoc lIdOne = addNotification( "test-2", "hello", "data", lStart + lTimeOne,
168                                            lTimeOne, 0);
169          Integer JavaDoc lIdTwo = addNotification( "test-2", "hello", "data", lStart + lTimeTwo,
170                                            lTimeTwo, 0);
171          
172          expectNotifications( 1, lWait );
173          expectNotifications( 2, lWait );
174          // Check time differences which should be around TIME ONE
175
TimerNotification JavaDoc lNotificationOne = (TimerNotification JavaDoc) receivedNotifications.get( 0 );
176          TimerNotification JavaDoc lNotificationTwo = (TimerNotification JavaDoc) receivedNotifications.get( 1 );
177          checkNotificationID( lNotificationOne, lIdOne );
178          checkNotificationID( lNotificationTwo, lIdOne );
179          checkTimeDifference( lNotificationOne, lNotificationTwo, lTimeOne );
180          
181          expectNotifications( 3, lWait );
182          lNotificationOne = lNotificationTwo;
183          lNotificationTwo = (TimerNotification JavaDoc) receivedNotifications.get( 2 );
184          checkNotificationID( lNotificationTwo, lIdTwo );
185          checkTimeDifference( lNotificationOne, lNotificationTwo, ( lTimeTwo - ( 2 * lTimeOne ) ) );
186          
187          expectNotifications( 4, lWait );
188          lNotificationOne = lNotificationTwo;
189          lNotificationTwo = (TimerNotification JavaDoc) receivedNotifications.get( 3 );
190          checkNotificationID( lNotificationTwo, lIdOne );
191          checkTimeDifference( lNotificationOne, lNotificationTwo, ( ( 3 * lTimeOne ) - lTimeTwo ) );
192          
193          expectNotifications( 5, lWait );
194          lNotificationOne = lNotificationTwo;
195          lNotificationTwo = (TimerNotification JavaDoc) receivedNotifications.get( 4 );
196          checkNotificationID( lNotificationTwo, lIdOne );
197          checkTimeDifference( lNotificationOne, lNotificationTwo, lTimeOne );
198          
199          expectNotifications( 6, lWait );
200          lNotificationOne = lNotificationTwo;
201          lNotificationTwo = (TimerNotification JavaDoc) receivedNotifications.get( 5 );
202          checkNotificationID( lNotificationTwo, lIdTwo );
203          checkTimeDifference( lNotificationOne, lNotificationTwo, ( ( 2 * lTimeTwo ) - ( 4 * lTimeOne ) ) );
204       }
205       finally
206       {
207          stopTimerService();
208       }
209    }
210
211   // Support functions ---------------------------------------------------------
212

213   /**
214    * Get an MBeanServer, install the timer service and a notification
215    * listener.
216    */

217   private void startTimerService()
218     throws Exception JavaDoc
219   {
220     server = MBeanServerFactory.createMBeanServer("Timer");
221
222     timerName = new ObjectName JavaDoc("Timer:type=TimerService");
223     server.createMBean("javax.management.timer.Timer", timerName,
224                        new Object JavaDoc[0], new String JavaDoc[0]);
225     server.invoke(timerName, "start", new Object JavaDoc[0], new String JavaDoc[0]);
226
227     receivedNotifications.clear();
228     server.addNotificationListener(timerName, this, null, null);
229   }
230
231   /**
232    * Remove everything used by this test. Cannot report failures because
233    * the test might have failed earlier. All notifications are removed,
234    * the RI hangs otherwise.
235    */

236   private void stopTimerService()
237   {
238     try
239     {
240       server.invoke(timerName, "removeAllNotifications", new Object JavaDoc[0], new String JavaDoc[0]);
241       server.invoke(timerName, "stop", new Object JavaDoc[0], new String JavaDoc[0]);
242       server.unregisterMBean(timerName);
243       MBeanServerFactory.releaseMBeanServer(server);
244     }
245     catch (Exception JavaDoc ignored) {}
246   }
247
248   /**
249    * Handle a notification, just add it to the list
250    *
251    * @param notification the notification received
252    * @param handback not used
253    */

254   public void handleNotification(Notification JavaDoc notification, Object JavaDoc handback)
255   {
256     synchronized (receivedNotifications)
257     {
258       receivedNotifications.add(notification);
259       receivedNotifications.notifyAll();
260     }
261   }
262
263   /**
264    * Wait for the timer notification and see if we have the correct number
265    * hopefully this should synchronize this test with the timer thread.
266    *
267    * @param expected the number of notifications expected
268    * @throws Exception when the notifications are incorrect
269    */

270   public void expectNotifications(int expected)
271     throws Exception JavaDoc
272   {
273      expectNotifications( expected, WAIT );
274   }
275
276   /**
277    * Wait for the timer notification and see if we have the correct number
278    * hopefully this should synchronize this test with the timer thread.
279    *
280    * @param expected the number of notifications expected
281    * @param wait time in milli seconds to wait for the notification
282    * @throws Exception when the notifications are incorrect
283    */

284   public void expectNotifications(int expected, long wait)
285     throws Exception JavaDoc
286   {
287      synchronized (receivedNotifications)
288      {
289        if (receivedNotifications.size() > expected)
290          fail("too many notifications");
291        if (receivedNotifications.size() < expected)
292        {
293          receivedNotifications.wait( wait );
294        }
295        assertEquals(expected, receivedNotifications.size());
296      }
297   }
298
299   /**
300    * Checks if the given Notification ID is the same as the
301    * one of the given Notification
302    *
303    * @param pNotification Notification to be tested
304    * @param pNotificationID Id the Notification should have
305    **/

306    public void checkNotificationID( TimerNotification JavaDoc pNotification, Integer JavaDoc pNotificationID ) {
307       if( pNotification == null ) {
308          fail( "Notification is null" );
309       }
310       if( !pNotification.getNotificationID().equals( pNotificationID ) ) {
311          fail( "Wrong Notification ID received: " + pNotification.getNotificationID() +
312             ", expected: " + pNotificationID );
313       }
314   }
315   
316   /**
317    * Checks if the time between the two Notification is in a
318    * +- 10% limit
319    *
320    * @param pNotificationOne First Notification to be tested
321    * @param pNotificationTwo Second Notification to be tested
322    * @param pTimeDiffernce Expected Time Difference
323    **/

324    public void checkTimeDifference(
325       TimerNotification JavaDoc pNotificationOne,
326       TimerNotification JavaDoc pNotificationTwo,
327       long pTimeDiffernce
328    ) {
329       long lDiff = pNotificationTwo.getTimeStamp() - pNotificationOne.getTimeStamp();
330       if( lDiff < ( pTimeDiffernce - ( pTimeDiffernce / 10 ) ) ||
331          lDiff > ( pTimeDiffernce + ( pTimeDiffernce / 10 ) )
332       ) {
333          fail( "Time between first two notification is too small or too big: " + pTimeDiffernce );
334       }
335    }
336
337   /**
338    * Add a timer notification
339    *
340    * @param type the type of the notification
341    * @param message the message
342    * @param data the user data
343    * @param time the time of the notification
344    * @param period the period of notification
345    * @param occurs the number of occurances
346    * @return the id of the notfication
347    */

348   private Integer JavaDoc addNotification(String JavaDoc type, String JavaDoc message, String JavaDoc data,
349                                   long time, long period, long occurs)
350     throws Exception JavaDoc
351   {
352     return (Integer JavaDoc) server.invoke(timerName, "addNotification",
353       new Object JavaDoc[] { type, message, data, new Date JavaDoc(time), new Long JavaDoc(period),
354                      new Long JavaDoc(occurs) },
355       new String JavaDoc[] { "java.lang.String", "java.lang.String", "java.lang.Object",
356                      "java.util.Date", "long", "long" } );
357   }
358
359   /**
360    * Get the notification type for an id
361    *
362    * @param id the id of the notification
363    * @return the type of the notification
364    */

365   private String JavaDoc getNotificationType(Integer JavaDoc id)
366     throws Exception JavaDoc
367   {
368     // This is called after the last expected notification
369
// The timer thread has notified us, but hasn't had time
370
// to remove the notification, give it chance, before
371
// checking for correct behaviour.
372
Thread.yield();
373     
374     return (String JavaDoc) server.invoke(timerName, "getNotificationType",
375       new Object JavaDoc[] { id },
376       new String JavaDoc[] { "java.lang.Integer" });
377   }
378
379   /**
380    * Calculate the time using an offset from the current time.
381    * @param offset the offset from the current time
382    * @return the calculated time
383    */

384   private long calcTime(long offset)
385   {
386     return System.currentTimeMillis() + offset;
387   }
388 }
389
Popular Tags