1   // 
2   //Copyright (c) 2003, Caltha - Gajda, Krzewski, Mach, Potempski Sp.J. 
3   //All rights reserved. 
4   //   
5   //Redistribution and use in source and binary forms, with or without modification,  
6   //are permitted provided that the following conditions are met: 
7   //   
8   //* Redistributions of source code must retain the above copyright notice,  
9   //this list of conditions and the following disclaimer. 
10  //* Redistributions in binary form must reproduce the above copyright notice,  
11  //this list of conditions and the following disclaimer in the documentation  
12  //and/or other materials provided with the distribution. 
13  //* Neither the name of the Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.  
14  //nor the names of its contributors may be used to endorse or promote products  
15  //derived from this software without specific prior written permission. 
16  // 
17  //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"  
18  //AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED  
19  //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
20  //IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,  
21  //INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  
22  //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
23  //OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
24  //WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)  
25  //ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  
26  //POSSIBILITY OF SUCH DAMAGE. 
27  //
28  
29  package org.objectledge.scheduler;
30  
31  import java.text.SimpleDateFormat;
32  import java.util.Calendar;
33  import java.util.Date;
34  
35  import javax.xml.parsers.DocumentBuilder;
36  import javax.xml.parsers.DocumentBuilderFactory;
37  
38  import org.apache.log4j.LogManager;
39  import org.jcontainer.dna.Configuration;
40  import org.jcontainer.dna.Logger;
41  import org.jcontainer.dna.impl.Log4JLogger;
42  import org.objectledge.context.Context;
43  import org.objectledge.filesystem.FileSystem;
44  import org.objectledge.i18n.I18n;
45  import org.objectledge.i18n.xml.XMLI18n;
46  import org.objectledge.logging.LedgeDOMConfigurator;
47  import org.objectledge.mail.MailSystem;
48  import org.objectledge.scheduler.cron.TokenMgrError;
49  import org.objectledge.threads.ThreadPool;
50  import org.objectledge.utils.LedgeTestCase;
51  import org.objectledge.xml.XMLGrammarCache;
52  import org.objectledge.xml.XMLValidator;
53  import org.picocontainer.MutablePicoContainer;
54  import org.picocontainer.defaults.DefaultPicoContainer;
55  import org.w3c.dom.Document;
56  import org.xml.sax.InputSource;
57  
58  /**
59   * @author <a href="mailto:pablo@caltha.pl">Pawel Potempski</a>
60   *
61   */
62  public class TransientSchedulerTest extends LedgeTestCase
63  {
64      private FileSystem fs = null;
65  
66      private TransientScheduler scheduler;
67  
68      /*
69       * @see TestCase#setUp()
70       */
71      protected void setUp() throws Exception
72      {
73          super.setUp();
74          fs = FileSystem.getStandardFileSystem("src/test/resources");
75          InputSource source = new InputSource(fs.getInputStream(
76              "config/org.objectledge.logging.LoggingConfigurator.xml"));
77          DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
78          Document logConfig = builder.parse(source);
79          LedgeDOMConfigurator configurator = new LedgeDOMConfigurator(fs);
80          configurator.doConfigure(logConfig.getDocumentElement(), LogManager.getLoggerRepository());
81          Logger logger = new Log4JLogger(org.apache.log4j.Logger.getLogger(MailSystem.class));
82          Configuration config = getConfig("config/org.objectledge.threads.ThreadPool.xml");
83          Context context = new Context();
84          ThreadPool threadPool = new ThreadPool(null, context,config, logger);
85          config = getConfig("config/org.objectledge.scheduler.TransientScheduler.xml");
86          XMLValidator validator = new XMLValidator(new XMLGrammarCache());
87          I18n i18n = new XMLI18n(config, logger, fs, validator);
88          
89          ScheduleFactory[] scheduleFactories = new ScheduleFactory[2];
90          scheduleFactories[0] = new AtScheduleFactory();
91          scheduleFactories[1] = new CronScheduleFactory(i18n);
92          MutablePicoContainer container = new DefaultPicoContainer();
93          scheduler = new TransientScheduler(container, config, 
94              logger, threadPool, scheduleFactories);
95          scheduler.start();
96      }
97  
98      public void testCreateJobDescriptor()
99          throws Exception
100     {
101         assertNotNull(scheduler);
102         try
103         {
104             scheduler.createJobDescriptor("foo",null,null);
105             fail("should throw the exception");
106         }
107         catch(UnsupportedOperationException e)
108         {
109             //ok!
110         }        
111     }
112     
113 
114     public void testDeleteJobDescriptor()
115         throws Exception
116     {
117         try
118         {
119             scheduler.deleteJobDescriptor(null);
120             fail("should throw the exception");
121         }
122         catch(UnsupportedOperationException e)
123         {
124             //ok!
125         }
126     }
127 
128     public void testAllowsModifications()
129     {
130         assertEquals(false,scheduler.allowsModifications());
131     }
132 
133     public void testLoadJobs()
134     {
135         // TODO implement or remove
136     }
137 
138     
139     public void testEnable()
140         throws Exception
141     {
142         AbstractJobDescriptor job = scheduler.getJobDescriptor("foo");
143         assertNotNull(job);
144         assertEquals(true, job.isEnabled());
145         scheduler.disable(job);
146         assertEquals(false, job.isEnabled());
147         scheduler.enable(job);
148         assertEquals(true, job.isEnabled());
149     }
150 
151     public void testGetJobDescriptor()
152     {
153         AbstractJobDescriptor job = scheduler.getJobDescriptor("foo");
154         try
155         {
156             job.setArgument("");
157             fail("should throw the exception");
158         }
159         catch(JobModificationException e)
160         {
161             //ok!
162         }
163         try
164         {
165             job.setSchedule(null);
166             fail("should throw the exception");
167         }
168         catch(JobModificationException e)
169         {
170             //ok!
171         }
172         try
173         {
174             job.setAutoClean(true);
175             fail("should throw the exception");
176         }
177         catch(JobModificationException e)
178         {
179             //ok!
180         }
181         try
182         {
183             job.setJobClassName("");
184             fail("should throw the exception");
185         }
186         catch(JobModificationException e)
187         {
188             //ok!
189         }
190         try
191         {
192             job.setRunCountLimit(1);
193             fail("should throw the exception");
194         }
195         catch(JobModificationException e)
196         {
197             //ok!
198         }
199         try
200         {
201             job.setTimeLimit(null,null);
202             fail("should throw the exception");
203         }
204         catch(JobModificationException e)
205         {
206             //ok!
207         }
208         try
209         {
210             job.setReentrant(false);
211             fail("should throw the exception");
212         }
213         catch(JobModificationException e)
214         {
215             //ok!
216         }
217         
218         
219         
220     }
221 
222 
223     public void testGetJobDescriptors()
224     {
225         AbstractJobDescriptor[] jobs = scheduler.getJobDescriptors();
226         assertEquals(2, jobs.length);
227     }
228 
229     public void testGetScheduleTypes()
230     {
231         String[] types = scheduler.getScheduleTypes();
232         assertEquals(2, types.length);
233     }
234 
235     public void testCreateSchedule()
236         throws Exception
237     {
238         Schedule schedule = scheduler.createSchedule("at","");
239         assertNotNull(schedule);
240         assertEquals("",schedule.getConfig());
241         assertEquals("at",schedule.getType());
242         assertNull(null,schedule.getNextRunTime(new Date(), new Date()));
243         try
244         {
245             scheduler.createSchedule("foo","");
246             fail("should throw the exception");
247         }
248         catch(InvalidScheduleException e)
249         {
250             //ok!
251         }
252         schedule = scheduler.createSchedule("cron","* * * * *");
253         Calendar calendar = Calendar.getInstance();
254         calendar.set(Calendar.SECOND,15);
255         calendar.set(Calendar.MILLISECOND,0);
256         Date currentTime = calendar.getTime();
257         
258         calendar.add(Calendar.MINUTE,-2);
259         Date lastRun = calendar.getTime();
260         calendar.add(Calendar.MINUTE, 3);
261         calendar.set(Calendar.SECOND,0);
262         Date expected = calendar.getTime();
263         assertEquals(expected,schedule.getNextRunTime(currentTime, lastRun));
264         assertEquals("cron",schedule.getType());
265         assertEquals("* * * * *",schedule.getConfig());
266         
267         
268         //TODO add some checking
269         schedule = scheduler.createSchedule("cron","* * * jan mon");
270         schedule = scheduler.createSchedule("cron","0-15/60 * * jan mon");
271         schedule = scheduler.createSchedule("cron","@yearly");
272         try
273         {
274             schedule = scheduler.createSchedule("cron","foo bar");
275             fail("should throw the exception");
276         }
277         catch(TokenMgrError e)
278         {
279             //ok!
280         }
281         try
282         {
283             schedule = scheduler.createSchedule("cron","\ufefe");
284             fail("should throw the exception");
285         }
286         catch(TokenMgrError e)
287         {
288             //ok!
289         }
290         
291         
292         schedule = scheduler.createSchedule("at","2003-12-01 10:22");
293         assertNotNull(schedule);
294         calendar.set(Calendar.YEAR, 2000);
295         Date oldDate = calendar.getTime();
296         calendar.set(Calendar.YEAR, 2003);
297         calendar.set(Calendar.MINUTE,22);
298         calendar.set(Calendar.HOUR_OF_DAY,10);
299         calendar.set(Calendar.MONTH,11);
300         calendar.set(Calendar.DAY_OF_MONTH,1);
301         calendar.set(Calendar.SECOND,0);
302         calendar.set(Calendar.MILLISECOND,0);
303         assertEquals(calendar.getTime(),schedule.getNextRunTime(oldDate, oldDate));
304         calendar.set(Calendar.YEAR,2005);
305         oldDate = calendar.getTime();
306         assertNull(schedule.getNextRunTime(oldDate, oldDate));
307         try
308         {
309             schedule.setConfig("foo-bar");
310             fail("should throw the exception");
311         }
312         catch(InvalidScheduleException e)
313         {
314             //ok!
315         }
316     }
317 
318     public void testGetDateFormat()
319     {
320         assertEquals(new SimpleDateFormat(AbstractScheduler.DATE_FORMAT_DEFAULT),
321                        scheduler.getDateFormat());
322     }
323 
324 
325     //////////////////////////////
326 
327     private Configuration getConfig(String name)
328         throws Exception
329     {
330         return getConfig(fs, name);
331     }
332 
333 }