Example #1
0
    def __init__(self) -> None:
        self.isopen = True
        self.user_host = base.get_user_host()
        self.default_identity = self.user_host

        # Accumulators for verifying that close is working.
        self.num_read_loops = 0

        self.done_task: asyncio.Future = asyncio.Future()

        # Set of SalInfo.
        self._salinfo_set: weakref.WeakSet[SalInfo] = weakref.WeakSet()

        self.origin = os.getpid()
        self.idl_dir = idl.get_idl_dir()

        qos_path = ddsconfig.get_qos_path()
        self.ackcmd_qos_set = QosSet(qos_path=qos_path,
                                     profile_name="AckcmdProfile")
        self.command_qos_set = QosSet(qos_path=qos_path,
                                      profile_name="CommandProfile")
        self.event_qos_set = QosSet(qos_path=qos_path,
                                    profile_name="EventProfile")
        self.telemetry_qos_set = QosSet(qos_path=qos_path,
                                        profile_name="TelemetryProfile")

        # Any of the three qos providers is fine for the participant qos.
        participant_qos = self.command_qos_set.qos_provider.get_participant_qos(
        )
        self.participant = dds.DomainParticipant(qos=participant_qos)
    def setUp(cls):
        cls.component = "Test"
        cls.data_dir = pathlib.Path(__file__).parent / "data" / "topic_names_sets"

        metadata = salobj.parse_idl(
            cls.component, idl.get_idl_dir() / "sal_revCoded_Test.idl"
        )
        command_names = []
        event_names = []
        telemetry_names = []
        for topic_metadata in metadata.topic_info.values():
            sal_topic_name = topic_metadata.sal_name
            if sal_topic_name.startswith("command_"):
                command_names.append(sal_topic_name[8:])
            elif sal_topic_name.startswith("logevent_"):
                event_names.append(sal_topic_name[9:])
            elif sal_topic_name != "ackcmd":
                telemetry_names.append(sal_topic_name)

        cls.command_names = tuple(command_names)
        cls.event_names = tuple(event_names)
        cls.telemetry_names = tuple(telemetry_names)
        cls.all_names = dict(
            commands=cls.command_names,
            events=cls.event_names,
            telemetry=cls.telemetry_names,
        )
        cls.categories = ("commands", "events", "telemetry")
Example #3
0
 def __init__(self, name):
     self.name = name
     self.xml_dir = get_env_dir("TS_XML_DIR", "ts_xml not setup")
     self.sal_work_dir = get_env_dir("SAL_WORK_DIR",
                                     "$SAL_WORK_DIR must be defined")
     idl_file_name = f"sal_revCoded_{self.name}.idl"
     self.idl_file_from_path = self.sal_work_dir / "idl-templates" / "validated" / "sal" / idl_file_name
     self.idl_file_to_path = idl.get_idl_dir() / idl_file_name
    def get_component_metadata(
        components: typing.List[str], ) -> typing.Dict[str, typing.Any]:
        """Gather metadada information, needed to validate topics versions.

        Parameters
        ----------
        components : `list` of `str`
            List of components name in the "Name:index" format.

        Returns
        -------
        `dict`
            Component metadata.
        """

        return dict([(
            component,
            salobj.parse_idl(
                component,
                idl.get_idl_dir() /
                f"sal_revCoded_{component.split(':')[0]}.idl",
            ),
        ) for component in components])
Example #5
0
    def test_test_idl(self) -> None:
        """Test a Test IDL file generated by the current version of ts_sal.

        This is to catch format changes relative to the local Simple IDL files.
        It is not as thorough as the tests for the local Simple IDL files
        because I don't want to make too many assumptions about minor details
        of the XML.
        """
        idl_path = idl.get_idl_dir() / "sal_revCoded_Test.idl"
        metadata = salobj.parse_idl(name="Test", idl_path=idl_path)
        assert metadata.name == "Test"
        assert idl_path.samefile(metadata.idl_path)

        # Check that names match between info dict keys
        # and the name in the metadata.
        for sal_topic_name, topic_metadata in metadata.topic_info.items():
            assert topic_metadata.sal_name == sal_topic_name
            for field_name, field_metadata in topic_metadata.field_info.items(
            ):
                assert field_metadata.name == field_name

        # Check that some of the expected topic names are present.
        some_expected_topic_names = (
            "command_enable",
            "command_setArrays",
            "command_setScalars",
            "logevent_arrays",
            "logevent_scalars",
            "arrays",
            "scalars",
        )
        assert set(some_expected_topic_names).issubset(
            set(metadata.topic_info.keys()))

        # Dict of field name: expected type name
        field_types = dict(
            salIndex="long",
            private_revCode="string",
            private_sndStamp="double",
            private_rcvStamp="double",
            private_seqNum="long",
            private_identity="string",
            private_origin="long",
            boolean0="boolean",
            byte0="octet",
            short0="short",
            int0="long",
            long0="long",
            longLong0="long long",
            string0="string",
            unsignedShort0="unsigned short",
            unsignedInt0="unsigned long",
            unsignedLong0="unsigned long",
            float0="float",
            double0="double",
        )

        # Check some details of arrays topics, including data type,
        # array length and string length.
        for topic_name in ("arrays", "logevent_arrays", "command_setArrays"):
            with self.subTest(topic_name=topic_name):
                topic_metadata = metadata.topic_info[topic_name]
                for deprecated_field in ("char0", "octet0"):
                    topic_metadata.field_info.pop(deprecated_field, None)

                expected_field_names = set(field_types.keys())
                expected_field_names.remove("string0")  # only in scalars
                assert set(
                    topic_metadata.field_info.keys()) == expected_field_names
                for field_metadata in topic_metadata.field_info.values():
                    if field_metadata.name[-1] != "0":
                        assert field_metadata.array_length is None
                    else:
                        assert field_metadata.array_length == 5
                    assert isinstance(field_metadata.description, str)
                    assert field_metadata.type_name == field_types[
                        field_metadata.name]

        # Check some details of scalars topics, including data type,
        # array length and string length.
        for topic_name in ("scalars", "logevent_scalars",
                           "command_setScalars"):
            with self.subTest(topic_name=topic_name):
                topic_metadata = metadata.topic_info[topic_name]
                for deprecated_field in ("char0", "octet0"):
                    topic_metadata.field_info.pop(deprecated_field, None)
                expected_field_names = set(field_types.keys())
                assert set(
                    topic_metadata.field_info.keys()) == expected_field_names
                for field_metadata in topic_metadata.field_info.values():
                    assert field_metadata.array_length is None
                    assert isinstance(field_metadata.description, str)
                    assert field_metadata.type_name == field_types[
                        field_metadata.name]
Example #6
0
    def __init__(self,
                 *,
                 component,
                 topic_names_list,
                 queue_len=salobj.topics.DEFAULT_QUEUE_LEN):
        self.component = component
        self.topic_names_list = list(topic_names_list)
        self.queue_len = int(queue_len)
        topic_categories = ("commands", "events", "telemetry")

        # Construct a dict of topic category: all topic names, by reading the
        # IDL file. Topic names *omit* the command_ and logevent_ prefix.
        all_names_dict = {category: set() for category in topic_categories}
        idl_metadata = salobj.parse_idl(
            component,
            idl.get_idl_dir() / f"sal_revCoded_{component}.idl")
        for topic in idl_metadata.topic_info:
            if topic.startswith("command_"):
                all_names_dict["commands"].add(topic[8:])
            elif topic.startswith("logevent_"):
                all_names_dict["events"].add(topic[9:])
            elif topic == "ackcmd":
                pass
            else:
                all_names_dict["telemetry"].add(topic)

        # Examine the topic_names_list, recording which topics have been seen
        # and looking for invalid and duplicate names.
        ackcmd_added = False
        seen_names_dict = {category: set() for category in topic_categories}
        for i, topic_names in enumerate(self.topic_names_list):
            if topic_names.add_ackcmd:
                if ackcmd_added:
                    raise ValueError(
                        f"topic_names_list[{i}] invalid: ackcmd already added")
                ackcmd_added = True

            for category in topic_categories:
                all_names = all_names_dict[category]
                seen_names = seen_names_dict[category]
                specified_names = set(getattr(topic_names, category, []))

                # Check that specified names are valid
                invalid_names = specified_names - all_names
                if invalid_names:
                    raise ValueError(
                        f"topic_names_list[{i}].{category} "
                        f"has invalid names: {sorted(invalid_names)}")

                # Check for duplicates
                duplicate_names = seen_names & specified_names
                if duplicate_names:
                    raise ValueError(
                        f"topic_names_list[{i}].{category} "
                        f"has names already specified: {sorted(duplicate_names)}"
                    )

                seen_names |= specified_names

        # Append a TopicNames to handle remaining topics, if needed.
        remaining_names = {
            category: all_names_dict[category] - seen_names_dict[category]
            for category in topic_categories
        }
        if not ackcmd_added or any(
                len(remaining_names[category]) > 0
                for category in topic_categories):
            self.topic_names_list.append(
                TopicNames(add_ackcmd=not ackcmd_added, **remaining_names))
Example #7
0
 def test_get_idl_dir(self):
     expected_idl_dir = self.get_expected_data_dir() / "idl"
     assert idl.get_idl_dir() == expected_idl_dir