GCC Code Coverage Report


Directory: ./
File: src/Daemon/daemon_load_config.cpp
Date: 2026-01-15 15:35:36
Exec Total Coverage
Lines: 80 85 94.1%
Functions: 5 5 100.0%
Branches: 198 242 81.8%

Line Branch Exec Source
1 /***************************************
2 Auteur : Pierre Aubert
3 Mail : pierre.aubert@lapp.in2p3.fr
4 Licence : CeCILL-C
5 ****************************************/
6
7 #include "parser_json.h"
8 #include "parser_toml.h"
9 #include "parser_yml.h"
10 #include "daemon_load_config.h"
11 #include "daemon_config_exception.h"
12 #include <sstream>
13
14 ///Load the daemon config into a ConfigNode from a json string
15 /** @param[out] log : log of the Daemon
16 * @param[out] dico : ConfigNode with all the configuration
17 * @param inputConfig : input string of the configuration
18 * @param format : format of the configuration
19 * @return true on success, false otherwise
20 */
21 13 void daemon_load_config(PLog & log, ConfigNode & dico, const PString & inputConfig, ConfigFormat::ConfigFormat format){
22
2/2
✓ Branch 0 (2→3) taken 4 times.
✓ Branch 1 (2→9) taken 9 times.
13 if(format == ConfigFormat::JSON){
23
2/2
✓ Branch 0 (4→5) taken 1 times.
✓ Branch 1 (4→33) taken 3 times.
4 if(!parser_jsonString(dico, inputConfig)){
24
1/2
✓ Branch 0 (5→6) taken 1 times.
✗ Branch 2 (6→7) not taken.
2 log.criticalAndThrow<Phoenix::ParserException>("daemon_load_config", "cannot load config from input string");
25 }
26
2/2
✓ Branch 0 (9→10) taken 4 times.
✓ Branch 1 (9→16) taken 5 times.
9 }else if(format == ConfigFormat::TOML){
27
2/2
✓ Branch 0 (11→12) taken 1 times.
✓ Branch 1 (11→33) taken 3 times.
4 if(!parser_tomlString(dico, inputConfig)){
28
1/2
✓ Branch 0 (12→13) taken 1 times.
✗ Branch 2 (13→14) not taken.
2 log.criticalAndThrow<Phoenix::ParserException>("daemon_load_config", "cannot load config from input string");
29 }
30
2/2
✓ Branch 0 (16→17) taken 4 times.
✓ Branch 1 (16→23) taken 1 times.
5 }else if(format == ConfigFormat::YAML){
31
2/2
✓ Branch 0 (18→19) taken 1 times.
✓ Branch 1 (18→33) taken 3 times.
4 if(!parser_ymlString(dico, inputConfig)){
32
1/2
✓ Branch 0 (19→20) taken 1 times.
✗ Branch 2 (20→21) not taken.
2 log.criticalAndThrow<Phoenix::ParserException>("daemon_load_config", "cannot load config from input string");
33 }
34 }else{
35
3/4
✓ Branch 0 (24→25) taken 1 times.
✓ Branch 2 (25→26) taken 1 times.
✓ Branch 4 (26→27) taken 1 times.
✗ Branch 6 (27→28) not taken.
5 log.criticalAndThrow<Phoenix::ParserException>("daemon_load_config", "unknown format '"+std::to_string(static_cast<int>(format))+"' of config");
36 }
37 9 }
38
39 ///Load the daemon config into a ConfigNode
40 /** @param[out] log : log of the Daemon
41 * @param[out] dico : ConfigNode with all the configuration
42 * @param configFile : file name of the configuration
43 * @return true on success, false otherwise
44 */
45 27 void daemon_load_config(PLog & log, ConfigNode & dico, const PPath & configFile){
46
1/1
✓ Branch 0 (2→3) taken 27 times.
27 PString extension = configFile.getExtension();
47
3/3
✓ Branch 0 (3→4) taken 27 times.
✓ Branch 2 (4→5) taken 16 times.
✓ Branch 3 (4→15) taken 11 times.
27 if(extension == "toml"){
48
3/3
✓ Branch 0 (5→6) taken 16 times.
✓ Branch 2 (6→7) taken 1 times.
✓ Branch 3 (6→51) taken 15 times.
16 if(!parser_toml(dico, configFile)){
49
3/4
✓ Branch 0 (7→8) taken 1 times.
✓ Branch 2 (8→9) taken 1 times.
✓ Branch 4 (9→10) taken 1 times.
✗ Branch 6 (10→11) not taken.
4 log.criticalAndThrow<Phoenix::ParserException>("daemon_load_config", "cannot load toml file '"+configFile+"'");
50 }
51
3/3
✓ Branch 0 (15→16) taken 11 times.
✓ Branch 2 (16→17) taken 5 times.
✓ Branch 3 (16→27) taken 6 times.
11 }else if(extension == "yml"){
52
3/3
✓ Branch 0 (17→18) taken 5 times.
✓ Branch 2 (18→19) taken 1 times.
✓ Branch 3 (18→51) taken 4 times.
5 if(!parser_yml(dico, configFile)){
53
3/4
✓ Branch 0 (19→20) taken 1 times.
✓ Branch 2 (20→21) taken 1 times.
✓ Branch 4 (21→22) taken 1 times.
✗ Branch 6 (22→23) not taken.
4 log.criticalAndThrow<Phoenix::ParserException>("daemon_load_config", "cannot load yml file '"+configFile+"'");
54 }
55
3/3
✓ Branch 0 (27→28) taken 6 times.
✓ Branch 2 (28→29) taken 4 times.
✓ Branch 3 (28→39) taken 2 times.
6 }else if(extension == "json"){
56
3/3
✓ Branch 0 (29→30) taken 4 times.
✓ Branch 2 (30→31) taken 1 times.
✓ Branch 3 (30→51) taken 3 times.
4 if(!parser_json(dico, configFile)){
57
3/4
✓ Branch 0 (31→32) taken 1 times.
✓ Branch 2 (32→33) taken 1 times.
✓ Branch 4 (33→34) taken 1 times.
✗ Branch 6 (34→35) not taken.
4 log.criticalAndThrow<Phoenix::ParserException>("daemon_load_config", "cannot load json file '"+configFile+"'");
58 }
59 }else{
60
5/6
✓ Branch 0 (39→40) taken 2 times.
✓ Branch 2 (40→41) taken 2 times.
✓ Branch 4 (41→42) taken 2 times.
✓ Branch 6 (42→43) taken 2 times.
✓ Branch 8 (43→44) taken 2 times.
✗ Branch 10 (44→45) not taken.
12 log.criticalAndThrow<Phoenix::ParserException>("daemon_load_config", "unknown extension '"+extension+"' of config file '"+configFile+"'");
61 }
62 27 }
63
64 ///Load a string value
65 /** @param dico : DicoValue to be used
66 * @param attributeName : name of the attribute to read
67 * @return corresponding string
68 */
69 184 PString daemon_loadString(const ConfigNode & dico, const PString & attributeName){
70
4/4
✓ Branch 0 (2→3) taken 184 times.
✓ Branch 2 (3→4) taken 184 times.
✓ Branch 4 (4→5) taken 184 times.
✓ Branch 6 (5→6) taken 184 times.
184 return phoenix_get_string(dico, attributeName, "unnamed_daemon").eraseFirstLastChar("\"'\t\n ");
71 // return phoenix_load_value_from_config<PString>(dico, attributeName, "unnamed_daemon").eraseFirstLastChar("\"'\t\n ");
72 }
73
74
75 ///Set a daemon config from a configNode
76 /// @param config : configuration of the daemon
77 /// @param log : log of the current daemon
78 /// @param mapTimeout : map of all Daemon timeout
79 /// @param nodeDict : ConfigNode with data to set the daemon config with.
80 /// @param throwOnError if true: an error is thrown if setting the configuration fails. Otherwise an error is logged but execution continues.
81 41 void set_daemon_config_from_node(DaemonConfig & config, PLog & log, MapTimeout & mapTimeout, const ConfigNode & nodeDict, bool throwOnError)
82 {
83
3/3
✓ Branch 0 (2→3) taken 41 times.
✓ Branch 2 (3→4) taken 41 times.
✓ Branch 4 (4→5) taken 41 times.
41 config.setName(daemon_loadString(nodeDict, "name"));
84
3/3
✓ Branch 0 (7→8) taken 41 times.
✓ Branch 2 (8→9) taken 41 times.
✓ Branch 4 (9→10) taken 41 times.
41 config.setDescription(daemon_loadString(nodeDict, "description"));
85
6/6
✓ Branch 0 (12→13) taken 41 times.
✓ Branch 2 (13→14) taken 41 times.
✓ Branch 4 (14→15) taken 41 times.
✓ Branch 6 (15→16) taken 41 times.
✓ Branch 8 (16→17) taken 41 times.
✓ Branch 10 (17→18) taken 41 times.
41 config.setHostName(PString(phoenix_get_string(nodeDict, "hostname", "localhost")).eraseFirstLastChar("\"'\t\n "));
86
3/3
✓ Branch 0 (23→24) taken 41 times.
✓ Branch 2 (24→25) taken 41 times.
✓ Branch 4 (25→26) taken 41 times.
41 config.setReceivingPort(phoenix_get_value<size_t>(nodeDict, "receiving_port", -1lu));
87
3/3
✓ Branch 0 (27→28) taken 41 times.
✓ Branch 2 (28→29) taken 41 times.
✓ Branch 4 (29→30) taken 41 times.
41 config.setStatNbBin(phoenix_get_value<size_t>(nodeDict, "stat_nb_bin", 100lu));
88
3/3
✓ Branch 0 (31→32) taken 41 times.
✓ Branch 2 (32→33) taken 41 times.
✓ Branch 4 (33→34) taken 41 times.
41 config.setStatHistLowerBound(phoenix_get_value<float>(nodeDict, "stat_hist_lower_bound", 0.f));
89
3/3
✓ Branch 0 (35→36) taken 41 times.
✓ Branch 2 (36→37) taken 41 times.
✓ Branch 4 (37→38) taken 41 times.
41 config.setStatHistUpperBound(phoenix_get_value<float>(nodeDict, "stat_hist_upper_bound", 100.f));
90
3/3
✓ Branch 0 (39→40) taken 41 times.
✓ Branch 2 (40→41) taken 41 times.
✓ Branch 4 (41→42) taken 41 times.
41 config.setStatTimerPeriodMs(phoenix_get_value<time_t>(nodeDict, "stat_timer_period", 1000lu));
91 //Add the timeout of current config to global daemon config
92
4/4
✓ Branch 0 (43→44) taken 41 times.
✓ Branch 2 (44→45) taken 41 times.
✓ Branch 4 (45→46) taken 41 times.
✓ Branch 6 (46→47) taken 41 times.
41 mapTimeout[config.getName()] = phoenix_get_value<size_t>(nodeDict, "daemon_required_response_timeout", 1000lu);
93
2/2
✓ Branch 0 (49→50) taken 1 times.
✓ Branch 1 (49→71) taken 40 times.
41 if(config.getReceivingPort() >= 65536lu){
94
7/7
✓ Branch 0 (50→51) taken 1 times.
✓ Branch 2 (51→52) taken 1 times.
✓ Branch 4 (52→53) taken 1 times.
✓ Branch 6 (53→54) taken 1 times.
✓ Branch 8 (54→55) taken 1 times.
✓ Branch 10 (55→56) taken 1 times.
✓ Branch 12 (56→57) taken 1 times.
1 std::string errorString("BaseDaemon::set_daemon_config_from_node : 'receiving_port' of Daemon '"+config.getName()+"' has invalid value '"+std::to_string(config.getReceivingPort())+"'");
95
1/2
✓ Branch 0 (61→62) taken 1 times.
✗ Branch 1 (61→66) not taken.
1 if(throwOnError){
96
1/2
✓ Branch 0 (62→63) taken 1 times.
✗ Branch 2 (63→64) not taken.
2 log.criticalAndThrow<Phoenix::ConfigException>("BaseDaemon::set_daemon_config_from_node", errorString);
97 }else{
98 log.getLogError() << errorString << std::endl;
99 }
100 1 }
101 40 }
102
103
104 ///Read the ConfigNode to initialise current Daemon
105 /** @param[out] daemonConfig : current Daemon configuration
106 * @param[out] mapDaemon : map of all Daemon configuration
107 * @param[out] log : log of the Daemon
108 * @param[out] mapTimeout : map of all Daemon timeout
109 * @param[out] extraConfigParam : pointer to extra configuration parameters of the Daemon (extra_parameter)
110 * @param dico : ConfigNode to be used
111 * @param daemonName : name of the current Daemon to load
112 * @return true on success, false otherwise
113 */
114 34 void daemon_read_configNode(DaemonConfig & daemonConfig, MapDaemonConfig & mapDaemon,
115 PLog & log, MapTimeout & mapTimeout, const ConfigNode *& extraConfigParam, const ConfigNode & dico, const PString & daemonName)
116 {
117
2/2
✓ Branch 0 (2→3) taken 34 times.
✓ Branch 2 (3→4) taken 34 times.
34 const ConfigNode * mapBaseDaemon = dico.getChild("daemon");
118
2/2
✓ Branch 0 (5→6) taken 7 times.
✓ Branch 1 (5→10) taken 27 times.
34 if(mapBaseDaemon == nullptr){
119
1/2
✓ Branch 0 (6→7) taken 7 times.
✗ Branch 2 (7→8) not taken.
14 log.criticalAndThrow<Phoenix::ConfigException>("BaseDaemon::daemon_read_configNode" , "Config doesn't contain a 'daemon' section'");
120 }
121
122 27 bool foundDaemonName(false);
123
1/1
✓ Branch 0 (10→11) taken 27 times.
27 const VecConfigNode & vecBaseDaemon = mapBaseDaemon->getVecChild();
124 //Make a first pass to load the current daemon to set the logger as soon as possible
125
6/6
✓ Branch 0 (109→110) taken 53 times.
✓ Branch 1 (109→112) taken 11 times.
✓ Branch 2 (110→111) taken 37 times.
✓ Branch 3 (110→112) taken 16 times.
✓ Branch 4 (113→12) taken 37 times.
✓ Branch 5 (113→114) taken 27 times.
128 for(VecConfigNode::const_iterator it(vecBaseDaemon.begin()); it != vecBaseDaemon.end() && !foundDaemonName; ++it){
126
4/4
✓ Branch 0 (12→13) taken 37 times.
✓ Branch 2 (15→16) taken 37 times.
✓ Branch 4 (19→20) taken 20 times.
✓ Branch 5 (19→99) taken 17 times.
74 if(daemon_loadString(**it, "name") == daemonName){
127
5/5
✓ Branch 0 (20→21) taken 20 times.
✓ Branch 2 (21→22) taken 20 times.
✓ Branch 4 (22→23) taken 20 times.
✓ Branch 6 (23→24) taken 20 times.
✓ Branch 8 (24→25) taken 20 times.
20 log.getLogInfo() << "BaseDaemon::daemon_read_configNode : configuration of current Daemon '"<<daemonName<<"' found" << std::endl;
128 //Set logger
129
4/4
✓ Branch 0 (25→26) taken 20 times.
✓ Branch 2 (28→29) taken 20 times.
✓ Branch 4 (29→30) taken 20 times.
✓ Branch 6 (30→31) taken 20 times.
40 log.setFileName(daemon_loadString(**it, "log_file"));
130
7/7
✓ Branch 0 (34→35) taken 20 times.
✓ Branch 2 (35→36) taken 20 times.
✓ Branch 4 (38→39) taken 20 times.
✓ Branch 6 (39→40) taken 20 times.
✓ Branch 8 (40→41) taken 20 times.
✓ Branch 10 (41→42) taken 20 times.
✓ Branch 12 (42→43) taken 20 times.
40 log.setLogLevel(phoenix_strToLogLevel(phoenix_get_string(**it, "log_level", "WARNING").eraseFirstLastChar("\"'\t\n ")));
131
2/3
✓ Branch 0 (48→49) taken 20 times.
✗ Branch 2 (49→50) not taken.
✓ Branch 3 (49→77) taken 20 times.
20 if(!log.open()){
132 if(log.getMode() == PLog::FILE_ONLY || log.getMode() == PLog::FILE_CAPTURE_STDOUT_STDERR){
133 log.criticalAndThrow<Phoenix::ConfigException>("BaseDaemon::daemon_read_configNode", "cannot open log file'"+log.getFileName()+"' of current daemon '"+daemonName+"' but log mode requires it.");
134 }else{
135 std::cerr << "BaseDaemon::daemon_read_configNode : cannot open log file '"<<log.getFileName()<<"' of current daemon '"<<daemonName<<"'"<<std::endl;
136 }
137 }
138
1/1
✓ Branch 0 (79→80) taken 20 times.
20 set_daemon_config_from_node(daemonConfig, log, mapTimeout, **it, true);
139 //Extra-parameters of current daemon
140
2/2
✓ Branch 0 (82→83) taken 20 times.
✓ Branch 2 (83→84) taken 20 times.
20 extraConfigParam = (*it)->getChild("extra_parameter");
141
12/12
✓ Branch 0 (85→86) taken 20 times.
✓ Branch 2 (86→87) taken 20 times.
✓ Branch 4 (87→88) taken 20 times.
✓ Branch 6 (88→89) taken 20 times.
✓ Branch 8 (89→90) taken 20 times.
✓ Branch 10 (90→91) taken 20 times.
✓ Branch 12 (91→92) taken 20 times.
✓ Branch 14 (92→93) taken 20 times.
✓ Branch 16 (93→94) taken 20 times.
✓ Branch 18 (94→95) taken 20 times.
✓ Branch 20 (95→96) taken 20 times.
✓ Branch 22 (96→97) taken 20 times.
20 log.getLogInfo() << "BaseDaemon::daemon_read_configNode : Daemon '"<<daemonName<<"' on host '"<<daemonConfig.getHostName()<<"' and port "<<std::to_string(daemonConfig.getReceivingPort())<<" is configured !"<<std::endl;
142 20 foundDaemonName = true;
143 }
144 }
145
2/2
✓ Branch 0 (114→115) taken 7 times.
✓ Branch 1 (114→123) taken 20 times.
27 if(!foundDaemonName){
146
3/4
✓ Branch 0 (115→116) taken 7 times.
✓ Branch 2 (116→117) taken 7 times.
✓ Branch 4 (117→118) taken 7 times.
✗ Branch 6 (118→119) not taken.
28 log.criticalAndThrow<Phoenix::ConfigException>("BaseDaemon::daemon_read_configNode", "current daemon '"+daemonName+"' not found!");
147 }
148 //Make second pass to load the other daemons, checking for duplicates definitions
149 20 std::map<PString, PLocation> daemon_config_location;
150
2/2
✓ Branch 0 (211→125) taken 41 times.
✓ Branch 1 (211→212) taken 19 times.
120 for(VecConfigNode::const_iterator it(vecBaseDaemon.begin()); it != vecBaseDaemon.end(); ++it){
151
1/1
✓ Branch 0 (125→126) taken 41 times.
41 DaemonConfig config;
152
3/3
✓ Branch 0 (126→127) taken 41 times.
✓ Branch 2 (129→130) taken 41 times.
✓ Branch 4 (130→131) taken 41 times.
82 config.setName(daemon_loadString(**it, "name"));
153 //Check for duplicates
154
2/2
✓ Branch 0 (133→134) taken 41 times.
✓ Branch 2 (134→135) taken 41 times.
41 std::map<PString, PLocation>::iterator daemon_config_location_iter = daemon_config_location.find(config.getName());
155
2/2
✓ Branch 0 (137→138) taken 1 times.
✓ Branch 1 (137→168) taken 40 times.
41 if(daemon_config_location_iter != daemon_config_location.end()){
156
1/1
✓ Branch 0 (138→139) taken 1 times.
1 std::stringstream errorStringStream;
157 errorStringStream << "BaseDaemon::daemon_read_configNode : Current daemon '" << daemonName << "' defined twice,"
158
5/5
✓ Branch 0 (139→140) taken 1 times.
✓ Branch 2 (140→141) taken 1 times.
✓ Branch 4 (141→142) taken 1 times.
✓ Branch 6 (142→143) taken 1 times.
✓ Branch 8 (144→145) taken 1 times.
1 << " first at " << daemon_config_location_iter->second
159
3/3
✓ Branch 0 (145→146) taken 1 times.
✓ Branch 2 (148→149) taken 1 times.
✓ Branch 4 (149→150) taken 1 times.
2 << " then at " << (*it)->getLocation();
160
2/3
✓ Branch 0 (151→152) taken 1 times.
✓ Branch 2 (153→154) taken 1 times.
✗ Branch 3 (153→160) not taken.
1 if(config.getName() == daemonName){
161
2/3
✓ Branch 0 (154→155) taken 1 times.
✓ Branch 2 (155→156) taken 1 times.
✗ Branch 4 (156→157) not taken.
3 log.criticalAndThrow<Phoenix::ConfigException>("BaseDaemon::daemon_read_configNode", errorStringStream.str());
162 }else{
163 log.getLogWarning() << errorStringStream.str() << std::endl;
164 }
165 1 }else{
166
4/4
✓ Branch 0 (170→171) taken 40 times.
✓ Branch 2 (171→172) taken 40 times.
✓ Branch 4 (172→173) taken 40 times.
✓ Branch 6 (173→174) taken 40 times.
40 daemon_config_location[config.getName()] = (*it)->getLocation();
167 }
168
3/3
✓ Branch 0 (176→177) taken 40 times.
✓ Branch 2 (178→179) taken 20 times.
✓ Branch 3 (178→200) taken 20 times.
40 if(config.getName() != daemonName){
169
1/1
✓ Branch 0 (181→182) taken 20 times.
20 set_daemon_config_from_node(config, log, mapTimeout, **it, false);
170
3/3
✓ Branch 0 (182→183) taken 20 times.
✓ Branch 2 (183→184) taken 20 times.
✓ Branch 4 (184→185) taken 20 times.
20 mapDaemon[config.getName()] = config;
171
13/13
✓ Branch 0 (185→186) taken 20 times.
✓ Branch 2 (186→187) taken 20 times.
✓ Branch 4 (187→188) taken 20 times.
✓ Branch 6 (188→189) taken 20 times.
✓ Branch 8 (189→190) taken 20 times.
✓ Branch 10 (190→191) taken 20 times.
✓ Branch 12 (191→192) taken 20 times.
✓ Branch 14 (192→193) taken 20 times.
✓ Branch 16 (193→194) taken 20 times.
✓ Branch 18 (194→195) taken 20 times.
✓ Branch 20 (195→196) taken 20 times.
✓ Branch 22 (196→197) taken 20 times.
✓ Branch 24 (197→198) taken 20 times.
20 log.getLogInfo() << "BaseDaemon::daemon_read_configNode : contact daemon '"<<config.getName()<<"' on host '"<<config.getHostName()<<"' and port "<<std::to_string(config.getReceivingPort())<<" loaded!"<<std::endl;
172 }
173 41 }
174 20 }
175
176