1 #include "utils/time_utils.hpp"
2 
3 #include <gmock/gmock.h> // IWYU pragma: keep
4 #include <gtest/gtest.h> // IWYU pragma: keep
5 
6 // IWYU pragma: no_include <gtest/gtest-message.h>
7 // IWYU pragma: no_include <gtest/gtest-test-part.h>
8 // IWYU pragma: no_include "gtest/gtest_pred_impl.h"
9 // IWYU pragma: no_include <gmock/gmock-matchers.h>
10 // IWYU pragma: no_include <gtest/gtest-matchers.h>
11 
12 namespace redfish::time_utils
13 {
14 namespace
15 {
16 
17 TEST(FromDurationTest, PositiveTests)
18 {
19     EXPECT_EQ(fromDurationString("PT12S"), std::chrono::milliseconds(12000));
20     EXPECT_EQ(fromDurationString("PT0.204S"), std::chrono::milliseconds(204));
21     EXPECT_EQ(fromDurationString("PT0.2S"), std::chrono::milliseconds(200));
22     EXPECT_EQ(fromDurationString("PT50M"), std::chrono::milliseconds(3000000));
23     EXPECT_EQ(fromDurationString("PT23H"), std::chrono::milliseconds(82800000));
24     EXPECT_EQ(fromDurationString("P51D"),
25               std::chrono::milliseconds(4406400000));
26     EXPECT_EQ(fromDurationString("PT2H40M10.1S"),
27               std::chrono::milliseconds(9610100));
28     EXPECT_EQ(fromDurationString("P20DT2H40M10.1S"),
29               std::chrono::milliseconds(1737610100));
30     EXPECT_EQ(fromDurationString(""), std::chrono::milliseconds(0));
31 }
32 
33 TEST(FromDurationTest, NegativeTests)
34 {
35     EXPECT_EQ(fromDurationString("PTS"), std::nullopt);
36     EXPECT_EQ(fromDurationString("P1T"), std::nullopt);
37     EXPECT_EQ(fromDurationString("PT100M1000S100"), std::nullopt);
38     EXPECT_EQ(fromDurationString("PDTHMS"), std::nullopt);
39     EXPECT_EQ(fromDurationString("P9999999999999999999999999DT"), std::nullopt);
40     EXPECT_EQ(fromDurationString("PD222T222H222M222.222S"), std::nullopt);
41     EXPECT_EQ(fromDurationString("PT99999H9999999999999999999999M99999999999S"),
42               std::nullopt);
43     EXPECT_EQ(fromDurationString("PT-9H"), std::nullopt);
44 }
45 TEST(ToDurationTest, PositiveTests)
46 {
47     EXPECT_EQ(toDurationString(std::chrono::milliseconds(12000)), "PT12.000S");
48     EXPECT_EQ(toDurationString(std::chrono::milliseconds(204)), "PT0.204S");
49     EXPECT_EQ(toDurationString(std::chrono::milliseconds(200)), "PT0.200S");
50     EXPECT_EQ(toDurationString(std::chrono::milliseconds(3000000)), "PT50M");
51     EXPECT_EQ(toDurationString(std::chrono::milliseconds(82800000)), "PT23H");
52     EXPECT_EQ(toDurationString(std::chrono::milliseconds(4406400000)), "P51DT");
53     EXPECT_EQ(toDurationString(std::chrono::milliseconds(9610100)),
54               "PT2H40M10.100S");
55     EXPECT_EQ(toDurationString(std::chrono::milliseconds(1737610100)),
56               "P20DT2H40M10.100S");
57 }
58 
59 TEST(ToDurationTest, NegativeTests)
60 {
61     EXPECT_EQ(toDurationString(std::chrono::milliseconds(-250)), "");
62 }
63 
64 TEST(ToDurationStringFromUintTest, PositiveTests)
65 {
66     uint64_t maxAcceptedTimeMs =
67         static_cast<uint64_t>(std::chrono::milliseconds::max().count());
68 
69     EXPECT_NE(toDurationStringFromUint(maxAcceptedTimeMs), std::nullopt);
70     EXPECT_EQ(toDurationStringFromUint(0), "PT");
71     EXPECT_EQ(toDurationStringFromUint(250), "PT0.250S");
72     EXPECT_EQ(toDurationStringFromUint(5000), "PT5.000S");
73 }
74 
75 TEST(ToDurationStringFromUintTest, NegativeTests)
76 {
77     uint64_t minNotAcceptedTimeMs =
78         static_cast<uint64_t>(std::chrono::milliseconds::max().count()) + 1;
79 
80     EXPECT_EQ(toDurationStringFromUint(minNotAcceptedTimeMs), std::nullopt);
81     EXPECT_EQ(toDurationStringFromUint(static_cast<uint64_t>(-1)),
82               std::nullopt);
83 }
84 
85 TEST(GetDateTimeStdtime, ConversionTests)
86 {
87     // some time before the epoch
88     EXPECT_EQ(getDateTimeStdtime(std::time_t{-1234567}),
89               "1970-01-01T00:00:00+00:00");
90 
91     // epoch
92     EXPECT_EQ(getDateTimeStdtime(std::time_t{0}), "1970-01-01T00:00:00+00:00");
93 
94     // Limits
95     EXPECT_EQ(getDateTimeStdtime(std::numeric_limits<std::time_t>::max()),
96               "9999-12-31T23:59:59+00:00");
97     EXPECT_EQ(getDateTimeStdtime(std::numeric_limits<std::time_t>::min()),
98               "1970-01-01T00:00:00+00:00");
99 }
100 
101 TEST(GetDateTimeUint, ConversionTests)
102 {
103     EXPECT_EQ(getDateTimeUint(uint64_t{1638312095}),
104               "2021-11-30T22:41:35+00:00");
105     // some time in the future, beyond 2038
106     EXPECT_EQ(getDateTimeUint(uint64_t{41638312095}),
107               "3289-06-18T21:48:15+00:00");
108     // the maximum time we support
109     EXPECT_EQ(getDateTimeUint(uint64_t{253402300799}),
110               "9999-12-31T23:59:59+00:00");
111 
112     // returns the maximum Redfish date
113     EXPECT_EQ(getDateTimeUint(std::numeric_limits<uint64_t>::max()),
114               "9999-12-31T23:59:59+00:00");
115 
116     EXPECT_EQ(getDateTimeUint(std::numeric_limits<uint64_t>::min()),
117               "1970-01-01T00:00:00+00:00");
118 }
119 
120 TEST(GetDateTimeUintMs, ConverstionTests)
121 {
122     EXPECT_EQ(getDateTimeUintMs(uint64_t{1638312095123}),
123               "2021-11-30T22:41:35.123+00:00");
124     // returns the maximum Redfish date
125     EXPECT_EQ(getDateTimeUintMs(std::numeric_limits<uint64_t>::max()),
126               "9999-12-31T23:59:59.999+00:00");
127     EXPECT_EQ(getDateTimeUintMs(std::numeric_limits<uint64_t>::min()),
128               "1970-01-01T00:00:00.000+00:00");
129 }
130 
131 TEST(Utility, GetDateTimeUintUs)
132 {
133     EXPECT_EQ(getDateTimeUintUs(uint64_t{1638312095123456}),
134               "2021-11-30T22:41:35.123456+00:00");
135     // returns the maximum Redfish date
136     EXPECT_EQ(getDateTimeUintUs(std::numeric_limits<uint64_t>::max()),
137               "9999-12-31T23:59:59.999999+00:00");
138     EXPECT_EQ(getDateTimeUintUs(std::numeric_limits<uint64_t>::min()),
139               "1970-01-01T00:00:00.000000+00:00");
140 }
141 
142 TEST(Utility, DateStringToEpoch)
143 {
144     EXPECT_EQ(dateStringToEpoch("2021-11-30T22:41:35.123456+00:00"),
145               usSinceEpoch{1638312095123456});
146     // no timezone
147     EXPECT_EQ(dateStringToEpoch("2021-11-30T22:41:35.123456"),
148               usSinceEpoch{1638312095123456});
149     // Milliseconds precision
150     EXPECT_EQ(dateStringToEpoch("2021-11-30T22:41:35.123"),
151               usSinceEpoch{1638312095123000});
152     // Seconds precision
153     EXPECT_EQ(dateStringToEpoch("2021-11-30T22:41:35"),
154               usSinceEpoch{1638312095000000});
155 
156     // Non zero timezone
157     EXPECT_EQ(dateStringToEpoch("2021-11-30T22:41:35.123456+04:00"),
158               usSinceEpoch{1638297695123456});
159 
160     // Epoch
161     EXPECT_EQ(dateStringToEpoch("1970-01-01T00:00:00.000000+00:00"),
162               usSinceEpoch{0});
163 
164     // Max time
165     EXPECT_EQ(dateStringToEpoch("9999-12-31T23:59:59.999999+00:00"),
166               usSinceEpoch{253402300799999999});
167 
168     // Underflow
169     // Currently gives wrong result
170     // EXPECT_EQ(dateStringToEpoch("1969-12-30T23:59:59.999999+00:00"),
171     //          std::nullopt);
172 }
173 
174 } // namespace
175 } // namespace redfish::time_utils
176