KickJava   Java API By Example, From Geeks To Geeks.

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


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 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.MBeanServerInvocationHandler JavaDoc;
30 import javax.management.Notification JavaDoc;
31 import javax.management.NotificationListener JavaDoc;
32 import javax.management.ObjectName JavaDoc;
33 import javax.management.timer.TimerMBean JavaDoc;
34
35 import org.jboss.test.jbossmx.compliance.TestCase;
36
37
38 /**
39  * Test fixed-delay/fixed-rate timer execution modes.
40  *
41  * Program a JMX timer to produce TIMES notifications, every PERIOD msces,
42  * with the initial notification after PERIOD msecs.
43  *
44  * Introduce a fixed DELAY (<PERIOD) in the reception of the timer notification
45  * to slow it down. Measure the total time in both fixed-rate & fixed-delay
46  * scenarios and compare it with an expected value +/- an allowed percentage
47  * difference.
48  *
49  * In fixed-rate mode the delay does not affect the periodic execution (because
50  * it's less than the period), so the expected total time is the number of repeatitions
51  * times the period, plus the final delay (because that one doesn't overlap with a period).
52  *
53  * In fixed-delay mode things are simpler. The total execution time is prolonged because
54  * the period doesn't overlap with the execution/delay time, so the total time is
55  * period plus delay times the number of repeatitions.
56  *
57  * The choice of numbers below makes sure that even with a 15% allowed difference
58  * there won't be any overlap in the fixed-rate/fixed-delay execution modes
59  * (i.e. one cannot be confused with the other)
60  *
61  * @author Dimitris.Andreadis@jboss.org
62  * @version $Revision: 46240 $
63  */

64 public class PeriodTestCase extends TestCase
65    implements NotificationListener JavaDoc
66 {
67    private final long PERIOD = 300;
68    private final long DELAY = 200;
69    private final long TIMES = 5;
70    private final long FIXED_RATE_TOTAL = PERIOD * TIMES + DELAY;
71    private final long FIXED_DELAY_TOTAL = (PERIOD + DELAY) * TIMES;
72    private final long ALLOWED_DIFFERENCE = 15;
73    
74    /** The object name of the timer service */
75    private ObjectName JavaDoc timerName;
76
77    /** The MBean server */
78    private MBeanServer JavaDoc server;
79    
80    /** Test start time */
81    private long startTime;
82    
83    /** The received notifications */
84    private ArrayList JavaDoc receivedNotifications = new ArrayList JavaDoc();
85    
86    // Constructor ---------------------------------------------------------------
87

88    public PeriodTestCase(String JavaDoc s)
89    {
90       super(s);
91    }
92
93    // Tests ---------------------------------------------------------------------
94

95    /**
96     * Test the (default) fixed-delay timer execution mode
97     */

98    public void testFixedDelay() throws Exception JavaDoc
99    {
100       try
101       {
102          startTimerService();
103          TimerMBean JavaDoc timer = (TimerMBean JavaDoc)MBeanServerInvocationHandler.newProxyInstance(server, timerName, TimerMBean JavaDoc.class, false);
104
105          // calculate all times from now
106
startTime = System.currentTimeMillis();
107          
108          // This must cause a fixed-delay timer notification production
109
// with TIMES notification produced, spaced at PERIOD msecs, starting in now+PERIOD
110
timer.addNotification("timer.notification", null, null, new Date JavaDoc(startTime + PERIOD), PERIOD, TIMES);
111          
112          long expectedDuration = FIXED_DELAY_TOTAL;
113          waitForNotifications(TIMES, expectedDuration * 2);
114          
115          long testDuration = System.currentTimeMillis() - startTime;
116          checkTimeDifference(expectedDuration, testDuration, ALLOWED_DIFFERENCE);
117       }
118       finally
119       {
120          stopTimerService();
121       }
122    }
123
124    /**
125     * Test the fixed-rate timer execution mode
126     */

127    public void testFixedRate() throws Exception JavaDoc
128    {
129       try
130       {
131          startTimerService();
132          TimerMBean JavaDoc timer = (TimerMBean JavaDoc)MBeanServerInvocationHandler.newProxyInstance(server, timerName, TimerMBean JavaDoc.class, false);
133
134          // calculate all times from now
135
startTime = System.currentTimeMillis();
136          
137          // This must cause a fixed-rate timer notification production
138
// with TIMES notification produced, spaced at PERIOD msecs, starting in now+PERIOD
139
timer.addNotification("timer.notification", null, null, new Date JavaDoc(startTime + PERIOD), PERIOD, TIMES, true);
140          
141          long expectedDuration = FIXED_RATE_TOTAL;
142          waitForNotifications(TIMES, expectedDuration * 2);
143          
144          long testDuration = System.currentTimeMillis() - startTime;
145          checkTimeDifference(expectedDuration, testDuration, ALLOWED_DIFFERENCE);
146       }
147       finally
148       {
149          stopTimerService();
150       }
151    }
152    
153    public void handleNotification(Notification JavaDoc notification, Object JavaDoc handback)
154    {
155       try
156       {
157          long time = notification.getTimeStamp() - startTime;
158          long seqNo = notification.getSequenceNumber();
159          log.debug("#" + seqNo + " (" + time + "ms) - " + notification);
160          
161          // cause an artifical delay
162
Thread.sleep(DELAY);
163       }
164       catch (InterruptedException JavaDoc ignore) {}
165       
166       synchronized (receivedNotifications)
167       {
168         receivedNotifications.add(notification);
169         
170         // Notify test completion
171
if (receivedNotifications.size() >= TIMES)
172            receivedNotifications.notifyAll();
173       }
174    }
175    
176    // Support functions ---------------------------------------------------------
177

178    private void checkTimeDifference(long expected, long actual, long percentage)
179    {
180       long actualDiff = (actual - expected) * 100 / expected;
181       log.debug("Actual time: " + actual + " msec, expected time: " + expected + " msecs");
182       log.debug("Actual difference: " + actualDiff + "%, allowed: +/-" + percentage + "%");
183
184       long diff = Math.abs(expected - actual);
185       long maxDeviation = expected / percentage;
186       
187       if (diff > maxDeviation)
188          fail("Time difference larger than " + percentage + "%");
189    }
190    
191    private void waitForNotifications(long totalExpected, long wait) throws Exception JavaDoc
192    {
193       synchronized (receivedNotifications)
194       {
195          if (receivedNotifications.size() > totalExpected)
196             fail("too many notifications " + receivedNotifications.size());
197       
198          if (receivedNotifications.size() < totalExpected)
199             receivedNotifications.wait(wait);
200       }
201       assertEquals(totalExpected, receivedNotifications.size());
202    }
203    
204    /**
205     * Get an MBeanServer, install the timer service and a notification
206     * listener.
207     */

208    private void startTimerService() throws Exception JavaDoc
209    {
210      server = MBeanServerFactory.createMBeanServer("Timer");
211      timerName = new ObjectName JavaDoc("Timer:type=TimerService");
212      server.createMBean("javax.management.timer.Timer", timerName, new Object JavaDoc[0], new String JavaDoc[0]);
213      server.invoke(timerName, "start", new Object JavaDoc[0], new String JavaDoc[0]);
214      server.addNotificationListener(timerName, this, null, null);
215      receivedNotifications.clear();
216    }
217
218    /**
219     * Remove everything used by this test.
220     */

221    private void stopTimerService()
222    {
223      try
224      {
225        server.invoke(timerName, "removeAllNotifications", new Object JavaDoc[0], new String JavaDoc[0]);
226        server.invoke(timerName, "stop", new Object JavaDoc[0], new String JavaDoc[0]);
227        server.unregisterMBean(timerName);
228        MBeanServerFactory.releaseMBeanServer(server);
229        receivedNotifications.clear();
230      }
231      catch (Exception JavaDoc ignored) {}
232    }
233       
234 }
Popular Tags