Example #1
0
    def test_image_encoding(self):
        if not rospy.get_node_uri():
            rospy.init_node("topic_store_tests")

        client = MongoStorage(collection="python_tests")

        # Test ROS_Message Serialisation with common Image Types
        from topic_store.utils import _numpy_types as numpy_types

        for encoding, np_type in numpy_types.items():
            size = (32, 32, np_type[1]) if np_type[1] != 1 else (32, 32)
            random_array = np.random.random(size)
            typed_array = (random_array * 255.0).astype(np_type[0])
            message = ros_numpy.msgify(Image, typed_array, encoding=encoding)

            # Insert image message
            im_document = TopicStore({"image": message})
            im_result = client.insert_one(im_document)

            # Get image message and check data is the same
            returned_im_document = client.find_by_id(im_result.inserted_id)
            assert returned_im_document.id == im_result.inserted_id
            retrieved_array = ros_numpy.numpify(
                returned_im_document.msgs["image"])
            np.testing.assert_equal(typed_array, retrieved_array)

            # Delete image message
            client.delete_by_id(im_result.inserted_id)
Example #2
0
 def __iter__(self):
     if not self.path.exists():
         raise StopIteration()
     with self.path.open("rb") as fh:
         while True:
             try:
                 yield TopicStore(data_tree=pickle.load(fh))
             except EOFError:
                 break
    def test_topic_store(self):
        if not rospy.get_node_uri():
            rospy.init_node("topic_store_tests")

        sample_tree = {"ros_msg": "/rosout", "int": 1, "float": 1.0, "str": "1", "dict": {0: 0}, "list": [0]}
        tree = SubscriberTree(sample_tree)

        rospy.sleep(1)
        messages = tree.get_message_tree()

        test_file = pathlib.Path(__file__).parent / "topic_store_tests.topic_store"
        try:
            test_file.unlink()
        except OSError:
            pass

        storage = TopicStorage(test_file)

        # Try getting an element that doesn't exist
        try:
            s = list(storage)[0]
            raise AssertionError()
        except IndexError:
            pass

        # Try looping over elements that don't exist
        for _ in storage:
            raise AssertionError()

        # Add a message and check
        write_n = 5
        for _ in range(write_n):
            storage.insert_one(messages)

        # Check iterator indexing
        stored_items = write_n
        read_items = 0
        for _ in storage:
            read_items += 1
        assert read_items == stored_items

        # Check loading
        storage = TopicStorage(test_file)
        storage.insert_one(TopicStore({0: 0}))
        stored_items += 1
        for s in storage:
            print(s)

        # Test API
        from topic_store import load
        loaded_messages = load(test_file)
        read_items = 0
        for _ in storage:
            read_items += 1
        assert read_items == stored_items

        print("All TopicStorage tests passed!")
    def test_sanitation(self):
        if not rospy.get_node_uri():
            rospy.init_node("topic_store_tests")

        test_dict = {
            # Data heavy types (binary)
            "1_Image": ("sensor_msgs/Image", sensor_msgs.msg.Image()),
            "1_RegionOfInterest": ("sensor_msgs/RegionOfInterest", sensor_msgs.msg.RegionOfInterest()),
            "1_CameraInfo": ("sensor_msgs/CameraInfo", sensor_msgs.msg.CameraInfo()),
            # Time types
            "1_Time_genpy": ("genpy.Time", rospy.rostime.Time(0)),
            "1_Duration_genpy": ("genpy.Duration", rospy.rostime.Duration(0)),
            "1_Time_rospy": ("genpy.Time", rospy.rostime.Time(0)),
            "1_Duration_rospy": ("genpy.Duration", rospy.rostime.Duration(0)),
            # Standard types
            "1_Header": ("std_msgs/Header", std_msgs.msg.Header()),
            # Duplicate the above to avoid memory copy not value copy errors
            # Data heavy types (binary)
            "2_Image": ("sensor_msgs/Image", sensor_msgs.msg.Image()),
            "2_RegionOfInterest": ("sensor_msgs/RegionOfInterest", sensor_msgs.msg.RegionOfInterest()),
            "2_CameraInfo": ("sensor_msgs/CameraInfo", sensor_msgs.msg.CameraInfo()),
            # Time types
            "2_Time_genpy": ("genpy.Time", rospy.rostime.Time(0)),
            "2_Duration_genpy": ("genpy.Duration", rospy.rostime.Duration(0)),
            "2_Time_rospy": ("genpy.Time", rospy.rostime.Time(0)),
            "2_Duration_rospy": ("genpy.Duration", rospy.rostime.Duration(0)),
            # Standard types
            "2_Header": ("std_msgs/Header", std_msgs.msg.Header()),
        }

        test_dict.update({
            # Test nested objects
            "1_ImageHeader": ("std_msgs/Header", test_dict["1_Image"][1].header),
            "1_CameraInfo": ("std_msgs/Header", test_dict["1_CameraInfo"][1].header),
            "1_CameraInfoRegionOfInterest": ("sensor_msgs/RegionOfInterest", test_dict["1_CameraInfo"][1].roi),
            "2_ImageHeader": ("std_msgs/Header", test_dict["2_Image"][1].header),
            "2_CameraInfo": ("std_msgs/Header", test_dict["2_CameraInfo"][1].header),
            "2_CameraInfoRegionOfInterest": ("sensor_msgs/RegionOfInterest", test_dict["2_CameraInfo"][1].roi),
        })

        # Check topic store functions
        store = TopicStore(test_dict)

        for key, (string_type, type_class) in test_dict.items():
            assert store[key][1]["_ros_meta"]["type"] == string_type  # check to python sanitation keeps type
            assert type(store(key)[1]) == type(type_class)  # check to rosify sanitation returns correct type

        # Check main sanitation functions
        sanitised = sanitise_dict(test_dict)
        rosified = rosify_dict(test_dict)

        for key, (string_type, type_class) in test_dict.items():
            assert sanitised[key][1]["_ros_meta"]["type"] == string_type  # check to python sanitation keeps type
            assert type(rosified[key][1]) == type(type_class)  # check to rosify sanitation returns correct type

        print("All sanitation tests passed!")
Example #5
0
    def insert_one(self, topic_store):
        """Inserts a topic store object into the database

        Returns:
            pymongo.results.InsertOneResult: Contains the ID for the inserted document
        """
        if isinstance(topic_store, dict):
            topic_store = TopicStore(topic_store)
        if not isinstance(topic_store, TopicStore):
            raise ValueError("Can only insert TopicStore items into the database not '{}'".format(type(topic_store)))

        parsed_store = self.__gridfs_ify(topic_store)
        return self.collection.insert_one(parsed_store)
Example #6
0
 def __get(self, cursor_ret):
     document = None
     try:
         document = self.parser(cursor_ret)
         if self.apply_fn:
             document = self.apply_fn(document)
         return TopicStore(document)
     except Exception as e:
         if not self.skip_on_error:
             raise
         print("Skipping document '{}' because '{}'".format(
             (document.get('id') + " ") if document else None, e.message))
         return document
Example #7
0
 def insert_one(self, topic_store):
     if isinstance(topic_store, dict):
         topic_store = TopicStore(topic_store)
     if not isinstance(topic_store, TopicStore):
         raise ValueError("TopicStorage only supports TopicStore types")
     # Create if doesn't exist on the system
     if not self.path.exists():
         try:
             self.path.parent.mkdir(parents=True)
         except OSError as e:
             if e.errno != 17:  # File exists is okay
                 raise
     with self.path.open("ab" if self.path.exists() else "wb") as fh:
         pickle.dump(topic_store.dict, fh, protocol=TopicStorage.PROTOCOL)
Example #8
0
    def test_documents(self):
        if not rospy.get_node_uri():
            rospy.init_node("topic_store_tests")

        client = MongoStorage(collection="python_tests")

        # Insert a test document
        insert_result = client.insert_one(
            TopicStore({
                "name": "test_name",
                "number": 1
            }))

        # Retrieve the inserted document
        inserted_document = client.find_by_id(insert_result.inserted_id)
        assert inserted_document.id == insert_result.inserted_id

        # Update the document name and number fields
        new_name = ''.join(random.sample('raymond', 7))
        new_number = random.randint(0, 100)
        update_result = client.update_one_by_id(inserted_document.id,
                                                name=new_name,
                                                number=new_number)

        inserted_document_after_update = client.find_by_id(
            insert_result.inserted_id)
        assert inserted_document_after_update.id == insert_result.inserted_id
        assert inserted_document_after_update.dict["number"] == new_number
        assert inserted_document_after_update.dict["name"] == new_name

        # Print all documents in the collection
        cursor = client.find()
        for x in cursor:
            print(
                "Doc:\n\t-As Structure: {}\n\t-As Dict: {}\n\t-As ROS Msgs: {}"
                .format(str(x), x.dict, x.msgs))

        # Or print using the same API as TopicStorage
        for x in client:
            print(
                "Doc:\n\t-As Structure: {}\n\t-As Dict: {}\n\t-As ROS Msgs: {}"
                .format(str(x), x.dict, x.msgs))

        # Cleanup test by deleting document
        delete_result = client.delete_by_id(insert_result.inserted_id)
Example #9
0
 def __iter__(self):
     if not self.path.exists():
         raise StopIteration()
     with self.path.open("rb") as fh:
         position = -1
         while True:
             try:
                 load_kwargs = {}
                 if sys.version_info[0] >= 3:  # python3 loading
                     load_kwargs = dict(encoding="latin1")
                 position += 1
                 tree = pickle.load(fh, **load_kwargs)
                 yield TopicStore(data_tree=tree)
             except EOFError:
                 break
             except Exception as e:
                 print(
                     "File at position {} is corrupt. Skipping, error: {}".
                     format(position, e))
Example #10
0
    def test_large_document(self):
        if not rospy.get_node_uri():
            rospy.init_node("topic_store_tests")

        client = MongoStorage(collection="python_tests", use_grid_fs=True)

        # Insert >16MB document
        random_array = np.random.random((3000, 3000, 3)).astype(np.float32)
        message = ros_numpy.msgify(Image, random_array, encoding="32FC3")

        # Insert image message
        im_document = TopicStore({"image": message})
        im_result = client.insert_one(im_document)

        # Get image message and check data is the same
        returned_im_document = client.find_by_id(im_result.inserted_id)
        assert returned_im_document.id == im_result.inserted_id
        retrieved_array = ros_numpy.numpify(returned_im_document.msgs["image"])
        np.testing.assert_equal(random_array, retrieved_array)

        # Delete image message
        client.delete_by_id(im_result.inserted_id)
Example #11
0
    def find_one(self, query, *args, **kwargs):
        """Returns a matched TopicStore document"""
        # TODO: remove FIND_ONE function in place of generic find function
        skip_fetch_binary, skip_on_error, args, kwargs = self.__parse_find_args_kwargs(args, kwargs)

        doc = None
        try:
            doc = self.collection.find_one(query, *args, **kwargs)
            if not doc:  # Return if doc not found
                return doc

            parsed_document = self.reverse_parser(doc)
            if not skip_fetch_binary:
                parsed_document = self.__ungridfs_ify(parsed_document)
            return TopicStore(parsed_document)
        except Exception as e:
            if not skip_on_error:
                raise
            print("Skipping document '{}' because '{}'".format(
                (doc.get('id') + " ") if doc else None, e.message)
            )
            return doc
Example #12
0
    def test_image_encoding(self):
        if not rospy.get_node_uri():
            rospy.init_node("topic_store_tests")

        client = MongoStorage(collection="python_tests")

        # Test ROS_Message Serialisation with common Image Types
        numpy_types = {
            "rgb8": (np.uint8, 3),
            "rgba8": (np.uint8, 4),
            "rgb16": (np.uint16, 3),
            "rgba16": (np.uint16, 4),
            "bgr8": (np.uint8, 3),
            "bgra8": (np.uint8, 4),
            "bgr16": (np.uint16, 3),
            "bgra16": (np.uint16, 4),
            "mono8": (np.uint8, 1),
            "mono16": (np.uint16, 1),
            "bayer_rggb8": (np.uint8, 1),
            "bayer_bggr8": (np.uint8, 1),
            "bayer_gbrg8": (np.uint8, 1),
            "bayer_grbg8": (np.uint8, 1),
            "bayer_rggb16": (np.uint16, 1),
            "bayer_bggr16": (np.uint16, 1),
            "bayer_gbrg16": (np.uint16, 1),
            "bayer_grbg16": (np.uint16, 1),
            "8UC1": (np.uint8, 1),
            "8UC2": (np.uint8, 2),
            "8UC3": (np.uint8, 3),
            "8UC4": (np.uint8, 4),
            "8SC1": (np.int8, 1),
            "8SC2": (np.int8, 2),
            "8SC3": (np.int8, 3),
            "8SC4": (np.int8, 4),
            "16UC1": (np.uint16, 1),
            "16UC2": (np.uint16, 2),
            "16UC3": (np.uint16, 3),
            "16UC4": (np.uint16, 4),
            "16SC1": (np.int16, 1),
            "16SC2": (np.int16, 2),
            "16SC3": (np.int16, 3),
            "16SC4": (np.int16, 4),
            "32SC1": (np.int32, 1),
            "32SC2": (np.int32, 2),
            "32SC3": (np.int32, 3),
            "32SC4": (np.int32, 4),
            "32FC1": (np.float32, 1),
            "32FC2": (np.float32, 2),
            "32FC3": (np.float32, 3),
            "32FC4": (np.float32, 4),
            "64FC1": (np.float64, 1),
            "64FC2": (np.float64, 2),
            "64FC3": (np.float64, 3),
            "64FC4": (np.float64, 4)
        }

        for encoding, np_type in numpy_types.items():
            size = (32, 32, np_type[1]) if np_type[1] != 1 else (32, 32)
            random_array = np.random.random(size)
            typed_array = (random_array * 255.0).astype(np_type[0])
            message = ros_numpy.msgify(Image, typed_array, encoding=encoding)

            # Insert image message
            im_document = TopicStore({"image": message})
            im_result = client.insert_one(im_document)

            # Get image message and check data is the same
            returned_im_document = client.find_by_id(im_result.inserted_id)
            assert returned_im_document.id == im_result.inserted_id
            retrieved_array = ros_numpy.numpify(
                returned_im_document.msgs["image"])
            np.testing.assert_equal(typed_array, retrieved_array)

            # Delete image message
            client.delete_by_id(im_result.inserted_id)
Example #13
0
 def next(self):
     return TopicStore(self.parser(self.cursor.next()))
Example #14
0
 def get_message_tree(self):
     """TopicStore: Representation of the SubscriberTree topics snapshot"""
     return TopicStore(self.__get_msg_tree(data_tree=self.tree))
Example #15
0
 def next(self):
     document = self.parser(self.cursor.next())
     if self.apply_fn:
         document = self.apply_fn(document)
     return TopicStore(document)
Example #16
0
 def __getitem__(self, item):
     document = self.parser(self.cursor.__getitem__(item))
     if self.apply_fn:
         document = self.apply_fn(document)
     return TopicStore(document)
Example #17
0
 def find_one(self, query, *args, **kwargs):
     """Returns a matched TopicStore document"""
     doc = self.collection.find_one(query, *args, **kwargs)
     parsed_document = self.reverse_parser(doc)
     parsed_document = self.__ungridfs_ify(parsed_document)
     return TopicStore(parsed_document)
Example #18
0
 def __getitem__(self, item):
     return TopicStore(self.parser(self.cursor.__getitem__(item)))
Example #19
0
 def find_one(self, query, *args, **kwargs):
     """Returns a matched TopicStore document"""
     return TopicStore(self.reverse_parser(self.collection.find_one(query, *args, **kwargs)))