11 #include <gtest/gtest.h> 12 #include <gmock/gmock.h> 18 using ::testing::UnorderedElementsAre;
36 void fullTopicCb(
const pal_statistics_msgs::StatisticsConstPtr &msg)
40 void namesTopicCb(
const pal_statistics_msgs::StatisticsNamesConstPtr &msg)
44 void valuesTopicCb(
const pal_statistics_msgs::StatisticsValuesConstPtr &msg)
84 std::vector<std::string>
getVariables(
const pal_statistics_msgs::Statistics &msg)
86 std::vector<std::string> v;
87 for (
const auto &
s : msg.statistics)
96 std::map<std::string, double> m;
97 for (
const auto &
s : msg.statistics)
108 registry->unregisterVariable(
"foo");
111 registry->unregisterVariable(
"var1");
112 registry->unregisterVariable(
"var1");
125 pal_statistics_msgs::Statistics msg = registry->createMsg();
129 EXPECT_EQ(
var1_,
s[
"var1"]);
130 EXPECT_EQ(
var2_,
s[
"var2"]);
134 msg = registry->createMsg();
136 EXPECT_EQ(
var1_,
s[
"var1"]);
137 EXPECT_EQ(
var2_,
s[
"var2"]);
146 short s = std::numeric_limits<short>::min();
147 const unsigned short us = std::numeric_limits<unsigned short>::max();
148 const char c = std::numeric_limits<char>::min();
149 const unsigned char uc = std::numeric_limits<unsigned char>::max();
150 int i = std::numeric_limits<int>::min();
151 const unsigned int ui = std::numeric_limits<unsigned int>::max();
152 long l = std::numeric_limits<long>::min();
153 const unsigned long ul = std::numeric_limits<long>::max();
154 long long ll = std::numeric_limits<long long>::min();
155 const unsigned long long ull = std::numeric_limits<unsigned long long>::max();
156 float min_f = std::numeric_limits<float>::min();
157 const float max_f = std::numeric_limits<float>::max();
158 const double min_d = std::numeric_limits<double>::min();
159 double max_d = std::numeric_limits<double>::max();
161 bool false_b =
false;
181 customRegister(*registry,
"container_size", boost::function<
size_t ()>(boost::bind(&std::vector<int>::size,
183 pal_statistics_msgs::Statistics msg = registry->createMsg();
186 EXPECT_EQ(s, values[
"s"]);
187 EXPECT_EQ(us, values[
"us"]);
188 EXPECT_EQ(c, values[
"c"]);
189 EXPECT_EQ(uc, values[
"uc"]);
190 EXPECT_EQ(i, values[
"i"]);
191 EXPECT_EQ(ui, values[
"ui"]);
192 EXPECT_EQ(l, values[
"l"]);
193 EXPECT_EQ(ul, values[
"ul"]);
194 EXPECT_EQ(ll, values[
"ll"]);
195 EXPECT_EQ(ull, values[
"ull"]);
196 EXPECT_EQ(min_f, values[
"min_f"]);
197 EXPECT_EQ(max_f, values[
"max_f"]);
198 EXPECT_EQ(min_d, values[
"min_d"]);
199 EXPECT_EQ(max_d, values[
"max_d"]);
200 EXPECT_EQ(true_b, values[
"true_b"]);
201 EXPECT_EQ(false_b, values[
"false_b"]);
202 EXPECT_EQ(
container_.size(), values[
"container_size"]);
204 EXPECT_NE(l, values[
"ul"]);
214 customRegister(*registry,
"container_size", boost::function<
size_t ()>(boost::bind(&std::vector<int>::size,
217 pal_statistics_msgs::Statistics msg = registry->createMsg();
221 UnorderedElementsAre(
"var1",
"var2",
"container_size",
222 "topic_stats.pal_statistics.publish_async_attempts",
223 "topic_stats.pal_statistics.publish_async_failures",
224 "topic_stats.pal_statistics.publish_buffer_full_errors",
225 "topic_stats.pal_statistics.last_async_pub_duration"));
227 registry->unregisterVariable(
"var2");
228 msg = registry->createMsg();
230 UnorderedElementsAre(
"var1",
"container_size",
231 "topic_stats.pal_statistics.publish_async_attempts",
232 "topic_stats.pal_statistics.publish_async_failures",
233 "topic_stats.pal_statistics.publish_buffer_full_errors",
234 "topic_stats.pal_statistics.last_async_pub_duration"));
236 EXPECT_TRUE(registry->disable(var1_id));
237 msg = registry->createMsg();
239 UnorderedElementsAre(
"container_size",
240 "topic_stats.pal_statistics.publish_async_attempts",
241 "topic_stats.pal_statistics.publish_async_failures",
242 "topic_stats.pal_statistics.publish_buffer_full_errors",
243 "topic_stats.pal_statistics.last_async_pub_duration"));
246 EXPECT_TRUE(registry->enable(var1_id));
247 msg = registry->createMsg();
249 UnorderedElementsAre(
"var1",
"container_size",
250 "topic_stats.pal_statistics.publish_async_attempts",
251 "topic_stats.pal_statistics.publish_async_failures",
252 "topic_stats.pal_statistics.publish_buffer_full_errors",
253 "topic_stats.pal_statistics.last_async_pub_duration"));
261 pal_statistics_msgs::Statistics msg;
268 msg = registry->createMsg();
272 UnorderedElementsAre(
"var1",
"var2",
273 "topic_stats.pal_statistics.publish_async_attempts",
274 "topic_stats.pal_statistics.publish_async_failures",
275 "topic_stats.pal_statistics.publish_buffer_full_errors",
276 "topic_stats.pal_statistics.last_async_pub_duration"));
279 msg = registry->createMsg();
281 UnorderedElementsAre(
"topic_stats.pal_statistics.publish_async_attempts",
282 "topic_stats.pal_statistics.publish_async_failures",
283 "topic_stats.pal_statistics.publish_buffer_full_errors",
284 "topic_stats.pal_statistics.last_async_pub_duration"));
287 msg = registry->createMsg();
289 UnorderedElementsAre(
"var1",
"var2",
290 "topic_stats.pal_statistics.publish_async_attempts",
291 "topic_stats.pal_statistics.publish_async_failures",
292 "topic_stats.pal_statistics.publish_buffer_full_errors",
293 "topic_stats.pal_statistics.last_async_pub_duration"));
297 msg = registry->createMsg();
299 UnorderedElementsAre(
"topic_stats.pal_statistics.publish_async_attempts",
300 "topic_stats.pal_statistics.publish_async_failures",
301 "topic_stats.pal_statistics.publish_buffer_full_errors",
302 "topic_stats.pal_statistics.last_async_pub_duration"));
316 registry->createMsg();
330 registry->startPublishThread();
337 registry->publishAsync();
341 EXPECT_EQ(
var1_,
s[
"var1"]);
342 EXPECT_EQ(
var2_,
s[
"var2"]);
346 <<
" Data shouldn't have been published because there were no calls to publishAsync";
350 registry->publishAsync();
354 EXPECT_EQ(
var1_,
s[
"var1"]);
355 EXPECT_EQ(
var2_,
s[
"var2"]);
359 registry->publishAsync();
362 EXPECT_EQ(4,
last_msg_->statistics.size());
379 UnorderedElementsAre(
"macro_var1",
"macro_var1_bk",
"macro_var2",
"&var2_",
380 "topic_stats.pal_statistics.publish_async_attempts",
381 "topic_stats.pal_statistics.publish_async_failures",
382 "topic_stats.pal_statistics.publish_buffer_full_errors",
383 "topic_stats.pal_statistics.last_async_pub_duration"));
389 UnorderedElementsAre(
"macro_var1",
"macro_var2",
390 "topic_stats.pal_statistics.publish_async_attempts",
391 "topic_stats.pal_statistics.publish_async_failures",
392 "topic_stats.pal_statistics.publish_buffer_full_errors",
393 "topic_stats.pal_statistics.last_async_pub_duration"));
402 UnorderedElementsAre(
"macro_var1",
"macro_var2_bis",
403 "topic_stats.pal_statistics.publish_async_attempts",
404 "topic_stats.pal_statistics.publish_async_failures",
405 "topic_stats.pal_statistics.publish_buffer_full_errors",
406 "topic_stats.pal_statistics.last_async_pub_duration"));
419 for (
size_t i = 0; i < iterations; ++i)
422 customRegister(*registry, prefix + std::to_string(i), variable, bookkeeping);
427 const std::string &prefix,
size_t n_variables)
430 for (
size_t i = n_variables; i > 0; --i)
432 registry->unregisterVariable(prefix + std::to_string(i - 1), NULL);
439 for (
size_t i = n_variables; i > 0; --i)
448 for (
size_t i = n_variables; i > 0; --i)
450 registry->publishAsync();
459 registry->startPublishThread();
462 size_t received_messages = 0;
471 [&](
const pal_statistics_msgs::StatisticsConstPtr &) { received_messages++; });
478 size_t num_messages = 3e4;
479 size_t success_async = 0;
480 for (
size_t i = 0; i < num_messages; ++i)
482 success_async += registry->publishAsync();
489 EXPECT_EQ(success_async - registry->registration_list_.overwritten_data_count_, received_messages);
494 size_t n_threads = 5;
495 size_t n_variables = 2e4/n_threads;
496 std::vector<boost::thread> threads;
499 registry->startPublishThread();
501 for (
size_t i = 0; i < n_threads; ++i)
503 threads.push_back(boost::thread(boost::bind(&
registerThread, registry,
504 std::to_string(i) +
"_", n_variables, &
var1_,
505 static_cast<RegistrationsRAII *>(NULL))));
507 for (
size_t i = 0; i < n_threads; ++i)
512 pal_statistics_msgs::Statistics msg = registry->createMsg();
514 EXPECT_EQ(4 + n_variables * n_threads, msg.statistics.size());
519 for (
size_t i = 0; i < iter; ++i)
521 registry->publishAsync();
525 ROS_INFO_STREAM(
"End publishAsync " << (1000. * (
ros::Time::now() - b).toSec()) /
double(iter));
526 ROS_INFO_STREAM(
"Start publish");
527 for (
size_t i = 0; i < n_variables; ++i)
531 ROS_INFO_STREAM(
"End publish");
534 ROS_INFO_STREAM(
"Start deregistration threads");
535 for (
size_t i = 0; i < n_threads; ++i)
537 threads.push_back(boost::thread(
538 boost::bind(&
unregisterThread, registry, std::to_string(i) +
"_", n_variables)));
540 for (
size_t i = 0; i < n_threads; ++i)
544 ROS_INFO_STREAM(
"Deregistration ended");
545 msg = registry->createMsg();
549 EXPECT_EQ(4, msg.statistics.size());
552 for (
size_t i = 0; i < n_threads; ++i)
562 size_t n_variables = 2e3;
563 size_t n_threads = 5;
564 std::vector<boost::thread> threads;
567 for (
size_t i = 0; i < n_threads; ++i)
569 threads.push_back(boost::thread(boost::bind(&
registerThread, registry,
570 std::to_string(i) +
"_", n_variables, &
var1_,
571 static_cast<RegistrationsRAII *>(NULL))));
573 for (
size_t i = 0; i < threads.size(); ++i)
582 for (
size_t i = 0; i < n_threads; ++i)
584 threads.push_back(boost::thread(
585 boost::bind(&
unregisterThread, registry, std::to_string(i) +
"_", n_variables)));
586 threads.push_back(boost::thread(boost::bind(&
registerThread, registry,
587 std::to_string(i + n_threads) +
"_",
588 n_variables, &
var1_, &bookkeeping)));
593 for (
size_t i = 0; i < threads.size(); ++i)
605 registry->publishCustomStatistic(
"single_stat", d);
609 ASSERT_EQ(1,
last_msg_->statistics.size());
610 EXPECT_EQ(
"single_stat",
last_msg_->statistics[0].name);
611 EXPECT_DOUBLE_EQ(d,
last_msg_->statistics[0].value);
644 UnorderedElementsAre(
"var2",
645 "topic_stats.pal_statistics.publish_async_attempts",
646 "topic_stats.pal_statistics.publish_async_failures",
647 "topic_stats.pal_statistics.publish_buffer_full_errors",
648 "topic_stats.pal_statistics.last_async_pub_duration"));
666 UnorderedElementsAre(
"var2",
667 "topic_stats.pal_statistics.publish_async_attempts",
668 "topic_stats.pal_statistics.publish_async_failures",
669 "topic_stats.pal_statistics.publish_buffer_full_errors",
670 "topic_stats.pal_statistics.last_async_pub_duration"));
676 std::string topic(
"other_topic");
684 unsigned int old_names_version = 0;
685 for (
int i = 0; i < 4; ++i)
687 for (
bool remove : {
false,
true})
697 SCOPED_TRACE(std::string(
"Iteration ") + std::to_string(i) +
" remove " +
698 std::to_string(
remove));
727 int main(
int argc,
char **argv)
729 ros::init(argc, argv,
"pal_statistics_test");
734 testing::InitGoogleTest(&argc, argv);
735 return RUN_ALL_TESTS();
pal_statistics_msgs::StatisticsValuesConstPtr last_values_msg_
void publish(boost::shared_ptr< StatisticsRegistry > registry, size_t n_variables)
ros::Subscriber values_sub_
#define PUBLISH_ASYNC_STATISTICS(TOPIC)
ros::Subscriber names_sub_
bool waitForMsg(const ros::Duration &timeout)
#define REGISTER_VARIABLE_SIMPLE(TOPIC, VARIABLE, BOOKKEEPING)
void publishAsync(boost::shared_ptr< StatisticsRegistry > registry, size_t n_variables)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
IdType customRegister(StatisticsRegistry ®istry, const std::string &name, const T *variable, RegistrationsRAII *bookkeeping=NULL, bool enabled=true)
Default implementation that accepts anything variable that can be casted to a double.
uint32_t getNumPublishers() const
void registerThread(boost::shared_ptr< StatisticsRegistry > registry, const std::string &prefix, size_t iterations, double *variable, RegistrationsRAII *bookkeeping=NULL)
#define UNREGISTER_VARIABLE(...)
std::vector< int > container_
boost::shared_ptr< StatisticsRegistry > getRegistry(const std::string &topic)
constexpr char DEFAULT_STATISTICS_TOPIC[]
void setCallbackQueue(CallbackQueueInterface *queue)
#define REGISTER_VARIABLE(...)
std::map< std::string, double > getVariableAndValues(const pal_statistics_msgs::Statistics &msg)
pal_statistics_msgs::StatisticsNamesConstPtr last_names_msg_
#define START_PUBLISH_THREAD(TOPIC)
#define PUBLISH_STATISTICS(TOPIC)
std::vector< std::string > getVariables(const pal_statistics_msgs::Statistics &msg)
The RegistrationsRAII class holds handles to registered variables and when it is destroyed, unregisters them automatically.
#define ROS_INFO_STREAM(args)
int main(int argc, char **argv)
TEST_F(PalStatisticsTest, misUse)
ros::CallbackQueue queue_
void fullTopicCb(const pal_statistics_msgs::StatisticsConstPtr &msg)
pal_statistics_msgs::StatisticsConstPtr last_msg_
void namesTopicCb(const pal_statistics_msgs::StatisticsNamesConstPtr &msg)
void unregisterThread(boost::shared_ptr< StatisticsRegistry > registry, const std::string &prefix, size_t n_variables)
void valuesTopicCb(const pal_statistics_msgs::StatisticsValuesConstPtr &msg)
static bool waitForValid()