GCC Code Coverage Report


Directory: ./
File: src/Daemon/BaseDaemon.cpp
Date: 2026-01-15 15:35:36
Exec Total Coverage
Lines: 240 261 92.0%
Functions: 32 35 91.4%
Branches: 275 329 83.6%

Line Branch Exec Source
1 /***************************************
2 Auteur : Pierre Aubert
3 Mail : pierre.aubert@lapp.in2p3.fr
4 Licence : CeCILL-C
5 ****************************************/
6
7 #include <cmath> //for std::nan
8 #include "BaseDaemon.h"
9 #include "PTimer.h"
10
11 ///Default constructor of BaseDaemon
12 46 BaseDaemon::BaseDaemon()
13
3/3
✓ Branch 0 (5→6) taken 46 times.
✓ Branch 2 (6→7) taken 46 times.
✓ Branch 4 (7→8) taken 46 times.
46 :p_optionParser(true, __PROGRAM_VERSION__)
14 {
15
1/1
✓ Branch 0 (12→13) taken 46 times.
46 initialisationBaseDaemon();
16 46 }
17
18 ///Destructor of BaseDaemon
19 46 BaseDaemon::~BaseDaemon(){
20 46 clearCallableMethod();
21 46 }
22
23 ///Parse arguments given to the BaseDaemon with command line
24 /** @param argc : number of arguments given to the program
25 * @param argv : list of arguments given to the program
26 * @return true on success, false otherwise
27 */
28 4 bool BaseDaemon::parseArgument(int argc, char** argv){
29
1/1
✓ Branch 0 (2→3) taken 4 times.
4 p_optionParser.parseArgument(argc, argv);
30
1/1
✓ Branch 0 (3→4) taken 4 times.
4 const OptionMode & defaultMode = p_optionParser.getDefaultMode();
31
1/1
✓ Branch 0 (4→5) taken 4 times.
4 PPath configurationFile;
32
2/2
✓ Branch 0 (5→6) taken 4 times.
✓ Branch 2 (6→7) taken 4 times.
4 defaultMode.getValue(configurationFile, "daemonconfig");
33
1/1
✓ Branch 0 (8→9) taken 4 times.
4 PString daemonName;
34
2/2
✓ Branch 0 (9→10) taken 4 times.
✓ Branch 2 (10→11) taken 4 times.
4 defaultMode.getValue(daemonName, "daemonname");
35
2/2
✓ Branch 0 (12→13) taken 4 times.
✓ Branch 2 (13→14) taken 4 times.
4 p_isFullMock = defaultMode.isOptionExist("mock");
36
2/2
✓ Branch 0 (15→16) taken 4 times.
✓ Branch 2 (16→17) taken 4 times.
4 p_isFullMockRecord = defaultMode.isOptionExist("mockrecord");
37
1/1
✓ Branch 0 (18→19) taken 4 times.
8 return load(configurationFile, daemonName);
38 4 }
39
40 ///Load configuration form a node of ConfigNode
41 /** @param[out] dico : loaded configuration
42 * @param daemonName : name of the current Daemon in the configuration
43 * @return true on success, false otherwise
44 */
45 31 void BaseDaemon::loadConfigFromNode(const ConfigNode & dico, const PString & daemonName) {
46
2/2
✓ Branch 0 (2→3) taken 31 times.
✓ Branch 2 (3→4) taken 31 times.
31 const ConfigNode * mapMainConfig = dico.getChild("swarm");
47
2/2
✓ Branch 0 (5→6) taken 14 times.
✓ Branch 1 (5→27) taken 17 times.
31 if(mapMainConfig != nullptr){
48
2/2
✓ Branch 0 (6→7) taken 14 times.
✓ Branch 2 (7→8) taken 14 times.
14 p_mainConfig.recvTimeoutMs = phoenix_get_value<int>(*mapMainConfig, "recv_timeout_ms", -1);
49
2/2
✓ Branch 0 (9→10) taken 14 times.
✓ Branch 2 (10→11) taken 14 times.
14 p_mainConfig.sendTimeoutMs = phoenix_get_value<int>(*mapMainConfig, "send_timeout_ms", -1);
50
4/4
✓ Branch 0 (12→13) taken 14 times.
✓ Branch 2 (13→14) taken 14 times.
✓ Branch 4 (14→15) taken 14 times.
✓ Branch 6 (15→16) taken 14 times.
14 p_mainConfig.recvFlag = daemonRecvFlagFromString(phoenix_get_string(*mapMainConfig, "recv_flag", "NON_BLOCK"));
51
4/4
✓ Branch 0 (19→20) taken 14 times.
✓ Branch 2 (20→21) taken 14 times.
✓ Branch 4 (21→22) taken 14 times.
✓ Branch 6 (22→23) taken 14 times.
14 p_mainConfig.sendFlag = daemonSendFlagFromString(phoenix_get_string(*mapMainConfig, "send_flag", "NON_BLOCK"));
52 }
53 31 std::map<PString, time_t> mapTimeout;
54 31 const ConfigNode * extraConfigParam = nullptr;
55
1/1
✓ Branch 0 (28→29) taken 19 times.
31 daemon_read_configNode(p_config, p_mapDaemon, p_log, mapTimeout, extraConfigParam, dico, daemonName);
56
57
2/2
✓ Branch 0 (29→30) taken 19 times.
✓ Branch 2 (30→31) taken 19 times.
19 const ConfigNode * mapStatDaemon = dico.getChild("statistics");
58
2/2
✓ Branch 0 (32→33) taken 4 times.
✓ Branch 1 (32→39) taken 15 times.
19 if(mapStatDaemon != nullptr){
59
3/3
✓ Branch 0 (33→34) taken 4 times.
✓ Branch 2 (34→35) taken 4 times.
✓ Branch 4 (35→36) taken 4 times.
4 p_config.setStatDaemonName(daemon_loadString(*mapStatDaemon, "stat_daemon_name"));
60 }
61
1/1
✓ Branch 0 (39→40) taken 19 times.
19 p_config.setMapTimeout(mapTimeout);
62
4/4
✓ Branch 0 (40→41) taken 19 times.
✓ Branch 2 (41→42) taken 19 times.
✓ Branch 4 (42→43) taken 4 times.
✓ Branch 5 (42→52) taken 15 times.
19 if(p_config.getStatDaemonName() != ""){
63
3/4
✓ Branch 0 (43→44) taken 4 times.
✓ Branch 2 (44→45) taken 4 times.
✗ Branch 4 (45→46) not taken.
✓ Branch 5 (45→52) taken 4 times.
4 if(!isDaemonExist(p_config.getStatDaemonName())){
64 p_log.getLogError() << "BaseDaemon::loadConfigFromNode : stat daemon '"<<p_config.getStatDaemonName()<<"' not found in configuration" << std::endl;
65 }
66 }
67
68
3/3
✓ Branch 0 (52→53) taken 19 times.
✓ Branch 2 (53→54) taken 19 times.
✓ Branch 4 (54→55) taken 19 times.
19 p_log.getLogInfo() << "BaseDaemon::loadConfigFromNode : loading configuration successful" << std::endl;
69
3/3
✓ Branch 0 (55→56) taken 19 times.
✓ Branch 2 (56→57) taken 19 times.
✓ Branch 4 (57→58) taken 19 times.
19 p_log.getLogInfo() << "BaseDaemon::loadConfigFromNode : ready to call addCallMethod to subscribe on received data" << std::endl;
70
1/1
✓ Branch 0 (58→59) taken 19 times.
19 addCallMethod();
71 31 }
72
73 ///Load the Json configuration which define all BaseDaemons of the Swarm
74 /** @param configFileContent : name of the configuration file of all the BaseDaemons of the Swarm in json format
75 * @param daemonName : name of the current BaseDaemon in the given file
76 * @param format : format of the configuration file
77 * @return true on success, false otherwise
78 */
79 9 bool BaseDaemon::load(const PString & configFileContent, const PString & daemonName, ConfigFormat::ConfigFormat format){
80
1/1
✓ Branch 0 (2→3) taken 9 times.
9 ConfigNode dico;
81
1/1
✓ Branch 0 (3→4) taken 9 times.
9 daemon_load_config(p_log, dico, configFileContent, format);
82
1/1
✓ Branch 0 (4→5) taken 3 times.
9 loadConfigFromNode(dico, daemonName);
83 3 return true;
84 9 }
85
86 ///Load the Toml configuration which define all BaseDaemons of the Swarm
87 /** @param fileName : name of the configuration file of all the BaseDaemons of the Swarm in toml format
88 * @param daemonName : name of the current BaseDaemon in the given file
89 * @return true on success, false otherwise
90 */
91 27 bool BaseDaemon::load(const PPath & fileName, const PString & daemonName){
92
1/1
✓ Branch 0 (2→3) taken 27 times.
27 ConfigNode dico;
93
1/1
✓ Branch 0 (3→4) taken 22 times.
27 daemon_load_config(p_log, dico, fileName);
94
1/1
✓ Branch 0 (4→5) taken 16 times.
22 loadConfigFromNode(dico, daemonName);
95 16 return true;
96 27 }
97
98 ///Extra call on load for the current Daemon
99 /** @param config : configuration for the current Daemon
100 * @return true on success, false otherwise
101 */
102 bool BaseDaemon::extraLoad(const ConfigNode * config){
103 return true;
104 }
105
106 ///Do the addCallableMethod here
107 16 void BaseDaemon::addCallMethod(){
108
1/2
✓ Branch 0 (3→4) taken 16 times.
✗ Branch 1 (3→7) not taken.
16 if(p_log.isOpen()){
109 16 p_log.getLogWarning() << "BaseDaemon::addCallMethod : no redefined addCallMethod " << std::endl;
110 }else{
111 std::cerr << "BaseDaemon::addCallMethod : no redefined addCallMethod (and no log file so we use std::cerr)" << std::endl;
112 }
113 16 }
114
115 ///Call an added callable method by name
116 /** @param[out] result : result of the call
117 * @param name : name of the method
118 * @param parameter : parameters of the call
119 * @return true on success, false otherwise
120 */
121 2 bool BaseDaemon::callMethod(Data & result, const PString & name, const Data & parameter){
122
1/1
✓ Branch 0 (2→3) taken 2 times.
2 std::map<PString, AbstractFunction*>::iterator it(p_mapCallableMethod.find(name));
123
1/2
✗ Branch 0 (5→6) not taken.
✓ Branch 1 (5→13) taken 2 times.
2 if(it == p_mapCallableMethod.end()){
124 getLog().getLogError() << "BaseDaemon::callMethod : function '"<<name<<"' not found" << std::endl;
125 return false;
126 }
127
2/2
✓ Branch 0 (13→14) taken 2 times.
✓ Branch 2 (14→15) taken 2 times.
2 return p_mapCallableMethod[name]->call(p_log, result, parameter);
128 }
129
130 ///Clear the map of callable methods
131 46 void BaseDaemon::clearCallableMethod(){
132
2/2
✓ Branch 0 (9→3) taken 2 times.
✓ Branch 1 (9→10) taken 46 times.
48 for(std::map<PString, AbstractFunction*>::iterator it(p_mapCallableMethod.begin()); it != p_mapCallableMethod.end(); ++it){
133
1/2
✓ Branch 0 (4→5) taken 2 times.
✗ Branch 1 (4→6) not taken.
2 delete it->second;
134 }
135 46 p_mapCallableMethod.clear();
136 46 }
137
138 ///Stops the BaseDaemon
139 9 void BaseDaemon::stop(){
140 9 p_log.getLogInfo() << "Stopping Daemon '"<<p_config.getName()<<"' at '"<<p_config.getHostName()<<"'" << std::endl;
141 9 p_isRun = false;
142 9 }
143
144 ///Return the OptionParser of the current BaseDaemon
145 /** @return OptionParser of the current BaseDaemon
146 */
147 OptionParser & BaseDaemon::getOptionParser(){
148 return p_optionParser;
149 }
150
151 ///Get the log of the current BaseDaemon
152 /** @return log of the current BaseDaemon
153 */
154 144 PLog & BaseDaemon::getLog(){
155 144 return p_log;
156 }
157
158 ///Say if a neighbour Daemon does exist
159 /** @param name : name of the Daemon to be searched
160 * @return true if the Daemon does exist, false otherwise
161 */
162 11 bool BaseDaemon::isDaemonExist(const PString & name) const{
163
1/1
✓ Branch 0 (2→3) taken 11 times.
11 MapDaemonConfig::const_iterator it(p_mapDaemon.find(name));
164
2/2
✓ Branch 0 (5→6) taken 1 times.
✓ Branch 1 (5→10) taken 10 times.
11 if(it == p_mapDaemon.end()){
165 //Then if the stat daemon does not exist in the map, it may be the current daemon
166
2/3
✓ Branch 0 (6→7) taken 1 times.
✓ Branch 2 (8→9) taken 1 times.
✗ Branch 3 (8→10) not taken.
1 if(p_config.getName() == name){
167 1 return true;
168 }
169 }
170
1/2
✓ Branch 0 (12→13) taken 10 times.
✗ Branch 1 (12→14) not taken.
10 if(it != p_mapDaemon.end()){
171 10 return true;
172 }
173
174 return false;
175 }
176
177 ///Add a message to confirm
178 /** @param message : message to be added
179 */
180 12 void BaseDaemon::addMessageToConfirm(const Message & message){
181
3/3
✓ Branch 0 (2→3) taken 12 times.
✓ Branch 2 (3→4) taken 12 times.
✓ Branch 4 (4→5) taken 12 times.
12 p_mapMessageToBeConfirmed[message.getId()] = message;
182 12 }
183
184 ///Get a message to confirm by id if it exists
185 /** @param[out] message : message which has the id id
186 * @param id : id of the message to be searched
187 * @return true if the message with id id does exist, false otherwise
188 */
189 3 bool BaseDaemon::getMessageToConfirm(Message & message, size_t id) const{
190
1/1
✓ Branch 0 (2→3) taken 3 times.
3 std::map<size_t, Message>::const_iterator it(p_mapMessageToBeConfirmed.find(id));
191
2/2
✓ Branch 0 (5→6) taken 1 times.
✓ Branch 1 (5→9) taken 2 times.
3 if(it != p_mapMessageToBeConfirmed.end()){
192
1/1
✓ Branch 0 (7→8) taken 1 times.
1 message = it->second;
193 1 return true;
194 }
195 2 return false;
196 }
197
198 ///Process confirmed message
199 /** @param id : id of the message to be removed
200 * @param currentTime : time when the confirmation was received
201 */
202 8 void BaseDaemon::processConfirmedMessage(size_t id, time_t currentTime){
203
1/1
✓ Branch 0 (2→3) taken 8 times.
8 std::map<size_t, Message>::const_iterator it(p_mapMessageToBeConfirmed.find(id));
204
1/2
✓ Branch 0 (7→8) taken 8 times.
✗ Branch 1 (7→47) not taken.
8 if(it != p_mapMessageToBeConfirmed.end()){
205
5/5
✓ Branch 0 (8→9) taken 8 times.
✓ Branch 2 (9→10) taken 8 times.
✓ Branch 4 (10→11) taken 8 times.
✓ Branch 6 (11→12) taken 8 times.
✓ Branch 8 (12→13) taken 8 times.
8 getLog().getLogInfo() << "BaseDaemon::processConfirmedMessage : adding statistics for processed transaction " << id << std::endl;
206 8 const Message & message = it->second;
207
1/1
✓ Branch 0 (14→15) taken 8 times.
8 time_t ellapsedTime = currentTime - message.getSendTime();
208
3/3
✓ Branch 0 (15→16) taken 8 times.
✓ Branch 2 (40→18) taken 8 times.
✓ Branch 3 (40→41) taken 8 times.
24 for(const PString & receiver : message.getVecRecver()){
209
5/5
✓ Branch 0 (20→21) taken 8 times.
✓ Branch 2 (21→22) taken 8 times.
✓ Branch 4 (22→23) taken 8 times.
✓ Branch 6 (23→24) taken 8 times.
✓ Branch 8 (24→25) taken 8 times.
8 getLog().getLogDebug() << "BaseDaemon::processConfirmedMessage : add statistic for receiver : " << receiver << std::endl;
210
6/6
✓ Branch 0 (25→26) taken 8 times.
✓ Branch 2 (26→27) taken 8 times.
✓ Branch 4 (27→28) taken 8 times.
✓ Branch 6 (28→29) taken 8 times.
✓ Branch 8 (29→30) taken 8 times.
✓ Branch 10 (30→31) taken 8 times.
8 getCommunicationStat(receiver, message.getData().getType(), ellapsedTime, p_config.getStatNbBin(), p_config.getStatHistLowerBound(), p_config.getStatHistUpperBound());
211 }
212 // Remove the confirmed message
213
5/5
✓ Branch 0 (41→42) taken 8 times.
✓ Branch 2 (42→43) taken 8 times.
✓ Branch 4 (43→44) taken 8 times.
✓ Branch 6 (44→45) taken 8 times.
✓ Branch 8 (45→46) taken 8 times.
8 getLog().getLogInfo() << "BaseDaemon::removeConfirmedMessage : remove confirmed transaction " << id << std::endl;
214
1/1
✓ Branch 0 (46→53) taken 8 times.
8 p_mapMessageToBeConfirmed.erase(it);
215 }else{
216 getLog().getLogError() << "BaseDaemon::processConfirmedMessage : transaction " << id << " not found in p_mapMessageToBeConfirmed" << std::endl;
217 }
218 8 }
219
220 /// Check if a message has reached the timeout
221 /** @param currentTime : current time
222 */
223 298 void BaseDaemon::checkMessageTimeout(time_t currentTime){
224 298 std::vector<size_t> messagesToRemove;
225
2/2
✓ Branch 0 (74→4) taken 569 times.
✓ Branch 1 (74→75) taken 298 times.
867 for(auto it = p_mapMessageToBeConfirmed.begin(); it != p_mapMessageToBeConfirmed.end(); ++it){
226 569 const size_t & messageId = it->first;
227 569 const Message & message = it->second;
228
1/1
✓ Branch 0 (6→7) taken 569 times.
569 time_t elapsedTime = currentTime - message.getSendTime();
229
2/3
✓ Branch 0 (7→8) taken 569 times.
✗ Branch 2 (9→10) not taken.
✓ Branch 3 (9→17) taken 569 times.
569 if(message.getVecRecver().size() == 0lu){
230 getLog().getLogError() << "BaseDaemon::checkMessageTimeout() : message " << messageId << " has no receiver." << std::endl;
231 continue;
232 }
233
3/3
✓ Branch 0 (17→18) taken 569 times.
✓ Branch 2 (18→19) taken 569 times.
✓ Branch 4 (20→21) taken 569 times.
569 std::map<PString, time_t>::const_iterator timeoutIt = p_config.getMapTimeout().find(message.getVecRecver().front());
234
2/3
✓ Branch 0 (22→23) taken 569 times.
✗ Branch 2 (26→27) not taken.
✓ Branch 3 (26→38) taken 569 times.
569 if(timeoutIt == p_config.getMapTimeout().end()){
235 getLog().getLogError() << "BaseDaemon::checkMessageTimeout() : no timeout found for receiver '" << message.getVecRecver().front() << "' of message " << messageId << "." << std::endl;
236 continue;
237 }
238 569 time_t timeout = timeoutIt->second;
239
5/5
✓ Branch 0 (41→42) taken 569 times.
✓ Branch 2 (44→45) taken 569 times.
✓ Branch 4 (47→48) taken 569 times.
✓ Branch 6 (48→49) taken 569 times.
✓ Branch 8 (50→51) taken 569 times.
2845 phoenix_assert(message.getVecRecver().size() != 0lu);
240
2/2
✓ Branch 0 (57→58) taken 1 times.
✓ Branch 1 (57→69) taken 568 times.
569 if (elapsedTime > timeout) {
241
1/1
✓ Branch 0 (58→59) taken 1 times.
1 messagesToRemove.push_back(messageId);
242
9/9
✓ Branch 0 (59→60) taken 1 times.
✓ Branch 2 (60→61) taken 1 times.
✓ Branch 4 (61→62) taken 1 times.
✓ Branch 6 (62→63) taken 1 times.
✓ Branch 8 (63→64) taken 1 times.
✓ Branch 10 (64→65) taken 1 times.
✓ Branch 12 (66→67) taken 1 times.
✓ Branch 14 (67→68) taken 1 times.
✓ Branch 16 (68→69) taken 1 times.
1 getLog().getLogWarning() << "BaseDaemon::checkMessageTimeout() : Timeout Reached for message " << messageId << " sent to '" << message.getVecRecver().front() << "'. Removing unconfirmed transaction" << std::endl;
243 }
244 }
245
2/2
✓ Branch 0 (89→77) taken 1 times.
✓ Branch 1 (89→90) taken 298 times.
597 for(const size_t & messageId : messagesToRemove){
246
1/1
✓ Branch 0 (79→80) taken 1 times.
1 p_mapMessageToBeConfirmed.erase(messageId);
247 }
248 298 }
249
250 ///Get current message id
251 /** @return current message id
252 */
253 10 size_t BaseDaemon::getMessageId(){
254 10 ++p_messageId;
255 10 return p_messageId;
256 }
257
258 ///Get the data function associated with the given data
259 /** @param data The data for which to retrieve the associated function
260 * @return A pointer to the associated data function, or nullptr if not found
261 */
262 14 AbstractDataFunction* BaseDaemon::getDataFunction(const Data & data){
263
2/2
✓ Branch 0 (2→3) taken 14 times.
✓ Branch 2 (3→4) taken 14 times.
14 PString prototype(data.getType());
264
1/1
✓ Branch 0 (4→5) taken 14 times.
14 std::map<PString, AbstractDataFunction*>::iterator it(p_mapDataFunction.find(prototype));
265
1/2
✗ Branch 0 (7→8) not taken.
✓ Branch 1 (7→15) taken 14 times.
14 if(it == p_mapDataFunction.end()){
266 getLog().getLogError() << "BaseDaemon::getDataFunction : function to process data '"<<prototype<<"' not found" << std::endl;
267 return nullptr;
268 }
269 14 return it->second;
270 14 }
271
272 ///Process given data with the proper method
273 /** @param data : data to be processed
274 * @return true on success, false otherwise
275 */
276 5 bool BaseDaemon::processData(const Data & data){
277 5 AbstractDataFunction* function = getDataFunction(data);
278
1/2
✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 5 times.
5 if(function == nullptr){
279 return false;
280 }
281 5 getLog().getLogDebug() << "BaseDaemon::processData : process data '"<<data.getType()<<"'" << std::endl;
282 5 bool b = function->call(p_log, data);
283 5 return b;
284 }
285
286 ///Update a computing statistic with a new value
287 /** @param stat : statistic to be updated
288 * @param value : new value to be added to the statistic
289 */
290 17 void BaseDaemon::updateStatAccumulator(StatAccumulator & stat, float value){
291 17 stat.setNbEvent(stat.getNbEvent() + 1lu);
292 17 getLog().getLogDebug() << "BaseDaemon::updateStatAccumulator : event nb is " << stat.getNbEvent() << std::endl;
293
2/2
✓ Branch 0 (11→12) taken 6 times.
✓ Branch 1 (11→15) taken 11 times.
17 if(stat.getNbEvent() == 1lu){
294 6 stat.setMin(value);
295 6 stat.setMax(value);
296 6 stat.setSum(value);
297 }else{
298
2/2
✓ Branch 0 (16→17) taken 7 times.
✓ Branch 1 (16→18) taken 4 times.
11 if(value < stat.getMin()){
299 7 stat.setMin(value);
300 }
301
2/2
✓ Branch 0 (19→20) taken 2 times.
✓ Branch 1 (19→21) taken 9 times.
11 if(value > stat.getMax()){
302 2 stat.setMax(value);
303 }
304 11 stat.setSum(stat.getSum() + value);
305 }
306
2/2
✓ Branch 0 (24→25) taken 8 times.
✓ Branch 1 (24→27) taken 9 times.
17 if(value > stat.getHistUpperBound()){
307 8 stat.setNbEventAboveUpperBound(stat.getNbEventAboveUpperBound() + 1lu);
308 }
309
2/2
✓ Branch 0 (28→29) taken 1 times.
✓ Branch 1 (28→31) taken 16 times.
17 if(value < stat.getHistLowerBound()){
310 1 stat.setNbEventBelowLowerBound(stat.getNbEventBelowLowerBound() + 1lu);
311 }
312 17 float binSize = (stat.getHistUpperBound() - stat.getHistLowerBound()) / stat.getVecHistogram().size();
313 17 size_t bin = (value - stat.getHistLowerBound()) / binSize;
314
2/2
✓ Branch 0 (38→39) taken 9 times.
✓ Branch 1 (38→43) taken 8 times.
17 if(bin < stat.getVecHistogram().size()){
315 9 std::vector<size_t> & vecHistogram = stat.getVecHistogram();
316 9 vecHistogram[bin] = vecHistogram[bin] + 1lu;
317 }
318 17 }
319
320 ///Create a new clear computing statistic
321 /** @param nbBin : number of bin of the histogram
322 * @param histLowerBound : lower bound of the histogram
323 * @param histUpperBound : upper bound of the histogram
324 * @return new clear computing statistic
325 */
326 13 StatAccumulator BaseDaemon::createNewStat(size_t nbBin, float histLowerBound, float histUpperBound){
327 13 StatAccumulator newStat;
328
1/1
✓ Branch 0 (3→4) taken 13 times.
13 newStat.setNbEvent(0lu);
329
1/1
✓ Branch 0 (4→5) taken 13 times.
13 newStat.setMin(std::nan(""));
330
1/1
✓ Branch 0 (5→6) taken 13 times.
13 newStat.setMax(std::nan(""));
331
1/1
✓ Branch 0 (6→7) taken 13 times.
13 newStat.setSum(std::nan(""));
332
1/1
✓ Branch 0 (7→8) taken 13 times.
13 newStat.setNbEventAboveUpperBound(0lu);
333
1/1
✓ Branch 0 (8→9) taken 13 times.
13 newStat.setNbEventBelowLowerBound(0lu);
334
1/1
✓ Branch 0 (9→10) taken 13 times.
13 newStat.setHistUpperBound(histUpperBound);
335
1/1
✓ Branch 0 (10→11) taken 13 times.
13 newStat.setHistLowerBound(histLowerBound);
336
2/2
✓ Branch 0 (13→14) taken 13 times.
✓ Branch 2 (14→15) taken 13 times.
13 newStat.setVecHistogram(std::vector<size_t>(nbBin, 0lu));
337 13 return newStat;
338 }
339
340 ///Get the map of message to be confirmed
341 /** @return map of message to be confirmed
342 */
343 140 const std::map<size_t, Message> & BaseDaemon::getMapMessageToBeConfirmed() const {
344 140 return p_mapMessageToBeConfirmed;
345 }
346
347
348 ///Clear all the statistics of the daemon
349 171 void BaseDaemon::clearStat(){
350
6/6
✓ Branch 0 (2→3) taken 171 times.
✓ Branch 2 (3→4) taken 171 times.
✓ Branch 4 (21→22) taken 338 times.
✓ Branch 6 (22→23) taken 338 times.
✓ Branch 8 (25→5) taken 167 times.
✓ Branch 9 (25→26) taken 171 times.
338 for(MapStatAccumulator::iterator it = p_config.getDaemonStatAccumulator().getMapStatComputing().begin(); it != p_config.getDaemonStatAccumulator().getMapStatComputing().end(); ++it){
351
1/1
✓ Branch 0 (6→7) taken 167 times.
167 it->second.setNbEvent(0lu);
352
2/2
✓ Branch 0 (8→9) taken 167 times.
✓ Branch 2 (11→12) taken 167 times.
334 std::fill(it->second.getVecHistogram().begin(), it->second.getVecHistogram().end(), 0lu);
353 }
354
6/6
✓ Branch 0 (26→27) taken 171 times.
✓ Branch 2 (27→28) taken 171 times.
✓ Branch 4 (52→53) taken 173 times.
✓ Branch 6 (53→54) taken 173 times.
✓ Branch 8 (56→29) taken 2 times.
✓ Branch 9 (56→57) taken 171 times.
173 for(MapDaemonStatAccumulator::iterator itMap = p_config.getDaemonStatAccumulator().getMapStatCommunication().begin(); itMap != p_config.getDaemonStatAccumulator().getMapStatCommunication().end(); ++itMap){
355
2/2
✓ Branch 0 (50→31) taken 2 times.
✓ Branch 1 (50→51) taken 2 times.
4 for(MapStatAccumulator::iterator it = itMap->second.begin(); it != itMap->second.end(); ++it){
356
1/1
✓ Branch 0 (32→33) taken 2 times.
2 it->second.setNbEvent(0lu);
357
2/2
✓ Branch 0 (34→35) taken 2 times.
✓ Branch 2 (37→38) taken 2 times.
4 std::fill(it->second.getVecHistogram().begin(), it->second.getVecHistogram().end(), 0lu);
358 }
359 }
360 171 }
361
362 ///Get the configuration of the current BaseDaemon
363 /** @return configuration of the current BaseDaemon
364 */
365 14 DaemonConfig & BaseDaemon::getConfig(){
366 14 return p_config;
367 }
368
369 ///Get the map of all Daemon configurations
370 /** @return map of all Daemon configurations
371 */
372 1 MapDaemonConfig & BaseDaemon::getMapDaemonConfig(){
373 1 return p_mapDaemon;
374 }
375
376 ///Get the main configuration of the swarm
377 /** @return main configuration of the swarm
378 */
379 1 DaemonMainConfig & BaseDaemon::getMainConfig(){
380 1 return p_mainConfig;
381 }
382
383 ///Get the logger of the current BaseDaemon
384 /** @return logger of the current BaseDaemon
385 */
386 1 PLog & BaseDaemon::getLogger(){
387 1 return p_log;
388 }
389
390 ///Initialisation function of the class BaseDaemon
391 46 void BaseDaemon::initialisationBaseDaemon(){
392
2/2
✓ Branch 0 (2→3) taken 46 times.
✓ Branch 2 (3→4) taken 46 times.
46 p_optionParser.setExampleLongOption("phoenix_daemon --daemonconfig=daemon_config.toml --daemonname=main");
393
2/2
✓ Branch 0 (5→6) taken 46 times.
✓ Branch 2 (6→7) taken 46 times.
46 p_optionParser.setExampleShortOption("phoenix_daemon -c daemon_config.toml -n main");
394
4/4
✓ Branch 0 (8→9) taken 46 times.
✓ Branch 2 (9→10) taken 46 times.
✓ Branch 4 (10→11) taken 46 times.
✓ Branch 6 (11→12) taken 46 times.
46 p_optionParser.addOption("daemonconfig", "c", OptionType::FILENAME, true, "Toml configuration file which define all Daemons of the swarm");
395
4/4
✓ Branch 0 (15→16) taken 46 times.
✓ Branch 2 (16→17) taken 46 times.
✓ Branch 4 (17→18) taken 46 times.
✓ Branch 6 (18→19) taken 46 times.
46 p_optionParser.addOption("daemonname", "n", OptionType::STRING, true, "Name of the current Daemon of the swarm configuration defined with --daemonconfig");
396
4/4
✓ Branch 0 (22→23) taken 46 times.
✓ Branch 2 (23→24) taken 46 times.
✓ Branch 4 (24→25) taken 46 times.
✓ Branch 6 (25→26) taken 46 times.
46 p_optionParser.addOption("mock", "m", OptionType::NONE, false, "Activate the Daemon in mock mode for the sockets and the clock");
397
4/4
✓ Branch 0 (29→30) taken 46 times.
✓ Branch 2 (30→31) taken 46 times.
✓ Branch 4 (31→32) taken 46 times.
✓ Branch 6 (32→33) taken 46 times.
46 p_optionParser.addOption("mockrecord", "r", OptionType::NONE, false, "Activate the Daemon in mock record mode for the sockets and the clock");
398 46 p_isRun = false;
399 46 p_messageId = 0lu;
400 46 p_isFullMock = false;
401 46 p_isFullMockRecord = false;
402 46 }
403
404 ///Create a new map of communication statistic
405 /** @param dataType : type of data which where pushed
406 * @param nbBin : number of bin of the histogram
407 * @param histLowerBound : lower bound of the histogram
408 * @param histUpperBound : upper bound of the histogram
409 * @return new map of communication statistic
410 */
411 4 std::map<PString, StatAccumulator> BaseDaemon::createNewCommunicationStatMap(const PString & dataType, size_t nbBin, float histLowerBound, float histUpperBound){
412 4 std::map<PString, StatAccumulator> newStatMap;
413
3/3
✓ Branch 0 (3→4) taken 4 times.
✓ Branch 2 (4→5) taken 4 times.
✓ Branch 4 (5→6) taken 4 times.
4 newStatMap[dataType] = createNewStat(nbBin, histLowerBound, histUpperBound);
414 4 return newStatMap;
415 }
416
417 ///Add a communication statistic
418 /** @param destName : name of the destination Daemon from which data where pushed
419 * @param dataType : type of data which where pushed
420 * @param latency : latency between the send of the data and the receiving of the confirmation by the daemon destName
421 * @param nbBin : number of bin of the histogram
422 * @param histLowerBound : lower bound of the histogram
423 * @param histUpperBound : upper bound of the histogram
424 */
425 8 void BaseDaemon::getCommunicationStat(const PString & destName, const PString & dataType, float latency, size_t nbBin, float histLowerBound, float histUpperBound){
426
2/2
✓ Branch 0 (2→3) taken 8 times.
✓ Branch 2 (3→4) taken 8 times.
8 std::map<PString, std::map<PString, StatAccumulator> > & mapCommunication = p_config.getDaemonStatAccumulator().getMapStatCommunication();
427
1/1
✓ Branch 0 (4→5) taken 8 times.
8 MapDaemonStatAccumulator::iterator it = mapCommunication.find(destName);
428
2/2
✓ Branch 0 (7→8) taken 4 times.
✓ Branch 1 (7→13) taken 4 times.
8 if(it == mapCommunication.end()){
429
2/2
✓ Branch 0 (8→9) taken 4 times.
✓ Branch 2 (9→10) taken 4 times.
4 mapCommunication[destName] = createNewCommunicationStatMap(dataType, nbBin, histLowerBound, histUpperBound);
430 }
431 else{
432
1/1
✓ Branch 0 (14→15) taken 4 times.
4 std::map<PString, StatAccumulator>::iterator itDataType = it->second.find(dataType);
433
1/2
✗ Branch 0 (18→19) not taken.
✓ Branch 1 (18→25) taken 4 times.
4 if(itDataType == it->second.end()){
434 it->second[dataType] = createNewStat(nbBin, histLowerBound, histUpperBound);
435 }
436 }
437
5/5
✓ Branch 0 (26→27) taken 8 times.
✓ Branch 2 (27→28) taken 8 times.
✓ Branch 4 (28→29) taken 8 times.
✓ Branch 6 (30→31) taken 8 times.
✓ Branch 8 (31→32) taken 8 times.
8 updateStatAccumulator(p_config.getDaemonStatAccumulator().getMapStatCommunication().find(destName)->second[dataType], latency);
438 8 }
439
440 ///Fill a VecStat from a StatAccumulator to send to the DamonStat
441 /** @param accumulator StatAccumulator to be converted
442 * @param startTimestamp time at which the statistic started to be filled
443 * @param endTimestamp time at which the statistic stopped to be filled
444 * @return VecStat filled with the statistics from the accumulator
445 */
446 170 VecStat BaseDaemon::fillVecStat(const StatAccumulator & accumulator, time_t startTimestamp, time_t endTimestamp){
447 170 VecStat vecStat;
448
449 // Compute event values
450
3/3
✓ Branch 0 (3→4) taken 170 times.
✓ Branch 2 (4→5) taken 170 times.
✓ Branch 4 (5→6) taken 170 times.
170 vecStat.getNbEvent().push_back(accumulator.getNbEvent());
451
3/3
✓ Branch 0 (6→7) taken 170 times.
✓ Branch 2 (7→8) taken 170 times.
✓ Branch 4 (8→9) taken 170 times.
170 vecStat.getMin().push_back(accumulator.getMin());
452
3/3
✓ Branch 0 (9→10) taken 170 times.
✓ Branch 2 (10→11) taken 170 times.
✓ Branch 4 (11→12) taken 170 times.
170 vecStat.getMax().push_back(accumulator.getMax());
453
4/4
✓ Branch 0 (12→13) taken 170 times.
✓ Branch 2 (13→14) taken 170 times.
✓ Branch 4 (14→15) taken 170 times.
✓ Branch 6 (15→16) taken 170 times.
170 vecStat.getAverage().push_back(accumulator.getSum() / accumulator.getNbEvent());
454
455 // Compute time values
456
2/2
✓ Branch 0 (16→17) taken 170 times.
✓ Branch 2 (17→18) taken 170 times.
170 vecStat.getStartTimestamp().push_back(startTimestamp);
457
2/2
✓ Branch 0 (18→19) taken 170 times.
✓ Branch 2 (19→20) taken 170 times.
170 vecStat.getEndTimestamp().push_back(endTimestamp);
458 170 time_t rate = endTimestamp - startTimestamp;
459
3/3
✓ Branch 0 (20→21) taken 170 times.
✓ Branch 2 (21→22) taken 170 times.
✓ Branch 4 (22→23) taken 170 times.
170 vecStat.getRate().push_back(accumulator.getNbEvent()*1e9 / rate);
460
3/3
✓ Branch 0 (23→24) taken 170 times.
✓ Branch 2 (24→25) taken 170 times.
✓ Branch 4 (25→26) taken 170 times.
170 vecStat.getRateEventAboveUpperBound().push_back(accumulator.getNbEventAboveUpperBound()*1e9 / rate);
461
3/3
✓ Branch 0 (26→27) taken 170 times.
✓ Branch 2 (27→28) taken 170 times.
✓ Branch 4 (28→29) taken 170 times.
170 vecStat.getRateEventBelowLowerBound().push_back(accumulator.getNbEventBelowLowerBound()*1e9 / rate);
462
463
3/3
✓ Branch 0 (29→30) taken 170 times.
✓ Branch 2 (30→31) taken 170 times.
✓ Branch 4 (32→33) taken 170 times.
170 vecStat.getVecRateQuantile().resize(accumulator.getVecHistogram().size());
464
3/3
✓ Branch 0 (40→41) taken 8415 times.
✓ Branch 2 (42→34) taken 8245 times.
✓ Branch 3 (42→43) taken 170 times.
8415 for(size_t i = 0; i < accumulator.getVecHistogram().size(); ++i){
465
3/3
✓ Branch 0 (34→35) taken 8245 times.
✓ Branch 2 (36→37) taken 8245 times.
✓ Branch 4 (38→39) taken 8245 times.
8245 vecStat.getVecRateQuantile()[i].push_back(accumulator.getVecHistogram()[i]*1e9 / rate);
466 }
467 170 return vecStat;
468 }
469
470 /// @brief Fill the DaemonStat with the current statistics of the daemon
471 /**
472 * @param stat DaemonStat to be filled
473 * @param startTimestamp time at which the statistic started to be filled
474 * @param endTimestamp time at which the statistic stopped to be filled
475 */
476 171 void BaseDaemon::fillDaemonStat(DaemonStat & stat, time_t startTimestamp, time_t endTimestamp){
477 // Fill the computing statistics
478 171 MapStatAccumulator & mapStatComputing = p_config.getDaemonStatAccumulator().getMapStatComputing();
479
2/2
✓ Branch 0 (15→5) taken 167 times.
✓ Branch 1 (15→16) taken 171 times.
338 for(MapStatAccumulator::iterator it = mapStatComputing.begin(); it != mapStatComputing.end(); ++it){
480 167 StatAccumulator & accumulator = it->second;
481
1/1
✓ Branch 0 (6→7) taken 167 times.
167 VecStat vecStat = fillVecStat(accumulator, startTimestamp, endTimestamp);
482
3/3
✓ Branch 0 (7→8) taken 167 times.
✓ Branch 2 (9→10) taken 167 times.
✓ Branch 4 (10→11) taken 167 times.
167 stat.getMapStatComputing()[it->first] = vecStat;
483 167 }
484
485 // Fill the communication statistics
486 171 MapDaemonStatAccumulator & mapStatCommunication = p_config.getDaemonStatAccumulator().getMapStatCommunication();
487
2/2
✓ Branch 0 (38→19) taken 2 times.
✓ Branch 1 (38→39) taken 171 times.
173 for(MapDaemonStatAccumulator::iterator itMap = mapStatCommunication.begin(); itMap != mapStatCommunication.end(); ++itMap){
488 2 const PString & destName = itMap->first;
489
2/2
✓ Branch 0 (20→21) taken 2 times.
✓ Branch 2 (21→22) taken 2 times.
2 std::map<PString, VecStat> & mapVecStat = stat.getMapStatCommunication()[destName];
490
2/2
✓ Branch 0 (34→24) taken 2 times.
✓ Branch 1 (34→35) taken 2 times.
4 for(MapStatAccumulator::iterator it = itMap->second.begin(); it != itMap->second.end(); ++it){
491 2 StatAccumulator & accumulator = it->second;
492
1/1
✓ Branch 0 (25→26) taken 2 times.
2 VecStat vecStat = fillVecStat(accumulator, startTimestamp, endTimestamp);
493
2/2
✓ Branch 0 (27→28) taken 2 times.
✓ Branch 2 (28→29) taken 2 times.
2 mapVecStat[it->first] = vecStat;
494 2 }
495 }
496 171 }
497
498