132 lines
3.8 KiB
C++
132 lines
3.8 KiB
C++
#include "Test.h"
|
|
|
|
#include "Command.h"
|
|
#include "Editor.h"
|
|
|
|
#include "tests/TestHarness.h" // for ktet::InstallDefaultCommandsOnce
|
|
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
#include <string>
|
|
#include <unistd.h>
|
|
|
|
namespace fs = std::filesystem;
|
|
|
|
|
|
static void
|
|
write_file_bytes(const std::string &path, const std::string &bytes)
|
|
{
|
|
std::ofstream out(path, std::ios::binary | std::ios::trunc);
|
|
out.write(bytes.data(), (std::streamsize) bytes.size());
|
|
}
|
|
|
|
|
|
TEST(SwapCleanup_ResetJournalOnSave)
|
|
{
|
|
ktet::InstallDefaultCommandsOnce();
|
|
|
|
const fs::path xdg_root = fs::temp_directory_path() /
|
|
(std::string("kte_ut_xdg_state_swap_cleanup_") + std::to_string((int) ::getpid()));
|
|
fs::remove_all(xdg_root);
|
|
fs::create_directories(xdg_root);
|
|
|
|
const char *old_xdg_p = std::getenv("XDG_STATE_HOME");
|
|
const std::string old_xdg = old_xdg_p ? std::string(old_xdg_p) : std::string();
|
|
const std::string xdg_s = xdg_root.string();
|
|
setenv("XDG_STATE_HOME", xdg_s.c_str(), 1);
|
|
|
|
const std::string path = (xdg_root / "work" / "file.txt").string();
|
|
fs::create_directories((xdg_root / "work"));
|
|
std::remove(path.c_str());
|
|
write_file_bytes(path, "base\n");
|
|
|
|
Editor ed;
|
|
ed.SetDimensions(24, 80);
|
|
// Seed scratch buffer so OpenFile can reuse it.
|
|
ed.AddBuffer(Buffer());
|
|
std::string err;
|
|
ASSERT_TRUE(ed.OpenFile(path, err));
|
|
Buffer *b = ed.CurrentBuffer();
|
|
ASSERT_TRUE(b != nullptr);
|
|
|
|
// Edit to ensure swap is created.
|
|
ASSERT_TRUE(Execute(ed, CommandId::MoveFileStart));
|
|
ASSERT_TRUE(Execute(ed, CommandId::InsertText, "X"));
|
|
ASSERT_TRUE(b->Dirty());
|
|
|
|
ed.Swap()->Flush(b);
|
|
const std::string swp = kte::SwapManager::ComputeSwapPathForTests(*b);
|
|
ASSERT_TRUE(fs::exists(swp));
|
|
|
|
// Save should reset/delete the journal.
|
|
ASSERT_TRUE(Execute(ed, CommandId::Save));
|
|
ed.Swap()->Flush(b);
|
|
ASSERT_TRUE(!fs::exists(swp));
|
|
|
|
// Subsequent edits should recreate a fresh swap.
|
|
ASSERT_TRUE(Execute(ed, CommandId::InsertText, "Y"));
|
|
ed.Swap()->Flush(b);
|
|
ASSERT_TRUE(fs::exists(swp));
|
|
|
|
// Cleanup.
|
|
ed.Swap()->Detach(b);
|
|
std::remove(path.c_str());
|
|
std::remove(swp.c_str());
|
|
if (!old_xdg.empty())
|
|
setenv("XDG_STATE_HOME", old_xdg.c_str(), 1);
|
|
else
|
|
unsetenv("XDG_STATE_HOME");
|
|
fs::remove_all(xdg_root);
|
|
}
|
|
|
|
|
|
TEST(SwapCleanup_PruneSwapDir_ByAge)
|
|
{
|
|
const fs::path xdg_root = fs::temp_directory_path() /
|
|
(std::string("kte_ut_xdg_state_swap_prune_") + std::to_string((int) ::getpid()));
|
|
fs::remove_all(xdg_root);
|
|
fs::create_directories(xdg_root);
|
|
|
|
const char *old_xdg_p = std::getenv("XDG_STATE_HOME");
|
|
const std::string old_xdg = old_xdg_p ? std::string(old_xdg_p) : std::string();
|
|
const std::string xdg_s = xdg_root.string();
|
|
setenv("XDG_STATE_HOME", xdg_s.c_str(), 1);
|
|
|
|
const fs::path swapdir = xdg_root / "kte" / "swap";
|
|
fs::create_directories(swapdir);
|
|
const fs::path oldp = swapdir / "old.swp";
|
|
const fs::path newp = swapdir / "new.swp";
|
|
const fs::path keep = swapdir / "note.txt";
|
|
write_file_bytes(oldp.string(), "x");
|
|
write_file_bytes(newp.string(), "y");
|
|
write_file_bytes(keep.string(), "z");
|
|
|
|
// Make old.swp look old (2 days ago) and new.swp recent.
|
|
std::error_code ec;
|
|
fs::last_write_time(oldp, fs::file_time_type::clock::now() - std::chrono::hours(48), ec);
|
|
fs::last_write_time(newp, fs::file_time_type::clock::now(), ec);
|
|
|
|
kte::SwapManager sm;
|
|
kte::SwapConfig cfg;
|
|
cfg.prune_on_startup = false;
|
|
cfg.prune_max_age_days = 1;
|
|
cfg.prune_max_files = 0; // disable count-based pruning for this test
|
|
sm.SetConfig(cfg);
|
|
sm.PruneSwapDir();
|
|
|
|
ASSERT_TRUE(!fs::exists(oldp));
|
|
ASSERT_TRUE(fs::exists(newp));
|
|
ASSERT_TRUE(fs::exists(keep));
|
|
|
|
// Cleanup.
|
|
std::remove(newp.string().c_str());
|
|
std::remove(keep.string().c_str());
|
|
if (!old_xdg.empty())
|
|
setenv("XDG_STATE_HOME", old_xdg.c_str(), 1);
|
|
else
|
|
unsetenv("XDG_STATE_HOME");
|
|
fs::remove_all(xdg_root);
|
|
}
|