GCC Code Coverage Report


Directory: ./
File: src/Daemon/BaseDaemon.cpp
Date: 2025-03-14 12:18:05
Exec Total Coverage
Lines: 77 119 64.7%
Branches: 131 269 48.7%

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