Skip to content

Commit

Permalink
test_utils: utility for getting a test directory
Browse files Browse the repository at this point in the history
This adds a utility method to get the pathname for a directory that
should be uniquely used by a single test case iteration.
  • Loading branch information
andrwng committed May 13, 2024
1 parent d55749d commit b8ffc7b
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/v/test_utils/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ find_package(GTest)

v_cc_library(
NAME gtest_main
SRCS gtest_main.cc
SRCS
gtest_main.cc
gtest_utils.cc
DEPS Seastar::seastar Seastar::seastar_testing GTest::gtest GTest::gmock v::bytes_random)

add_subdirectory(tests)
4 changes: 4 additions & 0 deletions src/v/test_utils/gtest_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@
* the Business Source License, use of this software will be governed
* by the Apache License, Version 2.0
*/
#include "test_utils/gtest_utils.h"
#include "test_utils/test.h"

int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
GTEST_FLAG_SET(death_test_style, "threadsafe");

auto& listeners = ::testing::UnitTest::GetInstance()->listeners();
listeners.Append(new rp_test_listener());

/*
* if the test is being passed --gtest_list_tests then do not start Seastar.
* this is an important optimization for using `gtest_discover_tests`
Expand Down
52 changes: 52 additions & 0 deletions src/v/test_utils/gtest_utils.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright 2024 Redpanda Data, Inc.
*
* Use of this software is governed by the Business Source License
* included in the file licenses/BSL.md
*
* As of the Change Date specified in that file, in accordance with
* the Business Source License, use of this software will be governed
* by the Apache License, Version 2.0
*/
#include "test_utils/gtest_utils.h"

#include "base/vassert.h"
#include "random/generators.h"

#include <seastar/core/lowres_clock.hh>

#include <fmt/format.h>
#include <gtest/gtest.h>

namespace {
int gtest_iteration = 0;
} // anonymous namespace

void rp_test_listener::OnTestIterationStart(
const ::testing::UnitTest& /*unit_test*/, int iteration) {
gtest_iteration = iteration;
}

ss::sstring get_test_directory() {
const auto* test_info
= ::testing::UnitTest::GetInstance()->current_test_info();
vassert(test_info != nullptr, "Must be a gtest!");

// The current timestamp uniquely identifies the process' test incantation,
// and the test iteration uniquely identifies the individual runs of test
// cases, e.g. in case of --gtest_repeat.
//
// This allows repeated test runs to operate independently without worrying
// about leftover files from previous iterations.
static auto now = ss::lowres_clock::now();
ss::sstring dir = fmt::format(
"{}.{}.{}.{}",
test_info->test_suite_name(),
test_info->name(),
now.time_since_epoch().count(),
gtest_iteration);

// Swap out any '/'s (may come from parameterized tests).
std::replace(dir.begin(), dir.end(), '/', '_');
return dir;
}
41 changes: 41 additions & 0 deletions src/v/test_utils/gtest_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright 2024 Redpanda Data, Inc.
*
* Use of this software is governed by the Business Source License
* included in the file licenses/BSL.md
*
* As of the Change Date specified in that file, in accordance with
* the Business Source License, use of this software will be governed
* by the Apache License, Version 2.0
*/
#pragma once

#include "base/seastarx.h"

#include <seastar/core/seastar.hh>

#include <gtest/gtest.h>

// Listens to the start of a gtest test iteration. May be used to track the
// test iteration number.
class rp_test_listener : public ::testing::EmptyTestEventListener {
void
OnTestIterationStart(const ::testing::UnitTest&, int iteration) override;
};

// Returns a pathname that may be used for the currently running test.
// Expects that the caller is in the context of a GTest.
//
// Relies on callers to create the directory.
//
// Examples:
//
// clang-format off
// MySeastarFixture.TestGetTestDirectory.6125307633855650.4
// ^-- test suite ^-- test case ^-- timestamp ^-- iteration
//
// Divisible_MySeastarParamFixture.TestGetTestDirectory_0.6126774487959615.6
// ^-- parameter name ^-- parameter ^-- iteration
// ^-- test suite ^-- test case ^-- timestamp
// clang-format on
ss::sstring get_test_directory();
39 changes: 39 additions & 0 deletions src/v/test_utils/tests/gtest_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,15 @@
* by the Apache License, Version 2.0
*/
#include "test_utils/async.h"
#include "test_utils/gtest_utils.h"
#include "test_utils/test.h"

#include <seastar/core/seastar.hh>
#include <seastar/core/sleep.hh>
#include <seastar/util/defer.hh>
#include <seastar/util/file.hh>

#include <gtest/gtest.h>

#include <chrono>

Expand Down Expand Up @@ -163,3 +169,36 @@ TEST_P(NotSeastarFixtureParam, T) {}

INSTANTIATE_TEST_SUITE_P(
NotSeastarParamTest, NotSeastarFixtureParam, testing::Values(1, 2, 3));

class directory_test {
public:
// Test body that creates and removes a test directory.
// Encapsulated to be reused across different test harness types.
void create_and_remove() {
auto dir = get_test_directory();
auto dir_again = get_test_directory();

// Repeated calls to get_test_directory() from the same test process
// should result in the same output.
ASSERT_EQ(dir, dir_again);

ASSERT_FALSE(ss::file_exists(dir).get());
ss::recursive_touch_directory(dir).get();
auto cleanup = ss::defer([&dir] {
ss::recursive_remove_directory(std::filesystem::path{dir}).get();
});
ASSERT_TRUE(ss::file_exists(dir).get());
}
};

TEST(NotSeastar, TestGetTestDirectory) {
ASSERT_NO_FATAL_FAILURE(directory_test{}.create_and_remove());
}

TEST_F(MySeastarFixture, TestGetTestDirectory) {
ASSERT_NO_FATAL_FAILURE(directory_test{}.create_and_remove());
}

TEST_P(MySeastarParamFixture, TestGetTestDirectory) {
ASSERT_NO_FATAL_FAILURE(directory_test{}.create_and_remove());
}

0 comments on commit b8ffc7b

Please sign in to comment.