From 7a97e873d98d07686160c91698ddb2f9767a8d29 Mon Sep 17 00:00:00 2001 From: Gerhard Schwanzer Date: Sun, 5 Jul 2026 15:52:25 +0200 Subject: [PATCH] Test Qt-only autosave recovery fallback Add a no-KF5 Catch regression test that leaves a KAutoSaveFile-compatible backup behind from a child process, then verifies stale-file discovery, stale-lock recovery, reading, and cleanup. Assisted-by: pi coding agent / Mika (OpenAI GPT-5.5) --- tests/catch/CMakeLists.txt | 14 +++++ tests/catch/src/kautosavefile_test.cpp | 81 ++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 tests/catch/src/kautosavefile_test.cpp diff --git a/tests/catch/CMakeLists.txt b/tests/catch/CMakeLists.txt index 5d39537fe..fb4ead5a3 100644 --- a/tests/catch/CMakeLists.txt +++ b/tests/catch/CMakeLists.txt @@ -83,6 +83,20 @@ add_executable( ${QET_DIR}/sources/borderproperties.h ) +if(NOT BUILD_WITH_KF5) + target_sources( + ${PROJECT_NAME} + PRIVATE + src/kautosavefile_test.cpp + ${QET_DIR}/sources/ui/nokde/kautosavefile.cpp + ) + target_include_directories( + ${PROJECT_NAME} + PRIVATE + ${QET_DIR}/sources/ui/nokde + ) +endif() + target_link_libraries( ${PROJECT_NAME} PUBLIC diff --git a/tests/catch/src/kautosavefile_test.cpp b/tests/catch/src/kautosavefile_test.cpp new file mode 100644 index 000000000..c2690bb9c --- /dev/null +++ b/tests/catch/src/kautosavefile_test.cpp @@ -0,0 +1,81 @@ +#include "../../../sources/ui/nokde/kautosavefile.h" + +#include + +#include +#include +#include +#include +#include + +#include + +#ifdef Q_OS_UNIX +#include +#include +#include +#endif + +TEST_CASE("Qt-only KAutoSaveFile recovers stale files", "[nokde][autosave]") +{ +#ifndef Q_OS_UNIX + SUCCEED("crash-style stale lock test is Unix-only"); +#else + QTemporaryDir data_home; + REQUIRE(data_home.isValid()); + + qputenv("XDG_DATA_HOME", QFile::encodeName(data_home.path())); + QCoreApplication::setOrganizationName(QStringLiteral("QElectroTech")); + QCoreApplication::setApplicationName(QStringLiteral("KAutoSaveFileTest")); + + const auto managed_path = data_home.filePath(QStringLiteral("project.qet")); + QFile managed_file(managed_path); + REQUIRE(managed_file.open(QIODevice::WriteOnly | QIODevice::Text)); + REQUIRE(managed_file.write("\n") > 0); + managed_file.close(); + + const QByteArray payload("\n"); + const auto child_pid = fork(); + REQUIRE(child_pid >= 0); + + if (child_pid == 0) { + KAutoSaveFile backup(QUrl::fromLocalFile(managed_path)); + if (!backup.open(QIODevice::WriteOnly + | QIODevice::Truncate + | QIODevice::Text)) { + _exit(2); + } + if (backup.write(payload) != payload.size()) { + _exit(3); + } + if (!backup.flush()) { + _exit(4); + } + + _exit(0); + } + + int status = 0; + REQUIRE(waitpid(child_pid, &status, 0) == child_pid); + REQUIRE(WIFEXITED(status)); + REQUIRE(WEXITSTATUS(status) == 0); + + auto stale_files = KAutoSaveFile::allStaleFiles(); + REQUIRE(stale_files.size() == 1); + + std::unique_ptr stale_file(stale_files.takeFirst()); + CHECK(stale_file->managedFile().path() + == QFileInfo(managed_path).absoluteFilePath()); + REQUIRE(stale_file->open(QIODevice::ReadOnly | QIODevice::Text)); + CHECK(stale_file->readAll() == payload); + + const auto autosave_file_name = stale_file->fileName(); + const auto metadata_file_name = autosave_file_name + QStringLiteral(".path"); + const auto lock_file_name = autosave_file_name + QStringLiteral(".lock"); + stale_file.reset(); + + CHECK_FALSE(QFile::exists(autosave_file_name)); + CHECK_FALSE(QFile::exists(metadata_file_name)); + CHECK_FALSE(QFile::exists(lock_file_name)); +#endif +}