]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1174] Changed stats to use C++11 chrono
authorFrancis Dupont <fdupont@isc.org>
Tue, 31 Mar 2020 16:39:50 +0000 (18:39 +0200)
committerTomek Mrugalski <tomek@isc.org>
Tue, 14 Jul 2020 13:37:51 +0000 (15:37 +0200)
15 files changed:
m4macros/ax_cpp11.m4
src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc
src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc
src/lib/stats/observation.cc
src/lib/stats/observation.h
src/lib/stats/stats_mgr.cc
src/lib/stats/stats_mgr.h
src/lib/stats/tests/context_unittest.cc
src/lib/stats/tests/observation_unittest.cc
src/lib/stats/tests/stats_mgr_unittest.cc
src/lib/util/Makefile.am
src/lib/util/chrono_time_utils.cc [new file with mode: 0644]
src/lib/util/chrono_time_utils.h [new file with mode: 0644]
src/lib/util/tests/Makefile.am
src/lib/util/tests/chrono_time_utils_unittest.cc [new file with mode: 0644]

index a63ea5e93b3adc3349cd510dc2d53bb800ffa95d..61767280163c3a80e9cf6cc6ada58c2127e3671b 100644 (file)
@@ -153,7 +153,7 @@ for retry in "none" "--std=c++11" "--std=c++0x" "--std=c++1x" "fail"; do
                 continue])
 
        AC_MSG_CHECKING(range-for support)
-       feature="constexpr"
+       feature="range-for support"
        AC_COMPILE_IFELSE(
                [AC_LANG_PROGRAM(
                        [#include <vector>
@@ -220,11 +220,22 @@ for retry in "none" "--std=c++11" "--std=c++0x" "--std=c++1x" "fail"; do
                        [#include <atomic>
                         std::atomic_flag flag;],
                        [])],
-               [AC_MSG_RESULT([yes])
-                break],
+               [AC_MSG_RESULT([yes])],
                [AC_MSG_RESULT([no])
                 continue])
 
+        AC_MSG_CHECKING(chrono support)
+        feature="chrono"
+        AC_COMPILE_IFELSE(
+               [AC_LANG_PROGRAM(
+                       [#include <chrono>
+                        using namespace std::chrono;],
+                       [auto now = high_resolution_clock::now();])],
+               [AC_MSG_RESULT([yes])
+                 break],
+                [AC_MSG_RESULT([no])
+                 continue])
+
 done
 
-])dnl AX_ISC_RPATH
+])dnl AX_ISC_CPP11
index 107caea4b1380bb4c194be70e4ebdf162f7db790..3e1645516c20878929cda2f46254b6e89851dc21 100644 (file)
@@ -21,8 +21,8 @@
 #include <hooks/hooks_manager.h>
 #include <log/logger_support.h>
 #include <stats/stats_mgr.h>
-#include <util/boost_time_utils.h>
 #include <util/multi_threading_mgr.h>
+#include <util/chrono_time_utils.h>
 #include <testutils/io_utils.h>
 #include <testutils/unix_control_client.h>
 #include <testutils/sandbox.h>
@@ -634,7 +634,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, controlChannelStats) {
     s << "{ \"arguments\": { ";
     for (auto st = initial_stats.begin(); st != initial_stats.end();) {
         s << "\"" << *st << "\": [ [ 0, \"";
-        s << isc::util::ptimeToText(StatsMgr::instance().getObservation(*st)->getInteger().second);
+        s << isc::util::clockToText(StatsMgr::instance().getObservation(*st)->getInteger().second);
         s << "\" ] ]";
         if (++st != initial_stats.end()) {
             s << ", ";
index 20ce9080f5704204d6c62399f771e67f7fbbb8d2..69fe15f0e8876bc7265dc64c876dffe152e51d5d 100644 (file)
 #include <hooks/hooks_manager.h>
 #include <log/logger_support.h>
 #include <stats/stats_mgr.h>
-#include <util/boost_time_utils.h>
 #include <util/multi_threading_mgr.h>
 #include <testutils/io_utils.h>
 #include <testutils/unix_control_client.h>
 #include <testutils/sandbox.h>
+#include <util/chrono_time_utils.h>
 
 #include "marker_file.h"
 #include "test_libraries.h"
@@ -1191,7 +1191,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, controlChannelStats) {
     s << "{ \"arguments\": { ";
     for (auto st = initial_stats.begin(); st != initial_stats.end();) {
         s << "\"" << *st << "\": [ [ 0, \"";
-        s << isc::util::ptimeToText(StatsMgr::instance().getObservation(*st)->getInteger().second);
+        s << isc::util::clockToText(StatsMgr::instance().getObservation(*st)->getInteger().second);
         s << "\" ] ]";
         if (++st != initial_stats.end()) {
             s << ", ";
index 926feff85f11d39680ce4368822a3f4f54a5ed2a..711df8874a0737f46fb320c6d8472828bc155bf5 100644 (file)
@@ -7,15 +7,14 @@
 #include <config.h>
 
 #include <stats/observation.h>
-#include <util/boost_time_utils.h>
+#include <util/chrono_time_utils.h>
 #include <cc/data.h>
-#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/date_time/gregorian/gregorian.hpp>
+#include <chrono>
 #include <utility>
 
 using namespace std;
+using namespace std::chrono;
 using namespace isc::data;
-using namespace boost::posix_time;
 
 namespace isc {
 namespace stats {
@@ -195,10 +194,10 @@ void Observation::setValueInternal(SampleType value, StorageType& storage,
     }
 
     if (storage.empty()) {
-        storage.push_back(make_pair(value, microsec_clock::local_time()));
+        storage.push_back(make_pair(value, SampleClock::now()));
     } else {
         // Storing of more than one sample
-        storage.push_front(make_pair(value, microsec_clock::local_time()));
+        storage.push_front(make_pair(value, SampleClock::now()));
 
         if (max_sample_count_.first) {
             // if max_sample_count_ is set to true
@@ -407,7 +406,7 @@ Observation::getJSON() const {
         for (std::list<IntegerSample>::iterator it = s.begin(); it != s.end(); ++it) {
             entry = isc::data::Element::createList();
             value = isc::data::Element::create(static_cast<int64_t>((*it).first));
-            timestamp = isc::data::Element::create(isc::util::ptimeToText((*it).second));
+            timestamp = isc::data::Element::create(isc::util::clockToText((*it).second));
 
             entry->add(value);
             entry->add(timestamp);
@@ -424,7 +423,7 @@ Observation::getJSON() const {
         for (std::list<FloatSample>::iterator it = s.begin(); it != s.end(); ++it) {
             entry = isc::data::Element::createList();
             value = isc::data::Element::create((*it).first);
-            timestamp = isc::data::Element::create(isc::util::ptimeToText((*it).second));
+            timestamp = isc::data::Element::create(isc::util::clockToText((*it).second));
 
             entry->add(value);
             entry->add(timestamp);
@@ -441,7 +440,7 @@ Observation::getJSON() const {
         for (std::list<DurationSample>::iterator it = s.begin(); it != s.end(); ++it) {
             entry = isc::data::Element::createList();
             value = isc::data::Element::create(isc::util::durationToText((*it).first));
-            timestamp = isc::data::Element::create(isc::util::ptimeToText((*it).second));
+            timestamp = isc::data::Element::create(isc::util::clockToText((*it).second));
 
             entry->add(value);
             entry->add(timestamp);
@@ -458,7 +457,7 @@ Observation::getJSON() const {
         for (std::list<StringSample>::iterator it = s.begin(); it != s.end(); ++it) {
             entry = isc::data::Element::createList();
             value = isc::data::Element::create((*it).first);
-            timestamp = isc::data::Element::create(isc::util::ptimeToText((*it).second));
+            timestamp = isc::data::Element::create(isc::util::clockToText((*it).second));
 
             entry->add(value);
             entry->add(timestamp);
@@ -489,7 +488,7 @@ void Observation::reset() {
     }
     case STAT_DURATION: {
         duration_samples_.clear();
-        setValue(time_duration(0, 0, 0, 0));
+        setValue(StatsDuration::zero());
         return;
     }
     case STAT_STRING: {
index 306d89335d38e4d96f24144c48f003eee0be0b71..f1c6583e48c395b8ee24908c890a59bc58a46e6c 100644 (file)
@@ -10,8 +10,7 @@
 #include <cc/data.h>
 #include <exceptions/exceptions.h>
 #include <boost/shared_ptr.hpp>
-#include <boost/date_time/time_duration.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <chrono>
 #include <list>
 #include <stdint.h>
 
@@ -28,9 +27,13 @@ public:
         isc::Exception(file, line, what) {}
 };
 
+/// @brief Define clock
+///
+typedef std::chrono::system_clock SampleClock;
+
 /// @brief Defines duration resolution
 ///
-typedef boost::posix_time::time_duration StatsDuration;
+typedef std::chrono::system_clock::duration StatsDuration;
 
 /// @defgroup stat_samples Specifies supported observation types.
 ///
@@ -39,16 +42,16 @@ typedef boost::posix_time::time_duration StatsDuration;
 /// @{
 
 /// @brief Integer (implemented as signed 64-bit integer)
-typedef std::pair<int64_t, boost::posix_time::ptime> IntegerSample;
+typedef std::pair<int64_t, SampleClock::time_point> IntegerSample;
 
 /// @brief Float (implemented as double precision)
-typedef std::pair<double, boost::posix_time::ptime> FloatSample;
+typedef std::pair<double, SampleClock::time_point> FloatSample;
 
 /// @brief Time Duration
-typedef std::pair<StatsDuration, boost::posix_time::ptime> DurationSample;
+typedef std::pair<StatsDuration, SampleClock::time_point> DurationSample;
 
 /// @brief String
-typedef std::pair<std::string, boost::posix_time::ptime> StringSample;
+typedef std::pair<std::string, SampleClock::time_point> StringSample;
 
 /// @}
 
@@ -121,9 +124,9 @@ public:
     /// @param duration determines maximum age of samples
     /// Example:
     /// To set a statistic to keep observations for the last 5 minutes, call:
-    /// setMaxSampleAge(time_duration(0, 5, 0, 0));
+    /// setMaxSampleAge(std::chrono::minutes(5));
     /// To revert statistic to a single value, call:
-    /// setMaxSampleAge(time_duration(0, 0, 0, 0));
+    /// setMaxSampleAge(StatsDuration::zero());
     void setMaxSampleAge(const StatsDuration& duration);
 
     /// @brief Determines how many samples of a given statistic should be kept.
@@ -388,7 +391,7 @@ private:
 
     /// @brief Maximum timespan of samples
     /// The limit is represented as a pair
-    /// of bool value and StatsDuration(boost::posix_time::time_duration)
+    /// of bool value and StatsDuration
     /// Only one kind of limit can be active
     /// The bool value informs which limit
     /// is available
@@ -399,7 +402,8 @@ private:
     ///
     /// By default the MaxSampleCount is set to 20
     /// and MaxSampleAge is disabled
-    static std::pair<bool, StatsDuration> default_max_sample_age_;
+    std::pair<bool, StatsDuration> max_sample_age_ = std::make_pair(false,
+        StatsDuration::zero());
 
     /// @defgroup samples_storage Storage for supported observations
     ///
index 67f5e5a3384897f39795925517c3e28f398fd742..8c4c93a3804f75fcb734831a9e2b093fc91cc75f 100644 (file)
 #include <stats/stats_mgr.h>
 #include <cc/data.h>
 #include <cc/command_interpreter.h>
-#include <util/boost_time_utils.h>
 #include <util/multi_threading_mgr.h>
-#include <boost/date_time/posix_time/posix_time.hpp>
 #include <boost/make_shared.hpp>
+#include <chrono>
 
 using namespace std;
+using namespace std::chrono;
 using namespace isc::data;
 using namespace isc::config;
 using namespace isc::util;
@@ -615,13 +615,7 @@ StatsMgr::getStatDuration(const ConstElementPtr& params,
         reason = "Missing mandatory 'duration' parameter.";
         return (false);
     }
-    int64_t time_duration = stat_duration->intValue();
-    int64_t hours = time_duration / 3600;
-    time_duration -= hours * 3600;
-    int64_t minutes = time_duration / 60;
-    time_duration -= minutes * 60;
-    int64_t seconds = time_duration;
-    duration = boost::posix_time::time_duration(hours, minutes, seconds, 0);
+    duration = std::chrono::seconds(stat_duration->intValue());
     return (true);
 }
 
index 9723c6b0aead6c7047f7d76ef99666919763dd08..4b5f576644bd05731d23e876c23897d15f66236c 100644 (file)
@@ -137,9 +137,9 @@ public:
     /// setMaxSampleCount() below.
     /// Example:
     /// To set a statistic to keep observations for the last 5 minutes, call:
-    /// setMaxSampleAge("incoming-packets", time_duration(0, 5, 0, 0));
+    /// setMaxSampleAge("incoming-packets", StatsDuration::minutes(5));
     /// to revert statistic to a single value, call:
-    /// setMaxSampleAge("incoming-packets", time_duration(0, 0, 0, 0));
+    /// setMaxSampleAge("incoming-packets", StatsDuration:zero());
     ///
     /// @param name name of the observation
     /// @param duration determines maximum age of samples
index 329cdae36f3b3d7dac539440cd06f83c8d932c5c..777db8bd8d80a9b5d9ade75cf535c74b97806c76 100644 (file)
@@ -8,13 +8,13 @@
 
 #include <stats/context.h>
 #include <gtest/gtest.h>
-#include <util/boost_time_utils.h>
+#include <util/chrono_time_utils.h>
 #include <string>
 
 using namespace isc::data;
 using namespace isc::stats;
-using namespace boost::posix_time;
 using namespace std;
+using namespace std::chrono;
 
 // Basic test that checks get, add, del methods
 TEST(ContextTest, basic) {
@@ -109,15 +109,16 @@ TEST(ContextTest, basic) {
     EXPECT_EQ(from_ctx->getMaxSampleCount().second, 50);
 
     // Set sample age for all statistics
-    EXPECT_NO_THROW(ctx.setMaxSampleAgeAll(millisec::time_duration(0, 4, 5, 3)));
+    const StatsDuration& dur(minutes(4) + seconds(5) + milliseconds(3));
+    EXPECT_NO_THROW(ctx.setMaxSampleAgeAll(dur));
 
     EXPECT_NO_THROW(from_ctx = ctx.get("alpha"));
     ASSERT_TRUE(from_ctx);
-    EXPECT_EQ(from_ctx->getMaxSampleAge().second, millisec::time_duration(0, 4, 5, 3));
+    EXPECT_EQ(from_ctx->getMaxSampleAge().second, dur);
 
     EXPECT_NO_THROW(from_ctx = ctx.get("gamma"));
     ASSERT_TRUE(from_ctx);
-    EXPECT_EQ(from_ctx->getMaxSampleAge().second, millisec::time_duration(0, 4, 5, 3));
+    EXPECT_EQ(from_ctx->getMaxSampleAge().second, dur);
 
     // Clear all statistics.
     EXPECT_NO_THROW(ctx.clear());
index 32e07bafdf3d2447adb259eead4448184a93c185..6c414ccf9ddeec7841d42a6bc7634e68149a5994 100644 (file)
@@ -8,9 +8,8 @@
 
 #include <stats/observation.h>
 #include <exceptions/exceptions.h>
-#include <util/boost_time_utils.h>
+#include <util/chrono_time_utils.h>
 #include <boost/shared_ptr.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
 #include <gtest/gtest.h>
 
 #include <iostream>
 
 using namespace isc;
 using namespace isc::stats;
-using namespace boost::posix_time;
+using namespace std::chrono;
 
 namespace {
 
+const StatsDuration& dur1234(hours(1) + minutes(2) + seconds(3) +
+                             milliseconds(4));
+const StatsDuration& dur5678(hours(5) + minutes(6) + seconds(7) +
+                             milliseconds(8));
+const StatsDuration& dur681012(hours(6) + minutes(8) + seconds(10) +
+                               milliseconds(12));
+const StatsDuration& dur453(minutes(4) + seconds(5) + milliseconds(3));
+
 /// @brief Test class for Observation
 ///
 /// This simple fixture class initializes four observations:
@@ -36,7 +43,7 @@ public:
     ObservationTest() :
         a("alpha", static_cast<int64_t>(1234)), // integer
         b("beta", 12.34), // float
-        c("gamma", millisec::time_duration(1, 2, 3, 4)), // duration
+        c("gamma", dur1234), // duration
         d("delta", "1234") { // string
     }
 
@@ -56,8 +63,7 @@ TEST_F(ObservationTest, constructor) {
 
     EXPECT_EQ(1234, a.getInteger().first);
     EXPECT_EQ(12.34, b.getFloat().first);
-    EXPECT_EQ(millisec::time_duration(1, 2, 3, 4),
-              c.getDuration().first);
+    EXPECT_EQ(dur1234, c.getDuration().first);
     EXPECT_EQ("1234", d.getString().first);
 
     // Let's check that attempting to get a different type
@@ -84,23 +90,23 @@ TEST_F(ObservationTest, constructor) {
 TEST_F(ObservationTest, setValue) {
     EXPECT_NO_THROW(a.setValue(static_cast<int64_t>(5678)));
     EXPECT_NO_THROW(b.setValue(56e+78));
-    EXPECT_NO_THROW(c.setValue(millisec::time_duration(5, 6, 7, 8)));
+    EXPECT_NO_THROW(c.setValue(dur5678));
     EXPECT_NO_THROW(d.setValue("fiveSixSevenEight"));
 
 
     EXPECT_EQ(5678, a.getInteger().first);
     EXPECT_EQ(56e+78, b.getFloat().first);
-    EXPECT_EQ(millisec::time_duration(5, 6, 7, 8), c.getDuration().first);
+    EXPECT_EQ(dur5678, c.getDuration().first);
     EXPECT_EQ("fiveSixSevenEight", d.getString().first);
 
     // Now check whether setting value to a different type does
     // throw an exception
     EXPECT_THROW(a.setValue(56e+78), InvalidStatType);
-    EXPECT_THROW(a.setValue(millisec::time_duration(5, 6, 7, 8)), InvalidStatType);
+    EXPECT_THROW(a.setValue(dur5678), InvalidStatType);
     EXPECT_THROW(a.setValue("fiveSixSevenEight"), InvalidStatType);
 
     EXPECT_THROW(b.setValue(static_cast<int64_t>(5678)), InvalidStatType);
-    EXPECT_THROW(b.setValue(millisec::time_duration(5, 6, 7, 8)), InvalidStatType);
+    EXPECT_THROW(b.setValue(dur5678), InvalidStatType);
     EXPECT_THROW(b.setValue("fiveSixSevenEight"), InvalidStatType);
 
     EXPECT_THROW(c.setValue(static_cast<int64_t>(5678)), InvalidStatType);
@@ -109,7 +115,7 @@ TEST_F(ObservationTest, setValue) {
 
     EXPECT_THROW(d.setValue(static_cast<int64_t>(5678)), InvalidStatType);
     EXPECT_THROW(d.setValue(56e+78), InvalidStatType);
-    EXPECT_THROW(d.setValue(millisec::time_duration(5, 6, 7, 8)), InvalidStatType);
+    EXPECT_THROW(d.setValue(dur5678), InvalidStatType);
 }
 
 // This test checks whether it is possible to add value to existing
@@ -120,12 +126,12 @@ TEST_F(ObservationTest, addValue) {
 
     EXPECT_NO_THROW(a.addValue(static_cast<int64_t>(5678)));
     EXPECT_NO_THROW(b.addValue(56.78));
-    EXPECT_NO_THROW(c.addValue(millisec::time_duration(5, 6, 7, 8)));
+    EXPECT_NO_THROW(c.addValue(dur5678));
     EXPECT_NO_THROW(d.addValue("fiveSixSevenEight"));
 
     EXPECT_EQ(6912, a.getInteger().first);
     EXPECT_EQ(69.12, b.getFloat().first);
-    EXPECT_EQ(millisec::time_duration(6, 8, 10, 12), c.getDuration().first);
+    EXPECT_EQ(dur681012, c.getDuration().first);
     EXPECT_EQ("1234fiveSixSevenEight", d.getString().first);
 
     ASSERT_EQ(a.getSize(), 2);
@@ -140,18 +146,18 @@ TEST_F(ObservationTest, moreThanOne) {
     // Arrays of 4 types of samples
     int64_t int_samples[3] = {1234, 6912, 5678};
     double float_samples[3] = {12.34, 69.12, 56e+78};
-    millisec::time_duration duration_samples[3] = {millisec::time_duration(1, 2, 3, 4),
-        millisec::time_duration(6, 8, 10, 12), millisec::time_duration(5, 6, 7, 8)};
+    StatsDuration duration_samples[3] = {dur1234,
+        dur681012, dur5678};
     std::string string_samples[3] = {"1234", "1234fiveSixSevenEight", "fiveSixSevenEight"};
 
     EXPECT_NO_THROW(a.addValue(static_cast<int64_t>(5678)));
     EXPECT_NO_THROW(b.addValue(56.78));
-    EXPECT_NO_THROW(c.addValue(millisec::time_duration(5, 6, 7, 8)));
+    EXPECT_NO_THROW(c.addValue(dur5678));
     EXPECT_NO_THROW(d.addValue("fiveSixSevenEight"));
 
     EXPECT_NO_THROW(a.setValue(static_cast<int64_t>(5678)));
     EXPECT_NO_THROW(b.setValue(56e+78));
-    EXPECT_NO_THROW(c.setValue(millisec::time_duration(5, 6, 7, 8)));
+    EXPECT_NO_THROW(c.setValue(dur5678));
     EXPECT_NO_THROW(d.setValue("fiveSixSevenEight"));
 
     ASSERT_EQ(a.getSize(), 3);
@@ -203,7 +209,7 @@ TEST_F(ObservationTest, getSize) {
 
     a.addValue(static_cast<int64_t>(5678));
     b.addValue(56.78);
-    c.addValue(millisec::time_duration(5, 6, 7, 8));
+    c.addValue(dur5678);
     d.addValue("fiveSixSevenEight");
 
     EXPECT_NO_THROW(a.getSize());
@@ -219,7 +225,7 @@ TEST_F(ObservationTest, getSize) {
 
     a.setValue(static_cast<int64_t>(5678));
     b.setValue(56e+78);
-    c.setValue(millisec::time_duration(5, 6, 7, 8));
+    c.setValue(dur5678);
     d.setValue("fiveSixSevenEight");
 
     EXPECT_NO_THROW(a.getSize());
@@ -245,10 +251,10 @@ TEST_F(ObservationTest, setCountLimit) {
     std::string string_samples[22] = {"a", "b", "c", "d", "e", "f", "g", "h",
             "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u",
             "v"};
-    millisec::time_duration duration_samples[22];
+    StatsDuration duration_samples[22];
 
     for (uint32_t i = 0; i < 22; ++i) {
-        duration_samples[i] = millisec::time_duration(0, 0, 0, i);
+        duration_samples[i] = milliseconds(i);
     }
 
     // By default the max_sample_count is set to 20 and max_sample_age
@@ -355,7 +361,7 @@ TEST_F(ObservationTest, setCountLimit) {
     // Add new values to each type of Observation
     a.setValue(static_cast<int64_t>(21));
     b.setValue(21.0);
-    c.setValue(millisec::time_duration(0, 0, 0, 21));
+    c.setValue(milliseconds(21));
     d.setValue("v");
 
     samples_int = a.getIntegers();
@@ -394,29 +400,29 @@ TEST_F(ObservationTest, setCountLimit) {
 // Checks whether setting age limits works properly
 TEST_F(ObservationTest, setAgeLimit) {
     // Set max_sample_age to 1 second
-    ASSERT_NO_THROW(c.setMaxSampleAge(millisec::time_duration(0, 0, 1, 0)));
+    ASSERT_NO_THROW(c.setMaxSampleAge(seconds(1)));
     // Add some value
-    c.setValue(millisec::time_duration(0, 0, 0, 5));
+    c.setValue(milliseconds(5));
     // Wait 1 second
     sleep(1);
     // and add new value
-    c.setValue(millisec::time_duration(0, 0, 0, 3));
+    c.setValue(milliseconds(3));
 
     // get the list of all samples
     std::list<DurationSample> samples_duration = c.getDurations();
     // check whether the size of samples is equal to 1
     ASSERT_EQ(c.getSize(), 1);
     // and whether it contains an expected value
-    EXPECT_EQ((*samples_duration.begin()).first, millisec::time_duration(0, 0, 0, 3));
+    EXPECT_EQ((*samples_duration.begin()).first, milliseconds(3));
 
     // Wait 1 second to ensure removing previously set value
     sleep(1);
     // add 10 new values
     for (uint32_t i = 0; i < 10; ++i) {
-        c.setValue(millisec::time_duration(0, 0, 0, i));
+        c.setValue(milliseconds(i));
     }
     // change the max_sample_age to smaller
-    ASSERT_NO_THROW(c.setMaxSampleAge(millisec::time_duration(0, 0, 0, 300)));
+    ASSERT_NO_THROW(c.setMaxSampleAge(milliseconds(300)));
 
     samples_duration = c.getDurations();
     // check whether the size of samples is equal to 10
@@ -425,7 +431,7 @@ TEST_F(ObservationTest, setAgeLimit) {
     // and whether it contains expected values
     uint32_t i = 9;
     for (std::list<DurationSample>::iterator it = samples_duration.begin(); it != samples_duration.end(); ++it) {
-        EXPECT_EQ((*it).first, millisec::time_duration(0, 0, 0, i));
+        EXPECT_EQ((*it).first, milliseconds(i));
         --i;
     }
 }
@@ -450,20 +456,20 @@ TEST_F(ObservationTest, getLimits) {
     EXPECT_EQ(d.getMaxSampleCount().second, 20);
 
     // change limit to time duration
-    ASSERT_NO_THROW(a.setMaxSampleAge(millisec::time_duration(0, 4, 5, 3)));
-    ASSERT_NO_THROW(b.setMaxSampleAge(millisec::time_duration(0, 4, 5, 3)));
-    ASSERT_NO_THROW(c.setMaxSampleAge(millisec::time_duration(0, 4, 5, 3)));
-    ASSERT_NO_THROW(d.setMaxSampleAge(millisec::time_duration(0, 4, 5, 3)));
+    ASSERT_NO_THROW(a.setMaxSampleAge(dur453));
+    ASSERT_NO_THROW(b.setMaxSampleAge(dur453));
+    ASSERT_NO_THROW(c.setMaxSampleAge(dur453));
+    ASSERT_NO_THROW(d.setMaxSampleAge(dur453));
 
     EXPECT_EQ(a.getMaxSampleAge().first, true);
     EXPECT_EQ(b.getMaxSampleAge().first, true);
     EXPECT_EQ(c.getMaxSampleAge().first, true);
     EXPECT_EQ(d.getMaxSampleAge().first, true);
 
-    EXPECT_EQ(a.getMaxSampleAge().second, millisec::time_duration(0, 4, 5, 3));
-    EXPECT_EQ(b.getMaxSampleAge().second, millisec::time_duration(0, 4, 5, 3));
-    EXPECT_EQ(c.getMaxSampleAge().second, millisec::time_duration(0, 4, 5, 3));
-    EXPECT_EQ(d.getMaxSampleAge().second, millisec::time_duration(0, 4, 5, 3));
+    EXPECT_EQ(a.getMaxSampleAge().second, dur453);
+    EXPECT_EQ(b.getMaxSampleAge().second, dur453);
+    EXPECT_EQ(c.getMaxSampleAge().second, dur453);
+    EXPECT_EQ(d.getMaxSampleAge().second, dur453);
 
     EXPECT_EQ(a.getMaxSampleCount().first, false);
     EXPECT_EQ(b.getMaxSampleCount().first, false);
@@ -480,12 +486,12 @@ TEST_F(ObservationTest, getLimits) {
 
 // Test checks whether timing is reported properly.
 TEST_F(ObservationTest, timers) {
-    ptime before = microsec_clock::local_time();
+    auto before = SampleClock::now();
     b.setValue(123.0); // Set it to a random value and record the time.
 
     // Allow a bit of imprecision. This test allows 500ms. That should be ok,
     // when running on virtual machines.
-    ptime after = before + milliseconds(500);
+    auto after = before + milliseconds(500);
 
     // Now wait some time. We want to confirm that the timestamp recorded is the
     // time the observation took place, not current time.
@@ -505,12 +511,12 @@ TEST_F(ObservationTest, timers) {
 TEST_F(ObservationTest, integerToJSON) {
     // String which contains first added sample
     std::string first_sample = ", [ 1234, \"" +
-        isc::util::ptimeToText(a.getInteger().second) + "\" ] ]";
+        isc::util::clockToText(a.getInteger().second) + "\" ] ]";
 
     a.setValue(static_cast<int64_t>(1234));
 
     std::string exp = "[ [ 1234, \"" +
-        isc::util::ptimeToText(a.getInteger().second) + "\" ]" + first_sample;
+        isc::util::clockToText(a.getInteger().second) + "\" ]" + first_sample;
 
     std::cout << a.getJSON()->str() << std::endl;
     EXPECT_EQ(exp, a.getJSON()->str());
@@ -523,7 +529,7 @@ TEST_F(ObservationTest, integerToJSON) {
 TEST_F(ObservationTest, floatToJSON) {
     // String which contains first added sample
     std::string first_sample = ", [ 12.34, \"" +
-        isc::util::ptimeToText(b.getFloat().second) + "\" ] ]";
+        isc::util::clockToText(b.getFloat().second) + "\" ] ]";
 
     // Let's use a value that converts easily to floating point.
     // No need to deal with infinite fractions in binary systems.
@@ -531,7 +537,7 @@ TEST_F(ObservationTest, floatToJSON) {
     b.setValue(1234.5);
 
     std::string exp = "[ [ 1234.5, \"" +
-        isc::util::ptimeToText(b.getFloat().second) + "\" ]" + first_sample;
+        isc::util::clockToText(b.getFloat().second) + "\" ]" + first_sample;
 
     std::cout << b.getJSON()->str() << std::endl;
     EXPECT_EQ(exp, b.getJSON()->str());
@@ -542,14 +548,14 @@ TEST_F(ObservationTest, floatToJSON) {
 // details.
 TEST_F(ObservationTest, durationToJSON) {
     // String which contains first added sample
-    std::string first_sample = ", [ \"01:02:03.000004\", \"" +
-        isc::util::ptimeToText(c.getDuration().second) + "\" ] ]";
+    std::string first_sample = ", [ \"01:02:03.004000\", \"" +
+        isc::util::clockToText(c.getDuration().second) + "\" ] ]";
 
     // 1 hour 2 minutes 3 seconds and 4 milliseconds
-    c.setValue(time_duration(1, 2, 3, 4));
+    c.setValue(dur1234);
 
-    std::string exp = "[ [ \"01:02:03.000004\", \"" +
-        isc::util::ptimeToText(c.getDuration().second) + "\" ]" + first_sample;
+    std::string exp = "[ [ \"01:02:03.004000\", \"" +
+        isc::util::clockToText(c.getDuration().second) + "\" ]" + first_sample;
 
     std::cout << c.getJSON()->str() << std::endl;
     EXPECT_EQ(exp, c.getJSON()->str());
@@ -561,12 +567,12 @@ TEST_F(ObservationTest, durationToJSON) {
 TEST_F(ObservationTest, stringToJSON) {
     // String which contains first added sample
     std::string first_sample = ", [ \"1234\", \"" +
-        isc::util::ptimeToText(d.getString().second) + "\" ] ]";
+        isc::util::clockToText(d.getString().second) + "\" ] ]";
 
     d.setValue("Lorem ipsum dolor sit amet");
 
     std::string exp = "[ [ \"Lorem ipsum dolor sit amet\", \"" +
-        isc::util::ptimeToText(d.getString().second) + "\" ]" + first_sample;
+        isc::util::clockToText(d.getString().second) + "\" ]" + first_sample;
 
     std::cout << d.getJSON()->str() << std::endl;
     EXPECT_EQ(exp, d.getJSON()->str());
@@ -576,7 +582,7 @@ TEST_F(ObservationTest, stringToJSON) {
 TEST_F(ObservationTest, reset) {
     EXPECT_NO_THROW(a.addValue(static_cast<int64_t>(5678)));
     EXPECT_NO_THROW(b.addValue(56.78));
-    EXPECT_NO_THROW(c.addValue(millisec::time_duration(5, 6, 7, 8)));
+    EXPECT_NO_THROW(c.addValue(dur5678));
     EXPECT_NO_THROW(d.addValue("fiveSixSevenEight"));
 
     a.reset(); // integer
@@ -586,7 +592,7 @@ TEST_F(ObservationTest, reset) {
 
     EXPECT_EQ(0, a.getInteger().first);
     EXPECT_EQ(0.0, b.getFloat().first);
-    EXPECT_EQ(time_duration(0, 0, 0, 0), c.getDuration().first);
+    EXPECT_EQ(StatsDuration::zero(), c.getDuration().first);
     EXPECT_EQ("", d.getString().first);
 
     ASSERT_EQ(a.getSize(), 1);
index 178de720470af9a363e9c76ed22cd29537438e0c..7a4f5d9077a772c86b5f9a9da77aa7fe5d2ae471 100644 (file)
@@ -10,8 +10,7 @@
 #include <exceptions/exceptions.h>
 #include <cc/data.h>
 #include <cc/command_interpreter.h>
-#include <util/boost_time_utils.h>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <util/chrono_time_utils.h>
 #include <boost/shared_ptr.hpp>
 #include <gtest/gtest.h>
 
@@ -22,10 +21,16 @@ using namespace isc;
 using namespace isc::data;
 using namespace isc::stats;
 using namespace isc::config;
-using namespace boost::posix_time;
+using namespace std::chrono;
 
 namespace {
 
+const StatsDuration& dur1234(hours(1) + minutes(2) + seconds(3) +
+                             milliseconds(4));
+const StatsDuration& dur5678(hours(5) + minutes(6) + seconds(7) +
+                             milliseconds(8));
+const StatsDuration& dur1245(hours(1) + minutes(2) + seconds(45));
+
 /// @brief Fixture class for StatsMgr testing
 ///
 /// Very simple class that makes sure that StatsMgr is indeed instantiated
@@ -66,7 +71,7 @@ TEST_F(StatsMgrTest, integerStat) {
     ASSERT_TRUE(alpha);
 
     std::string exp = "{ \"alpha\": [ [ 1234, \"" +
-        isc::util::ptimeToText(alpha->getInteger().second) + "\" ] ] }";
+        isc::util::clockToText(alpha->getInteger().second) + "\" ] ] }";
 
     EXPECT_EQ(exp, StatsMgr::instance().get("alpha")->str());
 }
@@ -81,7 +86,7 @@ TEST_F(StatsMgrTest, floatStat) {
     ASSERT_TRUE(beta);
 
     std::string exp = "{ \"beta\": [ [ 12.34, \"" +
-        isc::util::ptimeToText(beta->getFloat().second) + "\" ] ] }";
+        isc::util::clockToText(beta->getFloat().second) + "\" ] ] }";
 
     EXPECT_EQ(exp, StatsMgr::instance().get("beta")->str());
 }
@@ -89,15 +94,14 @@ TEST_F(StatsMgrTest, floatStat) {
 // Test checks whether it's possible to record and later report
 // a duration statistic.
 TEST_F(StatsMgrTest, durationStat) {
-    EXPECT_NO_THROW(StatsMgr::instance().setValue("gamma",
-                                                  microsec::time_duration(1, 2, 3, 4)));
+    EXPECT_NO_THROW(StatsMgr::instance().setValue("gamma", dur1234));
 
     ObservationPtr gamma;
     EXPECT_NO_THROW(gamma = StatsMgr::instance().getObservation("gamma"));
     ASSERT_TRUE(gamma);
 
-    std::string exp = "{ \"gamma\": [ [ \"01:02:03.000004\", \"" +
-        isc::util::ptimeToText(gamma->getDuration().second) + "\" ] ] }";
+    std::string exp = "{ \"gamma\": [ [ \"01:02:03.004000\", \"" +
+        isc::util::clockToText(gamma->getDuration().second) + "\" ] ] }";
 
     EXPECT_EQ(exp, StatsMgr::instance().get("gamma")->str());
 }
@@ -113,7 +117,7 @@ TEST_F(StatsMgrTest, stringStat) {
     ASSERT_TRUE(delta);
 
     std::string exp = "{ \"delta\": [ [ \"Lorem ipsum\", \"" +
-        isc::util::ptimeToText(delta->getString().second) + "\" ] ] }";
+        isc::util::clockToText(delta->getString().second) + "\" ] ] }";
 
     EXPECT_EQ(exp, StatsMgr::instance().get("delta")->str());
 }
@@ -122,7 +126,7 @@ TEST_F(StatsMgrTest, stringStat) {
 TEST_F(StatsMgrTest, getSize) {
     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
     StatsMgr::instance().setValue("beta", 12.34);
-    StatsMgr::instance().setValue("gamma", microsec::time_duration(1, 2, 3, 4));
+    StatsMgr::instance().setValue("gamma", dur1234);
     StatsMgr::instance().setValue("delta", "Lorem ipsum");
 
     EXPECT_NO_THROW(StatsMgr::instance().getSize("alpha"));
@@ -142,7 +146,7 @@ TEST_F(StatsMgrTest, setLimits) {
     StatsMgr::instance().setValue("foo", static_cast<int64_t>(1));
 
     EXPECT_NO_THROW(StatsMgr::instance().setMaxSampleAge("foo",
-                                                         time_duration(0, 0, 1, 0)));
+                                                         seconds(1)));
 
     for (uint32_t i = 0; i < 10; ++i) {
         if (i == 5) {
@@ -167,31 +171,31 @@ TEST_F(StatsMgrTest, setLimitsAll) {
     // Set a couple of statistics
     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
     StatsMgr::instance().setValue("beta", 12.34);
-    StatsMgr::instance().setValue("gamma", time_duration(1, 2, 3, 4));
+    StatsMgr::instance().setValue("gamma", dur1234);
     StatsMgr::instance().setValue("delta", "Lorem ipsum");
 
     // check the setting of time limit to existing statistics
-    EXPECT_NO_THROW(StatsMgr::instance().setMaxSampleAgeAll(time_duration(0, 0, 1, 0)));
+    EXPECT_NO_THROW(StatsMgr::instance().setMaxSampleAgeAll(seconds(1)));
 
     // check if time limit was set properly and whether count limit is disabled
     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().first, true);
     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().second,
-              time_duration(0, 0, 1, 0));
+              seconds(1));
     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().first, false);
 
     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().first, true);
     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().second,
-              time_duration(0, 0, 1, 0));
+              seconds(1));
     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().first, false);
 
     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().first, true);
     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().second,
-              time_duration(0, 0, 1, 0));
+              seconds(1));
     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().first, false);
 
     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().first, true);
     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().second,
-              time_duration(0, 0, 1, 0));
+              seconds(1));
     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().first, false);
 
     // check the setting of count limit to existing statistics
@@ -351,27 +355,27 @@ TEST_F(StatsMgrTest, getGetAll) {
     // Set a couple of statistics
     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
     StatsMgr::instance().setValue("beta", 12.34);
-    StatsMgr::instance().setValue("gamma", time_duration(1, 2, 3, 4));
+    StatsMgr::instance().setValue("gamma", dur1234);
     StatsMgr::instance().setValue("delta", "Lorem");
 
     // The string's representation of firstly added statistics
     std::string alpha_first = ", [ 1234, \"" +
-        isc::util::ptimeToText(StatsMgr::instance().getObservation("alpha")
+        isc::util::clockToText(StatsMgr::instance().getObservation("alpha")
                                    ->getInteger().second) + "\" ] ]";
     std::string beta_first = ", [ 12.34, \"" +
-        isc::util::ptimeToText(StatsMgr::instance().getObservation("beta")
+        isc::util::clockToText(StatsMgr::instance().getObservation("beta")
                                    ->getFloat().second) + "\" ] ]";
-    std::string gamma_first = ", [ \"01:02:03.000004\", \"" +
-        isc::util::ptimeToText(StatsMgr::instance().getObservation("gamma")
+    std::string gamma_first = ", [ \"01:02:03.004000\", \"" +
+        isc::util::clockToText(StatsMgr::instance().getObservation("gamma")
                                    ->getDuration().second) + "\" ] ]";
     std::string delta_first = ", [ \"Lorem\", \"" +
-        isc::util::ptimeToText(StatsMgr::instance().getObservation("delta")
+        isc::util::clockToText(StatsMgr::instance().getObservation("delta")
                                    ->getString().second) + "\" ] ]";
 
     // Now add some values to them
     StatsMgr::instance().addValue("alpha", static_cast<int64_t>(5678));
     StatsMgr::instance().addValue("beta", 56.78);
-    StatsMgr::instance().addValue("gamma", time_duration(5, 6, 7, 8));
+    StatsMgr::instance().addValue("gamma", dur5678);
     StatsMgr::instance().addValue("delta", " ipsum");
 
     // There should be 4 statistics reported
@@ -389,16 +393,16 @@ TEST_F(StatsMgrTest, getGetAll) {
     ASSERT_TRUE(rep_delta);
 
     std::string exp_str_alpha = "[ [ 6912, \"" +
-        isc::util::ptimeToText(StatsMgr::instance().getObservation("alpha")
+        isc::util::clockToText(StatsMgr::instance().getObservation("alpha")
                                    ->getInteger().second) + "\" ]" + alpha_first;
     std::string exp_str_beta = "[ [ 69.12, \"" +
-        isc::util::ptimeToText(StatsMgr::instance().getObservation("beta")
+        isc::util::clockToText(StatsMgr::instance().getObservation("beta")
                                    ->getFloat().second) + "\" ]" + beta_first;
-    std::string exp_str_gamma = "[ [ \"06:08:10.000012\", \"" +
-        isc::util::ptimeToText(StatsMgr::instance().getObservation("gamma")
+    std::string exp_str_gamma = "[ [ \"06:08:10.012000\", \"" +
+        isc::util::clockToText(StatsMgr::instance().getObservation("gamma")
                                    ->getDuration().second) + "\" ]" + gamma_first;
     std::string exp_str_delta = "[ [ \"Lorem ipsum\", \"" +
-        isc::util::ptimeToText(StatsMgr::instance().getObservation("delta")
+        isc::util::clockToText(StatsMgr::instance().getObservation("delta")
                                    ->getString().second) + "\" ]" + delta_first;
 
     // Check that individual stats are reported properly
@@ -434,7 +438,7 @@ TEST_F(StatsMgrTest, reset) {
     // Set a couple of statistics
     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
     StatsMgr::instance().setValue("beta", 12.34);
-    StatsMgr::instance().setValue("gamma", time_duration(1, 2, 3, 4));
+    StatsMgr::instance().setValue("gamma", dur1234);
     StatsMgr::instance().setValue("delta", "Lorem ipsum");
 
     // This should reset alpha to 0
@@ -445,7 +449,7 @@ TEST_F(StatsMgrTest, reset) {
     // The other stats should remain untouched
     EXPECT_EQ(12.34,
               StatsMgr::instance().getObservation("beta")->getFloat().first);
-    EXPECT_EQ(time_duration(1, 2, 3, 4),
+    EXPECT_EQ(dur1234,
               StatsMgr::instance().getObservation("gamma")->getDuration().first);
     EXPECT_EQ("Lorem ipsum",
               StatsMgr::instance().getObservation("delta")->getString().first);
@@ -456,7 +460,7 @@ TEST_F(StatsMgrTest, reset) {
     EXPECT_NO_THROW(StatsMgr::instance().reset("delta"));
     EXPECT_EQ(0.0,
               StatsMgr::instance().getObservation("beta")->getFloat().first);
-    EXPECT_EQ(time_duration(0, 0, 0, 0),
+    EXPECT_EQ(StatsDuration::zero(),
               StatsMgr::instance().getObservation("gamma")->getDuration().first);
     EXPECT_EQ("",
               StatsMgr::instance().getObservation("delta")->getString().first);
@@ -470,7 +474,7 @@ TEST_F(StatsMgrTest, resetAll) {
     // Set a couple of statistics
     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
     StatsMgr::instance().setValue("beta", 12.34);
-    StatsMgr::instance().setValue("gamma", time_duration(1, 2, 3, 4));
+    StatsMgr::instance().setValue("gamma", dur1234);
     StatsMgr::instance().setValue("delta", "Lorem ipsum");
 
     // This should reset alpha to 0
@@ -479,7 +483,7 @@ TEST_F(StatsMgrTest, resetAll) {
               StatsMgr::instance().getObservation("alpha")->getInteger().first);
     EXPECT_EQ(0.0,
               StatsMgr::instance().getObservation("beta")->getFloat().first);
-    EXPECT_EQ(time_duration(0, 0, 0, 0),
+    EXPECT_EQ(StatsDuration::zero(),
               StatsMgr::instance().getObservation("gamma")->getDuration().first);
     EXPECT_EQ("",
               StatsMgr::instance().getObservation("delta")->getString().first);
@@ -493,7 +497,7 @@ TEST_F(StatsMgrTest, removeAll) {
     // Set a couple of statistics
     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
     StatsMgr::instance().setValue("beta", 12.34);
-    StatsMgr::instance().setValue("gamma", time_duration(1, 2, 3, 4));
+    StatsMgr::instance().setValue("gamma", dur1234);
     StatsMgr::instance().setValue("delta", "Lorem ipsum");
 
     // This should reset alpha to 0
@@ -525,13 +529,13 @@ TEST_F(StatsMgrTest, DISABLED_performanceSingleAdd) {
 
     uint32_t cycles = 1000000;
 
-    ptime before = microsec_clock::local_time();
+    auto before = SampleClock::now();
     for (uint32_t i = 0; i < cycles; ++i) {
         StatsMgr::instance().addValue("metric1", 0.1 * i);
     }
-    ptime after = microsec_clock::local_time();
+    auto after = SampleClock::now();
 
-    time_duration dur = after - before;
+    auto dur = after - before;
 
     std::cout << "Incrementing a single statistic " << cycles << " times took: "
               << isc::util::durationToText(dur) << std::endl;
@@ -547,13 +551,13 @@ TEST_F(StatsMgrTest, DISABLED_performanceSingleSet) {
 
     uint32_t cycles = 1000000;
 
-    ptime before = microsec_clock::local_time();
+    auto before = SampleClock::now();
     for (uint32_t i = 0; i < cycles; ++i) {
         StatsMgr::instance().setValue("metric1", 0.1 * i);
     }
-    ptime after = microsec_clock::local_time();
+    auto after = SampleClock::now();
 
-    time_duration dur = after - before;
+    auto dur = after - before;
 
     std::cout << "Setting a single statistic " << cycles << " times took: "
               << isc::util::durationToText(dur) << std::endl;
@@ -577,13 +581,13 @@ TEST_F(StatsMgrTest, DISABLED_performanceMultipleAdd) {
         StatsMgr::instance().setValue(tmp.str(), static_cast<int64_t>(i));
     }
 
-    ptime before = microsec_clock::local_time();
+    auto before = SampleClock::now();
     for (uint32_t i = 0; i < cycles; ++i) {
         StatsMgr::instance().addValue("metric1", static_cast<int64_t>(i));
     }
-    ptime after = microsec_clock::local_time();
+    auto after = SampleClock::now();
 
-    time_duration dur = after - before;
+    auto dur = after - before;
 
     std::cout << "Incrementing one of " << stats << " statistics " << cycles
               << " times took: " << isc::util::durationToText(dur) << std::endl;
@@ -607,13 +611,13 @@ TEST_F(StatsMgrTest, DISABLED_performanceMultipleSet) {
         StatsMgr::instance().setValue(tmp.str(), static_cast<int64_t>(i));
     }
 
-    ptime before = microsec_clock::local_time();
+    auto before = SampleClock::now();
     for (uint32_t i = 0; i < cycles; ++i) {
         StatsMgr::instance().setValue("metric1", static_cast<int64_t>(i));
     }
-    ptime after = microsec_clock::local_time();
+    auto after = SampleClock::now();
 
-    time_duration dur = after - before;
+    auto dur = after - before;
 
     std::cout << "Setting one of " << stats << " statistics " << cycles
               << " times took: " << isc::util::durationToText(dur) << std::endl;
@@ -650,7 +654,7 @@ TEST_F(StatsMgrTest, commandStatisticGet) {
     ASSERT_TRUE(alpha);
 
     std::string exp = "{ \"alpha\": [ [ 1234, \"" +
-        isc::util::ptimeToText(alpha->getInteger().second) + "\" ] ] }";
+        isc::util::clockToText(alpha->getInteger().second) + "\" ] ] }";
 
     EXPECT_EQ("{ \"arguments\": " + exp + ", \"result\": 0 }", rsp->str());
 }
@@ -685,7 +689,7 @@ TEST_F(StatsMgrTest, commandGetAll) {
     // Set a couple of statistics
     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
     StatsMgr::instance().setValue("beta", 12.34);
-    StatsMgr::instance().setValue("gamma", time_duration(1, 2, 3, 4));
+    StatsMgr::instance().setValue("gamma", dur1234);
     StatsMgr::instance().setValue("delta", "Lorem ipsum");
 
     // Now get them. They're used to generate expected output
@@ -700,16 +704,16 @@ TEST_F(StatsMgrTest, commandGetAll) {
     ASSERT_TRUE(rep_delta);
 
     std::string exp_str_alpha = "[ [ 1234, \"" +
-        isc::util::ptimeToText(StatsMgr::instance().getObservation("alpha")
+        isc::util::clockToText(StatsMgr::instance().getObservation("alpha")
                                    ->getInteger().second) + "\" ] ]";
     std::string exp_str_beta = "[ [ 12.34, \"" +
-        isc::util::ptimeToText(StatsMgr::instance().getObservation("beta")
+        isc::util::clockToText(StatsMgr::instance().getObservation("beta")
                                    ->getFloat().second) + "\" ] ]";
-    std::string exp_str_gamma = "[ [ \"01:02:03.000004\", \"" +
-        isc::util::ptimeToText(StatsMgr::instance().getObservation("gamma")
+    std::string exp_str_gamma = "[ [ \"01:02:03.004000\", \"" +
+        isc::util::clockToText(StatsMgr::instance().getObservation("gamma")
                                    ->getDuration().second) + "\" ] ]";
     std::string exp_str_delta = "[ [ \"Lorem ipsum\", \"" +
-        isc::util::ptimeToText(StatsMgr::instance().getObservation("delta")
+        isc::util::clockToText(StatsMgr::instance().getObservation("delta")
                                    ->getString().second) + "\" ] ]";
 
     // Check that all of them can be reported at once
@@ -788,7 +792,7 @@ TEST_F(StatsMgrTest, commandResetAll) {
     // Set a couple of statistics
     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
     StatsMgr::instance().setValue("beta", 12.34);
-    StatsMgr::instance().setValue("gamma", time_duration(1, 2, 3, 4));
+    StatsMgr::instance().setValue("gamma", dur1234);
     StatsMgr::instance().setValue("delta", "Lorem ipsum");
 
     // Now get them. They're used to generate expected output
@@ -803,16 +807,16 @@ TEST_F(StatsMgrTest, commandResetAll) {
     ASSERT_TRUE(rep_delta);
 
     std::string exp_str_alpha = "[ [ 1234, \"" +
-        isc::util::ptimeToText(StatsMgr::instance().getObservation("alpha")
+        isc::util::clockToText(StatsMgr::instance().getObservation("alpha")
                                    ->getInteger().second) + "\" ] ]";
     std::string exp_str_beta = "[ [ 12.34, \"" +
-        isc::util::ptimeToText(StatsMgr::instance().getObservation("beta")
+        isc::util::clockToText(StatsMgr::instance().getObservation("beta")
                                    ->getFloat().second) + "\" ] ]";
-    std::string exp_str_gamma = "[ [ \"01:02:03.000004\", \"" +
-        isc::util::ptimeToText(StatsMgr::instance().getObservation("gamma")
+    std::string exp_str_gamma = "[ [ \"01:02:03.004000\", \"" +
+        isc::util::clockToText(StatsMgr::instance().getObservation("gamma")
                                    ->getDuration().second) + "\" ] ]";
     std::string exp_str_delta = "[ [ \"Lorem ipsum\", \"" +
-        isc::util::ptimeToText(StatsMgr::instance().getObservation("delta")
+        isc::util::clockToText(StatsMgr::instance().getObservation("delta")
                                    ->getString().second) + "\" ] ]";
 
     // Check that all of them can be reset at once
@@ -829,7 +833,7 @@ TEST_F(StatsMgrTest, commandResetAll) {
               StatsMgr::instance().getObservation("alpha")->getInteger().first);
     EXPECT_EQ(0.0f,
               StatsMgr::instance().getObservation("beta")->getFloat().first);
-    EXPECT_EQ(time_duration(0, 0, 0, 0),
+    EXPECT_EQ(StatsDuration::zero(),
               StatsMgr::instance().getObservation("gamma")->getDuration().first);
     EXPECT_EQ("",
               StatsMgr::instance().getObservation("delta")->getString().first);
@@ -884,7 +888,7 @@ TEST_F(StatsMgrTest, commandRemoveAll) {
     // Set a couple of statistics
     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
     StatsMgr::instance().setValue("beta", 12.34);
-    StatsMgr::instance().setValue("gamma", time_duration(1, 2, 3, 4));
+    StatsMgr::instance().setValue("gamma", dur1234);
     StatsMgr::instance().setValue("delta", "Lorem ipsum");
 
     // Check that all of them can be reset at once
@@ -909,7 +913,7 @@ TEST_F(StatsMgrTest, commandSetMaxSampleAge) {
 
     ElementPtr params = Element::createMap();
     params->set("name", Element::create("alpha"));
-    params->set("duration", Element::create(1245)); // time_duration(0, 20, 45, 0)
+    params->set("duration", Element::create(1245)); // minutes(20) + seconds(45)
 
     ConstElementPtr rsp =
         StatsMgr::instance().statisticSetMaxSampleAgeHandler("statistic-sample-age-set", params);
@@ -920,7 +924,7 @@ TEST_F(StatsMgrTest, commandSetMaxSampleAge) {
     // check if time limit was set properly and whether count limit is disabled
     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().first, true);
     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().second,
-              time_duration(0, 20, 45, 0));
+              minutes(20) + seconds(45));
     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().first, false);
 }
 
@@ -962,11 +966,11 @@ TEST_F(StatsMgrTest, commandSetMaxSampleAgeAll) {
     // Set a couple of statistics
     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
     StatsMgr::instance().setValue("beta", 12.34);
-    StatsMgr::instance().setValue("gamma", time_duration(1, 2, 3, 4));
+    StatsMgr::instance().setValue("gamma", dur1234);
     StatsMgr::instance().setValue("delta", "Lorem ipsum");
 
     ElementPtr params = Element::createMap();
-    params->set("duration", Element::create(3765)); // time_duration(1, 2, 45, 0)
+    params->set("duration", Element::create(3765)); // dur1245
 
     ConstElementPtr rsp =
         StatsMgr::instance().statisticSetMaxSampleAgeAllHandler(params);
@@ -982,22 +986,22 @@ TEST_F(StatsMgrTest, commandSetMaxSampleAgeAll) {
     // check if time limit was set properly and whether count limit is disabled
     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().first, true);
     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleAge().second,
-              time_duration(1, 2, 45, 0));
+              dur1245);
     EXPECT_EQ(StatsMgr::instance().getObservation("alpha")->getMaxSampleCount().first, false);
 
     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().first, true);
     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleAge().second,
-              time_duration(1, 2, 45, 0));
+              dur1245);
     EXPECT_EQ(StatsMgr::instance().getObservation("beta")->getMaxSampleCount().first, false);
 
     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().first, true);
     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleAge().second,
-              time_duration(1, 2, 45, 0));
+              dur1245);
     EXPECT_EQ(StatsMgr::instance().getObservation("gamma")->getMaxSampleCount().first, false);
 
     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().first, true);
     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleAge().second,
-              time_duration(1, 2, 45, 0));
+              dur1245);
     EXPECT_EQ(StatsMgr::instance().getObservation("delta")->getMaxSampleCount().first, false);
 }
 
@@ -1060,7 +1064,7 @@ TEST_F(StatsMgrTest, commandSetMaxSampleCountAll) {
     // Set a couple of statistics
     StatsMgr::instance().setValue("alpha", static_cast<int64_t>(1234));
     StatsMgr::instance().setValue("beta", 12.34);
-    StatsMgr::instance().setValue("gamma", time_duration(1, 2, 3, 4));
+    StatsMgr::instance().setValue("gamma", dur1234);
     StatsMgr::instance().setValue("delta", "Lorem ipsum");
 
     ElementPtr params = Element::createMap();
index 14319e9e9d9f028e70a52e032e39b79cbd073d0f..ceced193b59479d8425b94d2925ff35d3ba53e83 100644 (file)
@@ -9,6 +9,7 @@ AM_CXXFLAGS = $(KEA_CXXFLAGS)
 lib_LTLIBRARIES = libkea-util.la
 libkea_util_la_SOURCES  = boost_time_utils.h boost_time_utils.cc
 libkea_util_la_SOURCES += buffer.h io_utilities.h
+libkea_util_la_SOURCES += chrono_time_utils.h chrono_time_utils.cc
 libkea_util_la_SOURCES += csv_file.h csv_file.cc
 libkea_util_la_SOURCES += doubles.h
 libkea_util_la_SOURCES += filename.h filename.cc
diff --git a/src/lib/util/chrono_time_utils.cc b/src/lib/util/chrono_time_utils.cc
new file mode 100644 (file)
index 0000000..f351397
--- /dev/null
@@ -0,0 +1,83 @@
+// Copyright (C) 2015-2020 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <config.h>
+
+#include <util/chrono_time_utils.h>
+#include <sstream>
+#include <iomanip>
+
+using namespace std::chrono;
+
+std::string
+isc::util::clockToText(system_clock::time_point t, size_t fsecs_precision) {
+    time_t tt = system_clock::to_time_t(t);
+    struct tm tm;
+    localtime_r(&tt, &tm);
+    std::stringstream s;
+    s << (tm.tm_year + 1900)
+      << "-" << std::setw(2) << std::setfill('0') << (tm.tm_mon + 1)
+      << "-" << std::setw(2) << std::setfill('0') << tm.tm_mday
+      << " " << std::setw(2) << std::setfill('0') << tm.tm_hour
+      << ":" << std::setw(2) << std::setfill('0') << tm.tm_min
+      << ":" << std::setw(2) << std::setfill('0') << tm.tm_sec;
+
+    // If the requested precision is less than the maximum native precision
+    // we will divide the fractional seconds value by 10^(max - requested)
+    if (fsecs_precision) {
+        microseconds frac = t - system_clock::from_time_t(tt);
+        auto fsecs = frac.count();
+        size_t width = MAX_FSECS_PRECISION;
+        if (fsecs_precision < width) {
+            for (auto i = 0; i < width - fsecs_precision; ++i) {
+                fsecs /= 10;
+            }
+
+            width = fsecs_precision;
+        }
+
+        s << "." << std::setw(width)
+          << std::setfill('0')
+          << fsecs;
+    }
+
+    return (s.str());
+}
+
+std::string
+isc::util::durationToText(system_clock::duration dur, size_t fsecs_precision) {
+    seconds unfrac = duration_cast<seconds>(dur);
+    auto secs = unfrac.count();
+    std::stringstream s;
+    auto hours = secs / 3600;
+    secs -= hours * 3600;
+    s << std::setw(2) << std::setfill('0') << hours;
+    auto mins = secs / 60;
+    secs -= mins * 60;
+    s << ":" << std::setw(2) << std::setfill('0') << mins
+      << ":" << std::setw(2) << std::setfill('0') << secs;
+
+    // If the requested precision is less than the maximum native precision
+    // we will divide the fractional seconds value by 10^(max - requested)
+    if (fsecs_precision) {
+        microseconds frac = dur - unfrac;
+        auto fsecs = frac.count();
+        size_t width = MAX_FSECS_PRECISION;
+        if (fsecs_precision < width) {
+            for (auto i = 0; i < width - fsecs_precision; ++i) {
+                fsecs /= 10;
+            }
+
+            width = fsecs_precision;
+        }
+
+        s << "." << std::setw(width)
+          << std::setfill('0')
+          << fsecs;
+    }
+
+    return (s.str());
+}
diff --git a/src/lib/util/chrono_time_utils.h b/src/lib/util/chrono_time_utils.h
new file mode 100644 (file)
index 0000000..cfceccc
--- /dev/null
@@ -0,0 +1,45 @@
+// Copyright (C) 2015-2020 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef KEA_CHRONO_TIME_UTILS_H
+#define KEA_CHRONO_TIME_UTILS_H
+
+#include <chrono>
+#include <string>
+
+namespace isc {
+namespace util {
+
+/// @brief The number of digits of fractional seconds supplied by the
+/// underlying class, std::chrono::time_point. Typically 6 = microseconds.
+const size_t MAX_FSECS_PRECISION = 6;
+
+/// @brief Converts chrono time point structure to text
+///
+/// This is Kea implementation for converting time point to strings.
+/// @param t time point value to convert to text
+/// @param fsecs_precision number of digits of precision for fractional seconds.
+/// Zero omits the value.
+///
+/// @return a string representing time
+std::string clockToText(std::chrono::system_clock::time_point t,
+                        size_t fsecs_precision = MAX_FSECS_PRECISION);
+
+/// @brief Converts StatsDuration to text
+///
+/// See @ref clockToText for explanation why we chose our own implementation.
+/// @param dur duration value to convert to text
+/// @param fsecs_precision number of digits of precision for fractional seconds.
+/// Zero omits the value.
+///
+/// @return a string representing time
+std::string durationToText(std::chrono::system_clock::duration,
+                           size_t fsecs_precision = MAX_FSECS_PRECISION);
+
+}; // end of isc::util namespace
+}; // end of isc namespace
+
+#endif
index a5668e33349e686d6c802a466795494bad5f280d..b04d07278fadda8f1a9132156625f8984b521f1e 100644 (file)
@@ -32,6 +32,7 @@ run_unittests_SOURCES += base32hex_unittest.cc
 run_unittests_SOURCES += base64_unittest.cc
 run_unittests_SOURCES += boost_time_utils_unittest.cc
 run_unittests_SOURCES += buffer_unittest.cc
+run_unittests_SOURCES += chrono_time_utils_unittest.cc
 run_unittests_SOURCES += csv_file_unittest.cc
 run_unittests_SOURCES += doubles_unittest.cc
 run_unittests_SOURCES += fd_share_tests.cc
diff --git a/src/lib/util/tests/chrono_time_utils_unittest.cc b/src/lib/util/tests/chrono_time_utils_unittest.cc
new file mode 100644 (file)
index 0000000..a0ed42f
--- /dev/null
@@ -0,0 +1,147 @@
+// Copyright (C) 2015-2020 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <config.h>
+
+#include <util/chrono_time_utils.h>
+
+#include <string.h>
+
+#include <gtest/gtest.h>
+
+using namespace std;
+using namespace std::chrono;
+using namespace isc::util;
+
+/// Check the clockToText() function returns a numeric month.
+TEST(ChronoTimeUtilsTest, epoch) {
+    // The system clock is a wall clock using the local time zone so
+    // the epoch is zero only at some places or of course if the
+    // system is in UTC...
+    struct tm epoch;
+    memset(&epoch, 0, sizeof(epoch));
+    epoch.tm_year = 70;
+    epoch.tm_mday = 1;
+    time_t tepoch = timelocal(&epoch);
+    system_clock::time_point pepoch = system_clock::from_time_t(tepoch);
+
+    // We're going to loop through precision values starting with 0 through
+    // the max supported precision.  Each pass should after the first, should
+    // add an additional level of precision: secs, secs/10, secs/100,
+    // secs/1000 and so on.  The initial string has no fraction seconds.
+    std::string expected("1970-01-01 00:00:00");
+    std::string sepoch;
+    for (int precision = 0; precision <= MAX_FSECS_PRECISION; ++precision) {
+        if (precision == 1) {
+            // Adding fractional seconds so we need append a decimal point.
+            expected.push_back('.');
+        }
+
+        if (precision >= 1) {
+            // Adding an additional level of precision, append a zero.
+            expected.push_back('0');
+        }
+
+        // Now let's see if we get the correct precision in the text.
+        sepoch = clockToText(pepoch, precision);
+        EXPECT_EQ(expected, sepoch) << " test precision:" << precision;
+    }
+
+    // Expected string should have same precision as default, so
+    // test the default.
+    sepoch = clockToText(pepoch);
+    EXPECT_EQ(expected, sepoch);
+
+    // Now test a requested precision beyond default.  We should
+    // get the default precision.
+    sepoch = clockToText(pepoch, MAX_FSECS_PRECISION + 1);
+    EXPECT_EQ(expected, sepoch);
+
+}
+
+/// Check the durationToText() works as expected.
+/// Note durationToText() is not called by clockToText().
+TEST(ChronoTimeUtilsTest, duration) {
+    system_clock::duration p123 = hours(1) + minutes(2) + seconds(3);
+
+    // We're going to loop through precision values starting with 0 through
+    // the max supported precision.  Each pass should after the first, should
+    // add an additional level of precision: secs, secs/10, secs/100,
+    // secs/1000 and so on.  The initial string has no fraction seconds.
+    std::string expected("01:02:03");
+    std::string s123;
+    for (int precision = 0; precision <= MAX_FSECS_PRECISION; ++precision) {
+        if (precision == 1) {
+            // Adding fractional seconds so we need append a decimal point.
+            expected.push_back('.');
+        }
+
+        if (precision >= 1) {
+            // Adding an additional level of precision, append a zero.
+            expected.push_back('0');
+        }
+
+        // Now let's see if we get the correct precision in the text.
+        s123 = durationToText(p123, precision);
+        EXPECT_EQ(expected, s123) << " test precision:" << precision;
+    }
+
+    // Expected string should have same precision as default, so
+    // test the default.
+    s123 = durationToText(p123);
+    EXPECT_EQ(expected, s123);
+
+    // Now test a requested precision beyond default.  We should
+    // get the default precision.
+    s123 = durationToText(p123, MAX_FSECS_PRECISION + 1);
+    EXPECT_EQ(expected, s123);
+}
+
+// The 2015 Bastille day
+TEST(ChronoTimeUtilsTest, bastilleDay) {
+    struct tm tm;
+    tm.tm_year = 2015 - 1900;
+    tm.tm_mon = 7 - 1;
+    tm.tm_mday = 14;
+    tm.tm_hour = 12;
+    tm.tm_min = 13;
+    tm.tm_sec = 14;
+    time_t tbast = timelocal(&tm);
+    system_clock::time_point tpbast = system_clock::from_time_t(tbast);
+    tpbast += milliseconds(500);
+
+    // We're going to loop through precision values starting with 0 through
+    // the max supported precision.  Each pass should after the first, should
+    // add an additional level of precision: secs, secs/10, secs/100,
+    // secs/1000 and so on.  The initial string has no fraction seconds.
+    std::string expected("2015-07-14 12:13:14");
+    std::string sbast;
+    for (int precision = 0; precision <= MAX_FSECS_PRECISION; ++precision) {
+        if (precision == 1) {
+            // Adding fractional seconds so we need append a decimal point
+            // and the digit 5 (i.e. 500 ms = .5 secs).
+            expected.push_back('.');
+            expected.push_back('5');
+        } else if (precision > 1) {
+            // Adding an additional level of precision, append a zero.
+            expected.push_back('0');
+        }
+
+        // Now let's see if we get the correct precision in the text.
+        sbast = clockToText(tpbast, precision);
+        EXPECT_EQ(expected, sbast) << " test precision:" << precision;
+    }
+
+    // Expected string should have same precision as default, so
+    // test the default.
+    sbast = clockToText(tpbast);
+    EXPECT_EQ(expected, sbast);
+
+    // Now test a requested precision beyond default.  We should
+    // get the default precision.
+    sbast = clockToText(tpbast, MAX_FSECS_PRECISION + 1);
+    EXPECT_EQ(expected, sbast);
+}