KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > test > timer > test > BasicTimerUnitTestCase


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.timer.test;
23
24 import java.rmi.RemoteException JavaDoc;
25 import java.rmi.ServerException JavaDoc;
26 import java.util.Date JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import javax.ejb.EJBHome JavaDoc;
29 import javax.ejb.NoSuchObjectLocalException JavaDoc;
30 import javax.jms.Message JavaDoc;
31 import javax.jms.Queue JavaDoc;
32 import javax.jms.QueueConnection JavaDoc;
33 import javax.jms.QueueConnectionFactory JavaDoc;
34 import javax.jms.QueueReceiver JavaDoc;
35 import javax.jms.QueueSender JavaDoc;
36 import javax.jms.QueueSession JavaDoc;
37 import javax.jms.TextMessage JavaDoc;
38 import javax.naming.InitialContext JavaDoc;
39 import javax.naming.NamingException JavaDoc;
40 import javax.security.auth.login.LoginContext JavaDoc;
41
42 import junit.framework.Test;
43 import junit.framework.TestSuite;
44 import org.jboss.test.JBossTestCase;
45 import org.jboss.test.JBossTestSetup;
46 import org.jboss.test.util.AppCallbackHandler;
47 import org.jboss.test.timer.interfaces.TimerEntity;
48 import org.jboss.test.timer.interfaces.TimerEntityHome;
49 import org.jboss.test.timer.interfaces.TimerSFSB;
50 import org.jboss.test.timer.interfaces.TimerSFSBHome;
51 import org.jboss.test.timer.interfaces.TimerSLSBHome;
52 import org.jboss.test.timer.interfaces.TimerSLSB;
53
54 /**
55  * Simple unit tests for the EJB Timer service
56  */

57 public class BasicTimerUnitTestCase extends JBossTestCase
58 {
59
60    private static final String JavaDoc EJB_TIMER_XAR = "ejb-timer.ear";
61
62    private static final int SHORT_PERIOD = 1 * 1000; // 1s
63
private static final int LONG_PERIOD = 20 * 1000; // 20s
64
private LoginContext JavaDoc lc;
65
66    /**
67     * Setup the test suite.
68     */

69    public static Test suite() throws Exception JavaDoc
70    {
71       TestSuite suite = new TestSuite();
72
73       suite.addTest(new JBossTestSetup(new TestSuite(BasicTimerUnitTestCase.class))
74       {
75          protected void setUp() throws Exception JavaDoc
76          {
77             super.setUp();
78             ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
79             deploy (loader.getResource("messaging/test-destinations-full-service.xml").toString());
80             deploy (EJB_TIMER_XAR);
81          }
82          protected void tearDown() throws Exception JavaDoc
83          {
84             super.tearDown();
85             ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
86             undeploy (EJB_TIMER_XAR);
87             undeploy (loader.getResource("messaging/test-destinations-full-service.xml").toString());
88          }
89       });
90
91       return suite;
92    }
93
94    /**
95     * Constructor for the BasicTimerUnitTest object
96     */

97    public BasicTimerUnitTestCase(String JavaDoc pName)
98    {
99       super(pName);
100    }
101
102    public void tearDown()
103    {
104    }
105
106    /**
107     * Test that a Stafeful Session Bean cannot access a Timer Service
108     *
109     * @throws Exception Unexpected Exception indicating an error
110     */

111    public void testStatefulSessionBeanTimer()
112       throws Exception JavaDoc
113    {
114       TimerSFSBHome lHome = (TimerSFSBHome) getEJBHome(TimerSFSBHome.JNDI_NAME);
115       TimerSFSB lBean = lHome.create();
116       try
117       {
118          lBean.checkTimerService();
119          fail("Stateful Session Bean is not allowed to get a Timer Service");
120       }
121       catch (RemoteException JavaDoc re)
122       {
123          Throwable JavaDoc lCause = re.detail;
124          if (lCause instanceof ServerException JavaDoc)
125          {
126             lCause = ((ServerException JavaDoc) lCause).detail;
127             if (lCause instanceof IllegalStateException JavaDoc)
128             {
129                // This exception is expected -> ignore
130
}
131             else
132             {
133                throw re;
134             }
135          }
136       }
137    }
138
139    /**
140     * Test that a repetitive Stafeless Session Bean Timer
141     *
142     * @throws Exception Unexpected Exception indicating an error
143     */

144    public void testStatelessSessionBeanTimer()
145       throws Exception JavaDoc
146    {
147       TimerSLSBHome home = (TimerSLSBHome) getEJBHome(TimerSLSBHome.JNDI_NAME);
148       TimerSLSB bean = home.create();
149       byte[] handle = bean.startTimer(SHORT_PERIOD);
150       Thread.sleep(12 * SHORT_PERIOD + SHORT_PERIOD);
151       int count = bean.getTimeoutCount(handle);
152       bean.stopTimer(handle);
153       assertTrue("Timeout was expected to be called at least 10 times but was "
154          + "only called: " + count + " times",
155          count >= 10);
156       Thread.sleep(5 * SHORT_PERIOD);
157       int count2 = bean.getTimeoutCount(handle);
158       assertTrue("After the timer was stopped no timeout should happen but "
159          + "it was called " + count2 + " more times",
160          count2 == 0);
161       bean.remove();
162    }
163
164    /**
165     * Test that a repetitive Stateless Session Bean Timer with a retry.
166     * NOTE: This test was added to test JIRA issue JBAS-1926.
167     * Since the same timer mechanism is used (with respects to what this test actualy tests)
168     * with entity and message beans, testing on those would probably be redundant, so a test
169     * is only run on stateless session bean.
170     *
171     *
172     * @throws Exception Unexpected Exception indicating an error
173     */

174    public void testStatelessSessionBeanTimerRetry()
175       throws Exception JavaDoc
176    {
177       log.info("testStatelessSessionBeanTimerRetry(): start");
178       TimerSLSBHome home = (TimerSLSBHome) getEJBHome(TimerSLSBHome.JNDI_NAME);
179       TimerSLSB bean = home.create();
180
181       // We need to make sure that the next timer interval occurs
182
// while the retry timeout is STILL running in order to test JBAS-1926
183
final long retryMs = bean.getRetryTimeoutPeriod();
184       log.info("testStatelessSessionBeanTimerRetry():GOT RETRY TIME:" + retryMs);
185       assertFalse("Failed to get valid retry timeout!", retryMs == -1);
186       final HashMap JavaDoc info = new HashMap JavaDoc();
187       info.put(TimerSLSB.INFO_EXEC_FAIL_COUNT,new Integer JavaDoc(1)); // fail only once
188
// RE: JIRA Issue JBAS-1926
189
// This is the amount of time the task will take to execute
190
// This is intentionlly more than the time of the interval
191
// so that the we can be sure that the interval will fire again
192
// WHILE the retry is still in progress.
193
final int taskTime = SHORT_PERIOD * 2;
194       info.put(TimerSLSB.INFO_TASK_RUNTIME,new Integer JavaDoc(taskTime)); // the time is takes to execute the task
195

196       final byte[] handle = bean.startTimer(SHORT_PERIOD,info);
197       // Wait for 1 SHORT_PERIOD for the first firing
198
// Another retryMs for the amount of time it takes for the retry to happen
199
// and finally the amount of time that it takes to execute the task and 200ms to be safe.
200
Thread.sleep(SHORT_PERIOD + retryMs + taskTime + 200);
201       int count = bean.getTimeoutCount(handle);
202       bean.stopTimer(handle);
203       assertEquals("Timeout was called too many times. Should have been once for the initial" +
204             ", and once for the retry during the time allotted.",2,count);
205
206       bean.remove();
207    }
208    
209
210    /**
211     * Test that a single Stafeless Session Bean Timer
212     *
213     * @throws Exception Unexpected Exception indicating an error
214     */

215    public void testStatelessSessionBeanSingleTimer()
216       throws Exception JavaDoc
217    {
218       TimerSLSBHome home = (TimerSLSBHome) getEJBHome(TimerSLSBHome.JNDI_NAME);
219       TimerSLSB bean = home.create();
220       byte[] handle = bean.startSingleTimer(SHORT_PERIOD);
221       Thread.sleep(5 * SHORT_PERIOD);
222       int lCount = bean.getTimeoutCount(handle);
223       assertTrue("Timeout was expected to be called only once but was called: "
224          + lCount + " times",
225          lCount == 1);
226       try
227       {
228          bean.stopTimer(handle);
229          fail("A single timer should expire after the first event and therefore this "
230             + "has to throw an NoSuchObjectLocalException");
231       }
232       catch (RemoteException JavaDoc re)
233       {
234          Throwable JavaDoc lCause = re.detail;
235          if (lCause instanceof ServerException JavaDoc)
236          {
237             lCause = ((ServerException JavaDoc) lCause).detail;
238             if (lCause instanceof NoSuchObjectLocalException JavaDoc)
239             {
240                // This exception is expected -> ignore
241
}
242             else
243             {
244                throw re;
245             }
246          }
247       }
248
249       // Test for the case where a transaction fails, the time should be retried once
250
// This test assumes the FixedRetryPolicy is left at the default of 200ms.
251
// The "fail-once" data in the timer will be used by the bean to fail the
252
// transaction once, to make sure that it is automatically retried.
253
log.info("testStatelessSessionBeanSingleTimer(): Testing retry on timer.");
254       final HashMap JavaDoc info = new HashMap JavaDoc(1);
255       info.put(TimerSLSB.INFO_EXEC_FAIL_COUNT,new Integer JavaDoc(1));
256       handle = bean.startSingleTimer(SHORT_PERIOD,info);
257       Thread.sleep(5 * SHORT_PERIOD);
258       assertEquals("Timeout was expected to be called twice, once inititially, one once for the retry.",
259                2,bean.getTimeoutCount(handle));
260
261
262    }
263
264    /**
265     * Test that a repetitive Entity Bean Timer
266     *
267     * @throws Exception Unexpected Exception indicating an error
268     */

269    public void testEntityBeanTimer()
270       throws Exception JavaDoc
271    {
272       TimerEntityHome home = (TimerEntityHome) getEJBHome(TimerEntityHome.JNDI_NAME);
273       TimerEntity entity = home.create(new Integer JavaDoc(111));
274       entity.startTimer(SHORT_PERIOD);
275       Thread.sleep(12 * SHORT_PERIOD);
276       entity.stopTimer();
277       int lCount = entity.getTimeoutCount();
278       assertTrue("Timeout was expected to be called at least 10 times but was "
279          + "only called: " + lCount + " times",
280          lCount >= 10);
281       Thread.sleep(5 * SHORT_PERIOD);
282       int lCount2 = entity.getTimeoutCount();
283       assertTrue("After the timer was stopped no timeout should happen but "
284          + "it was called " + (lCount2 - lCount) + " more times",
285          lCount == lCount2);
286       entity.remove();
287    }
288
289    /**
290     * Test that a single Entity Bean Timer
291     *
292     * @throws Exception Unexpected Exception indicating an error
293     */

294    public void testEntityBeanSingleTimer()
295       throws Exception JavaDoc
296    {
297       TimerEntityHome home = (TimerEntityHome) getEJBHome(TimerEntityHome.JNDI_NAME);
298       TimerEntity entity = home.create(new Integer JavaDoc(222));
299       entity.startSingleTimer(SHORT_PERIOD);
300       Thread.sleep(5 * SHORT_PERIOD);
301       int lCount = entity.getTimeoutCount();
302       assertTrue("Timeout was expected to be called only once but was called: "
303          + lCount + " times",
304          lCount == 1);
305       try
306       {
307          entity.stopTimer();
308          fail("A single timer should expire after the first event and therefore this "
309             + "has to throw an NoSuchObjectLocalException");
310       }
311       catch (RemoteException JavaDoc re)
312       {
313          Throwable JavaDoc lCause = re.detail;
314          if (lCause instanceof ServerException JavaDoc)
315          {
316             lCause = ((ServerException JavaDoc) lCause).detail;
317             if (lCause instanceof NoSuchObjectLocalException JavaDoc)
318             {
319                // This exception is expected -> ignore
320
}
321             else
322             {
323                throw re;
324             }
325          }
326       }
327       entity.remove();
328    }
329
330    /** Test an mdb that creates a timer for each onMessage
331     * @throws Exception
332     */

333    public void testMDBTimer() throws Exception JavaDoc
334    {
335       InitialContext JavaDoc ctx = new InitialContext JavaDoc();
336       QueueConnectionFactory JavaDoc factory = (QueueConnectionFactory JavaDoc) ctx.lookup("ConnectionFactory");
337       QueueConnection JavaDoc queConn = factory.createQueueConnection();
338       queConn.start();
339
340       Queue JavaDoc queueA = (Queue JavaDoc) ctx.lookup("queue/A");
341       Queue JavaDoc queueB = (Queue JavaDoc) ctx.lookup("queue/B");
342
343       QueueSession JavaDoc session = queConn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
344       QueueSender JavaDoc sender = session.createSender(queueA);
345       TextMessage JavaDoc message = session.createTextMessage();
346       message.setText("testMDBTimer");
347       message.setIntProperty("UNIQUE_ID", 123456789);
348       message.setJMSReplyTo(queueB);
349       sender.send(message);
350       // Get the initial onMessage ack
351
QueueReceiver JavaDoc receiver = session.createReceiver(queueB);
352       Message JavaDoc reply = receiver.receive(15000);
353       log.info("onMessage reply: " + reply);
354       assertTrue("onMessage reply != null", reply != null);
355       int id = reply.getIntProperty("UNIQUE_ID");
356       assertTrue("onMessage reply.id = 123456789", id == 123456789);
357       // Get the initial timer reply
358
reply = receiver.receive(15000);
359       log.info("ejbTimeout reply: " + reply);
360       assertTrue("ejbTimeout reply != null", reply != null);
361       id = reply.getIntProperty("UNIQUE_ID");
362       assertTrue("onMessage reply.id = 123456789", id == 123456789);
363
364       session.close();
365       queConn.close();
366    }
367
368    /** Test an mdb that creates a timer in its ejbCreate method
369     * @throws Exception
370     */

371    public void testOnCreateMDBTimer() throws Exception JavaDoc
372    {
373       log.info("+++ testOnCreateMDBTimer");
374       InitialContext JavaDoc ctx = new InitialContext JavaDoc();
375       QueueConnectionFactory JavaDoc factory = (QueueConnectionFactory JavaDoc) ctx.lookup("ConnectionFactory");
376       QueueConnection JavaDoc queConn = factory.createQueueConnection();
377       queConn.start();
378
379       Queue JavaDoc queueA = (Queue JavaDoc) ctx.lookup("queue/C");
380       Queue JavaDoc queueB = (Queue JavaDoc) ctx.lookup("queue/D");
381
382       QueueSession JavaDoc session = queConn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
383       QueueSender JavaDoc sender = session.createSender(queueA);
384       TextMessage JavaDoc message = session.createTextMessage();
385       message.setText("testOnCreateMDBTimer");
386       message.setIntProperty("UNIQUE_ID", 123456788);
387       message.setJMSReplyTo(queueB);
388       sender.send(message);
389       // Get the initial onMessage ack
390
QueueReceiver JavaDoc receiver = session.createReceiver(queueB);
391       Message JavaDoc reply = receiver.receive(15000);
392       log.info("onMessage reply: " + reply);
393       assertTrue("onMessage reply != null", reply != null);
394       int id = reply.getIntProperty("UNIQUE_ID");
395       assertTrue("onMessage reply.id = 123456788", id == 123456788);
396
397       // Get the 10 ejbCreate timer replys
398
for(int n = 0; n < 10; n ++)
399       {
400          reply = receiver.receive(15000);
401          log.info("ejbTimeout reply: " + reply);
402          assertTrue("ejbTimeout reply != null", reply != null);
403          id = reply.getIntProperty("UNIQUE_ID");
404          assertTrue("onMessage reply.id = 123456788", id == 123456788);
405          long elapsed = reply.getLongProperty("Elapsed");
406          log.info("Elapsed: "+elapsed);
407       }
408
409       session.close();
410       queConn.close();
411    }
412
413    /**
414     * Test with a repetitive timer the timer interface
415     *
416     * @throws Exception Unexpected Exception indicating an error
417     */

418    public void testTimerImplementation()
419       throws Exception JavaDoc
420    {
421       TimerSLSBHome home = (TimerSLSBHome) getEJBHome(TimerSLSBHome.JNDI_NAME);
422       TimerSLSB bean = home.create();
423       byte[] handle = bean.startTimer(LONG_PERIOD);
424       Date JavaDoc lNextEvent = bean.getNextTimeout(handle);
425       long lUntilNextEvent = lNextEvent.getTime() - new Date JavaDoc().getTime();
426       Thread.sleep(SHORT_PERIOD);
427       long lTimeRemaining = bean.getTimeRemaining(handle);
428       Object JavaDoc info = bean.getInfo(handle);
429       assertTrue("Date of the next event must be greater than 0", lUntilNextEvent > 0);
430       assertTrue("Period until next event must be greater than 0", lTimeRemaining > 0);
431       assertTrue("Period until next event must be smaller than time until next even because it "
432          + "it is called later", lUntilNextEvent > lTimeRemaining);
433       assertTrue("Info("+info+") must be 'TimerSLSBean.startTimer'",
434          "TimerSLSBean.startTimer".equals(info));
435       assertTrue("Must be able to get a handle", handle != null);
436       bean.stopTimer(handle);
437    }
438
439    /**
440     * Test that a session that does not implement TimedObject cannot obtain
441     * the TimerService from its EJBContext
442     *
443     * @throws Exception Unexpected Exception indicating an error
444     */

445    public void testBadStatelessSessionBeanTimer()
446       throws Exception JavaDoc
447    {
448       TimerSLSBHome home = (TimerSLSBHome) getEJBHome("ejb/test/timer/NoTimedObjectBean");
449       TimerSLSB bean = home.create();
450       try
451       {
452          bean.startTimer(SHORT_PERIOD);
453          fail("Was able to call NoTimedObjectBean.startTimer");
454       }
455       catch(RemoteException JavaDoc e)
456       {
457          log.info("Saw exception as expected", e);
458       }
459       bean.remove();
460    }
461
462    private EJBHome JavaDoc getEJBHome(String JavaDoc pJNDIName)
463       throws NamingException JavaDoc
464    {
465       InitialContext JavaDoc lContext = new InitialContext JavaDoc();
466       return (EJBHome JavaDoc) lContext.lookup(pJNDIName);
467    }
468
469    private void login() throws Exception JavaDoc
470    {
471       lc = null;
472       String JavaDoc username = "jduke";
473       char[] password = "theduke".toCharArray();
474       AppCallbackHandler handler = new AppCallbackHandler(username, password);
475       log.debug("Creating LoginContext(ejb-timers)");
476       lc = new LoginContext JavaDoc("ejb-timers", handler);
477       lc.login();
478       log.debug("Created LoginContext, subject="+lc.getSubject());
479    }
480    private void logout() throws Exception JavaDoc
481    {
482       if( lc != null )
483       {
484          lc.logout();
485          lc = null;
486       }
487    }
488 }
489
Popular Tags