v01
This commit is contained in:
65
thirdparty/ros/ros_comm/test/test_rosbag/test/connection_count.py
vendored
Executable file
65
thirdparty/ros/ros_comm/test/test_rosbag/test/connection_count.py
vendored
Executable file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python
|
||||
# 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 Willow Garage, Inc. 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.
|
||||
|
||||
import unittest
|
||||
import rosunit
|
||||
import sys
|
||||
import time
|
||||
import subprocess
|
||||
|
||||
class ConnectionCount(unittest.TestCase):
|
||||
|
||||
def test_connection_count(self):
|
||||
# Wait while the recorder creates a bag for us to examine
|
||||
time.sleep(10.0)
|
||||
|
||||
# Check the connection count returned by `rosbag info`
|
||||
# We could probably do this through the rosbag Python API...
|
||||
cmd = ['rosbag', 'info',
|
||||
'/tmp/test_rosbag_record_two_publishers.bag',
|
||||
'-y', '-k', 'topics']
|
||||
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
out,err = p.communicate()
|
||||
self.assertEqual(p.returncode, 0, 'Failed to check bag\ncmd=%s\nstdout=%s\nstderr=%s'%(cmd,out,err))
|
||||
|
||||
conns = False
|
||||
for l in out.decode().split('\n'):
|
||||
f = l.strip().split(': ')
|
||||
if len(f) == 2 and f[0] == 'connections':
|
||||
conns = int(f[1])
|
||||
break
|
||||
|
||||
self.assertEqual(conns, 2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
rosunit.unitrun('test_rosbag', 'connection_count', ConnectionCount, sys.argv)
|
||||
22
thirdparty/ros/ros_comm/test/test_rosbag/test/double_pub.cpp
vendored
Normal file
22
thirdparty/ros/ros_comm/test/test_rosbag/test/double_pub.cpp
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
#include <ros/ros.h>
|
||||
#include <std_msgs/String.h>
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
ros::init(argc, argv, "double_pub");
|
||||
ros::NodeHandle n;
|
||||
ros::Publisher p1 = n.advertise<std_msgs::String>("chatter", 1);
|
||||
ros::Publisher p2 = n.advertise<std_msgs::String>("rettahc", 1);
|
||||
|
||||
ros::Rate r(10.0);
|
||||
while(ros::ok())
|
||||
{
|
||||
std_msgs::String s;
|
||||
s.data = "hello";
|
||||
p1.publish(s);
|
||||
s.data = "goodbye";
|
||||
p2.publish(s);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
56
thirdparty/ros/ros_comm/test/test_rosbag/test/latched_pub.py
vendored
Executable file
56
thirdparty/ros/ros_comm/test/test_rosbag/test/latched_pub.py
vendored
Executable file
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python
|
||||
# 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 Willow Garage, Inc. 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.
|
||||
|
||||
import unittest
|
||||
import rospy
|
||||
import rostest
|
||||
import sys
|
||||
from std_msgs.msg import *
|
||||
|
||||
class LatchedPub(unittest.TestCase):
|
||||
|
||||
def test_latched_pub(self):
|
||||
rospy.init_node('latched_pub')
|
||||
|
||||
# Wait a while before publishing
|
||||
rospy.sleep(rospy.Duration.from_sec(5.0))
|
||||
|
||||
pub= rospy.Publisher("chatter", String, latch=True)
|
||||
|
||||
pub.publish(String("hello"))
|
||||
|
||||
rospy.sleep(rospy.Duration.from_sec(5.0))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
rostest.rosrun('test_rosbag', 'latched_pub', LatchedPub, sys.argv)
|
||||
4
thirdparty/ros/ros_comm/test/test_rosbag/test/latched_pub.test
vendored
Normal file
4
thirdparty/ros/ros_comm/test/test_rosbag/test/latched_pub.test
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<launch>
|
||||
<node name="recorder" pkg="rosbag" type="record" args="chatter -O /tmp/test_rosbag_latched_pub"/>
|
||||
<test test-name="latched_pub" pkg="test_rosbag" type="latched_pub.py"/>
|
||||
</launch>
|
||||
60
thirdparty/ros/ros_comm/test/test_rosbag/test/latched_sub.py
vendored
Executable file
60
thirdparty/ros/ros_comm/test/test_rosbag/test/latched_sub.py
vendored
Executable file
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env python
|
||||
# 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 Willow Garage, Inc. 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.
|
||||
|
||||
import unittest
|
||||
import rospy
|
||||
import rostest
|
||||
import sys
|
||||
from std_msgs.msg import *
|
||||
|
||||
class LatchedSub(unittest.TestCase):
|
||||
|
||||
def msg_cb(self, msg):
|
||||
self.success = True
|
||||
|
||||
|
||||
def test_latched_sub(self):
|
||||
rospy.init_node('random_sub')
|
||||
|
||||
self.success = False
|
||||
|
||||
rospy.sleep(rospy.Duration.from_sec(5.0))
|
||||
|
||||
sub = rospy.Subscriber("chatter", String, self.msg_cb)
|
||||
|
||||
rospy.sleep(rospy.Duration.from_sec(5.0))
|
||||
|
||||
self.assertEqual(self.success, True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
rostest.rosrun('rosbag', 'lateched_sub', LatchedSub, sys.argv)
|
||||
4
thirdparty/ros/ros_comm/test/test_rosbag/test/latched_sub.test.in
vendored
Normal file
4
thirdparty/ros/ros_comm/test/test_rosbag/test/latched_sub.test.in
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<launch>
|
||||
<node name="player" pkg="rosbag" type="play" args="@PROJECT_BINARY_DIR@/test/test_rosbag_latched_pub.bag --keep-alive"/>
|
||||
<test test-name="latched_sub" pkg="test_rosbag" type="latched_sub.py"/>
|
||||
</launch>
|
||||
9
thirdparty/ros/ros_comm/test/test_rosbag/test/play_play.test.in
vendored
Normal file
9
thirdparty/ros/ros_comm/test/test_rosbag/test/play_play.test.in
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<launch>
|
||||
<node name="player" pkg="rosbag" type="play" args="@PROJECT_BINARY_DIR@/test/chatter_50hz.bag"/>
|
||||
<test test-name="play_hztest" pkg="rostest" type="hztest">
|
||||
<param name="topic" value="chatter"/>
|
||||
<param name="hz" value="50.0"/>
|
||||
<param name="hzerror" value="5"/>
|
||||
<param name="test_duration" value="7.0" />
|
||||
</test>
|
||||
</launch>
|
||||
7
thirdparty/ros/ros_comm/test/test_rosbag/test/record_one_publisher_two_topics.test
vendored
Normal file
7
thirdparty/ros/ros_comm/test/test_rosbag/test/record_one_publisher_two_topics.test
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<launch>
|
||||
<node pkg="test_rosbag" type="double_pub" name="double_pub"/>
|
||||
<node name="recorder" pkg="rosbag" type="record" output="screen"
|
||||
args="chatter rettahc -O /tmp/test_rosbag_record_one_publisher_two_topics --duration=5"/>
|
||||
<test test-name="topic_count" pkg="test_rosbag" type="topic_count.py"/>
|
||||
</launch>
|
||||
|
||||
10
thirdparty/ros/ros_comm/test/test_rosbag/test/record_two_publishers.test
vendored
Normal file
10
thirdparty/ros/ros_comm/test/test_rosbag/test/record_two_publishers.test
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<launch>
|
||||
<node pkg="rostopic" type="rostopic" name="rostopic_pub1"
|
||||
args="pub -r 10 chatter std_msgs/String chatter1"/>
|
||||
<node pkg="rostopic" type="rostopic" name="rostopic_pub2"
|
||||
args="pub -r 10 chatter std_msgs/String chatter2"/>
|
||||
<node name="recorder" pkg="rosbag" type="record"
|
||||
args="chatter -O /tmp/test_rosbag_record_two_publishers --duration=5"/>
|
||||
<test test-name="connection_count" pkg="test_rosbag" type="connection_count.py"/>
|
||||
</launch>
|
||||
|
||||
9
thirdparty/ros/ros_comm/test/test_rosbag/test/rosbag_play.test.in
vendored
Normal file
9
thirdparty/ros/ros_comm/test/test_rosbag/test/rosbag_play.test.in
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<launch>
|
||||
<node name="player" pkg="rosbag" type="rosbag" args="play @PROJECT_BINARY_DIR@/test/chatter_50hz.bag"/>
|
||||
<test test-name="rosbag_play_hztest" pkg="rostest" type="hztest">
|
||||
<param name="topic" value="chatter"/>
|
||||
<param name="hz" value="50.0"/>
|
||||
<param name="hzerror" value="5"/>
|
||||
<param name="test_duration" value="7.0" />
|
||||
</test>
|
||||
</launch>
|
||||
657
thirdparty/ros/ros_comm/test/test_rosbag/test/test_bag.cpp.in
vendored
Normal file
657
thirdparty/ros/ros_comm/test/test_rosbag/test/test_bag.cpp.in
vendored
Normal file
@@ -0,0 +1,657 @@
|
||||
// Copyright (c) 2010, 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 Willow Garage, Inc. 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.
|
||||
|
||||
#include "ros/ros.h"
|
||||
#include "rosbag/bag.h"
|
||||
#include "rosbag/chunked_file.h"
|
||||
#include "rosbag/view.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
#include <boost/assign/list_of.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "std_msgs/String.h"
|
||||
#include "std_msgs/Int32.h"
|
||||
|
||||
#define foreach BOOST_FOREACH
|
||||
|
||||
class BagTest : public testing::Test
|
||||
{
|
||||
protected:
|
||||
std_msgs::String foo_, bar_;
|
||||
std_msgs::Int32 i_;
|
||||
|
||||
virtual void SetUp() {
|
||||
foo_.data = std::string("foo");
|
||||
bar_.data = std::string("bar");
|
||||
i_.data = 42;
|
||||
}
|
||||
|
||||
void dumpContents(std::string const& filename) {
|
||||
rosbag::Bag b;
|
||||
b.open(filename, rosbag::bagmode::Read);
|
||||
dumpContents(b);
|
||||
b.close();
|
||||
}
|
||||
|
||||
void dumpContents(rosbag::Bag& b) {
|
||||
rosbag::View view(b);
|
||||
foreach(rosbag::MessageInstance m, view)
|
||||
std::cout << m.getTime() << ": [" << m.getTopic() << "]" << std::endl;
|
||||
}
|
||||
|
||||
void checkContents(std::string const& filename) {
|
||||
rosbag::Bag b;
|
||||
b.open(filename, rosbag::bagmode::Read);
|
||||
|
||||
int message_count = 0;
|
||||
|
||||
rosbag::View view(b);
|
||||
foreach(rosbag::MessageInstance m, view) {
|
||||
std_msgs::String::ConstPtr s = m.instantiate<std_msgs::String>();
|
||||
if (s != NULL) {
|
||||
ASSERT_EQ(s->data, foo_.data);
|
||||
message_count++;
|
||||
}
|
||||
std_msgs::Int32::ConstPtr i = m.instantiate<std_msgs::Int32>();
|
||||
if (i != NULL) {
|
||||
ASSERT_EQ(i->data, i_.data);
|
||||
message_count++;
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(message_count, 2);
|
||||
|
||||
b.close();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(BagTest, write_then_read_works) {
|
||||
std::string filename("/tmp/write_then_read_works.bag");
|
||||
|
||||
rosbag::Bag b1;
|
||||
b1.open(filename, rosbag::bagmode::Write);
|
||||
b1.write("chatter", ros::Time::now(), foo_);
|
||||
b1.write("numbers", ros::Time::now(), i_);
|
||||
b1.close();
|
||||
|
||||
checkContents(filename);
|
||||
}
|
||||
|
||||
TEST_F(BagTest, append_works) {
|
||||
std::string filename("/tmp/append_works.bag");
|
||||
|
||||
rosbag::Bag b1;
|
||||
b1.open(filename, rosbag::bagmode::Write);
|
||||
b1.write("chatter", ros::Time::now(), foo_);
|
||||
b1.close();
|
||||
|
||||
rosbag::Bag b2;
|
||||
b2.open(filename, rosbag::bagmode::Append);
|
||||
b2.write("numbers", ros::Time::now(), i_);
|
||||
b2.close();
|
||||
|
||||
checkContents(filename);
|
||||
}
|
||||
|
||||
TEST_F(BagTest, different_writes) {
|
||||
std::string filename("/tmp/different_writes.bag");
|
||||
|
||||
rosbag::Bag b1;
|
||||
b1.open(filename, rosbag::bagmode::Write | rosbag::bagmode::Read);
|
||||
|
||||
std_msgs::String msg1;
|
||||
std_msgs::String::Ptr msg2 = boost::make_shared<std_msgs::String>();
|
||||
std_msgs::String::ConstPtr msg3 = boost::make_shared<std_msgs::String const>();
|
||||
|
||||
rosbag::View view;
|
||||
view.addQuery(b1);
|
||||
|
||||
b1.write("t1", ros::Time::now(), msg1);
|
||||
b1.write("t2", ros::Time::now(), msg2);
|
||||
b1.write("t3", ros::Time::now(), msg3);
|
||||
b1.write("t4", ros::Time::now(), *view.begin());
|
||||
|
||||
ASSERT_EQ(view.size(), (uint32_t)(4));
|
||||
|
||||
b1.close();
|
||||
}
|
||||
|
||||
TEST_F(BagTest, reopen_works) {
|
||||
rosbag::Bag b;
|
||||
|
||||
std::string filename1("/tmp/reopen_works1.bag");
|
||||
b.open(filename1, rosbag::bagmode::Write);
|
||||
b.write("chatter", ros::Time::now(), foo_);
|
||||
b.write("numbers", ros::Time::now(), i_);
|
||||
b.close();
|
||||
|
||||
std::string filename2("/tmp/reopen_works1.bag");
|
||||
b.open(filename2, rosbag::bagmode::Write);
|
||||
b.write("chatter", ros::Time::now(), foo_);
|
||||
b.write("numbers", ros::Time::now(), i_);
|
||||
b.close();
|
||||
|
||||
checkContents(filename1);
|
||||
checkContents(filename2);
|
||||
}
|
||||
|
||||
TEST_F(BagTest, bag_not_open_fails) {
|
||||
rosbag::Bag b;
|
||||
try
|
||||
{
|
||||
b.write("/test", ros::Time::now(), foo_);
|
||||
FAIL();
|
||||
}
|
||||
catch (rosbag::BagIOException ex) {
|
||||
SUCCEED();
|
||||
}
|
||||
}
|
||||
|
||||
TEST(rosbag, simple_write_and_read_works) {
|
||||
rosbag::Bag b1("/tmp/simple_write_and_read_works.bag", rosbag::bagmode::Write);
|
||||
|
||||
std_msgs::String str;
|
||||
str.data = std::string("foo");
|
||||
|
||||
std_msgs::Int32 i;
|
||||
i.data = 42;
|
||||
|
||||
b1.write("chatter", ros::Time::now(), str);
|
||||
b1.write("numbers", ros::Time::now(), i);
|
||||
|
||||
b1.close();
|
||||
|
||||
rosbag::Bag b2("/tmp/simple_write_and_read_works.bag", rosbag::bagmode::Read);
|
||||
|
||||
std::vector<std::string> topics;
|
||||
topics.push_back(std::string("chatter"));
|
||||
topics.push_back(std::string("numbers"));
|
||||
|
||||
int count = 0;
|
||||
rosbag::View view(b2, rosbag::TopicQuery(topics));
|
||||
foreach(rosbag::MessageInstance const m, view) {
|
||||
std_msgs::String::ConstPtr s = m.instantiate<std_msgs::String>();
|
||||
if (s != NULL)
|
||||
{
|
||||
count++;
|
||||
ASSERT_EQ(s->data, std::string("foo"));
|
||||
}
|
||||
|
||||
std_msgs::Int32::ConstPtr i = m.instantiate<std_msgs::Int32>();
|
||||
if (i != NULL)
|
||||
{
|
||||
count++;
|
||||
ASSERT_EQ(i->data, 42);
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT_EQ(count,2);
|
||||
|
||||
b2.close();
|
||||
}
|
||||
|
||||
TEST(rosbag, append_indexed_1_2_fails) {
|
||||
try{
|
||||
rosbag::Bag b("@PROJECT_BINARY_DIR@/test/test_indexed_1.2.bag", rosbag::bagmode::Append);
|
||||
|
||||
FAIL();
|
||||
}
|
||||
catch (rosbag::BagException ex) {
|
||||
SUCCEED();
|
||||
}
|
||||
}
|
||||
|
||||
TEST(rosbag, read_indexed_1_2_succeeds) {
|
||||
rosbag::Bag b("@PROJECT_BINARY_DIR@/test/test_indexed_1.2.bag", rosbag::bagmode::Read);
|
||||
rosbag::View view(b);
|
||||
|
||||
int32_t i = 0;
|
||||
|
||||
foreach(rosbag::MessageInstance const m, view) {
|
||||
std_msgs::Int32::ConstPtr imsg = m.instantiate<std_msgs::Int32>();
|
||||
if (imsg != NULL)
|
||||
ASSERT_EQ(imsg->data, i++);
|
||||
}
|
||||
|
||||
b.close();
|
||||
}
|
||||
|
||||
|
||||
TEST(rosbag, write_then_read_without_read_mode_fails) {
|
||||
rosbag::Bag b("/tmp/write_then_read_without_read_mode_fails.bag", rosbag::bagmode::Write);
|
||||
std_msgs::String str;
|
||||
str.data = std::string("foo");
|
||||
b.write("chatter", ros::Time::now(), str);
|
||||
|
||||
try
|
||||
{
|
||||
rosbag::View view(b);
|
||||
foreach(rosbag::MessageInstance const m, view) {
|
||||
std_msgs::String::ConstPtr s = m.instantiate<std_msgs::String>();
|
||||
if (s != NULL)
|
||||
ASSERT_EQ(s->data, std::string("foo"));
|
||||
}
|
||||
FAIL();
|
||||
}
|
||||
catch (rosbag::BagException ex) {
|
||||
SUCCEED();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(BagTest, read_then_write_without_write_mode_fails) {
|
||||
rosbag::Bag b1("/tmp/read_then_write_without_write_mode_fails.bag", rosbag::bagmode::Write);
|
||||
b1.write("chatter", ros::Time::now(), foo_);
|
||||
b1.close();
|
||||
|
||||
rosbag::Bag b2("/tmp/read_then_write_without_write_mode_fails.bag", rosbag::bagmode::Read);
|
||||
try
|
||||
{
|
||||
b2.write("chatter", ros::Time::now(), foo_);
|
||||
FAIL();
|
||||
}
|
||||
catch (rosbag::BagException ex) {
|
||||
SUCCEED();
|
||||
}
|
||||
}
|
||||
|
||||
TEST(rosbag, time_query_works) {
|
||||
rosbag::Bag outbag;
|
||||
outbag.open("/tmp/time_query_works.bag", rosbag::bagmode::Write);
|
||||
|
||||
std_msgs::Int32 imsg;
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
imsg.data = i;
|
||||
switch (rand() % 5) {
|
||||
case 0: outbag.write("t0", ros::Time(i, 1), imsg); break;
|
||||
case 1: outbag.write("t1", ros::Time(i, 1), imsg); break;
|
||||
case 2: outbag.write("t2", ros::Time(i, 1), imsg); break;
|
||||
case 3: outbag.write("t2", ros::Time(i, 1), imsg); break;
|
||||
case 4: outbag.write("t4", ros::Time(i, 1), imsg); break;
|
||||
}
|
||||
}
|
||||
outbag.close();
|
||||
|
||||
rosbag::Bag bag;
|
||||
bag.open("/tmp/time_query_works.bag", rosbag::bagmode::Read);
|
||||
|
||||
int i = 23;
|
||||
|
||||
rosbag::View view(bag, ros::Time(23, 1), ros::Time(782, 1));
|
||||
foreach(rosbag::MessageInstance const m, view) {
|
||||
std_msgs::Int32::ConstPtr imsg = m.instantiate<std_msgs::Int32>();
|
||||
if (imsg != NULL) {
|
||||
ASSERT_EQ(imsg->data, i++);
|
||||
ASSERT_TRUE(m.getTime() < ros::Time(783,0));
|
||||
}
|
||||
}
|
||||
|
||||
bag.close();
|
||||
}
|
||||
|
||||
TEST(rosbag, topic_query_works) {
|
||||
rosbag::Bag outbag;
|
||||
outbag.open("/tmp/topic_query_works.bag", rosbag::bagmode::Write);
|
||||
|
||||
std_msgs::Int32 imsg;
|
||||
|
||||
int j0 = 0;
|
||||
int j1 = 0;
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
switch (rand() % 5) {
|
||||
case 0: imsg.data = j0++; outbag.write("t0", ros::Time(i, 1), imsg); break;
|
||||
case 1: imsg.data = j0++; outbag.write("t1", ros::Time(i, 1), imsg); break;
|
||||
case 2: imsg.data = j1++; outbag.write("t2", ros::Time(i, 1), imsg); break;
|
||||
case 3: imsg.data = j1++; outbag.write("t3", ros::Time(i, 1), imsg); break;
|
||||
case 4: imsg.data = j1++; outbag.write("t4", ros::Time(i, 1), imsg); break;
|
||||
}
|
||||
}
|
||||
outbag.close();
|
||||
|
||||
rosbag::Bag bag;
|
||||
bag.open("/tmp/topic_query_works.bag", rosbag::bagmode::Read);
|
||||
|
||||
std::vector<std::string> t = boost::assign::list_of("t0")("t1");
|
||||
|
||||
int i = 0;
|
||||
|
||||
rosbag::View view(bag, rosbag::TopicQuery(t));
|
||||
foreach(rosbag::MessageInstance const m, view) {
|
||||
std_msgs::Int32::ConstPtr imsg = m.instantiate<std_msgs::Int32>();
|
||||
if (imsg != NULL)
|
||||
ASSERT_EQ(imsg->data, i++);
|
||||
}
|
||||
|
||||
bag.close();
|
||||
}
|
||||
|
||||
|
||||
TEST(rosbag, bad_topic_query_works) {
|
||||
rosbag::Bag outbag;
|
||||
outbag.open("/tmp/bad_topic_query_works.bag", rosbag::bagmode::Write);
|
||||
|
||||
std_msgs::Int32 imsg;
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
outbag.write("t0", ros::Time(i, 1), imsg);
|
||||
}
|
||||
outbag.close();
|
||||
|
||||
rosbag::Bag bag;
|
||||
bag.open("/tmp/bad_topic_query_works.bag", rosbag::bagmode::Read);
|
||||
|
||||
std::vector<std::string> t = boost::assign::list_of("t1");
|
||||
|
||||
rosbag::View view(bag, rosbag::TopicQuery(t));
|
||||
foreach(rosbag::MessageInstance const m, view) {
|
||||
(void)m;
|
||||
FAIL();
|
||||
}
|
||||
|
||||
bag.close();
|
||||
}
|
||||
|
||||
//This test fails on the storm machines
|
||||
/*
|
||||
TEST(rosbag, incremental_time) {
|
||||
ros::Time last = ros::Time::now();
|
||||
ros::Time next = ros::Time::now();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
next = ros::Time::now();
|
||||
ASSERT_TRUE(last != next);
|
||||
last = next;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
TEST(rosbag, multiple_bag_works) {
|
||||
rosbag::Bag outbag1("/tmp/multiple_bag_works1.bag", rosbag::bagmode::Write);
|
||||
rosbag::Bag outbag2("/tmp/multiple_bag_works2.bag", rosbag::bagmode::Write);
|
||||
|
||||
std_msgs::Int32 imsg;
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
imsg.data = i;
|
||||
switch (rand() % 5) {
|
||||
case 0: outbag1.write("t0", ros::Time(0,i+1), imsg); break;
|
||||
case 1: outbag1.write("t1", ros::Time(0,i+1), imsg); break;
|
||||
case 2: outbag1.write("t2", ros::Time(0,i+1), imsg); break;
|
||||
case 3: outbag2.write("t0", ros::Time(0,i+1), imsg); break;
|
||||
case 4: outbag2.write("t1", ros::Time(0,i+1), imsg); break;
|
||||
}
|
||||
}
|
||||
|
||||
outbag1.close();
|
||||
outbag2.close();
|
||||
|
||||
rosbag::Bag bag1("/tmp/multiple_bag_works1.bag", rosbag::bagmode::Read);
|
||||
rosbag::Bag bag2("/tmp/multiple_bag_works2.bag", rosbag::bagmode::Read);
|
||||
|
||||
rosbag::View view;
|
||||
view.addQuery(bag1);
|
||||
view.addQuery(bag2);
|
||||
|
||||
int i = 0;
|
||||
|
||||
foreach(rosbag::MessageInstance const m, view) {
|
||||
std_msgs::Int32::ConstPtr imsg = m.instantiate<std_msgs::Int32>();
|
||||
if (imsg != NULL)
|
||||
ASSERT_EQ(imsg->data, i++);
|
||||
}
|
||||
|
||||
bag1.close();
|
||||
bag2.close();
|
||||
}
|
||||
|
||||
|
||||
TEST(rosbag, overlapping_query_works) {
|
||||
rosbag::Bag outbag1("/tmp/overlapping_query_1.bag", rosbag::bagmode::Write);
|
||||
rosbag::Bag outbag2("/tmp/overlapping_query_2.bag", rosbag::bagmode::Write);
|
||||
|
||||
std_msgs::Int32 imsg;
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
imsg.data = i;
|
||||
switch (rand() % 5) {
|
||||
case 0: outbag1.write("t0", ros::Time(i+1), imsg); break;
|
||||
case 1: outbag1.write("t1", ros::Time(i+1), imsg); break;
|
||||
case 2: outbag1.write("t2", ros::Time(i+1), imsg); break;
|
||||
case 3: outbag2.write("t0", ros::Time(i+1), imsg); break;
|
||||
case 4: outbag2.write("t1", ros::Time(i+1), imsg); break;
|
||||
}
|
||||
}
|
||||
|
||||
outbag1.close();
|
||||
outbag2.close();
|
||||
|
||||
rosbag::Bag bag1("/tmp/overlapping_query_1.bag", rosbag::bagmode::Read);
|
||||
rosbag::Bag bag2("/tmp/overlapping_query_2.bag", rosbag::bagmode::Read);
|
||||
|
||||
rosbag::View view1(false);
|
||||
view1.addQuery(bag1, ros::Time(1), ros::Time(750));
|
||||
view1.addQuery(bag1, ros::Time(251), ros::Time(1002));
|
||||
view1.addQuery(bag2, ros::Time(1), ros::Time(750));
|
||||
view1.addQuery(bag2, ros::Time(251), ros::Time(1002));
|
||||
|
||||
rosbag::View view2(true);
|
||||
view2.addQuery(bag1, ros::Time(1), ros::Time(750));
|
||||
view2.addQuery(bag1, ros::Time(251), ros::Time(1002));
|
||||
view2.addQuery(bag2, ros::Time(1), ros::Time(750));
|
||||
view2.addQuery(bag2, ros::Time(251), ros::Time(1002));
|
||||
|
||||
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
foreach(rosbag::MessageInstance const m, view1) {
|
||||
std_msgs::Int32::ConstPtr imsg = m.instantiate<std_msgs::Int32>();
|
||||
if (imsg != NULL)
|
||||
ASSERT_EQ(imsg->data, i);
|
||||
if (i >= 250 && i < 750)
|
||||
{
|
||||
i += (j++ % 2);
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
foreach(rosbag::MessageInstance const m, view2) {
|
||||
std_msgs::Int32::ConstPtr imsg = m.instantiate<std_msgs::Int32>();
|
||||
if (imsg != NULL)
|
||||
ASSERT_EQ(imsg->data, i++);
|
||||
}
|
||||
|
||||
bag1.close();
|
||||
bag2.close();
|
||||
}
|
||||
|
||||
|
||||
TEST(rosbag, no_min_time) {
|
||||
rosbag::Bag outbag("/tmp/no_min_time.bag", rosbag::bagmode::Write);
|
||||
|
||||
std_msgs::Int32 imsg;
|
||||
try
|
||||
{
|
||||
outbag.write("t0", ros::Time(0,0), imsg);
|
||||
FAIL();
|
||||
} catch (rosbag::BagException& e)
|
||||
{
|
||||
SUCCEED();
|
||||
}
|
||||
|
||||
outbag.close();
|
||||
}
|
||||
|
||||
TEST(rosbag, modify_view_works) {
|
||||
rosbag::Bag outbag;
|
||||
outbag.open("/tmp/modify_view_works.bag", rosbag::bagmode::Write);
|
||||
|
||||
std_msgs::Int32 imsg;
|
||||
|
||||
int j0 = 0;
|
||||
int j1 = 1;
|
||||
|
||||
// Create a bag with 2 interlaced topics
|
||||
for (int i = 0; i < 100; i++) {
|
||||
imsg.data = j0;
|
||||
j0 += 2;
|
||||
outbag.write("t0", ros::Time(2 * i + 1, 0), imsg);
|
||||
|
||||
imsg.data = j1;
|
||||
j1 += 2;
|
||||
outbag.write("t1", ros::Time(2 * i + 2, 0), imsg);
|
||||
}
|
||||
outbag.close();
|
||||
|
||||
rosbag::Bag bag;
|
||||
bag.open("/tmp/modify_view_works.bag", rosbag::bagmode::Read);
|
||||
|
||||
std::vector<std::string> t0 = boost::assign::list_of("t0");
|
||||
std::vector<std::string> t1 = boost::assign::list_of("t1");
|
||||
|
||||
// We're going to skip the t1 for the first half
|
||||
j0 = 0;
|
||||
j1 = 101;
|
||||
|
||||
rosbag::View view(bag, rosbag::TopicQuery(t0));
|
||||
|
||||
rosbag::View::iterator iter = view.begin();
|
||||
|
||||
for (int i = 0; i < 50; i++) {
|
||||
std_msgs::Int32::ConstPtr imsg = iter->instantiate<std_msgs::Int32>();
|
||||
if (imsg != NULL) {
|
||||
ASSERT_EQ(imsg->data, j0);
|
||||
j0 += 2;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
|
||||
// We now add our query, and expect it to show up
|
||||
view.addQuery(bag, rosbag::TopicQuery(t1));
|
||||
|
||||
for (int i = 0; i < 50; i++) {
|
||||
std_msgs::Int32::ConstPtr imsg = iter->instantiate<std_msgs::Int32>();
|
||||
if (imsg != NULL) {
|
||||
ASSERT_EQ(imsg->data, j0);
|
||||
j0 += 2;
|
||||
}
|
||||
iter++;
|
||||
|
||||
imsg = iter->instantiate<std_msgs::Int32>();
|
||||
if (imsg != NULL) {
|
||||
ASSERT_EQ(imsg->data, j1);
|
||||
j1 += 2;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
|
||||
bag.close();
|
||||
}
|
||||
|
||||
TEST(rosbag, modify_bag_works) {
|
||||
rosbag::Bag rwbag("/tmp/modify_bag_works.bag", rosbag::bagmode::Write | rosbag::bagmode::Read);
|
||||
rwbag.setChunkThreshold(1);
|
||||
|
||||
std::vector<std::string> t0 = boost::assign::list_of("t0");
|
||||
|
||||
rosbag::View view(rwbag, rosbag::TopicQuery(t0));
|
||||
|
||||
std_msgs::Int32 omsg;
|
||||
|
||||
// Put a message at time 5
|
||||
omsg.data = 5;
|
||||
rwbag.write("t0", ros::Time(5 + 1, 0), omsg);
|
||||
|
||||
// Verify begin gets us to 5
|
||||
rosbag::View::iterator iter1 = view.begin();
|
||||
std_msgs::Int32::ConstPtr imsg = iter1->instantiate<std_msgs::Int32>();
|
||||
ASSERT_EQ(imsg->data, 5);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
omsg.data = i;
|
||||
rwbag.write("t0", ros::Time(i + 1, 0), omsg);
|
||||
}
|
||||
|
||||
// New iterator should be at 0
|
||||
rosbag::View::iterator iter2 = view.begin();
|
||||
imsg = iter2->instantiate<std_msgs::Int32>();
|
||||
ASSERT_EQ(imsg->data, 0);
|
||||
|
||||
// Increment it once
|
||||
iter2++;
|
||||
|
||||
// Output additional messages after time 5
|
||||
for (int i = 6; i < 10; i++) {
|
||||
omsg.data = i;
|
||||
rwbag.write("t0", ros::Time(i + 1, 0), omsg);
|
||||
}
|
||||
|
||||
// Iter2 should contain 1->10
|
||||
for (int i = 1; i < 10; i++) {
|
||||
imsg = iter2->instantiate<std_msgs::Int32>();
|
||||
ASSERT_EQ(imsg->data, i);
|
||||
iter2++;
|
||||
}
|
||||
|
||||
// Iter1 should contain 5->10
|
||||
for (int i = 5; i < 10; i++) {
|
||||
imsg = iter1->instantiate<std_msgs::Int32>();
|
||||
ASSERT_EQ(imsg->data, i);
|
||||
iter1++;
|
||||
}
|
||||
|
||||
rwbag.close();
|
||||
|
||||
rosbag::Bag rwbag2("/tmp/modify_bag_works.bag", rosbag::bagmode::Read);
|
||||
|
||||
rosbag::View view2(rwbag2, rosbag::TopicQuery(t0));
|
||||
|
||||
rosbag::View::iterator iter3 = view2.begin();
|
||||
imsg = iter3->instantiate<std_msgs::Int32>();
|
||||
// Iter2 should contain 1->10
|
||||
for (int i = 0; i < 10; i++) {
|
||||
imsg = iter3->instantiate<std_msgs::Int32>();
|
||||
ASSERT_EQ(imsg->data, i);
|
||||
iter3++;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
ros::init(argc, argv, "test_bag");
|
||||
ros::Time::init();
|
||||
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
438
thirdparty/ros/ros_comm/test/test_rosbag/test/test_bag.py
vendored
Executable file
438
thirdparty/ros/ros_comm/test/test_rosbag/test/test_bag.py
vendored
Executable file
@@ -0,0 +1,438 @@
|
||||
#!/usr/bin/env python
|
||||
# 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 Willow Garage, Inc. 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.
|
||||
#
|
||||
# test_bag.py
|
||||
|
||||
import hashlib
|
||||
import heapq
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
import unittest
|
||||
|
||||
import genpy
|
||||
|
||||
import rosbag
|
||||
from rosbag import bag
|
||||
import rospy
|
||||
from std_msgs.msg import Int32
|
||||
from std_msgs.msg import ColorRGBA
|
||||
from std_msgs.msg import String
|
||||
|
||||
class TestRosbag(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def test_opening_stream_works(self):
|
||||
f = open('/tmp/test_opening_stream_works.bag', 'wb')
|
||||
with rosbag.Bag(f, 'w') as b:
|
||||
for i in range(10):
|
||||
msg = Int32()
|
||||
msg.data = i
|
||||
b.write('/int', msg)
|
||||
|
||||
f = open('/tmp/test_opening_stream_works.bag', 'rb')
|
||||
b = rosbag.Bag(f, 'r')
|
||||
self.assert_(len(list(b.read_messages())) == 10)
|
||||
b.close()
|
||||
|
||||
def test_invalid_bag_arguments_fails(self):
|
||||
f = '/tmp/test_invalid_bad_arguments_fails.bag'
|
||||
|
||||
def fn1(): rosbag.Bag('')
|
||||
def fn2(): rosbag.Bag(None)
|
||||
def fn3(): rosbag.Bag(f, 'z')
|
||||
def fn4(): rosbag.Bag(f, 'r', compression='foobar')
|
||||
def fn5(): rosbag.Bag(f, 'r', chunk_threshold=-1000)
|
||||
for fn in [fn1, fn2, fn3, fn4, fn5]:
|
||||
self.failUnlessRaises(ValueError, fn)
|
||||
|
||||
def test_io_on_close_fails(self):
|
||||
def fn():
|
||||
b = rosbag.Bag('/tmp/test_io_close_fails.bag', 'w')
|
||||
b.close()
|
||||
size = b.size()
|
||||
self.failUnlessRaises(ValueError, fn)
|
||||
|
||||
def test_write_invalid_message_fails(self):
|
||||
def fn():
|
||||
with rosbag.Bag('/tmp/test_write_invalid_message_fails.bag', 'w') as b:
|
||||
b.write(None, None, None)
|
||||
self.failUnlessRaises(ValueError, fn)
|
||||
|
||||
def test_simple_write_uncompressed_works(self):
|
||||
with rosbag.Bag('/tmp/test_simple_write_uncompressed_works.bag', 'w') as b:
|
||||
msg_count = 0
|
||||
for i in range(5, 0, -1):
|
||||
msg = Int32()
|
||||
msg.data = i
|
||||
t = genpy.Time.from_sec(i)
|
||||
b.write('/ints' + str(i), msg, t)
|
||||
msg_count += 1
|
||||
|
||||
msgs = list(rosbag.Bag('/tmp/test_simple_write_uncompressed_works.bag').read_messages())
|
||||
|
||||
self.assert_(len(msgs) == msg_count, 'not all messages written: expected %d, got %d' % (msg_count, len(msgs)))
|
||||
|
||||
for (_, _, t1), (_, _, t2) in zip(msgs, msgs[1:]):
|
||||
self.assert_(t1 < t2, 'messages returned unordered: got timestamp %s before %s' % (str(t1), str(t2)))
|
||||
|
||||
def test_writing_nonchronological_works(self):
|
||||
with rosbag.Bag('/tmp/test_writing_nonchronological_works.bag', 'w') as b:
|
||||
msg_count = 0
|
||||
for i in range(5, 0, -1):
|
||||
msg = Int32()
|
||||
msg.data = i
|
||||
t = genpy.Time.from_sec(i)
|
||||
b.write('/ints', msg, t)
|
||||
msg_count += 1
|
||||
|
||||
msgs = list(rosbag.Bag('/tmp/test_writing_nonchronological_works.bag').read_messages())
|
||||
|
||||
self.assert_(len(msgs) == msg_count, 'not all messages written: expected %d, got %d' % (msg_count, len(msgs)))
|
||||
|
||||
for (_, _, t1), (_, _, t2) in zip(msgs, msgs[1:]):
|
||||
self.assert_(t1 < t2, 'messages returned unordered: got timestamp %s before %s' % (str(t1), str(t2)))
|
||||
|
||||
def test_large_write_works(self):
|
||||
for compression in [rosbag.Compression.NONE, rosbag.Compression.BZ2]:
|
||||
with rosbag.Bag('/tmp/test_large_write_works.bag', 'w', compression=compression) as b:
|
||||
msg_count = 0
|
||||
for i in range(10000):
|
||||
msg = Int32()
|
||||
msg.data = i
|
||||
t = genpy.Time.from_sec(i)
|
||||
b.write('/ints', msg, t)
|
||||
msg_count += 1
|
||||
|
||||
msgs = list(rosbag.Bag('/tmp/test_large_write_works.bag').read_messages())
|
||||
|
||||
self.assertEquals(len(msgs), msg_count, 'not all messages written: expected %d, got %d' % (msg_count, len(msgs)))
|
||||
|
||||
for (_, _, t1), (_, _, t2) in zip(msgs, msgs[1:]):
|
||||
self.assert_(t1 < t2, 'messages returned unordered: got timestamp %s before %s' % (str(t1), str(t2)))
|
||||
|
||||
def test_get_messages_time_range_works(self):
|
||||
with rosbag.Bag('/tmp/test_get_messages_time_range_works.bag', 'w') as b:
|
||||
for i in range(30):
|
||||
msg = Int32()
|
||||
msg.data = i
|
||||
t = genpy.Time.from_sec(i)
|
||||
b.write('/ints', msg, t)
|
||||
|
||||
start_time = genpy.Time.from_sec(3)
|
||||
end_time = genpy.Time.from_sec(7)
|
||||
msgs = list(rosbag.Bag('/tmp/test_get_messages_time_range_works.bag').read_messages(topics='/ints', start_time=start_time, end_time=end_time))
|
||||
|
||||
self.assertEquals(len(msgs), 5)
|
||||
|
||||
def test_get_messages_filter_works(self):
|
||||
with rosbag.Bag('/tmp/test_get_messages_filter_works.bag', 'w') as b:
|
||||
for i in range(30):
|
||||
msg = Int32()
|
||||
msg.data = i
|
||||
t = genpy.Time.from_sec(i)
|
||||
b.write('/ints' + str(i), msg, t)
|
||||
|
||||
def filter(topic, datatype, md5sum, msg_def, header):
|
||||
return '5' in topic and datatype == Int32._type and md5sum == Int32._md5sum and msg_def == Int32._full_text
|
||||
|
||||
self.assertEquals(len(list(rosbag.Bag('/tmp/test_get_messages_filter_works.bag').read_messages(connection_filter=filter))), 3)
|
||||
|
||||
def test_rosbag_filter(self):
|
||||
inbag_filename = '/tmp/test_rosbag_filter__1.bag'
|
||||
outbag_filename = '/tmp/test_rosbag_filter__2.bag'
|
||||
|
||||
with rosbag.Bag(inbag_filename, 'w') as b:
|
||||
for i in range(30):
|
||||
msg = Int32()
|
||||
msg.data = i
|
||||
t = genpy.Time.from_sec(i)
|
||||
b.write('/ints' + str(i), msg, t)
|
||||
|
||||
expression = "(int(t.secs) == m.data) and (topic == '/ints' + str(m.data)) and (m.data >= 15 and m.data < 20)"
|
||||
|
||||
os.system('rosbag filter %s %s "%s"' % (inbag_filename, outbag_filename, expression))
|
||||
|
||||
msgs = list(rosbag.Bag(outbag_filename).read_messages())
|
||||
|
||||
self.assertEquals(len(msgs), 5)
|
||||
|
||||
# Regression test for issue #736
|
||||
def test_trivial_rosbag_filter(self):
|
||||
tempdir = tempfile.mkdtemp()
|
||||
try:
|
||||
inbag_filename = os.path.join(tempdir, 'test_rosbag_filter__1.bag')
|
||||
outbag1_filename = os.path.join(tempdir, 'test_rosbag_filter__2.bag')
|
||||
outbag2_filename = os.path.join(tempdir, 'test_rosbag_filter__3.bag')
|
||||
|
||||
with rosbag.Bag(inbag_filename, 'w') as b:
|
||||
for i in range(30):
|
||||
msg = ColorRGBA()
|
||||
t = genpy.Time.from_sec(i)
|
||||
b.write('/ints' + str(i), msg, t)
|
||||
|
||||
# filtering multiple times should not affect the filtered rosbag
|
||||
cmd = 'rosbag filter %s %s "True"'
|
||||
os.system(cmd % (inbag_filename, outbag1_filename))
|
||||
os.system(cmd % (outbag1_filename, outbag2_filename))
|
||||
|
||||
with open(outbag1_filename, 'r') as h:
|
||||
outbag1_md5 = hashlib.md5(h.read()).hexdigest()
|
||||
with open(outbag2_filename, 'r') as h:
|
||||
outbag2_md5 = hashlib.md5(h.read()).hexdigest()
|
||||
self.assertEquals(outbag1_md5, outbag2_md5)
|
||||
finally:
|
||||
shutil.rmtree(tempdir)
|
||||
|
||||
def test_reindex_works(self):
|
||||
fn = '/tmp/test_reindex_works.bag'
|
||||
|
||||
chunk_threshold = 1024
|
||||
|
||||
with rosbag.Bag(fn, 'w', chunk_threshold=chunk_threshold) as b:
|
||||
for i in range(100):
|
||||
for j in range(5):
|
||||
msg = Int32()
|
||||
msg.data = i
|
||||
b.write('/topic%d' % j, msg)
|
||||
file_header_pos = b._file_header_pos
|
||||
|
||||
start_index = 4117 + chunk_threshold * 2 + int(chunk_threshold / 2)
|
||||
|
||||
trunc_filename = '%s.trunc%s' % os.path.splitext(fn)
|
||||
reindex_filename = '%s.reindex%s' % os.path.splitext(fn)
|
||||
|
||||
for trunc_index in range(start_index, start_index + chunk_threshold):
|
||||
shutil.copy(fn, trunc_filename)
|
||||
|
||||
with open(trunc_filename, 'r+b') as f:
|
||||
f.seek(file_header_pos)
|
||||
header = {
|
||||
'op': bag._pack_uint8(bag._OP_FILE_HEADER),
|
||||
'index_pos': bag._pack_uint64(0),
|
||||
'conn_count': bag._pack_uint32(0),
|
||||
'chunk_count': bag._pack_uint32(0)
|
||||
}
|
||||
bag._write_record(f, header, padded_size=bag._FILE_HEADER_LENGTH)
|
||||
f.truncate(trunc_index)
|
||||
|
||||
shutil.copy(trunc_filename, reindex_filename)
|
||||
|
||||
try:
|
||||
b = rosbag.Bag(reindex_filename, 'a', allow_unindexed=True)
|
||||
except Exception as ex:
|
||||
pass
|
||||
for done in b.reindex():
|
||||
pass
|
||||
b.close()
|
||||
|
||||
msgs = list(rosbag.Bag(reindex_filename, 'r'))
|
||||
|
||||
def test_future_version_works(self):
|
||||
fn = '/tmp/test_future_version_2.1.bag'
|
||||
|
||||
with rosbag.Bag(fn, 'w', chunk_threshold=256) as b:
|
||||
for i in range(10):
|
||||
msg = Int32()
|
||||
msg.data = i
|
||||
b.write('/int', msg)
|
||||
|
||||
header = { 'op': bag._pack_uint8(max(bag._OP_CODES.keys()) + 1) }
|
||||
data = 'ABCDEFGHI123456789'
|
||||
bag._write_record(b._file, header, data)
|
||||
|
||||
b._file.seek(0)
|
||||
data = '#ROSBAG V%d.%d\n' % (int(b._version / 100), (b._version % 100) + 1) # increment the minor version
|
||||
data = data.encode()
|
||||
b._file.write(data)
|
||||
b._file.seek(0, os.SEEK_END)
|
||||
|
||||
with rosbag.Bag(fn) as b:
|
||||
for topic, msg, t in b:
|
||||
pass
|
||||
|
||||
def test_get_message_count(self):
|
||||
fn = '/tmp/test_get_message_count.bag'
|
||||
with rosbag.Bag(fn, mode='w') as bag:
|
||||
for i in range(100):
|
||||
bag.write("/test_bag", Int32(data=i))
|
||||
bag.write("/test_bag", String(data='also'))
|
||||
bag.write("/test_bag/more", String(data='alone'))
|
||||
|
||||
with rosbag.Bag(fn) as bag:
|
||||
self.assertEquals(bag.get_message_count(), 300)
|
||||
self.assertEquals(bag.get_message_count(topic_filters='/test_bag'), 200)
|
||||
self.assertEquals(bag.get_message_count(topic_filters=['/test_bag', '/test_bag/more']), 300)
|
||||
self.assertEquals(bag.get_message_count(topic_filters=['/none']), 0)
|
||||
|
||||
def test_get_compression_info(self):
|
||||
fn = '/tmp/test_get_compression_info.bag'
|
||||
|
||||
# No Compression
|
||||
with rosbag.Bag(fn, mode='w') as bag:
|
||||
for i in range(100):
|
||||
bag.write("/test_bag", Int32(data=i))
|
||||
|
||||
with rosbag.Bag(fn) as bag:
|
||||
info = bag.get_compression_info()
|
||||
self.assertEquals(info.compression, rosbag.Compression.NONE)
|
||||
# 167 Bytes of overhead, 50 Bytes per Int32.
|
||||
self.assertEquals(info.uncompressed, 5166)
|
||||
self.assertEquals(info.compressed, 5166)
|
||||
|
||||
with rosbag.Bag(fn, mode='w', compression=rosbag.Compression.BZ2) as bag:
|
||||
for i in range(100):
|
||||
bag.write("/test_bag", Int32(data=i))
|
||||
|
||||
with rosbag.Bag(fn) as bag:
|
||||
info = bag.get_compression_info()
|
||||
self.assertEquals(info.compression, rosbag.Compression.BZ2)
|
||||
self.assertEquals(info.uncompressed, 5166)
|
||||
|
||||
# the value varies each run, I suspect based on rand, but seems
|
||||
# to generally be around 960 to 980 on my comp
|
||||
self.assertLess(info.compressed, 1050)
|
||||
self.assertGreater(info.compressed, 850)
|
||||
|
||||
def test_get_time(self):
|
||||
fn = '/tmp/test_get_time.bag'
|
||||
|
||||
with rosbag.Bag(fn, mode='w') as bag:
|
||||
for i in range(100):
|
||||
bag.write("/test_bag", Int32(data=i), t=genpy.Time.from_sec(i))
|
||||
|
||||
with rosbag.Bag(fn) as bag:
|
||||
start_stamp = bag.get_start_time()
|
||||
end_stamp = bag.get_end_time()
|
||||
|
||||
self.assertEquals(start_stamp, 0.0)
|
||||
self.assertEquals(end_stamp, 99.0)
|
||||
|
||||
def test_get_time_empty_bag(self):
|
||||
"""Test for issue #657"""
|
||||
fn = '/tmp/test_get_time_emtpy_bag.bag'
|
||||
|
||||
with rosbag.Bag(fn, mode='w') as bag:
|
||||
self.assertRaisesRegexp(rosbag.ROSBagException,
|
||||
'Bag contains no message',
|
||||
bag.get_start_time)
|
||||
self.assertRaisesRegexp(rosbag.ROSBagException,
|
||||
'Bag contains no message',
|
||||
bag.get_end_time)
|
||||
|
||||
def test_get_type_and_topic_info(self):
|
||||
fn = '/tmp/test_get_type_and_topic_info.bag'
|
||||
topic_1 = "/test_bag"
|
||||
topic_2 = "/test_bag/more"
|
||||
with rosbag.Bag(fn, mode='w') as bag:
|
||||
for i in range(100):
|
||||
bag.write(topic_1, Int32(data=i))
|
||||
bag.write(topic_1, String(data='also'))
|
||||
bag.write(topic_2, String(data='alone'))
|
||||
|
||||
with rosbag.Bag(fn) as bag:
|
||||
msg_types, topics = bag.get_type_and_topic_info()
|
||||
self.assertEquals(len(msg_types), 2)
|
||||
self.assertTrue("std_msgs/Int32" in msg_types)
|
||||
self.assertTrue("std_msgs/String" in msg_types)
|
||||
self.assertEquals(len(topics), 2)
|
||||
self.assertTrue(topic_1 in topics)
|
||||
self.assertTrue(topic_2 in topics)
|
||||
|
||||
self.assertEquals(topics[topic_1].message_count, 200)
|
||||
self.assertEquals(topics[topic_1].msg_type, "std_msgs/Int32")
|
||||
self.assertEquals(topics[topic_2].message_count, 100)
|
||||
self.assertEquals(topics[topic_2].msg_type, "std_msgs/String")
|
||||
|
||||
#filter on topic 1
|
||||
msg_types, topics = bag.get_type_and_topic_info(topic_1)
|
||||
|
||||
# msg_types should be unaffected by the filter
|
||||
self.assertEquals(len(msg_types), 2)
|
||||
self.assertTrue("std_msgs/Int32" in msg_types)
|
||||
self.assertTrue("std_msgs/String" in msg_types)
|
||||
|
||||
self.assertEquals(len(topics), 1)
|
||||
self.assertTrue(topic_1 in topics)
|
||||
|
||||
self.assertEquals(topics[topic_1].message_count, 200)
|
||||
self.assertEquals(topics[topic_1].msg_type, "std_msgs/Int32")
|
||||
|
||||
#filter on topic 2
|
||||
msg_types, topics = bag.get_type_and_topic_info(topic_2)
|
||||
|
||||
# msg_types should be unaffected by the filter
|
||||
self.assertEquals(len(msg_types), 2)
|
||||
self.assertTrue("std_msgs/Int32" in msg_types)
|
||||
self.assertTrue("std_msgs/String" in msg_types)
|
||||
|
||||
self.assertEquals(len(topics), 1)
|
||||
self.assertTrue(topic_2 in topics)
|
||||
|
||||
self.assertEquals(topics[topic_2].message_count, 100)
|
||||
self.assertEquals(topics[topic_2].msg_type, "std_msgs/String")
|
||||
|
||||
#filter on missing topic
|
||||
msg_types, topics = bag.get_type_and_topic_info("/none")
|
||||
|
||||
# msg_types should be unaffected by the filter
|
||||
self.assertEquals(len(msg_types), 2)
|
||||
self.assertTrue("std_msgs/Int32" in msg_types)
|
||||
self.assertTrue("std_msgs/String" in msg_types)
|
||||
|
||||
# topics should be empty
|
||||
self.assertEquals(len(topics), 0)
|
||||
|
||||
def _print_bag_records(self, fn):
|
||||
with open(fn) as f:
|
||||
f.seek(0, os.SEEK_END)
|
||||
size = f.tell()
|
||||
f.seek(0)
|
||||
|
||||
version_line = f.readline().rstrip()
|
||||
print(version_line)
|
||||
|
||||
while f.tell() < size:
|
||||
header = bag._read_header(f)
|
||||
op = bag._read_uint8_field(header, 'op')
|
||||
data = bag._read_record_data(f)
|
||||
|
||||
print(bag._OP_CODES.get(op, op))
|
||||
|
||||
if __name__ == '__main__':
|
||||
import rostest
|
||||
PKG='rosbag'
|
||||
rostest.run(PKG, 'TestRosbag', TestRosbag, sys.argv)
|
||||
66
thirdparty/ros/ros_comm/test/test_rosbag/test/topic_count.py
vendored
Executable file
66
thirdparty/ros/ros_comm/test/test_rosbag/test/topic_count.py
vendored
Executable file
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env python
|
||||
# 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 Willow Garage, Inc. 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.
|
||||
#
|
||||
|
||||
import roslib
|
||||
roslib.load_manifest('rosbag')
|
||||
|
||||
import unittest
|
||||
import rostest
|
||||
import sys
|
||||
import time
|
||||
import subprocess
|
||||
|
||||
class TopicCount(unittest.TestCase):
|
||||
|
||||
def test_topic_count(self):
|
||||
# Wait while the recorder creates a bag for us to examine
|
||||
time.sleep(10.0)
|
||||
|
||||
# Check the topic count returned by `rosbag info`
|
||||
# We could probably do this through the rosbag Python API...
|
||||
cmd = ['rosbag', 'info',
|
||||
'/tmp/test_rosbag_record_one_publisher_two_topics.bag',
|
||||
'-y', '-k', 'topics']
|
||||
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
out,err = p.communicate()
|
||||
topic_count = 0
|
||||
for l in out.decode().split('\n'):
|
||||
f = l.strip().split(': ')
|
||||
if len(f) == 2 and f[0] == '- topic':
|
||||
topic_count += 1
|
||||
|
||||
self.assertEqual(topic_count, 2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
rostest.unitrun('test_rosbag', 'topic_count', TopicCount, sys.argv)
|
||||
Reference in New Issue
Block a user