Public Access
- lib/storage_model (host-tested): FAT-safe names, daily Log paths, dates from Log/Capture file names, CleanupPlan by category and age, byte formatting - StorageService does all card I/O on its task: queued Log lines are written in batches each second (dropped while Logs are paused), plus file listing and deletion jobs - Settings > Storage moves into StoragePage: usage, Clean up (category, age with size preview, confirmation), Erase SD card - Clock: local date for Log names - Serial: log <text>, sd list Verified on the device: lines land in /irc/dev/#test/2026-10-02.log with folders created as needed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
75 lines
2.6 KiB
C++
75 lines
2.6 KiB
C++
#include <unity.h>
|
|
|
|
#include "cleanup_plan.h"
|
|
|
|
using namespace roro;
|
|
|
|
void setUp() {}
|
|
void tearDown() {}
|
|
|
|
static const int kToday = 20728; // 2026-10-02
|
|
|
|
static std::vector<StoredFile> files() {
|
|
return {
|
|
{"/irc/libera/#roro/2026-10-01.log", 1000}, // 1 day old
|
|
{"/irc/libera/#roro/2026-08-01.log", 2000}, // 62 days
|
|
{"/irc/libera/#roro/2025-09-01.log", 4000}, // 396 days
|
|
{"/irc/libera/#roro/undated.log", 8000},
|
|
};
|
|
}
|
|
|
|
void test_age_cutoffs_select_strictly_older_files() {
|
|
auto plan = CleanupPlan::make(files(), CleanupAge::OneMonth, kToday);
|
|
TEST_ASSERT_EQUAL(2, plan.paths.size());
|
|
TEST_ASSERT_EQUAL(6000, plan.bytes);
|
|
}
|
|
|
|
void test_a_year_keeps_everything_younger() {
|
|
auto plan = CleanupPlan::make(files(), CleanupAge::OneYear, kToday);
|
|
TEST_ASSERT_EQUAL(1, plan.paths.size());
|
|
TEST_ASSERT_EQUAL_STRING("/irc/libera/#roro/2025-09-01.log", plan.paths[0].c_str());
|
|
}
|
|
|
|
void test_undated_files_only_go_with_everything() {
|
|
auto plan = CleanupPlan::make(files(), CleanupAge::Everything, kToday);
|
|
TEST_ASSERT_EQUAL(4, plan.paths.size());
|
|
TEST_ASSERT_EQUAL(15000, plan.bytes);
|
|
}
|
|
|
|
void test_nothing_to_delete_is_an_empty_plan() {
|
|
auto plan = CleanupPlan::make({{"/irc/a/b/2026-10-02.log", 10}}, CleanupAge::OneMonth, kToday);
|
|
TEST_ASSERT_TRUE(plan.paths.empty());
|
|
TEST_ASSERT_EQUAL(0, plan.bytes);
|
|
}
|
|
|
|
void test_notes_are_never_selected() {
|
|
auto plan = CleanupPlan::make({{"/notes/2020-01-01.log", 10}}, CleanupAge::Everything, kToday);
|
|
TEST_ASSERT_TRUE(plan.paths.empty());
|
|
}
|
|
|
|
void test_categories_cover_logs_and_captures_but_not_notes() {
|
|
bool notes = false;
|
|
for (auto& c : kCleanupCategories) notes |= std::string(c.folder) == "/notes";
|
|
TEST_ASSERT_FALSE(notes);
|
|
TEST_ASSERT_TRUE(sizeof(kCleanupCategories) / sizeof(kCleanupCategories[0]) >= 3);
|
|
}
|
|
|
|
void test_size_formatting() {
|
|
TEST_ASSERT_EQUAL_STRING("512 B", formatBytes(512).c_str());
|
|
TEST_ASSERT_EQUAL_STRING("1.5 KB", formatBytes(1536).c_str());
|
|
TEST_ASSERT_EQUAL_STRING("340 MB", formatBytes(340ull * 1024 * 1024).c_str());
|
|
TEST_ASSERT_EQUAL_STRING("2.1 GB", formatBytes(2254857830ull).c_str());
|
|
}
|
|
|
|
int main() {
|
|
UNITY_BEGIN();
|
|
RUN_TEST(test_age_cutoffs_select_strictly_older_files);
|
|
RUN_TEST(test_a_year_keeps_everything_younger);
|
|
RUN_TEST(test_undated_files_only_go_with_everything);
|
|
RUN_TEST(test_nothing_to_delete_is_an_empty_plan);
|
|
RUN_TEST(test_notes_are_never_selected);
|
|
RUN_TEST(test_categories_cover_logs_and_captures_but_not_notes);
|
|
RUN_TEST(test_size_formatting);
|
|
return UNITY_END();
|
|
}
|