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

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


The following commit(s) were added to refs/heads/LOGCXX-514 by this push:
     new 3a2326ce Added some unit tests for the FMTLayout
3a2326ce is described below

commit 3a2326cea2e5a8cc2efee504803ad3789f2a0b4d
Author: Robert Middleton <[email protected]>
AuthorDate: Wed Nov 23 20:05:28 2022 -0500

    Added some unit tests for the FMTLayout
---
 src/main/cpp/fmtlayout.cpp                         |   3 +
 src/main/cpp/loggingevent.cpp                      |  12 +-
 src/main/include/log4cxx/fmtlayout.h               |  16 +-
 src/main/include/log4cxx/log4cxx.h.in              |   3 +
 src/main/include/log4cxx/spi/loggingevent.h        |   3 +
 src/test/cpp/CMakeLists.txt                        |   3 +
 src/test/cpp/fmttest.cpp                           | 197 +++++++++++++++++++++
 src/test/resources/input/fmtLayout1.properties     |  21 +++
 src/test/resources/input/fmtLayout10.properties    |  21 +++
 .../resources/input/fmtLayout1_expanded.properties |  21 +++
 10 files changed, 290 insertions(+), 10 deletions(-)

diff --git a/src/main/cpp/fmtlayout.cpp b/src/main/cpp/fmtlayout.cpp
index 15ce753a..20b7cf54 100644
--- a/src/main/cpp/fmtlayout.cpp
+++ b/src/main/cpp/fmtlayout.cpp
@@ -21,8 +21,10 @@
 #include <log4cxx/helpers/pool.h>
 #include <log4cxx/helpers/optionconverter.h>
 #include <log4cxx/level.h>
+#include <chrono>
 
 #include <fmt/format.h>
+#include <fmt/chrono.h>
 
 using namespace log4cxx;
 using namespace log4cxx::spi;
@@ -88,6 +90,7 @@ void FMTLayout::format(LogString& output,
 
        fmt::format_to(std::back_inserter(output),
                                   m_priv->conversionPattern,
+                                  fmt::arg("d", event->getChronoTimeStamp()),
                                   fmt::arg("c", event->getLoggerName()),
                                   fmt::arg("logger", event->getLoggerName()),
                                   fmt::arg("f", 
event->getLocationInformation().getShortFileName()),
diff --git a/src/main/cpp/loggingevent.cpp b/src/main/cpp/loggingevent.cpp
index 8adcd0e6..f58924da 100644
--- a/src/main/cpp/loggingevent.cpp
+++ b/src/main/cpp/loggingevent.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#include <chrono>
 #include <log4cxx/spi/loggingevent.h>
 #include <log4cxx/ndc.h>
 
@@ -68,10 +69,11 @@ struct LoggingEvent::LoggingEventPrivate
                ndcLookupRequired(true),
                mdcCopyLookupRequired(true),
                message(message1),
-               timeStamp(apr_time_now()),
+               timeStamp(Date::currentTime()),
                locationInfo(locationInfo1),
                threadName(getCurrentThreadName()),
-               threadUserName(getCurrentThreadUserName())
+               threadUserName(getCurrentThreadUserName()),
+               chronoTimeStamp(std::chrono::milliseconds(timeStamp))
        {
        }
 
@@ -138,6 +140,8 @@ struct LoggingEvent::LoggingEventPrivate
         * systems or SetThreadDescription on Windows.
         */
        const LogString& threadUserName;
+
+       std::chrono::time_point<std::chrono::high_resolution_clock> 
chronoTimeStamp;
 };
 
 IMPLEMENT_LOG4CXX_OBJECT(LoggingEvent)
@@ -432,3 +436,7 @@ const log4cxx::spi::LocationInfo& 
LoggingEvent::getLocationInformation() const
        return m_priv->locationInfo;
 }
 
+log4cxx_timepoint_t LoggingEvent::getChronoTimeStamp() const{
+       return m_priv->chronoTimeStamp;
+}
+
diff --git a/src/main/include/log4cxx/fmtlayout.h 
b/src/main/include/log4cxx/fmtlayout.h
index 9bc5bbb4..79fb9e28 100644
--- a/src/main/include/log4cxx/fmtlayout.h
+++ b/src/main/include/log4cxx/fmtlayout.h
@@ -33,14 +33,14 @@ namespace log4cxx
  * Most of the standard PatternLayout arguments are also accepted as 
arguments, so that you can easily
  * convert a PatternLayout to a FMTLayout.  For example, given the following 
PatternLayout:
  *
- * %c %-5p - %m%n
+ * <pre>%c %-5p - %m%n</pre>
  * which outputs something like:
- * root INFO  - Hello there!
+ * <pre>root INFO  - Hello there!</pre>
  *
  * The equivalent FMTLayout can be written as:
- * {c} {p:-5} - {m}{n}
+ * <pre>{c} {p:<5} - {m}{n}</pre>
  * Or more verbosely as:
- * {logger} {level:-5} - {message}{newline}
+ * <pre>{logger} {level:<5} - {message}{newline}</pre>
  *
  * All replacements are done using the named arguments feature of {fmt}.
  *
@@ -215,15 +215,15 @@ class LOG4CXX_EXPORT FMTLayout : public Layout
     LOG4CXX_DECLARE_PRIVATE_MEMBER_PTR(FMTLayoutPrivate, m_priv)
 
        public:
-                DECLARE_LOG4CXX_OBJECT(FMTLayout)
+               DECLARE_LOG4CXX_OBJECT(FMTLayout)
                BEGIN_LOG4CXX_CAST_MAP()
-                LOG4CXX_CAST_ENTRY(FMTLayout)
+               LOG4CXX_CAST_ENTRY(FMTLayout)
                LOG4CXX_CAST_ENTRY_CHAIN(Layout)
                END_LOG4CXX_CAST_MAP()
 
-                FMTLayout();
+               FMTLayout();
 
-                FMTLayout(const LogString& pattern);
+               FMTLayout(const LogString& pattern);
 
                ~FMTLayout();
 
diff --git a/src/main/include/log4cxx/log4cxx.h.in 
b/src/main/include/log4cxx/log4cxx.h.in
index 88470937..251be8e4 100644
--- a/src/main/include/log4cxx/log4cxx.h.in
+++ b/src/main/include/log4cxx/log4cxx.h.in
@@ -60,6 +60,9 @@ typedef unsigned int log4cxx_uint32_t;
 
 #include "boost-std-configuration.h"
 #include <memory>
+#include <chrono>
+
+typedef std::chrono::time_point<std::chrono::system_clock> log4cxx_timepoint_t;
 
 #define LOG4CXX_PTR_DEF(T) typedef std::shared_ptr<T> T##Ptr;\
        typedef std::weak_ptr<T> T##WeakPtr
diff --git a/src/main/include/log4cxx/spi/loggingevent.h 
b/src/main/include/log4cxx/spi/loggingevent.h
index 55816aef..2b1ffaae 100644
--- a/src/main/include/log4cxx/spi/loggingevent.h
+++ b/src/main/include/log4cxx/spi/loggingevent.h
@@ -24,6 +24,7 @@
 #include <log4cxx/mdc.h>
 #include <log4cxx/spi/location/locationinfo.h>
 #include <vector>
+#include <chrono>
 
 
 namespace log4cxx
@@ -107,6 +108,8 @@ class LOG4CXX_EXPORT LoggingEvent :
                 was created. */
                log4cxx_time_t getTimeStamp() const;
 
+               log4cxx_timepoint_t getChronoTimeStamp() const;
+
                /* Return the file where this log statement was written. */
                const log4cxx::spi::LocationInfo& getLocationInformation() 
const;
 
diff --git a/src/test/cpp/CMakeLists.txt b/src/test/cpp/CMakeLists.txt
index 0e9cad93..74a35e5b 100644
--- a/src/test/cpp/CMakeLists.txt
+++ b/src/test/cpp/CMakeLists.txt
@@ -58,6 +58,9 @@ set(ALL_LOG4CXX_TESTS
     locationtest
     locationdisabledtest
 )
+if(${ENABLE_FMT_LAYOUT})
+    set(ALL_LOG4CXX_TESTS ${ALL_LOG4CXX_TESTS} fmttest)
+endif()
 foreach(fileName IN LISTS ALL_LOG4CXX_TESTS)
     add_executable(${fileName} "${fileName}.cpp")
 endforeach()
diff --git a/src/test/cpp/fmttest.cpp b/src/test/cpp/fmttest.cpp
new file mode 100644
index 00000000..6752e1e3
--- /dev/null
+++ b/src/test/cpp/fmttest.cpp
@@ -0,0 +1,197 @@
+/*
+ * 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.
+ */
+#include "logunit.h"
+#include "testchar.h"
+#include "util/compare.h"
+#include "util/transformer.h"
+#include "util/absolutedateandtimefilter.h"
+#include "util/iso8601filter.h"
+#include "util/absolutetimefilter.h"
+#include "util/relativetimefilter.h"
+#include "util/controlfilter.h"
+#include "util/threadfilter.h"
+#include "util/linenumberfilter.h"
+#include "util/filenamefilter.h"
+#include "vectorappender.h"
+#include <log4cxx/fmtlayout.h>
+#include <log4cxx/propertyconfigurator.h>
+#include <log4cxx/helpers/date.h>
+#include <log4cxx/spi/loggingevent.h>
+#include <iostream>
+#include <iomanip>
+
+#define REGEX_STR(x) x
+#define PAT0 REGEX_STR("\\[[0-9A-FXx]*]\\ (DEBUG|INFO|WARN|ERROR|FATAL) .* - 
Message [0-9]\\{1,2\\}")
+#define PAT1 ISO8601_PAT REGEX_STR(" ") PAT0
+#define PAT2 ABSOLUTE_DATE_AND_TIME_PAT REGEX_STR(" ") PAT0
+#define PAT3 ABSOLUTE_TIME_PAT REGEX_STR(" ") PAT0
+#define PAT4 RELATIVE_TIME_PAT REGEX_STR(" ") PAT0
+#define PAT5 REGEX_STR("\\[[0-9A-FXx]*]\\ (DEBUG|INFO|WARN|ERROR|FATAL) .* : 
Message [0-9]\\{1,2\\}")
+#define PAT6 REGEX_STR("\\[[0-9A-FXx]*]\\ (DEBUG|INFO |WARN |ERROR|FATAL) 
.*patternlayouttest.cpp\\([0-9]\\{1,4\\}\\): Message [0-9]\\{1,3\\}")
+#define PAT11a REGEX_STR("^(DEBUG|INFO |WARN |ERROR|FATAL) \\[[0-9A-FXx]*]\\ 
log4j.PatternLayoutTest: Message [0-9]\\{1,2\\}")
+#define PAT11b REGEX_STR("^(DEBUG|INFO |WARN |ERROR|FATAL) \\[[0-9A-FXx]*]\\ 
root: Message [0-9]\\{1,2\\}")
+#define PAT12 REGEX_STR("^\\[[0-9A-FXx]*]\\ (DEBUG|INFO |WARN |ERROR|FATAL) ")\
+       REGEX_STR(".*patternlayouttest.cpp([0-9]\\{1,4\\}): ")\
+       REGEX_STR("Message [0-9]\\{1,2\\}")
+#define PAT_MDC_1 REGEX_STR("")
+
+using namespace log4cxx;
+using namespace log4cxx::helpers;
+
+LOGUNIT_CLASS(FMTTestCase)
+{
+       LOGUNIT_TEST_SUITE(FMTTestCase);
+       LOGUNIT_TEST(test1);
+       LOGUNIT_TEST(test1_expanded);
+       LOGUNIT_TEST(test10);
+       LOGUNIT_TEST(test_date);
+       LOGUNIT_TEST_SUITE_END();
+
+       LoggerPtr root;
+       LoggerPtr logger;
+
+public:
+       void setUp()
+       {
+               root = Logger::getRootLogger();
+               MDC::clear();
+               logger = 
Logger::getLogger(LOG4CXX_TEST_STR("java.org.apache.log4j.PatternLayoutTest"));
+       }
+
+       void tearDown()
+       {
+               MDC::clear();
+               auto rep = root->getLoggerRepository();
+
+               if (rep)
+               {
+                       rep->resetConfiguration();
+               }
+       }
+
+       void test1()
+       {
+               
PropertyConfigurator::configure(LOG4CXX_FILE("input/fmtLayout1.properties"));
+               common();
+               LOGUNIT_ASSERT(Compare::compare(TEMP, 
LOG4CXX_FILE("witness/patternLayout.1")));
+       }
+
+       void test1_expanded()
+       {
+               
PropertyConfigurator::configure(LOG4CXX_FILE("input/fmtLayout1_expanded.properties"));
+               common();
+               LOGUNIT_ASSERT(Compare::compare(TEMP, 
LOG4CXX_FILE("witness/patternLayout.1")));
+       }
+
+       void test10()
+       {
+               
PropertyConfigurator::configure(LOG4CXX_FILE("input/fmtLayout10.properties"));
+               common();
+
+               ControlFilter filter1;
+               filter1 << PAT6;
+               ThreadFilter filter2;
+               LineNumberFilter filter3;
+               FilenameFilter filenameFilter(__FILE__, 
"patternlayouttest.cpp");
+
+
+               std::vector<Filter*> filters;
+               filters.push_back(&filenameFilter);
+               filters.push_back(&filter1);
+               filters.push_back(&filter2);
+               filters.push_back(&filter3);
+
+
+               try
+               {
+                       Transformer::transform(TEMP, FILTERED, filters);
+               }
+               catch (UnexpectedFormatException& e)
+               {
+                       std::cout << "UnexpectedFormatException :" << e.what() 
<< std::endl;
+                       throw;
+               }
+
+               LOGUNIT_ASSERT(Compare::compare(FILTERED, 
LOG4CXX_FILE("witness/patternLayout.10")));
+       }
+
+       void test_date(){
+               std::tm tm = {};
+               std::stringstream ss("2013-04-11 08:35:34");
+               ss >> std::get_time(&tm, "%Y-%m-%d %H:%M:%S");
+               auto tp = 
std::chrono::system_clock::from_time_t(std::mktime(&tm));
+               uint64_t millis = 
std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch()).count();
+
+               log4cxx::helpers::Date::setGetCurrentTimeFunction([millis](){
+                       return millis;
+               });
+
+               log4cxx::spi::LoggingEventPtr logEvt = 
std::make_shared<log4cxx::spi::LoggingEvent>( "foo",
+                                                                               
                                                                                
                         Level::getInfo(),
+                                                                               
                                                                                
                         "A Message",
+                                                                               
                                                                                
                         log4cxx::spi::LocationInfo::getLocationUnavailable());
+               FMTLayout layout("{d:%Y-%m-%d %H:%M:%S} {message}" );
+               LogString output;
+               log4cxx::helpers::Pool pool;
+               layout.format( output, logEvt, pool);
+
+               log4cxx::helpers::Date::setGetCurrentTimeFunction(nullptr);
+
+               LOGUNIT_ASSERT_EQUAL("2013-04-11 09:35:34 A Message", output);
+       }
+
+       std::string createMessage(Pool & pool, int i)
+       {
+               std::string msg("Message ");
+               msg.append(pool.itoa(i));
+               return msg;
+       }
+
+       void common()
+       {
+               int i = -1;
+
+               Pool pool;
+
+
+               LOG4CXX_DEBUG(logger, createMessage(pool, ++i));
+               LOG4CXX_DEBUG(root, createMessage(pool, i));
+
+               LOG4CXX_INFO(logger, createMessage(pool, ++i));
+               LOG4CXX_INFO(root, createMessage(pool, i));
+
+               LOG4CXX_WARN(logger, createMessage(pool, ++i));
+               LOG4CXX_WARN(root, createMessage(pool, i));
+
+               LOG4CXX_ERROR(logger, createMessage(pool, ++i));
+               LOG4CXX_ERROR(root, createMessage(pool, i));
+
+               LOG4CXX_FATAL(logger, createMessage(pool, ++i));
+               LOG4CXX_FATAL(root, createMessage(pool, i));
+       }
+
+       private:
+               static const LogString FILTERED;
+               static const LogString TEMP;
+
+};
+
+const LogString FMTTestCase::TEMP(LOG4CXX_STR("output/fmtlayout"));
+const LogString FMTTestCase::FILTERED(LOG4CXX_STR("output/fmtlayoutfiltered"));
+
+
+LOGUNIT_TEST_SUITE_REGISTRATION(FMTTestCase);
diff --git a/src/test/resources/input/fmtLayout1.properties 
b/src/test/resources/input/fmtLayout1.properties
new file mode 100644
index 00000000..ecd14df4
--- /dev/null
+++ b/src/test/resources/input/fmtLayout1.properties
@@ -0,0 +1,21 @@
+# 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.rootCategory=DEBUG, testAppender
+log4j.appender.testAppender=org.apache.log4j.FileAppender
+log4j.appender.testAppender.file=output/fmtlayout
+log4j.appender.testAppender.Append=false
+log4j.appender.testAppender.layout=org.apache.log4j.FMTLayout
+log4j.appender.testAppender.layout.ConversionPattern={p:<5} - {m}{n}
diff --git a/src/test/resources/input/fmtLayout10.properties 
b/src/test/resources/input/fmtLayout10.properties
new file mode 100644
index 00000000..3608cc74
--- /dev/null
+++ b/src/test/resources/input/fmtLayout10.properties
@@ -0,0 +1,21 @@
+# 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.rootCategory=DEBUG, testAppender
+log4j.appender.testAppender=org.apache.log4j.FileAppender
+log4j.appender.testAppender.File= output/fmtlayout
+log4j.appender.testAppender.Append= false 
+log4j.appender.testAppender.layout=org.apache.log4j.FMTLayout 
+log4j.appender.testAppender.layout.ConversionPattern=[{t}] {p:<5} {l}: {m}{n}
diff --git a/src/test/resources/input/fmtLayout1_expanded.properties 
b/src/test/resources/input/fmtLayout1_expanded.properties
new file mode 100644
index 00000000..70c32d8e
--- /dev/null
+++ b/src/test/resources/input/fmtLayout1_expanded.properties
@@ -0,0 +1,21 @@
+# 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.rootCategory=DEBUG, testAppender
+log4j.appender.testAppender=org.apache.log4j.FileAppender
+log4j.appender.testAppender.file=output/fmtlayout
+log4j.appender.testAppender.Append=false
+log4j.appender.testAppender.layout=org.apache.log4j.FMTLayout
+log4j.appender.testAppender.layout.ConversionPattern={level:<5} - 
{message}{newline}

Reply via email to