1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// Copyright (C) 2015-2024 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 file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <time.h><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <gtest/gtest.h><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

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;
    epoch.tm_isdst = -1;
    time_t tepoch = mktime(&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 (size_t 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 (size_t 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;
    tm.tm_isdst = -1;
    time_t tbast = mktime(&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 (size_t 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);
}

// Try steady clock duration.
TEST(ChronoTimeUtilsTest, steadyClock) {
    steady_clock::duration p12345 = hours(1) + minutes(2) + seconds(3) +
        milliseconds(4) + microseconds(5);
    std::string expected("01:02:03.004005");
    std::string s12345 = durationToText(p12345, 6);
    EXPECT_EQ(expected, s12345);
}