GCC Code Coverage Report


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