View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.configuration2.reloading;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertFalse;
21  import static org.junit.jupiter.api.Assertions.assertNotNull;
22  import static org.junit.jupiter.api.Assertions.assertSame;
23  import static org.junit.jupiter.api.Assertions.assertTrue;
24  import static org.mockito.Mockito.mock;
25  import static org.mockito.Mockito.when;
26  
27  import java.io.File;
28  import java.net.URL;
29  
30  import org.apache.commons.configuration2.io.FileHandler;
31  import org.junit.jupiter.api.Test;
32  
33  /**
34   * Test class for {@code FileHandlerReloadingDetector}.
35   */
36  public class TestFileHandlerReloadingDetector {
37  
38      /**
39       * A test implementation which allows mocking the monitored file.
40       */
41      private static final class FileHandlerReloadingDetectorTestImpl extends FileHandlerReloadingDetector {
42  
43          /** The mock file. */
44          private final File mockFile;
45  
46          /**
47           * Creates a new instance of {@code FileHandlerReloadingDetectorTestImpl} and initializes it with the mock file.
48           *
49           * @param file the mock file
50           */
51          public FileHandlerReloadingDetectorTestImpl(final File file) {
52              this(file, 0);
53          }
54  
55          /**
56           * Creates a new instance of {@code FileHandlerReloadingDetectorTestImpl} and initializes it with the mock file and a
57           * refresh delay.
58           *
59           * @param file the mock file
60           * @param delay the delay
61           */
62          public FileHandlerReloadingDetectorTestImpl(final File file, final long delay) {
63              super(null, delay);
64              mockFile = file;
65          }
66  
67          /**
68           * Always returns the mock file.
69           */
70          @Override
71          protected File getFile() {
72              return mockFile;
73          }
74      }
75  
76      /** Constant for a file's modification time. */
77      private static final long LAST_MODIFIED = 20121008215654L;
78  
79      /**
80       * Tests the default refresh delay.
81       */
82      @Test
83      void testDefaultRefreshDelay() {
84          final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetector();
85          assertEquals(5000, detector.getRefreshDelay());
86      }
87  
88      /**
89       * Tests whether a jar URL is handled correctly.
90       */
91      @Test
92      void testGetFileJarURL() throws Exception {
93          final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetector();
94          final URL url = new URL("jar:" + new File("conf/resources.jar").getAbsoluteFile().toURI().toURL() + "!/test-jar.xml");
95          detector.getFileHandler().setURL(url);
96          final File file = detector.getFile();
97          assertNotNull(file);
98          assertEquals("resources.jar", file.getName());
99      }
100 
101     /** The detector to be tested. */
102 
103     /**
104      * Tests whether an instance can be created with a file handler.
105      */
106     @Test
107     void testInitWithFileHandler() {
108         final FileHandler handler = new FileHandler();
109         final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetector(handler);
110         assertSame(handler, detector.getFileHandler());
111     }
112 
113     /**
114      * Tests whether a non-existing file is handled correctly.
115      */
116     @Test
117     void testIsReloadingRequiredFileDoesNotExist() {
118         final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetector();
119         detector.getFileHandler().setFile(new File("NonExistingFile.txt"));
120         detector.reloadingPerformed();
121         assertFalse(detector.isReloadingRequired());
122     }
123 
124     /**
125      * Tests isReloadingRequired() if no location has been set.
126      */
127     @Test
128     void testIsReloadingRequiredNoLocation() {
129         final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetector();
130         assertFalse(detector.isReloadingRequired());
131     }
132 
133     /**
134      * Tests whether a changed file is detected.
135      */
136     @Test
137     void testIsReloadingRequiredTrue() throws Exception {
138         final File f = mock(File.class);
139 
140         when(f.exists()).thenReturn(Boolean.TRUE);
141         when(f.lastModified()).thenReturn(LAST_MODIFIED, LAST_MODIFIED + 1);
142 
143         final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetectorTestImpl(f);
144         assertFalse(detector.isReloadingRequired());
145         assertTrue(detector.isReloadingRequired());
146     }
147 
148     /**
149      * Tests that a newly created instance does not have a location.
150      */
151     @Test
152     void testLocationAfterInit() {
153         final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetector();
154         assertFalse(detector.getFileHandler().isLocationDefined());
155     }
156 
157     /**
158      * Tests whether the refresh delay is taken into account.
159      */
160     @Test
161     void testRefreshDelay() throws Exception {
162         final File f = mock(File.class);
163 
164         when(f.exists()).thenReturn(Boolean.TRUE);
165         when(f.lastModified()).thenReturn(LAST_MODIFIED, LAST_MODIFIED);
166 
167         final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetectorTestImpl(f, 60 * 60 * 1000L);
168         detector.reloadingPerformed();
169         assertFalse(detector.isReloadingRequired());
170         assertFalse(detector.isReloadingRequired());
171     }
172 
173     /**
174      * Tests whether a changed file is detected after initialization and invoking refresh.
175      */
176     @Test
177     void testRefreshIsReloadingRequiredTrue() throws Exception {
178         final File f = mock(File.class);
179 
180         when(f.exists()).thenReturn(Boolean.TRUE);
181         when(f.lastModified()).thenReturn(LAST_MODIFIED, LAST_MODIFIED + 1);
182 
183         final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetectorTestImpl(f);
184         detector.refresh();
185         assertTrue(detector.isReloadingRequired());
186     }
187 
188     /**
189      * Tests a refresh cycle with a detected reload operation and a notification that reloading was performed.
190      */
191     @Test
192     void testRefreshReloadingAndReset() throws Exception {
193         final File f = mock(File.class);
194 
195         when(f.exists()).thenReturn(Boolean.TRUE);
196         when(f.lastModified()).thenReturn(
197                 LAST_MODIFIED, LAST_MODIFIED, // 2 times
198                 LAST_MODIFIED + 1, LAST_MODIFIED + 1, LAST_MODIFIED + 1, // 3 times
199                 LAST_MODIFIED + 2);
200 
201         final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetectorTestImpl(f);
202         detector.refresh();
203         assertFalse(detector.isReloadingRequired());
204         assertTrue(detector.isReloadingRequired());
205         detector.reloadingPerformed();
206         assertFalse(detector.isReloadingRequired());
207         assertTrue(detector.isReloadingRequired());
208     }
209 
210     /**
211      * Tests a cycle with a detected reload operation and a notification that reloading was performed.
212      */
213     @Test
214     void testReloadingAndReset() throws Exception {
215         final File f = mock(File.class);
216 
217         when(f.exists()).thenReturn(Boolean.TRUE);
218         when(f.lastModified()).thenReturn(
219                 LAST_MODIFIED,
220                 LAST_MODIFIED + 1, LAST_MODIFIED + 1, LAST_MODIFIED + 1, // 3 times
221                 LAST_MODIFIED + 2);
222 
223         final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetectorTestImpl(f);
224         assertFalse(detector.isReloadingRequired());
225         assertTrue(detector.isReloadingRequired());
226         detector.reloadingPerformed();
227         assertFalse(detector.isReloadingRequired());
228         assertTrue(detector.isReloadingRequired());
229     }
230 }