GCC Code Coverage Report


Directory: ./
File: src/iguana/services/YAMLReader.cc
Date: 2025-06-02 23:22:06
Exec Total Coverage
Lines: 55 73 75.3%
Functions: 20 20 100.0%
Branches: 111 211 52.6%

Line Branch Exec Source
1 #include "YAMLReader.h"
2
3 namespace iguana {
4
5 41 void YAMLReader::LoadFiles()
6 {
7 41 m_log->Debug("YAMLReader::LoadFiles():");
8
2/2
✓ Branch 0 (23→4) taken 47 times.
✓ Branch 1 (23→24) taken 41 times.
88 for(auto const& file : m_files) {
9 try {
10
2/6
✓ Branch 0 (8→9) taken 47 times.
✗ Branch 1 (8→25) not taken.
✗ Branch 2 (9→10) not taken.
✓ Branch 3 (9→12) taken 47 times.
✗ Branch 4 (25→26) not taken.
✗ Branch 5 (25→28) not taken.
47 m_log->Debug(" - load: {}", file);
11
2/4
✓ Branch 0 (14→15) taken 47 times.
✗ Branch 1 (14→35) not taken.
✓ Branch 2 (15→16) taken 47 times.
✗ Branch 3 (15→33) not taken.
94 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 41 }
21
22 ///////////////////////////////////////////////////////////////////////////////
23
24 template <typename SCALAR>
25
1/2
✓ Branch 0 (2→3) taken 82 times.
✗ Branch 1 (2→15) not taken.
82 std::optional<SCALAR> YAMLReader::GetScalar(YAML::Node node)
26 {
27
2/4
✓ Branch 0 (4→5) taken 82 times.
✗ Branch 1 (4→15) not taken.
✓ Branch 2 (6→7) taken 82 times.
✗ Branch 3 (6→15) not taken.
164 if(node.IsDefined() && !node.IsNull()) {
28 try {
29
1/2
✓ Branch 0 (7→8) taken 82 times.
✗ Branch 1 (7→17) not taken.
131 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 106 std::optional<SCALAR> YAMLReader::GetScalar(node_path_t node_path)
48 {
49
2/2
✓ Branch 0 (22→3) taken 114 times.
✓ Branch 1 (22→23) taken 23 times.
168 for(auto const& [config, filename] : m_configs) {
50
4/6
✓ Branch 0 (4→5) taken 114 times.
✗ Branch 1 (4→27) not taken.
✓ Branch 2 (5→6) taken 113 times.
✓ Branch 3 (5→25) taken 1 times.
✓ Branch 4 (8→9) taken 113 times.
✗ Branch 5 (8→13) not taken.
115 auto node = FindNode(config, node_path);
51
3/4
✓ Branch 0 (10→11) taken 83 times.
✗ Branch 1 (10→13) not taken.
✓ Branch 2 (12→13) taken 31 times.
✓ Branch 3 (12→15) taken 82 times.
196 if(node.IsDefined() && !node.IsNull())
52
2/4
✓ Branch 0 (15→16) taken 82 times.
✗ Branch 1 (15→31) not taken.
✓ Branch 2 (16→17) taken 82 times.
✗ Branch 3 (16→29) not taken.
82 return GetScalar<SCALAR>(node);
53 }
54 23 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 (2→3) taken 73 times.
✗ Branch 1 (2→33) not taken.
73 std::optional<std::vector<SCALAR>> YAMLReader::GetVector(YAML::Node node)
64 {
65
3/6
✓ Branch 0 (4→5) taken 73 times.
✗ Branch 1 (4→33) not taken.
✓ Branch 2 (6→7) taken 73 times.
✗ Branch 3 (6→33) not taken.
✓ Branch 4 (8→9) taken 73 times.
✗ Branch 5 (8→33) not taken.
219 if(node.IsDefined() && !node.IsNull() && node.IsSequence()) {
66 try {
67 std::vector<SCALAR> result;
68
5/8
✓ Branch 0 (9→10) taken 73 times.
✗ Branch 1 (9→49) not taken.
✓ Branch 2 (10→22) taken 73 times.
✗ Branch 3 (10→46) not taken.
✓ Branch 4 (11→12) taken 159 times.
✗ Branch 5 (11→43) not taken.
✓ Branch 6 (26→11) taken 159 times.
✓ Branch 7 (26→27) taken 73 times.
305 for(auto const& element : node)
69
2/4
✓ Branch 0 (12→13) taken 159 times.
✗ Branch 1 (12→41) not taken.
✓ Branch 2 (13→14) taken 147 times.
✗ Branch 3 (13→29) not taken.
171 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 31 std::optional<std::vector<SCALAR>> YAMLReader::GetVector(node_path_t node_path)
89 {
90
2/2
✓ Branch 0 (22→3) taken 35 times.
✓ Branch 1 (22→23) taken 4 times.
47 for(auto const& [config, filename] : m_configs) {
91
3/6
✓ Branch 0 (4→5) taken 35 times.
✗ Branch 1 (4→27) not taken.
✓ Branch 2 (5→6) taken 35 times.
✗ Branch 3 (5→25) not taken.
✓ Branch 4 (8→9) taken 35 times.
✗ Branch 5 (8→13) not taken.
35 auto node = FindNode(config, node_path);
92
3/4
✓ Branch 0 (10→11) taken 29 times.
✗ Branch 1 (10→13) not taken.
✓ Branch 2 (12→13) taken 8 times.
✓ Branch 3 (12→15) taken 27 times.
64 if(node.IsDefined() && !node.IsNull())
93
2/4
✓ Branch 0 (15→16) taken 27 times.
✗ Branch 1 (15→31) not taken.
✓ Branch 2 (16→17) taken 27 times.
✗ Branch 3 (16→29) not taken.
27 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 42 YAMLReader::node_finder_t YAMLReader::InRange(std::string const& key, SCALAR val)
105 {
106
4/8
✗ Branch 0 (2→3) not taken.
✓ Branch 1 (2→4) taken 82 times.
✗ Branch 2 (3→4) not taken.
✓ Branch 3 (3→5) taken 176 times.
✗ Branch 4 (3→4) not taken.
✓ Branch 5 (3→5) taken 8 times.
✗ Branch 6 (3→4) not taken.
✓ Branch 7 (3→5) taken 34 times.
858 return [this, key, val](YAML::Node node) -> YAML::Node
107 {
108
2/4
✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→8) taken 8 times.
✗ Branch 2 (3→4) not taken.
✓ Branch 3 (3→8) taken 34 times.
42 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 (9→44) taken 8 times.
✗ Branch 1 (9→107) not taken.
✓ Branch 2 (10→11) taken 16 times.
✗ Branch 3 (10→104) not taken.
✓ Branch 4 (48→10) taken 16 times.
✓ Branch 5 (48→49) taken 2 times.
✓ Branch 6 (9→44) taken 34 times.
✗ Branch 7 (9→107) not taken.
✓ Branch 8 (10→11) taken 57 times.
✗ Branch 9 (10→104) not taken.
✓ Branch 10 (48→10) taken 57 times.
✓ Branch 11 (48→49) taken 24 times.
214 for(const auto& sub_node : node) {
114
2/4
✓ Branch 0 (11→12) taken 16 times.
✗ Branch 1 (11→102) not taken.
✓ Branch 2 (11→12) taken 57 times.
✗ Branch 3 (11→102) not taken.
73 auto bounds_node = sub_node[key];
115
2/4
✓ Branch 0 (14→15) taken 14 times.
✗ Branch 1 (14→40) not taken.
✓ Branch 2 (14→15) taken 32 times.
✗ Branch 3 (14→40) not taken.
46 if(bounds_node.IsDefined()) {
116
6/12
✓ Branch 0 (15→16) taken 14 times.
✗ Branch 1 (15→100) not taken.
✓ Branch 2 (16→17) taken 14 times.
✗ Branch 3 (16→96) not taken.
✓ Branch 4 (18→19) taken 14 times.
✗ Branch 5 (18→20) not taken.
✓ Branch 6 (15→16) taken 32 times.
✗ Branch 7 (15→100) not taken.
✓ Branch 8 (16→17) taken 32 times.
✗ Branch 9 (16→96) not taken.
✓ Branch 10 (18→19) taken 32 times.
✗ Branch 11 (18→20) not taken.
46 auto bounds = GetVector<SCALAR>(bounds_node);
117
9/12
✓ Branch 0 (22→23) taken 14 times.
✗ Branch 1 (22→29) not taken.
✓ Branch 2 (25→26) taken 14 times.
✗ Branch 3 (25→29) not taken.
✓ Branch 4 (28→29) taken 8 times.
✓ Branch 5 (28→31) taken 6 times.
✓ Branch 6 (22→23) taken 32 times.
✗ Branch 7 (22→29) not taken.
✓ Branch 8 (25→26) taken 26 times.
✓ Branch 9 (25→29) taken 6 times.
✓ Branch 10 (28→29) taken 16 times.
✓ Branch 11 (28→31) taken 10 times.
132 if(bounds.value().size() == 2 && bounds.value()[0] <= val && bounds.value()[1] >= val)
118
2/4
✓ Branch 0 (31→32) taken 6 times.
✗ Branch 1 (31→98) not taken.
✓ Branch 2 (31→32) taken 10 times.
✗ Branch 3 (31→98) not taken.
16 return sub_node;
119 }
120 }
121 // fallback to the default node
122
7/12
✓ Branch 0 (54→72) taken 2 times.
✗ Branch 1 (54→115) not taken.
✓ Branch 2 (55→56) taken 7 times.
✗ Branch 3 (55→112) not taken.
✓ Branch 4 (76→55) taken 7 times.
✗ Branch 5 (76→77) not taken.
✓ Branch 6 (54→72) taken 24 times.
✗ Branch 7 (54→115) not taken.
✓ Branch 8 (55→56) taken 31 times.
✗ Branch 9 (55→112) not taken.
✓ Branch 10 (76→55) taken 31 times.
✓ Branch 11 (76→77) taken 1 times.
103 for(const auto& sub_node : node) {
123
6/8
✓ Branch 0 (56→57) taken 7 times.
✗ Branch 1 (56→110) not taken.
✓ Branch 2 (61→62) taken 2 times.
✓ Branch 3 (61→63) taken 5 times.
✓ Branch 4 (56→57) taken 31 times.
✗ Branch 5 (56→110) not taken.
✓ Branch 6 (61→62) taken 23 times.
✓ Branch 7 (61→63) taken 8 times.
76 if(sub_node["default"].IsDefined())
124
2/4
✓ Branch 0 (62→65) taken 2 times.
✗ Branch 1 (62→110) not taken.
✓ Branch 2 (62→65) taken 23 times.
✗ Branch 3 (62→110) not taken.
25 return sub_node;
125 }
126 // if no default found, return empty
127
3/16
✗ Branch 0 (81→82) not taken.
✗ Branch 1 (81→83) not taken.
✗ Branch 2 (84→85) not taken.
✗ Branch 3 (84→118) not taken.
✗ Branch 4 (85→86) not taken.
✗ Branch 5 (85→88) not taken.
✗ Branch 6 (118→119) not taken.
✗ Branch 7 (118→121) not taken.
✗ Branch 8 (81→82) not taken.
✓ Branch 9 (81→83) taken 1 times.
✓ Branch 10 (84→85) taken 1 times.
✗ Branch 11 (84→118) not taken.
✓ Branch 12 (85→86) taken 1 times.
✗ Branch 13 (85→88) not taken.
✗ Branch 14 (118→119) not taken.
✗ Branch 15 (118→121) not taken.
2 m_log->Error("No default node for `InRange('{}',{})`", key, val);
128
1/4
✗ Branch 0 (91→92) not taken.
✗ Branch 1 (91→124) not taken.
✓ Branch 2 (91→92) taken 1 times.
✗ Branch 3 (91→124) not taken.
1 throw std::runtime_error("Failed `InRange`");
129
1/2
✓ Branch 0 (5→6) taken 42 times.
✗ Branch 1 (5→12) not taken.
84 };
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 (2→3) taken 112 times.
✓ Branch 1 (2→5) taken 415 times.
527 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 (2→3) taken 112 times.
✓ Branch 1 (2→5) taken 415 times.
527 if(node_path.empty()) {
141 112 m_log->Trace("... found");
142 112 return node;
143 }
144
145 // find the next node using the first `node_id_t` in `node_path`
146 830 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
4/8
✗ Branch 0 (2→3) not taken.
✓ Branch 1 (2→4) taken 373 times.
✓ Branch 2 (5→6) taken 373 times.
✗ Branch 3 (5→13) not taken.
✓ Branch 4 (6→7) taken 218 times.
✓ Branch 5 (6→9) taken 155 times.
✗ Branch 6 (13→14) not taken.
✗ Branch 7 (13→16) not taken.
746 m_log->Trace("... by key '{}'", arg);
152 373 return node[arg];
153 }
154 // find a node using a `node_finder_t`
155 else {
156 42 m_log->Trace("... by node finder function");
157 84 return arg(node);
158 }
159 415 };
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 (8→9) taken 36 times.
✓ Branch 1 (8→10) taken 378 times.
414 if(!result.IsDefined())
164 return {};
165
166 // recurse to the next element of `node_path`
167 378 node_path.pop_front();
168
4/6
✓ Branch 0 (11→12) taken 378 times.
✗ Branch 1 (11→23) not taken.
✓ Branch 2 (12→13) taken 378 times.
✗ Branch 3 (12→21) not taken.
✓ Branch 4 (13→14) taken 376 times.
✓ Branch 5 (13→19) taken 2 times.
380 return FindNode(result, node_path);
169 414 }
170
171 }
172