diff --git a/source/test-java/org/alfresco/Repository01TestSuite.java b/source/test-java/org/alfresco/Repository01TestSuite.java
index 7e4cb39167..837eb2c951 100644
--- a/source/test-java/org/alfresco/Repository01TestSuite.java
+++ b/source/test-java/org/alfresco/Repository01TestSuite.java
@@ -430,11 +430,12 @@ public class Repository01TestSuite extends TestSuite
static void tests63(TestSuite suite) // tests="187" time="364.334"
{
suite.addTest(new JUnit4TestAdapter(org.alfresco.util.schemacomp.DbToXMLTest.class));
- suite.addTest(new JUnit4TestAdapter(org.alfresco.util.schemacomp.ExportDbTest.class));
+ suite.addTest(new JUnit4TestAdapter(org.alfresco.util.schemacomp.ExportDbTest.class));
suite.addTest(new JUnit4TestAdapter(org.alfresco.util.schemacomp.SchemaReferenceFileTest.class));
suite.addTest(new JUnit4TestAdapter(org.alfresco.util.test.junitrules.AlfrescoPersonTest.class));
suite.addTest(new JUnit4TestAdapter(org.alfresco.util.test.junitrules.ApplicationContextInitTest.class));
suite.addTest(new JUnit4TestAdapter(org.alfresco.util.test.junitrules.TemporaryNodesTest.class));
suite.addTest(new JUnit4TestAdapter(org.alfresco.util.test.junitrules.TemporarySitesTest.class));
+ suite.addTest(new JUnit4TestAdapter(org.alfresco.util.CronTriggerBeanTest.class));
}
}
diff --git a/source/test-java/org/alfresco/util/CronTriggerBeanSystemTest.java b/source/test-java/org/alfresco/util/CronTriggerBeanSystemTest.java
new file mode 100644
index 0000000000..760b62f484
--- /dev/null
+++ b/source/test-java/org/alfresco/util/CronTriggerBeanSystemTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2014 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+
+package org.alfresco.util;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.*;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+/**
+ * This class tests that the CronTriggerBean correctly delays jobs when
+ * specified.
+ *
+ * @author Ahmed Owian
+ */
+public class CronTriggerBeanSystemTest
+{
+ private ClassPathXmlApplicationContext context;
+
+ @Before
+ public void setUp() throws Exception
+ {
+ this.context = (ClassPathXmlApplicationContext) ApplicationContextHelper
+ .getApplicationContext();
+ }
+
+ /**
+ * All CronTriggerBean classes should be configured with a delay
+ * to allow the server to start before the jobs run.
+ */
+ @Test
+ public void testAllCronTriggerBeansHaveDelay()
+ {
+ Map beans = this.context
+ .getBeansOfType(org.alfresco.util.CronTriggerBean.class);
+ assertFalse(beans.isEmpty());
+ List undelayedJobs = new ArrayList<>();
+
+ for (Map.Entry entry : beans.entrySet())
+ {
+ CronTriggerBean bean = entry.getValue();
+ if (bean.getStartDelay() == 0)
+ {
+ undelayedJobs.add(entry.getKey());
+ }
+ }
+
+ assertTrue("Undelayed CronTriggerBeans: " + undelayedJobs, undelayedJobs.isEmpty());
+ }
+}
diff --git a/source/test-java/org/alfresco/util/CronTriggerBeanTest.java b/source/test-java/org/alfresco/util/CronTriggerBeanTest.java
index 998720c7f0..eb9b0ea322 100644
--- a/source/test-java/org/alfresco/util/CronTriggerBeanTest.java
+++ b/source/test-java/org/alfresco/util/CronTriggerBeanTest.java
@@ -1,3 +1,21 @@
+/*
+ * Copyright (C) 2014 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
package org.alfresco.util;
import static org.junit.Assert.*;
@@ -16,139 +34,183 @@ import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
-public class CronTriggerBeanTest {
- // One second - an arbitrarily small amount of time to allow for the scheduler to start the jobs
- final long PRECISION_LEEWAY = 1000L;
+
+/**
+ * This class tests that the CronTriggerBean correctly delays jobs when specified.
+ * @author Ahmed Owian
+ */
+public class CronTriggerBeanTest
+{
+ // One second - an arbitrarily small amount of time to allow for the
+ // scheduler to start the jobs
+ final long PRECISION_LEEWAY = 1000L;
+
final long INTERVAL = 1000L;// One run every second
- private ClassPathXmlApplicationContext context;
- private Scheduler scheduler;
- private static Map> dummyJobRuns;
- private static Object lockToken = new Object();
+ private ClassPathXmlApplicationContext context;
- @Before
- public void setUp() throws Exception {
- dummyJobRuns = new HashMap>();
- this.context = null;
- this.scheduler = null;
- }
+ private Scheduler scheduler;
- @After
- public void tearDown() throws Exception {
- try {
- this.scheduler.shutdown();
- } catch (Exception e) {
- // do nothing
- }
-
- try {
- context.close();
- } catch (Exception e) {
- // do nothing
- }
- }
+ private static Map> dummyJobRuns;
- @Test
- public void testCodedCronTriggerBean() throws Exception {
- final String JOB_NAME = "codedCronJob";
- List jobRuns = this.getRunList(JOB_NAME);
- assertEquals(0, jobRuns.size());
- scheduler = StdSchedulerFactory.getDefaultScheduler();
- scheduler.start();
- CronTriggerBean ctBean = new CronTriggerBean();
- ctBean.setBeanName("Dummy");
- ctBean.setCronExpression("0/1 * * * * ? *");
- ctBean.setEnabled(true);
- JobDetail jobDetail = new JobDetail(JOB_NAME, "DefaultGroup", DummyJob.class);
- ctBean.setJobDetail(jobDetail);
- ctBean.setScheduler(scheduler);
- ctBean.afterPropertiesSet();
+ private static Object lockToken = new Object();
- assertJobRunsAfterInterval(jobRuns);
- scheduler.shutdown();
- this.assertJobStopsAfterShutdown(jobRuns);
- }
+ @Before
+ public void setUp() throws Exception
+ {
+ dummyJobRuns = new HashMap>();
+ this.context = null;
+ this.scheduler = null;
+ }
+ @After
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ this.scheduler.shutdown();
+ }
+ catch (Exception e)
+ {
+ // do nothing
+ }
+
+ try
+ {
+ context.close();
+ }
+ catch (Exception e)
+ {
+ // do nothing
+ }
+ }
+
+ /**
+ * Ensures that jobs that are coded without a delay run without delay.
+ * @throws Exception
+ */
@Test
- public void testConfiguredCronTriggerBean() throws BeansException, Exception {
+ public void testCodedCronTriggerBean() throws Exception
+ {
+ final String JOB_NAME = "codedCronJob";
+ List jobRuns = this.getRunList(JOB_NAME);
+ assertEquals(0, jobRuns.size());
+ scheduler = StdSchedulerFactory.getDefaultScheduler();
+ scheduler.start();
+ CronTriggerBean ctBean = new CronTriggerBean();
+ ctBean.setBeanName("Dummy");
+ ctBean.setCronExpression("0/1 * * * * ? *");
+ ctBean.setEnabled(true);
+ JobDetail jobDetail = new JobDetail(JOB_NAME, "DefaultGroup", DummyJob.class);
+ ctBean.setJobDetail(jobDetail);
+ ctBean.setScheduler(scheduler);
+ ctBean.afterPropertiesSet();
+
+ assertJobRunsAfterInterval(jobRuns);
+ scheduler.shutdown();
+ this.assertJobStopsAfterShutdown(jobRuns);
+ }
+
+ /**
+ * Ensures that jobs that are configured without a delay run without delay.
+ * @throws BeansException
+ * @throws Exception
+ */
+ @Test
+ public void testConfiguredCronTriggerBean() throws BeansException, Exception
+ {
final String JOB_NAME = "configuredCronJob";
List jobRuns = this.getRunList(JOB_NAME);
assertEquals(0, jobRuns.size());
- context = new ClassPathXmlApplicationContext(
- "alfresco/scheduler-core-context.xml",
- "org/alfresco/util/test-scheduled-jobs-context.xml");
+ context = new ClassPathXmlApplicationContext("alfresco/scheduler-core-context.xml",
+ "org/alfresco/util/test-scheduled-jobs-context.xml");
CronTriggerBean ctBean = context.getBean("cronTriggerBean", CronTriggerBean.class);
scheduler = ctBean.getScheduler();
scheduler.start();
assertJobRunsAfterInterval(jobRuns);
- context.close(); // When the context closes, the scheduler should close, thereby stopping the job
+ context.close(); // When the context closes, the scheduler should close,
+ // thereby stopping the job
assertJobStopsAfterShutdown(jobRuns);
}
-
- @Test
- public void testCodedDelayedCronTriggerBean() throws Exception {
- final String JOB_NAME = "codedDelayedCronJob";
- List jobRuns = this.getRunList(JOB_NAME);
- assertEquals(0, jobRuns.size());
- CronTriggerBean ctBean = new CronTriggerBean();
- ctBean.setBeanName("Dummy");
- ctBean.setCronExpression("0/1 * * * * ? *");
- ctBean.setEnabled(true);
- JobDetail jobDetail = new JobDetail(JOB_NAME, "DefaultGroup", DummyJob.class);
- ctBean.setJobDetail(jobDetail);
+
+ /**
+ * Ensures that jobs that are coded with a delay run after the delay.
+ * @throws Exception
+ */
+ @Test
+ public void testCodedDelayedCronTriggerBean() throws Exception
+ {
+ final String JOB_NAME = "codedDelayedCronJob";
+ List jobRuns = this.getRunList(JOB_NAME);
+ assertEquals(0, jobRuns.size());
+ CronTriggerBean ctBean = new CronTriggerBean();
+ ctBean.setBeanName("Dummy");
+ ctBean.setCronExpression("0/1 * * * * ? *");
+ ctBean.setEnabled(true);
+ JobDetail jobDetail = new JobDetail(JOB_NAME, "DefaultGroup", DummyJob.class);
+ ctBean.setJobDetail(jobDetail);
scheduler = StdSchedulerFactory.getDefaultScheduler();
- ctBean.setScheduler(scheduler);
- final long START_DELAY = 4000L;
- ctBean.setStartDelay(START_DELAY);
-
+ ctBean.setScheduler(scheduler);
+ final long START_DELAY = 4000L;
+ ctBean.setStartDelay(START_DELAY);
+
final long PRE_SCHEDULING = System.currentTimeMillis();
- ctBean.afterPropertiesSet(); // This is when the trigger is actually scheduled
+ ctBean.afterPropertiesSet(); // This is when the trigger is actually
+ // scheduled
long startTime = ctBean.getTrigger().getStartTime().getTime();
- assertTrue("The startTime should be the time when the trigger is scheduled plus the START_DELAY.",
+ assertTrue("The startTime should be the time when the trigger is scheduled plus the START_DELAY.",
startTime - PRE_SCHEDULING - START_DELAY <= PRECISION_LEEWAY);
assertEquals(0, jobRuns.size());
scheduler.start();
assertJobDoesNotRunBeforeStartTime(jobRuns, startTime);
assertJobRunsAfterInterval(jobRuns);
- scheduler.shutdown();
- assertJobStopsAfterShutdown(jobRuns);
- }
-
- @Test
- public void testConfiguredDelayedCronTriggerBean() throws BeansException, Exception {
- final String JOB_NAME = "configuredDelayedCronJob";
- List jobRuns = this.getRunList(JOB_NAME);
- assertEquals(0, jobRuns.size());
-
- // Captures the system time before the Spring context is initialized and the triggers are scheduled
- final long PRE_INITIALIZATION = System.currentTimeMillis();
- context = new ClassPathXmlApplicationContext(
- "alfresco/scheduler-core-context.xml",
- "org/alfresco/util/test-scheduled-jobs-context.xml");
- CronTriggerBean ctBean = context.getBean("cronTriggerBeanDelayed", CronTriggerBean.class);
- final long START_DELAY = ctBean.getStartDelay();
- long startTime = ctBean.getTrigger().getStartTime().getTime();
- assertTrue("The startTime should be the time when the Spring context is initialized plus the START_DELAY.",
- startTime - PRE_INITIALIZATION - START_DELAY <= PRECISION_LEEWAY);
- assertEquals(0, jobRuns.size());
-
- scheduler = ctBean.getScheduler();
- scheduler.start();
- assertJobDoesNotRunBeforeStartTime(jobRuns, startTime);
- assertJobRunsAfterInterval(jobRuns);
- context.close(); // When the context closes, the scheduler should close, thereby stopping the job
+ scheduler.shutdown();
assertJobStopsAfterShutdown(jobRuns);
- }
+ }
+
+ /**
+ * Ensures that jobs that are configured with a delay run after the delay.
+ * @throws BeansException
+ * @throws Exception
+ */
+ @Test
+ public void testConfiguredDelayedCronTriggerBean() throws BeansException, Exception
+ {
+ final String JOB_NAME = "configuredDelayedCronJob";
+ List jobRuns = this.getRunList(JOB_NAME);
+ assertEquals(0, jobRuns.size());
+
+ // Captures the system time before the Spring context is initialized and
+ // the triggers are scheduled
+ final long PRE_INITIALIZATION = System.currentTimeMillis();
+ context = new ClassPathXmlApplicationContext("alfresco/scheduler-core-context.xml",
+ "org/alfresco/util/test-scheduled-jobs-context.xml");
+ CronTriggerBean ctBean = context.getBean("cronTriggerBeanDelayed", CronTriggerBean.class);
+ final long START_DELAY = ctBean.getStartDelay();
+ long startTime = ctBean.getTrigger().getStartTime().getTime();
+ assertTrue("The startTime should be the time when the Spring context is initialized plus the START_DELAY.",
+ startTime - PRE_INITIALIZATION - START_DELAY <= PRECISION_LEEWAY);
+ assertEquals(0, jobRuns.size());
+
+ scheduler = ctBean.getScheduler();
+ scheduler.start();
+ assertJobDoesNotRunBeforeStartTime(jobRuns, startTime);
+ assertJobRunsAfterInterval(jobRuns);
+ context.close(); // When the context closes, the scheduler should close,
+ // thereby stopping the job
+ assertJobStopsAfterShutdown(jobRuns);
+ }
private void assertJobStopsAfterShutdown(List jobRuns) throws InterruptedException
{
- // Gives the job one final interval to stop, but after that, there should be no more runs
+ // Gives the job one final interval to stop, but after that, there
+ // should be no more runs
Thread.sleep(INTERVAL);
- int runs = jobRuns.size();
- Thread.sleep(INTERVAL);
- assertEquals(runs, jobRuns.size());
+ int runs = jobRuns.size();
+ Thread.sleep(INTERVAL);
+ assertEquals(runs, jobRuns.size());
Thread.sleep(INTERVAL);
assertEquals(runs, jobRuns.size());
}
@@ -156,45 +218,51 @@ public class CronTriggerBeanTest {
private void assertJobRunsAfterInterval(List jobRuns) throws InterruptedException
{
// After the interval, there should be at least one run
- Thread.sleep(INTERVAL);
- assertTrue(jobRuns.size() > 0);
+ Thread.sleep(INTERVAL);
+ assertTrue(jobRuns.size() > 0);
}
private void assertJobDoesNotRunBeforeStartTime(List jobRuns, long startTime)
throws InterruptedException
{
// Synchronizing on an object prevents jobs from running while checking
- synchronized (lockToken)
+ synchronized (lockToken)
{
// It should not run before the start time
- while (System.currentTimeMillis() < startTime) {
- assertEquals(0, jobRuns.size());
+ while (System.currentTimeMillis() < startTime)
+ {
+ assertEquals(0, jobRuns.size());
Thread.sleep(20); // Sleeps so as to not take up all the CPU
- }
+ }
}
}
-
- public static class DummyJob implements Job {
- public void execute(JobExecutionContext context) throws JobExecutionException {
- synchronized (lockToken)
- {
- long now = System.currentTimeMillis();
- ArrayList runs = dummyJobRuns.get(context.getJobDetail().getName());
- if (runs == null) {
- runs = new ArrayList();
- dummyJobRuns.put(context.getJobDetail().getName(), runs);
- }
- runs.add(now);
- }
- }
- }
-
- private List getRunList(String jobName) {
- ArrayList runs = dummyJobRuns.get(jobName);
- if (runs == null) {
- runs = new ArrayList();
- dummyJobRuns.put(jobName, runs);
- }
- return runs;
- }
+
+ public static class DummyJob implements Job
+ {
+ public void execute(JobExecutionContext context) throws JobExecutionException
+ {
+ synchronized (lockToken)
+ {
+ long now = System.currentTimeMillis();
+ ArrayList runs = dummyJobRuns.get(context.getJobDetail().getName());
+ if (runs == null)
+ {
+ runs = new ArrayList();
+ dummyJobRuns.put(context.getJobDetail().getName(), runs);
+ }
+ runs.add(now);
+ }
+ }
+ }
+
+ private List getRunList(String jobName)
+ {
+ ArrayList runs = dummyJobRuns.get(jobName);
+ if (runs == null)
+ {
+ runs = new ArrayList();
+ dummyJobRuns.put(jobName, runs);
+ }
+ return runs;
+ }
}
diff --git a/source/test-resources/alfresco/extension/wcm-bootstrap-context.xml b/source/test-resources/alfresco/extension/wcm-bootstrap-context.xml
index fd3498995c..929b687ca4 100644
--- a/source/test-resources/alfresco/extension/wcm-bootstrap-context.xml
+++ b/source/test-resources/alfresco/extension/wcm-bootstrap-context.xml
@@ -77,6 +77,9 @@
0 * * * * ?
+
+ ${system.cronJob.startDelayMinutes}
+
@@ -102,6 +105,9 @@
0 30 3 * * ?
+
+ ${system.cronJob.startDelayMinutes}
+