topic_service_test.cpp
Go to the documentation of this file.
00001 // *****************************************************************************
00002 //
00003 // Copyright (c) 2018, Southwest Research Institute® (SwRI®)
00004 // All rights reserved.
00005 //
00006 // Redistribution and use in source and binary forms, with or without
00007 // modification, are permitted provided that the following conditions are met:
00008 //     * Redistributions of source code must retain the above copyright
00009 //       notice, this list of conditions and the following disclaimer.
00010 //     * Redistributions in binary form must reproduce the above copyright
00011 //       notice, this list of conditions and the following disclaimer in the
00012 //       documentation and/or other materials provided with the distribution.
00013 //     * Neither the name of Southwest Research Institute® (SwRI®) nor the
00014 //       names of its contributors may be used to endorse or promote products
00015 //       derived from this software without specific prior written permission.
00016 //
00017 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020 // ARE DISCLAIMED. IN NO EVENT SHALL SOUTHWEST RESEARCH INSTITUTE BE LIABLE FOR ANY
00021 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00022 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00023 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00024 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00026 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027 //
00028 // *****************************************************************************
00029 #include <gtest/gtest.h>
00030 
00031 #include <ros/ros.h>
00032 
00033 #include <swri_roscpp/TestTopicServiceRequest.h>
00034 #include <swri_roscpp/TestTopicServiceResponse.h>
00035 
00036 #include <swri_roscpp/topic_service_client.h>
00037 #include <swri_roscpp/topic_service_server.h>
00038 
00039 namespace swri_roscpp
00040 {
00041   /*
00042    * This class would normally be auto-generated by the add_topic_service_files
00043    * CMake macro, but we can't use that in swri_roscpp's own tests because the
00044    * .cmake file will not have been generated and installed at the time the
00045    * tests are run.
00046    */
00047   class TestTopicService
00048   {
00049   public:
00050     typedef TestTopicServiceResponse Response;
00051     typedef TestTopicServiceRequest Request;
00052 
00053     Request request;
00054     Response response;
00055   };
00056 
00057   static const std::string topic_name = "/test_topic_service";
00058 
00059   static const size_t value_count = 5;
00060   static const int test_values[] = {5, 10, 100, 10000, 50000};
00061 
00062   /*
00063    * Class used by the server to respond to service requests
00064    */
00065   class TopicServiceHandler
00066   {
00067   public:
00068     TopicServiceHandler() :
00069       call_count_(0),
00070       error_(false),
00071       is_running_(true)
00072     {}
00073 
00074     bool handleTopicServiceRequest(const swri_roscpp::TestTopicService::Request& req,
00075                                    swri_roscpp::TestTopicService::Response& resp)
00076     {
00077       ROS_INFO("TopicServiceHandler::handleTopicServiceRequest");
00078       resp.response_value = req.request_value;
00079 
00080       if (call_count_ >= value_count || (test_values[call_count_] != req.request_value))
00081       {
00082         error_ = true;
00083         return false;
00084       }
00085 
00086       if (req.request_value == test_values[value_count-1])
00087       {
00088         is_running_ = false;
00089       }
00090 
00091       call_count_++;
00092 
00093       return is_running_;
00094     }
00095 
00096     int call_count_;
00097     bool error_;
00098     bool is_running_;
00099   };
00100 }
00101 
00102 TEST(TopicServiceClientTests, testTopicServiceClient)
00103 {
00104   ros::NodeHandle nh("~");
00105 
00106   swri::TopicServiceClient<swri_roscpp::TestTopicService> client;
00107   client.initialize(nh, swri_roscpp::topic_name, "test_client");
00108 
00109   ros::Duration one_second(1.0);
00110   int checks = 0;
00111   // Wait up to 20s for the server to exist (it should be much faster than that)
00112   while (!client.exists() && checks < 20)
00113   {
00114     ROS_INFO("Waiting for server to exist...");
00115     one_second.sleep();
00116     checks++;
00117   }
00118   ASSERT_TRUE(client.exists());
00119 
00120   swri_roscpp::TestTopicService srv;
00121 
00122   // Iterate through our tests values and test submitting all of them
00123   for (size_t i = 0; i < swri_roscpp::value_count; i++)
00124   {
00125     srv.request.request_value = swri_roscpp::test_values[i];
00126     bool result = client.call(srv);
00127 
00128     if (i + 1 < swri_roscpp::value_count)
00129     {
00130       ASSERT_TRUE(result);
00131     }
00132     else
00133     {
00134       // The very last value should cause the server to return false
00135       ASSERT_FALSE(result);
00136     }
00137     ASSERT_EQ(swri_roscpp::test_values[i], srv.response.response_value);
00138   }
00139 }
00140 
00141 TEST(TopicServiceServerTests, testTopicServiceServer)
00142 {
00143   ros::NodeHandle nh("~");
00144   swri_roscpp::TopicServiceHandler handler;
00145 
00146   swri::TopicServiceServer server;
00147 
00148   ROS_INFO("Initializing server.");
00149 
00150   server.initialize(
00151       nh,
00152       swri_roscpp::topic_name,
00153       &swri_roscpp::TopicServiceHandler::handleTopicServiceRequest,
00154       &handler);
00155 
00156   ros::Rate rate(50);
00157   ros::Time start = ros::Time::now();
00158   // Wait up to 20s for the client to complete; it should be much faster than that
00159   while (handler.is_running_ && (ros::Time::now() - start) < ros::Duration(20))
00160   {
00161     // If the server encounters any errors, it will set error_ to true
00162     ASSERT_FALSE(handler.error_);
00163     ros::spinOnce();
00164     rate.sleep();
00165   }
00166 
00167   ROS_INFO("Server is exiting.");
00168 }
00169 
00170 int main(int argc, char** argv)
00171 {
00172   ros::init(argc, argv, "topic_service_test", ros::init_options::AnonymousName);
00173 
00174   int retval = 0;
00175   ros::start();
00176   testing::InitGoogleTest(&argc, argv);
00177   retval = RUN_ALL_TESTS();
00178   ros::shutdown();
00179 
00180   return retval;
00181 }


swri_roscpp
Author(s):
autogenerated on Thu Jun 6 2019 20:34:47