Skip to content

Commit

Permalink
crash_tracker/test: validate file cleanup
Browse files Browse the repository at this point in the history
Implement a simple test to verify that crash reports are getting removed
on `start()` when their number exceeds `crash_files_to_keep`.
  • Loading branch information
pgellert committed Feb 3, 2025
1 parent ad6df1c commit e7d5780
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/v/crash_tracker/recorder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ recorder& get_recorder() {
return inst;
}

recorder get_test_recorder() { return recorder{}; }

ss::future<> recorder::ensure_crashdir_exists() const {
auto crash_report_dir = config::node().crash_report_dir_path();
if (!co_await ss::file_exists(crash_report_dir.string())) {
Expand Down
8 changes: 7 additions & 1 deletion src/v/crash_tracker/recorder.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class recorder {
using include_malformed_files
= ss::bool_class<struct include_malformed_files_tag>;

/// Visible for testing
~recorder() = default;

ss::future<> start();
ss::future<> stop();

Expand All @@ -56,7 +59,6 @@ class recorder {

private:
recorder() = default;
~recorder() = default;

ss::future<> ensure_crashdir_exists() const;
ss::future<std::filesystem::path> generate_crashfile_name() const;
Expand All @@ -65,9 +67,13 @@ class recorder {
prepared_writer _writer;

friend recorder& get_recorder();
friend recorder get_test_recorder();
};

/// Singleton access to global static recorder
recorder& get_recorder();

/// Make a test instance of the recorder that is not a static singleton
recorder get_test_recorder();

} // namespace crash_tracker
15 changes: 15 additions & 0 deletions src/v/crash_tracker/tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@ redpanda_cc_gtest(
],
)

redpanda_cc_gtest(
name = "recorder_test",
timeout = "short",
srcs = [
"recorder_test.cc",
],
deps = [
"//src/v/config",
"//src/v/crash_tracker",
"//src/v/model",
"//src/v/test_utils:gtest",
"@googletest//:gtest",
],
)

redpanda_cc_binary(
name = "crash_report_generator",
srcs = ["report_generator.cc"],
Expand Down
10 changes: 10 additions & 0 deletions src/v/crash_tracker/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ rp_test(
ARGS "-- -c 1"
)

rp_test(
UNIT_TEST
GTEST
BINARY_NAME recorder_test
SOURCES
recorder_test.cc
LIBRARIES v::gtest_main v::config v::crash_tracker
ARGS "-- -c 1"
)

add_executable(crash_report_generator report_generator.cc)
set_property(TARGET crash_report_generator PROPERTY POSITION_INDEPENDENT_CODE ON)
target_link_libraries(crash_report_generator PUBLIC v::crash_tracker)
Expand Down
58 changes: 58 additions & 0 deletions src/v/crash_tracker/tests/recorder_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright 2025 Redpanda Data, Inc.
*
* Licensed as a Redpanda Enterprise file under the Redpanda Community
* License (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* https://github.com/redpanda-data/redpanda/blob/master/licenses/rcl.md
*/

#include "config/node_config.h"
#include "crash_tracker/recorder.h"
#include "test_utils/tmp_dir.h"

#include <gtest/gtest.h>

#include <exception>
#include <stdexcept>

namespace crash_tracker {

class RecorderTest : public testing::Test {
public:
void SetUp() override {
config::node().data_directory.set_value(_dir.get_path());
}
void TearDown() override {
_dir.remove().get();
config::node().data_directory.reset();
}

private:
temporary_dir _dir{"recorder_test"};
};

TEST_F(RecorderTest, TestFileCleanup) {
const auto test_eptr = std::make_exception_ptr(std::runtime_error{""});

// Observe no recorded crashes before the first start
auto crashes = get_test_recorder().get_recorded_crashes().get();
ASSERT_EQ(crashes.size(), 0);

// Simulate lots of crashed restarts to generate crash reports on disk
for (size_t i = 0; i < recorder::crash_files_to_keep + 5; i++) {
auto rec = get_test_recorder();
rec.start().get();
rec.record_crash_exception(test_eptr);
}

// Run one more restart and observe that old crash files are cleaned up
auto rec = get_test_recorder();
rec.start().get();

crashes = rec.get_recorded_crashes().get();
ASSERT_EQ(crashes.size(), recorder::crash_files_to_keep);
}

} // namespace crash_tracker

0 comments on commit e7d5780

Please sign in to comment.