GCC Code Coverage Report


Directory: ./
File: src/iguana/services/YAMLReader.cc
Date: 2025-01-05 09:03:17
Exec Total Coverage
Lines: 55 73 75.3%
Functions: 20 20 100.0%
Branches: 105 189 55.6%

Line Branch Exec Source
1 #include "YAMLReader.h"
2
3 namespace iguana {
4
5 39 void YAMLReader::LoadFiles()
6 {
7 39 m_log->Debug("YAMLReader::LoadFiles():");
8
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 39 times.
84 for(auto const& file : m_files) {
9 try {
10
1/2
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
45 m_log->Debug(" - load: {}", file);
11
2/4
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45 times.
✗ Branch 3 not taken.
90 m_configs.push_back({YAML::LoadFile(file), file}); // m_config must be the same ordering as m_files, so `push_back`
12 }
13 catch(const YAML::Exception& e) {
14 m_log->Error(" - YAML Exception: {}", e.what());
15 }
16 catch(std::exception const& e) {
17 m_log->Error(" - Exception: {}", e.what());
18 }
19 }
20 39 }
21
22 ///////////////////////////////////////////////////////////////////////////////
23
24 template <typename SCALAR>
25
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 std::optional<SCALAR> YAMLReader::GetScalar(YAML::Node node)
26 {
27
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
144 if(node.IsDefined() && !node.IsNull()) {
28 try {
29
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
113 return node.as<SCALAR>();
30 }
31 catch(const YAML::Exception& e) {
32 m_log->Error("YAML Parsing Exception: {}", e.what());
33 }
34 catch(std::exception const& e) {
35 m_log->Error("YAML Misc. Exception: {}", e.what());
36 }
37 }
38 return std::nullopt;
39 }
40 template std::optional<int> YAMLReader::GetScalar(YAML::Node node);
41 template std::optional<double> YAMLReader::GetScalar(YAML::Node node);
42 template std::optional<std::string> YAMLReader::GetScalar(YAML::Node node);
43
44 ///////////////////////////////////////////////////////////////////////////////
45
46 template <typename SCALAR>
47 94 std::optional<SCALAR> YAMLReader::GetScalar(node_path_t node_path)
48 {
49
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 21 times.
152 for(auto const& [config, filename] : m_configs) {
50
4/6
✓ Branch 0 taken 102 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 101 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 101 times.
✗ Branch 5 not taken.
103 auto node = FindNode(config, node_path);
51
3/4
✓ Branch 0 taken 73 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 72 times.
174 if(node.IsDefined() && !node.IsNull())
52
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 return GetScalar<SCALAR>(node);
53 }
54 21 return std::nullopt;
55 }
56 template std::optional<int> YAMLReader::GetScalar(node_path_t node_path);
57 template std::optional<double> YAMLReader::GetScalar(node_path_t node_path);
58 template std::optional<std::string> YAMLReader::GetScalar(node_path_t node_path);
59
60 ///////////////////////////////////////////////////////////////////////////////
61
62 template <typename SCALAR>
63
1/2
✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
71 std::optional<std::vector<SCALAR>> YAMLReader::GetVector(YAML::Node node)
64 {
65
3/6
✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 71 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 71 times.
✗ Branch 5 not taken.
213 if(node.IsDefined() && !node.IsNull() && node.IsSequence()) {
66 try {
67 std::vector<SCALAR> result;
68
5/8
✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 71 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 153 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 153 times.
✓ Branch 7 taken 71 times.
295 for(auto const& element : node)
69
2/4
✓ Branch 0 taken 153 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 141 times.
✗ Branch 3 not taken.
165 result.push_back(element.as<SCALAR>());
70 return result;
71 5 }
72 catch(const YAML::Exception& e) {
73 m_log->Error("YAML Parsing Exception: {}", e.what());
74 }
75 catch(std::exception const& e) {
76 m_log->Error("YAML Misc. Exception: {}", e.what());
77 }
78 }
79 return std::nullopt;
80 }
81 template std::optional<std::vector<int>> YAMLReader::GetVector(YAML::Node node);
82 template std::optional<std::vector<double>> YAMLReader::GetVector(YAML::Node node);
83 template std::optional<std::vector<std::string>> YAMLReader::GetVector(YAML::Node node);
84
85 ///////////////////////////////////////////////////////////////////////////////
86
87 template <typename SCALAR>
88 29 std::optional<std::vector<SCALAR>> YAMLReader::GetVector(node_path_t node_path)
89 {
90
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 4 times.
45 for(auto const& [config, filename] : m_configs) {
91
3/6
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 33 times.
✗ Branch 5 not taken.
33 auto node = FindNode(config, node_path);
92
3/4
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 25 times.
60 if(node.IsDefined() && !node.IsNull())
93
2/4
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
25 return GetVector<SCALAR>(node);
94 }
95 4 return std::nullopt;
96 }
97 template std::optional<std::vector<int>> YAMLReader::GetVector(node_path_t node_path);
98 template std::optional<std::vector<double>> YAMLReader::GetVector(node_path_t node_path);
99 template std::optional<std::vector<std::string>> YAMLReader::GetVector(node_path_t node_path);
100
101 ///////////////////////////////////////////////////////////////////////////////
102
103 template <typename SCALAR>
104 38 YAMLReader::node_finder_t YAMLReader::InRange(std::string const& key, SCALAR val)
105 {
106
4/8
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 156 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 30 times.
✗ Branch 7 not taken.
544 return [this, key, val](YAML::Node node) -> YAML::Node
107 {
108
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
38 if(!node.IsSequence()) {
109 m_log->Error("YAML node path expected a sequence at current node");
110 throw std::runtime_error("Failed `InRange`");
111 }
112 // search each sub-node for one with `val` with in the range at `key`
113
8/12
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 30 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 53 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 53 times.
✓ Branch 11 taken 20 times.
198 for(const auto& sub_node : node) {
114
2/4
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53 times.
✗ Branch 3 not taken.
69 auto bounds_node = sub_node[key];
115
2/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
46 if(bounds_node.IsDefined()) {
116
6/12
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 32 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 32 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 32 times.
✗ Branch 11 not taken.
46 auto bounds = GetVector<SCALAR>(bounds_node);
117
9/12
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 32 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 26 times.
✓ Branch 9 taken 6 times.
✓ Branch 10 taken 16 times.
✓ Branch 11 taken 10 times.
92 if(bounds.value().size() == 2 && bounds.value()[0] <= val && bounds.value()[1] >= val)
118
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
16 return sub_node;
119 }
120 }
121 // fallback to the default node
122
7/12
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 20 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 27 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 27 times.
✓ Branch 11 taken 1 times.
91 for(const auto& sub_node : node) {
123
6/8
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 27 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 19 times.
✓ Branch 7 taken 8 times.
68 if(sub_node["default"].IsDefined())
124
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19 times.
✗ Branch 3 not taken.
21 return sub_node;
125 }
126 // if no default found, return empty
127
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 m_log->Error("No default node for `InRange('{}',{})`", key, val);
128
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 throw std::runtime_error("Failed `InRange`");
129
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
76 };
130 }
131 template YAMLReader::node_finder_t YAMLReader::InRange(std::string const& key, int val);
132 template YAMLReader::node_finder_t YAMLReader::InRange(std::string const& key, double val);
133
134 ///////////////////////////////////////////////////////////////////////////////
135
136
2/2
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 373 times.
473 YAML::Node YAMLReader::FindNode(YAML::Node node, node_path_t node_path)
137 {
138
139 // if `node_path` is empty, we are likely at the end of the node path; end recursion and return `node`
140
2/2
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 373 times.
473 if(node_path.empty()) {
141 100 m_log->Trace("... found");
142 100 return node;
143 }
144
145 // find the next node using the first `node_id_t` in `node_path`
146 746 auto node_id_visitor = [&node, &m_log = this->m_log](auto&& arg) -> YAML::Node
147 {
148 using arg_t = std::decay_t<decltype(arg)>;
149 // find a node by key name
150 if constexpr(std::is_same_v<arg_t, std::string>) {
151
1/2
✓ Branch 0 taken 335 times.
✗ Branch 1 not taken.
335 m_log->Trace("... by key '{}'", arg);
152 335 return node[arg];
153 }
154 // find a node using a `node_finder_t`
155 else {
156 38 m_log->Trace("... by node finder function");
157 76 return arg(node);
158 }
159 373 };
160 auto result = std::visit(node_id_visitor, node_path.front());
161
162 // if the resulting node is not defined, return an empty node; callers must check the result
163
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 338 times.
372 if(!result.IsDefined())
164 return {};
165
166 // recurse to the next element of `node_path`
167 338 node_path.pop_front();
168
4/6
✓ Branch 0 taken 338 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 338 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 336 times.
✓ Branch 5 taken 2 times.
340 return FindNode(result, node_path);
169 372 }
170
171 }
172