1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.configuration;
18
19 import java.io.File;
20 import java.io.FileWriter;
21 import java.io.IOException;
22 import java.io.PrintWriter;
23 import java.text.MessageFormat;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Iterator;
27 import java.util.NoSuchElementException;
28 import java.util.Set;
29
30 import junit.framework.Assert;
31 import junit.framework.TestCase;
32
33 import org.apache.commons.configuration.event.ConfigurationEvent;
34 import org.apache.commons.configuration.event.ConfigurationListener;
35 import org.apache.commons.configuration.reloading.FileAlwaysReloadingStrategy;
36 import org.apache.commons.configuration.tree.DefaultExpressionEngine;
37 import org.apache.commons.configuration.tree.NodeCombiner;
38 import org.apache.commons.configuration.tree.UnionCombiner;
39
40 /***
41 * Test class for CombinedConfiguration.
42 *
43 * @version $Id: TestCombinedConfiguration.java 712401 2008-11-08 15:29:56Z oheger $
44 */
45 public class TestCombinedConfiguration extends TestCase
46 {
47 /*** Constant for the name of a sub configuration. */
48 private static final String TEST_NAME = "SUBCONFIG";
49
50 /*** Constant for a test key. */
51 private static final String TEST_KEY = "test.value";
52
53 /*** Constant for the name of the first child configuration.*/
54 private static final String CHILD1 = TEST_NAME + "1";
55
56 /*** Constant for the name of the second child configuration.*/
57 private static final String CHILD2 = TEST_NAME + "2";
58
59 /*** Constant for the name of the XML reload test file.*/
60 private static final String RELOAD_XML_NAME = "reload.xml";
61
62 /*** Constant for the content of a XML reload test file.*/
63 private static final String RELOAD_XML_CONTENT = "<xml><xmlReload>{0}</xmlReload></xml>";
64
65 /*** Constant for the name of the properties reload test file.*/
66 private static final String RELOAD_PROPS_NAME = "reload.properties";
67
68 /*** Constant for the content of a properties reload test file.*/
69 private static final String RELOAD_PROPS_CONTENT = "propsReload = {0}";
70
71 /*** Constant for the directory for writing test files.*/
72 private static final File TEST_DIR = new File("target");
73
74 /*** A list with files created during a test.*/
75 private Collection testFiles;
76
77 /*** The configuration to be tested. */
78 private CombinedConfiguration config;
79
80 /*** The test event listener. */
81 private CombinedListener listener;
82
83 protected void setUp() throws Exception
84 {
85 super.setUp();
86 config = new CombinedConfiguration();
87 listener = new CombinedListener();
88 config.addConfigurationListener(listener);
89 }
90
91 /***
92 * Performs clean-up after a test run. If test files have been created, they
93 * are removed now.
94 */
95 protected void tearDown() throws Exception
96 {
97 if (testFiles != null)
98 {
99 for (Iterator it = testFiles.iterator(); it.hasNext();)
100 {
101 File f = (File) it.next();
102 if (f.exists())
103 {
104 assertTrue("Cannot delete test file: " + f, f.delete());
105 }
106 }
107 }
108 }
109
110 /***
111 * Tests accessing a newly created combined configuration.
112 */
113 public void testInit()
114 {
115 assertEquals("Already configurations contained", 0, config
116 .getNumberOfConfigurations());
117 assertTrue("Set of names is not empty", config.getConfigurationNames()
118 .isEmpty());
119 assertTrue("Wrong node combiner",
120 config.getNodeCombiner() instanceof UnionCombiner);
121 assertNull("Test config was found", config.getConfiguration(TEST_NAME));
122 assertFalse("Force reload check flag is set", config.isForceReloadCheck());
123 }
124
125 /***
126 * Tests adding a configuration (without further information).
127 */
128 public void testAddConfiguration()
129 {
130 AbstractConfiguration c = setUpTestConfiguration();
131 config.addConfiguration(c);
132 checkAddConfig(c);
133 assertEquals("Wrong number of configs", 1, config
134 .getNumberOfConfigurations());
135 assertTrue("Name list is not empty", config.getConfigurationNames()
136 .isEmpty());
137 assertSame("Added config not found", c, config.getConfiguration(0));
138 assertTrue("Wrong property value", config.getBoolean(TEST_KEY));
139 listener.checkEvent(1, 0);
140 }
141
142 /***
143 * Tests adding a configuration with a name.
144 */
145 public void testAddConfigurationWithName()
146 {
147 AbstractConfiguration c = setUpTestConfiguration();
148 config.addConfiguration(c, TEST_NAME);
149 checkAddConfig(c);
150 assertEquals("Wrong number of configs", 1, config
151 .getNumberOfConfigurations());
152 assertSame("Added config not found", c, config.getConfiguration(0));
153 assertSame("Added config not found by name", c, config
154 .getConfiguration(TEST_NAME));
155 Set names = config.getConfigurationNames();
156 assertEquals("Wrong number of config names", 1, names.size());
157 assertTrue("Name not found", names.contains(TEST_NAME));
158 assertTrue("Wrong property value", config.getBoolean(TEST_KEY));
159 listener.checkEvent(1, 0);
160 }
161
162 /***
163 * Tests adding a configuration with a name when this name already exists.
164 * This should cause an exception.
165 */
166 public void testAddConfigurationWithNameTwice()
167 {
168 config.addConfiguration(setUpTestConfiguration(), TEST_NAME);
169 try
170 {
171 config.addConfiguration(setUpTestConfiguration(), TEST_NAME,
172 "prefix");
173 fail("Could add config with same name!");
174 }
175 catch (ConfigurationRuntimeException cex)
176 {
177
178 }
179 }
180
181 /***
182 * Tests adding a configuration and specifying an at position.
183 */
184 public void testAddConfigurationAt()
185 {
186 AbstractConfiguration c = setUpTestConfiguration();
187 config.addConfiguration(c, null, "my");
188 checkAddConfig(c);
189 assertTrue("Wrong property value", config.getBoolean("my." + TEST_KEY));
190 }
191
192 /***
193 * Tests adding a configuration with a complex at position. Here the at path
194 * contains a dot, which must be escaped.
195 */
196 public void testAddConfigurationComplexAt()
197 {
198 AbstractConfiguration c = setUpTestConfiguration();
199 config.addConfiguration(c, null, "This..is.a.complex");
200 checkAddConfig(c);
201 assertTrue("Wrong property value", config
202 .getBoolean("This..is.a.complex." + TEST_KEY));
203 }
204
205 /***
206 * Checks if a configuration was correctly added to the combined config.
207 *
208 * @param c the config to check
209 */
210 private void checkAddConfig(AbstractConfiguration c)
211 {
212 Collection listeners = c.getConfigurationListeners();
213 assertEquals("Wrong number of configuration listeners", 1, listeners
214 .size());
215 assertTrue("Combined config is no listener", listeners.contains(config));
216 }
217
218 /***
219 * Tests adding a null configuration. This should cause an exception to be
220 * thrown.
221 */
222 public void testAddNullConfiguration()
223 {
224 try
225 {
226 config.addConfiguration(null);
227 fail("Could add null configuration!");
228 }
229 catch (IllegalArgumentException iex)
230 {
231
232 }
233 }
234
235 /***
236 * Tests accessing properties if no configurations have been added.
237 */
238 public void testAccessPropertyEmpty()
239 {
240 assertFalse("Found a key", config.containsKey(TEST_KEY));
241 assertNull("Key has a value", config.getString("test.comment"));
242 assertTrue("Config is not empty", config.isEmpty());
243 }
244
245 /***
246 * Tests accessing properties if multiple configurations have been added.
247 */
248 public void testAccessPropertyMulti()
249 {
250 config.addConfiguration(setUpTestConfiguration());
251 config.addConfiguration(setUpTestConfiguration(), null, "prefix1");
252 config.addConfiguration(setUpTestConfiguration(), null, "prefix2");
253 assertTrue("Prop1 not found", config.getBoolean(TEST_KEY));
254 assertTrue("Prop 2 not found", config.getBoolean("prefix1." + TEST_KEY));
255 assertTrue("Prop 3 not found", config.getBoolean("prefix2." + TEST_KEY));
256 assertFalse("Configuration is empty", config.isEmpty());
257 listener.checkEvent(3, 0);
258 }
259
260 /***
261 * Tests removing a configuration.
262 */
263 public void testRemoveConfiguration()
264 {
265 AbstractConfiguration c = setUpTestConfiguration();
266 config.addConfiguration(c);
267 checkAddConfig(c);
268 assertTrue("Config could not be removed", config.removeConfiguration(c));
269 checkRemoveConfig(c);
270 }
271
272 /***
273 * Tests removing a configuration by index.
274 */
275 public void testRemoveConfigurationAt()
276 {
277 AbstractConfiguration c = setUpTestConfiguration();
278 config.addConfiguration(c);
279 assertSame("Wrong config removed", c, config.removeConfigurationAt(0));
280 checkRemoveConfig(c);
281 }
282
283 /***
284 * Tests removing a configuration by name.
285 */
286 public void testRemoveConfigurationByName()
287 {
288 AbstractConfiguration c = setUpTestConfiguration();
289 config.addConfiguration(c, TEST_NAME);
290 assertSame("Wrong config removed", c, config
291 .removeConfiguration(TEST_NAME));
292 checkRemoveConfig(c);
293 }
294
295 /***
296 * Tests removing a configuration with a name.
297 */
298 public void testRemoveNamedConfiguration()
299 {
300 AbstractConfiguration c = setUpTestConfiguration();
301 config.addConfiguration(c, TEST_NAME);
302 config.removeConfiguration(c);
303 checkRemoveConfig(c);
304 }
305
306 /***
307 * Tests removing a named configuration by index.
308 */
309 public void testRemoveNamedConfigurationAt()
310 {
311 AbstractConfiguration c = setUpTestConfiguration();
312 config.addConfiguration(c, TEST_NAME);
313 assertSame("Wrong config removed", c, config.removeConfigurationAt(0));
314 checkRemoveConfig(c);
315 }
316
317 /***
318 * Tests removing a configuration that was not added prior.
319 */
320 public void testRemoveNonContainedConfiguration()
321 {
322 assertFalse("Could remove non contained config", config
323 .removeConfiguration(setUpTestConfiguration()));
324 listener.checkEvent(0, 0);
325 }
326
327 /***
328 * Tests removing a configuration by name, which is not contained.
329 */
330 public void testRemoveConfigurationByUnknownName()
331 {
332 assertNull("Could remove configuration by unknown name", config
333 .removeConfiguration("unknownName"));
334 listener.checkEvent(0, 0);
335 }
336
337 /***
338 * Tests whether a configuration was completely removed.
339 *
340 * @param c the removed configuration
341 */
342 private void checkRemoveConfig(AbstractConfiguration c)
343 {
344 assertTrue("Listener was not removed", c.getConfigurationListeners()
345 .isEmpty());
346 assertEquals("Wrong number of contained configs", 0, config
347 .getNumberOfConfigurations());
348 assertTrue("Name was not removed", config.getConfigurationNames()
349 .isEmpty());
350 listener.checkEvent(2, 0);
351 }
352
353 /***
354 * Tests if an update of a contained configuration leeds to an invalidation
355 * of the combined configuration.
356 */
357 public void testUpdateContainedConfiguration()
358 {
359 AbstractConfiguration c = setUpTestConfiguration();
360 config.addConfiguration(c);
361 c.addProperty("test.otherTest", "yes");
362 assertEquals("New property not found", "yes", config
363 .getString("test.otherTest"));
364 listener.checkEvent(2, 0);
365 }
366
367 /***
368 * Tests if setting a node combiner causes an invalidation.
369 */
370 public void testSetNodeCombiner()
371 {
372 NodeCombiner combiner = new UnionCombiner();
373 config.setNodeCombiner(combiner);
374 assertSame("Node combiner was not set", combiner, config
375 .getNodeCombiner());
376 listener.checkEvent(1, 0);
377 }
378
379 /***
380 * Tests setting a null node combiner. This should cause an exception.
381 */
382 public void testSetNullNodeCombiner()
383 {
384 try
385 {
386 config.setNodeCombiner(null);
387 fail("Could set null node combiner!");
388 }
389 catch (IllegalArgumentException iex)
390 {
391
392 }
393 }
394
395 /***
396 * Tests cloning a combined configuration.
397 */
398 public void testClone()
399 {
400 config.addConfiguration(setUpTestConfiguration());
401 config.addConfiguration(setUpTestConfiguration(), TEST_NAME, "conf2");
402 config.addConfiguration(new PropertiesConfiguration(), "props");
403
404 CombinedConfiguration cc2 = (CombinedConfiguration) config.clone();
405 assertEquals("Wrong number of contained configurations", config
406 .getNumberOfConfigurations(), cc2.getNumberOfConfigurations());
407 assertSame("Wrong node combiner", config.getNodeCombiner(), cc2
408 .getNodeCombiner());
409 assertEquals("Wrong number of names", config.getConfigurationNames()
410 .size(), cc2.getConfigurationNames().size());
411 assertTrue("Event listeners were cloned", cc2
412 .getConfigurationListeners().isEmpty());
413
414 StrictConfigurationComparator comp = new StrictConfigurationComparator();
415 for (int i = 0; i < config.getNumberOfConfigurations(); i++)
416 {
417 assertNotSame("Configuration at " + i + " was not cloned", config
418 .getConfiguration(i), cc2.getConfiguration(i));
419 assertEquals("Wrong config class at " + i, config.getConfiguration(
420 i).getClass(), cc2.getConfiguration(i).getClass());
421 assertTrue("Configs not equal at " + i, comp.compare(config
422 .getConfiguration(i), cc2.getConfiguration(i)));
423 }
424
425 assertTrue("Combined configs not equal", comp.compare(config, cc2));
426 }
427
428 /***
429 * Tests if the cloned configuration is decoupled from the original.
430 */
431 public void testCloneModify()
432 {
433 config.addConfiguration(setUpTestConfiguration(), TEST_NAME);
434 CombinedConfiguration cc2 = (CombinedConfiguration) config.clone();
435 assertTrue("Name is missing", cc2.getConfigurationNames().contains(
436 TEST_NAME));
437 cc2.removeConfiguration(TEST_NAME);
438 assertFalse("Names in original changed", config.getConfigurationNames()
439 .isEmpty());
440 }
441
442 /***
443 * Tests clearing a combined configuration. This should remove all contained
444 * configurations.
445 */
446 public void testClear()
447 {
448 config.addConfiguration(setUpTestConfiguration(), TEST_NAME, "test");
449 config.addConfiguration(setUpTestConfiguration());
450
451 config.clear();
452 assertEquals("Still configs contained", 0, config
453 .getNumberOfConfigurations());
454 assertTrue("Still names contained", config.getConfigurationNames()
455 .isEmpty());
456 assertTrue("Config is not empty", config.isEmpty());
457
458 listener.checkEvent(3, 2);
459 }
460
461 /***
462 * Tests if file-based configurations can be reloaded.
463 */
464 public void testReloading() throws Exception
465 {
466 config.setForceReloadCheck(true);
467 File testXmlFile = writeReloadFile(RELOAD_XML_NAME, RELOAD_XML_CONTENT, 0);
468 File testPropsFile = writeReloadFile(RELOAD_PROPS_NAME, RELOAD_PROPS_CONTENT, 0);
469 XMLConfiguration c1 = new XMLConfiguration(testXmlFile);
470 c1.setReloadingStrategy(new FileAlwaysReloadingStrategy());
471 PropertiesConfiguration c2 = new PropertiesConfiguration(testPropsFile);
472 c2.setThrowExceptionOnMissing(true);
473 c2.setReloadingStrategy(new FileAlwaysReloadingStrategy());
474 config.addConfiguration(c1);
475 config.addConfiguration(c2);
476 assertEquals("Wrong xml reload value", 0, config.getInt("xmlReload"));
477 assertEquals("Wrong props reload value", 0, config
478 .getInt("propsReload"));
479
480 writeReloadFile(RELOAD_XML_NAME, RELOAD_XML_CONTENT, 1);
481 assertEquals("XML reload not detected", 1, config.getInt("xmlReload"));
482 config.setForceReloadCheck(false);
483 writeReloadFile(RELOAD_PROPS_NAME, RELOAD_PROPS_CONTENT, 1);
484 assertEquals("Props reload detected though check flag is false", 0, config
485 .getInt("propsReload"));
486 }
487
488 /***
489 * Tests whether the reload check works with a subnode configuration. This
490 * test is related to CONFIGURATION-341.
491 */
492 public void testReloadingSubnodeConfig() throws IOException,
493 ConfigurationException
494 {
495 config.setForceReloadCheck(true);
496 File testXmlFile = writeReloadFile(RELOAD_XML_NAME, RELOAD_XML_CONTENT,
497 0);
498 XMLConfiguration c1 = new XMLConfiguration(testXmlFile);
499 c1.setReloadingStrategy(new FileAlwaysReloadingStrategy());
500 final String prefix = "reloadCheck";
501 config.addConfiguration(c1, CHILD1, prefix);
502 SubnodeConfiguration sub = config.configurationAt(prefix, true);
503 writeReloadFile(RELOAD_XML_NAME, RELOAD_XML_CONTENT, 1);
504 assertEquals("Reload not detected", 1, sub.getInt("xmlReload"));
505 }
506
507 /***
508 * Prepares a test of the getSource() method.
509 */
510 private void setUpSourceTest()
511 {
512 HierarchicalConfiguration c1 = new HierarchicalConfiguration();
513 PropertiesConfiguration c2 = new PropertiesConfiguration();
514 c1.addProperty(TEST_KEY, TEST_NAME);
515 c2.addProperty("another.key", "test");
516 config.addConfiguration(c1, CHILD1);
517 config.addConfiguration(c2, CHILD2);
518 }
519
520 /***
521 * Tests the gestSource() method when the source property is defined in a
522 * hierarchical configuration.
523 */
524 public void testGetSourceHierarchical()
525 {
526 setUpSourceTest();
527 assertEquals("Wrong source configuration", config
528 .getConfiguration(CHILD1), config.getSource(TEST_KEY));
529 }
530
531 /***
532 * Tests whether the source configuration can be detected for non
533 * hierarchical configurations.
534 */
535 public void testGetSourceNonHierarchical()
536 {
537 setUpSourceTest();
538 assertEquals("Wrong source configuration", config
539 .getConfiguration(CHILD2), config.getSource("another.key"));
540 }
541
542 /***
543 * Tests the getSource() method when the passed in key is not contained.
544 * Result should be null in this case.
545 */
546 public void testGetSourceUnknown()
547 {
548 setUpSourceTest();
549 assertNull("Wrong result for unknown key", config
550 .getSource("an.unknown.key"));
551 }
552
553 /***
554 * Tests the getSource() method when a null key is passed in. This should
555 * cause an exception.
556 */
557 public void testGetSourceNull()
558 {
559 try
560 {
561 config.getSource(null);
562 fail("Could resolve source for null key!");
563 }
564 catch (IllegalArgumentException iex)
565 {
566
567 }
568 }
569
570 /***
571 * Tests the getSource() method when the passed in key belongs to the
572 * combined configuration itself.
573 */
574 public void testGetSourceCombined()
575 {
576 setUpSourceTest();
577 final String key = "yet.another.key";
578 config.addProperty(key, Boolean.TRUE);
579 assertEquals("Wrong source for key", config, config.getSource(key));
580 }
581
582 /***
583 * Tests the getSource() method when the passed in key refers to multiple
584 * values, which are all defined in the same source configuration.
585 */
586 public void testGetSourceMulti()
587 {
588 setUpSourceTest();
589 final String key = "list.key";
590 config.getConfiguration(CHILD1).addProperty(key, "1,2,3");
591 assertEquals("Wrong source for multi-value property", config
592 .getConfiguration(CHILD1), config.getSource(key));
593 }
594
595 /***
596 * Tests the getSource() method when the passed in key refers to multiple
597 * values defined by different sources. This should cause an exception.
598 */
599 public void testGetSourceMultiSources()
600 {
601 setUpSourceTest();
602 final String key = "list.key";
603 config.getConfiguration(CHILD1).addProperty(key, "1,2,3");
604 config.getConfiguration(CHILD2).addProperty(key, "a,b,c");
605 try
606 {
607 config.getSource(key);
608 fail("Multiple sources not detected!");
609 }
610 catch (IllegalArgumentException iex)
611 {
612
613 }
614 }
615
616 /***
617 * Tests whether escaped list delimiters are treated correctly.
618 */
619 public void testEscapeListDelimiters()
620 {
621 PropertiesConfiguration sub = new PropertiesConfiguration();
622 sub.addProperty("test.pi", "3//,1415");
623 config.addConfiguration(sub);
624 assertEquals("Wrong value", "3,1415", config.getString("test.pi"));
625 }
626
627 /***
628 * Tests whether an invalidate event is fired only after a change. This test
629 * is related to CONFIGURATION-315.
630 */
631 public void testInvalidateAfterChange()
632 {
633 ConfigurationEvent event = new ConfigurationEvent(config, 0, null,
634 null, true);
635 config.configurationChanged(event);
636 assertEquals("Invalidate event fired", 0, listener.invalidateEvents);
637 event = new ConfigurationEvent(config, 0, null, null, false);
638 config.configurationChanged(event);
639 assertEquals("No invalidate event fired", 1, listener.invalidateEvents);
640 }
641
642 /***
643 * Tests using a conversion expression engine for child configurations with
644 * strange keys. This test is related to CONFIGURATION-336.
645 */
646 public void testConversionExpressionEngine()
647 {
648 PropertiesConfiguration child = new PropertiesConfiguration();
649 child.addProperty("test(a)", "1,2,3");
650 config.addConfiguration(child);
651 DefaultExpressionEngine engineQuery = new DefaultExpressionEngine();
652 engineQuery.setIndexStart("<");
653 engineQuery.setIndexEnd(">");
654 config.setExpressionEngine(engineQuery);
655 DefaultExpressionEngine engineConvert = new DefaultExpressionEngine();
656 engineConvert.setIndexStart("[");
657 engineConvert.setIndexEnd("]");
658 config.setConversionExpressionEngine(engineConvert);
659 assertEquals("Wrong property 1", "1", config.getString("test(a)<0>"));
660 assertEquals("Wrong property 2", "2", config.getString("test(a)<1>"));
661 assertEquals("Wrong property 3", "3", config.getString("test(a)<2>"));
662 }
663
664 /***
665 * Tests whether reload operations can cause a deadlock when the combined
666 * configuration is accessed concurrently. This test is related to
667 * CONFIGURATION-344.
668 */
669 public void testDeadlockWithReload() throws ConfigurationException,
670 InterruptedException
671 {
672 final PropertiesConfiguration child = new PropertiesConfiguration(
673 "test.properties");
674 child.setReloadingStrategy(new FileAlwaysReloadingStrategy());
675 config.addConfiguration(child);
676 final int count = 1000;
677
678 class ReloadThread extends Thread
679 {
680 boolean error = false;
681
682 public void run()
683 {
684 for (int i = 0; i < count && !error; i++)
685 {
686 try
687 {
688 if (!child.getBoolean("configuration.loaded"))
689 {
690 error = true;
691 }
692 }
693 catch (NoSuchElementException nsex)
694 {
695 error = true;
696 }
697 }
698 }
699 }
700
701 ReloadThread reloadThread = new ReloadThread();
702 reloadThread.start();
703 for (int i = 0; i < count; i++)
704 {
705 assertEquals("Wrong value of combined property", 10, config
706 .getInt("test.integer"));
707 }
708 reloadThread.join();
709 assertFalse("Failure in thread", reloadThread.error);
710 }
711
712 /***
713 * Helper method for writing a file. The file is also added to a list and
714 * will be deleted in teadDown() automatically.
715 *
716 * @param file the file to be written
717 * @param content the file's content
718 * @throws IOException if an error occurs
719 */
720 private void writeFile(File file, String content) throws IOException
721 {
722 PrintWriter out = null;
723 try
724 {
725 out = new PrintWriter(new FileWriter(file));
726 out.print(content);
727
728 if (testFiles == null)
729 {
730 testFiles = new ArrayList();
731 }
732 testFiles.add(file);
733 }
734 finally
735 {
736 if (out != null)
737 {
738 out.close();
739 }
740 }
741 }
742
743 /***
744 * Helper method for writing a test file. The file will be created in the
745 * test directory. It is also scheduled for automatic deletion after the
746 * test.
747 *
748 * @param fileName the name of the test file
749 * @param content the content of the file
750 * @return the <code>File</code> object for the test file
751 * @throws IOException if an error occurs
752 */
753 private File writeFile(String fileName, String content) throws IOException
754 {
755 File file = new File(TEST_DIR, fileName);
756 writeFile(file, content);
757 return file;
758 }
759
760 /***
761 * Writes a file for testing reload operations.
762 *
763 * @param name the name of the reload test file
764 * @param content the content of the file
765 * @param value the value of the reload test property
766 * @return the file that was written
767 * @throws IOException if an error occurs
768 */
769 private File writeReloadFile(String name, String content, int value)
770 throws IOException
771 {
772 return writeFile(name, MessageFormat.format(content, new Object[] {
773 new Integer(value)
774 }));
775 }
776
777 /***
778 * Helper method for creating a test configuration to be added to the
779 * combined configuration.
780 *
781 * @return the test configuration
782 */
783 private AbstractConfiguration setUpTestConfiguration()
784 {
785 HierarchicalConfiguration config = new HierarchicalConfiguration();
786 config.addProperty(TEST_KEY, Boolean.TRUE);
787 config.addProperty("test.comment", "This is a test");
788 return config;
789 }
790
791 /***
792 * Test event listener class for checking if the expected invalidate events
793 * are fired.
794 */
795 static class CombinedListener implements ConfigurationListener
796 {
797 int invalidateEvents;
798
799 int otherEvents;
800
801 public void configurationChanged(ConfigurationEvent event)
802 {
803 if (event.getType() == CombinedConfiguration.EVENT_COMBINED_INVALIDATE)
804 {
805 invalidateEvents++;
806 }
807 else
808 {
809 otherEvents++;
810 }
811 }
812
813 /***
814 * Checks if the expected number of events was fired.
815 *
816 * @param expectedInvalidate the expected number of invalidate events
817 * @param expectedOthers the expected number of other events
818 */
819 public void checkEvent(int expectedInvalidate, int expectedOthers)
820 {
821 Assert.assertEquals("Wrong number of invalidate events",
822 expectedInvalidate, invalidateEvents);
823 Assert.assertEquals("Wrong number of other events", expectedOthers,
824 otherEvents);
825 }
826 }
827 }