test_subscription_queue.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009, Willow Garage, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of Willow Garage, Inc. nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 /* Author: Josh Faust */
31 
32 /*
33  * Test subscription queue
34  */
35 
36 #include <gtest/gtest.h>
37 #include "ros/subscription_queue.h"
41 #include "ros/init.h"
42 
43 #include <boost/shared_array.hpp>
44 #include <boost/bind.hpp>
45 #include <boost/thread.hpp>
46 
47 using namespace ros;
48 
50 {
51 public:
52  virtual const std::string __getDataType() const { return ""; }
53  virtual const std::string __getMD5Sum() const { return ""; }
54  virtual const std::string __getMessageDefinition() const { return ""; }
55  virtual uint32_t serializationLength() const { return 0; }
56  virtual uint8_t *serialize(uint8_t *write_ptr, uint32_t seq) const { (void)seq; return write_ptr; }
57  virtual uint8_t *deserialize(uint8_t *read_ptr) { return read_ptr; }
58 };
59 
61 {
62 public:
64  : calls_(0)
65  {}
66 
68  {
69  return boost::make_shared<FakeMessage>();
70  }
71 
72  virtual std::string getMD5Sum() { return ""; }
73  virtual std::string getDataType() { return ""; }
74 
76  {
77  (void)params;
78  {
79  boost::mutex::scoped_lock lock(mutex_);
80  ++calls_;
81  }
82 
83  if (cb_)
84  {
85  cb_();
86  }
87  }
88 
89  virtual const std::type_info& getTypeInfo() { return typeid(FakeMessage); }
90  virtual bool isConst() { return true; }
91  virtual bool hasHeader() { return false; }
92 
93  boost::mutex mutex_;
94  int32_t calls_;
95 
96  boost::function<void(void)> cb_;
97 };
99 
101 {
102  SubscriptionQueue queue("blah", 1, false);
103 
104  FakeSubHelperPtr helper(boost::make_shared<FakeSubHelper>());
105  MessageDeserializerPtr des(boost::make_shared<MessageDeserializer>(helper, SerializedMessage(), boost::shared_ptr<M_string>()));
106 
107  ASSERT_FALSE(queue.full());
108 
109  queue.push(helper, des, false, VoidConstWPtr(), true);
110 
111  ASSERT_TRUE(queue.full());
112 
113  ASSERT_EQ(queue.call(), CallbackInterface::Success);
114 
115  ASSERT_FALSE(queue.full());
116 
117  queue.push(helper, des, false, VoidConstWPtr(), true);
118 
119  ASSERT_TRUE(queue.full());
120 
121  ASSERT_TRUE(queue.ready());
122 
123  queue.push(helper, des, false, VoidConstWPtr(), true);
124 
125  ASSERT_TRUE(queue.full());
126 
127  ASSERT_EQ(queue.call(), CallbackInterface::Success);
128  ASSERT_EQ(queue.call(), CallbackInterface::Invalid);
129 
130  ASSERT_EQ(helper->calls_, 2);
131 }
132 
133 TEST(SubscriptionQueue, infiniteQueue)
134 {
135  SubscriptionQueue queue("blah", 0, false);
136 
137  FakeSubHelperPtr helper(boost::make_shared<FakeSubHelper>());
138  MessageDeserializerPtr des(boost::make_shared<MessageDeserializer>(helper, SerializedMessage(), boost::shared_ptr<M_string>()));
139 
140  ASSERT_FALSE(queue.full());
141 
142  queue.push(helper, des, false, VoidConstWPtr(), true);
143  ASSERT_EQ(queue.call(), CallbackInterface::Success);
144 
145  ASSERT_FALSE(queue.full());
146 
147  for (int i = 0; i < 10000; ++i)
148  {
149  queue.push(helper, des, false, VoidConstWPtr(), true);
150  }
151 
152  ASSERT_FALSE(queue.full());
153 
154  for (int i = 0; i < 10000; ++i)
155  {
156  ASSERT_EQ(queue.call(), CallbackInterface::Success);
157  }
158 
159  ASSERT_EQ(queue.call(), CallbackInterface::Invalid);
160 
161  ASSERT_EQ(helper->calls_, 10001);
162 }
163 
165 {
166  SubscriptionQueue queue("blah", 1, false);
167 
168  FakeSubHelperPtr helper(boost::make_shared<FakeSubHelper>());
169  MessageDeserializerPtr des(boost::make_shared<MessageDeserializer>(helper, SerializedMessage(), boost::shared_ptr<M_string>()));
170 
171  queue.push(helper, des, false, VoidConstWPtr(), true);
172  queue.clear();
173  ASSERT_EQ(queue.call(), CallbackInterface::Invalid);
174 }
175 
176 TEST(SubscriptionQueue, clearThenAddAndCall)
177 {
178  SubscriptionQueue queue("blah", 1, false);
179 
180  FakeSubHelperPtr helper(boost::make_shared<FakeSubHelper>());
181  MessageDeserializerPtr des(boost::make_shared<MessageDeserializer>(helper, SerializedMessage(), boost::shared_ptr<M_string>()));
182 
183  queue.push(helper, des, false, VoidConstWPtr(), true);
184  queue.clear();
185  queue.push(helper, des, false, VoidConstWPtr(), true);
186  ASSERT_EQ(queue.call(), CallbackInterface::Success);
187 }
188 
190 {
191  queue.clear();
192 }
193 
194 TEST(SubscriptionQueue, clearInCallback)
195 {
196  SubscriptionQueue queue("blah", 1, false);
197 
198  FakeSubHelperPtr helper(boost::make_shared<FakeSubHelper>());
199  MessageDeserializerPtr des(boost::make_shared<MessageDeserializer>(helper, SerializedMessage(), boost::shared_ptr<M_string>()));
200 
201  helper->cb_ = boost::bind(clearInCallbackCallback, boost::ref(queue));
202  queue.push(helper, des, false, VoidConstWPtr(), true);
203  queue.call();
204 }
205 
206 void clearWhileThreadIsBlockingCallback(bool* done, boost::barrier* barrier)
207 {
208  barrier->wait();
209  ros::WallDuration(.1).sleep();
210  *done = true;
211 }
212 
214 {
215  queue.call();
216 }
217 
218 TEST(SubscriptionQueue, clearWhileThreadIsBlocking)
219 {
220  SubscriptionQueue queue("blah", 1, false);
221 
222  FakeSubHelperPtr helper(boost::make_shared<FakeSubHelper>());
223  MessageDeserializerPtr des(boost::make_shared<MessageDeserializer>(helper, SerializedMessage(), boost::shared_ptr<M_string>()));
224 
225  bool done = false;
226  boost::barrier barrier(2);
227  helper->cb_ = boost::bind(clearWhileThreadIsBlockingCallback, &done, &barrier);
228  queue.push(helper, des, false, VoidConstWPtr(), true);
229  boost::thread t(callThread, boost::ref(queue));
230  barrier.wait();
231 
232  queue.clear();
233 
234  ASSERT_TRUE(done);
235 }
236 
237 void waitForBarrier(boost::barrier* bar)
238 {
239  bar->wait();
240 }
241 
242 TEST(SubscriptionQueue, concurrentCallbacks)
243 {
244  SubscriptionQueue queue("blah", 0, true);
245  FakeSubHelperPtr helper(boost::make_shared<FakeSubHelper>());
246  MessageDeserializerPtr des(boost::make_shared<MessageDeserializer>(helper, SerializedMessage(), boost::shared_ptr<M_string>()));
247 
248  boost::barrier bar(2);
249  helper->cb_ = boost::bind(waitForBarrier, &bar);
250  queue.push(helper, des, false, VoidConstWPtr(), true);
251  queue.push(helper, des, false, VoidConstWPtr(), true);
252  boost::thread t1(callThread, boost::ref(queue));
253  boost::thread t2(callThread, boost::ref(queue));
254  t1.join();
255  t2.join();
256 
257  ASSERT_EQ(helper->calls_, 2);
258 }
259 
261 {
262  ros::WallDuration(1.0).sleep();
263 }
264 
265 TEST(SubscriptionQueue, nonConcurrentOrdering)
266 {
267  SubscriptionQueue queue("blah", 0, false);
268  FakeSubHelperPtr helper(boost::make_shared<FakeSubHelper>());
269  MessageDeserializerPtr des(boost::make_shared<MessageDeserializer>(helper, SerializedMessage(), boost::shared_ptr<M_string>()));
270 
271  helper->cb_ = waitForASecond;
272  queue.push(helper, des, false, VoidConstWPtr(), true);
273  queue.push(helper, des, false, VoidConstWPtr(), true);
274  boost::thread t1(callThread, boost::ref(queue));
275  boost::thread t2(callThread, boost::ref(queue));
276  t1.join();
277  t2.join();
278 
279  ASSERT_EQ(helper->calls_, 1);
280  queue.call();
281  ASSERT_EQ(helper->calls_, 2);
282 }
283 
284 int main(int argc, char** argv)
285 {
286  testing::InitGoogleTest(&argc, argv);
287  ros::init(argc, argv, "blah");
288  return RUN_ALL_TESTS();
289 }
290 
291 
virtual uint8_t * serialize(uint8_t *write_ptr, uint32_t seq) const
virtual uint32_t serializationLength() const
boost::function< void(void)> cb_
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
virtual const std::string __getMessageDefinition() const
virtual VoidConstPtr deserialize(const SubscriptionCallbackHelperDeserializeParams &)
virtual std::string getDataType()
void waitForBarrier(boost::barrier *bar)
int main(int argc, char **argv)
virtual CallbackInterface::CallResult call()
bool sleep() const
void push(const SubscriptionCallbackHelperPtr &helper, const MessageDeserializerPtr &deserializer, bool has_tracked_object, const VoidConstWPtr &tracked_object, bool nonconst_need_copy, ros::Time receipt_time=ros::Time(), bool *was_full=0)
virtual const std::string __getMD5Sum() const
virtual bool hasHeader()
boost::weak_ptr< void const > VoidConstWPtr
boost::shared_ptr< FakeSubHelper > FakeSubHelperPtr
virtual const std::type_info & getTypeInfo()
void callThread(SubscriptionQueue &queue)
virtual std::string getMD5Sum()
virtual bool ready()
void waitForASecond()
virtual const std::string __getDataType() const
void clearInCallbackCallback(SubscriptionQueue &queue)
void clearWhileThreadIsBlockingCallback(bool *done, boost::barrier *barrier)
ros::WallTime t
virtual void call(SubscriptionCallbackHelperCallParams &params)
TEST(SubscriptionQueue, queueSize)
virtual uint8_t * deserialize(uint8_t *read_ptr)


test_roscpp
Author(s): Morgan Quigley, Josh Faust, Brian Gerkey, Troy Straszheim, Dirk Thomas
autogenerated on Mon Nov 2 2020 03:52:46