KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > test > jbossmx > compliance > timer > BasicTestCase


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.jbossmx.compliance.timer;
23
24 import org.jboss.test.jbossmx.compliance.TestCase;
25
26 import java.util.ArrayList JavaDoc;
27 import java.util.Date JavaDoc;
28
29 import javax.management.MBeanServer JavaDoc;
30 import javax.management.MBeanServerFactory JavaDoc;
31 import javax.management.Notification JavaDoc;
32 import javax.management.NotificationListener JavaDoc;
33 import javax.management.ObjectName JavaDoc;
34 import javax.management.timer.TimerNotification JavaDoc;
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 BasicTestCase
45   extends TestCase
46   implements NotificationListener JavaDoc
47 {
48   // Attributes ----------------------------------------------------------------
49

50   /**
51    * The object name of the timer service
52    */

53   ObjectName JavaDoc timerName;
54
55   /**
56    * The MBean server
57    */

58   MBeanServer JavaDoc server;
59
60   /**
61    * The received notifications
62    */

63   ArrayList JavaDoc receivedNotifications = new ArrayList JavaDoc();
64
65   // Constructor ---------------------------------------------------------------
66

67   public BasicTestCase(String JavaDoc s)
68   {
69     super(s);
70   }
71
72   // Tests ---------------------------------------------------------------------
73

74   /**
75    * Test a single notification works.
76    */

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

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

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

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

205   /**
206    * Get an MBeanServer, install the timer service and a notification
207    * listener.
208    */

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

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

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

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

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

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

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

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

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

376   private long calcTime(long offset)
377   {
378     return System.currentTimeMillis() + offset;
379   }
380 }
381
Popular Tags