test_util.cc 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // Copyright 2017 The Abseil Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "absl/time/internal/test_util.h"
  15. #include <algorithm>
  16. #include <cstddef>
  17. #include <cstring>
  18. #include "absl/base/config.h"
  19. #include "absl/base/internal/raw_logging.h"
  20. #include "absl/time/internal/cctz/include/cctz/zone_info_source.h"
  21. namespace cctz = absl::time_internal::cctz;
  22. namespace absl {
  23. ABSL_NAMESPACE_BEGIN
  24. namespace time_internal {
  25. TimeZone LoadTimeZone(const std::string& name) {
  26. TimeZone tz;
  27. ABSL_RAW_CHECK(LoadTimeZone(name, &tz), name.c_str());
  28. return tz;
  29. }
  30. } // namespace time_internal
  31. ABSL_NAMESPACE_END
  32. } // namespace absl
  33. namespace absl {
  34. ABSL_NAMESPACE_BEGIN
  35. namespace time_internal {
  36. namespace cctz_extension {
  37. namespace {
  38. // Embed the zoneinfo data for time zones used during tests and benchmarks.
  39. // The data was generated using "xxd -i zoneinfo-file". There is no need
  40. // to update the data as long as the tests do not depend on recent changes
  41. // (and the past rules remain the same).
  42. #include "absl/time/internal/zoneinfo.inc"
  43. const struct ZoneInfo {
  44. const char* name;
  45. const char* data;
  46. std::size_t length;
  47. } kZoneInfo[] = {
  48. // The three real time zones used by :time_test and :time_benchmark.
  49. {"America/Los_Angeles", //
  50. reinterpret_cast<char*>(America_Los_Angeles), America_Los_Angeles_len},
  51. {"America/New_York", //
  52. reinterpret_cast<char*>(America_New_York), America_New_York_len},
  53. {"Australia/Sydney", //
  54. reinterpret_cast<char*>(Australia_Sydney), Australia_Sydney_len},
  55. // Other zones named in tests but which should fail to load.
  56. {"Invalid/TimeZone", nullptr, 0},
  57. {"", nullptr, 0},
  58. // Also allow for loading the local time zone under TZ=US/Pacific.
  59. {"US/Pacific", //
  60. reinterpret_cast<char*>(America_Los_Angeles), America_Los_Angeles_len},
  61. // Allows use of the local time zone from a system-specific location.
  62. #ifdef _MSC_VER
  63. {"localtime", //
  64. reinterpret_cast<char*>(America_Los_Angeles), America_Los_Angeles_len},
  65. #else
  66. {"/etc/localtime", //
  67. reinterpret_cast<char*>(America_Los_Angeles), America_Los_Angeles_len},
  68. #endif
  69. };
  70. class TestZoneInfoSource : public cctz::ZoneInfoSource {
  71. public:
  72. TestZoneInfoSource(const char* data, std::size_t size)
  73. : data_(data), end_(data + size) {}
  74. std::size_t Read(void* ptr, std::size_t size) override {
  75. const std::size_t len = std::min<std::size_t>(size, end_ - data_);
  76. memcpy(ptr, data_, len);
  77. data_ += len;
  78. return len;
  79. }
  80. int Skip(std::size_t offset) override {
  81. data_ += std::min<std::size_t>(offset, end_ - data_);
  82. return 0;
  83. }
  84. private:
  85. const char* data_;
  86. const char* const end_;
  87. };
  88. std::unique_ptr<cctz::ZoneInfoSource> TestFactory(
  89. const std::string& name,
  90. const std::function<std::unique_ptr<cctz::ZoneInfoSource>(
  91. const std::string& name)>& /*fallback_factory*/) {
  92. for (const ZoneInfo& zoneinfo : kZoneInfo) {
  93. if (name == zoneinfo.name) {
  94. if (zoneinfo.data == nullptr) return nullptr;
  95. return std::unique_ptr<cctz::ZoneInfoSource>(
  96. new TestZoneInfoSource(zoneinfo.data, zoneinfo.length));
  97. }
  98. }
  99. ABSL_RAW_LOG(FATAL, "Unexpected time zone \"%s\" in test", name.c_str());
  100. return nullptr;
  101. }
  102. } // namespace
  103. #if !defined(__MINGW32__)
  104. // MinGW does not support the weak symbol extension mechanism.
  105. ZoneInfoSourceFactory zone_info_source_factory = TestFactory;
  106. #endif
  107. } // namespace cctz_extension
  108. } // namespace time_internal
  109. ABSL_NAMESPACE_END
  110. } // namespace absl