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