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    *     http://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       * A test implementation which allows mocking the monitored file.
39       */
40      private static final class FileHandlerReloadingDetectorTestImpl extends FileHandlerReloadingDetector {
41          /** The mock file. */
42          private final File mockFile;
43  
44          /**
45           * Creates a new instance of {@code FileHandlerReloadingDetectorTestImpl} and initializes it with the mock file.
46           *
47           * @param file the mock file
48           */
49          public FileHandlerReloadingDetectorTestImpl(final File file) {
50              this(file, 0);
51          }
52  
53          /**
54           * Creates a new instance of {@code FileHandlerReloadingDetectorTestImpl} and initializes it with the mock file and a
55           * refresh delay.
56           *
57           * @param file the mock file
58           * @param delay the delay
59           */
60          public FileHandlerReloadingDetectorTestImpl(final File file, final long delay) {
61              super(null, delay);
62              mockFile = file;
63          }
64  
65          /**
66           * Always returns the mock file.
67           */
68          @Override
69          protected File getFile() {
70              return mockFile;
71          }
72      }
73  
74      /** Constant for a file's modification time. */
75      private static final long LAST_MODIFIED = 20121008215654L;
76  
77      /**
78       * Tests the default refresh delay.
79       */
80      @Test
81      public void testDefaultRefreshDelay() {
82          final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetector();
83          assertEquals(5000, detector.getRefreshDelay());
84      }
85  
86      /**
87       * Tests whether a jar URL is handled correctly.
88       */
89      @Test
90      public void testGetFileJarURL() throws Exception {
91          final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetector();
92          final URL url = new URL("jar:" + new File("conf/resources.jar").getAbsoluteFile().toURI().toURL() + "!/test-jar.xml");
93          detector.getFileHandler().setURL(url);
94          final File file = detector.getFile();
95          assertNotNull(file);
96          assertEquals("resources.jar", file.getName());
97      }
98  
99      /** The detector to be tested. */
100     /**
101      * Tests whether an instance can be created with a file handler.
102      */
103     @Test
104     public void testInitWithFileHandler() {
105         final FileHandler handler = new FileHandler();
106         final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetector(handler);
107         assertSame(handler, detector.getFileHandler());
108     }
109 
110     /**
111      * Tests whether a non-existing file is handled correctly.
112      */
113     @Test
114     public void testIsReloadingRequiredFileDoesNotExist() {
115         final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetector();
116         detector.getFileHandler().setFile(new File("NonExistingFile.txt"));
117         detector.reloadingPerformed();
118         assertFalse(detector.isReloadingRequired());
119     }
120 
121     /**
122      * Tests isReloadingRequired() if no location has been set.
123      */
124     @Test
125     public void testIsReloadingRequiredNoLocation() {
126         final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetector();
127         assertFalse(detector.isReloadingRequired());
128     }
129 
130     /**
131      * Tests whether a changed file is detected.
132      */
133     @Test
134     public void testIsReloadingRequiredTrue() throws Exception {
135         final File f = mock(File.class);
136 
137         when(f.exists()).thenReturn(Boolean.TRUE);
138         when(f.lastModified()).thenReturn(LAST_MODIFIED, LAST_MODIFIED + 1);
139 
140         final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetectorTestImpl(f);
141         assertFalse(detector.isReloadingRequired());
142         assertTrue(detector.isReloadingRequired());
143     }
144 
145     /**
146      * Tests that a newly created instance does not have a location.
147      */
148     @Test
149     public void testLocationAfterInit() {
150         final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetector();
151         assertFalse(detector.getFileHandler().isLocationDefined());
152     }
153 
154     /**
155      * Tests whether the refresh delay is taken into account.
156      */
157     @Test
158     public void testRefreshDelay() throws Exception {
159         final File f = mock(File.class);
160 
161         when(f.exists()).thenReturn(Boolean.TRUE);
162         when(f.lastModified()).thenReturn(LAST_MODIFIED, LAST_MODIFIED);
163 
164         final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetectorTestImpl(f, 60 * 60 * 1000L);
165         detector.reloadingPerformed();
166         assertFalse(detector.isReloadingRequired());
167         assertFalse(detector.isReloadingRequired());
168     }
169 
170     /**
171      * Tests whether a changed file is detected after initialization and invoking refresh.
172      */
173     @Test
174     public void testRefreshIsReloadingRequiredTrue() throws Exception {
175         final File f = mock(File.class);
176 
177         when(f.exists()).thenReturn(Boolean.TRUE);
178         when(f.lastModified()).thenReturn(LAST_MODIFIED, LAST_MODIFIED + 1);
179 
180         final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetectorTestImpl(f);
181         detector.refresh();
182         assertTrue(detector.isReloadingRequired());
183     }
184 
185     /**
186      * Tests a refresh cycle with a detected reload operation and a notification that reloading was performed.
187      */
188     @Test
189     public void testRefreshReloadingAndReset() throws Exception {
190         final File f = mock(File.class);
191 
192         when(f.exists()).thenReturn(Boolean.TRUE);
193         when(f.lastModified()).thenReturn(
194                 LAST_MODIFIED, LAST_MODIFIED, // 2 times
195                 LAST_MODIFIED + 1, LAST_MODIFIED + 1, LAST_MODIFIED + 1, // 3 times
196                 LAST_MODIFIED + 2);
197 
198         final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetectorTestImpl(f);
199         detector.refresh();
200         assertFalse(detector.isReloadingRequired());
201         assertTrue(detector.isReloadingRequired());
202         detector.reloadingPerformed();
203         assertFalse(detector.isReloadingRequired());
204         assertTrue(detector.isReloadingRequired());
205     }
206 
207     /**
208      * Tests a cycle with a detected reload operation and a notification that reloading was performed.
209      */
210     @Test
211     public void testReloadingAndReset() throws Exception {
212         final File f = mock(File.class);
213 
214         when(f.exists()).thenReturn(Boolean.TRUE);
215         when(f.lastModified()).thenReturn(
216                 LAST_MODIFIED,
217                 LAST_MODIFIED + 1, LAST_MODIFIED + 1, LAST_MODIFIED + 1, // 3 times
218                 LAST_MODIFIED + 2);
219 
220         final FileHandlerReloadingDetector detector = new FileHandlerReloadingDetectorTestImpl(f);
221         assertFalse(detector.isReloadingRequired());
222         assertTrue(detector.isReloadingRequired());
223         detector.reloadingPerformed();
224         assertFalse(detector.isReloadingRequired());
225         assertTrue(detector.isReloadingRequired());
226     }
227 }