Skip to content
This repository has been archived by the owner on May 7, 2020. It is now read-only.

Commit

Permalink
Timer fixes (#6480)
Browse files Browse the repository at this point in the history
Signed-off-by: Jon Evans <jon.evans@pobox.com>
  • Loading branch information
evansj authored and kaikreuzer committed Nov 9, 2018
1 parent 4d991fe commit 0ece46a
Show file tree
Hide file tree
Showing 9 changed files with 735 additions and 7 deletions.
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/test/java"/>
<classpathentry kind="src" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="output" path="target/classes"/>
Expand Down
Expand Up @@ -31,6 +31,7 @@ Import-Package:
org.hamcrest;core=split,
org.hamcrest.core,
org.junit;version="4.0.0",
org.quartz.spi,
org.slf4j
Require-Bundle:
org.eclipse.core.runtime,
Expand Down
@@ -0,0 +1,154 @@
/**
* Copyright (c) 2014,2018 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.smarthome.model.script.actions;

import static org.hamcrest.CoreMatchers.*;
import static org.joda.time.Instant.now;
import static org.junit.Assert.assertThat;

import org.eclipse.smarthome.model.script.scheduler.test.MockClosure.MockClosure0;
import org.eclipse.smarthome.model.script.scheduler.test.MockClosure.MockClosure1;
import org.eclipse.smarthome.model.script.scheduler.test.MockScheduler;
import org.junit.BeforeClass;
import org.junit.Test;
import org.quartz.SchedulerException;
import org.quartz.impl.SchedulerRepository;
import org.quartz.impl.StdSchedulerFactory;

/**
* Tests for {@link ScriptExecution}
*
* @author Jon Evans - initial contribution
*
*/
public class ScriptExecutionTest {
private static MockScheduler scheduler;

/**
* Set up Quartz to use our mock scheduler class
*
* @throws SchedulerException
*/
@BeforeClass
public static void setUp() throws SchedulerException {
scheduler = new MockScheduler();
System.setProperty(StdSchedulerFactory.PROPERTIES_FILE, "quartz-test.properties");
SchedulerRepository.getInstance().bind(scheduler);

assertThat(StdSchedulerFactory.getDefaultScheduler(), sameInstance(scheduler));
}

private Timer createTimer(MockClosure0 closure) {
Timer timer = ScriptExecution.createTimer(now(), closure);
// The code in our mock closure needs access to the timer object
closure.setTimer(timer);
return timer;
}

private Timer createTimer(Object arg, MockClosure1 closure) {
Timer timer = ScriptExecution.createTimerWithArgument(now(), arg, closure);
// The code in our mock closure needs access to the timer object
closure.setTimer(timer);
return timer;
}

/**
* Test that a running Timer can be rescheduled from within its closure
*
* @throws Exception
*/
@Test
public void testRescheduleTimerDuringExecution() throws Exception {
MockClosure0 closure = new MockClosure0(1);
Timer t = createTimer(closure);

assertThat(t.isRunning(), is(equalTo(false)));
assertThat(t.hasTerminated(), is(equalTo(false)));
assertThat(closure.getApplyCount(), is(equalTo(0)));
assertThat(scheduler.getPendingJobCount(), is(equalTo(1)));

// Run the scheduler twice
scheduler.run();
assertThat(scheduler.getPendingJobCount(), is(equalTo(1)));
scheduler.run();
assertThat(scheduler.getPendingJobCount(), is(equalTo(0)));

// Check that the Timer ran
assertThat(closure.getApplyCount(), is(equalTo(2)));
assertThat(t.isRunning(), is(equalTo(false)));
assertThat(t.hasTerminated(), is(equalTo(true)));
}

/**
* Tests that a Timer can be rescheduled after it has terminated
*
* @throws Exception
*/
@Test
public void testRescheduleTimerAfterExecution() throws Exception {
MockClosure0 closure = new MockClosure0();
Timer t = createTimer(closure);

assertThat(t.isRunning(), is(equalTo(false)));
assertThat(t.hasTerminated(), is(equalTo(false)));
assertThat(closure.getApplyCount(), is(equalTo(0)));
assertThat(scheduler.getPendingJobCount(), is(equalTo(1)));

// Run the scheduler
scheduler.run();
assertThat(scheduler.getPendingJobCount(), is(equalTo(0)));

// Check that the Timer ran
assertThat(closure.getApplyCount(), is(equalTo(1)));
assertThat(t.isRunning(), is(equalTo(false)));
assertThat(t.hasTerminated(), is(equalTo(true)));

// Now try to reschedule the Timer to run again after 10ms
boolean rescheduled = t.reschedule(now());
assertThat(rescheduled, is(equalTo(true)));
assertThat(t.hasTerminated(), is(equalTo(false)));
assertThat(scheduler.getPendingJobCount(), is(equalTo(1)));

// Run the scheduler
scheduler.run();
assertThat(scheduler.getPendingJobCount(), is(equalTo(0)));

// Check that the Timer ran again
assertThat(closure.getApplyCount(), is(equalTo(2)));
assertThat(t.isRunning(), is(equalTo(false)));
assertThat(t.hasTerminated(), is(equalTo(true)));
}

@Test
public void testClosureWithOneArgument() throws Exception {
Object arg = Integer.valueOf(42);
MockClosure1 closure = new MockClosure1(arg, 1);
Timer t = createTimer(arg, closure);

assertThat(t.isRunning(), is(equalTo(false)));
assertThat(t.hasTerminated(), is(equalTo(false)));
assertThat(closure.getApplyCount(), is(equalTo(0)));
assertThat(scheduler.getPendingJobCount(), is(equalTo(1)));

// Run the scheduler twice
scheduler.run();
assertThat(scheduler.getPendingJobCount(), is(equalTo(1)));
scheduler.run();
assertThat(scheduler.getPendingJobCount(), is(equalTo(0)));

// Check that the Timer ran
assertThat(closure.getApplyCount(), is(equalTo(2)));
assertThat(t.isRunning(), is(equalTo(false)));
assertThat(t.hasTerminated(), is(equalTo(true)));
}
}

0 comments on commit 0ece46a

Please sign in to comment.