def test_Subscriber_unregister(self): # regression test for #3029 (unregistering a Subcriber with no # callback) plus other unregistration tests import rospy from rospy.impl.registration import get_topic_manager, Registration from rospy.topics import Subscriber, DEFAULT_BUFF_SIZE #Subscriber: name, data_class, callback=None, callback_args=None, #queue_size=None, buff_size=DEFAULT_BUFF_SIZE, tcp_nodelay=False): name = 'unregistertest' rname = rospy.resolve_name(name) data_class = test_rospy.msg.Val sub = Subscriber(name, data_class) self.assertEquals(None, sub.callback) # verify impl (test_Subscriber handles more verification, we # just care about callbacks and ref_count state here) impl = get_topic_manager().get_impl(Registration.SUB, rname) self.assert_(impl == sub.impl) self.assertEquals(1, impl.ref_count) self.assertEquals([], impl.callbacks) # unregister should release the underlying impl sub.unregister() self.assertEquals( None, get_topic_manager().get_impl(Registration.SUB, rname)) # create two subs sub2 = Subscriber(name, data_class) sub3 = Subscriber(name, data_class) impl = get_topic_manager().get_impl(Registration.SUB, rname) # - test that they share the same impl self.assert_(impl == sub2.impl) self.assert_(impl == sub3.impl) # - test basic impl state self.assertEquals([], impl.callbacks) self.assertEquals(2, impl.ref_count) sub2.unregister() self.assertEquals(1, impl.ref_count) # - make sure double unregister is safe sub2.unregister() self.assertEquals(1, impl.ref_count) # - clean it up sub3.unregister() self.assertEquals(0, impl.ref_count) self.assertEquals( None, get_topic_manager().get_impl(Registration.SUB, rname)) # CALLBACKS cb_args5 = 5 cb_args6 = 6 cb_args7 = 7 sub4 = Subscriber(name, data_class, callback1) # - use should be allowed to subcribe using the same callback # and it shouldn't interfere on unregister sub5 = Subscriber(name, data_class, callback2, cb_args5) sub6 = Subscriber(name, data_class, callback2, cb_args6) sub7 = Subscriber(name, data_class, callback2, cb_args7) impl = get_topic_manager().get_impl(Registration.SUB, rname) self.assertEquals(4, impl.ref_count) self.assertEquals([(callback1, None), (callback2, cb_args5), (callback2, cb_args6), (callback2, cb_args7)], impl.callbacks) # unregister sub6 first to as it is most likely to confuse any callback-finding logic sub6.unregister() self.assertEquals([(callback1, None), (callback2, cb_args5), (callback2, cb_args7)], impl.callbacks) self.assertEquals(3, impl.ref_count) sub5.unregister() self.assertEquals([(callback1, None), (callback2, cb_args7)], impl.callbacks) self.assertEquals(2, impl.ref_count) sub4.unregister() self.assertEquals([(callback2, cb_args7)], impl.callbacks) self.assertEquals(1, impl.ref_count) sub7.unregister() self.assertEquals([], impl.callbacks) self.assertEquals(0, impl.ref_count) self.assertEquals( None, get_topic_manager().get_impl(Registration.SUB, rname)) # one final condition: two identical subscribers sub8 = Subscriber(name, data_class, callback1, 'hello') sub9 = Subscriber(name, data_class, callback1, 'hello') impl = get_topic_manager().get_impl(Registration.SUB, rname) self.assertEquals([(callback1, 'hello'), (callback1, 'hello')], impl.callbacks) self.assertEquals(2, impl.ref_count) sub8.unregister() self.assertEquals([(callback1, 'hello')], impl.callbacks) self.assertEquals(1, impl.ref_count) sub9.unregister() self.assertEquals([], impl.callbacks) self.assertEquals(0, impl.ref_count)
def test_Subscriber(self): #TODO: test callback args #TODO: negative buff_size #TODO: negative queue_size import rospy from rospy.impl.registration import get_topic_manager, Registration from rospy.topics import Subscriber, DEFAULT_BUFF_SIZE #Subscriber: name, data_class, callback=None, callback_args=None, #queue_size=None, buff_size=DEFAULT_BUFF_SIZE, tcp_nodelay=False): name = 'foo' rname = rospy.resolve_name('foo') data_class = test_rospy.msg.Val # test invalid params for n in [None, '', 1]: try: Subscriber(n, data_class) self.fail("should not allow invalid name") except ValueError: pass for d in [None, 1, TestRospyTopics]: try: Subscriber(name, d) self.fail("should now allow invalid data_class") except ValueError: pass try: Subscriber(name, None) self.fail("None should not be allowed for data_class") except ValueError: pass sub = Subscriber(name, data_class) self.assertEquals(rname, sub.resolved_name) self.assertEquals(data_class, sub.data_class) self.assertEquals('test_rospy/Val', sub.type) self.assertEquals(data_class._md5sum, sub.md5sum) self.assertEquals(Registration.SUB, sub.reg_type) # verify impl as well impl = get_topic_manager().get_impl(Registration.SUB, rname) self.assert_(impl == sub.impl) self.assertEquals([], impl.callbacks) self.assertEquals(rname, impl.resolved_name) self.assertEquals(data_class, impl.data_class) self.assertEquals(None, impl.queue_size) self.assertEquals(DEFAULT_BUFF_SIZE, impl.buff_size) self.failIf(impl.tcp_nodelay) self.assertEquals(1, impl.ref_count) self.failIf(impl.closed) # round 2, now start setting options and make sure underlying impl is reconfigured name = 'foo' data_class = test_rospy.msg.Val queue_size = 1 buff_size = 1 sub = Subscriber(name, data_class, callback=callback1, queue_size=queue_size, buff_size=buff_size, tcp_nodelay=True) self.assertEquals(rname, sub.resolved_name) # - sub.name is a backwards-compat field as it is public API self.assertEquals(rname, sub.name) self.assertEquals(data_class, sub.data_class) # verify impl impl2 = get_topic_manager().get_impl(Registration.SUB, rname) self.assert_(impl == impl2) # should be same instance self.assertEquals([(callback1, None)], impl.callbacks) self.assertEquals(rname, impl.resolved_name) self.assertEquals(data_class, impl.data_class) self.assertEquals(queue_size, impl.queue_size) self.assertEquals(buff_size, impl.buff_size) self.assert_(impl.tcp_nodelay) self.assertEquals(2, impl.ref_count) self.failIf(impl.closed) # round 3, make sure that options continue to reconfigure # underlying impl also test that tcp_nodelay is sticky. this # is technically undefined, but this is how rospy chose to # implement. name = 'foo' data_class = test_rospy.msg.Val queue_size = 2 buff_size = 2 sub = Subscriber(name, data_class, callback=callback2, queue_size=queue_size, buff_size=buff_size, tcp_nodelay=False) # verify impl impl2 = get_topic_manager().get_impl(Registration.SUB, rname) self.assert_(impl == impl2) # should be same instance self.assertEquals(set([(callback1, None), (callback2, None)]), set(impl.callbacks)) self.assertEquals(queue_size, impl.queue_size) self.assertEquals(buff_size, impl.buff_size) self.assert_(impl.tcp_nodelay) self.assertEquals(3, impl.ref_count) self.failIf(impl.closed)
def test_Subscriber_unregister(self): # regression test for #3029 (unregistering a Subcriber with no # callback) plus other unregistration tests import rospy from rospy.impl.registration import get_topic_manager, Registration from rospy.topics import Subscriber, DEFAULT_BUFF_SIZE #Subscriber: name, data_class, callback=None, callback_args=None, #queue_size=None, buff_size=DEFAULT_BUFF_SIZE, tcp_nodelay=False): name = 'unregistertest' rname = rospy.resolve_name(name) data_class = test_rospy.msg.Val sub = Subscriber(name, data_class) self.assertEquals(None, sub.callback) # verify impl (test_Subscriber handles more verification, we # just care about callbacks and ref_count state here) impl = get_topic_manager().get_impl(Registration.SUB, rname) self.assert_(impl == sub.impl) self.assertEquals(1, impl.ref_count) self.assertEquals([], impl.callbacks) # unregister should release the underlying impl sub.unregister() self.assertEquals(None, get_topic_manager().get_impl(Registration.SUB, rname)) # create two subs sub2 = Subscriber(name, data_class) sub3 = Subscriber(name, data_class) impl = get_topic_manager().get_impl(Registration.SUB, rname) # - test that they share the same impl self.assert_(impl == sub2.impl) self.assert_(impl == sub3.impl) # - test basic impl state self.assertEquals([], impl.callbacks) self.assertEquals(2, impl.ref_count) sub2.unregister() self.assertEquals(1, impl.ref_count) # - make sure double unregister is safe sub2.unregister() self.assertEquals(1, impl.ref_count) # - clean it up sub3.unregister() self.assertEquals(0, impl.ref_count) self.assertEquals(None, get_topic_manager().get_impl(Registration.SUB, rname)) # CALLBACKS cb_args5 = 5 cb_args6 = 6 cb_args7 = 7 sub4 = Subscriber(name, data_class, callback1) # - use should be allowed to subcribe using the same callback # and it shouldn't interfere on unregister sub5 = Subscriber(name, data_class, callback2, cb_args5) sub6 = Subscriber(name, data_class, callback2, cb_args6) sub7 = Subscriber(name, data_class, callback2, cb_args7) impl = get_topic_manager().get_impl(Registration.SUB, rname) self.assertEquals(4, impl.ref_count) self.assertEquals([(callback1, None), (callback2, cb_args5), (callback2, cb_args6), (callback2, cb_args7)], impl.callbacks) # unregister sub6 first to as it is most likely to confuse any callback-finding logic sub6.unregister() self.assertEquals([(callback1, None), (callback2, cb_args5), (callback2, cb_args7)], impl.callbacks) self.assertEquals(3, impl.ref_count) sub5.unregister() self.assertEquals([(callback1, None), (callback2, cb_args7)], impl.callbacks) self.assertEquals(2, impl.ref_count) sub4.unregister() self.assertEquals([(callback2, cb_args7)], impl.callbacks) self.assertEquals(1, impl.ref_count) sub7.unregister() self.assertEquals([], impl.callbacks) self.assertEquals(0, impl.ref_count) self.assertEquals(None, get_topic_manager().get_impl(Registration.SUB, rname)) # one final condition: two identical subscribers sub8 = Subscriber(name, data_class, callback1, 'hello') sub9 = Subscriber(name, data_class, callback1, 'hello') impl = get_topic_manager().get_impl(Registration.SUB, rname) self.assertEquals([(callback1, 'hello'), (callback1, 'hello')], impl.callbacks) self.assertEquals(2, impl.ref_count) sub8.unregister() self.assertEquals([(callback1, 'hello')], impl.callbacks) self.assertEquals(1, impl.ref_count) sub9.unregister() self.assertEquals([], impl.callbacks) self.assertEquals(0, impl.ref_count)