intraprocess_subscriptions.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2010, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
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 Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       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 THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 /* Author: Josh Faust */
00031 
00032 /*
00033  * Subscribe intraprocess, ensuring that no copy happens
00034  */
00035 
00036 #include <string>
00037 
00038 #include <gtest/gtest.h>
00039 
00040 #include <stdlib.h>
00041 
00042 #include "ros/ros.h"
00043 
00044 uint32_t g_msg_constructor = 0;
00045 uint32_t g_msg2_constructor = 0;
00046 
00047 struct Msg
00048 {
00049   Msg()
00050   : serialized(false)
00051   , deserialized(false)
00052   {
00053     ++g_msg_constructor;
00054   }
00055 
00056   mutable bool serialized;
00057   bool deserialized;
00058 };
00059 typedef boost::shared_ptr<Msg const> MsgConstPtr;
00060 
00061 namespace ros
00062 {
00063 namespace message_traits
00064 {
00065   template<>
00066   struct MD5Sum<Msg>
00067   {
00068     static const char* value() { return "MsgMD5Sum"; }
00069     static const char* value(const Msg&) { return "MsgMD5Sum"; }
00070   };
00071 
00072   template<>
00073   struct DataType<Msg>
00074   {
00075     static const char* value() { return "test_roscpp/MsgDataType"; }
00076     static const char* value(const Msg&) { return "test_roscpp/MsgDataType"; }
00077   };
00078 
00079   template<>
00080   struct Definition<Msg>
00081   {
00082     static const char* value() { return ""; }
00083     static const char* value(const Msg&) { return ""; }
00084   };
00085 } // namespace message_traits
00086 
00087 namespace serialization
00088 {
00089 template<>
00090 struct Serializer<Msg>
00091 {
00092   template<typename Stream>
00093   inline static void write(Stream& stream, const Msg& v)
00094   {
00095     v.serialized = true;
00096   }
00097 
00098   template<typename Stream>
00099   inline static void read(Stream& stream, Msg& v)
00100   {
00101     v.deserialized = true;
00102   }
00103 
00104   inline static uint32_t serializedLength(const Msg& v)
00105   {
00106     return 0;
00107   }
00108 };
00109 } // namespace serialization
00110 } // namespace ros
00111 
00112 MsgConstPtr g_msg;
00113 
00114 struct Msg2
00115 {
00116   Msg2()
00117   : serialized(false)
00118   , deserialized(false)
00119   {
00120     ++g_msg2_constructor;
00121   }
00122 
00123   mutable bool serialized;
00124   bool deserialized;
00125 };
00126 typedef boost::shared_ptr<Msg2 const> Msg2ConstPtr;
00127 
00128 namespace ros
00129 {
00130 namespace message_traits
00131 {
00132   template<>
00133   struct MD5Sum<Msg2>
00134   {
00135     static const char* value() { return "MsgMD5Sum"; }
00136     static const char* value(const Msg2&) { return "MsgMD5Sum"; }
00137   };
00138 
00139   template<>
00140   struct DataType<Msg2>
00141   {
00142     static const char* value() { return "test_roscpp/MsgDataType"; }
00143     static const char* value(const Msg2&) { return "test_roscpp/MsgDataType"; }
00144   };
00145 
00146   template<>
00147   struct Definition<Msg2>
00148   {
00149     static const char* value() { return ""; }
00150     static const char* value(const Msg2&) { return ""; }
00151   };
00152 } // namespace message_traits
00153 
00154 namespace serialization
00155 {
00156 template<>
00157 struct Serializer<Msg2>
00158 {
00159   template<typename Stream>
00160   inline static void write(Stream& stream, const Msg2& v)
00161   {
00162     v.serialized = true;
00163   }
00164 
00165   template<typename Stream>
00166   inline static void read(Stream& stream, Msg2& v)
00167   {
00168     v.deserialized = true;
00169   }
00170 
00171   inline static uint32_t serializedLength(const Msg2& v)
00172   {
00173     return 0;
00174   }
00175 };
00176 } // namespace serialization
00177 } // namespace ros
00178 
00179 void messageCallback(const MsgConstPtr& msg)
00180 {
00181   g_msg = msg;
00182 }
00183 
00184 TEST(IntraprocessSubscriptions, noCopy)
00185 {
00186   g_msg.reset();
00187   g_msg_constructor = 0;
00188 
00189   ros::NodeHandle nh;
00190   ros::Subscriber sub = nh.subscribe("test", 0, messageCallback);
00191   ros::Publisher pub = nh.advertise<Msg>("test", 0);
00192 
00193   MsgConstPtr msg(new Msg);
00194 
00195   while (pub.getNumSubscribers() == 0)
00196   {
00197     ros::Duration(0.01).sleep();
00198   }
00199 
00200   pub.publish(msg);
00201 
00202   while (!g_msg)
00203   {
00204     ros::spinOnce();
00205     ros::Duration(0.01).sleep();
00206   }
00207 
00208   ASSERT_TRUE(g_msg);
00209   EXPECT_EQ(g_msg.get(), msg.get());
00210   EXPECT_FALSE(g_msg->serialized);
00211   EXPECT_FALSE(g_msg->deserialized);
00212   EXPECT_EQ(g_msg_constructor, 1ULL);
00213 }
00214 
00215 TEST(IntraprocessSubscriptions, differentRTTI)
00216 {
00217   g_msg_constructor = 0;
00218   g_msg.reset();
00219 
00220   ros::NodeHandle nh;
00221   ros::Subscriber sub = nh.subscribe("test", 0, messageCallback);
00222   ros::Publisher pub = nh.advertise<Msg2>("test", 0);
00223 
00224   Msg2ConstPtr msg(new Msg2);
00225 
00226   while (pub.getNumSubscribers() == 0)
00227   {
00228     ros::Duration(0.01).sleep();
00229   }
00230 
00231   pub.publish(msg);
00232 
00233   while (!g_msg)
00234   {
00235     ros::spinOnce();
00236     ros::Duration(0.01).sleep();
00237   }
00238 
00239   ASSERT_TRUE(g_msg);
00240   EXPECT_NE((void*)g_msg.get(), (void*)msg.get());
00241   EXPECT_TRUE(msg->serialized);
00242   EXPECT_TRUE(g_msg->deserialized);
00243   EXPECT_EQ(g_msg_constructor, 1ULL);
00244   EXPECT_EQ(g_msg2_constructor, 1ULL);
00245 }
00246 
00247 Msg2ConstPtr g_msg2;
00248 void messageCallback2(const Msg2ConstPtr& msg)
00249 {
00250   g_msg2 = msg;
00251 }
00252 
00253 TEST(IntraprocessSubscriptions, noCopyAndDifferentRTTI)
00254 {
00255   g_msg.reset();
00256 
00257   ros::NodeHandle nh;
00258   ros::Subscriber sub1 = nh.subscribe("test", 0, messageCallback);
00259   ros::Subscriber sub2 = nh.subscribe("test", 0, messageCallback2);
00260   ros::Publisher pub = nh.advertise<Msg2>("test", 0);
00261 
00262   Msg2ConstPtr msg(new Msg2);
00263 
00264   while (pub.getNumSubscribers() == 0)
00265   {
00266     ros::Duration(0.01).sleep();
00267   }
00268 
00269   pub.publish(msg);
00270 
00271   while (!g_msg || !g_msg2)
00272   {
00273     ros::spinOnce();
00274     ros::Duration(0.01).sleep();
00275   }
00276 
00277   ASSERT_TRUE(g_msg);
00278   EXPECT_NE((void*)g_msg.get(), (void*)msg.get());
00279   EXPECT_TRUE(msg->serialized);
00280   EXPECT_TRUE(g_msg->deserialized);
00281 
00282   ASSERT_TRUE(g_msg2);
00283   EXPECT_EQ(g_msg2.get(), msg.get());
00284   EXPECT_TRUE(g_msg2->serialized);
00285   EXPECT_FALSE(g_msg2->deserialized);
00286 }
00287 
00288 int main(int argc, char** argv)
00289 {
00290   testing::InitGoogleTest(&argc, argv);
00291   ros::init(argc, argv, "intraprocess_subscriptions");
00292 
00293   ros::NodeHandle nh;
00294 
00295   return RUN_ALL_TESTS();
00296 }
00297 


test_roscpp
Author(s): Morgan Quigley mquigley@cs.stanford.edu, Ken Conley kwc@willowgarage.com
autogenerated on Sat Dec 28 2013 17:36:21