1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.configuration;
19
20 import java.io.File;
21 import java.io.FileInputStream;
22 import java.io.FileOutputStream;
23 import java.io.FileWriter;
24 import java.io.IOException;
25 import java.io.PrintWriter;
26 import java.net.URL;
27 import java.util.Iterator;
28 import java.util.Properties;
29
30 import junit.framework.TestCase;
31
32 import org.apache.commons.configuration.reloading.FileAlwaysReloadingStrategy;
33 import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
34
35 /***
36 * @author Emmanuel Bourg
37 * @version $Revision: 711782 $, $Date: 2008-11-06 08:23:41 +0100 (Do, 06 Nov 2008) $
38 */
39 public class TestFileConfiguration extends TestCase
40 {
41 /*** Constant for the output directory.*/
42 private static final File TARGET_DIR = new File("target");
43
44 /*** Constant for the directory with the test configuration files.*/
45 private static final File TEST_DIR = new File("conf");
46
47 /*** Constant for the name of a test file.*/
48 private static final String TEST_FILENAME = "test.properties";
49
50 /*** Constant for a test file.*/
51 private static final File TEST_FILE = new File(TEST_DIR, TEST_FILENAME);
52
53 /*** Constant for the name of a resource to be resolved.*/
54 private static final String RESOURCE_NAME = "config/deep/deeptest.properties";
55
56 public void testSetURL() throws Exception
57 {
58
59 FileConfiguration config = new PropertiesConfiguration();
60 config.setURL(new URL("http://commons.apache.org/configuration/index.html"));
61
62 assertEquals("base path", "http://commons.apache.org/configuration/", config.getBasePath());
63 assertEquals("file name", "index.html", config.getFileName());
64
65
66 config.setURL(new URL("file:/temp/test.properties"));
67 assertEquals("base path", "file:/temp/", config.getBasePath());
68 assertEquals("file name", "test.properties", config.getFileName());
69 }
70
71 public void testSetURLWithParams() throws Exception
72 {
73 FileConfiguration config = new PropertiesConfiguration();
74 URL url = new URL("http://issues.apache.org/bugzilla/show_bug.cgi?id=37886");
75 config.setURL(url);
76 assertEquals("Base path incorrect", "http://issues.apache.org/bugzilla/", config.getBasePath());
77 assertEquals("File name incorrect", "show_bug.cgi", config.getFileName());
78 assertEquals("URL was not correctly stored", url, config.getURL());
79 }
80
81 public void testLocations() throws Exception
82 {
83 PropertiesConfiguration config = new PropertiesConfiguration();
84
85 File directory = TEST_DIR;
86 File file = TEST_FILE;
87 config.setFile(file);
88 assertEquals(directory.getAbsolutePath(), config.getBasePath());
89 assertEquals(TEST_FILENAME, config.getFileName());
90 assertEquals(file.getAbsolutePath(), config.getPath());
91
92 config.setPath("conf" + File.separator + TEST_FILENAME);
93 assertEquals(TEST_FILENAME, config.getFileName());
94 assertEquals(directory.getAbsolutePath(), config.getBasePath());
95 assertEquals(file.getAbsolutePath(), config.getPath());
96 assertEquals(file.toURL(), config.getURL());
97
98 config.setBasePath(null);
99 config.setFileName(TEST_FILENAME);
100 assertNull(config.getBasePath());
101 assertEquals(TEST_FILENAME, config.getFileName());
102 }
103
104 public void testCreateFile1() throws Exception
105 {
106 File file = new File("target/test-resources/foo/bar/test.properties");
107 if (file.exists())
108 {
109 file.delete();
110 file.getParentFile().delete();
111 }
112
113 assertFalse("The file should not exist", file.exists());
114
115 FileConfiguration config = new PropertiesConfiguration(file);
116 config.save();
117
118 assertTrue("The file doesn't exist", file.exists());
119 }
120
121 public void testCreateFile2() throws Exception
122 {
123 File file = new File("target/test-resources/foo/bar/test.properties");
124 if (file.exists())
125 {
126 file.delete();
127 file.getParentFile().delete();
128 }
129
130 assertFalse("The file should not exist", file.exists());
131
132 FileConfiguration config = new PropertiesConfiguration();
133 config.setFile(file);
134 config.save();
135
136 assertTrue("The file doesn't exist", file.exists());
137 }
138
139 public void testCreateFile3() throws Exception
140 {
141 File file = new File("target/test-resources/foo/bar/test.properties");
142 if (file.exists())
143 {
144 file.delete();
145 file.getParentFile().delete();
146 }
147
148 assertFalse("The file should not exist", file.exists());
149
150 FileConfiguration config = new PropertiesConfiguration();
151 config.save(file);
152
153 assertTrue("The file doesn't exist", file.exists());
154 }
155
156 /***
157 * Tests collaboration with ConfigurationFactory: Is the base path set on
158 * loading is valid in file based configurations?
159 *
160 * @throws Exception if an error occurs
161 */
162 public void testWithConfigurationFactory() throws Exception
163 {
164 File dir = new File("conf");
165 File file = new File(dir, "testFileConfiguration.properties");
166
167 if (file.exists())
168 {
169 assertTrue("File cannot be deleted", file.delete());
170 }
171
172 try
173 {
174 ConfigurationFactory factory = new ConfigurationFactory();
175 factory.setConfigurationURL(new File(dir, "testDigesterConfiguration2.xml").toURL());
176 CompositeConfiguration cc = (CompositeConfiguration) factory.getConfiguration();
177 PropertiesConfiguration config = null;
178 for (int i = 0; config == null; i++)
179 {
180 if (cc.getConfiguration(i) instanceof PropertiesConfiguration)
181 {
182 config = (PropertiesConfiguration) cc.getConfiguration(i);
183 }
184 }
185
186 config.setProperty("test", "yes");
187 config.save(file.getName());
188 assertTrue(file.exists());
189 config = new PropertiesConfiguration();
190 config.setFile(file);
191 config.load();
192
193 assertEquals("yes", config.getProperty("test"));
194 assertEquals("masterOfPost", config.getProperty("mail.account.user"));
195 }
196 finally
197 {
198 if (file.exists())
199 {
200 assertTrue("File could not be deleted", file.delete());
201 }
202 }
203 }
204
205 /***
206 * Tests if invalid URLs cause an exception.
207 */
208 public void testSaveInvalidURL() throws Exception
209 {
210 FileConfiguration config = new PropertiesConfiguration();
211
212 try
213 {
214 config.save(new URL("http://jakarta.apache.org/test.properties"));
215 fail("Should throw a ConfigurationException!");
216 }
217 catch (ConfigurationException cex)
218 {
219
220 }
221
222 try
223 {
224 config.save("http://www.apache.org/test.properties");
225 fail("Should throw a ConfigurationException!");
226 }
227 catch (ConfigurationException cex)
228 {
229
230 }
231 }
232
233 /***
234 * Tests if the URL used by the load() method is also used by save().
235 */
236 public void testFileOverwrite() throws Exception
237 {
238 FileOutputStream out = null;
239 FileInputStream in = null;
240 File tempFile = null;
241 try
242 {
243 String path = System.getProperties().getProperty("user.home");
244 File homeDir = new File(path);
245 tempFile = File.createTempFile("CONF", null, homeDir);
246 String fileName = tempFile.getName();
247 Properties props = new Properties();
248 props.setProperty("1", "one");
249 out = new FileOutputStream(tempFile);
250 props.store(out, "TestFileOverwrite");
251 out.close();
252 out = null;
253 FileConfiguration config = new PropertiesConfiguration(fileName);
254 config.load();
255 String value = config.getString("1");
256 assertTrue("one".equals(value));
257 config.setProperty("1", "two");
258 config.save();
259 props = new Properties();
260 in = new FileInputStream(tempFile);
261 props.load(in);
262 String value2 = props.getProperty("1");
263 assertTrue("two".equals(value2));
264 }
265 finally
266 {
267 if (out != null)
268 {
269 try
270 {
271 out.close();
272 }
273 catch (IOException ioex)
274 {
275 ioex.printStackTrace();
276 }
277 }
278 if (in != null)
279 {
280 try
281 {
282 in.close();
283 }
284 catch (IOException ioex)
285 {
286 ioex.printStackTrace();
287 }
288 }
289 if (tempFile.exists())
290 {
291 assertTrue(tempFile.delete());
292 }
293 }
294 }
295
296 /***
297 * Tests setting a file changed reloading strategy together with the auto
298 * save feature.
299 */
300 public void testReloadingWithAutoSave() throws Exception
301 {
302 File configFile = new File(TARGET_DIR, TEST_FILENAME);
303 PrintWriter out = null;
304
305 try
306 {
307 out = new PrintWriter(new FileWriter(configFile));
308 out.println("a = one");
309 out.close();
310 out = null;
311
312 PropertiesConfiguration config = new PropertiesConfiguration(
313 configFile);
314 config.setReloadingStrategy(new FileChangedReloadingStrategy());
315 config.setAutoSave(true);
316
317 assertEquals("one", config.getProperty("a"));
318 config.setProperty("b", "two");
319 assertEquals("one", config.getProperty("a"));
320 }
321 finally
322 {
323 if (out != null)
324 {
325 out.close();
326 }
327 if (configFile.exists())
328 {
329 assertTrue(configFile.delete());
330 }
331 }
332 }
333
334 /***
335 * Tests loading and saving a configuration file with a complicated path
336 * name including spaces. (related to issue 35210)
337 */
338 public void testPathWithSpaces() throws Exception
339 {
340 File path = new File(TARGET_DIR, "path with spaces");
341 File confFile = new File(path, "config-test.properties");
342 PrintWriter out = null;
343
344 try
345 {
346 if (!path.exists())
347 {
348 assertTrue(path.mkdir());
349 }
350 out = new PrintWriter(new FileWriter(confFile));
351 out.println("saved = false");
352 out.close();
353 out = null;
354
355 URL url = new URL(TARGET_DIR.toURL()
356 + "path%20with%20spaces/config-test.properties");
357 PropertiesConfiguration config = new PropertiesConfiguration(url);
358 config.load();
359 assertFalse(config.getBoolean("saved"));
360
361 config.setProperty("saved", Boolean.TRUE);
362 config.save();
363 config = new PropertiesConfiguration();
364 config.setFile(confFile);
365 config.load();
366 assertTrue(config.getBoolean("saved"));
367 }
368 finally
369 {
370 if (out != null)
371 {
372 out.close();
373 }
374 if (confFile.exists())
375 {
376 assertTrue(confFile.delete());
377 }
378 if (path.exists())
379 {
380 assertTrue(path.delete());
381 }
382 }
383 }
384
385 /***
386 * Tests the getFile() method.
387 */
388 public void testGetFile() throws ConfigurationException
389 {
390 FileConfiguration config = new PropertiesConfiguration();
391 assertNull(config.getFile());
392 File file = TEST_FILE.getAbsoluteFile();
393 config.setFile(file);
394 assertEquals(file, config.getFile());
395 config.load();
396 assertEquals(file, config.getFile());
397 }
398
399 /***
400 * Tests whether getFile() returns a valid file after a configuration has
401 * been loaded.
402 */
403 public void testGetFileAfterLoad() throws ConfigurationException,
404 IOException
405 {
406 FileConfiguration config = new PropertiesConfiguration();
407 config.load(TEST_FILE.getAbsolutePath());
408 assertNotNull("No source URL set", config.getURL());
409 assertEquals("Wrong source file", TEST_FILE.getCanonicalFile(), config
410 .getFile().getCanonicalFile());
411 }
412
413 /***
414 * Tests whether calling load() multiple times changes the source. This
415 * should not be the case.
416 */
417 public void testLoadMultiple() throws ConfigurationException
418 {
419 FileConfiguration config = new PropertiesConfiguration();
420 config.load(TEST_FILE.getAbsolutePath());
421 URL srcUrl = config.getURL();
422 File srcFile = config.getFile();
423 File file2 = new File(TEST_DIR, "testEqual.properties");
424 config.load(file2.getAbsolutePath());
425 assertEquals("Source URL was changed", srcUrl, config.getURL());
426 assertEquals("Source file was changed", srcFile, config.getFile());
427 }
428
429 /***
430 * Tests to invoke save() without explicitly setting a file name. This
431 * will cause an exception.
432 */
433 public void testSaveWithoutFileName() throws Exception
434 {
435 FileConfiguration config = new PropertiesConfiguration();
436 File file = TEST_FILE;
437 config.load(file);
438 try
439 {
440 config.save();
441 fail("Could save config without setting a file name!");
442 }
443 catch(ConfigurationException cex)
444 {
445
446 }
447
448 config = new PropertiesConfiguration();
449 config.load(TEST_FILE);
450 try
451 {
452 config.save();
453 fail("Could save config without setting a file name!");
454 }
455 catch(ConfigurationException cex)
456 {
457
458 }
459
460 config = new PropertiesConfiguration();
461 config.load(file.toURL());
462 try
463 {
464 config.save();
465 fail("Could save config without setting a file name!");
466 }
467 catch(ConfigurationException cex)
468 {
469
470 }
471 }
472
473 /***
474 * Checks that loading a directory instead of a file throws an exception.
475 */
476 public void testLoadDirectory()
477 {
478 PropertiesConfiguration config = new PropertiesConfiguration();
479
480 try
481 {
482 config.load("target");
483 fail("Could load config from a directory!");
484 }
485 catch (ConfigurationException e)
486 {
487
488 }
489
490 try
491 {
492 config.load(new File("target"));
493 fail("Could load config from a directory!");
494 }
495 catch (ConfigurationException e)
496 {
497
498 }
499
500 try
501 {
502 new PropertiesConfiguration("target");
503 fail("Could load config from a directory!");
504 }
505 catch (ConfigurationException e)
506 {
507
508 }
509
510 try
511 {
512 new PropertiesConfiguration(new File("target"));
513 fail("Could load config from a directory!");
514 }
515 catch (ConfigurationException e)
516 {
517
518 }
519 }
520
521 /***
522 * Tests whether the constructor behaves the same as setFileName() when the
523 * configuration source is in the classpath.
524 */
525 public void testInitFromClassPath() throws ConfigurationException
526 {
527 PropertiesConfiguration config1 = new PropertiesConfiguration();
528 config1.setFileName(RESOURCE_NAME);
529 config1.load();
530 PropertiesConfiguration config2 = new PropertiesConfiguration(
531 RESOURCE_NAME);
532 compare(config1, config2);
533 }
534
535 /***
536 * Tests the loading of configuration file in a Combined configuration
537 * when the configuration source is in the classpath.
538 */
539 public void testLoadFromClassPath() throws ConfigurationException
540 {
541 DefaultConfigurationBuilder cf =
542 new DefaultConfigurationBuilder("conf/config/deep/testFileFromClasspath.xml");
543 CombinedConfiguration config = cf.getConfiguration(true);
544 Configuration config1 = config.getConfiguration("propConf");
545 Configuration config2 = config.getConfiguration("propConfDeep");
546 compare(config1, config2);
547 }
548
549 /***
550 * Tests cloning a file based configuration.
551 */
552 public void testClone() throws ConfigurationException
553 {
554 PropertiesConfiguration config = new PropertiesConfiguration(
555 RESOURCE_NAME);
556 PropertiesConfiguration copy = (PropertiesConfiguration) config.clone();
557 compare(config, copy);
558 assertNull("URL was not reset", copy.getURL());
559 assertNull("Base path was not reset", copy.getBasePath());
560 assertNull("File name was not reset", copy.getFileName());
561 assertNotSame("Reloading strategy was not reset", config
562 .getReloadingStrategy(), copy.getReloadingStrategy());
563 }
564
565 /***
566 * Tests whether an error log listener was registered at the configuration.
567 */
568 public void testLogErrorListener()
569 {
570 PropertiesConfiguration config = new PropertiesConfiguration();
571 assertEquals("No error log listener registered", 1, config
572 .getErrorListeners().size());
573 }
574
575 /***
576 * Tests handling of errors in the reload() method.
577 */
578 public void testReloadError() throws ConfigurationException
579 {
580 ConfigurationErrorListenerImpl l = new ConfigurationErrorListenerImpl();
581 PropertiesConfiguration config = new PropertiesConfiguration(
582 RESOURCE_NAME);
583 config.clearErrorListeners();
584 config.addErrorListener(l);
585 config.setReloadingStrategy(new FileAlwaysReloadingStrategy());
586 config.getString("test");
587 config.setFileName("Not existing file");
588 config.getString("test");
589 l.verify(AbstractFileConfiguration.EVENT_RELOAD, null, null);
590 assertNotNull("Exception is not set", l.getLastEvent().getCause());
591 }
592
593 /***
594 * Tests iterating over the keys of a non hierarchical file-based
595 * configuration while a reload happens. This test is related to
596 * CONFIGURATION-347.
597 */
598 public void testIterationWithReloadFlat() throws ConfigurationException
599 {
600 PropertiesConfiguration config = new PropertiesConfiguration(TEST_FILE);
601 checkIterationWithReload(config);
602 }
603
604 /***
605 * Tests iterating over the keys of a hierarchical file-based configuration
606 * while a reload happens. This test is related to CONFIGURATION-347.
607 */
608 public void testIterationWithReloadHierarchical()
609 throws ConfigurationException
610 {
611 XMLConfiguration config = new XMLConfiguration("test.xml");
612 checkIterationWithReload(config);
613 }
614
615 /***
616 * Helper method for testing an iteration over the keys of a file-based
617 * configuration while a reload happens.
618 *
619 * @param config the configuration to test
620 */
621 private void checkIterationWithReload(FileConfiguration config)
622 {
623 config.setReloadingStrategy(new FileAlwaysReloadingStrategy());
624 for (Iterator it = config.getKeys(); it.hasNext();)
625 {
626 String key = (String) it.next();
627 assertNotNull("No value for key " + key, config.getProperty(key));
628 }
629 }
630
631 /***
632 * Helper method for comparing the content of two configuration objects.
633 *
634 * @param config1 the first configuration
635 * @param config2 the second configuration
636 */
637 private void compare(Configuration config1, Configuration config2)
638 {
639 StrictConfigurationComparator cc = new StrictConfigurationComparator();
640 assertTrue("Configurations are different", cc.compare(config1, config2));
641 }
642 }