1 //===-- flang/unittests/Runtime/Time.cpp ----------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef __clang__ // 16.0.3 lacks <charconv>
11 #include "gtest/gtest.h"
12 #include "flang/Runtime/time-intrinsic.h"
18 using namespace Fortran::runtime
;
20 TEST(TimeIntrinsics
, CpuTime
) {
21 // We can't really test that we get the "right" result for CPU_TIME, but we
22 // can have a smoke test to see that we get something reasonable on the
23 // platforms where we expect to support it.
24 double start
{RTNAME(CpuTime
)()};
25 ASSERT_GE(start
, 0.0);
27 // Loop until we get a different value from CpuTime. If we don't get one
28 // before we time out, then we should probably look into an implementation
29 // for CpuTime with a better timer resolution.
30 for (double end
= start
; end
== start
; end
= RTNAME(CpuTime
)()) {
32 ASSERT_GE(end
, start
);
36 using count_t
= std::int64_t;
38 TEST(TimeIntrinsics
, SystemClock
) {
39 // We can't really test that we get the "right" result for SYSTEM_CLOCK, but
40 // we can have a smoke test to see that we get something reasonable on the
41 // platforms where we expect to support it.
43 // The value of the count rate and max will vary by platform, but they should
44 // always be strictly positive if we have a working implementation of
46 EXPECT_GT(RTNAME(SystemClockCountRate
)(), 0);
48 count_t max1
{RTNAME(SystemClockCountMax
)(1)};
50 EXPECT_LE(max1
, static_cast<count_t
>(0x7f));
51 count_t start1
{RTNAME(SystemClockCount
)(1)};
53 EXPECT_LE(start1
, max1
);
55 count_t max2
{RTNAME(SystemClockCountMax
)(2)};
57 EXPECT_LE(max2
, static_cast<count_t
>(0x7fff));
58 count_t start2
{RTNAME(SystemClockCount
)(2)};
60 EXPECT_LE(start2
, max2
);
62 count_t max4
{RTNAME(SystemClockCountMax
)(4)};
64 EXPECT_LE(max4
, static_cast<count_t
>(0x7fffffff));
65 count_t start4
{RTNAME(SystemClockCount
)(4)};
67 EXPECT_LE(start4
, max4
);
69 count_t max8
{RTNAME(SystemClockCountMax
)(8)};
71 count_t start8
{RTNAME(SystemClockCount
)(8)};
73 EXPECT_LT(start8
, max8
);
75 count_t max16
{RTNAME(SystemClockCountMax
)(16)};
77 count_t start16
{RTNAME(SystemClockCount
)(16)};
78 EXPECT_GE(start16
, 0);
79 EXPECT_LT(start16
, max16
);
81 // Loop until we get a different value from SystemClockCount. If we don't get
82 // one before we time out, then we should probably look into an implementation
83 // for SystemClokcCount with a better timer resolution on this platform.
84 for (count_t end
{start8
}; end
== start8
; end
= RTNAME(SystemClockCount
)(8)) {
87 EXPECT_GE(end
, start8
);
91 TEST(TimeIntrinsics
, DateAndTime
) {
92 constexpr std::size_t bufferSize
{16};
93 std::string
date(bufferSize
, 'Z'), time(bufferSize
, 'Z'),
94 zone(bufferSize
, 'Z');
96 (date
.data(), date
.size(), time
.data(), time
.size(), zone
.data(), zone
.size(),
97 /*source=*/nullptr, /*line=*/0, /*values=*/nullptr);
98 auto isBlank
= [](const std::string
&s
) -> bool {
100 s
.begin(), s
.end(), [](char c
) { return std::isblank(c
); });
102 // Validate date is blank or YYYYMMDD.
107 // Use stol to allow GCC 7.5 to build tests
108 number
= std::stol(date
);
109 ASSERT_TRUE(errno
!= ERANGE
);
110 EXPECT_GE(number
, 0);
111 auto year
= number
/ 10000;
112 auto month
= (number
- year
* 10000) / 100;
113 auto day
= number
% 100;
114 // Do not assume anything about the year, the test could be
115 // run on system with fake/outdated dates.
116 EXPECT_LE(month
, 12);
122 // Validate time is hhmmss.sss or blank.
123 std::string
acceptedPattern("hhmmss.sss");
128 // Use stol to allow GCC 7.5 to build tests
129 auto dotPosition
= acceptedPattern
.find('.');
130 number
= std::stol(time
.substr(0, dotPosition
));
131 ASSERT_TRUE(errno
!= ERANGE
);
132 ASSERT_GE(number
, 0);
133 auto hours
= number
/ 10000;
134 auto minutes
= (number
- hours
* 10000) / 100;
135 auto seconds
= number
% 100;
136 EXPECT_LE(hours
, 23);
137 EXPECT_LE(minutes
, 59);
138 // Accept 60 for leap seconds.
139 EXPECT_LE(seconds
, 60);
140 EXPECT_EQ(time
.substr(dotPosition
, 1), ".");
142 count_t milliseconds
{-1};
143 milliseconds
= std::stol(time
.substr(dotPosition
+ 1, 3));
144 ASSERT_TRUE(errno
!= ERANGE
);
145 EXPECT_GE(milliseconds
, 0);
146 EXPECT_LE(milliseconds
, 999);
149 // Validate zone is +hhmm or -hhmm or blank.
153 ASSERT_TRUE(zone
.size() > 1);
154 EXPECT_TRUE(zone
[0] == '+' || zone
[0] == '-');
156 // Use stol to allow GCC 7.5 to build tests
157 number
= std::stol(zone
.substr(1, 4));
158 ASSERT_TRUE(errno
!= ERANGE
);
159 ASSERT_GE(number
, 0);
160 auto hours
= number
/ 100;
161 auto minutes
= number
% 100;
162 EXPECT_LE(hours
, 23);
163 EXPECT_LE(minutes
, 59);