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 #include "gtest/gtest.h"
10 #include "flang/Runtime/time-intrinsic.h"
16 using namespace Fortran::runtime
;
18 TEST(TimeIntrinsics
, CpuTime
) {
19 // We can't really test that we get the "right" result for CPU_TIME, but we
20 // can have a smoke test to see that we get something reasonable on the
21 // platforms where we expect to support it.
22 double start
{RTNAME(CpuTime
)()};
23 ASSERT_GE(start
, 0.0);
25 // Loop until we get a different value from CpuTime. If we don't get one
26 // before we time out, then we should probably look into an implementation
27 // for CpuTime with a better timer resolution.
28 for (double end
= start
; end
== start
; end
= RTNAME(CpuTime
)()) {
30 ASSERT_GE(end
, start
);
34 using count_t
= std::int64_t;
36 TEST(TimeIntrinsics
, SystemClock
) {
37 // We can't really test that we get the "right" result for SYSTEM_CLOCK, but
38 // we can have a smoke test to see that we get something reasonable on the
39 // platforms where we expect to support it.
41 // The value of the count rate and max will vary by platform, but they should
42 // always be strictly positive if we have a working implementation of
44 EXPECT_GT(RTNAME(SystemClockCountRate
)(), 0);
46 count_t max1
{RTNAME(SystemClockCountMax
)(1)};
48 EXPECT_LE(max1
, static_cast<count_t
>(0x7f));
49 count_t start1
{RTNAME(SystemClockCount
)(1)};
51 EXPECT_LE(start1
, max1
);
53 count_t max2
{RTNAME(SystemClockCountMax
)(2)};
55 EXPECT_LE(max2
, static_cast<count_t
>(0x7fff));
56 count_t start2
{RTNAME(SystemClockCount
)(2)};
58 EXPECT_LE(start2
, max2
);
60 count_t max4
{RTNAME(SystemClockCountMax
)(4)};
62 EXPECT_LE(max4
, static_cast<count_t
>(0x7fffffff));
63 count_t start4
{RTNAME(SystemClockCount
)(4)};
65 EXPECT_LE(start4
, max4
);
67 count_t max8
{RTNAME(SystemClockCountMax
)(8)};
69 count_t start8
{RTNAME(SystemClockCount
)(8)};
71 EXPECT_LT(start8
, max8
);
73 count_t max16
{RTNAME(SystemClockCountMax
)(16)};
75 count_t start16
{RTNAME(SystemClockCount
)(16)};
76 EXPECT_GE(start16
, 0);
77 EXPECT_LT(start16
, max16
);
79 // Loop until we get a different value from SystemClockCount. If we don't get
80 // one before we time out, then we should probably look into an implementation
81 // for SystemClokcCount with a better timer resolution on this platform.
82 for (count_t end
{start8
}; end
== start8
; end
= RTNAME(SystemClockCount
)(8)) {
85 EXPECT_GE(end
, start8
);
89 TEST(TimeIntrinsics
, DateAndTime
) {
90 constexpr std::size_t bufferSize
{16};
91 std::string
date(bufferSize
, 'Z'), time(bufferSize
, 'Z'),
92 zone(bufferSize
, 'Z');
94 (date
.data(), date
.size(), time
.data(), time
.size(), zone
.data(), zone
.size(),
95 /*source=*/nullptr, /*line=*/0, /*values=*/nullptr);
96 auto isBlank
= [](const std::string
&s
) -> bool {
98 s
.begin(), s
.end(), [](char c
) { return std::isblank(c
); });
100 // Validate date is blank or YYYYMMDD.
106 std::from_chars(date
.data(), date
.data() + date
.size(), number
)};
107 ASSERT_TRUE(ec
!= std::errc::invalid_argument
&&
108 ec
!= std::errc::result_out_of_range
);
109 EXPECT_GE(number
, 0);
110 auto year
= number
/ 10000;
111 auto month
= (number
- year
* 10000) / 100;
112 auto day
= number
% 100;
113 // Do not assume anything about the year, the test could be
114 // run on system with fake/outdated dates.
115 EXPECT_LE(month
, 12);
121 // Validate time is hhmmss.sss or blank.
127 std::from_chars(time
.data(), time
.data() + date
.size(), number
)};
128 ASSERT_TRUE(ec
!= std::errc::invalid_argument
&&
129 ec
!= std::errc::result_out_of_range
);
130 ASSERT_GE(number
, 0);
131 auto hours
= number
/ 10000;
132 auto minutes
= (number
- hours
* 10000) / 100;
133 auto seconds
= number
% 100;
134 EXPECT_LE(hours
, 23);
135 EXPECT_LE(minutes
, 59);
136 // Accept 60 for leap seconds.
137 EXPECT_LE(seconds
, 60);
138 ASSERT_TRUE(next
!= time
.data() + time
.size());
139 EXPECT_EQ(*next
, '.');
141 count_t milliseconds
{-1};
142 ASSERT_TRUE(next
+ 1 != time
.data() + time
.size());
144 std::from_chars(next
+ 1, time
.data() + date
.size(), milliseconds
)};
145 ASSERT_TRUE(ec2
!= std::errc::invalid_argument
&&
146 ec2
!= std::errc::result_out_of_range
);
147 EXPECT_GE(milliseconds
, 0);
148 EXPECT_LE(milliseconds
, 999);
151 // Validate zone is +hhmm or -hhmm or blank.
155 ASSERT_TRUE(zone
.size() > 1);
156 EXPECT_TRUE(zone
[0] == '+' || zone
[0] == '-');
159 std::from_chars(zone
.data() + 1, zone
.data() + zone
.size(), number
)};
160 ASSERT_TRUE(ec
!= std::errc::invalid_argument
&&
161 ec
!= std::errc::result_out_of_range
);
162 ASSERT_GE(number
, 0);
163 auto hours
= number
/ 100;
164 auto minutes
= number
% 100;
165 EXPECT_LE(hours
, 23);
166 EXPECT_LE(minutes
, 59);