brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.4 KiB · 548c083 Raw
165 lines · cpp
1//===-- unittests/Runtime/Time.cpp ------------------------------*- C++ -*-===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "gtest/gtest.h"10#include "flang/Runtime/time-intrinsic.h"11#include <algorithm>12#include <cctype>13#include <cerrno>14#include <string>15 16using namespace Fortran::runtime;17 18TEST(TimeIntrinsics, CpuTime) {19  // We can't really test that we get the "right" result for CPU_TIME, but we20  // can have a smoke test to see that we get something reasonable on the21  // platforms where we expect to support it.22  double start{RTNAME(CpuTime)()};23  ASSERT_GE(start, 0.0);24 25  // Loop until we get a different value from CpuTime. If we don't get one26  // before we time out, then we should probably look into an implementation27  // 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);31  }32}33 34using count_t = std::int64_t;35 36TEST(TimeIntrinsics, SystemClock) {37  // We can't really test that we get the "right" result for SYSTEM_CLOCK, but38  // we can have a smoke test to see that we get something reasonable on the39  // platforms where we expect to support it.40 41  // The value of the count rate and max will vary by platform, but they should42  // always be strictly positive if we have a working implementation of43  // SYSTEM_CLOCK.44  EXPECT_GT(RTNAME(SystemClockCountRate)(), 0);45 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);52 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);59 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);66 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);72 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);78 79  // Loop until we get a different value from SystemClockCount. If we don't get80  // one before we time out, then we should probably look into an implementation81  // 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);86  }87}88 89TEST(TimeIntrinsics, DateAndTime) {90  errno = 0;91  constexpr std::size_t bufferSize{16};92  std::string date(bufferSize, 'Z'), time(bufferSize, 'Z'),93      zone(bufferSize, 'Z');94  RTNAME(DateAndTime)95  (date.data(), date.size(), time.data(), time.size(), zone.data(), zone.size(),96      /*source=*/nullptr, /*line=*/0, /*values=*/nullptr);97  auto isBlank = [](const std::string &s) -> bool {98    return std::all_of(99        s.begin(), s.end(), [](char c) { return std::isblank(c); });100  };101  // Validate date is blank or YYYYMMDD.102  if (isBlank(date)) {103    EXPECT_TRUE(true);104  } else {105    count_t number{-1};106    // Use stol to allow GCC 7.5 to build tests107    number = std::stol(date);108    ASSERT_TRUE(errno != ERANGE);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 be114    // 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);119  }120 121  // Validate time is hhmmss.sss or blank.122  std::string acceptedPattern("hhmmss.sss");123  if (isBlank(time)) {124    EXPECT_TRUE(true);125  } else {126    count_t number{-1};127    // Use stol to allow GCC 7.5 to build tests128    auto dotPosition = acceptedPattern.find('.');129    number = std::stol(time.substr(0, dotPosition));130    ASSERT_TRUE(errno != ERANGE);131    ASSERT_GE(number, 0);132    auto hours = number / 10000;133    auto minutes = (number - hours * 10000) / 100;134    auto seconds = number % 100;135    EXPECT_LE(hours, 23);136    EXPECT_LE(minutes, 59);137    // Accept 60 for leap seconds.138    EXPECT_LE(seconds, 60);139    EXPECT_EQ(time.substr(dotPosition, 1), ".");140 141    count_t milliseconds{-1};142    milliseconds = std::stol(time.substr(dotPosition + 1, 3));143    ASSERT_TRUE(errno != ERANGE);144    EXPECT_GE(milliseconds, 0);145    EXPECT_LE(milliseconds, 999);146  }147 148  // Validate zone is +hhmm or -hhmm or blank.149  if (isBlank(zone)) {150    EXPECT_TRUE(true);151  } else {152    ASSERT_TRUE(zone.size() > 1);153    EXPECT_TRUE(zone[0] == '+' || zone[0] == '-');154    count_t number{-1};155    // Use stol to allow GCC 7.5 to build tests156    number = std::stol(zone.substr(1, 4));157    ASSERT_TRUE(errno != ERANGE);158    ASSERT_GE(number, 0);159    auto hours = number / 100;160    auto minutes = number % 100;161    EXPECT_LE(hours, 23);162    EXPECT_LE(minutes, 59);163  }164}165