self_test.h
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2008, Willow Garage, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of the Willow Garage nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 
35 #ifndef SELFTEST_HH
36 #define SELFTEST_HH
37 
38 #include <stdexcept>
39 #include <vector>
40 #include <string>
41 
42 #include <boost/thread.hpp>
43 #include <ros/callback_queue.h>
44 
45 #include "diagnostic_msgs/DiagnosticStatus.h"
46 #include "diagnostic_msgs/SelfTest.h"
48 
49 namespace self_test
50 {
51 
52  using namespace diagnostic_updater;
53 
68  class TestRunner : public DiagnosticTaskVector
69  {
70  private:
71  ros::ServiceServer service_server_;
72  ros::CallbackQueue self_test_queue_;
73  ros::NodeHandle node_handle_;
74  ros::NodeHandle private_node_handle_;
75  std::string id_;
76 
77  bool verbose;
78 
79  public:
81 
91  node_handle_(h),
92  private_node_handle_(ph)
93  {
94  ROS_DEBUG("Advertising self_test");
95  ros::AdvertiseServiceOptions ops;//use options so that we can set callback queue directly
96  ops.init<diagnostic_msgs::SelfTest::Request, diagnostic_msgs::SelfTest::Response>("self_test", boost::bind(&TestRunner::doTest, this, boost::placeholders::_1, boost::placeholders::_2));
97  ops.callback_queue = &self_test_queue_;
98  service_server_ = private_node_handle_.advertiseService(ops);
99  verbose = true;
100  }
101 
107  void checkTest()
108  {
109  self_test_queue_.callAvailable(ros::WallDuration(0));
110  }
111 
121  void setID(std::string id)
122  {
123  id_ = id;
124  }
125 
126  private:
130  bool doTest(diagnostic_msgs::SelfTest::Request &req,
131  diagnostic_msgs::SelfTest::Response &res)
132  {
133  bool retval = false;
134  bool ignore_set_id_warn = false;
135 
136  if (node_handle_.ok())
137  {
138  const std::string unspecified_id("unspecified");
139 
140  ROS_INFO("Entering self-test.");
141 
142  std::vector<diagnostic_msgs::DiagnosticStatus> status_vec;
143 
144  const std::vector<DiagnosticTaskInternal> &tasks = getTasks();
145  for (std::vector<DiagnosticTaskInternal>::const_iterator iter = tasks.begin();
146  iter != tasks.end(); iter++)
147  {
148  if (ros::isShuttingDown())
149  {
150  ROS_ERROR("ROS has shut down. Exiting.");
151  return false;
152  }
153 
155 
156  status.level = 2;
157  status.message = "No message was set";
158 
159  try {
160  ROS_INFO("Starting test: %s", iter->getName().c_str());
161  iter->run(status);
162 
163  } catch (std::exception& e)
164  {
165  status.level = 2;
166  status.message = std::string("Uncaught exception: ") + e.what();
167  ignore_set_id_warn = true;
168  }
169 
170  if (status.level >= 1)
171  if (verbose)
172  ROS_WARN("Non-zero self-test test status. Name: '%s', status %i: '%s'", status.name.c_str(), status.level, status.message.c_str());
173 
174  status_vec.push_back(status);
175  }
176 
177  if (!ignore_set_id_warn && id_.empty())
178  ROS_WARN("setID was not called by any self-test. The node author should be notified. If there is no suitable ID for this node, an ID of 'none' should be used.");
179 
180  //One of the test calls should use setID
181  res.id = id_;
182 
183  res.passed = true;
184  for (std::vector<diagnostic_msgs::DiagnosticStatus>::iterator status_iter = status_vec.begin();
185  status_iter != status_vec.end();
186  status_iter++)
187  {
188  if (status_iter->level >= 2)
189  res.passed = false;
190  }
191 
192  if (res.passed && id_ == unspecified_id)
193  ROS_WARN("Self-test passed, but setID was not called. This is a bug in the driver. Please report it.");
194 
195  res.status = status_vec;
196 
197  retval = true;
198 
199  ROS_INFO("Self-test complete.");
200  }
201 
202  return retval;
203 
204  }
205  };
206 }
207 
208 #endif
ros::AdvertiseServiceOptions::init
void init(const std::string &_service, const boost::function< bool(MReq &, MRes &)> &_callback)
ros::NodeHandle::advertiseService
ServiceServer advertiseService(AdvertiseServiceOptions &ops)
diagnostic_updater::DiagnosticTaskVector
self_test::TestRunner::doTest
bool doTest(diagnostic_msgs::SelfTest::Request &req, diagnostic_msgs::SelfTest::Response &res)
Definition: self_test.h:162
self_test
Definition: self_test.h:49
diagnostic_updater.h
ros::ServiceServer
testing::internal::string
::std::string string
Definition: gtest.h:1979
ros::AdvertiseServiceOptions::callback_queue
CallbackQueueInterface * callback_queue
ros::CallbackQueue
ROS_DEBUG
#define ROS_DEBUG(...)
diagnostic_updater
doTest
bool doTest(ros::NodeHandle nh)
Definition: run_selftest.cpp:41
ROS_WARN
#define ROS_WARN(...)
self_test::TestRunner
Class to facilitate the creation of component self-tests.
Definition: self_test.h:100
ros::AdvertiseServiceOptions
callback_queue.h
ros::NodeHandle::ok
bool ok() const
ROS_ERROR
#define ROS_ERROR(...)
ros::isShuttingDown
ROSCPP_DECL bool isShuttingDown()
diagnostic_updater::DiagnosticStatusWrapper
ros::WallDuration
ROS_INFO
#define ROS_INFO(...)
diagnostic_updater::DiagnosticTaskVector::add
void add(const std::string &name, TaskFunction f)
ros::CallbackQueue::callAvailable
void callAvailable()
ros::NodeHandle


self_test
Author(s): Kevin Watts, Brice Rebsamen , Jeremy Leibs and Blaise Gassend
autogenerated on Tue Nov 15 2022 03:17:24