| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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.apache.commons.configuration2.reloading; |
| |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertTrue; |
| |
| import java.util.concurrent.ScheduledExecutorService; |
| import java.util.concurrent.ScheduledFuture; |
| import java.util.concurrent.TimeUnit; |
| |
| import org.apache.commons.lang3.mutable.MutableObject; |
| import org.easymock.EasyMock; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| /** |
| * Test class for {@code PeriodicReloadingTrigger}. |
| * |
| */ |
| public class TestPeriodicReloadingTrigger |
| { |
| /** Constant for a parameter to be passed to the controller. */ |
| private static final Object CTRL_PARAM = "Test controller parameter"; |
| |
| /** Constant for the period. */ |
| private static final long PERIOD = 60; |
| |
| /** Constant for the period's time unit. */ |
| private static final TimeUnit UNIT = TimeUnit.SECONDS; |
| |
| /** A mock for the executor service. */ |
| private ScheduledExecutorService executor; |
| |
| /** A mock for the reloading controller. */ |
| private ReloadingController controller; |
| |
| @Before |
| public void setUp() throws Exception |
| { |
| executor = EasyMock.createMock(ScheduledExecutorService.class); |
| controller = EasyMock.createMock(ReloadingController.class); |
| } |
| |
| /** |
| * Creates a test instance with default parameters. |
| * |
| * @return the test instance |
| */ |
| private PeriodicReloadingTrigger createTrigger() |
| { |
| return new PeriodicReloadingTrigger(controller, CTRL_PARAM, PERIOD, UNIT, |
| executor); |
| } |
| |
| /** |
| * Tests whether a default executor service is created if necessary. |
| */ |
| @Test |
| public void testDefaultExecutor() |
| { |
| final PeriodicReloadingTrigger trigger = |
| new PeriodicReloadingTrigger(controller, CTRL_PARAM, PERIOD, UNIT); |
| assertNotNull("No executor service", trigger.getExecutorService()); |
| } |
| |
| /** |
| * Tries to create an instance without a controller. |
| */ |
| @Test(expected = IllegalArgumentException.class) |
| public void testInitNoController() |
| { |
| new PeriodicReloadingTrigger(null, CTRL_PARAM, PERIOD, UNIT); |
| } |
| |
| /** |
| * Tests that a newly created trigger is not running. |
| */ |
| @Test |
| public void testIsRunningAfterInit() |
| { |
| assertFalse("Running", createTrigger().isRunning()); |
| } |
| |
| /** |
| * Creates a mock object for a scheduled future. |
| * |
| * @return the mock |
| */ |
| private static ScheduledFuture<Void> createFutureMock() |
| { |
| @SuppressWarnings("unchecked") |
| final |
| ScheduledFuture<Void> mock = EasyMock.createMock(ScheduledFuture.class); |
| return mock; |
| } |
| |
| /** |
| * Prepares the executor mock to expect an invocation which schedules the |
| * trigger task. |
| * |
| * @param future the future object to return |
| */ |
| private void expectSchedule(final ScheduledFuture<Void> future) |
| { |
| executor.scheduleAtFixedRate(EasyMock.anyObject(Runnable.class), |
| EasyMock.eq(PERIOD), EasyMock.eq(PERIOD), EasyMock.eq(UNIT)); |
| if (future != null) |
| { |
| EasyMock.expectLastCall().andReturn(future); |
| } |
| } |
| |
| /** |
| * Tests whether the trigger can be started. |
| */ |
| @Test |
| public void testStart() |
| { |
| final ScheduledFuture<Void> future = createFutureMock(); |
| final MutableObject<Runnable> refTask = new MutableObject<>(); |
| expectSchedule(null); |
| EasyMock.expectLastCall().andAnswer( |
| () -> { |
| refTask.setValue((Runnable) EasyMock |
| .getCurrentArguments()[0]); |
| return future; |
| }); |
| EasyMock.expect(controller.checkForReloading(CTRL_PARAM)).andReturn( |
| Boolean.FALSE); |
| EasyMock.replay(future, controller, executor); |
| final PeriodicReloadingTrigger trigger = createTrigger(); |
| trigger.start(); |
| assertTrue("Not started", trigger.isRunning()); |
| refTask.getValue().run(); |
| EasyMock.verify(future, controller, executor); |
| } |
| |
| /** |
| * Tests whether start() is a noop if the trigger is already running. |
| */ |
| @Test |
| public void testStartTwice() |
| { |
| final ScheduledFuture<Void> future = createFutureMock(); |
| expectSchedule(future); |
| EasyMock.replay(future, controller, executor); |
| final PeriodicReloadingTrigger trigger = createTrigger(); |
| trigger.start(); |
| trigger.start(); |
| EasyMock.verify(future, controller, executor); |
| } |
| |
| /** |
| * Tests stop() if the trigger is not running. |
| */ |
| @Test |
| public void testStopNotRunning() |
| { |
| EasyMock.replay(controller, executor); |
| createTrigger().stop(); |
| } |
| |
| /** |
| * Tests whether a running trigger can be stopped. |
| */ |
| @Test |
| public void testStop() |
| { |
| final ScheduledFuture<Void> future = createFutureMock(); |
| expectSchedule(future); |
| EasyMock.expect(future.cancel(false)).andReturn(Boolean.TRUE); |
| EasyMock.replay(future, controller, executor); |
| final PeriodicReloadingTrigger trigger = createTrigger(); |
| trigger.start(); |
| trigger.stop(); |
| assertFalse("Still running", trigger.isRunning()); |
| EasyMock.verify(future, controller, executor); |
| } |
| |
| /** |
| * Tests a shutdown operation. |
| */ |
| @Test |
| public void testShutdown() |
| { |
| final ScheduledFuture<Void> future = createFutureMock(); |
| expectSchedule(future); |
| EasyMock.expect(future.cancel(false)).andReturn(Boolean.TRUE); |
| executor.shutdown(); |
| EasyMock.replay(future, controller, executor); |
| final PeriodicReloadingTrigger trigger = createTrigger(); |
| trigger.start(); |
| trigger.shutdown(); |
| EasyMock.verify(future, controller, executor); |
| } |
| |
| /** |
| * Tests a shutdown operation which excludes the executor service. |
| */ |
| @Test |
| public void testShutdownNoExecutor() |
| { |
| EasyMock.replay(controller, executor); |
| createTrigger().shutdown(false); |
| } |
| } |