[lldb] Add ability to hide the root name of a value
[llvm-project.git] / flang / unittests / Runtime / Time.cpp
blobceccb4a70805c5458a78ae1ea658e4cd0bbfe571
1 //===-- flang/unittests/Runtime/Time.cpp ----------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
9 #include "gtest/gtest.h"
10 #include "flang/Runtime/time-intrinsic.h"
11 #include <algorithm>
12 #include <cctype>
13 #include <charconv>
14 #include <string>
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)()) {
29 ASSERT_GE(end, 0.0);
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
43 // SYSTEM_CLOCK.
44 EXPECT_GT(RTNAME(SystemClockCountRate)(), 0);
46 count_t max1{RTNAME(SystemClockCountMax)(1)};
47 EXPECT_GT(max1, 0);
48 EXPECT_LE(max1, static_cast<count_t>(0x7f));
49 count_t start1{RTNAME(SystemClockCount)(1)};
50 EXPECT_GE(start1, 0);
51 EXPECT_LE(start1, max1);
53 count_t max2{RTNAME(SystemClockCountMax)(2)};
54 EXPECT_GT(max2, 0);
55 EXPECT_LE(max2, static_cast<count_t>(0x7fff));
56 count_t start2{RTNAME(SystemClockCount)(2)};
57 EXPECT_GE(start2, 0);
58 EXPECT_LE(start2, max2);
60 count_t max4{RTNAME(SystemClockCountMax)(4)};
61 EXPECT_GT(max4, 0);
62 EXPECT_LE(max4, static_cast<count_t>(0x7fffffff));
63 count_t start4{RTNAME(SystemClockCount)(4)};
64 EXPECT_GE(start4, 0);
65 EXPECT_LE(start4, max4);
67 count_t max8{RTNAME(SystemClockCountMax)(8)};
68 EXPECT_GT(max8, 0);
69 count_t start8{RTNAME(SystemClockCount)(8)};
70 EXPECT_GE(start8, 0);
71 EXPECT_LT(start8, max8);
73 count_t max16{RTNAME(SystemClockCountMax)(16)};
74 EXPECT_GT(max16, 0);
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)) {
83 EXPECT_GE(end, 0);
84 EXPECT_LE(end, max8);
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');
93 RTNAME(DateAndTime)
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 {
97 return std::all_of(
98 s.begin(), s.end(), [](char c) { return std::isblank(c); });
100 // Validate date is blank or YYYYMMDD.
101 if (isBlank(date)) {
102 EXPECT_TRUE(true);
103 } else {
104 count_t number{-1};
105 auto [_, ec]{
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);
116 EXPECT_GT(month, 0);
117 EXPECT_LE(day, 31);
118 EXPECT_GT(day, 0);
121 // Validate time is hhmmss.sss or blank.
122 if (isBlank(time)) {
123 EXPECT_TRUE(true);
124 } else {
125 count_t number{-1};
126 auto [next, ec]{
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());
143 auto [_, ec2]{
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.
152 if (isBlank(zone)) {
153 EXPECT_TRUE(true);
154 } else {
155 ASSERT_TRUE(zone.size() > 1);
156 EXPECT_TRUE(zone[0] == '+' || zone[0] == '-');
157 count_t number{-1};
158 auto [next, ec]{
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);