You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by oh...@apache.org on 2013/04/02 21:08:46 UTC
svn commit: r1463692 - in /commons/proper/configuration/trunk/src:
main/java/org/apache/commons/configuration/builder/combined/
test/java/org/apache/commons/configuration/
test/java/org/apache/commons/configuration/builder/combined/
Author: oheger
Date: Tue Apr 2 19:08:45 2013
New Revision: 1463692
URL: http://svn.apache.org/r1463692
Log:
Reworked test cases for reloading of combined configurations.
Because reloading is now handled by builders, tests related to reloading of
combined configurations have been removed from TestCombinedConfiguration.
A new test class has been added with corresponding tests for
ReloadingCombinedConfigurationBuilder.
Added:
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestReloadingCombinedConfigurationBuilderFileBased.java
Modified:
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/ReloadingCombinedConfigurationBuilder.java
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestCombinedConfiguration.java
Modified: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/ReloadingCombinedConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/ReloadingCombinedConfigurationBuilder.java?rev=1463692&r1=1463691&r2=1463692&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/ReloadingCombinedConfigurationBuilder.java (original)
+++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/ReloadingCombinedConfigurationBuilder.java Tue Apr 2 19:08:45 2013
@@ -160,7 +160,10 @@ public class ReloadingCombinedConfigurat
obtainReloadingController(subControllers, b);
}
- return new CombinedReloadingController(subControllers);
+ CombinedReloadingController ctrl =
+ new CombinedReloadingController(subControllers);
+ ctrl.resetInitialReloadingState();
+ return ctrl;
}
/**
Modified: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestCombinedConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestCombinedConfiguration.java?rev=1463692&r1=1463691&r2=1463692&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestCombinedConfiguration.java (original)
+++ commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestCombinedConfiguration.java Tue Apr 2 19:08:45 2013
@@ -30,7 +30,6 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
-import java.text.MessageFormat;
import java.util.Collection;
import java.util.List;
import java.util.Set;
@@ -39,14 +38,10 @@ import junit.framework.Assert;
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.MergeCombiner;
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.xpath.XPathExpressionEngine;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -71,12 +66,6 @@ public class TestCombinedConfiguration
/** Constant for the name of the second child configuration.*/
private static final String CHILD2 = TEST_NAME + "2";
- /** Constant for the name of the XML reload test file.*/
- private static final String RELOAD_XML_NAME = "reload.xml";
-
- /** Constant for the content of a XML reload test file.*/
- private static final String RELOAD_XML_CONTENT = "<xml><xmlReload>{0}</xmlReload></xml>";
-
/** Helper object for managing temporary files. */
@Rule
public TemporaryFolder folder = new TemporaryFolder();
@@ -445,26 +434,6 @@ public class TestCombinedConfiguration
}
/**
- * Tests whether the reload check works with a subnode configuration. This
- * test is related to CONFIGURATION-341.
- */
- @Test
- public void testReloadingSubnodeConfig() throws IOException,
- ConfigurationException
- {
- config.setForceReloadCheck(true);
- File testXmlFile = writeReloadFile(RELOAD_XML_NAME, RELOAD_XML_CONTENT,
- 0);
- XMLConfiguration c1 = new XMLConfiguration(testXmlFile);
- c1.setReloadingStrategy(new FileAlwaysReloadingStrategy());
- final String prefix = "reloadCheck";
- config.addConfiguration(c1, CHILD1, prefix);
- SubnodeConfiguration sub = config.configurationAt(prefix, true);
- writeReloadFile(RELOAD_XML_NAME, RELOAD_XML_CONTENT, 1);
- assertEquals("Reload not detected", 1, sub.getInt("xmlReload"));
- }
-
- /**
* Prepares a test of the getSource() method.
*/
private void setUpSourceTest()
@@ -645,68 +614,6 @@ public class TestCombinedConfiguration
}
/**
- * Tests whether changes on a sub node configuration that is part of a
- * combined configuration are detected. This test is related to
- * CONFIGURATION-368.
- */
- @Test
- public void testReloadWithSubNodeConfig() throws Exception
- {
- final String reloadContent = "<config><default><xmlReload1>{0}</xmlReload1></default></config>";
- config.setForceReloadCheck(true);
- config.setNodeCombiner(new OverrideCombiner());
- File testXmlFile1 = writeReloadFile(RELOAD_XML_NAME, reloadContent, 0);
- final String prefix1 = "default";
- XMLConfiguration c1 = new XMLConfiguration(testXmlFile1);
- SubnodeConfiguration sub1 = c1.configurationAt(prefix1, true);
- assertEquals("Inital test for sub config 1 failed", 0, sub1
- .getInt("xmlReload1"));
- config.addConfiguration(sub1);
- assertEquals(
- "Could not get value for sub config 1 from combined config", 0,
- config.getInt("xmlReload1"));
- c1.setReloadingStrategy(new FileAlwaysReloadingStrategy());
- writeReloadFile(RELOAD_XML_NAME, reloadContent, 1);
- assertEquals("Reload of sub config 1 not detected", 1, config
- .getInt("xmlReload1"));
- }
-
- @Test
- 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);
- }
-
- /**
* Tests whether a combined configuration can be copied to an XML
* configuration. This test is related to CONFIGURATION-445.
*/
@@ -739,101 +646,6 @@ public class TestCombinedConfiguration
x3.getString("key2[@override]"));
}
- 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;
- }
- @Override
- 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.
- *
- * @param file the file to be written
- * @param content the file's content
- * @throws IOException if an error occurs
- */
- private void writeFile(File file, String content) throws IOException
- {
- PrintWriter out = null;
- try
- {
- out = new PrintWriter(new FileWriter(file));
- out.print(content);
- }
- finally
- {
- if (out != null)
- {
- out.close();
- }
- }
- }
-
- /**
- * Helper method for writing a test file. The file will be created in the
- * test directory. It is also scheduled for automatic deletion after the
- * test.
- *
- * @param fileName the name of the test file
- * @param content the content of the file
- * @return the <code>File</code> object for the test file
- * @throws IOException if an error occurs
- */
- private File writeFile(String fileName, String content) throws IOException
- {
- File file = new File(folder.getRoot(), fileName);
- writeFile(file, content);
- return file;
- }
-
- /**
- * Writes a file for testing reload operations.
- *
- * @param name the name of the reload test file
- * @param content the content of the file
- * @param value the value of the reload test property
- * @return the file that was written
- * @throws IOException if an error occurs
- */
- private File writeReloadFile(String name, String content, int value)
- throws IOException
- {
- return writeFile(name, MessageFormat.format(content, new Object[] {
- new Integer(value)
- }));
- }
-
/**
* Helper method for creating a test configuration to be added to the
* combined configuration.
Added: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestReloadingCombinedConfigurationBuilderFileBased.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestReloadingCombinedConfigurationBuilderFileBased.java?rev=1463692&view=auto
==============================================================================
--- commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestReloadingCombinedConfigurationBuilderFileBased.java (added)
+++ commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestReloadingCombinedConfigurationBuilderFileBased.java Tue Apr 2 19:08:45 2013
@@ -0,0 +1,339 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.configuration.builder.combined;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.text.MessageFormat;
+
+import org.apache.commons.configuration.BaseHierarchicalConfiguration;
+import org.apache.commons.configuration.CombinedConfiguration;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.commons.configuration.builder.BasicConfigurationBuilder;
+import org.apache.commons.configuration.builder.FileBasedBuilderParametersImpl;
+import org.apache.commons.configuration.builder.ReloadingDetectorFactory;
+import org.apache.commons.configuration.builder.fluent.Parameters;
+import org.apache.commons.configuration.io.FileHandler;
+import org.apache.commons.configuration.reloading.AlwaysReloadingDetector;
+import org.apache.commons.configuration.reloading.RandomReloadingDetector;
+import org.apache.commons.configuration.reloading.ReloadingDetector;
+import org.apache.commons.configuration.tree.MergeCombiner;
+import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * Test class for {@code ReloadingCombinedConfigurationBuilder} which actually
+ * accesses files to be reloaded.
+ *
+ * @version $Id: $
+ */
+public class TestReloadingCombinedConfigurationBuilderFileBased
+{
+ /** Constant for the prefix for XML configuration sources. */
+ private static final String PROP_SRC = "override.xml";
+
+ /** Constant for the prefix of the reload property. */
+ private static final String PROP_RELOAD = "default.xmlReload";
+
+ /** Constant for content of a XML configuration for reload tests. */
+ private static final String RELOAD_CONTENT =
+ "<config><default><xmlReload{1}>{0}</xmlReload{1}></default></config>";
+
+ /** A helper object for managing temporary files. */
+ @Rule
+ public TemporaryFolder folder = new TemporaryFolder();
+
+ /** The builder to be tested. */
+ private ReloadingCombinedConfigurationBuilder builder;
+
+ @Before
+ public void setUp() throws Exception
+ {
+ builder = new ReloadingCombinedConfigurationBuilder();
+ }
+
+ /**
+ * Adds a source for a configuration which can be reloaded to the definition
+ * configuration.
+ *
+ * @param config the definition configuration
+ * @param fileName the name of the file
+ */
+ private static void addReloadSource(Configuration config, String fileName)
+ {
+ config.addProperty(PROP_SRC + "(-1)[@fileName]", fileName);
+ config.addProperty(PROP_SRC + "[@config-reload]", Boolean.TRUE);
+ }
+
+ /**
+ * Helper method for writing a file.
+ *
+ * @param file the file to be written
+ * @param content the file's content
+ * @throws IOException if an error occurs
+ */
+ private static void writeFile(File file, String content) throws IOException
+ {
+ PrintWriter out = null;
+ try
+ {
+ out = new PrintWriter(new FileWriter(file));
+ out.print(content);
+ }
+ finally
+ {
+ if (out != null)
+ {
+ out.close();
+ }
+ }
+ }
+
+ /**
+ * Helper method for writing a test file for reloading. The file will be
+ * created in the test directory. It is also scheduled for automatic
+ * deletion after the test.
+ *
+ * @param f the file to be written or <b>null</b> for creating a new one
+ * @param content the content of the file
+ * @return the <code>File</code> object for the test file
+ * @throws IOException if an error occurs
+ */
+ private File writeReloadFile(File f, String content) throws IOException
+ {
+ File file = (f != null) ? f : folder.newFile();
+ writeFile(file, content);
+ return file;
+ }
+
+ /**
+ * Writes a file for testing reload operations.
+ *
+ * @param f the file to be written or <b>null</b> for creating a new one
+ * @param tagIdx the index of the tag
+ * @param value the value of the reload test property
+ * @return the file that was written
+ * @throws IOException if an error occurs
+ */
+ private File writeReloadFile(File f, int tagIdx, int value)
+ throws IOException
+ {
+ return writeReloadFile(f,
+ MessageFormat.format(RELOAD_CONTENT, new Object[] {
+ value, tagIdx
+ }));
+ }
+
+ /**
+ * Returns the name of a test property.
+ *
+ * @param idx the index of the property
+ * @return the test property with this index
+ */
+ private static String testProperty(int idx)
+ {
+ return PROP_RELOAD + idx;
+ }
+
+ /**
+ * Tests whether a changed file is detected on disk.
+ */
+ @Test
+ public void testReloadFromFile() throws ConfigurationException, IOException
+ {
+ File xmlConf1 = writeReloadFile(null, 1, 0);
+ File xmlConf2 = writeReloadFile(null, 2, 0);
+ ReloadingDetectorFactory detectorFactory =
+ new ReloadingDetectorFactory()
+ {
+ public ReloadingDetector createReloadingDetector(
+ FileHandler handler,
+ FileBasedBuilderParametersImpl params)
+ throws ConfigurationException
+ {
+ return new AlwaysReloadingDetector();
+ }
+ };
+ HierarchicalConfiguration defConf = new BaseHierarchicalConfiguration();
+ addReloadSource(defConf, xmlConf1.getAbsolutePath());
+ addReloadSource(defConf, xmlConf2.getAbsolutePath());
+ builder.configure(Parameters
+ .combined()
+ .setDefinitionBuilder(new ConstantConfigurationBuilder(defConf))
+ .addChildParameters(
+ new FileBasedBuilderParametersImpl()
+ .setReloadingDetectorFactory(detectorFactory)));
+ CombinedConfiguration config = builder.getConfiguration();
+ assertEquals("Wrong initial value (1)", 0,
+ config.getInt(testProperty(1)));
+ assertEquals("Wrong initial value (2)", 0,
+ config.getInt(testProperty(2)));
+
+ writeReloadFile(xmlConf1, 1, 1);
+ builder.getReloadingController().checkForReloading(null);
+ config = builder.getConfiguration();
+ assertEquals("Updated value not reloaded (1)", 1,
+ config.getInt(testProperty(1)));
+ assertEquals("Value modified", 0, config.getInt(testProperty(2)));
+
+ writeReloadFile(xmlConf2, 2, 2);
+ builder.getReloadingController().checkForReloading(null);
+ config = builder.getConfiguration();
+ assertEquals("Wrong value for config 1", 1,
+ config.getInt(testProperty(1)));
+ assertEquals("Updated value not reloaded (2)", 2,
+ config.getInt(testProperty(2)));
+ }
+
+ /**
+ * Tests concurrent access to a reloading builder for combined
+ * configurations.
+ */
+ @Test
+ public void testConcurrentGetAndReload() throws Exception
+ {
+ final int threadCount = 4;
+ final int loopCount = 100;
+ ReloadingDetectorFactory detectorFactory =
+ new ReloadingDetectorFactory()
+ {
+ public ReloadingDetector createReloadingDetector(
+ FileHandler handler,
+ FileBasedBuilderParametersImpl params)
+ throws ConfigurationException
+ {
+ return new RandomReloadingDetector();
+ }
+ };
+ HierarchicalConfiguration defConf = new BaseHierarchicalConfiguration();
+ defConf.addProperty("header.result.nodeCombiner[@config-class]",
+ MergeCombiner.class.getName());
+ defConf.addProperty("header.result.expressionEngine[@config-class]",
+ XPathExpressionEngine.class.getName());
+ addReloadSource(defConf, "configA.xml");
+ addReloadSource(defConf, "configB.xml");
+ builder.configure(Parameters
+ .combined()
+ .setDefinitionBuilder(new ConstantConfigurationBuilder(defConf))
+ .addChildParameters(
+ new FileBasedBuilderParametersImpl()
+ .setReloadingDetectorFactory(detectorFactory)));
+
+ assertEquals("Wrong initial value", "100", builder.getConfiguration()
+ .getString("/property[@name='config']/@value"));
+
+ Thread testThreads[] = new Thread[threadCount];
+ int failures[] = new int[threadCount];
+
+ for (int i = 0; i < testThreads.length; ++i)
+ {
+ testThreads[i] = new ReloadThread(builder, 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);
+ }
+
+ /**
+ * A test builder class which always returns the same configuration.
+ */
+ private static class ConstantConfigurationBuilder extends
+ BasicConfigurationBuilder<HierarchicalConfiguration>
+ {
+ private final HierarchicalConfiguration configuration;
+
+ public ConstantConfigurationBuilder(HierarchicalConfiguration conf)
+ {
+ super(HierarchicalConfiguration.class);
+ configuration = conf;
+ }
+
+ @Override
+ public HierarchicalConfiguration getConfiguration()
+ throws ConfigurationException
+ {
+ return configuration;
+ }
+ }
+
+ /**
+ * A thread class for testing concurrent reload operations.
+ */
+ private static class ReloadThread extends Thread
+ {
+ /** The builder to be queried. */
+ private final ReloadingCombinedConfigurationBuilder builder;
+
+ /** An array for reporting failures. */
+ private final int[] failures;
+
+ /** The index of this thread in the array with failures. */
+ private final int index;
+
+ /** The number of test operations. */
+ private final int count;
+
+ ReloadThread(ReloadingCombinedConfigurationBuilder bldr,
+ int[] failures, int index, int count)
+ {
+ builder = bldr;
+ this.failures = failures;
+ this.index = index;
+ this.count = count;
+ }
+
+ @Override
+ public void run()
+ {
+ failures[index] = 0;
+ for (int i = 0; i < count; i++)
+ {
+ try
+ {
+ builder.getReloadingController().checkForReloading(null);
+ String value =
+ builder.getConfiguration().getString(
+ "/property[@name='config']/@value");
+ if (value == null || !value.equals("100"))
+ {
+ ++failures[index];
+ }
+ }
+ catch (Exception ex)
+ {
+ ++failures[index];
+ }
+ }
+ }
+ }
+}