This is an automated email from the ASF dual-hosted git repository.

swebb2066 pushed a commit to branch require_appender_for_configurator_success
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git

commit e7f098686f4fc494c8d6c0906d018becb449db37
Author: Stephen Webb <[email protected]>
AuthorDate: Tue Sep 2 12:46:26 2025 +1000

    Require the configuration file specify an appender to be valid
---
 src/main/cpp/charsetdecoder.cpp                    |  6 +++
 src/main/cpp/domconfigurator.cpp                   | 49 +++++++++++++++------
 src/main/cpp/propertyconfigurator.cpp              |  7 +--
 src/main/include/log4cxx/helpers/charsetdecoder.h  | 22 +++++++---
 src/test/cpp/asyncappendertestcase.cpp             |  3 +-
 src/test/cpp/customlogger/xloggertestcase.cpp      |  3 +-
 src/test/cpp/db/odbcappendertestcase.cpp           |  3 +-
 src/test/cpp/fmttest.cpp                           |  9 ++--
 src/test/cpp/helpers/messagebuffertest.cpp         |  3 +-
 src/test/cpp/hierarchythresholdtestcase.cpp        | 24 +++++++----
 src/test/cpp/l7dtestcase.cpp                       |  3 +-
 src/test/cpp/locationdisabledtest.cpp              |  3 +-
 src/test/cpp/locationtest.cpp                      |  3 +-
 src/test/cpp/ndctestcase.cpp                       |  3 +-
 src/test/cpp/net/smtpappendertestcase.cpp          |  6 ++-
 src/test/cpp/net/xmlsocketappendertestcase.cpp     |  3 +-
 src/test/cpp/patternlayouttest.cpp                 | 45 ++++++++++++-------
 src/test/cpp/propertyconfiguratortest.cpp          |  9 ++--
 src/test/cpp/rolling/filterbasedrollingtest.cpp    |  5 +--
 src/test/cpp/varia/errorhandlertestcase.cpp        |  6 ++-
 src/test/cpp/xml/customleveltestcase.cpp           | 10 +++--
 src/test/cpp/xml/domtestcase.cpp                   | 50 +++++++++++++++++-----
 src/test/resources/input/xml/DOMTestCase5_bad1.xml | 33 ++++++++++++++
 src/test/resources/input/xml/DOMTestCase5_bad2.xml | 33 ++++++++++++++
 src/test/resources/input/xml/DOMTestCase5_good.xml | 33 ++++++++++++++
 25 files changed, 295 insertions(+), 79 deletions(-)

diff --git a/src/main/cpp/charsetdecoder.cpp b/src/main/cpp/charsetdecoder.cpp
index b985f475..76aa6aa1 100644
--- a/src/main/cpp/charsetdecoder.cpp
+++ b/src/main/cpp/charsetdecoder.cpp
@@ -585,6 +585,12 @@ CharsetDecoderPtr CharsetDecoder::getDecoder(const 
LogString& charset)
 #endif
 }
 
+log4cxx_status_t CharsetDecoder::decode(const char* in, size_t maxByteCount, 
LogString& out)
+{
+       ByteBuffer buf((char*)in, strnlen_s(in, maxByteCount));
+       return decode(buf, out);
+}
+
 
 
 
diff --git a/src/main/cpp/domconfigurator.cpp b/src/main/cpp/domconfigurator.cpp
index 6f78b3ac..c0dd0f92 100644
--- a/src/main/cpp/domconfigurator.cpp
+++ b/src/main/cpp/domconfigurator.cpp
@@ -68,6 +68,7 @@ struct DOMConfigurator::DOMConfiguratorPrivate
        helpers::Properties props = Configurator::properties();
        spi::LoggerRepositoryPtr repository;
        spi::LoggerFactoryPtr loggerFactory;
+       bool appenderAdded{ false };
 };
 
 namespace LOG4CXX_NS
@@ -323,6 +324,7 @@ AppenderPtr DOMConfigurator::parseAppender(Pool& p,
                                                        + LOG4CXX_STR(" named 
[") + appender->getName() + LOG4CXX_STR("]"));
                                        }
                                        
aa->addAppender(findAppenderByReference(p, utf8Decoder, currentElement, doc, 
appenders));
+                                       m_priv->appenderAdded = true;
                                }
                                else if (refName.empty())
                                {
@@ -461,7 +463,7 @@ void DOMConfigurator::parseLogger(
 
        if (LogLog::isDebugEnabled())
        {
-               LogLog::debug(LOG4CXX_STR("Retreiving an instance of ") + 
loggerName);
+               LogLog::debug(LOG4CXX_STR("Getting [") + loggerName + 
LOG4CXX_STR("]"));
        }
        LoggerPtr logger = m_priv->repository->getLogger(loggerName, 
m_priv->loggerFactory);
 
@@ -493,7 +495,12 @@ void DOMConfigurator::parseLoggerFactory(
 
        if (className.empty())
        {
-               LogLog::error(LOG4CXX_STR("Logger Factory tag class attribute 
not found."));
+               LogString msg(LOG4CXX_STR("["));
+               utf8Decoder->decode(factoryElement->name, 
MAX_ATTRIBUTE_NAME_LEN, msg);
+               msg += LOG4CXX_STR("] attribute [");
+               utf8Decoder->decode(CLASS_ATTR, MAX_ATTRIBUTE_NAME_LEN, msg);
+               msg += LOG4CXX_STR("] not found");
+               LogLog::warn(msg);
        }
        else
        {
@@ -561,7 +568,16 @@ void DOMConfigurator::parseChildrenOfLoggerElement(
                        AppenderPtr appender = findAppenderByReference(p, 
utf8Decoder, currentElement, doc, appenders);
                        LogString refName =  subst(getAttribute(utf8Decoder, 
currentElement, REF_ATTR));
 
-                       if (appender)
+                       if (refName.empty())
+                       {
+                               LogString msg(LOG4CXX_STR("["));
+                               utf8Decoder->decode(currentElement->name, 
MAX_ATTRIBUTE_NAME_LEN, msg);
+                               msg += LOG4CXX_STR("] attribute [");
+                               utf8Decoder->decode(REF_ATTR, 
MAX_ATTRIBUTE_NAME_LEN, msg);
+                               msg += LOG4CXX_STR("] not found");
+                               LogLog::warn(msg);
+                       }
+                       else if (appender)
                        {
                                if (LogLog::isDebugEnabled())
                                {
@@ -573,8 +589,8 @@ void DOMConfigurator::parseChildrenOfLoggerElement(
                        }
                        else
                        {
-                               LogLog::debug(LOG4CXX_STR("Appender named [") + 
refName +
-                                       LOG4CXX_STR("] not found."));
+                               
LogLog::warn(Appender::getStaticClass().getName()
+                                       + LOG4CXX_STR(" named [") + refName + 
LOG4CXX_STR("] not found"));
                        }
 
                }
@@ -594,8 +610,10 @@ void DOMConfigurator::parseChildrenOfLoggerElement(
        if (newappenders.empty())
                logger->removeAllAppenders();
        else
+       {
                logger->replaceAppenders(newappenders);
-
+               m_priv->appenderAdded = true;
+       }
        propSetter.activate(p);
 }
 
@@ -760,7 +778,7 @@ void DOMConfigurator::parseLevel(
        LogString levelStr(subst(getAttribute(utf8Decoder, element, 
VALUE_ATTR)));
        if (LogLog::isDebugEnabled())
        {
-               LogLog::debug(LOG4CXX_STR("Level value for ") + loggerName + 
LOG4CXX_STR(" is [") + levelStr + LOG4CXX_STR("]"));
+               LogLog::debug(LOG4CXX_STR("Setting [") + loggerName + 
LOG4CXX_STR("] level to [") + levelStr + LOG4CXX_STR("]"));
        }
 
        if (StringHelper::equalsIgnoreCase(levelStr, LOG4CXX_STR("INHERITED"), 
LOG4CXX_STR("inherited"))
@@ -815,7 +833,7 @@ void DOMConfigurator::parseLevel(
 
        if (LogLog::isDebugEnabled())
        {
-               LogLog::debug(loggerName + LOG4CXX_STR(" level set to ") +
+               LogLog::debug(LOG4CXX_STR("[") + loggerName + LOG4CXX_STR("] 
level is ") +
                        logger->getEffectiveLevel()->toString());
        }
 }
@@ -841,7 +859,6 @@ spi::ConfigurationStatus DOMConfigurator::doConfigure
        )
 {
        m_priv->repository = repository ? repository : 
LogManager::getLoggerRepository();
-       m_priv->repository->setConfigured(true);
 
 #if LOG4CXX_ABI_VERSION <= 15
        m_priv->loggerFactory = std::make_shared<DefaultLoggerFactory>();
@@ -910,6 +927,10 @@ spi::ConfigurationStatus DOMConfigurator::doConfigure
                }
        }
 
+       if (!m_priv->appenderAdded)
+               return spi::ConfigurationStatus::NotConfigured;
+
+       m_priv->repository->setConfigured(true);
        return spi::ConfigurationStatus::Configured;
 }
 
@@ -1042,7 +1063,12 @@ void DOMConfigurator::parse(
                }
                else
                {
-                       LogLog::error(LOG4CXX_STR("DOM element is - not a 
<configuration> element."));
+                       LogString msg(LOG4CXX_STR("Root element ["));
+                       utf8Decoder->decode(element->name, 
MAX_ATTRIBUTE_NAME_LEN, msg);
+                       msg += LOG4CXX_STR("] is not [");
+                       utf8Decoder->decode(CONFIGURATION_TAG, 
MAX_ATTRIBUTE_NAME_LEN, msg);
+                       msg += LOG4CXX_STR("]");
+                       LogLog::error(msg);
                        return;
                }
        }
@@ -1163,8 +1189,7 @@ LogString DOMConfigurator::getAttribute(
        {
                if (attrName == attr->name)
                {
-                       ByteBuffer buf((char*) attr->value, 
strnlen_s(attr->value, MAX_ATTRIBUTE_NAME_LEN));
-                       utf8Decoder->decode(buf, attrValue);
+                       utf8Decoder->decode(attr->value, 
MAX_ATTRIBUTE_NAME_LEN, attrValue);
                }
        }
 
diff --git a/src/main/cpp/propertyconfigurator.cpp 
b/src/main/cpp/propertyconfigurator.cpp
index 6dd2036b..388f81a9 100644
--- a/src/main/cpp/propertyconfigurator.cpp
+++ b/src/main/cpp/propertyconfigurator.cpp
@@ -111,7 +111,6 @@ spi::ConfigurationStatus PropertyConfigurator::doConfigure
        )
 {
        auto hierarchy = repository ? repository : 
LogManager::getLoggerRepository();
-       hierarchy->setConfigured(true);
 
        Properties props = Configurator::properties();
 
@@ -225,14 +224,16 @@ spi::ConfigurationStatus 
PropertyConfigurator::doConfigure(helpers::Properties&
        configureRootLogger(properties, hierarchy);
        configureLoggerFactory(properties);
        parseCatsAndRenderers(properties, hierarchy);
-
        LogLog::debug(LOG4CXX_STR("Finished configuring."));
+       auto result = registry->empty()
+               ? spi::ConfigurationStatus::NotConfigured
+               : spi::ConfigurationStatus::Configured;
 
        // We don't want to hold references to appenders preventing their
        // destruction.
        registry->clear();
 
-       return spi::ConfigurationStatus::Configured;
+       return result;
 }
 
 void PropertyConfigurator::configureLoggerFactory(helpers::Properties& props)
diff --git a/src/main/include/log4cxx/helpers/charsetdecoder.h 
b/src/main/include/log4cxx/helpers/charsetdecoder.h
index 3c276ac8..d801e70b 100644
--- a/src/main/include/log4cxx/helpers/charsetdecoder.h
+++ b/src/main/include/log4cxx/helpers/charsetdecoder.h
@@ -77,14 +77,24 @@ class LOG4CXX_EXPORT CharsetDecoder : public Object
 
 
                /**
-                *  Decodes as many bytes as possible from the given
-                *   input buffer, writing the results to the given output 
string.
-                *  @param in input buffer.
-                *  @param out output string.
+                *  Decodes as many bytes as possible from \c in,
+                *  appending the result onto \c out.
+                *  @param in a null terminated string.
+                *  @param out the string onto which characters are appended.
                 *  @return APR_SUCCESS if not encoding errors were found.
                 */
-               virtual log4cxx_status_t decode(ByteBuffer& in,
-                       LogString& out) = 0;
+               virtual log4cxx_status_t decode(ByteBuffer& in, LogString& out) 
= 0;
+
+
+               /**
+                *  Decodes up to \c maxByteCount bytes from \c in,
+                *  appending the result onto \c out.
+                *  @param in a null terminated string.
+                *  @param maxByteCount the limit on the size of \c in.
+                *  @param out the string onto which characters are appended.
+                *  @return APR_SUCCESS if not encoding errors were found.
+                */
+               log4cxx_status_t decode(const char* in, size_t maxByteCount, 
LogString& out);
 
                /**
                 *  Determins if status value indicates an invalid byte 
sequence.
diff --git a/src/test/cpp/asyncappendertestcase.cpp 
b/src/test/cpp/asyncappendertestcase.cpp
index ea6781fc..206efc1f 100644
--- a/src/test/cpp/asyncappendertestcase.cpp
+++ b/src/test/cpp/asyncappendertestcase.cpp
@@ -360,7 +360,8 @@ class AsyncAppenderTestCase : public 
AppenderSkeletonTestCase
 #if LOG4CXX_HAS_DOMCONFIGURATOR
                void testConfiguration()
                {
-                       
log4cxx::xml::DOMConfigurator::configure("input/xml/asyncAppender1.xml");
+                       auto status = 
xml::DOMConfigurator::configure("input/xml/asyncAppender1.xml");
+                       LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                        AsyncAppenderPtr asyncAppender = 
log4cxx::cast<AsyncAppender>(Logger::getRootLogger()->getAppender(LOG4CXX_STR("ASYNC")));
                        LOGUNIT_ASSERT(!(asyncAppender == 0));
                        LOGUNIT_ASSERT_EQUAL(100, 
asyncAppender->getBufferSize());
diff --git a/src/test/cpp/customlogger/xloggertestcase.cpp 
b/src/test/cpp/customlogger/xloggertestcase.cpp
index 74302e5c..7a4ef690 100644
--- a/src/test/cpp/customlogger/xloggertestcase.cpp
+++ b/src/test/cpp/customlogger/xloggertestcase.cpp
@@ -74,7 +74,8 @@ public:
                std::string fn("input/xml/customLogger");
                fn.append(number);
                fn.append(".xml");
-               DOMConfigurator::configure(fn);
+               auto status = DOMConfigurator::configure(fn);
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
 
                int i = 0;
                LOG4CXX_LOG(logger, log4cxx::XLevel::getTrace(), "Message " << 
i);
diff --git a/src/test/cpp/db/odbcappendertestcase.cpp 
b/src/test/cpp/db/odbcappendertestcase.cpp
index ca568aed..2e7dec99 100644
--- a/src/test/cpp/db/odbcappendertestcase.cpp
+++ b/src/test/cpp/db/odbcappendertestcase.cpp
@@ -84,7 +84,8 @@ class ODBCAppenderTestCase : public AppenderSkeletonTestCase
 //
                void testConnectUsingDSN()
                {
-                       
xml::DOMConfigurator::configure("input/xml/odbcAppenderDSN-Log4cxxTest.xml");
+                       auto status = 
xml::DOMConfigurator::configure("input/xml/odbcAppenderDSN-Log4cxxTest.xml");
+                       LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                        auto odbc = Logger::getLogger("DB.UnitTest");
                        for (int i = 0; i < 100; ++i)
                        {
diff --git a/src/test/cpp/fmttest.cpp b/src/test/cpp/fmttest.cpp
index 3827f69c..c7674d70 100644
--- a/src/test/cpp/fmttest.cpp
+++ b/src/test/cpp/fmttest.cpp
@@ -85,21 +85,24 @@ public:
 
        void test1()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/fmtLayout1.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/fmtLayout1.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
                LOGUNIT_ASSERT(Compare::compare(TEMP, 
LOG4CXX_FILE("witness/patternLayout.1")));
        }
 
        void test1_expanded()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/fmtLayout1_expanded.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/fmtLayout1_expanded.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
                LOGUNIT_ASSERT(Compare::compare(TEMP, 
LOG4CXX_FILE("witness/patternLayout.1")));
        }
 
        void test10()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/fmtLayout10.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/fmtLayout10.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
 
                ControlFilter filter1;
diff --git a/src/test/cpp/helpers/messagebuffertest.cpp 
b/src/test/cpp/helpers/messagebuffertest.cpp
index f953ea30..e257528d 100644
--- a/src/test/cpp/helpers/messagebuffertest.cpp
+++ b/src/test/cpp/helpers/messagebuffertest.cpp
@@ -148,7 +148,8 @@ public:
                root = Logger::getRootLogger();
                logger = 
Logger::getLogger(LOG4CXX_STR("java.org.apache.log4j.PatternLayoutTest"));
 
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/messagebuffer1.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/messagebuffer1.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
 
                int num = 220;
                LOG4CXX_INFO(logger, "number in hex: " << std::hex << num);
diff --git a/src/test/cpp/hierarchythresholdtestcase.cpp 
b/src/test/cpp/hierarchythresholdtestcase.cpp
index de836f09..65383cd8 100644
--- a/src/test/cpp/hierarchythresholdtestcase.cpp
+++ b/src/test/cpp/hierarchythresholdtestcase.cpp
@@ -59,56 +59,64 @@ public:
 
        void test1()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold1.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold1.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
                LOGUNIT_ASSERT(Compare::compare(TEMP, 
LOG4CXX_FILE("witness/hierarchyThreshold.1")));
        }
 
        void test2()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold2.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold2.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
                LOGUNIT_ASSERT(Compare::compare(TEMP, 
LOG4CXX_FILE("witness/hierarchyThreshold.2")));
        }
 
        void test3()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold3.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold3.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
                LOGUNIT_ASSERT(Compare::compare(TEMP, 
LOG4CXX_FILE("witness/hierarchyThreshold.3")));
        }
 
        void test4()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold4.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold4.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
                LOGUNIT_ASSERT(Compare::compare(TEMP, 
LOG4CXX_FILE("witness/hierarchyThreshold.4")));
        }
 
        void test5()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold5.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold5.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
                LOGUNIT_ASSERT(Compare::compare(TEMP, 
LOG4CXX_FILE("witness/hierarchyThreshold.5")));
        }
 
        void test6()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold6.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold6.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
                LOGUNIT_ASSERT(Compare::compare(TEMP, 
LOG4CXX_FILE("witness/hierarchyThreshold.6")));
        }
 
        void test7()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold7.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold7.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
                LOGUNIT_ASSERT(Compare::compare(TEMP, 
LOG4CXX_FILE("witness/hierarchyThreshold.7")));
        }
 
        void test8()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold8.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold8.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
                LOGUNIT_ASSERT(Compare::compare(TEMP, 
LOG4CXX_FILE("witness/hierarchyThreshold.8")));
        }
diff --git a/src/test/cpp/l7dtestcase.cpp b/src/test/cpp/l7dtestcase.cpp
index 7c70b74a..36b5eea8 100644
--- a/src/test/cpp/l7dtestcase.cpp
+++ b/src/test/cpp/l7dtestcase.cpp
@@ -77,7 +77,8 @@ public:
 
        void test1()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/l7d1.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/l7d1.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
 
                log4cxx::helpers::Pool pool;
 
diff --git a/src/test/cpp/locationdisabledtest.cpp 
b/src/test/cpp/locationdisabledtest.cpp
index fa682f61..976e4d81 100644
--- a/src/test/cpp/locationdisabledtest.cpp
+++ b/src/test/cpp/locationdisabledtest.cpp
@@ -48,7 +48,8 @@ public:
 
        void test1()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/locationdisabled.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/locationdisabled.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
                
LOGUNIT_ASSERT(Compare::compare(LOG4CXX_STR("output/location-disabled-test"), 
LOG4CXX_FILE("witness/location1-disabled")));
        }
diff --git a/src/test/cpp/locationtest.cpp b/src/test/cpp/locationtest.cpp
index aa98a63d..701e1896 100644
--- a/src/test/cpp/locationtest.cpp
+++ b/src/test/cpp/locationtest.cpp
@@ -48,7 +48,8 @@ public:
 
        void test1()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/location1.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/location1.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
                
LOGUNIT_ASSERT(Compare::compare(LOG4CXX_STR("output/location-good-test"), 
LOG4CXX_FILE("witness/location1-good")));
        }
diff --git a/src/test/cpp/ndctestcase.cpp b/src/test/cpp/ndctestcase.cpp
index 75e55371..383f7a71 100644
--- a/src/test/cpp/ndctestcase.cpp
+++ b/src/test/cpp/ndctestcase.cpp
@@ -68,7 +68,8 @@ public:
 
        void test1()
        {
-               
PropertyConfigurator::configure(File("input/ndc/NDC1.properties"));
+               auto status = 
PropertyConfigurator::configure(File("input/ndc/NDC1.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
                LOGUNIT_ASSERT(Compare::compare(TEMP, 
File("witness/ndc/NDC.1")));
        }
diff --git a/src/test/cpp/net/smtpappendertestcase.cpp 
b/src/test/cpp/net/smtpappendertestcase.cpp
index 213cf4f3..d3036239 100644
--- a/src/test/cpp/net/smtpappendertestcase.cpp
+++ b/src/test/cpp/net/smtpappendertestcase.cpp
@@ -106,7 +106,8 @@ class SMTPAppenderTestCase : public AppenderSkeletonTestCase
                 */
                void testTrigger()
                {
-                       
xml::DOMConfigurator::configure("input/xml/smtpAppender1.xml");
+                       auto status = 
xml::DOMConfigurator::configure("input/xml/smtpAppender1.xml");
+                       LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                        auto appender = 
log4cxx::cast<SMTPAppender>(Logger::getRootLogger()->getAppender(LOG4CXX_STR("A1")));
                        LOGUNIT_ASSERT(appender);
                        auto evaluator = appender->getEvaluator();
@@ -135,7 +136,8 @@ class SMTPAppenderTestCase : public AppenderSkeletonTestCase
 
                void testValid()
                {
-                       
xml::DOMConfigurator::configure("input/xml/smtpAppenderValid.xml");
+                       auto status = 
xml::DOMConfigurator::configure("input/xml/smtpAppenderValid.xml");
+                       LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                        auto root = Logger::getRootLogger();
                        LOG4CXX_INFO(root, "Hello, World.\n\nThis paragraph 
should be preceeded by a blank line.");
 
diff --git a/src/test/cpp/net/xmlsocketappendertestcase.cpp 
b/src/test/cpp/net/xmlsocketappendertestcase.cpp
index cfd715b8..95b450e7 100644
--- a/src/test/cpp/net/xmlsocketappendertestcase.cpp
+++ b/src/test/cpp/net/xmlsocketappendertestcase.cpp
@@ -48,7 +48,8 @@ class XMLSocketAppenderTestCase : public 
AppenderSkeletonTestCase
 
                void test_fluent_bit()
                {
-                       
xml::DOMConfigurator::configure("input/xml/fluent-bit.xml");
+                       auto status = 
xml::DOMConfigurator::configure("input/xml/fluent-bit.xml");
+                       LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                        auto log = Logger::getRootLogger();
                        for (int i = 0; i < 100; ++i)
                        {
diff --git a/src/test/cpp/patternlayouttest.cpp 
b/src/test/cpp/patternlayouttest.cpp
index a5723bbf..c142ae04 100644
--- a/src/test/cpp/patternlayouttest.cpp
+++ b/src/test/cpp/patternlayouttest.cpp
@@ -105,14 +105,16 @@ public:
 
        void test1()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout1.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout1.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
                LOGUNIT_ASSERT(Compare::compare(TEMP, 
LOG4CXX_FILE("witness/patternLayout.1")));
        }
 
        void test2()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout2.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout2.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
 
                ControlFilter filter1;
@@ -140,7 +142,8 @@ public:
 
        void test3()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout3.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout3.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
 
                ControlFilter filter1;
@@ -170,7 +173,8 @@ public:
        // 06 avr. 2002 18:30:58,937 [12345] DEBUG atternLayoutTest - Message 0
        void test4()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout4.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout4.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
 
                ControlFilter filter1;
@@ -198,7 +202,8 @@ public:
 
        void test5()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout5.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout5.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
 
                ControlFilter filter1;
@@ -226,7 +231,8 @@ public:
 
        void test6()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout6.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout6.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
 
                ControlFilter filter1;
@@ -254,7 +260,8 @@ public:
 
        void test7()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout7.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout7.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
 
                ControlFilter filter1;
@@ -282,7 +289,8 @@ public:
 
        void test8()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout8.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout8.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
 
 
@@ -313,7 +321,8 @@ public:
 
        void test9()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout9.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout9.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
 
                ControlFilter filter1;
@@ -339,7 +348,8 @@ public:
 
        void test10()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout10.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout10.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
 
                ControlFilter filter1;
@@ -371,7 +381,8 @@ public:
 
        void test11()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout11.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout11.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
 
                ControlFilter filter1;
@@ -397,7 +408,8 @@ public:
 
        void test12()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout12.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout12.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
 
                ControlFilter filter1;
@@ -427,21 +439,24 @@ public:
 
        void test13()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout13.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout13.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
                LOGUNIT_ASSERT(Compare::compare(TEMP, 
LOG4CXX_FILE("witness/patternLayout.13")));
        }
 
        void test14()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout14.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout14.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
                LOGUNIT_ASSERT(Compare::compare(TEMP, 
LOG4CXX_FILE("witness/patternLayout.14")));
        }
 
        void testMDC1()
        {
-               
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout.mdc.1.properties"));
+               auto status = 
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout.mdc.1.properties"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                MDC::put(LOG4CXX_TEST_STR("key1"), LOG4CXX_TEST_STR("va11"));
                MDC::put(LOG4CXX_TEST_STR("key2"), LOG4CXX_TEST_STR("va12"));
                logger->debug(LOG4CXX_TEST_STR("Hello World"));
diff --git a/src/test/cpp/propertyconfiguratortest.cpp 
b/src/test/cpp/propertyconfiguratortest.cpp
index b051614e..2d57ee67 100644
--- a/src/test/cpp/propertyconfiguratortest.cpp
+++ b/src/test/cpp/propertyconfiguratortest.cpp
@@ -41,7 +41,8 @@ public:
                
props.put(LOG4CXX_STR("log4j.logger.org.apache.log4j.PropertyConfiguratorTest"),
 LOG4CXX_STR("inherited,VECTOR2"));
                props.put(LOG4CXX_STR("log4j.appender.VECTOR1"), 
LOG4CXX_STR("org.apache.log4j.VectorAppender"));
                props.put(LOG4CXX_STR("log4j.appender.VECTOR2"), 
LOG4CXX_STR("org.apache.log4j.VectorAppender"));
-               PropertyConfigurator::configure(props);
+               auto status = PropertyConfigurator::configure(props);
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                LoggerPtr logger = 
Logger::getLogger("org.apache.log4j.PropertyConfiguratorTest");
                LOGUNIT_ASSERT_EQUAL((int) Level::DEBUG_INT,
                        logger->getEffectiveLevel()->toInt());
@@ -58,7 +59,8 @@ public:
                
props.put(LOG4CXX_STR("log4j.logger.org.apache.log4j.PropertyConfiguratorTest"),
 LOG4CXX_STR("NuLL,VECTOR2"));
                props.put(LOG4CXX_STR("log4j.appender.VECTOR1"), 
LOG4CXX_STR("org.apache.log4j.VectorAppender"));
                props.put(LOG4CXX_STR("log4j.appender.VECTOR2"), 
LOG4CXX_STR("org.apache.log4j.VectorAppender"));
-               PropertyConfigurator::configure(props);
+               auto status = PropertyConfigurator::configure(props);
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                LoggerPtr logger = 
Logger::getLogger("org.apache.log4j.PropertyConfiguratorTest");
                LOGUNIT_ASSERT_EQUAL((int) Level::DEBUG_INT,
                        logger->getEffectiveLevel()->toInt());
@@ -74,7 +76,8 @@ public:
                props.put(LOG4CXX_STR("log4j.rootLogger"), 
LOG4CXX_STR("ALL,VECTOR1"));
                props.put(LOG4CXX_STR("log4j.appender.VECTOR1"), 
LOG4CXX_STR("org.apache.log4j.VectorAppender"));
                props.put(LOG4CXX_STR("log4j.appender.VECTOR1.threshold"), 
LOG4CXX_STR("WARN"));
-               PropertyConfigurator::configure(props);
+               auto status = PropertyConfigurator::configure(props);
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                LoggerPtr root(Logger::getRootLogger());
                VectorAppenderPtr appender = 
log4cxx::cast<VectorAppender>(root->getAppender(LOG4CXX_STR("VECTOR1")));
                LOGUNIT_ASSERT_EQUAL((int) Level::WARN_INT, 
appender->getThreshold()->toInt());
diff --git a/src/test/cpp/rolling/filterbasedrollingtest.cpp 
b/src/test/cpp/rolling/filterbasedrollingtest.cpp
index 43448125..bbff3fdc 100644
--- a/src/test/cpp/rolling/filterbasedrollingtest.cpp
+++ b/src/test/cpp/rolling/filterbasedrollingtest.cpp
@@ -60,9 +60,8 @@ public:
        void test1()
        {
 #if LOG4CXX_HAS_DOMCONFIGURATOR
-               log4cxx::xml::DOMConfigurator::configure(
-                       "./input/rolling/filter1.xml" /*, 
LogManager::getLoggerRepository() */);
-
+               auto status = 
xml::DOMConfigurator::configure("./input/rolling/filter1.xml");
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common(LOG4CXX_STR("output/filterBased-test1"));
 #endif
        }
diff --git a/src/test/cpp/varia/errorhandlertestcase.cpp 
b/src/test/cpp/varia/errorhandlertestcase.cpp
index 468ab4bf..5a479258 100644
--- a/src/test/cpp/varia/errorhandlertestcase.cpp
+++ b/src/test/cpp/varia/errorhandlertestcase.cpp
@@ -85,7 +85,8 @@ public:
 
        void test1()
        {
-               DOMConfigurator::configure("input/xml/fallback1.xml");
+               auto status = 
DOMConfigurator::configure("input/xml/fallback1.xml");
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                auto appender = root->getAppender(LOG4CXX_STR("PRIMARY"));
                auto primary = log4cxx::cast<FileAppender>(appender);
                auto errHandle = primary->getErrorHandler();
@@ -127,7 +128,8 @@ public:
 
        void test2()
        {
-               DOMConfigurator::configure("input/xml/fallback2.xml");
+               auto status = 
DOMConfigurator::configure("input/xml/fallback2.xml");
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                auto appender = root->getAppender(LOG4CXX_STR("PRIMARY"));
                auto primary = log4cxx::cast<FileAppender>(appender);
                auto errHandle = primary->getErrorHandler();
diff --git a/src/test/cpp/xml/customleveltestcase.cpp 
b/src/test/cpp/xml/customleveltestcase.cpp
index d2259a56..b58c0081 100644
--- a/src/test/cpp/xml/customleveltestcase.cpp
+++ b/src/test/cpp/xml/customleveltestcase.cpp
@@ -69,7 +69,8 @@ public:
 
        void test1()
        {
-               
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/customLevel1.xml"));
+               auto status = 
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/customLevel1.xml"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
                const File witness("witness/customLevel.1");
                LOGUNIT_ASSERT(Compare::compare(TEMP, witness));
@@ -77,7 +78,8 @@ public:
 
        void test2()
        {
-               
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/customLevel2.xml"));
+               auto status = 
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/customLevel2.xml"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
                const File witness("witness/customLevel.2");
                LOGUNIT_ASSERT(Compare::compare(TEMP, witness));
@@ -86,6 +88,7 @@ public:
        void test3()
        {
                
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/customLevel3.xml"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
                const File witness("witness/customLevel.3");
                LOGUNIT_ASSERT(Compare::compare(TEMP, witness));
@@ -93,7 +96,8 @@ public:
 
        void test4()
        {
-               
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/customLevel4.xml"));
+               auto status = 
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/customLevel4.xml"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
                const File witness("witness/customLevel.4");
                LOGUNIT_ASSERT(Compare::compare(TEMP, witness));
diff --git a/src/test/cpp/xml/domtestcase.cpp b/src/test/cpp/xml/domtestcase.cpp
index 5f98b29e..ebcf5baa 100644
--- a/src/test/cpp/xml/domtestcase.cpp
+++ b/src/test/cpp/xml/domtestcase.cpp
@@ -17,6 +17,7 @@
 
 #include <log4cxx/logger.h>
 #include <log4cxx/xml/domconfigurator.h>
+#include <log4cxx/defaultconfigurator.h>
 #include "../logunit.h"
 #include "../util/compare.h"
 #include "xlevel.h"
@@ -56,6 +57,7 @@ LOGUNIT_CLASS(DOMTestCase)
        LOGUNIT_TEST(recursiveAppenderRef);
        LOGUNIT_TEST(invalidAppender);
        LOGUNIT_TEST(invalidLevel);
+       LOGUNIT_TEST(testAutoFallback);
        LOGUNIT_TEST_SUITE_END();
 
        LoggerPtr root;
@@ -73,6 +75,7 @@ LOGUNIT_CLASS(DOMTestCase)
 public:
        void setUp()
        {
+               LogLog::setInternalDebugging(true);
                root = Logger::getRootLogger();
                logger = 
Logger::getLogger(LOG4CXX_TEST_STR("org.apache.log4j.xml.DOMTestCase"));
        }
@@ -89,8 +92,8 @@ public:
 
        void test1()
        {
-               LogLog::setInternalDebugging(true);
-               
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMTestCase1.xml"));
+               auto status = 
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMTestCase1.xml"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
 
                ControlFilter cf1;
@@ -134,7 +137,8 @@ public:
        //
        void test2()
        {
-               
DOMConfigurator::configure(LOG4CXX_TEST_STR("input\\xml\\DOMTestCase2.xml"));
+               auto status = 
DOMConfigurator::configure(LOG4CXX_TEST_STR("input\\xml\\DOMTestCase2.xml"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                common();
 
                ThreadFilter threadFilter;
@@ -196,7 +200,8 @@ public:
         */
        void test3()
        {
-               
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMTestCase3.xml"));
+               auto status = 
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMTestCase3.xml"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                LOG4CXX_INFO(logger, "File name is expected to end with a 
superscript 3");
 #if LOG4CXX_LOGCHAR_IS_UTF8
                const logchar fname[] = { 0x6F, 0x75, 0x74, 0x70, 0x75, 0x74, 
0x2F, 0x64, 0x6F, 0x6D, static_cast<logchar>(0xC2), static_cast<logchar>(0xB3), 
0 };
@@ -216,7 +221,8 @@ public:
         */
        void test4()
        {
-               
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMTestCase4.xml"));
+               auto status = 
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMTestCase4.xml"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
                LOG4CXX_INFO(logger, "File name is expected to end with an 
ideographic 4");
 #if LOG4CXX_LOGCHAR_IS_UTF8
                const logchar fname[] = { 0x6F, 0x75, 0x74, 0x70, 0x75, 0x74, 
0x2F, 0x64, 0x6F, 0x6D, static_cast<logchar>(0xE3), static_cast<logchar>(0x86), 
static_cast<logchar>(0x95), 0 };
@@ -234,22 +240,46 @@ public:
        void recursiveAppenderRef()
        {
                // Load a bad XML file, make sure that we don't crash in 
endless recursion
-               
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMConfiguratorRecursive.xml"));
-  }
+               auto status = 
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMConfiguratorRecursive.xml"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::NotConfigured);
+       }
 
        void invalidAppender()
        {
                // Load an XML file that attempts to use a levelmatchfilter as 
an appender.
                // We should not crash when loading this file.
-               
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMInvalidAppender.xml"));
-  }
+               auto status = 
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMInvalidAppender.xml"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::NotConfigured);
+       }
   
        void invalidLevel()
        {
                // Load an XML file that attempts to use a filter as a level.
                // We should not crash when loading this file.
-               
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMInvalidLevel.xml"));
+               auto status = 
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMInvalidLevel.xml"));
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
        }
+
+       void testAutoFallback()
+       {
+               LogString fileName = LOG4CXX_STR("DOMTestCase5");
+               std::vector<LogString> paths
+               { LOG4CXX_STR("input/xml")
+               };
+               std::vector<LogString> names
+               { LOG4CXX_STR("DOMTestCase5_bad1.xml")
+               , LOG4CXX_STR("DOMTestCase5_bad2.xml")
+               , LOG4CXX_STR("DOMTestCase5_good.xml")
+               };
+               LogString configFile;
+               spi::ConfigurationStatus status;
+               std::tie(status, configFile) = 
DefaultConfigurator::configureFromFile(paths, names);
+               LOGUNIT_ASSERT_EQUAL(status, 
spi::ConfigurationStatus::Configured);
+               LOGUNIT_ASSERT(configFile.npos != 
configFile.find(LOG4CXX_STR("DOMTestCase5_good.xml")));
+               // Prevent "DOMTestCase5_good.xml" use in subsequent default 
configuration
+               DefaultConfigurator::setConfigurationFileName(LogString());
+       }
+
 };
 
 LOGUNIT_TEST_SUITE_REGISTRATION(DOMTestCase);
diff --git a/src/test/resources/input/xml/DOMTestCase5_bad1.xml 
b/src/test/resources/input/xml/DOMTestCase5_bad1.xml
new file mode 100644
index 00000000..213a8824
--- /dev/null
+++ b/src/test/resources/input/xml/DOMTestCase5_bad1.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<!--
+ 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.
+
+-->
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/";>
+  <appender name="A1" class="org.apache.log4j.UnknownAppender">
+    <layout class="org.apache.log4j.PatternLayout">
+      <param name="ConversionPattern" value="%-5p %c{2} - %m%n"/>
+    </layout>
+  </appender>
+
+  <root>
+    <priority value ="debug" />
+    <appender-ref ref="A1" />
+  </root>
+
+</log4j:configuration>
diff --git a/src/test/resources/input/xml/DOMTestCase5_bad2.xml 
b/src/test/resources/input/xml/DOMTestCase5_bad2.xml
new file mode 100644
index 00000000..bc26d9fc
--- /dev/null
+++ b/src/test/resources/input/xml/DOMTestCase5_bad2.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<!--
+ 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.
+
+-->
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/";>
+  <appender class="org.apache.log4j.FileAppender">
+    <layout class="org.apache.log4j.PatternLayout">
+      <param name="ConversionPattern" value="%-5p %c{2} - %m%n"/>
+    </layout>
+  </appender>
+
+  <root>
+    <priority value ="debug" />
+    <appender-ref ref="A1" />
+  </root>
+
+</log4j:configuration>
diff --git a/src/test/resources/input/xml/DOMTestCase5_good.xml 
b/src/test/resources/input/xml/DOMTestCase5_good.xml
new file mode 100644
index 00000000..568df13e
--- /dev/null
+++ b/src/test/resources/input/xml/DOMTestCase5_good.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<!--
+ 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.
+
+-->
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/";>
+  <appender name="A1" class="org.apache.log4j.ConsoleAppender">
+    <layout class="org.apache.log4j.PatternLayout">
+      <param name="ConversionPattern" value="%Y%-5p %c{2} - %m%y%n"/>
+    </layout>
+  </appender>
+
+  <root>
+    <priority value ="debug" />
+    <appender-ref ref="A1" />
+  </root>
+
+</log4j:configuration>


Reply via email to