blob: da880df655a5240cc6826c56e47882edab6f7623 [file] [log] [blame]
Tomáš Pecka6a2334b2022-07-12 13:57:54 +02001/*
2 * Copyright (C) 2020 - 2022 CESNET, https://photonics.cesnet.cz/
3 *
4 * Written by Tomáš Pecka <tomas.pecka@cesnet.cz>
5 *
6 */
7
8#include "trompeloeil_doctest.h"
9#include <sysrepo-cpp/Connection.hpp>
10#include <sysrepo-cpp/Enum.hpp>
11#include <sysrepo-cpp/Subscription.hpp>
12#include <thread>
13#include "dbus-helpers/dbus_systemd_server.h"
Tomáš Pecka1d2b95c2023-05-11 16:01:46 +020014#include "health/SystemdUnits.h"
Tomáš Pecka8e5a2d32022-08-22 17:48:58 +020015#include "pretty_printers.h"
Tomáš Pecka6a2334b2022-07-12 13:57:54 +020016#include "test_log_setup.h"
Tomáš Peckab80a7e32024-01-24 15:04:14 +010017#include "tests/sysrepo-helpers/alarms.h"
Tomáš Peckac164ca62024-01-24 13:38:03 +010018#include "tests/sysrepo-helpers/common.h"
Tomáš Pecka6a2334b2022-07-12 13:57:54 +020019#include "utils/log-init.h"
20#include "utils/log.h"
21
22using namespace std::chrono_literals;
23
Tomáš Pecka9bd61272024-01-31 15:08:13 +010024#define VEC(...) (std::vector<std::string>{__VA_ARGS__})
Jan Kundrátc1511512024-01-15 13:47:28 +010025#define REQUIRE_NEW_ALARM_INVENTORY_UNIT(UNIT) \
Tomáš Pecka4a0c6ea2024-01-31 15:14:55 +010026 REQUIRE_NEW_ALARM_INVENTORY_RESOURCES(alarmsWatcher, (std::vector<std::string>{"velia-alarms:systemd-unit-failure"}), std::vector<std::string>{UNIT})
Jan Kundrátc1511512024-01-15 13:47:28 +010027
28#define REQUIRE_ALARM_RPC(UNIT, SEVERITY, TEXT) \
Tomáš Pecka4163c0c2024-01-31 13:21:03 +010029 REQUIRE_NEW_ALARM(alarmsWatcher, "velia-alarms:systemd-unit-failure", UNIT, SEVERITY, TEXT)
Tomáš Pecka6a2334b2022-07-12 13:57:54 +020030
Tomáš Pecka6a2334b2022-07-12 13:57:54 +020031TEST_CASE("systemd unit state monitoring (alarms)")
32{
33 TEST_INIT_LOGS;
34 TEST_SYSREPO_INIT;
Tomáš Pecka6fcb7592024-01-24 14:42:14 +010035 TEST_SYSREPO_INIT_CLIENT;
Tomáš Pecka6a2334b2022-07-12 13:57:54 +020036 trompeloeil::sequence seq1;
37
38 // Create and setup separate connections for both client and server to simulate real-world server-client architecture.
39 // Also this doesn't work one a single dbus connection.
40 auto clientConnection = sdbus::createSessionBusConnection();
41 auto serverConnection = sdbus::createSessionBusConnection();
42 clientConnection->enterEventLoopAsync();
43 serverConnection->enterEventLoopAsync();
44
45 auto server = DbusSystemdServer(*serverConnection);
Tomáš Pecka6a2334b2022-07-12 13:57:54 +020046
Tomáš Peckab80a7e32024-01-24 15:04:14 +010047 client.switchDatastore(sysrepo::Datastore::Operational);
48 AlarmWatcher alarmsWatcher(client);
49
Tomáš Pecka9bd61272024-01-31 15:08:13 +010050 REQUIRE_NEW_ALARM_INVENTORY_ENTRIES(alarmsWatcher,
51 (std::vector<velia::alarms::AlarmInventoryEntry>{{
52 "velia-alarms:systemd-unit-failure",
53 "The systemd service is considered in failed state.",
54 VEC("unit1.service", "unit2.service", "unit3.service"),
55 VEC("critical"),
56 }}));
Tomáš Peckab80a7e32024-01-24 15:04:14 +010057
Tomáš Pecka6fcb7592024-01-24 14:42:14 +010058 REQUIRE_ALARM_RPC("unit1.service", "cleared", "systemd unit state: (active, running)");
Tomáš Pecka6a2334b2022-07-12 13:57:54 +020059 server.createUnit(*serverConnection, "unit1.service", "/org/freedesktop/systemd1/unit/unit1", "active", "running");
Tomáš Peckab80a7e32024-01-24 15:04:14 +010060
Tomáš Pecka6fcb7592024-01-24 14:42:14 +010061 REQUIRE_ALARM_RPC("unit2.service", "critical", "systemd unit state: (activating, auto-restart)");
Tomáš Pecka6a2334b2022-07-12 13:57:54 +020062 server.createUnit(*serverConnection, "unit2.service", "/org/freedesktop/systemd1/unit/unit2", "activating", "auto-restart");
Tomáš Peckab80a7e32024-01-24 15:04:14 +010063
Tomáš Pecka6fcb7592024-01-24 14:42:14 +010064 REQUIRE_ALARM_RPC("unit3.service", "critical", "systemd unit state: (failed, failed)");
Tomáš Pecka6a2334b2022-07-12 13:57:54 +020065 server.createUnit(*serverConnection, "unit3.service", "/org/freedesktop/systemd1/unit/unit3", "failed", "failed");
66
67 auto systemdAlarms = std::make_shared<velia::health::SystemdUnits>(srSess, *clientConnection, serverConnection->getUniqueName(), "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "org.freedesktop.systemd1.Unit");
68
Tomáš Pecka6fcb7592024-01-24 14:42:14 +010069 REQUIRE_ALARM_RPC("unit2.service", "cleared", "systemd unit state: (active, running)");
70 REQUIRE_ALARM_RPC("unit3.service", "cleared", "systemd unit state: (active, running)");
Tomáš Peckab80a7e32024-01-24 15:04:14 +010071 REQUIRE_NEW_ALARM_INVENTORY_UNIT("unit4.service");
Tomáš Pecka6fcb7592024-01-24 14:42:14 +010072 REQUIRE_ALARM_RPC("unit4.service", "critical", "systemd unit state: (failed, failed)");
73 REQUIRE_ALARM_RPC("unit3.service", "critical", "systemd unit state: (activating, auto-restart)");
74 REQUIRE_ALARM_RPC("unit3.service", "cleared", "systemd unit state: (active, running)");
75 REQUIRE_ALARM_RPC("unit3.service", "critical", "systemd unit state: (failed, failed)");
76 REQUIRE_ALARM_RPC("unit3.service", "critical", "systemd unit state: (activating, auto-restart)");
77 REQUIRE_ALARM_RPC("unit3.service", "cleared", "systemd unit state: (active, running)");
78 REQUIRE_ALARM_RPC("unit4.service", "cleared", "systemd unit state: (active, running)");
Tomáš Pecka6a2334b2022-07-12 13:57:54 +020079
80 std::thread systemdSimulator([&] {
81 server.changeUnitState("/org/freedesktop/systemd1/unit/unit2", "active", "running");
82 server.changeUnitState("/org/freedesktop/systemd1/unit/unit3", "active", "running");
83
84 // In case we obtain a notifications that unit changed state from (X,Y) to (X,Y), do not trigger any events.
85 server.changeUnitState("/org/freedesktop/systemd1/unit/unit3", "active", "running");
86
87 // add new unit with failed/failed, DbusSystemdInput should receive UnitNew signal and monitor this unit too
88 server.createUnit(*serverConnection, "unit4.service", "/org/freedesktop/systemd1/unit/unit4", "failed", "failed");
89
90 // Sleep for a while; the rest of the code might be too fast and we need to be sure that we pick up event for (failed, failed) before the state of unit4 is changed in the DBus server
Tomáš Pecka457016b2023-07-12 15:18:09 +020091 std::this_thread::sleep_for(250ms);
Tomáš Pecka6a2334b2022-07-12 13:57:54 +020092
93 server.changeUnitState("/org/freedesktop/systemd1/unit/unit3", "activating", "auto-restart");
94 server.changeUnitState("/org/freedesktop/systemd1/unit/unit3", "active", "running");
95 server.changeUnitState("/org/freedesktop/systemd1/unit/unit3", "failed", "failed");
96 server.changeUnitState("/org/freedesktop/systemd1/unit/unit3", "activating", "auto-restart");
97 server.changeUnitState("/org/freedesktop/systemd1/unit/unit3", "active", "running");
98
99 server.changeUnitState("/org/freedesktop/systemd1/unit/unit4", "active", "running");
100 });
101
Tomáš Pecka6a2334b2022-07-12 13:57:54 +0200102 systemdSimulator.join();
103 waitForCompletionAndBitMore(seq1);
Tomáš Pecka6a2334b2022-07-12 13:57:54 +0200104}