blob: 6c55b102c88a02bdc943339bea7373f75b326341 [file] [log] [blame]
Tomáš Peckabaf289c2024-01-24 15:12:44 +01001/*
2 * Copyright (C) 2024 CESNET, https://photonics.cesnet.cz/
3 *
4 * Written by Tomáš Pecka <tomas.pecka@cesnet.cz>
5 *
6 */
7
8#pragma once
9
10#include "trompeloeil_doctest.h"
Tomáš Pecka1211fd92024-01-24 15:24:07 +010011#include <optional>
Tomáš Peckabaf289c2024-01-24 15:12:44 +010012#include <sysrepo-cpp/Subscription.hpp>
13#include "sysrepo-helpers/common.h"
14#include "sysrepo-helpers/datastore.h"
15#include "sysrepo-helpers/rpc.h"
16#include "test_log_setup.h"
Tomáš Pecka9bd61272024-01-31 15:08:13 +010017#include "utils/alarms.h"
Tomáš Peckabaf289c2024-01-24 15:12:44 +010018
Tomáš Pecka9bd61272024-01-31 15:08:13 +010019inline ValueChanges constructAlarmInventoryChange(const std::vector<velia::alarms::AlarmInventoryEntry>& entries)
Tomáš Pecka1211fd92024-01-24 15:24:07 +010020{
Tomáš Pecka87844292024-01-30 15:20:21 +010021 ValueChanges ret;
Tomáš Pecka1211fd92024-01-24 15:24:07 +010022
Tomáš Pecka9bd61272024-01-31 15:08:13 +010023 for (const auto& entry : entries) {
24 const std::string prefix = "/ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='" + entry.alarmType + "'][alarm-type-qualifier='']";
Tomáš Peckae66a1932024-01-25 13:43:51 +010025
Tomáš Pecka9bd61272024-01-31 15:08:13 +010026 ret.emplace(prefix + "/alarm-type-id", entry.alarmType);
27 ret.emplace(prefix + "/alarm-type-qualifier", "");
Tomáš Peckae66a1932024-01-25 13:43:51 +010028
Tomáš Pecka9bd61272024-01-31 15:08:13 +010029 ret.emplace(prefix + "/will-clear", entry.willClear ? "true" : "false");
30 ret.emplace(prefix + "/description", entry.description);
Tomáš Pecka1211fd92024-01-24 15:24:07 +010031
Tomáš Pecka9bd61272024-01-31 15:08:13 +010032 size_t i = 1; /* YANG uses 1-based indexing */
33 for (const auto& severity : entry.severities) {
34 ret.emplace(prefix + "/severity-level[" + std::to_string(i++) + "]", severity);
35 }
36
37 i = 1;
38 for (const auto& resource : entry.resources) {
39 ret.emplace(prefix + "/resource[" + std::to_string(i++) + "]", resource);
40 }
Tomáš Pecka1211fd92024-01-24 15:24:07 +010041 }
42
43 return ret;
44}
45
Tomáš Pecka4a0c6ea2024-01-31 15:14:55 +010046inline ValueChanges constructAlarmInventoryResourceChange(const std::vector<std::string>& alarmTypeIds, const std::vector<std::string>& resources) {
Tomáš Pecka52d50462024-01-31 13:37:29 +010047 ValueChanges ret;
48
49 for (const auto& alarmType : alarmTypeIds) {
50 const std::string prefix = "/ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='" + alarmType + "'][alarm-type-qualifier='']";
51
52 size_t i = 1;
53 for (const auto& resource : resources) {
54 ret.emplace(prefix + "/resource[" + std::to_string(i++) + "]", resource);
55 }
56 }
57
58 return ret;
59}
60
Tomáš Peckabaf289c2024-01-24 15:12:44 +010061/** @brief A simple mock implementation of the alarm server */
62struct AlarmWatcher {
63 /** @brief Poor man's /ietf-alarms:alarms/alarm-inventory implementation in C++. */
64 struct AlarmInventory {
Tomáš Pecka4163c0c2024-01-31 13:21:03 +010065 using AlarmType = std::string;
66
Tomáš Pecka1211fd92024-01-24 15:24:07 +010067 struct AllowedResourcesAndSeverities {
68 std::set<std::string> resources;
69 std::set<std::string> severities;
70 };
Tomáš Peckabaf289c2024-01-24 15:12:44 +010071
Tomáš Pecka4163c0c2024-01-31 13:21:03 +010072 std::map<AlarmType, AllowedResourcesAndSeverities> inventory;
73
Tomáš Pecka4a0c6ea2024-01-31 15:14:55 +010074 void add(const std::vector<std::string>& alarmTypeIds, const std::vector<std::string>& resources, const std::vector<std::string>& severities);
Tomáš Pecka9bd61272024-01-31 15:08:13 +010075 void add(const std::vector<velia::alarms::AlarmInventoryEntry>& entries);
Tomáš Pecka4163c0c2024-01-31 13:21:03 +010076 bool contains(const std::string& alarmTypeId, const std::optional<std::string>& resource, const std::optional<std::string>& severity) const;
Tomáš Peckabaf289c2024-01-24 15:12:44 +010077 };
78
79 AlarmInventory alarmInventory;
80 DatastoreWatcher datastoreWatcher;
81 RPCWatcher rpcWatcher;
82
83 AlarmWatcher(sysrepo::Session& session);
84};
85
86// checks if the alarm is contained in AlarmInventory
Tomáš Pecka4163c0c2024-01-31 13:21:03 +010087#define WITH_ALARM_IN_INVENTORY(INV, ALARM_TYPE, RESOURCE, SEVERITY) \
88 LR_WITH(INV.contains(ALARM_TYPE, RESOURCE, SEVERITY))
Tomáš Peckabaf289c2024-01-24 15:12:44 +010089
90// inserts the alarm in AlarmInventory as a side effect
Tomáš Pecka52d50462024-01-31 13:37:29 +010091#define INSERT_INTO_INVENTORY(INV, ALARM_TYPES, RESOURCES, SEVERITIES) \
92 LR_SIDE_EFFECT(INV.add(ALARM_TYPES, RESOURCES, SEVERITIES))
Tomáš Pecka9bd61272024-01-31 15:08:13 +010093#define INSERT_INTO_INVENTORY_MANY(INV, ALARMS) \
94 LR_SIDE_EFFECT(INV.add(ALARMS))
Tomáš Peckabaf289c2024-01-24 15:12:44 +010095
Tomáš Pecka9bd61272024-01-31 15:08:13 +010096#define REQUIRE_NEW_ALARM_INVENTORY_ENTRIES(WATCHER, ALARMS) \
97 REQUIRE_DATASTORE_CHANGE(WATCHER.datastoreWatcher, constructAlarmInventoryChange(ALARMS)) \
98 .INSERT_INTO_INVENTORY_MANY(WATCHER.alarmInventory, ALARMS)
Tomáš Peckabaf289c2024-01-24 15:12:44 +010099
Tomáš Pecka52d50462024-01-31 13:37:29 +0100100#define REQUIRE_NEW_ALARM_INVENTORY_RESOURCES(WATCHER, ALARM_TYPES, RESOURCES) \
101 REQUIRE_DATASTORE_CHANGE(WATCHER.datastoreWatcher, constructAlarmInventoryResourceChange(ALARM_TYPES, RESOURCES)) \
Tomáš Pecka4a0c6ea2024-01-31 15:14:55 +0100102 .INSERT_INTO_INVENTORY(WATCHER.alarmInventory, ALARM_TYPES, RESOURCES, (std::vector<std::string>{}))
Tomáš Peckabaf289c2024-01-24 15:12:44 +0100103
Tomáš Pecka4163c0c2024-01-31 13:21:03 +0100104#define REQUIRE_NEW_ALARM(WATCHER, ALARM_TYPE, RESOURCE, SEVERITY, TEXT) \
Tomáš Peckabaf289c2024-01-24 15:12:44 +0100105 REQUIRE_RPC_CALL(WATCHER.rpcWatcher, (Values{ \
106 {"/sysrepo-ietf-alarms:create-or-update-alarm", "(unprintable)"}, \
107 {"/sysrepo-ietf-alarms:create-or-update-alarm/alarm-text", TEXT}, \
108 {"/sysrepo-ietf-alarms:create-or-update-alarm/alarm-type-id", ALARM_TYPE}, \
Tomáš Pecka4163c0c2024-01-31 13:21:03 +0100109 {"/sysrepo-ietf-alarms:create-or-update-alarm/alarm-type-qualifier", ""}, \
Tomáš Peckabaf289c2024-01-24 15:12:44 +0100110 {"/sysrepo-ietf-alarms:create-or-update-alarm/resource", RESOURCE}, \
111 {"/sysrepo-ietf-alarms:create-or-update-alarm/severity", SEVERITY}, \
112 })) \
Tomáš Pecka4163c0c2024-01-31 13:21:03 +0100113 .WITH_ALARM_IN_INVENTORY(WATCHER.alarmInventory, ALARM_TYPE, RESOURCE, SEVERITY)