You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4cxx-dev@logging.apache.org by ca...@apache.org on 2005/01/05 23:42:59 UTC

cvs commit: logging-log4cxx/tests/witness/ndc NDC.1

carnold     2005/01/05 14:42:59

  Modified:    include/log4cxx ndc.h
               src      loggingevent.cpp ndc.cpp ttcclayout.cpp
                        xmllayout.cpp
  Added:       tests/input/ndc NDC1.properties
               tests/src ndctestcase.cpp
               tests/witness/ndc NDC.1
  Log:
  LOGCXX-51: Moving over NDC unit tests from log4j
  
  Revision  Changes    Path
  1.12      +21 -2     logging-log4cxx/include/log4cxx/ndc.h
  
  Index: ndc.h
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/include/log4cxx/ndc.h,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- ndc.h	4 Jan 2005 04:57:41 -0000	1.11
  +++ ndc.h	5 Jan 2005 22:42:58 -0000	1.12
  @@ -163,7 +163,13 @@
                   /**
                   Get the current nesting depth of this diagnostic context.
                   */
  -                static int getDepth();
  +                static int getDepth();
  +
  +
  +                /**
  +                * Tests if the NDC is empty.
  +                */
  +                static bool empty();
   
                   /**
                   Clients should call this method before leaving a diagnostic
  @@ -209,7 +215,20 @@
                   you never call it, then your application is sure to run out of
                   memory.
                   */
  -                static void remove();
  +                static void remove();
  +
  +
  +                /**
  +                 *  Tests if the specified string is the value
  +                 *  (usually "null") returned when the NDC is empty.
  +                 */
  +                static bool isNull(const LogString& str);
  +
  +        private:
  +                 /**
  +                  *  Get the string returned when the NDC is empty.
  +                  */
  +                 static const LogString& getNull();
           }; // class NDC;
   }  // namespace log4cxx
   
  
  
  
  1.24      +2 -0      logging-log4cxx/src/loggingevent.cpp
  
  Index: loggingevent.cpp
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/src/loggingevent.cpp,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- loggingevent.cpp	4 Jan 2005 03:37:07 -0000	1.23
  +++ loggingevent.cpp	5 Jan 2005 22:42:58 -0000	1.24
  @@ -48,6 +48,7 @@
   
   LoggingEvent::LoggingEvent() :
      properties(0),
  +   ndc(LOG4CXX_STR("null")),
      ndcLookupRequired(true),
      mdcCopyLookupRequired(true),
      timeStamp(0),
  @@ -60,6 +61,7 @@
      logger(logger),
      level(level),
      properties(0),
  +   ndc(LOG4CXX_STR("null")),
      ndcLookupRequired(true),
      mdcCopyLookupRequired(true),
      message(message),
  
  
  
  1.12      +17 -3     logging-log4cxx/src/ndc.cpp
  
  Index: ndc.cpp
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/src/ndc.cpp,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- ndc.cpp	4 Jan 2005 06:41:51 -0000	1.11
  +++ ndc.cpp	5 Jan 2005 22:42:58 -0000	1.12
  @@ -96,7 +96,7 @@
           {
                   return stack.top().fullMessage;
           }
  -        return LogString();
  +        return getNull();
   }
   
   int NDC::getDepth()
  @@ -113,7 +113,7 @@
                   stack.pop();
                   return value;
           }
  -        return LogString();
  +        return getNull();
   }
   
   LogString NDC::peek()
  @@ -123,7 +123,7 @@
           {
                   return stack.top().message;
           }
  -        return LogString();
  +        return getNull();
   }
   
   void NDC::pushLogString(const LogString& message)
  @@ -158,3 +158,17 @@
           clear();
   }
   
  +bool NDC::empty() {
  +    Stack& stack = ThreadSpecificData::getCurrentThreadStack();
  +    return stack.empty();
  +}
  +
  +bool NDC::isNull(const LogString& str) {
  +    return str == getNull();
  +}
  +
  +
  +const LogString& NDC::getNull() {
  +    static LogString nullStr(LOG4CXX_STR("null"));
  +    return nullStr;
  +}
  \ No newline at end of file
  
  
  
  1.16      +2 -2      logging-log4cxx/src/ttcclayout.cpp
  
  Index: ttcclayout.cpp
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/src/ttcclayout.cpp,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- ttcclayout.cpp	3 Jan 2005 06:43:44 -0000	1.15
  +++ ttcclayout.cpp	5 Jan 2005 22:42:58 -0000	1.16
  @@ -18,7 +18,7 @@
   #include <log4cxx/spi/loggingevent.h>
   #include <log4cxx/level.h>
   #include <log4cxx/helpers/stringhelper.h>
  -
  +#include <log4cxx/ndc.h>
   
   using namespace log4cxx;
   using namespace log4cxx::spi;
  @@ -67,7 +67,7 @@
           {
                   LogString ndc = event->getNDC();
   
  -                if(!ndc.empty())
  +                if(!NDC::isNull(ndc))
                   {
                           output.append(ndc);
                           output.append(1, LOG4CXX_STR(' '));
  
  
  
  1.22      +4 -2      logging-log4cxx/src/xmllayout.cpp
  
  Index: xmllayout.cpp
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/src/xmllayout.cpp,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- xmllayout.cpp	3 Jan 2005 06:43:44 -0000	1.21
  +++ xmllayout.cpp	5 Jan 2005 22:42:58 -0000	1.22
  @@ -21,7 +21,9 @@
   #include <log4cxx/helpers/transform.h>
   #include <log4cxx/helpers/iso8601dateformat.h>
   #include <log4cxx/helpers/stringhelper.h>
  -#include <log4cxx/helpers/transcoder.h>
  +#include <log4cxx/helpers/transcoder.h>
  +#include <log4cxx/ndc.h>
  +
   
   using namespace log4cxx;
   using namespace log4cxx::helpers;
  @@ -66,7 +68,7 @@
           output.append(LOG4CXX_STR("]]></log4j:message>\n"));
   
           const LogString& ndc = event->getNDC();
  -        if(!ndc.empty())
  +        if(!NDC::isNull(ndc))
           {
                   output.append(LOG4CXX_STR("<log4j:NDC><![CDATA["));
                   output.append(ndc);
  
  
  
  1.1                  logging-log4cxx/tests/input/ndc/NDC1.properties
  
  Index: NDC1.properties
  ===================================================================
  log4j.rootCategory=DEBUG, testAppender
  log4j.appender.testAppender=org.apache.log4j.FileAppender
  log4j.appender.testAppender.file=output/temp
  log4j.appender.testAppender.Append=false
  log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout
  log4j.appender.testAppender.layout.ConversionPattern=%-5p %x - %m%n
  
  #  Prevent internal log4j DEBUG messages from polluting the output. 
  log4j.logger.org.apache.log4j.PropertyConfigurator=INFO
  log4j.logger.org.apache.log4j.config.PropertySetter=INFO
  log4j.logger.org.apache.log4j.FileAppender=INFO
  
  
  
  1.1                  logging-log4cxx/tests/src/ndctestcase.cpp
  
  Index: ndctestcase.cpp
  ===================================================================
  
  /*
   * Copyright 2005 The Apache Software Foundation.
   *
   * Licensed 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.
   */
  
  #include <cppunit/TestFixture.h>
  #include <cppunit/extensions/HelperMacros.h>
  
  #include <log4cxx/ndc.h>
  #include <log4cxx/file.h>
  #include <log4cxx/logger.h>
  #include <log4cxx/propertyconfigurator.h>
  #include "insertwide.h"
  #include "util/compare.h"
  
  
  
  using namespace log4cxx;
  
  class NDCTestCase : public CppUnit::TestFixture
  {
           static File TEMP;
           static LoggerPtr logger;
  
          CPPUNIT_TEST_SUITE(NDCTestCase);
                  CPPUNIT_TEST(testPushPop);
                  CPPUNIT_TEST(test1);
          CPPUNIT_TEST_SUITE_END();
  
  public:
  
          void setUp() {
          }
  
          void tearDown() {
              logger->getLoggerRepository()->resetConfiguration();
          }
  
          /**
           *   Push and pop a value from the NDC
           */
          void testPushPop()
          {
                  NDC::push("trivial context");
                  LogString actual(NDC::pop());
                  CPPUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("trivial context"), actual);
          }
  
  
          void test1()  {
              PropertyConfigurator::configure(File("input/ndc/NDC1.properties"));
              common();
              CPPUNIT_ASSERT(Compare::compare(TEMP, File("witness/ndc/NDC.1")));
          }
  
          static void common() {
              commonLog();
              NDC::push("n1");
              commonLog();
              NDC::push("n2");
              NDC::push("n3");
              commonLog();
              NDC::pop();
              commonLog();
              NDC::clear();
              commonLog();
          }
  
          static void commonLog() {
              LOG4CXX_DEBUG(logger, "m1");
              LOG4CXX_INFO(logger, "m2");
              LOG4CXX_WARN(logger, "m3");
              LOG4CXX_ERROR(logger, "m4");
              LOG4CXX_FATAL(logger, "m5");
          }
  
  };
  
  
  File NDCTestCase::TEMP("output/temp");
  LoggerPtr NDCTestCase::logger(Logger::getLogger("org.apache.log4j.NDCTestCase"));
  
  CPPUNIT_TEST_SUITE_REGISTRATION(NDCTestCase);
  
  
  
  1.1                  logging-log4cxx/tests/witness/ndc/NDC.1
  
  Index: NDC.1
  ===================================================================
  DEBUG null - m1
  INFO  null - m2
  WARN  null - m3
  ERROR null - m4
  FATAL null - m5
  DEBUG n1 - m1
  INFO  n1 - m2
  WARN  n1 - m3
  ERROR n1 - m4
  FATAL n1 - m5
  DEBUG n1 n2 n3 - m1
  INFO  n1 n2 n3 - m2
  WARN  n1 n2 n3 - m3
  ERROR n1 n2 n3 - m4
  FATAL n1 n2 n3 - m5
  DEBUG n1 n2 - m1
  INFO  n1 n2 - m2
  WARN  n1 n2 - m3
  ERROR n1 n2 - m4
  FATAL n1 n2 - m5
  DEBUG null - m1
  INFO  null - m2
  WARN  null - m3
  ERROR null - m4
  FATAL null - m5
  
  
  

Re: Testing strategy (was Re: cvs commit: logging-log4cxx/tests/witness/ndc NDC.1)

Posted by Kevin Tew <li...@ekstrom.org>.
Curt Arnold wrote:

>
> On Jan 6, 2005, at 4:45 AM, Ceki Gülcü wrote:
>
>>
>> Curt,
>>
>> While you are importing unit tests over from log4j, you probably
>> became aware that the log4j tests based on the witness approach,
>> although very valuable, are fragile and somewhat hard to maintain. I
>> suspect that better and cheaper testing methodologies are out there.
>>
>> What do you think?
>>
>
> The "witness" tests are effectively integration tests.  They only work 
> if a whole lot of things are working properly and if they fail, the 
> cause of the failure may be difficult to isolate.  It is good to have 
> "integration" tests, but they are more fragile and don't effectively 
> test atypical conditions.
>
> My current approach to dealing with reported issues in log4cxx is to 
> check that all the relevant log4j tests have been migrated.  If that 
> doesn't reproduce the reported bug, then I'll write new unit tests for 
> log4cxx that demonstrate the bug and donate those back to log4j.
>
> If I'm substantially rewriting some aspect (like the date 
> formatting).  I'll likely start by writing a lot of tests for log4j to 
> really pin down what it does, then port the tests and implementation 
> to log4cxx.
>
> The coverage analysis reports can be very helpful in guiding test 
> writing.  I find it most effective to try to push classes that have 
> fairly good coverage to 100%, then work on the next tier and favor 
> writing tests for the core classes.
>
> log4j has enough eyeballs on it that bugs get identified and squashed 
> pretty quickly.  Having a good test suite is definitely a benefit to 
> the derived implementations.  In a perfect world, the log4cxx test 
> suite would have all the tests that log4j has.
>
> If anybody wants to contribute to log4cxx by migrating log4j tests, 
> your help would be appreciated.



Testing strategy (was Re: cvs commit: logging-log4cxx/tests/witness/ndc NDC.1)

Posted by Curt Arnold <ca...@apache.org>.
On Jan 6, 2005, at 4:45 AM, Ceki Gülcü wrote:

>
> Curt,
>
> While you are importing unit tests over from log4j, you probably
> became aware that the log4j tests based on the witness approach,
> although very valuable, are fragile and somewhat hard to maintain. I
> suspect that better and cheaper testing methodologies are out there.
>
> What do you think?
>

The "witness" tests are effectively integration tests.  They only work 
if a whole lot of things are working properly and if they fail, the 
cause of the failure may be difficult to isolate.  It is good to have 
"integration" tests, but they are more fragile and don't effectively 
test atypical conditions.

My current approach to dealing with reported issues in log4cxx is to 
check that all the relevant log4j tests have been migrated.  If that 
doesn't reproduce the reported bug, then I'll write new unit tests for 
log4cxx that demonstrate the bug and donate those back to log4j.

If I'm substantially rewriting some aspect (like the date formatting).  
I'll likely start by writing a lot of tests for log4j to really pin 
down what it does, then port the tests and implementation to log4cxx.

The coverage analysis reports can be very helpful in guiding test 
writing.  I find it most effective to try to push classes that have 
fairly good coverage to 100%, then work on the next tier and favor 
writing tests for the core classes.

log4j has enough eyeballs on it that bugs get identified and squashed 
pretty quickly.  Having a good test suite is definitely a benefit to 
the derived implementations.  In a perfect world, the log4cxx test 
suite would have all the tests that log4j has.

If anybody wants to contribute to log4cxx by migrating log4j tests, 
your help would be appreciated.

Re: cvs commit: logging-log4cxx/tests/witness/ndc NDC.1

Posted by Ceki Gülcü <ce...@qos.ch>.
Curt,

While you are importing unit tests over from log4j, you probably
became aware that the log4j tests based on the witness approach,
although very valuable, are fragile and somewhat hard to maintain. I
suspect that better and cheaper testing methodologies are out there.

What do you think?

At 11:42 PM 1/5/2005, you wrote:
>carnold     2005/01/05 14:42:59
>
>   Modified:    include/log4cxx ndc.h
>                src      loggingevent.cpp ndc.cpp ttcclayout.cpp
>                         xmllayout.cpp
>   Added:       tests/input/ndc NDC1.properties
>                tests/src ndctestcase.cpp
>                tests/witness/ndc NDC.1
>   Log:
>   LOGCXX-51: Moving over NDC unit tests from log4j
>
>   Revision  Changes    Path
>   1.12      +21 -2     logging-log4cxx/include/log4cxx/ndc.h

[cut]

-- 
Ceki Gülcü

   The complete log4j manual: http://www.qos.ch/log4j/