#include #include #include "event_bus.h" #include "storage_monitor.h" using namespace roro; void setUp() {} void tearDown() {} static const uint64_t GB = 1024ull * 1024 * 1024; static const uint64_t MB = 1024ull * 1024; struct Fixture { EventBus bus{16}; StorageMonitor monitor{bus}; std::vector notifications; std::vector thresholds; Fixture() { bus.subscribe(EventType::Notification, [&](const Event& e) { notifications.push_back(e); }); bus.subscribe(EventType::StorageThreshold, [&](const Event& e) { thresholds.push_back(e); }); } void update(uint64_t used, uint64_t total = 32 * GB) { monitor.update(true, total, used); bus.dispatch(); } }; void test_no_card_means_nothing_can_be_written() { Fixture f; f.monitor.update(false, 0, 0); TEST_ASSERT_FALSE(f.monitor.state().present); TEST_ASSERT_FALSE(f.monitor.state().logsAllowed); TEST_ASSERT_FALSE(f.monitor.state().capturesAllowed); } void test_below_80_percent_everything_is_allowed_quietly() { Fixture f; f.update(16 * GB); TEST_ASSERT_EQUAL(50, f.monitor.state().usedPercent); TEST_ASSERT_TRUE(f.monitor.state().logsAllowed); TEST_ASSERT_TRUE(f.monitor.state().capturesAllowed); TEST_ASSERT_EQUAL(0, f.notifications.size()); } void test_crossing_80_percent_warns_once_per_boot() { Fixture f; f.update(26 * GB); // 81 % TEST_ASSERT_EQUAL(1, f.notifications.size()); f.update(26 * GB); f.update(10 * GB); // cleaned up f.update(27 * GB); // over again, same boot TEST_ASSERT_EQUAL(1, f.notifications.size()); } void test_warning_is_a_warning_level_notification() { Fixture f; f.update(26 * GB); TEST_ASSERT_EQUAL(static_cast(NotificationLevel::Warning), f.notifications[0].a); } void test_at_90_percent_logs_stop_but_captures_continue() { Fixture f; f.update(29 * GB); // 90.6 % TEST_ASSERT_FALSE(f.monitor.state().logsAllowed); TEST_ASSERT_TRUE(f.monitor.state().capturesAllowed); } void test_logs_resume_after_clean_up_below_90() { Fixture f; f.update(29 * GB); f.update(20 * GB); TEST_ASSERT_TRUE(f.monitor.state().logsAllowed); } void test_captures_stop_when_card_is_full() { Fixture f; f.update(32 * GB - MB); // less than the 2 MiB reserve left TEST_ASSERT_FALSE(f.monitor.state().capturesAllowed); } void test_threshold_event_only_when_level_changes() { Fixture f; f.update(10 * GB); // level 0, initial f.update(26 * GB); // 80 f.update(26 * GB); // still 80 f.update(29 * GB); // 90 f.update(32 * GB); // full TEST_ASSERT_EQUAL(3, f.thresholds.size()); TEST_ASSERT_EQUAL(80, f.thresholds[0].b); TEST_ASSERT_EQUAL(90, f.thresholds[1].b); TEST_ASSERT_EQUAL(100, f.thresholds[2].b); } int main() { UNITY_BEGIN(); RUN_TEST(test_no_card_means_nothing_can_be_written); RUN_TEST(test_below_80_percent_everything_is_allowed_quietly); RUN_TEST(test_crossing_80_percent_warns_once_per_boot); RUN_TEST(test_warning_is_a_warning_level_notification); RUN_TEST(test_at_90_percent_logs_stop_but_captures_continue); RUN_TEST(test_logs_resume_after_clean_up_below_90); RUN_TEST(test_captures_stop_when_card_is_full); RUN_TEST(test_threshold_event_only_when_level_changes); return UNITY_END(); }