You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by rg...@apache.org on 2009/09/28 00:28:18 UTC
svn commit: r819418 [2/2] - in
/commons/proper/configuration/branches/CONFIGURATION_390: ./ conf/
src/java/org/apache/commons/configuration/
src/java/org/apache/commons/configuration/reloading/
src/test/org/apache/commons/configuration/ src/test/org/ap...
Modified: commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestCombinedConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestCombinedConfiguration.java?rev=819418&r1=819417&r2=819418&view=diff
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestCombinedConfiguration.java (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestCombinedConfiguration.java Sun Sep 27 22:28:16 2009
@@ -34,10 +34,13 @@
import org.apache.commons.configuration.event.ConfigurationEvent;
import org.apache.commons.configuration.event.ConfigurationListener;
import org.apache.commons.configuration.reloading.FileAlwaysReloadingStrategy;
+import org.apache.commons.configuration.reloading.FileRandomReloadingStrategy;
import org.apache.commons.configuration.tree.DefaultExpressionEngine;
import org.apache.commons.configuration.tree.NodeCombiner;
import org.apache.commons.configuration.tree.OverrideCombiner;
import org.apache.commons.configuration.tree.UnionCombiner;
+import org.apache.commons.configuration.tree.MergeCombiner;
+import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
/**
* Test class for CombinedConfiguration.
@@ -764,6 +767,75 @@
.getInt("xmlReload1"));
}
+ public void testConcurrentGetAndReload() throws Exception
+ {
+ final int threadCount = 5;
+ final int loopCount = 1000;
+ config.setForceReloadCheck(true);
+ config.setNodeCombiner(new MergeCombiner());
+ final XMLConfiguration xml = new XMLConfiguration("configA.xml");
+ xml.setReloadingStrategy(new FileRandomReloadingStrategy());
+ config.addConfiguration(xml);
+ final XMLConfiguration xml2 = new XMLConfiguration("configB.xml");
+ xml2.setReloadingStrategy(new FileRandomReloadingStrategy());
+ config.addConfiguration(xml2);
+ config.setExpressionEngine(new XPathExpressionEngine());
+
+ assertEquals(config.getString("/property[@name='config']/@value"), "100");
+
+ Thread testThreads[] = new Thread[threadCount];
+ int failures[] = new int[threadCount];
+
+ for (int i = 0; i < testThreads.length; ++i)
+ {
+ testThreads[i] = new ReloadThread(config, failures, i, loopCount);
+ testThreads[i].start();
+ }
+
+ int totalFailures = 0;
+ for (int i = 0; i < testThreads.length; ++i)
+ {
+ testThreads[i].join();
+ totalFailures += failures[i];
+ }
+ assertTrue(totalFailures + " failures Occurred", totalFailures == 0);
+ }
+
+ private class ReloadThread extends Thread
+ {
+ CombinedConfiguration combined;
+ int[] failures;
+ int index;
+ int count;
+
+ ReloadThread(CombinedConfiguration config, int[] failures, int index, int count)
+ {
+ combined = config;
+ this.failures = failures;
+ this.index = index;
+ this.count = count;
+ }
+ public void run()
+ {
+ failures[index] = 0;
+ for (int i = 0; i < count; i++)
+ {
+ try
+ {
+ String value = combined.getString("/property[@name='config']/@value");
+ if (value == null || !value.equals("100"))
+ {
+ ++failures[index];
+ }
+ }
+ catch (Exception ex)
+ {
+ ++failures[index];
+ }
+ }
+ }
+ }
+
/**
* Helper method for writing a file. The file is also added to a list and
* will be deleted in teadDown() automatically.
Modified: commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestMultiFileHierarchicalConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestMultiFileHierarchicalConfiguration.java?rev=819418&r1=819417&r2=819418&view=diff
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestMultiFileHierarchicalConfiguration.java (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestMultiFileHierarchicalConfiguration.java Sun Sep 27 22:28:16 2009
@@ -19,6 +19,9 @@
import junit.framework.TestCase;
import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
+import org.xml.sax.SAXParseException;
+
+import java.io.*;
/**
* Unit test for simple MultiConfigurationTest.
@@ -27,6 +30,15 @@
{
private static String PATTERN1 = "target/test-classes/testMultiConfiguration_${sys:Id}.xml";
+ private static final File MULTI_TENENT_FILE = new File(
+ "conf/testMultiTenentConfigurationBuilder2.xml");
+
+ private static final File MULTI_TENENT_FILE2 = new File(
+ "target/test-classes/testMultiTenentConfigurationBuilder2.xml");
+
+ private static final File MULTI_RELOAD_FILE = new File(
+ "conf/testMultiTenentConfigurationBuilder3.xml");
+
/**
* Rigourous Test :-)
*/
@@ -48,4 +60,238 @@
System.setProperty("Id", "1003");
assertTrue(config.getInt("rowsPerPage") == 35);
}
+
+ public void testSchemaValidationError() throws Exception
+ {
+ System.clearProperty("Id");
+ DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
+ factory.setFile(MULTI_TENENT_FILE);
+ CombinedConfiguration config = factory.getConfiguration(true);
+ try
+ {
+ System.setProperty("Id", "2001");
+ config.getInt("rowsPerPage");
+ fail("No exception thrown");
+ }
+ catch (Exception ex)
+ {
+ Throwable cause = ex.getCause();
+ while (cause != null && !(cause instanceof SAXParseException))
+ {
+ cause = cause.getCause();
+ }
+ assertTrue("SAXParseException was not thrown", cause instanceof SAXParseException);
+ }
+ }
+
+ public void testSchemaValidation() throws Exception
+ {
+ System.clearProperty("Id");
+ DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
+ factory.setFile(MULTI_TENENT_FILE);
+ CombinedConfiguration config = factory.getConfiguration(true);
+ System.setProperty("Id", "2002");
+ int rows = config.getInt("rowsPerPage");
+ assertTrue("expected: " + rows + " actual: " + "25", 25 == rows);
+ }
+
+ public void testMissingFile() throws Exception
+ {
+ System.clearProperty("Id");
+ DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
+ factory.setFile(MULTI_TENENT_FILE);
+ CombinedConfiguration config = factory.getConfiguration(true);
+ System.setProperty("Id", "3099");
+ int rows = config.getInt("rowsPerPage");
+ assertTrue("expected: " + rows + " actual: " + "50", 50 == rows);
+
+ }
+
+ public void testFileReload1() throws Exception
+ {
+ System.getProperties().remove("Id");
+ DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
+ factory.setFile(MULTI_RELOAD_FILE);
+ CombinedConfiguration config = factory.getConfiguration(true);
+
+ // create a new configuration
+ File input = new File("target/test-classes/testMultiConfiguration_3001.xml");
+ File output = new File("target/test-classes/testwrite/testMultiConfiguration_3001.xml");
+ output.delete();
+ output.getParentFile().mkdir();
+ copyFile(input, output);
+
+ assertNotNull(config);
+ verify("3001", config, 15);
+ Thread.sleep(1100);
+ XMLConfiguration x = new XMLConfiguration();
+ x.setFile(output);
+ x.setAttributeSplittingDisabled(true);
+ x.setDelimiterParsingDisabled(true);
+ x.load();
+ x.setProperty("rowsPerPage", "35");
+ //Insure orginal timestamp and new timestamp aren't the same second.
+ Thread.sleep(1100);
+ x.save();
+ verify("3001", config, 35);
+ output.delete();
+ }
+
+ public void testFileReload2() throws Exception
+ {
+ // create a new configuration
+ File input = new File("target/test-classes/testMultiConfiguration_3002.xml");
+ File output = new File("target/test-classes/testwrite/testMultiConfiguration_3002.xml");
+ output.delete();
+
+ System.getProperties().remove("Id");
+ DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
+ factory.setFile(MULTI_RELOAD_FILE);
+ CombinedConfiguration config = factory.getConfiguration(true);
+ assertNotNull(config);
+ // The file should not exist yet.
+ verify("3002", config, 50);
+
+ output.getParentFile().mkdir();
+ copyFile(input, output);
+ Thread.sleep(600);
+ verify("3002", config, 25);
+ output.delete();
+ }
+
+ public void testFileReload3() throws Exception
+ {
+ // create a new configuration
+ File input = new File("target/test-classes/testMultiConfiguration_3001.xml");
+ File output = new File("target/test-classes/testwrite/testMultiConfiguration_3001.xml");
+ output.delete();
+ output.getParentFile().mkdir();
+
+ System.getProperties().remove("Id");
+ DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
+ factory.setFile(MULTI_RELOAD_FILE);
+ CombinedConfiguration config = factory.getConfiguration(true);
+ assertNotNull(config);
+ //The file does not exist yet.
+ verify("3001", config, 50);
+ copyFile(input, output);
+ //Sleep so refreshDelay elapses
+ Thread.sleep(600);
+ verify("3001", config, 15);
+ Thread.sleep(500);
+ XMLConfiguration x = new XMLConfiguration();
+ x.setFile(output);
+ x.setAttributeSplittingDisabled(true);
+ x.setDelimiterParsingDisabled(true);
+ x.load();
+ x.setProperty("rowsPerPage", "35");
+ // Insure original timestamp and new timestamp are not the same second.
+ Thread.sleep(1100);
+ x.save();
+ verify("3001", config, 35);
+ output.delete();
+ }
+
+
+ public void testReloadDefault() throws Exception
+ {
+ // create a new configuration
+ String defaultName = "target/test-classes/testMultiConfiguration_default.xml";
+ File input = new File(defaultName);
+
+ System.getProperties().remove("Id");
+ DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
+ factory.setFile(MULTI_TENENT_FILE2);
+ CombinedConfiguration config = factory.getConfiguration(true);
+ assertNotNull(config);
+ verify("3001", config, 15);
+ verify("3002", config, 25);
+ System.setProperty("Id", "3002");
+ config.addProperty("/ TestProp", "Test");
+ assertTrue("Property not added", "Test".equals(config.getString("TestProp")));
+ System.getProperties().remove("Id");
+ //Sleep so refreshDelay elapses
+ Thread.sleep(600);
+ long time = System.currentTimeMillis();
+ long original = input.lastModified();
+ input.setLastModified(time);
+ File defaultFile = new File(defaultName);
+ long newTime = defaultFile.lastModified();
+ assertTrue("time mismatch", original != newTime);
+ Thread.sleep(600);
+ verify("3001", config, 15);
+ verify("3002", config, 25);
+ System.setProperty("Id", "3002");
+ String test = config.getString("TestProp");
+ assertNull("Property was not cleared by reload", test);
+ }
+
+
+ public void testFileReloadSchemaValidationError() throws Exception
+ {
+ System.getProperties().remove("Id");
+ DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
+ factory.setFile(MULTI_RELOAD_FILE);
+ CombinedConfiguration config = factory.getConfiguration(true);
+
+ // create a new configuration
+ File input = new File("target/test-classes/testMultiConfiguration_3001.xml");
+ File output = new File("target/test-classes/testwrite/testMultiConfiguration_3001.xml");
+ output.delete();
+ output.getParentFile().mkdir();
+ copyFile(input, output);
+
+ assertNotNull(config);
+ verify("3001", config, 15);
+ Thread.sleep(1100);
+ XMLConfiguration x = new XMLConfiguration();
+ x.setFile(output);
+ x.setAttributeSplittingDisabled(true);
+ x.setDelimiterParsingDisabled(true);
+ x.load();
+ x.setProperty("rowsPerPage", "test");
+ //Insure orginal timestamp and new timestamp aren't the same second.
+ Thread.sleep(1100);
+ x.save();
+ System.setProperty("Id", "3001");
+ try
+ {
+ config.getInt("rowsPerPage");
+ fail("No exception was thrown");
+ }
+ catch (Exception ex)
+ {
+
+ }
+
+ output.delete();
+ }
+
+ private void copyFile(File input, File output) throws IOException
+ {
+ Reader reader = new FileReader(input);
+ Writer writer = new FileWriter(output);
+ char[] buffer = new char[4096];
+ int n = 0;
+ while (-1 != (n = reader.read(buffer)))
+ {
+ writer.write(buffer, 0, n);
+ }
+ reader.close();
+ writer.close();
+ }
+
+ private void verify(String key, CombinedConfiguration config, int rows)
+ {
+ if (key == null)
+ {
+ System.getProperties().remove("Id");
+ }
+ else
+ {
+ System.setProperty("Id", key);
+ }
+ int actual = config.getInt("rowsPerPage");
+ assertTrue("expected: " + rows + " actual: " + actual, actual == rows);
+ }
}
Modified: commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestVFSConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestVFSConfigurationBuilder.java?rev=819418&r1=819417&r2=819418&view=diff
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestVFSConfigurationBuilder.java (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestVFSConfigurationBuilder.java Sun Sep 27 22:28:16 2009
@@ -31,7 +31,6 @@
import org.apache.commons.configuration.beanutils.BeanHelper;
import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
-import org.apache.commons.configuration.reloading.VFSFileMonitorReloadingStrategy;
import org.apache.commons.configuration.tree.DefaultConfigurationNode;
import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
import org.apache.commons.configuration.event.ConfigurationListener;
@@ -91,14 +90,17 @@
private static final File FILESYSTEM_FILE = new File(
"conf/testFileSystem.xml");
- private static final File FILEMONITOR_FILE = new File(
- "target/test-classes/testFileMonitorConfigurationBuilder.xml");
+ private static final File FILERELOAD_FILE = new File(
+ "target/test-classes/testFileReloadConfigurationBuilder.xml");
- private static final File FILEMONITOR2_FILE = new File(
- "target/test-classes/testFileMonitorConfigurationBuilder2.xml");
+ private static final File FILERELOAD2_FILE = new File(
+ "target/test-classes/testFileReloadConfigurationBuilder2.xml");
- private static final String FILEMONITOR_URI = "file://" + System.getProperty("user.dir")
- + "/target/test-classes/testFileMonitorConfigurationBuilder2.xml";
+ private static final File MULTI_RELOAD_FILE1 = new File(
+ "target/test-classes/testVFSMultiTenentConfigurationBuilder1.xml");
+
+ private static final File MULTI_RELOAD_FILE2 = new File(
+ "target/test-classes/testVFSMultiTenentConfigurationBuilder2.xml");
/** Constant for the name of an optional configuration.*/
private static final String OPTIONAL_NAME = "optionalConfig";
@@ -109,12 +111,6 @@
/** Stores the object to be tested. */
DefaultConfigurationBuilder factory;
- public TestVFSConfigurationBuilder()
- {
- super();
- VFSFileMonitorReloadingStrategy.stopMonitor();
- }
-
protected void setUp() throws Exception
{
super.setUp();
@@ -1005,7 +1001,7 @@
}
}
- public void testFileMonitor1() throws Exception
+ public void testFileReload1() throws Exception
{
// create a new configuration
File input = new File("target/test-classes/testMultiConfiguration_1001.xml");
@@ -1013,116 +1009,147 @@
output.delete();
output.getParentFile().mkdir();
copyFile(input, output);
+ // Sleep to make sure the file timestamp is not in the same second as "now".
+ Thread.sleep(1100);
- factory.setFile(FILEMONITOR_FILE);
+ factory.setFile(FILERELOAD_FILE);
FileSystem.resetDefaultFileSystem();
System.getProperties().remove("Id");
CombinedConfiguration config = factory.getConfiguration(true);
assertNotNull(config);
- config.addConfigurationListener(this);
verify("1001", config, 15);
-
- // Allow time for FileMonitor to set up.
- Thread.sleep(1000);
XMLConfiguration x = new XMLConfiguration(output);
x.setProperty("rowsPerPage", "50");
x.save();
-
- waitForChange();
verify("1001", config, 50);
output.delete();
- VFSFileMonitorReloadingStrategy.stopMonitor();
}
- public void testFileMonitor2() throws Exception
+ public void testFileReload2() throws Exception
{
// create a new configuration
File input = new File("target/test-classes/testMultiConfiguration_1002.xml");
File output = new File("target/test-classes/testwrite/testMultiConfiguration_1002.xml");
output.delete();
- factory.setFile(FILEMONITOR_FILE);
+ factory.setFile(FILERELOAD_FILE);
FileSystem.resetDefaultFileSystem();
System.getProperties().remove("Id");
CombinedConfiguration config = factory.getConfiguration(true);
- config.addConfigurationListener(this);
assertNotNull(config);
verify("1002", config, 50);
- Thread.sleep(1000);
-
+ // Sleep to make sure the file timestamp is not in the same second as "now".
+ Thread.sleep(1100);
output.getParentFile().mkdir();
copyFile(input, output);
-
- // Allow time for the monitor to notice the change.
- //Thread.sleep(2000);
- waitForChange();
verify("1002", config, 25);
output.delete();
- VFSFileMonitorReloadingStrategy.stopMonitor();
}
-
- public void testFileMonitor3() throws Exception
+ public void testFileReload3() throws Exception
{
// create a new configuration
File input = new File("target/test-classes/testMultiConfiguration_1001.xml");
File output = new File("target/test-classes/testwrite/testMultiConfiguration_1001.xml");
output.delete();
output.getParentFile().mkdir();
- copyFile(input, output);
- factory.setFile(FILEMONITOR2_FILE);
+ factory.setFile(FILERELOAD_FILE);
+ FileSystem.resetDefaultFileSystem();
System.getProperties().remove("Id");
CombinedConfiguration config = factory.getConfiguration(true);
assertNotNull(config);
- config.addConfigurationListener(this);
+ verify("1001", config, 50);
+ copyFile(input, output);
+ // Sleep to make sure the file timestamp is not in the same second as "now".
+ Thread.sleep(1100);
verify("1001", config, 15);
-
- // Allow time for FileMonitor to set up.
- Thread.sleep(1000);
XMLConfiguration x = new XMLConfiguration(output);
- x.setProperty("rowsPerPage", "50");
+ x.setProperty("rowsPerPage", "25");
x.save();
- // Let FileMonitor detect the change.
- //Thread.sleep(2000);
- waitForChange();
- verify("1001", config, 50);
+ // Sleep to make sure the file timestamp is not in the same second as "now".
+ Thread.sleep(1100);
+ verify("1001", config, 25);
output.delete();
- VFSFileMonitorReloadingStrategy.stopMonitor();
}
- public void testFileMonitor4() throws Exception
+ public void testReloadDefault() throws Exception
{
// create a new configuration
- File input = new File("target/test-classes/testMultiConfiguration_1002.xml");
- File output = new File("target/test-classes/testwrite/testMultiConfiguration_1002.xml");
- output.delete();
+ String defaultName = "target/test-classes/testMultiConfiguration_default.xml";
+ File input = new File(defaultName);
- factory.setFileName(FILEMONITOR_URI);
System.getProperties().remove("Id");
-
+ factory.setFile(MULTI_RELOAD_FILE1);
CombinedConfiguration config = factory.getConfiguration(true);
assertNotNull(config);
- config.addConfigurationListener(this);
+ verify("3001", config, 15);
+ verify("3002", config, 25);
+ System.setProperty("Id", "3002");
+ config.addProperty("/ TestProp", "Test");
+ assertTrue("Property not added", "Test".equals(config.getString("TestProp")));
+ System.getProperties().remove("Id");
+ //Sleep so refreshDelay elapses
+ Thread.sleep(600);
+ long time = System.currentTimeMillis();
+ long original = input.lastModified();
+ input.setLastModified(time);
+ File defaultFile = new File(defaultName);
+ long newTime = defaultFile.lastModified();
+ assertTrue("time mismatch", original != newTime);
+ Thread.sleep(600);
+ verify("3001", config, 15);
+ verify("3002", config, 25);
+ System.setProperty("Id", "3002");
+ String test = config.getString("TestProp");
+ assertNull("Property was not cleared by reload", test);
+ }
- verify("1002", config, 50);
- Thread.sleep(1000);
+ public void testFileReloadSchemaValidationError() throws Exception
+ {
+ System.getProperties().remove("Id");
+ factory.setFile(MULTI_RELOAD_FILE2);
+ CombinedConfiguration config = factory.getConfiguration(true);
+
+ // create a new configuration
+ File input = new File("target/test-classes/testMultiConfiguration_3001.xml");
+ File output = new File("target/test-classes/testwrite/testMultiConfiguration_3001.xml");
+ output.delete();
output.getParentFile().mkdir();
copyFile(input, output);
- // Allow time for the monitor to notice the change.
- //Thread.sleep(2000);
- waitForChange();
- verify("1002", config, 25);
+ assertNotNull(config);
+ verify("3001", config, 15);
+ Thread.sleep(1100);
+ XMLConfiguration x = new XMLConfiguration();
+ x.setFile(output);
+ x.setAttributeSplittingDisabled(true);
+ x.setDelimiterParsingDisabled(true);
+ x.load();
+ x.setProperty("rowsPerPage", "test");
+ //Insure orginal timestamp and new timestamp aren't the same second.
+ Thread.sleep(1100);
+ x.save();
+ System.setProperty("Id", "3001");
+ try
+ {
+ config.getInt("rowsPerPage");
+ fail("No exception was thrown");
+ }
+ catch (Exception ex)
+ {
+
+ }
+
output.delete();
- VFSFileMonitorReloadingStrategy.stopMonitor();
}
+
private void copyFile(File input, File output) throws IOException
{
Reader reader = new FileReader(input);
@@ -1161,7 +1188,11 @@
int count = 0;
while (!configChanged && count++ <= 3)
{
- this.wait(5000);
+ this.wait(2000);
+ }
+ if (!configChanged)
+ {
+ throw new IllegalStateException("No change detected");
}
}
catch (InterruptedException ie)
Modified: commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestWebdavConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestWebdavConfigurationBuilder.java?rev=819418&r1=819417&r2=819418&view=diff
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestWebdavConfigurationBuilder.java (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestWebdavConfigurationBuilder.java Sun Sep 27 22:28:16 2009
@@ -21,7 +21,6 @@
import java.io.Reader;
import java.io.FileReader;
import java.io.Writer;
-import java.io.FileWriter;
import java.io.OutputStreamWriter;
import java.util.Collection;
import java.util.HashMap;
@@ -32,7 +31,6 @@
import org.apache.commons.configuration.beanutils.BeanHelper;
import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
-import org.apache.commons.configuration.reloading.VFSFileMonitorReloadingStrategy;
import org.apache.commons.configuration.tree.DefaultConfigurationNode;
import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
import org.apache.commons.configuration.event.ConfigurationEvent;
@@ -42,7 +40,6 @@
import org.apache.commons.vfs.VFS;
import org.apache.commons.vfs.FileName;
import org.apache.commons.vfs.FileSystemOptions;
-import org.apache.commons.vfs.FileContent;
/**
* Test class for DefaultConfigurationBuilder.
@@ -93,13 +90,13 @@
private static final String MULTI_TENENT_FILE =
"testMultiTenentConfigurationBuilder.xml";
- private static final String FILEMONITOR2_FILE =
- "testFileMonitorConfigurationBuilder2.xml";
+ private static final String FILERELOAD2_FILE =
+ "testFileReloadConfigurationBuilder2.xml";
- private static final String FILEMONITOR_1001_FILE =
+ private static final String FILERELOAD_1001_FILE =
"testwrite/testMultiConfiguration_1001.xml";
- private static final String FILEMONITOR_1002_FILE =
+ private static final String FILERELOAD_1002_FILE =
"testwrite/testMultiConfiguration_1002.xml";
private static final String TEST_PROPERTIES = "test.properties.xml";
@@ -900,16 +897,16 @@
verify("1005", config, 50);
}
- public void testFileMonitor1() throws Exception
+ public void testFileChanged() throws Exception
{
// create a new configuration
File input = new File("target/test-classes/testMultiConfiguration_1001.xml");
- FileObject output = getFile(getBasePath() + FILEMONITOR_1001_FILE);
+ FileObject output = getFile(getBasePath() + FILERELOAD_1001_FILE);
output.delete();
output.getParent().createFolder();
copyFile(input, output);
- factory.setFileName(getBasePath() + FILEMONITOR2_FILE);
+ factory.setFileName(getBasePath() + FILERELOAD2_FILE);
System.getProperties().remove("Id");
CombinedConfiguration config = factory.getConfiguration(true);
@@ -919,7 +916,7 @@
// Allow time for FileMonitor to set up.
Thread.sleep(1000);
- XMLConfiguration x = new XMLConfiguration(getBasePath() + FILEMONITOR_1001_FILE);
+ XMLConfiguration x = new XMLConfiguration(getBasePath() + FILERELOAD_1001_FILE);
x.setProperty("rowsPerPage", "50");
x.save();
// Let FileMonitor detect the change.
@@ -927,17 +924,16 @@
waitForChange();
verify("1001", config, 50);
output.delete();
- VFSFileMonitorReloadingStrategy.stopMonitor();
}
- public void testFileMonitor2() throws Exception
+ public void testFileChanged2() throws Exception
{
// create a new configuration
File input = new File("target/test-classes/testMultiConfiguration_1002.xml");
- FileObject output = getFile(getBasePath() + FILEMONITOR_1002_FILE);
+ FileObject output = getFile(getBasePath() + FILERELOAD_1002_FILE);
output.delete();
- factory.setFileName(getBasePath() + FILEMONITOR2_FILE);
+ factory.setFileName(getBasePath() + FILERELOAD2_FILE);
System.getProperties().remove("Id");
CombinedConfiguration config = factory.getConfiguration(true);
@@ -955,7 +951,6 @@
waitForChange();
verify("1002", config, 25);
output.delete();
- VFSFileMonitorReloadingStrategy.stopMonitor();
}
Modified: commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestXMLConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestXMLConfiguration.java?rev=819418&r1=819417&r2=819418&view=diff
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestXMLConfiguration.java (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestXMLConfiguration.java Sun Sep 27 22:28:16 2009
@@ -1597,6 +1597,50 @@
}
}
+ public void testConcurrentGetAndReload() throws Exception
+ {
+ //final FileConfiguration config = new PropertiesConfiguration("test.properties");
+ final FileConfiguration config = new XMLConfiguration("test.xml");
+ config.setReloadingStrategy(new FileAlwaysReloadingStrategy());
+
+ assertTrue("Property not found", config.getProperty("test.short") != null);
+
+ Thread testThreads[] = new Thread[5];
+
+ for (int i = 0; i < testThreads.length; ++i)
+ {
+ testThreads[i] = new ReloadThread(config);
+ testThreads[i].start();
+ }
+
+ for (int i = 0; i < 2000; i++)
+ {
+ assertTrue("Property not found", config.getProperty("test.short") != null);
+ }
+
+ for (int i = 0; i < testThreads.length; ++i)
+ {
+ testThreads[i].join();
+ }
+ }
+
+ private class ReloadThread extends Thread
+ {
+ FileConfiguration config;
+
+ ReloadThread(FileConfiguration config)
+ {
+ this.config = config;
+ }
+ public void run()
+ {
+ for (int i = 0; i < 1000; i++)
+ {
+ config.reload();
+ }
+ }
+ }
+
/**
* Prepares a configuration object for testing a reload operation.
*
Added: commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/reloading/FileRandomReloadingStrategy.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/reloading/FileRandomReloadingStrategy.java?rev=819418&view=auto
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/reloading/FileRandomReloadingStrategy.java (added)
+++ commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/reloading/FileRandomReloadingStrategy.java Sun Sep 27 22:28:16 2009
@@ -0,0 +1,31 @@
+package org.apache.commons.configuration.reloading;
+
+import java.io.File;
+import java.util.Random;
+
+/**
+ * A ReloadingStrategy that randomly returns true or false;
+ */
+public class FileRandomReloadingStrategy extends FileChangedReloadingStrategy
+{
+ Random random = new Random();
+ /**
+ * Checks whether a reload is necessary.
+ *
+ * @return a flag whether a reload is required
+ */
+ public boolean reloadingRequired()
+ {
+ return random.nextBoolean();
+ }
+
+ /**
+ * Returns the file that is watched by this strategy.
+ *
+ * @return the monitored file
+ */
+ public File getMonitoredFile()
+ {
+ return getFile();
+ }
+}
Modified: commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/reloading/TestFileChangedReloadingStrategy.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/reloading/TestFileChangedReloadingStrategy.java?rev=819418&r1=819417&r2=819418&view=diff
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/reloading/TestFileChangedReloadingStrategy.java (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/reloading/TestFileChangedReloadingStrategy.java Sun Sep 27 22:28:16 2009
@@ -19,6 +19,7 @@
import java.io.File;
import java.io.FileWriter;
+import java.io.ByteArrayOutputStream;
import java.net.URL;
import junit.framework.TestCase;
@@ -26,6 +27,12 @@
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.configuration.XMLConfiguration;
+import org.apache.log4j.Logger;
+import org.apache.log4j.Layout;
+import org.apache.log4j.PatternLayout;
+import org.apache.log4j.Appender;
+import org.apache.log4j.WriterAppender;
+import org.apache.log4j.Level;
/**
* Test case for the ReloadableConfiguration class.
@@ -163,4 +170,46 @@
strategy.reloadingPerformed();
assertFalse("Reloading still required", strategy.reloadingRequired());
}
+
+ public void testFileDeletion() throws Exception
+ {
+ Logger logger = Logger.getLogger(FileChangedReloadingStrategy.class.getName());
+ Layout layout = new PatternLayout("%p - %m%n");
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ Appender appender = new WriterAppender(layout, os);
+ logger.addAppender(appender);
+ logger.setLevel(Level.WARN);
+ logger.setAdditivity(false);
+ // create a new configuration
+ File file = new File("target/testReload.properties");
+
+ if (file.exists())
+ {
+ file.delete();
+ }
+
+ // create the configuration file
+ FileWriter out = new FileWriter(file);
+ out.write("string=value1");
+ out.flush();
+ out.close();
+
+ // load the configuration
+ PropertiesConfiguration config = new PropertiesConfiguration("target/testReload.properties");
+ FileChangedReloadingStrategy strategy = new FileChangedReloadingStrategy();
+ strategy.setRefreshDelay(500);
+ config.setReloadingStrategy(strategy);
+ assertEquals("Initial value", "value1", config.getString("string"));
+
+ Thread.sleep(2000);
+
+ // Delete the file.
+ file.delete();
+ //Old value should still be returned.
+ assertEquals("Initial value", "value1", config.getString("string"));
+ logger.removeAppender(appender);
+ String str = os.toString();
+ //System.out.println(str);
+ assertTrue("No error was logged", str != null && str.length() > 0);
+ }
}
Copied: commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/reloading/TestVFSFileChangedReloadingStrategy.java (from r805888, commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/reloading/TestVFSFileMonitorReloadingStrategy.java)
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/reloading/TestVFSFileChangedReloadingStrategy.java?p2=commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/reloading/TestVFSFileChangedReloadingStrategy.java&p1=commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/reloading/TestVFSFileMonitorReloadingStrategy.java&r1=805888&r2=819418&rev=819418&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/reloading/TestVFSFileMonitorReloadingStrategy.java (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/reloading/TestVFSFileChangedReloadingStrategy.java Sun Sep 27 22:28:16 2009
@@ -38,11 +38,10 @@
* @author Ralph Goers
* @version $Revision$
*/
-public class TestVFSFileMonitorReloadingStrategy extends TestCase
- implements ConfigurationListener
+public class TestVFSFileChangedReloadingStrategy extends TestCase
{
- /** true when a file is changed */
- private boolean configChanged = false;
+ /** Constant for the name of a test properties file.*/
+ private static final String TEST_FILE = "test.properties";
protected void setUp() throws Exception
{
@@ -74,12 +73,12 @@
// load the configuration
PropertiesConfiguration config = new PropertiesConfiguration("target/testReload.properties");
- VFSFileMonitorReloadingStrategy strategy = new VFSFileMonitorReloadingStrategy();
- strategy.setDelay(500);
+ VFSFileChangedReloadingStrategy strategy = new VFSFileChangedReloadingStrategy();
+ strategy.setRefreshDelay(500);
config.setReloadingStrategy(strategy);
assertEquals("Initial value", "value1", config.getString("string"));
- Thread.sleep(1000);
+ Thread.sleep(2000);
// change the file
out = new FileWriter(file);
@@ -87,15 +86,8 @@
out.flush();
out.close();
- Thread.sleep(2000);
-
// test the automatic reloading
assertEquals("Modified value with enabled reloading", "value2", config.getString("string"));
- strategy.stopMonitor();
- if (file.exists())
- {
- file.delete();
- }
}
public void testNewFileReloading() throws Exception
@@ -110,9 +102,8 @@
PropertiesConfiguration config = new PropertiesConfiguration();
config.setFile(file);
- config.addConfigurationListener(this);
- VFSFileMonitorReloadingStrategy strategy = new VFSFileMonitorReloadingStrategy();
- strategy.setDelay(500);
+ VFSFileChangedReloadingStrategy strategy = new VFSFileChangedReloadingStrategy();
+ strategy.setRefreshDelay(500);
config.setReloadingStrategy(strategy);
assertNull("Initial value", config.getString("string"));
@@ -123,106 +114,40 @@
out.flush();
out.close();
- waitForChange();
+ Thread.sleep(2000);
// test the automatic reloading
- try
- {
- assertEquals("Modified value with enabled reloading", "value1", config.getString("string"));
- }
- finally
- {
- strategy.stopMonitor();
- if (file.exists())
- {
- file.delete();
- }
- }
+ assertEquals("Modified value with enabled reloading", "value1", config.getString("string"));
}
public void testGetRefreshDelay() throws Exception
{
- // create a new configuration
- File file = new File("target/testReload.properties");
-
- if (file.exists())
- {
- file.delete();
- }
-
- // create the configuration file
- FileWriter out = new FileWriter(file);
- out.write("string=value1");
- out.flush();
- out.close();
-
- PropertiesConfiguration config = new PropertiesConfiguration("target/testReload.properties");
- VFSFileMonitorReloadingStrategy strategy = new VFSFileMonitorReloadingStrategy();
- strategy.setDelay(500);
- config.setReloadingStrategy(strategy);
- // Minimum is 1 second.
- assertEquals("refresh delay", 1000, strategy.getDelay());
-
- config = new PropertiesConfiguration("target/testReload.properties");
- strategy = new VFSFileMonitorReloadingStrategy();
- strategy.setDelay(1500);
- config.setReloadingStrategy(strategy);
- // Can be made longer
- assertEquals("refresh delay", 1500, strategy.getDelay());
-
- config = new PropertiesConfiguration("target/testReload.properties");
- strategy = new VFSFileMonitorReloadingStrategy();
- strategy.setDelay(500);
- config.setReloadingStrategy(strategy);
- // Can't be made shorter
- assertEquals("refresh delay", 1500, strategy.getDelay());
-
- strategy.stopMonitor();
- // Reset and verify everything clears
- config = new PropertiesConfiguration("target/testReload.properties");
- strategy = new VFSFileMonitorReloadingStrategy();
- strategy.setDelay(1100);
- config.setReloadingStrategy(strategy);
- assertEquals("refresh delay", 1100, strategy.getDelay());
- strategy.stopMonitor();
- if (file.exists())
- {
- file.delete();
- }
- }
-
- private void waitForChange()
- {
- synchronized(this)
- {
- try
- {
- int count = 0;
- while (!configChanged && count++ <= 3)
- {
- this.wait(5000);
- }
- }
- catch (InterruptedException ie)
- {
- throw new IllegalStateException("wait timed out");
- }
- finally
- {
- configChanged = false;
- }
- }
+ VFSFileChangedReloadingStrategy strategy = new VFSFileChangedReloadingStrategy();
+ strategy.setRefreshDelay(500);
+ assertEquals("refresh delay", 500, strategy.getRefreshDelay());
}
- public void configurationChanged(ConfigurationEvent event)
+ /**
+ * Tests calling reloadingRequired() multiple times before a reload actually
+ * happens. This test is related to CONFIGURATION-302.
+ */
+ public void testReloadingRequiredMultipleTimes()
+ throws ConfigurationException
{
- if (event.getType() == AbstractFileConfiguration.EVENT_CONFIG_CHANGED)
+ VFSFileChangedReloadingStrategy strategy = new VFSFileChangedReloadingStrategy()
{
- synchronized(this)
+ protected boolean hasChanged()
{
- configChanged = true;
- this.notify();
+ // signal always a change
+ return true;
}
- }
+ };
+ strategy.setRefreshDelay(100000);
+ PropertiesConfiguration config = new PropertiesConfiguration(TEST_FILE);
+ config.setReloadingStrategy(strategy);
+ assertTrue("Reloading not required", strategy.reloadingRequired());
+ assertTrue("Reloading no more required", strategy.reloadingRequired());
+ strategy.reloadingPerformed();
+ assertFalse("Reloading still required", strategy.reloadingRequired());
}
}
\ No newline at end of file
Modified: commons/proper/configuration/branches/CONFIGURATION_390/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/xdocs/changes.xml?rev=819418&r1=819417&r2=819418&view=diff
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/xdocs/changes.xml (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/xdocs/changes.xml Sun Sep 27 22:28:16 2009
@@ -23,6 +23,13 @@
<body>
<release version="1.7" date="in SVN" description="">
+ <action dev="rgoers" type="fix" issue="CONFIGURATION-397">
+ Schema violation exceptions are now propagated back to the caller.
+ </action>
+ <action dev="rgoers" type="fix" issue="CONFIGURATION-390">
+ XMLConfiguration and CombinedConfiguraton are now synchronized to fix problems
+ caused by reloading in a multithreaded environment.
+ </action>
<action dev="oheger" type="fix" issue="CONFIGURATION-396">
HierarchicalConfiguration.NodeVisitor is now passed the correct key to
its visitAfterChildren() method.
Modified: commons/proper/configuration/branches/CONFIGURATION_390/xdocs/userguide/howto_filesystems.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/xdocs/userguide/howto_filesystems.xml?rev=819418&r1=819417&r2=819418&view=diff
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/xdocs/userguide/howto_filesystems.xml (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/xdocs/userguide/howto_filesystems.xml Sun Sep 27 22:28:16 2009
@@ -77,7 +77,7 @@
</xml>
</override>
</configuration>
-]]></source>
+]]></source>
</subsection>
<subsection name="File Options Provider">
<p>
@@ -95,15 +95,11 @@
</subsection>
<subsection name="File Reloading Strategy">
<p>
- The <code><a href="../apidocs/org/apache/commons/configuration/reloading/VFSFileMonitorReloadingStrategy.html">VFSFileMonitorReloadingStrategy</a></code>
+ The <code><a href="../apidocs/org/apache/commons/configuration/reloading/VFSFileChangedReloadingStrategy.html">VFSFileChangedReloadingStrategy</a></code>
can be used to cause Configurations accessed via the <code>VFSFileSystem</code> to be
monitored and reloaded when the files are modified. The example below shows how
<code>DefaultConfigurationBuilder</code> can be configured to use
- <code>VFSFileMonitorReloadingStrategy</code>. While each declaration will result in
- a new reloading strategy object, each instance will share a common <code>FileMonitor</code>.
- The delay setting controls how often the <code>FileMonitor</code> checks for changes
- and since there is only a single <code>FileMonitor</code>, only the largest value
- specified on any <code>VFSFileMonitorReloadingStrategy</code> is used.
+ <code>VFSFilChangedReloadingStrategy</code>.
In the example below both test.properties and settings.xml would be checked for changes
once per minute.
</p>
@@ -117,12 +113,12 @@
</header>
<override>
<properties fileName="test.properties" throwExceptionOnMissing="true">
- <reloadingStrategy delay="60000"
- config-class="org.apache.commons.configuration.reloading.VFSFileMonitorReloadingStrategy"/>
+ <reloadingStrategy refreshDelay="60000"
+ config-class="org.apache.commons.configuration.reloading.VFSFileChangedReloadingStrategy"/>
</properties>
<xml fileName="settings.xml" config-name="xml">
- <reloadingStrategy
- config-class="org.apache.commons.configuration.reloading.VFSFileMonitorReloadingStrategy"/>
+ <reloadingStrategy refreshDelay="60000"
+ config-class="org.apache.commons.configuration.reloading.VFSFileChangedReloadingStrategy"/>
</xml>
</override>
</configuration>
Modified: commons/proper/configuration/branches/CONFIGURATION_390/xdocs/userguide/howto_multitenant.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/xdocs/userguide/howto_multitenant.xml?rev=819418&r1=819417&r2=819418&view=diff
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/xdocs/userguide/howto_multitenant.xml (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/xdocs/userguide/howto_multitenant.xml Sun Sep 27 22:28:16 2009
@@ -54,6 +54,14 @@
ReloadingStrategy and listeners will be propogated to each of the
created configurations.
</p>
+ <p>
+ When used in a combined configuration it is often acceptable for a file
+ matching a particular pattern to be missing so, by default, most exceptions
+ encountered when loading files are ignored. To change this behavior
+ call setIgnoreException(false) or configure the attribute to false in
+ DefaultConfigurationBuilder's configuration file. If schema validation
+ is enabled validation exceptions will always cause a failure.
+ </p>
</subsection>
<subsection name="DynamicCombinedConfiguration">
<p>