diff --git a/docs/design/snitch.md b/docs/design/snitch.md index e0d8cb3be8..628dc2025d 100644 --- a/docs/design/snitch.md +++ b/docs/design/snitch.md @@ -22,14 +22,14 @@ The alarm system is exposed through the `com.skaginn3x.Alarm` interface. RegisterAlarm (s: tfc_id, i: alarm_level, b: latching) -> i: alarm_id Note errors can only be latched # ListAlarms returns boolean true in_locale if translation exists otherwise english ListAlarms () -> s -> json of: std::vector ; }> - # Note active = -1 for all, alarm_level = -1 for all a max size of 100 alarms will be sent at a time - ListActivations (s: locale, i: start_count, i: count, i: alarm_level, i: active, x: startunixTimestamp, x: endUnixTimestamp) -> s -> json of: struct { string description; string details; bool latching; enum alarm_level; bool active; std::uint64_t millisec_from_epoch; }; + # Note for state = -1 for all, alarm_level = -1 for all a max size of 100 alarms will be sent at a time + ListActivations (s: locale, i: start_count, i: count, i: alarm_level, i: state, x: startunixTimestamp, x: endUnixTimestamp) -> s -> json of: struct { string description; string details; bool latching; enum alarm_level; state_e state; std::uint64_t millisec_from_epoch; }; SetAlarm(i: alarm_id, as: variables) ResetAlarm(i: alarm_id) TryReset(i: alarm_id) # Transmits a signal to the alarm to reset itself TryResetAll() # Transmits a signal to all alarms to reset themselfs ### Signals - AlarmActivationChanged(i: alarm_id, b: current_activation) + AlarmChanged(i: alarm_id, n: state) TryReset(i: alarm_id) TryResetAll() ### Properties diff --git a/exes/themis/inc/alarm_database.hpp b/exes/themis/inc/alarm_database.hpp index a6a8c48320..b567c628fd 100644 --- a/exes/themis/inc/alarm_database.hpp +++ b/exes/themis/inc/alarm_database.hpp @@ -114,20 +114,14 @@ CREATE TABLE IF NOT EXISTS AlarmVariables( db_ << "BEGIN;"; db_ << fmt::format( "INSERT INTO Alarms(tfc_id, sha1sum, alarm_level, alarm_latching, registered_at) VALUES('{}','{}',{}, {}, {}) ON " - "CONFLICT (tfc_id, sha1sum) DO UPDATE SET registered_at={};", + "CONFLICT (tfc_id, sha1sum) DO UPDATE SET registered_at={} RETURNING alarm_id;", tfc_id, sha1_ascii, std::to_underlying(alarm_level), latching ? 1 : 0, ms_count_registered_at, - ms_count_registered_at); - auto insert_id = db_.last_insert_rowid(); - if (insert_id < 0) { - throw dbus_error("Failed to insert alarm into database"); - } - alarm_id = static_cast(insert_id); + ms_count_registered_at) >> + [&](snitch::api::alarm_id_t id) { alarm_id = id; }; add_alarm_translation(alarm_id, "en", description, details); // Reset the alarm if high on register - if (is_alarm_active(alarm_id)) { - reset_alarm(alarm_id); - } + [[maybe_unused]] bool was_reset = reset_alarm(alarm_id); db_ << "COMMIT;"; } catch (std::exception& e) { // Rollback the transaction and rethrow @@ -244,7 +238,7 @@ ON Alarms.sha1sum = AlarmTranslations.sha1sum; std::uint64_t activation_id; try { db_ << fmt::format("INSERT INTO AlarmActivations(alarm_id, activation_time, activation_level) VALUES({},{},{})", - alarm_id, milliseconds_since_epoch(tp), std::to_underlying(tfc::snitch::api::active_e::active)); + alarm_id, milliseconds_since_epoch(tp), std::to_underlying(tfc::snitch::api::state_e::active)); activation_id = static_cast(db_.last_insert_rowid()); for (auto& [key, value] : variables) { @@ -258,15 +252,22 @@ ON Alarms.sha1sum = AlarmTranslations.sha1sum; db_ << "COMMIT;"; return activation_id; } - auto reset_alarm(snitch::api::alarm_id_t activation_id, std::optional tp = {}) -> void { + /** + * @brief Reset an alarm in the database + * @param activation_id the activation_id of the alarm to reset + * @param tp an optional timepoint + * @return true if the alarm was reset + */ + [[nodiscard]] auto reset_alarm(snitch::api::alarm_id_t activation_id, std::optional tp = {}) + -> bool { if (!is_activation_high(activation_id)) { - throw dbus_error("Cannot reset an inactive activation"); + return false; } db_ << fmt::format("UPDATE AlarmActivations SET activation_level = {}, reset_time = {} WHERE activation_id = {};", - std::to_underlying(tfc::snitch::api::active_e::inactive), milliseconds_since_epoch(tp), - activation_id); + std::to_underlying(tfc::snitch::api::state_e::inactive), milliseconds_since_epoch(tp), activation_id); + return true; } - auto set_activation_status(snitch::api::alarm_id_t activation_id, tfc::snitch::api::active_e activation) -> void { + auto set_activation_status(snitch::api::alarm_id_t activation_id, tfc::snitch::api::state_e activation) -> void { if (!is_activation_high(activation_id)) { throw dbus_error("Cannot reset an inactive activation"); } @@ -277,7 +278,7 @@ ON Alarms.sha1sum = AlarmTranslations.sha1sum; auto get_activation_id_for_active_alarm(snitch::api::alarm_id_t alarm_id) -> std::optional { std::optional activation_id = std::nullopt; db_ << fmt::format("SELECT activation_id FROM AlarmActivations WHERE alarm_id = {} AND activation_level = {};", alarm_id, - std::to_underlying(tfc::snitch::api::active_e::active)) >> + std::to_underlying(tfc::snitch::api::state_e::active)) >> [&](std::uint64_t id) { activation_id = id; }; return activation_id; } @@ -286,7 +287,7 @@ ON Alarms.sha1sum = AlarmTranslations.sha1sum; std::uint64_t start_count, std::uint64_t count, tfc::snitch::level_e level, - tfc::snitch::api::active_e active, + tfc::snitch::api::state_e active, std::optional start, std::optional end) -> std::vector { @@ -314,7 +315,7 @@ WHERE activation_time >= {} AND activation_time <= {})", if (level != tfc::snitch::level_e::all) { populated_query += fmt::format(" AND alarm_level = {}", std::to_underlying(level)); } - if (active != tfc::snitch::api::active_e::all) { + if (active != tfc::snitch::api::state_e::all) { populated_query += fmt::format(" AND activation_level = {}", std::to_underlying(active)); } populated_query += fmt::format(" LIMIT {} OFFSET {};", count, start_count); @@ -323,7 +324,7 @@ WHERE activation_time >= {} AND activation_time <= {})", db_ << populated_query >> [&](snitch::api::activation_id_t activation_id, snitch::api::alarm_id_t alarm_id, std::int64_t activation_time, std::optional reset_time, - std::underlying_type_t activation_level, + std::underlying_type_t activation_level, std::optional primary_details, std::optional primary_description, std::optional backup_details, std::optional backup_description, bool alarm_latching, std::underlying_type_t alarm_level) { @@ -338,7 +339,7 @@ WHERE activation_time >= {} AND activation_time <= {})", final_reset_time = timepoint_from_milliseconds(reset_time.value()); } activations.emplace_back(alarm_id, activation_id, description, details, - static_cast(activation_level), + static_cast(activation_level), static_cast(alarm_level), alarm_latching, timepoint_from_milliseconds(activation_time), final_reset_time, in_locale); }; diff --git a/exes/themis/inc/dbus_interface.hpp b/exes/themis/inc/dbus_interface.hpp index 8738020619..d3e7c0b55a 100644 --- a/exes/themis/inc/dbus_interface.hpp +++ b/exes/themis/inc/dbus_interface.hpp @@ -20,11 +20,15 @@ using namespace tfc::snitch::api::dbus; using std::string_view_literals::operator""sv; using dbus_error = tfc::dbus::exception::runtime; +using tfc::snitch::level_e; +using tfc::snitch::api::alarm_id_t; +using tfc::snitch::api::state_e; + class interface { public: explicit interface(std::shared_ptr connection, tfc::themis::alarm_database& database) - : database_(database) { - connection_ = connection; + : connection_(std::move(connection)), database_(database) { + // Initialize the object server and request the service name object_server_ = std::make_unique(connection_); connection_->request_name(service_name.data()); interface_ = object_server_->add_unique_interface(object_path.data(), interface_name.data()); @@ -48,16 +52,26 @@ class interface { auto alarm_id = database.register_alarm_en(tfc_id, description, details, latching, static_cast(alarm_level)); dbus_ids_to_monitor_[sender].push_back(alarm_id); + notify_alarm_state(alarm_id, state_e::inactive); return alarm_id; }); interface_->register_method( std::string(methods::set_alarm), [&](snitch::api::alarm_id_t alarm_id, const std::unordered_map& args) -> std::uint64_t { - return database.set_alarm(alarm_id, args); + auto activation_id = database.set_alarm(alarm_id, args); + notify_alarm_state(alarm_id, state_e::active); + return activation_id; }); - interface_->register_method(std::string(methods::reset_alarm), - [&](snitch::api::alarm_id_t alarm_id) -> void { database.reset_alarm(alarm_id); }); + interface_->register_method(std::string(methods::reset_alarm), [&](snitch::api::alarm_id_t alarm_id) -> void { + if (!database.reset_alarm(alarm_id)) { + throw dbus_error("Cannot reset an inactive activation"); + } else { + // Notify the change in alarm status of this alarm + notify_alarm_state(alarm_id, state_e::inactive); + } + }); + interface_->register_method(std::string(methods::try_reset), [&](snitch::api::alarm_id_t alarm_id) -> void { if (database.is_alarm_active(alarm_id)) { auto message = interface_->new_signal(signals::try_reset.data()); @@ -67,6 +81,7 @@ class interface { throw dbus_error("Alarm is not active"); } }); + interface_->register_method(std::string(methods::try_reset_all), [&]() -> void { if (database.is_some_alarm_active()) { auto message = interface_->new_signal(signals::try_reset_all.data()); @@ -75,17 +90,16 @@ class interface { throw dbus_error("No alarm is active"); } }); - using tfc::snitch::level_e; - using tfc::snitch::api::active_e; + interface_->register_method(std::string(methods::list_activations), [&](const std::string& locale, std::uint64_t start_count, std::uint64_t count, - std::underlying_type_t alarm_level, std::underlying_type_t active, + std::underlying_type_t alarm_level, std::underlying_type_t active, int64_t start, int64_t end) -> std::string { auto cstart = tfc::themis::alarm_database::timepoint_from_milliseconds(start); auto cend = tfc::themis::alarm_database::timepoint_from_milliseconds(end); auto const activations_str{ glz::write_json(database.list_activations( locale, start_count, count, static_cast(alarm_level), - static_cast(active), cstart, cend)) }; + static_cast(active), cstart, cend)) }; if (!activations_str) { throw dbus_error("Failed to serialize activations"); } @@ -93,7 +107,8 @@ class interface { }); // Signal alarm_id, current_activation, ack_status - interface_->register_signal>(std::string(signals::alarm_activation_changed)); + interface_->register_signal>>( + std::string(signals::alarm_activation_changed)); interface_->register_signal(std::string(signals::try_reset)); interface_->register_signal(std::string(signals::try_reset_all)); name_lost_match_ = std::make_unique(*connection_, match_rule_.data(), @@ -108,6 +123,12 @@ class interface { static constexpr std::string_view name_owner_changed_ = "NameOwnerChanged"sv; static constexpr std::string_view match_rule_ = tfc::dbus::match::rules:: make_match_rule(); + + auto notify_alarm_state(alarm_id_t alarm_id, state_e state) -> void { + sdbusplus::message_t alarm_change_message = interface_->new_signal(signals::alarm_activation_changed.data()); + alarm_change_message.append(std::tuple(alarm_id, std::to_underlying(state))); + alarm_change_message.signal_send(); + } auto match_callback(sdbusplus::message_t& msg) -> void { std::tuple container; sdbusplus::utility::read_into_tuple(container, msg); @@ -121,7 +142,8 @@ class interface { for (auto& alarm_id : alarm_vec) { auto activation = database_.get_activation_id_for_active_alarm(alarm_id); if (activation.has_value()) { - database_.set_activation_status(activation.value(), tfc::snitch::api::active_e::unknown); + database_.set_activation_status(activation.value(), tfc::snitch::api::state_e::unknown); + notify_alarm_state(alarm_id, state_e::unknown); } } } diff --git a/exes/themis/tests/themis_database_test.cpp b/exes/themis/tests/themis_database_test.cpp index 5a29419792..027e16999a 100644 --- a/exes/themis/tests/themis_database_test.cpp +++ b/exes/themis/tests/themis_database_test.cpp @@ -68,25 +68,25 @@ auto main(int argc, char** argv) -> int { // Verify there is no sql logic error auto activations = alarm_db.list_activations( - "es", 0, 10, tfc::snitch::level_e::unknown, tfc::snitch::api::active_e::all, + "es", 0, 10, tfc::snitch::level_e::unknown, tfc::snitch::api::state_e::all, tfc::themis::alarm_database::timepoint_from_milliseconds(0), tfc::themis::alarm_database::timepoint_from_milliseconds(std::numeric_limits::max())); expect(activations.size() == 0); activations = alarm_db.list_activations( - "es", 0, 10, tfc::snitch::level_e::unknown, tfc::snitch::api::active_e::active, + "es", 0, 10, tfc::snitch::level_e::unknown, tfc::snitch::api::state_e::active, tfc::themis::alarm_database::timepoint_from_milliseconds(0), tfc::themis::alarm_database::timepoint_from_milliseconds(std::numeric_limits::max())); expect(activations.size() == 0); activations = alarm_db.list_activations( - "es", 0, 10, tfc::snitch::level_e::info, tfc::snitch::api::active_e::active, + "es", 0, 10, tfc::snitch::level_e::info, tfc::snitch::api::state_e::active, tfc::themis::alarm_database::timepoint_from_milliseconds(0), tfc::themis::alarm_database::timepoint_from_milliseconds(std::numeric_limits::max())); expect(activations.size() == 0); activations = alarm_db.list_activations( - "es", 0, 10, tfc::snitch::level_e::info, tfc::snitch::api::active_e::all, + "es", 0, 10, tfc::snitch::level_e::info, tfc::snitch::api::state_e::all, tfc::themis::alarm_database::timepoint_from_milliseconds(0), tfc::themis::alarm_database::timepoint_from_milliseconds(std::numeric_limits::max())); expect(activations.size() == 0); @@ -94,24 +94,24 @@ auto main(int argc, char** argv) -> int { // Add some activations for (int i = 0; i < 10; i++) { auto activation_id = alarm_db.set_alarm(insert_id, {}); - alarm_db.reset_alarm(activation_id); + expect(alarm_db.reset_alarm(activation_id)); } // Insert an invalid activation expect(throws([&] { [[maybe_unused]] auto _ = alarm_db.set_alarm(999, {}); })); // Verify our inserts activations = alarm_db.list_activations( - "es", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::active_e::all, + "es", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::state_e::all, tfc::themis::alarm_database::timepoint_from_milliseconds(0), tfc::themis::alarm_database::timepoint_from_milliseconds(std::numeric_limits::max())); expect(activations.size() == 10) << activations.size(); activations = alarm_db.list_activations( - "es", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::active_e::active, + "es", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::state_e::active, tfc::themis::alarm_database::timepoint_from_milliseconds(0), tfc::themis::alarm_database::timepoint_from_milliseconds(std::numeric_limits::max())); expect(activations.size() == 0) << activations.size(); activations = alarm_db.list_activations( - "es", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::active_e::inactive, + "es", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::state_e::inactive, tfc::themis::alarm_database::timepoint_from_milliseconds(0), tfc::themis::alarm_database::timepoint_from_milliseconds(std::numeric_limits::max())); expect(activations.size() == 10) << activations.size(); @@ -122,7 +122,7 @@ auto main(int argc, char** argv) -> int { alarm_db.add_alarm_translation(alarm_db.list_alarms().at(0).alarm_id, "es", "spanish description", "spanish details"); [[maybe_unused]] auto _ = alarm_db.set_alarm(insert_id, {}); auto activations = alarm_db.list_activations( - "is", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::active_e::active, + "is", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::state_e::active, tfc::themis::alarm_database::timepoint_from_milliseconds(0), tfc::themis::alarm_database::timepoint_from_milliseconds(std::numeric_limits::max())); expect(activations.size() == 1); @@ -131,7 +131,7 @@ auto main(int argc, char** argv) -> int { expect(activations.at(0).in_requested_locale == false); activations = alarm_db.list_activations( - "es", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::active_e::active, + "es", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::state_e::active, tfc::themis::alarm_database::timepoint_from_milliseconds(0), tfc::themis::alarm_database::timepoint_from_milliseconds(std::numeric_limits::max())); expect(activations.size() == 1); @@ -146,7 +146,7 @@ auto main(int argc, char** argv) -> int { expect(alarm_db.list_alarms().size() == 1); [[maybe_unused]] auto _ = alarm_db.set_alarm(var_alarm_id, { { "var", "10.0" } }); auto activations = alarm_db.list_activations( - "en", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::active_e::active, + "en", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::state_e::active, tfc::themis::alarm_database::timepoint_from_milliseconds(0), tfc::themis::alarm_database::timepoint_from_milliseconds(std::numeric_limits::max())); expect(activations.size() == 1); @@ -161,7 +161,7 @@ auto main(int argc, char** argv) -> int { "spanish details {var} {var2} {var3}"); _ = alarm_db.set_alarm(var_alarm_id, { { "var", "10.0" }, { "var2", "20.0" }, { "var3", "30.0" } }); activations = alarm_db.list_activations( - "en", 0, 10000, tfc::snitch::level_e::warning, tfc::snitch::api::active_e::active, + "en", 0, 10000, tfc::snitch::level_e::warning, tfc::snitch::api::state_e::active, tfc::themis::alarm_database::timepoint_from_milliseconds(0), tfc::themis::alarm_database::timepoint_from_milliseconds(std::numeric_limits::max())); expect(activations.size() == 1); @@ -169,7 +169,7 @@ auto main(int argc, char** argv) -> int { expect(activations.at(0).description == "description 10.0 20.0 30.0") << activations.at(0).description; expect(activations.at(0).details == "details 10.0 20.0 30.0") << activations.at(0).details; activations = alarm_db.list_activations( - "es", 0, 10000, tfc::snitch::level_e::warning, tfc::snitch::api::active_e::active, + "es", 0, 10000, tfc::snitch::level_e::warning, tfc::snitch::api::state_e::active, tfc::themis::alarm_database::timepoint_from_milliseconds(0), tfc::themis::alarm_database::timepoint_from_milliseconds(std::numeric_limits::max())); expect(activations.size() == 1); @@ -177,7 +177,7 @@ auto main(int argc, char** argv) -> int { expect(activations.at(0).description == "spanish description 10.0 20.0 30.0") << activations.at(0).description; expect(activations.at(0).details == "spanish details 10.0 20.0 30.0") << activations.at(0).details; activations = alarm_db.list_activations( - "is", 0, 10000, tfc::snitch::level_e::warning, tfc::snitch::api::active_e::active, + "is", 0, 10000, tfc::snitch::level_e::warning, tfc::snitch::api::state_e::active, tfc::themis::alarm_database::timepoint_from_milliseconds(0), tfc::themis::alarm_database::timepoint_from_milliseconds(std::numeric_limits::max())); expect(activations.size() == 1); @@ -206,14 +206,14 @@ auto main(int argc, char** argv) -> int { time = alarm_database::timepoint_from_milliseconds(1); auto activation_id = db.set_alarm(alarm_id, {}, time); auto activations = - db.list_activations("en", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::active_e::all, min_time, max_time); + db.list_activations("en", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::state_e::all, min_time, max_time); expect(activations.size() == 1); expect(activations.at(0).set_timestamp == time); expect(!activations.at(0).reset_timestamp.has_value()); auto reset_time = alarm_database::timepoint_from_milliseconds(2); - db.reset_alarm(activation_id, reset_time); + expect(db.reset_alarm(activation_id, reset_time)); activations = - db.list_activations("en", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::active_e::all, min_time, max_time); + db.list_activations("en", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::state_e::all, min_time, max_time); expect(!db.is_alarm_active(alarm_id)); expect(activations.size() == 1); expect(activations.at(0).set_timestamp == time); @@ -225,8 +225,8 @@ auto main(int argc, char** argv) -> int { auto alarm_id = db.register_alarm_en("tfc_id", "description", "details", false, tfc::snitch::level_e::info); auto activation_id = db.set_alarm(alarm_id, {}); expect(throws([&] { [[maybe_unused]] auto _ = db.set_alarm(alarm_id, {}); })); - db.reset_alarm(activation_id); - expect(throws([&] { db.reset_alarm(activation_id, {}); })); + expect(db.reset_alarm(activation_id)); + expect(!db.reset_alarm(activation_id)); }; "Verify alarm id when replacing reinstantiating alarms"_test = [] { tfc::themis::alarm_database db(true); @@ -260,4 +260,35 @@ auto main(int argc, char** argv) -> int { expect(alarm_id == new_alarm_id); expect(!db.is_alarm_active(alarm_id)); }; + "empty alarm list"_test = [] { + auto db = tfc::themis::alarm_database(true); + auto alarms = db.list_alarms(); + expect(alarms.size() == 0); + }; + "Second time an alarm is registered it should get the correct insert id"_test = [] { + auto db = tfc::themis::alarm_database(true); + auto alarm_id = db.register_alarm_en("tfc_id", "description", "details", false, tfc::snitch::level_e::info); + auto alarm_id2 = db.register_alarm_en("tfc_id", "description", "details", false, tfc::snitch::level_e::info); + auto alarms = db.list_alarms(); + expect(alarm_id == alarm_id2); + expect(alarms.size() == 1); + expect(alarms.at(0).alarm_id == alarm_id); + }; + + "Second time an alarm is registered it should get the correct insert id with a different alarm registered in the middle"_test = + [] { + auto db = tfc::themis::alarm_database(true); + auto alarm_id_first_time = + db.register_alarm_en("tfc_id", "description", "details", false, tfc::snitch::level_e::info); + auto alarms = db.list_alarms(); + expect(alarms.size() == 1); + auto other_alarm = db.register_alarm_en("tfc_other", "description", "details", false, tfc::snitch::level_e::info); + auto alarm_id_second_time = + db.register_alarm_en("tfc_id", "description", "details", false, tfc::snitch::level_e::info); + alarms = db.list_alarms(); + expect(alarm_id_first_time == alarm_id_second_time); + expect(alarm_id_first_time != other_alarm); + expect(alarms.size() == 2); + expect(alarms.at(0).alarm_id == alarm_id_first_time); + }; } diff --git a/exes/themis/tests/themis_integration_test.cpp b/exes/themis/tests/themis_integration_test.cpp index 9cb8c49072..56f4dfd3e2 100644 --- a/exes/themis/tests/themis_integration_test.cpp +++ b/exes/themis/tests/themis_integration_test.cpp @@ -108,7 +108,7 @@ int main(int argc, char** argv) { expect(t.ran[5]); t.client.list_activations( - "en", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::active_e::active, + "en", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::state_e::active, tfc::themis::alarm_database::timepoint_from_milliseconds(0), tfc::themis::alarm_database::timepoint_from_milliseconds(std::numeric_limits::max()), [&](const std::error_code& err, std::vector act) { @@ -127,7 +127,7 @@ int main(int argc, char** argv) { t.ctx.run_for(2ms); expect(t.ran[2]); t.client.list_activations( - "en", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::active_e::active, + "en", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::state_e::active, tfc::themis::alarm_database::timepoint_from_milliseconds(0), tfc::themis::alarm_database::timepoint_from_milliseconds(std::numeric_limits::max()), [&](const std::error_code& err, std::vector act) { @@ -136,7 +136,7 @@ int main(int argc, char** argv) { t.ran[3] = true; }); t.client.list_activations( - "en", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::active_e::inactive, + "en", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::state_e::inactive, tfc::themis::alarm_database::timepoint_from_milliseconds(0), tfc::themis::alarm_database::timepoint_from_milliseconds(std::numeric_limits::max()), [&](const std::error_code& err, std::vector act) { @@ -252,7 +252,7 @@ int main(int argc, char** argv) { t.ran[0] = true; t.client.list_activations( - "en", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::active_e::active, + "en", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::state_e::active, tfc::themis::alarm_database::timepoint_from_milliseconds(0), tfc::themis::alarm_database::timepoint_from_milliseconds(std::numeric_limits::max()), [&](auto list_err, std::vector const& act) { @@ -300,7 +300,7 @@ int main(int argc, char** argv) { client.ctx.run_for(2ms); expect(client.ran[1]); client.client.list_activations( - "en", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::active_e::active, + "en", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::state_e::active, tfc::themis::alarm_database::timepoint_from_milliseconds(0), tfc::themis::alarm_database::timepoint_from_milliseconds(std::numeric_limits::max()), [&](const std::error_code& err, std::vector act) { @@ -338,7 +338,7 @@ int main(int argc, char** argv) { fmt::println(stderr, "Client has been killed"); test_setup_c new_client; new_client.client.list_activations( - "en", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::active_e::unknown, + "en", 0, 10000, tfc::snitch::level_e::info, tfc::snitch::api::state_e::unknown, tfc::themis::alarm_database::timepoint_from_milliseconds(0), tfc::themis::alarm_database::timepoint_from_milliseconds(std::numeric_limits::max()), [&](const std::error_code& err, std::vector act) { @@ -348,11 +348,28 @@ int main(int argc, char** argv) { expect(alarm.description == "desc"); expect(alarm.details == "details"); expect(alarm.lvl == tfc::snitch::level_e::info); - expect(alarm.active == tfc::snitch::api::active_e::unknown); + expect(alarm.active == tfc::snitch::api::state_e::unknown); new_client.ran[0] = true; }); new_client.ctx.run_for(2ms); expect(new_client.ran[0]); }; + + "When no alarm has been registered an empty list shall be returned"_test = [] { + test_setup t; + t.client.list_alarms([&](const std::error_code& err, std::vector alarms) { + expect(!err) << err.message(); + expect(alarms.size() == 0); + t.ran[0] = true; + }); + t.ctx.run_for(2ms); + expect(t.ran[0]); + }; + "When no alarm has been registered an empty list shall be returned no integration"_test = [] { + test_setup_s s; + auto vec = s.db.list_alarms(); + auto json = glz::write_json(vec); + expect(json == "[]") << json.value_or(""); + }; return 0; } diff --git a/libs/snitch/inc/public/tfc/snitch/common.hpp b/libs/snitch/inc/public/tfc/snitch/common.hpp index f371e6a132..d5158e26df 100644 --- a/libs/snitch/inc/public/tfc/snitch/common.hpp +++ b/libs/snitch/inc/public/tfc/snitch/common.hpp @@ -16,7 +16,7 @@ using alarm_id_t = std::uint64_t; using activation_id_t = alarm_id_t; // std::int8_t is not in the dbus spec, so we use std::int16_t instead -enum struct active_e : std::int16_t { all = -1, inactive = 0, active = 1, unknown = 32767 }; +enum struct state_e : std::int16_t { all = -1, inactive = 0, active = 1, unknown = 32767 }; struct alarm { alarm_id_t alarm_id; @@ -38,7 +38,7 @@ struct activation { std::uint64_t activation_id; std::string description; std::string details; - active_e active{ active_e::unknown }; + state_e active{ state_e::unknown }; level_e lvl{ level_e::unknown }; bool latching{}; time_point set_timestamp; diff --git a/libs/snitch/inc/public/tfc/snitch/details/dbus_client.hpp b/libs/snitch/inc/public/tfc/snitch/details/dbus_client.hpp index 5e9f12a262..e8a12cc1d9 100644 --- a/libs/snitch/inc/public/tfc/snitch/details/dbus_client.hpp +++ b/libs/snitch/inc/public/tfc/snitch/details/dbus_client.hpp @@ -27,7 +27,7 @@ class dbus_client { std::uint64_t start_count, std::uint64_t count, level_e, - api::active_e, + api::state_e, api::time_point start, api::time_point end, std::function)> token) -> void; diff --git a/libs/snitch/src/dbus_client.cpp b/libs/snitch/src/dbus_client.cpp index 06ce019729..dc280dc041 100644 --- a/libs/snitch/src/dbus_client.cpp +++ b/libs/snitch/src/dbus_client.cpp @@ -69,7 +69,7 @@ auto dbus_client::list_activations(std::string_view locale, std::uint64_t start_count, std::uint64_t count, level_e lvl, - api::active_e active, + api::state_e active, api::time_point start, api::time_point end, std::function)> token) -> void {