blob: 87c17db82f5cb32dbeb26e85ad7d553ff041d23a [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"
17
Tomáš Pecka52d50462024-01-31 13:37:29 +010018inline ValueChanges constructAlarmInventoryChange(const std::string& alarmType,
Tomáš Pecka4a0c6ea2024-01-31 15:14:55 +010019 const std::vector<std::string>& resources,
20 const std::vector<std::string>& severities,
Tomáš Peckae66a1932024-01-25 13:43:51 +010021 const std::optional<bool>& willClear,
22 const std::optional<std::string>& description)
Tomáš Pecka1211fd92024-01-24 15:24:07 +010023{
Tomáš Pecka4163c0c2024-01-31 13:21:03 +010024 const std::string prefix = "/ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='" + alarmType + "'][alarm-type-qualifier='']";
Tomáš Pecka1211fd92024-01-24 15:24:07 +010025
Tomáš Pecka87844292024-01-30 15:20:21 +010026 ValueChanges ret;
Tomáš Pecka52d50462024-01-31 13:37:29 +010027 ret.emplace(prefix + "/alarm-type-id", alarmType);
28 ret.emplace(prefix + "/alarm-type-qualifier", "");
Tomáš Pecka1211fd92024-01-24 15:24:07 +010029
Tomáš Peckae66a1932024-01-25 13:43:51 +010030 if (willClear) {
31 ret.emplace(prefix + "/will-clear", *willClear ? "true" : "false");
32 }
33
34 if (description) {
35 ret.emplace(prefix + "/description", *description);
36 }
37
Tomáš Pecka1211fd92024-01-24 15:24:07 +010038 size_t i = 1; /* YANG uses 1-based indexing */
39 for (const auto& severity : severities) {
40 ret.emplace(prefix + "/severity-level[" + std::to_string(i++) + "]", severity);
41 }
42
43 i = 1;
44 for (const auto& resource : resources) {
45 ret.emplace(prefix + "/resource[" + std::to_string(i++) + "]", resource);
46 }
47
48 return ret;
49}
50
Tomáš Pecka4a0c6ea2024-01-31 15:14:55 +010051inline ValueChanges constructAlarmInventoryResourceChange(const std::vector<std::string>& alarmTypeIds, const std::vector<std::string>& resources) {
Tomáš Pecka52d50462024-01-31 13:37:29 +010052 ValueChanges ret;
53
54 for (const auto& alarmType : alarmTypeIds) {
55 const std::string prefix = "/ietf-alarms:alarms/alarm-inventory/alarm-type[alarm-type-id='" + alarmType + "'][alarm-type-qualifier='']";
56
57 size_t i = 1;
58 for (const auto& resource : resources) {
59 ret.emplace(prefix + "/resource[" + std::to_string(i++) + "]", resource);
60 }
61 }
62
63 return ret;
64}
65
Tomáš Peckabaf289c2024-01-24 15:12:44 +010066/** @brief A simple mock implementation of the alarm server */
67struct AlarmWatcher {
68 /** @brief Poor man's /ietf-alarms:alarms/alarm-inventory implementation in C++. */
69 struct AlarmInventory {
Tomáš Pecka4163c0c2024-01-31 13:21:03 +010070 using AlarmType = std::string;
71
Tomáš Pecka1211fd92024-01-24 15:24:07 +010072 struct AllowedResourcesAndSeverities {
73 std::set<std::string> resources;
74 std::set<std::string> severities;
75 };
Tomáš Peckabaf289c2024-01-24 15:12:44 +010076
Tomáš Pecka4163c0c2024-01-31 13:21:03 +010077 std::map<AlarmType, AllowedResourcesAndSeverities> inventory;
78
Tomáš Pecka4a0c6ea2024-01-31 15:14:55 +010079 void add(const std::vector<std::string>& alarmTypeIds, const std::vector<std::string>& resources, const std::vector<std::string>& severities);
Tomáš Pecka4163c0c2024-01-31 13:21:03 +010080 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 +010081 };
82
83 AlarmInventory alarmInventory;
84 DatastoreWatcher datastoreWatcher;
85 RPCWatcher rpcWatcher;
86
87 AlarmWatcher(sysrepo::Session& session);
88};
89
90// checks if the alarm is contained in AlarmInventory
Tomáš Pecka4163c0c2024-01-31 13:21:03 +010091#define WITH_ALARM_IN_INVENTORY(INV, ALARM_TYPE, RESOURCE, SEVERITY) \
92 LR_WITH(INV.contains(ALARM_TYPE, RESOURCE, SEVERITY))
Tomáš Peckabaf289c2024-01-24 15:12:44 +010093
94// inserts the alarm in AlarmInventory as a side effect
Tomáš Pecka52d50462024-01-31 13:37:29 +010095#define INSERT_INTO_INVENTORY(INV, ALARM_TYPES, RESOURCES, SEVERITIES) \
96 LR_SIDE_EFFECT(INV.add(ALARM_TYPES, RESOURCES, SEVERITIES))
Tomáš Peckabaf289c2024-01-24 15:12:44 +010097
Tomáš Pecka4163c0c2024-01-31 13:21:03 +010098#define REQUIRE_NEW_ALARM_INVENTORY_ENTRY(WATCHER, ALARM_TYPE, RESOURCES, SEVERITIES, WILL_CLEAR, DESCRIPTION) \
Tomáš Pecka52d50462024-01-31 13:37:29 +010099 REQUIRE_DATASTORE_CHANGE(WATCHER.datastoreWatcher, constructAlarmInventoryChange(ALARM_TYPE, RESOURCES, SEVERITIES, WILL_CLEAR, DESCRIPTION)) \
Tomáš Pecka4a0c6ea2024-01-31 15:14:55 +0100100 .INSERT_INTO_INVENTORY(WATCHER.alarmInventory, (std::vector<std::string>{ALARM_TYPE}), RESOURCES, SEVERITIES)
Tomáš Peckabaf289c2024-01-24 15:12:44 +0100101
Tomáš Pecka52d50462024-01-31 13:37:29 +0100102#define REQUIRE_NEW_ALARM_INVENTORY_RESOURCES(WATCHER, ALARM_TYPES, RESOURCES) \
103 REQUIRE_DATASTORE_CHANGE(WATCHER.datastoreWatcher, constructAlarmInventoryResourceChange(ALARM_TYPES, RESOURCES)) \
Tomáš Pecka4a0c6ea2024-01-31 15:14:55 +0100104 .INSERT_INTO_INVENTORY(WATCHER.alarmInventory, ALARM_TYPES, RESOURCES, (std::vector<std::string>{}))
Tomáš Peckabaf289c2024-01-24 15:12:44 +0100105
Tomáš Pecka4163c0c2024-01-31 13:21:03 +0100106#define REQUIRE_NEW_ALARM(WATCHER, ALARM_TYPE, RESOURCE, SEVERITY, TEXT) \
Tomáš Peckabaf289c2024-01-24 15:12:44 +0100107 REQUIRE_RPC_CALL(WATCHER.rpcWatcher, (Values{ \
108 {"/sysrepo-ietf-alarms:create-or-update-alarm", "(unprintable)"}, \
109 {"/sysrepo-ietf-alarms:create-or-update-alarm/alarm-text", TEXT}, \
110 {"/sysrepo-ietf-alarms:create-or-update-alarm/alarm-type-id", ALARM_TYPE}, \
Tomáš Pecka4163c0c2024-01-31 13:21:03 +0100111 {"/sysrepo-ietf-alarms:create-or-update-alarm/alarm-type-qualifier", ""}, \
Tomáš Peckabaf289c2024-01-24 15:12:44 +0100112 {"/sysrepo-ietf-alarms:create-or-update-alarm/resource", RESOURCE}, \
113 {"/sysrepo-ietf-alarms:create-or-update-alarm/severity", SEVERITY}, \
114 })) \
Tomáš Pecka4163c0c2024-01-31 13:21:03 +0100115 .WITH_ALARM_IN_INVENTORY(WATCHER.alarmInventory, ALARM_TYPE, RESOURCE, SEVERITY)