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.builder.combined;
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.assertInstanceOf;
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.reset;
26  import static org.mockito.Mockito.verify;
27  import static org.mockito.Mockito.verifyNoMoreInteractions;
28  import static org.mockito.Mockito.when;
29  
30  import java.util.ArrayList;
31  import java.util.List;
32  import java.util.Map;
33  
34  import org.apache.commons.configuration2.XMLConfiguration;
35  import org.apache.commons.configuration2.builder.BasicBuilderParameters;
36  import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
37  import org.apache.commons.configuration2.builder.ReloadingFileBasedConfigurationBuilder;
38  import org.apache.commons.configuration2.builder.XMLBuilderParametersImpl;
39  import org.apache.commons.configuration2.ex.ConfigurationException;
40  import org.apache.commons.configuration2.reloading.ReloadingController;
41  import org.apache.commons.configuration2.tree.ExpressionEngine;
42  import org.apache.commons.configuration2.tree.xpath.XPathExpressionEngine;
43  import org.junit.jupiter.api.Test;
44  
45  /**
46   * Test class for {@code ReloadingMultiFileConfigurationBuilder}.
47   */
48  public class TestReloadingMultiFileConfigurationBuilder extends AbstractMultiFileConfigurationBuilderTest {
49  
50      /**
51       * A test implementation of the class under test which allows access to reloading controllers of managed configuration
52       * builders.
53       */
54      private static final class ReloadingMultiFileConfigurationBuilderTestImpl extends ReloadingMultiFileConfigurationBuilder<XMLConfiguration> {
55  
56          /**
57           * A list with mocks for reloading controllers created by this instance.
58           */
59          private final List<ReloadingController> reloadingControllers;
60  
61          public ReloadingMultiFileConfigurationBuilderTestImpl() {
62              super(XMLConfiguration.class, createTestBuilderParameters(null).getParameters());
63              reloadingControllers = new ArrayList<>();
64          }
65  
66          /**
67           * {@inheritDoc} This implementation creates a specialized reloading builder which is associated with a mock reloading
68           * controller.
69           */
70          @Override
71          protected FileBasedConfigurationBuilder<XMLConfiguration> createManagedBuilder(final String fileName, final Map<String, Object> params)
72              throws ConfigurationException {
73              final ReloadingController ctrl = mock(ReloadingController.class);
74              reloadingControllers.add(ctrl);
75              return new ReloadingFileBasedConfigurationBuilder<XMLConfiguration>(getResultClass(), params) {
76                  @Override
77                  public ReloadingController getReloadingController() {
78                      return ctrl;
79                  }
80              };
81          }
82  
83          /**
84           * Returns the list with the mock reloading controllers for the managed configuration builders created by this instance.
85           *
86           * @return the list with mock reloading controllers
87           */
88          public List<ReloadingController> getReloadingControllers() {
89              return reloadingControllers;
90          }
91      }
92  
93      /**
94       * Tests whether correct managed builders are created.
95       */
96      @Test
97      void testCreateManagedBuilder() throws ConfigurationException {
98          final ReloadingMultiFileConfigurationBuilder<XMLConfiguration> builder = new ReloadingMultiFileConfigurationBuilder<>(XMLConfiguration.class);
99          final FileBasedConfigurationBuilder<XMLConfiguration> managedBuilder = builder.createManagedBuilder("test.xml",
100             createTestBuilderParameters(null).getParameters());
101         assertInstanceOf(ReloadingFileBasedConfigurationBuilder.class, managedBuilder);
102         assertFalse(managedBuilder.isAllowFailOnInit());
103     }
104 
105     /**
106      * Tests whether the allowFailOnInit flag is passed to newly created managed builders.
107      */
108     @Test
109     void testCreateManagedBuilderWithAllowFailFlag() throws ConfigurationException {
110         final ReloadingMultiFileConfigurationBuilder<XMLConfiguration> builder = new ReloadingMultiFileConfigurationBuilder<>(XMLConfiguration.class, null,
111             true);
112         final FileBasedConfigurationBuilder<XMLConfiguration> managedBuilder = builder.createManagedBuilder("test.xml",
113             createTestBuilderParameters(null).getParameters());
114         assertTrue(managedBuilder.isAllowFailOnInit());
115     }
116 
117     /**
118      * Tests whether parameters passed to the constructor are passed to the super class.
119      */
120     @Test
121     void testInitWithParameters() throws ConfigurationException {
122         final ExpressionEngine engine = new XPathExpressionEngine();
123         final BasicBuilderParameters params = createTestBuilderParameters(new XMLBuilderParametersImpl().setExpressionEngine(engine));
124         final ReloadingMultiFileConfigurationBuilder<XMLConfiguration> builder = new ReloadingMultiFileConfigurationBuilder<>(XMLConfiguration.class,
125             params.getParameters());
126         switchToConfig(1);
127         final XMLConfiguration config = builder.getConfiguration();
128         assertSame(engine, config.getExpressionEngine());
129     }
130 
131     /**
132      * Tests whether a reloading check works correctly.
133      */
134     @Test
135     void testReloadingControllerCheck() throws ConfigurationException {
136         final ReloadingMultiFileConfigurationBuilderTestImpl builder = new ReloadingMultiFileConfigurationBuilderTestImpl();
137         switchToConfig(1);
138         builder.getConfiguration();
139         switchToConfig(2);
140         builder.getConfiguration();
141         final List<ReloadingController> controllers = builder.getReloadingControllers();
142         assertEquals(2, controllers.size());
143 
144         for (final ReloadingController c : controllers) {
145             reset(c);
146             when(c.checkForReloading(null)).thenReturn(Boolean.FALSE);
147         }
148 
149         assertFalse(builder.getReloadingController().checkForReloading(this));
150 
151         for (final ReloadingController c : controllers) {
152             verify(c).checkForReloading(null);
153             verifyNoMoreInteractions(c);
154         }
155     }
156 
157     /**
158      * Tests a reloading check which detects the need to reload.
159      */
160     @Test
161     void testReloadingControllerCheckReloadingRequired() throws ConfigurationException {
162         final ReloadingMultiFileConfigurationBuilderTestImpl builder = new ReloadingMultiFileConfigurationBuilderTestImpl();
163         for (int i = 1; i <= 3; i++) {
164             switchToConfig(i);
165             builder.getConfiguration();
166         }
167         final List<ReloadingController> controllers = builder.getReloadingControllers();
168 
169         reset(controllers.toArray());
170         when(controllers.get(0).checkForReloading(null)).thenReturn(Boolean.FALSE);
171         when(controllers.get(1).checkForReloading(null)).thenReturn(Boolean.TRUE);
172         when(controllers.get(2).checkForReloading(null)).thenReturn(Boolean.FALSE);
173 
174         assertTrue(builder.getReloadingController().checkForReloading(this));
175 
176         for (final ReloadingController c : controllers) {
177             verify(c).checkForReloading(null);
178             verifyNoMoreInteractions(c);
179         }
180     }
181 
182     /**
183      * Tests whether the reloading state of the reloading controller can be reset.
184      */
185     @Test
186     void testReloadingControllerResetReloadingState() throws ConfigurationException {
187         final ReloadingMultiFileConfigurationBuilderTestImpl builder = new ReloadingMultiFileConfigurationBuilderTestImpl();
188         switchToConfig(1);
189         builder.getConfiguration();
190         switchToConfig(2);
191         builder.getConfiguration();
192         final List<ReloadingController> controllers = builder.getReloadingControllers();
193 
194         reset(controllers.toArray());
195         for (final ReloadingController c : controllers) {
196             when(c.checkForReloading(null)).thenReturn(Boolean.TRUE);
197         }
198 
199         builder.getReloadingController().checkForReloading(null);
200         builder.getReloadingController().resetReloadingState();
201 
202         for (final ReloadingController c : controllers) {
203             verify(c).checkForReloading(null);
204             verify(c).resetReloadingState();
205             verifyNoMoreInteractions(c);
206         }
207     }
208 }