/* * Copyright 2001-2009 Terracotta, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package org.quartz; import static org.quartz.JobBuilder.newJob; import static org.quartz.TriggerBuilder.newTrigger; import java.util.List; import java.util.Properties; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.atomic.AtomicBoolean; import junit.framework.TestCase; import org.quartz.impl.StdSchedulerFactory; /** * Test job interruption */ public class InterruptableJobTest extends TestCase { static final CyclicBarrier sync = new CyclicBarrier(2); public static class TestInterruptableJob implements InterruptableJob { public static final AtomicBoolean interrupted = new AtomicBoolean(false); public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("TestInterruptableJob is executing."); try { sync.await(); // wait for test thread to notice the job is now running } catch (InterruptedException e1) { } catch (BrokenBarrierException e1) { } for(int i=0; i < 200; i++) { try { Thread.sleep(50); // simulate being busy for a while, then checking interrupted flag... } catch (InterruptedException ingore) { } if(TestInterruptableJob.interrupted.get()) { System.out.println("TestInterruptableJob main loop detected interrupt signal."); break; } } try { System.out.println("TestInterruptableJob exiting with interrupted = " + interrupted); sync.await(); } catch (InterruptedException e) { } catch (BrokenBarrierException e) { } } public void interrupt() throws UnableToInterruptJobException { TestInterruptableJob.interrupted.set(true); System.out.println("TestInterruptableJob.interrupt() called."); } } @Override protected void setUp() throws Exception { } public void testJobInterruption() throws Exception { // create a simple scheduler Properties config = new Properties(); config.setProperty("org.quartz.scheduler.instanceName", "InterruptableJobTest_Scheduler"); config.setProperty("org.quartz.scheduler.instanceId", "AUTO"); config.setProperty("org.quartz.threadPool.threadCount", "2"); config.setProperty("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); Scheduler sched = new StdSchedulerFactory(config).getScheduler(); sched.start(); // add a job with a trigger that will fire immediately JobDetail job = newJob() .ofType(TestInterruptableJob.class) .withIdentity("j1") .build(); Trigger trigger = newTrigger() .withIdentity("t1") .forJob(job) .startNow() .build(); sched.scheduleJob(job, trigger); sync.await(); // make sure the job starts running... List<JobExecutionContext> executingJobs = sched.getCurrentlyExecutingJobs(); assertTrue("Number of executing jobs should be 1 ", executingJobs.size() == 1); JobExecutionContext jec = executingJobs.get(0); boolean interruptResult = sched.interrupt(jec.getFireInstanceId()); sync.await(); // wait for the job to terminate assertTrue("Expected successful result from interruption of job ", interruptResult); assertTrue("Expected interrupted flag to be set on job class ", TestInterruptableJob.interrupted.get()); sched.clear(); sched.shutdown(); } }