GCC Code Coverage Report


Directory: ./
File: src/Daemon/BaseDaemon.cpp
Date: 2025-03-27 14:50:11
Exec Total Coverage
Lines: 104 143 72.7%
Branches: 182 325 56.0%

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_toml.h"
8 #include "parser_yml.h"
9 #include "BaseDaemon.h"
10 #include "PTimer.h"
11
12 ///Load a string value
13 /** @param dico : DicoValue to be used
14 * @param attributeName : name of the attribute to read
15 * @return corresponding string
16 */
17 46 PString daemon_loadString(const DicoValue & dico, const PString & attributeName){
18
3/3
✓ Branch 2 taken 46 times.
✓ Branch 5 taken 46 times.
✓ Branch 8 taken 46 times.
46 return phoenix_load_value_from_config<PString>(dico, attributeName, "unnamed_daemon").eraseFirstLastChar("\"'\t\n ");
19 }
20
21 ///Default constructor of BaseDaemon
22 14 BaseDaemon::BaseDaemon()
23
3/3
✓ Branch 3 taken 14 times.
✓ Branch 6 taken 14 times.
✓ Branch 9 taken 14 times.
14 :p_optionParser(true, __PROGRAM_VERSION__)
24 {
25
1/1
✓ Branch 1 taken 14 times.
14 initialisationBaseDaemon();
26 14 }
27
28 ///Destructor of BaseDaemon
29 28 BaseDaemon::~BaseDaemon(){
30 28 clearCallableMethod();
31 }
32
33 ///Parse arguments given to the BaseDaemon with command line
34 /** @param argc : number of arguments given to the program
35 * @param argv : list of arguments given to the program
36 * @return true on success, false otherwise
37 */
38 bool BaseDaemon::parseArgument(int argc, char** argv){
39 p_optionParser.parseArgument(argc, argv);
40 const OptionMode & defaultMode = p_optionParser.getDefaultMode();
41 PPath configurationFile;
42 defaultMode.getValue(configurationFile, "daemonconfig");
43 PString daemonName;
44 defaultMode.getValue(daemonName, "daemonname");
45 return load(configurationFile, daemonName);
46 }
47
48 ///Load the Toml configuration which define all BaseDaemons of the Swarm
49 /** @param fileName : name of the configuration file of all the BaseDaemons of the Swarm in toml format
50 * @param daemonName : name of the current BaseDaemon in the given file
51 * @return true on success, false otherwise
52 */
53 12 bool BaseDaemon::load(const PPath & fileName, const PString & daemonName){
54
1/1
✓ Branch 1 taken 12 times.
12 DicoValue dico;
55
3/3
✓ Branch 1 taken 12 times.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 4 times.
12 if(fileName.getExtension() == "toml"){
56
3/3
✓ Branch 1 taken 8 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 7 times.
8 if(!parser_toml(dico, fileName)){
57
4/4
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 10 taken 1 times.
1 std::cerr << "BaseDaemon::load : cannot load toml file '"<<fileName<<"'" << std::endl;
58 1 return false;
59 }
60 }
61
2/3
✓ Branch 1 taken 4 times.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
4 else if(fileName.getExtension() == "yml"){
62
3/3
✓ Branch 1 taken 4 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 3 times.
4 if(!parser_yml(dico, fileName)){
63
4/4
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 10 taken 1 times.
1 std::cerr << "BaseDaemon::load : cannot load yml file '"<<fileName<<"'" << std::endl;
64 1 return false;
65 }
66 }
67 else{
68 std::cerr << "BaseDaemon::load : unknown extension of file '"<<fileName<<"'" << std::endl;
69 return false;
70 }
71
2/2
✓ Branch 1 taken 10 times.
✓ Branch 4 taken 10 times.
10 const DicoValue * mapBaseDaemon = dico.getMap("daemon");
72
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(mapBaseDaemon == NULL){
73 std::cerr << "BaseDaemon::load : no 'daemon' defined in file '"<<fileName<<"'" << std::endl;
74 return false;
75 }
76 10 bool b(true);
77
1/1
✓ Branch 1 taken 10 times.
10 const VecDicoValue & vecBaseDaemon = mapBaseDaemon->getVecChild();
78
5/6
✓ Branch 4 taken 19 times.
✓ Branch 5 taken 10 times.
✓ Branch 6 taken 19 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 19 times.
✓ Branch 9 taken 10 times.
29 for(VecDicoValue::const_iterator it(vecBaseDaemon.begin()); it != vecBaseDaemon.end() && b; ++it){
79
1/1
✓ Branch 1 taken 19 times.
19 DaemonConfig config;
80
3/3
✓ Branch 1 taken 19 times.
✓ Branch 5 taken 19 times.
✓ Branch 8 taken 19 times.
19 config.setName(daemon_loadString(*it, "name"));
81
82
3/3
✓ Branch 1 taken 19 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 11 times.
19 if(daemonName == config.getName()){ //is this is the configuration of the current BaseDaemon
83 //We can get the log file
84
4/4
✓ Branch 1 taken 8 times.
✓ Branch 5 taken 8 times.
✓ Branch 8 taken 8 times.
✓ Branch 11 taken 8 times.
8 p_log.setFileName(daemon_loadString(*it, "log_file"));
85
7/7
✓ Branch 1 taken 8 times.
✓ Branch 4 taken 8 times.
✓ Branch 8 taken 8 times.
✓ Branch 11 taken 8 times.
✓ Branch 14 taken 8 times.
✓ Branch 17 taken 8 times.
✓ Branch 20 taken 8 times.
8 p_log.setLogLevel(phoenix_strToLogLevel(phoenix_load_value_from_config<PString>(*it, "log_level", "WARNING").eraseFirstLastChar("\"'\t\n ")));
86
2/3
✓ Branch 1 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
8 if(!p_log.open()){
87 std::cerr << "BaseDaemon::load : cannot open log file '"<<p_log.getFileName()<<"' of daemon '"<<daemonName<<"'" << std::endl;
88 return false;
89 }
90
5/5
✓ Branch 1 taken 8 times.
✓ Branch 4 taken 8 times.
✓ Branch 7 taken 8 times.
✓ Branch 10 taken 8 times.
✓ Branch 13 taken 8 times.
8 p_log.getLogInfo() << "BaseDaemon::load : configuration of current Daemon '"<<daemonName<<"' found" << std::endl;
91 }
92
3/3
✓ Branch 1 taken 19 times.
✓ Branch 5 taken 19 times.
✓ Branch 8 taken 19 times.
19 config.setDescription(daemon_loadString(*it, "description"));
93
7/7
✓ Branch 2 taken 19 times.
✓ Branch 5 taken 19 times.
✓ Branch 9 taken 19 times.
✓ Branch 12 taken 19 times.
✓ Branch 15 taken 19 times.
✓ Branch 18 taken 19 times.
✓ Branch 21 taken 19 times.
19 config.setHostName(PString(phoenix_load_value_from_config<std::string>(*it, "hostname", "localhost")).eraseFirstLastChar("\"'\t\n "));
94
3/3
✓ Branch 1 taken 19 times.
✓ Branch 5 taken 19 times.
✓ Branch 8 taken 19 times.
19 config.setRecievingPort(phoenix_load_value_from_config<size_t>(*it, "recieving_port", -1lu));
95
4/4
✓ Branch 1 taken 19 times.
✓ Branch 4 taken 19 times.
✓ Branch 8 taken 19 times.
✓ Branch 11 taken 19 times.
19 config.getLatency().setNbMaxLatency(phoenix_load_value_from_config<size_t>(*it, "nb_latencies_per_daemon", 1000lu));
96
5/5
✓ Branch 1 taken 19 times.
✓ Branch 5 taken 19 times.
✓ Branch 8 taken 19 times.
✓ Branch 11 taken 19 times.
✓ Branch 14 taken 19 times.
19 config.getMapTimeout()[config.getName()] = phoenix_load_value_from_config<size_t>(*it, "daemon_required_response_timeout", 1000lu);
97 //Add the timeout of current config to global dameon config
98
6/6
✓ Branch 1 taken 19 times.
✓ Branch 4 taken 19 times.
✓ Branch 7 taken 19 times.
✓ Branch 10 taken 19 times.
✓ Branch 13 taken 19 times.
✓ Branch 16 taken 19 times.
19 p_config.getMapTimeout()[config.getName()] = config.getMapTimeout()[config.getName()];
99
2/3
✓ Branch 1 taken 19 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 19 times.
19 if(config.getRecievingPort() >= 65536lu){
100 std::cerr << "BaseDaemon::load : undefined 'receiving_port' of BaseDaemon '"<<config.getName()<<"'" << std::endl;
101 b = false;
102 }
103
3/3
✓ Branch 1 taken 19 times.
✓ Branch 4 taken 19 times.
✓ Branch 7 taken 19 times.
19 p_mapDaemon[config.getName()] = config;
104
3/3
✓ Branch 1 taken 19 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 11 times.
19 if(daemonName == config.getName()){
105
1/1
✓ Branch 1 taken 8 times.
8 p_config = config;
106
10/10
✓ Branch 1 taken 8 times.
✓ Branch 4 taken 8 times.
✓ Branch 7 taken 8 times.
✓ Branch 10 taken 8 times.
✓ Branch 13 taken 8 times.
✓ Branch 16 taken 8 times.
✓ Branch 19 taken 8 times.
✓ Branch 22 taken 8 times.
✓ Branch 25 taken 8 times.
✓ Branch 28 taken 8 times.
8 p_log.getLogInfo() << "BaseDaemon::load : set configuration of current Daemon '"<<daemonName<<"' on host '"<<config.getHostName()<<"' and port " << config.getRecievingPort() << std::endl;
107 }
108
1/2
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
19 }
109
3/3
✓ Branch 1 taken 10 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 8 times.
10 if(!p_log.isOpen()){
110
4/4
✓ Branch 1 taken 2 times.
✓ Branch 4 taken 2 times.
✓ Branch 7 taken 2 times.
✓ Branch 10 taken 2 times.
2 std::cerr << "BaseDaemon::load : current BaseDaemon '"<<daemonName<<"' has no log file" << std::endl;
111 2 b = false;
112 }
113
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 times.
10 if(b){
114
5/5
✓ Branch 1 taken 8 times.
✓ Branch 4 taken 8 times.
✓ Branch 7 taken 8 times.
✓ Branch 10 taken 8 times.
✓ Branch 13 taken 8 times.
8 p_log.getLogInfo() << "BaseDaemon::load : loading of configuration '"<<fileName<<"' successfull" << std::endl;
115 }else{
116
4/4
✓ Branch 1 taken 2 times.
✓ Branch 4 taken 2 times.
✓ Branch 7 taken 2 times.
✓ Branch 10 taken 2 times.
2 std::cerr << "BaseDaemon::load : error when loading of configuration '"<<fileName<<"'" << std::endl;
117 }
118 10 return b;
119 12 }
120
121 ///Call an added callable method by name
122 /** @param[out] result : result of the call
123 * @param name : name of the method
124 * @param parameter : parameters of the call
125 * @return true on success, false otherwise
126 */
127 1 bool BaseDaemon::callMethod(Data & result, const PString & name, const Data & parameter){
128
1/1
✓ Branch 1 taken 1 times.
1 std::map<PString, AbstractFunction*>::iterator it(p_mapCallableMethod.find(name));
129
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if(it == p_mapCallableMethod.end()){
130 getLog().getLogError() << "BaseDaemon::callMethod : function '"<<name<<"' not found" << std::endl;
131 return false;
132 }
133
2/2
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
1 return p_mapCallableMethod[name]->call(p_log, result, parameter);
134 }
135
136 ///Clear the map of callable methods
137 14 void BaseDaemon::clearCallableMethod(){
138
2/2
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 14 times.
16 for(std::map<PString, AbstractFunction*>::iterator it(p_mapCallableMethod.begin()); it != p_mapCallableMethod.end(); ++it){
139
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 delete it->second;
140 }
141 14 p_mapCallableMethod.clear();
142 14 }
143
144 ///Stops the BaseDaemon
145 8 void BaseDaemon::stop(){
146 8 p_log.getLogInfo() << "Stopping Daemon '"<<p_config.getName()<<"' at '"<<p_config.getHostName()<<"'" << std::endl;
147 8 p_isRun = false;
148 8 }
149
150 ///Return the OptionParser of the current BaseDaemon
151 /** @return OptionParser of the current BaseDaemon
152 */
153 OptionParser & BaseDaemon::getOptionParser(){
154 return p_optionParser;
155 }
156
157 ///Get the log of the current BaseDaemon
158 /** @return log of the current BaseDaemon
159 */
160 35 PLog & BaseDaemon::getLog(){
161 35 return p_log;
162 }
163
164 ///Say if a neighbour Daemon does exist
165 /** @param name : name of the Daemon to be searched
166 * @return true if the Daemon does exist, false otherwise
167 */
168 2 bool BaseDaemon::isDaemonExist(const PString & name) const{
169
1/1
✓ Branch 1 taken 2 times.
2 MapDaemonConfig::const_iterator it(p_mapDaemon.find(name));
170 2 return it != p_mapDaemon.end();
171 }
172
173 ///Add a message to confirm
174 /** @param message : message to be added
175 */
176 3 void BaseDaemon::addMessageToConfirm(const Message & message){
177
2/2
✓ Branch 2 taken 3 times.
✓ Branch 5 taken 3 times.
3 p_mapMessageToBeConfirmed[message.getId()] = message;
178 3 }
179
180 ///Get a message to confirm by id if it exists
181 /** @param[out] message : message which has the id id
182 * @param id : id of the message to be searched
183 * @return true if the message with id id does exist, false otherwise
184 */
185 bool BaseDaemon::getMessageToConfirm(Message & message, size_t id) const{
186 std::map<size_t, Message>::const_iterator it(p_mapMessageToBeConfirmed.find(id));
187 if(it != p_mapMessageToBeConfirmed.end()){
188 message = it->second;
189 return true;
190 }
191 return false;
192 }
193
194 ///Removed confirmed message
195 /** @param id : id of the message to be removed
196 * @param currentTime : time when the confirmation was recieved
197 */
198 void BaseDaemon::removeConfirmedMessage(size_t id, time_t currentTime){
199 std::map<size_t, Message>::const_iterator it(p_mapMessageToBeConfirmed.find(id));
200 if(it != p_mapMessageToBeConfirmed.end()){
201 getLog().getLogInfo() << "BaseDaemon::removeConfirmedMessage : remove confirmed transaction " << id << std::endl;
202 const Message & message = it->second;
203
204 DaemonLatency & latency = p_mapDaemon[message.getSender()].getLatency();
205 time_t ellapsedTime = currentTime - message.getSendTime();
206 if(latency.getVecLatency().size() < latency.getNbMaxLatency()){
207 latency.getVecLatency().push_back(ellapsedTime);
208 }
209
210 p_mapMessageToBeConfirmed.erase(it);
211 }else{
212 getLog().getLogError() << "BaseDaemon::removeConfirmedMessage : transaction " << id << " not found in p_mapMessageToBeConfirmed" << std::endl;
213 }
214 }
215
216 /// Check if a message has reached the timeout
217 /** @param currentTime : current time
218 */
219 12 void BaseDaemon::checkMesageTimeout(time_t currentTime){
220 12 std::vector<size_t> messagesToRemove;
221
2/2
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 12 times.
17 for (auto it = p_mapMessageToBeConfirmed.begin(); it != p_mapMessageToBeConfirmed.end(); ++it) {
222 5 const size_t & messageId = it->first;
223 5 const Message & message = it->second;
224
225
1/1
✓ Branch 1 taken 5 times.
5 time_t elapsedTime = currentTime - message.getSendTime();
226
3/3
✓ Branch 1 taken 5 times.
✓ Branch 4 taken 5 times.
✓ Branch 8 taken 5 times.
5 time_t timeout = p_config.getMapTimeout()[message.getVecRecver().front()];
227
228
5/5
✓ Branch 2 taken 5 times.
✓ Branch 6 taken 5 times.
✓ Branch 10 taken 5 times.
✓ Branch 13 taken 5 times.
✓ Branch 17 taken 5 times.
5 phoenix_assert(message.getVecRecver().size() != 0lu);
229
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
5 if (elapsedTime > timeout) {
230
1/1
✓ Branch 1 taken 1 times.
1 messagesToRemove.push_back(messageId);
231
9/9
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 10 taken 1 times.
✓ Branch 13 taken 1 times.
✓ Branch 16 taken 1 times.
✓ Branch 20 taken 1 times.
✓ Branch 23 taken 1 times.
✓ Branch 26 taken 1 times.
1 getLog().getLogWarning() << "BaseDaemon::checkMessageTimeout() : Timeout Reached for message " << messageId << " sent to " << message.getVecRecver().front() << ". Removing unconfirmed transaction" << std::endl;
232 }
233 }
234
2/2
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 12 times.
13 for (const size_t &messageId : messagesToRemove) {
235
1/1
✓ Branch 1 taken 1 times.
1 p_mapMessageToBeConfirmed.erase(messageId);
236 }
237 12 }
238
239 ///Get current message id
240 /** @return current message id
241 */
242 3 size_t BaseDaemon::getMessageId(){
243 3 ++p_messageId;
244 3 return p_messageId;
245 }
246
247 ///Process given data with the proper method
248 /** @param data : data to be processed
249 * @return true on success, false otherwise
250 */
251 4 bool BaseDaemon::processData(const Data & data){
252
2/2
✓ Branch 1 taken 4 times.
✓ Branch 4 taken 4 times.
4 PString prototype(data.getType());
253
1/1
✓ Branch 1 taken 4 times.
4 std::map<PString, AbstractDataFunction*>::iterator it(p_mapDataFunction.find(prototype));
254
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 if(it == p_mapDataFunction.end()){
255 getLog().getLogError() << "BaseDaemon::processData : function to process data '"<<prototype<<"' not found" << std::endl;
256 return false;
257 }
258
6/6
✓ Branch 1 taken 4 times.
✓ Branch 4 taken 4 times.
✓ Branch 7 taken 4 times.
✓ Branch 10 taken 4 times.
✓ Branch 13 taken 4 times.
✓ Branch 16 taken 4 times.
4 getLog().getLogDebug() << "BaseDaemon::processData : process data '"<<prototype<<"'" << std::endl;
259
1/1
✓ Branch 2 taken 4 times.
4 bool b = it->second->call(p_log, data);
260 4 return b;
261 4 }
262
263 ///Initialisation function of the class BaseDaemon
264 14 void BaseDaemon::initialisationBaseDaemon(){
265
1/1
✓ Branch 2 taken 14 times.
14 p_optionParser.setExampleLongOption("phoenix_daemon --daemonconfig=daemon_config.toml --daemonname=main");
266
1/1
✓ Branch 2 taken 14 times.
14 p_optionParser.setExampleShortOption("phoenix_daemon -c daemon_config.toml -n main");
267
3/3
✓ Branch 2 taken 14 times.
✓ Branch 5 taken 14 times.
✓ Branch 8 taken 14 times.
14 p_optionParser.addOption("daemonconfig", "c", OptionType::FILENAME, true, "Toml configuration file which define all Daemons of the swarm");
268
3/3
✓ Branch 2 taken 14 times.
✓ Branch 5 taken 14 times.
✓ Branch 8 taken 14 times.
14 p_optionParser.addOption("daemonname", "n", OptionType::STRING, true, "Name of the current Daemon of the swarm configuration defined with --daemonconfig");
269 14 p_isRun = false;
270 14 p_messageId = 0lu;
271 14 }
272
273
274
275
276
277