~ubuntu-branches/ubuntu/saucy/commons-configuration/saucy

« back to all changes in this revision

Viewing changes to src/test/java/org/apache/commons/configuration/TestDynamicCombinedConfiguration.java

  • Committer: Package Import Robot
  • Author(s): Emmanuel Bourg
  • Date: 2013-07-01 16:29:44 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20130701162944-98waq5gogha5gpn1
Tags: 1.9-1
* New upstream release
* debian/control:
  - Updated Standards-Version to 3.9.4 (no changes)
  - Use canonical URLs for the Vcs-* fields
  - Added new build dependencies (libjavacc-maven-plugin-java, junit4)
  - Upgraded the dependency on the Servlet API (2.5 -> 3.0)
  - Removed the dependency on the Activation Framework (glassfish-activation)
  - Replaced the dependency on glassfish-mail with libgnumail-java
  - Removed the unused dependencies:
    liblog4j1.2-java-doc, libmaven-assembly-plugin-java
  - Replaced the dependency on libcommons-jexl-java by libcommons-jexl2-java
* debian/watch: Changed to point the official Apache distribution server
* Removed the obsolete file debian/ant.properties
* Installed the upstream changelog in the binary packages
* Added the report plugins to maven.ignoreRules
* Added the classpath attribute to the jar manifest

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
18
package org.apache.commons.configuration;
 
19
 
 
20
import static org.junit.Assert.assertEquals;
 
21
import static org.junit.Assert.assertFalse;
 
22
import static org.junit.Assert.assertNotNull;
 
23
import static org.junit.Assert.assertTrue;
 
24
 
 
25
import java.io.File;
 
26
import java.io.FileReader;
 
27
import java.io.FileWriter;
 
28
import java.io.IOException;
 
29
import java.io.Reader;
 
30
import java.io.Writer;
 
31
 
 
32
import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
 
33
import org.apache.commons.lang.text.StrLookup;
 
34
import org.junit.Test;
 
35
 
 
36
public class TestDynamicCombinedConfiguration
 
37
{
 
38
    private static String PATTERN = "${sys:Id}";
 
39
    private static String PATTERN1 = "target/test-classes/testMultiConfiguration_${sys:Id}.xml";
 
40
    private static String DEFAULT_FILE = "target/test-classes/testMultiConfiguration_default.xml";
 
41
    private static final File MULTI_TENENT_FILE = new File(
 
42
            "conf/testMultiTenentConfigurationBuilder4.xml");
 
43
    private static final File MULTI_DYNAMIC_FILE = new File(
 
44
            "conf/testMultiTenentConfigurationBuilder5.xml");
 
45
 
 
46
    /** Constant for the number of test threads. */
 
47
    private static final int THREAD_COUNT = 3;
 
48
 
 
49
    /** Constant for the number of loops in the multi-thread tests. */
 
50
    private static final int LOOP_COUNT = 100;
 
51
 
 
52
    @Test
 
53
    public void testConfiguration() throws Exception
 
54
    {
 
55
        DynamicCombinedConfiguration config = new DynamicCombinedConfiguration();
 
56
        XPathExpressionEngine engine = new XPathExpressionEngine();
 
57
        config.setExpressionEngine(engine);
 
58
        config.setKeyPattern(PATTERN);
 
59
        config.setDelimiterParsingDisabled(true);
 
60
        MultiFileHierarchicalConfiguration multi = new MultiFileHierarchicalConfiguration(PATTERN1);
 
61
        multi.setExpressionEngine(engine);
 
62
        config.addConfiguration(multi, "Multi");
 
63
        XMLConfiguration xml = new XMLConfiguration();
 
64
        xml.setExpressionEngine(engine);
 
65
        xml.setDelimiterParsingDisabled(true);
 
66
        xml.setFile(new File(DEFAULT_FILE));
 
67
        xml.load();
 
68
        config.addConfiguration(xml, "Default");
 
69
 
 
70
        verify("1001", config, 15);
 
71
        verify("1002", config, 25);
 
72
        verify("1003", config, 35);
 
73
        verify("1004", config, 50);
 
74
        assertEquals("a,b,c", config.getString("split/list3/@values"));
 
75
        assertEquals(0, config.getMaxIndex("split/list3/@values"));
 
76
        assertEquals("a\\,b\\,c", config.getString("split/list4/@values"));
 
77
        assertEquals("a,b,c", config.getString("split/list1"));
 
78
        assertEquals(0, config.getMaxIndex("split/list1"));
 
79
        assertEquals("a\\,b\\,c", config.getString("split/list2"));
 
80
    }
 
81
 
 
82
    @Test
 
83
    public void testConcurrentGetAndReload() throws Exception
 
84
    {
 
85
        System.getProperties().remove("Id");
 
86
        DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
 
87
        factory.setFile(MULTI_TENENT_FILE);
 
88
        CombinedConfiguration config = factory.getConfiguration(true);
 
89
 
 
90
        assertEquals(config.getString("rowsPerPage"), "50");
 
91
        Thread testThreads[] = new Thread[THREAD_COUNT];
 
92
        int failures[] = new int[THREAD_COUNT];
 
93
 
 
94
        for (int i = 0; i < testThreads.length; ++i)
 
95
        {
 
96
            testThreads[i] = new ReloadThread(config, failures, i, LOOP_COUNT, false, null, "50");
 
97
            testThreads[i].start();
 
98
        }
 
99
 
 
100
        int totalFailures = 0;
 
101
        for (int i = 0; i < testThreads.length; ++i)
 
102
        {
 
103
            testThreads[i].join();
 
104
            totalFailures += failures[i];
 
105
        }
 
106
        assertTrue(totalFailures + " failures Occurred", totalFailures == 0);
 
107
    }
 
108
 
 
109
    @Test
 
110
    public void testConcurrentGetAndReload2() throws Exception
 
111
    {
 
112
        System.getProperties().remove("Id");
 
113
        DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
 
114
        factory.setFile(MULTI_TENENT_FILE);
 
115
        CombinedConfiguration config = factory.getConfiguration(true);
 
116
 
 
117
        assertEquals(config.getString("rowsPerPage"), "50");
 
118
 
 
119
        Thread testThreads[] = new Thread[THREAD_COUNT];
 
120
        int failures[] = new int[THREAD_COUNT];
 
121
        System.setProperty("Id", "2002");
 
122
        assertEquals(config.getString("rowsPerPage"), "25");
 
123
        for (int i = 0; i < testThreads.length; ++i)
 
124
        {
 
125
            testThreads[i] = new ReloadThread(config, failures, i, LOOP_COUNT, false, null, "25");
 
126
            testThreads[i].start();
 
127
        }
 
128
 
 
129
        int totalFailures = 0;
 
130
        for (int i = 0; i < testThreads.length; ++i)
 
131
        {
 
132
            testThreads[i].join();
 
133
            totalFailures += failures[i];
 
134
        }
 
135
        System.getProperties().remove("Id");
 
136
        assertTrue(totalFailures + " failures Occurred", totalFailures == 0);
 
137
    }
 
138
 
 
139
    @Test
 
140
    public void testConcurrentGetAndReloadMultipleClients() throws Exception
 
141
    {
 
142
        System.getProperties().remove("Id");
 
143
        DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
 
144
        factory.setFile(MULTI_TENENT_FILE);
 
145
        CombinedConfiguration config = factory.getConfiguration(true);
 
146
 
 
147
        assertEquals(config.getString("rowsPerPage"), "50");
 
148
 
 
149
        Thread testThreads[] = new Thread[THREAD_COUNT];
 
150
        int failures[] = new int[THREAD_COUNT];
 
151
        String[] ids = new String[] {null, "2002", "3001", "3002", "3003"};
 
152
        String[] expected = new String[] {"50", "25", "15", "25", "50"};
 
153
        for (int i = 0; i < testThreads.length; ++i)
 
154
        {
 
155
            testThreads[i] = new ReloadThread(config, failures, i, LOOP_COUNT, true, ids[i], expected[i]);
 
156
            testThreads[i].start();
 
157
        }
 
158
 
 
159
        int totalFailures = 0;
 
160
        for (int i = 0; i < testThreads.length; ++i)
 
161
        {
 
162
            testThreads[i].join();
 
163
            totalFailures += failures[i];
 
164
        }
 
165
        System.getProperties().remove("Id");
 
166
        if (totalFailures != 0)
 
167
        {
 
168
            System.out.println("Failures:");
 
169
            for (int i = 0; i < testThreads.length; ++i)
 
170
            {
 
171
                System.out.println("Thread " + i + " " + failures[i]);
 
172
            }
 
173
        }
 
174
        assertTrue(totalFailures + " failures Occurred", totalFailures == 0);
 
175
    }
 
176
 
 
177
    @Test
 
178
  public void testConcurrentGetAndReloadFile() throws Exception
 
179
    {
 
180
        final int threadCount = 25;
 
181
        System.getProperties().remove("Id");
 
182
        // create a new configuration
 
183
        File input = new File("target/test-classes/testMultiDynamic_default.xml");
 
184
        File output = new File("target/test-classes/testwrite/testMultiDynamic_default.xml");
 
185
        output.delete();
 
186
        output.getParentFile().mkdir();
 
187
        copyFile(input, output);
 
188
 
 
189
        DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
 
190
        factory.setFile(MULTI_DYNAMIC_FILE);
 
191
        CombinedConfiguration config = factory.getConfiguration(true);
 
192
 
 
193
        assertEquals(config.getString("Product/FIIndex/FI[@id='123456781']"), "ID0001");
 
194
 
 
195
        ReaderThread testThreads[] = new ReaderThread[threadCount];
 
196
        for (int i = 0; i < testThreads.length; ++i)
 
197
        {
 
198
            testThreads[i] = new ReaderThread(config);
 
199
            testThreads[i].start();
 
200
        }
 
201
 
 
202
        Thread.sleep(2000);
 
203
 
 
204
        input = new File("target/test-classes/testMultiDynamic_default2.xml");
 
205
        copyFile(input, output);
 
206
 
 
207
        Thread.sleep(2000);
 
208
        String id = config.getString("Product/FIIndex/FI[@id='123456782']");
 
209
        assertNotNull("File did not reload, id is null", id);
 
210
        String rows = config.getString("rowsPerPage");
 
211
        assertTrue("Incorrect value for rowsPerPage", "25".equals(rows));
 
212
 
 
213
        for (int i = 0; i < testThreads.length; ++i)
 
214
        {
 
215
            testThreads[i].shutdown();
 
216
            testThreads[i].join();
 
217
        }
 
218
        for (int i = 0; i < testThreads.length; ++i)
 
219
        {
 
220
            assertFalse(testThreads[i].failed());
 
221
        }
 
222
        assertEquals("ID0002", config.getString("Product/FIIndex/FI[@id='123456782']"));
 
223
        output.delete();
 
224
    }
 
225
 
 
226
 
 
227
    private class ReloadThread extends Thread
 
228
    {
 
229
        CombinedConfiguration combined;
 
230
        int[] failures;
 
231
        int index;
 
232
        int count;
 
233
        String expected;
 
234
        String id;
 
235
        boolean useId;
 
236
 
 
237
        ReloadThread(CombinedConfiguration config, int[] failures, int index, int count,
 
238
                     boolean useId, String id, String expected)
 
239
        {
 
240
            combined = config;
 
241
            this.failures = failures;
 
242
            this.index = index;
 
243
            this.count = count;
 
244
            this.expected = expected;
 
245
            this.id = id;
 
246
            this.useId = useId;
 
247
        }
 
248
        @Override
 
249
        public void run()
 
250
        {
 
251
            failures[index] = 0;
 
252
 
 
253
            if (useId)
 
254
            {
 
255
                ThreadLookup.setId(id);
 
256
            }
 
257
            for (int i = 0; i < count; i++)
 
258
            {
 
259
                try
 
260
                {
 
261
                    String value = combined.getString("rowsPerPage", null);
 
262
                    if (value == null || !value.equals(expected))
 
263
                    {
 
264
                        ++failures[index];
 
265
                    }
 
266
                }
 
267
                catch (Exception ex)
 
268
                {
 
269
                    ++failures[index];
 
270
                }
 
271
            }
 
272
        }
 
273
    }
 
274
 
 
275
    private class ReaderThread extends Thread
 
276
    {
 
277
        private boolean running = true;
 
278
        private boolean failed = false;
 
279
        CombinedConfiguration combined;
 
280
 
 
281
        public ReaderThread(CombinedConfiguration c)
 
282
        {
 
283
            combined = c;
 
284
        }
 
285
 
 
286
        @Override
 
287
        public void run()
 
288
        {
 
289
            while (running)
 
290
            {
 
291
                String bcId = combined.getString("Product/FIIndex/FI[@id='123456781']");
 
292
                if ("ID0001".equalsIgnoreCase(bcId))
 
293
                {
 
294
                    if (failed)
 
295
                    {
 
296
                        System.out.println("Thread failed, but recovered");
 
297
                    }
 
298
                    failed = false;
 
299
                }
 
300
                else
 
301
                {
 
302
                    failed = true;
 
303
                }
 
304
            }
 
305
        }
 
306
 
 
307
        public boolean failed()
 
308
        {
 
309
            return failed;
 
310
        }
 
311
 
 
312
        public void shutdown()
 
313
        {
 
314
            running = false;
 
315
        }
 
316
 
 
317
    }
 
318
 
 
319
    private void verify(String key, DynamicCombinedConfiguration config, int rows)
 
320
    {
 
321
        System.setProperty("Id", key);
 
322
        assertTrue(config.getInt("rowsPerPage") == rows);
 
323
    }
 
324
 
 
325
    private void copyFile(File input, File output) throws IOException
 
326
    {
 
327
        Reader reader = new FileReader(input);
 
328
        Writer writer = new FileWriter(output);
 
329
        char[] buffer = new char[4096];
 
330
        int n = 0;
 
331
        while (-1 != (n = reader.read(buffer)))
 
332
        {
 
333
            writer.write(buffer, 0, n);
 
334
        }
 
335
        reader.close();
 
336
        writer.close();
 
337
    }
 
338
 
 
339
    public static class ThreadLookup extends StrLookup
 
340
    {
 
341
        private static ThreadLocal<String> id = new ThreadLocal<String>();
 
342
 
 
343
 
 
344
 
 
345
        public ThreadLookup()
 
346
        {
 
347
 
 
348
        }
 
349
 
 
350
        public static void setId(String value)
 
351
        {
 
352
            id.set(value);
 
353
        }
 
354
 
 
355
        @Override
 
356
        public String lookup(String key)
 
357
        {
 
358
            if (key == null || !key.equals("Id"))
 
359
            {
 
360
                return null;
 
361
            }
 
362
            String value = System.getProperty("Id");
 
363
            if (value != null)
 
364
            {
 
365
                return value;
 
366
            }
 
367
            return id.get();
 
368
 
 
369
        }
 
370
    }
 
371
}