Program Listing for File test_runner.hpp
↰ Return to documentation for file (/tmp/ws/src/diagnostics/self_test/include/self_test/test_runner.hpp
)
/*********************************************************************
* Software License Agreement (BSD License)
*
* Copyright (c) 2008, Willow Garage, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the Willow Garage nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/
#ifndef SELF_TEST__TEST_RUNNER_HPP_
#define SELF_TEST__TEST_RUNNER_HPP_
#include <functional>
#include <memory>
#include <stdexcept>
#include <string>
#include <thread>
#include <vector>
#include "diagnostic_msgs/msg/diagnostic_status.hpp"
#include "diagnostic_msgs/srv/self_test.hpp"
#include "diagnostic_updater/diagnostic_updater.hpp"
#include "rclcpp/rclcpp.hpp"
namespace self_test
{
class TestRunner : public diagnostic_updater::DiagnosticTaskVector
{
private:
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr base_interface_;
rclcpp::node_interfaces::NodeServicesInterface::SharedPtr service_interface_;
rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr logger_interface_;
rclcpp::Logger logger_;
rclcpp::Service<diagnostic_msgs::srv::SelfTest>::SharedPtr service_server_;
std::string id_;
bool verbose;
public:
using diagnostic_updater::DiagnosticTaskVector::add;
TestRunner(
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr base_interface,
rclcpp::node_interfaces::NodeServicesInterface::SharedPtr
service_interface,
rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr logger_interface)
: base_interface_(base_interface),
service_interface_(service_interface),
logger_interface_(logger_interface),
logger_(logger_interface_->get_logger())
{
RCLCPP_DEBUG(logger_, "Advertising self_test");
auto serviceCB =
[this](
std::shared_ptr<diagnostic_msgs::srv::SelfTest::Request> request,
std::shared_ptr<diagnostic_msgs::srv::SelfTest::Response> response)
-> bool {
(void)request;
bool retval = false;
bool ignore_set_id_warn = false;
if (rclcpp::ok()) {
const std::string unspecified_id("unspecified");
RCLCPP_INFO(logger_, "Entering self-test.");
std::vector<diagnostic_msgs::msg::DiagnosticStatus> status_vec;
const std::vector<DiagnosticTaskInternal> & tasks = getTasks();
for (std::vector<DiagnosticTaskInternal>::const_iterator iter =
tasks.begin();
iter != tasks.end(); iter++)
{
diagnostic_updater::DiagnosticStatusWrapper status;
status.level = 2;
status.message = "No message was set";
try {
RCLCPP_INFO(logger_, "Starting test: %s", iter->getName().c_str());
iter->run(status);
} catch (std::exception & e) {
status.level = 2;
status.message = std::string("Uncaught exception: ") + e.what();
ignore_set_id_warn = true;
}
if (status.level >= 1) {
if (verbose) {
RCLCPP_WARN(
logger_,
"Non-zero self-test test status. Name: %s Status %i: "
"Message: %s",
status.name.c_str(), status.level,
status.message.c_str());
}
}
status_vec.push_back(status);
}
if (!ignore_set_id_warn && id_.empty()) {
RCLCPP_WARN(logger_, "setID was not called by any self-test.");
}
// One of the test calls should use setID
response->id = id_;
response->passed = true;
for (std::vector<diagnostic_msgs::msg::DiagnosticStatus>::iterator
status_iter = status_vec.begin();
status_iter != status_vec.end(); status_iter++)
{
if (status_iter->level >= 2) {
response->passed = false;
}
}
if (response->passed && id_ == unspecified_id) {
RCLCPP_WARN(
logger_,
"Self-test passed, but setID was not called. This is a "
"bug in the driver.");
}
response->status = status_vec;
retval = true;
RCLCPP_INFO(logger_, "Self-test complete.");
}
return retval;
};
service_server_ = rclcpp::create_service<diagnostic_msgs::srv::SelfTest>(
base_interface_, service_interface_,
std::string(base_interface_->get_name()) + std::string("/self_test"),
serviceCB, rmw_qos_profile_default, nullptr);
verbose = true;
}
void setID(std::string id) {id_ = id;}
};
} // namespace self_test
#endif // SELF_TEST__TEST_RUNNER_HPP_