| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| // These macros and functions are inspired by Apache Kudu. |
| |
| #pragma once |
| |
| #include <fmt/core.h> |
| #include <gtest/gtest.h> |
| #include <chrono> |
| #include <cstdint> |
| #include <cstdio> |
| #include <functional> |
| #include <string> |
| |
| #include "runtime/api_layer1.h" |
| #include "utils/env.h" |
| // IWYU refused to include "utils/defer.h" everywhere, both in .h and .cpp files. |
| // However, once "utils/defer.h" is not included, it is inevitable that compilation |
| // will fail since dsn::defer is referenced. Thus force IWYU to keep it. |
| #include "utils/defer.h" // IWYU pragma: keep |
| #include "utils/flags.h" |
| #include "utils/test_macros.h" |
| |
| DSN_DECLARE_bool(encrypt_data_at_rest); |
| |
| namespace dsn { |
| namespace replication { |
| class file_meta; |
| } // namespace replication |
| } // namespace dsn |
| |
| // Save the current value of a flag and restore it at the end of the function. |
| #define PRESERVE_FLAG(name) \ |
| const auto PRESERVED_FLAGS_##name = FLAGS_##name; \ |
| auto PRESERVED_FLAGS_##name##_cleanup = \ |
| dsn::defer([PRESERVED_FLAGS_##name]() { FLAGS_##name = PRESERVED_FLAGS_##name; }) |
| |
| namespace pegasus { |
| |
| // A base parameterized test class for testing enable/disable encryption at rest. |
| class encrypt_data_test_base : public testing::TestWithParam<bool> |
| { |
| public: |
| encrypt_data_test_base() |
| { |
| FLAGS_encrypt_data_at_rest = GetParam(); |
| // The size of an actual encrypted file should plus kEncryptionHeaderkSize bytes if consider |
| // it as kNonSensitive. |
| if (FLAGS_encrypt_data_at_rest) { |
| _extra_encrypted_file_size = dsn::utils::kEncryptionHeaderkSize; |
| } |
| } |
| |
| uint64_t extra_encrypted_file_size() const { return _extra_encrypted_file_size; } |
| |
| private: |
| uint64_t _extra_encrypted_file_size = 0; |
| }; |
| |
| class stop_watch |
| { |
| public: |
| stop_watch() { _start_ms = dsn_now_ms(); } |
| void stop_and_output(const std::string &msg) |
| { |
| auto duration_ms = |
| std::chrono::duration_cast<std::chrono::duration<double>>( |
| std::chrono::milliseconds(static_cast<int64_t>(dsn_now_ms() - _start_ms))) |
| .count(); |
| fmt::print(stdout, "{}, cost {} ms\n", msg, duration_ms); |
| } |
| |
| private: |
| uint64_t _start_ms = 0; |
| }; |
| |
| void create_local_test_file(const std::string &full_name, dsn::replication::file_meta *fm); |
| |
| #define ASSERT_EVENTUALLY(expr) \ |
| do { \ |
| AssertEventually(expr); \ |
| NO_PENDING_FATALS(); \ |
| } while (0) |
| |
| #define ASSERT_IN_TIME(expr, sec) \ |
| do { \ |
| AssertEventually(expr, sec); \ |
| NO_PENDING_FATALS(); \ |
| } while (0) |
| |
| #define ASSERT_IN_TIME_WITH_FIXED_INTERVAL(expr, sec) \ |
| do { \ |
| AssertEventually(expr, sec, ::pegasus::WaitBackoff::NONE); \ |
| NO_PENDING_FATALS(); \ |
| } while (0) |
| |
| #define WAIT_IN_TIME(expr, sec) \ |
| do { \ |
| WaitCondition(expr, sec); \ |
| NO_PENDING_FATALS(); \ |
| } while (0) |
| |
| // Wait until 'f()' succeeds without adding any GTest 'fatal failures'. |
| // For example: |
| // |
| // AssertEventually([]() { |
| // ASSERT_GT(ReadValueOfMetric(), 10); |
| // }); |
| // |
| // The function is run in a loop with optional back-off. |
| // |
| // To check whether AssertEventually() eventually succeeded, call |
| // NO_PENDING_FATALS() afterward, or use ASSERT_EVENTUALLY() which performs |
| // this check automatically. |
| enum class WaitBackoff |
| { |
| // Use exponential back-off while looping, capped at one second. |
| EXPONENTIAL, |
| |
| // Sleep for a millisecond while looping. |
| NONE, |
| }; |
| void AssertEventually(const std::function<void(void)> &f, |
| int timeout_sec = 30, |
| WaitBackoff backoff = WaitBackoff::EXPONENTIAL); |
| |
| // Wait until 'f()' succeeds or timeout, there is no GTest 'fatal failures' |
| // regardless failed or timeout. |
| void WaitCondition(const std::function<bool(void)> &f, |
| int timeout_sec = 30, |
| WaitBackoff backoff = WaitBackoff::EXPONENTIAL); |
| } // namespace pegasus |