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];
+                }
+            }
+        }
+    }
+}