Пример #1
0
async def test_all_topic_names(client):
    """Test the get topic_names response."""
    salobj.set_random_lsst_dds_partition_prefix()
    async with salobj.Domain() as domain:
        domain = salobj.Domain()
        available_idl_files = list(domain.idl_dir.glob(idl_glob))
        names = [
            file.name.split("_", )[-1].replace(".idl", "")
            for file in available_idl_files
        ]
        names = names[:conftest.REMOTES_LEN_LIMIT]

        response = await client.get("/salinfo/topic-names")

        assert response.status == 200

        response_data = await response.json()

        for name, data in response_data.items():
            # assert name in names
            assert "command_names" in data
            assert "event_names" in data
            assert "telemetry_names" in data
            assert type(data["command_names"]) == list
            assert type(data["event_names"]) == list
            assert type(data["telemetry_names"]) == list
Пример #2
0
    async def test_salinfo_metadata(self) -> None:
        """Test some of the metadata in SalInfo.

        The main tests of the IDL parser are elsewhere.
        """
        async with salobj.Domain() as domain:
            salinfo = salobj.SalInfo(domain=domain, name="Test")

            # Check some topic and field metadata
            for topic_name, topic_metadata in salinfo.metadata.topic_info.items(
            ):
                assert topic_name == topic_metadata.sal_name
                for field_name, field_metadata in topic_metadata.field_info.items(
                ):
                    assert field_name == field_metadata.name

            some_expected_topic_names = (
                "command_enable",
                "command_setArrays",
                "command_setScalars",
                "logevent_arrays",
                "logevent_scalars",
                "arrays",
                "scalars",
            )
            assert set(some_expected_topic_names).issubset(
                set(salinfo.metadata.topic_info.keys()))
Пример #3
0
    async def test_run_command_line(self):
        exe_name = "run_one_script.py"
        exe_path = shutil.which(exe_name)
        if exe_path is None:
            self.fail(
                f"Could not find bin script {exe_name}; did you setup and scons this package?"
            )

        index = 135
        script = DATA_DIR / "standard" / "subdir" / "script3"
        config_path = DATA_DIR / "config1.yaml"
        async with salobj.Domain() as domain, salobj.Remote(
                domain=domain, name="Script", index=index) as remote:
            process = await asyncio.create_subprocess_exec(
                exe_name,
                str(script),
                "--config",
                str(config_path),
                "--index",
                str(index),
                "--loglevel",
                "10",
            )
            try:
                t0 = time.monotonic()
                await asyncio.wait_for(process.wait(), timeout=STD_TIMEOUT)
                dt = time.monotonic() - t0
                print(f"It took {dt:0.2f} seconds to run the script")
            except Exception:
                if process.returncode is None:
                    process.terminate()
                raise
            final_state = remote.evt_state.get()
            assert final_state.state == ScriptState.DONE
Пример #4
0
 async def test_class_creation_speed(self) -> None:
     """Test the speed of creating topic classes on the fly."""
     async with salobj.Domain() as domain:
         t0 = time.monotonic()
         salinfo = salobj.SalInfo(domain, "Test", index=self.index)
         topic_names = (
             ["logevent_" + name for name in salinfo.event_names]
             + ["command_" + name for name in salinfo.command_names]
             + list(salinfo.telemetry_names)
         )
         for topic_name in topic_names:
             revname = salinfo.revnames.get(topic_name)
             ddsutil.make_dds_topic_class(
                 parsed_idl=salinfo.parsed_idl, revname=revname
             )
         dt = time.monotonic() - t0
         ntopics = len(topic_names)
         creation_speed = ntopics / dt
         print(
             f"Created {creation_speed:0.1f} topic classes/sec ({ntopics} topic classes); "
             f"total duration {dt:0.2f} seconds."
         )
         self.insert_measurement(
             verify.Measurement(
                 "salobj.CreateClasses", creation_speed * u.ct / u.second
             )
         )
Пример #5
0
    async def test_make_ack_cmd(self) -> None:
        async with salobj.Domain() as domain:
            salinfo = salobj.SalInfo(domain=domain, name="Test")

            # Use all defaults
            seqNum = 55
            ack = salobj.SalRetCode.CMD_COMPLETE
            ackcmd = salinfo.make_ackcmd(private_seqNum=seqNum, ack=ack)
            assert ackcmd.private_seqNum == seqNum
            assert ackcmd.ack == ack
            assert ackcmd.error == 0
            assert ackcmd.result == ""

            # Specify an error code and result
            seqNum = 27
            ack = salobj.SalRetCode.CMD_FAILED
            error = 127
            result = "why not?"
            ackcmd = salinfo.make_ackcmd(
                private_seqNum=seqNum,
                ack=ack,
                error=error,
                result=result,
            )
            assert ackcmd.private_seqNum == seqNum
            assert ackcmd.ack == ack
            assert ackcmd.error == error
            assert ackcmd.result == result
Пример #6
0
    async def test_do_callbacks_true(self) -> None:
        index = next(index_gen)
        async with salobj.Domain() as domain, salobj.SalInfo(
                domain=domain, name="Test", index=index) as salinfo:
            command_names = salinfo.command_names

        # Build a controller and check that callbacks are asigned.
        async with ControllerWithDoMethods(command_names) as controller:
            for cmd_name in command_names:
                with self.subTest(cmd_name=cmd_name):
                    cmd = getattr(controller, "cmd_" + cmd_name)
                    assert cmd.has_callback

        # do_setAuthList and do_setLogLevel are provided by Controller
        skip_names = {"setAuthList", "setLogLevel"}
        for missing_name in command_names:
            if missing_name in skip_names:
                continue
            with self.subTest(missing_name=missing_name):
                bad_names = [
                    name for name in command_names if name != missing_name
                ]
                with pytest.raises(TypeError):
                    ControllerWithDoMethods(bad_names)

        extra_names = list(command_names) + ["extra_command"]
        with pytest.raises(TypeError):
            ControllerWithDoMethods(extra_names)
    async def check_executable(self, script_path):
        """Check that an executable script can be launched.

        Parameter
        ---------
        script_path : `str`
            Full path to script.
        """
        salobj.set_random_lsst_dds_partition_prefix()

        index = self.next_index()

        script_path = pathlib.Path(script_path).resolve()

        assert script_path.is_file()

        async with salobj.Domain() as domain, salobj.Remote(
                domain=domain, name="Script", index=index) as remote:

            initial_path = os.environ["PATH"]
            try:
                os.environ["PATH"] = str(
                    script_path.parent) + ":" + initial_path
                process = await asyncio.create_subprocess_exec(
                    str(script_path), str(index))

                state = await remote.evt_state.next(flush=False,
                                                    timeout=MAKE_TIMEOUT)
                assert state.state == Script.ScriptState.UNCONFIGURED
            finally:
                process.terminate()
                os.environ["PATH"] = initial_path
Пример #8
0
    async def test_negative_lsst_dds_historysync(self) -> None:
        """Test that setting LSST_DDS_HISTORYSYNC < 0
        prevents waiting for historical data.

        This setting applies to SalInfo, not Remote,
        but it requires some topics in order to be tested,
        and Remote provides topics.
        """
        index = next(index_gen)
        async with salobj.Domain() as domain:
            # Make a normal remote that waits for historical data.
            remote1 = salobj.Remote(domain=domain, name="Test", index=index)
            await asyncio.wait_for(remote1.start_task, timeout=STD_TIMEOUT)
            assert len(remote1.salinfo.wait_history_isok) > 0

            # Make a remote that does not wait for historical data
            # by defining the history timeout env variable < 0.
            os.environ[HISTORY_TIMEOUT_NAME] = "-1"
            try:
                remote2 = salobj.Remote(domain=domain,
                                        name="Test",
                                        index=index)
                await asyncio.wait_for(remote2.start_task, timeout=STD_TIMEOUT)
            finally:
                if INITIAL_HISTORY_TIMEOUT is None:
                    del os.environ[HISTORY_TIMEOUT_NAME]
                else:
                    os.environ[HISTORY_TIMEOUT_NAME] = INITIAL_HISTORY_TIMEOUT

            assert len(remote2.salinfo.wait_history_isok) == 0
async def main():
    logging.info("main method")
    async with salobj.Domain() as domain:
        remote = salobj.Remote(domain=domain, name="GenericCamera", index=args.index)
        logging.info(f"starting remote with index {args.index}")
        await remote.start_task
        logging.info("starting CSC")
        await remote.cmd_start.set_start(timeout=120)
        logging.info("disabling")
        await salobj.set_summary_state(
            remote=remote, state=salobj.State.DISABLED, timeout=120
        )
        logging.info("enabling")
        await salobj.set_summary_state(
            remote=remote, state=salobj.State.ENABLED, timeout=120
        )
        logging.info("taking a picture")
        await remote.cmd_takeImages.set_start(
            numImages=1,
            expTime=2.0,
            shutter=True,
            sensors="",
            keyValueMap="",
            obsNote="image",
        )
        logging.info("disabling again")
        await salobj.set_summary_state(
            remote=remote, state=salobj.State.DISABLED, timeout=120
        )
        logging.info("offline")
        await salobj.set_summary_state(
            remote=remote, state=salobj.State.OFFLINE, timeout=120
        )
Пример #10
0
 async def test_lsst_dds_partition_prefix_required(self) -> None:
     # Delete LSST_DDS_PARTITION_PREFIX. This should prevent
     # constructing a Domain
     with utils.modify_environ(LSST_DDS_PARTITION_PREFIX=None):
         async with salobj.Domain() as domain:
             with pytest.raises(RuntimeError):
                 salobj.SalInfo(domain=domain, name="Test", index=1)
Пример #11
0
async def test_successful_command(client, *args, **kwargs):
    # Arrange
    remote = salobj.Remote(domain=salobj.Domain(), name="LOVE")

    await remote.start_task

    observing_log_msg = {
        "user": "******",
        "message": "a message",
    }

    # Act
    remote.evt_observingLog.flush()
    response = await client.post("/lovecsc/observinglog",
                                 data=json.dumps(observing_log_msg))

    # Assert
    assert response.status == 200
    response = await response.json()
    assert response["ack"] == "Added new observing log to SAL"

    result = await remote.evt_observingLog.next(flush=False)
    assert result.user == "an user"
    assert result.message == "a message"

    # Clean up
    await remote.close()
Пример #12
0
    async def test_all_names(self):
        async with salobj.Domain() as domain:
            remote = salobj.Remote(
                domain=domain,
                name="Test",
                index=self.index,
                readonly=True,
                include=(),
                start=False,
            )
            topic_names = [
                f"evt_{name}" for name in remote.salinfo.event_names
            ]
            topic_names += [
                f"tel_{name}" for name in remote.salinfo.telemetry_names
            ]

            # Check that no topics have been added yet
            for name in topic_names:
                self.assertFalse(hasattr(remote, name))

            wrapper = watcher.base.RemoteWrapper(remote=remote,
                                                 topic_names=topic_names)
            desired_attr_name = (remote.salinfo.name.lower() + "_" +
                                 str(remote.salinfo.index))
            self.assertEqual(wrapper.attr_name, desired_attr_name)

            # Check that all topics have been added
            for name in topic_names:
                self.assertTrue(hasattr(remote, name))

            wrapper_dir = set(dir(wrapper))
            self.assertTrue(set(topic_names).issubset(wrapper_dir))

            await asyncio.wait_for(remote.start(), timeout=LONG_TIMEOUT)

            # Check that the initial value for each topic is None.
            for name in topic_names:
                self.assertIsNone(getattr(wrapper, name))

            # Write one event and one telemetry topic
            evt_scalars_writer = salobj.topics.ControllerEvent(
                salinfo=remote.salinfo, name="scalars")
            tel_scalars_writer = salobj.topics.ControllerTelemetry(
                salinfo=remote.salinfo, name="scalars")
            evtint = -3
            telint = 47
            evt_scalars_writer.set_put(int0=evtint)
            tel_scalars_writer.set_put(int0=telint)

            # Wait for the read topics to read the data.
            await remote.evt_scalars.next(flush=False, timeout=STD_TIMEOUT)
            await remote.tel_scalars.next(flush=False, timeout=STD_TIMEOUT)

            # Verify that the wrapper produces the expected values.
            self.assertEqual(wrapper.evt_scalars.int0, evtint)
            self.assertEqual(wrapper.tel_scalars.int0, telint)
Пример #13
0
    async def test_start_false(self) -> None:
        """Test the start argument of Remote."""

        index = next(index_gen)
        async with salobj.Domain() as domain:
            remote = salobj.Remote(domain=domain,
                                   name="Test",
                                   index=index,
                                   start=False)
            assert not hasattr(remote, "start_task")
Пример #14
0
    async def run_command(self):
        async with salobj.Domain() as domain:
            arc = salobj.Remote(domain=domain, name=self.device_name, index=0)
            await arc.start_task

            try:
                cmd = getattr(arc, f"cmd_{self.command}")
                await cmd.set_start(timeout=self.timeout)
            except Exception as e:
                print(e)
Пример #15
0
async def test_some_topic_names(client):
    """Test the use of query params to get only some of the topic_names."""
    salobj.set_random_lsst_dds_partition_prefix()
    async with salobj.Domain() as domain:
        domain = salobj.Domain()
        available_idl_files = list(domain.idl_dir.glob(idl_glob))
        names = [
            file.name.split("_", )[-1].replace(".idl", "")
            for file in available_idl_files
        ]
        names = names[:conftest.REMOTES_LEN_LIMIT]

        # Get all combinations of categories:
        categories = ["command", "event", "telemetry"]
        combs = chain.from_iterable(
            combinations(categories, r) for r in range(len(categories) + 1))

        for comb in combs:
            # Get categories to be requested and not to be requested
            requested = list(comb)
            non_req = list(set(categories) - set(requested))
            query_param = "-".join(requested)
            # Requeste them
            response = await client.get("/salinfo/topic-names?categories=" +
                                        query_param)
            assert response.status == 200
            response_data = await response.json()

            # If query_params is empty no filtering is applied:
            if len(requested) == 0:
                requested = categories
                non_req = []

            for _, data in response_data.items():
                # Assert that requested categories are in the response
                for r in requested:
                    key = r + "_names"
                    assert key in data
                    assert type(data[key]) == list
                # Assert that non-requested categories are NOT in the response
                for nr in non_req:
                    key = nr + "_names"
                    assert key not in data
Пример #16
0
 async def test_evt_max_history(self) -> None:
     """Test non-default evt_max_history Remote constructor argument."""
     evt_max_history = 0
     index = next(index_gen)
     async with salobj.Domain() as domain:
         remote = salobj.Remote(domain=domain,
                                name="Test",
                                index=index,
                                evt_max_history=evt_max_history)
         self.assert_max_history(remote, evt_max_history=evt_max_history)
Пример #17
0
async def shutdown(opts):
    end_state = getattr(salobj.State, opts.state.upper())

    domain = salobj.Domain()
    try:
        remote = salobj.Remote(domain=domain, name="DSM", index=opts.index)
        await remote.start_task
        await salobj.set_summary_state(remote, end_state)
    finally:
        await domain.close()
Пример #18
0
def make_comcam_remotes():
    d = salobj.Domain()
    CCArchiver = salobj.Remote(d, 'CCArchiver')
    CCCamera = salobj.Remote(d, 'CCCamera')
    CCHeaderService = salobj.Remote(d, 'CCHeaderService')

    return {
        "CCArchiver": CCArchiver,
        "CCCamera": CCCamera,
        "CCHeaderService": CCHeaderService
    }
Пример #19
0
    async def test_salinfo_constructor(self) -> None:
        with pytest.raises(TypeError):
            salobj.SalInfo(domain=None, name="Test")

        async with salobj.Domain() as domain:
            with pytest.raises(RuntimeError):
                salobj.SalInfo(domain=domain, name="invalid_component_name")

            for invalid_index in (1.1, "one"):
                with pytest.raises(TypeError):
                    salobj.SalInfo(domain=domain,
                                   name="Test",
                                   index=invalid_index)

            index = next(index_gen)
            salinfo = salobj.SalInfo(domain=domain, name="Test", index=index)
            assert salinfo.name == "Test"
            assert salinfo.index == index
            assert not salinfo.start_task.done()
            assert not salinfo.done_task.done()
            assert not salinfo.started
            with pytest.raises(RuntimeError):
                salinfo.assert_started()

            asyncio.create_task(salinfo.start())
            # Use a short time limit because there are no topics to read
            await asyncio.wait_for(salinfo.start_task, timeout=STD_TIMEOUT)
            assert salinfo.start_task.done()
            assert not salinfo.done_task.done()
            assert salinfo.started
            salinfo.assert_started()

            with pytest.raises(RuntimeError):
                await salinfo.start()

            await asyncio.wait_for(salinfo.close(), timeout=STD_TIMEOUT)
            assert salinfo.start_task.done()
            assert salinfo.done_task.done()
            assert salinfo.started
            salinfo.assert_started()

            # Test enum index
            class SalIndex(enum.IntEnum):
                ONE = 1
                TWO = 2

            salinfo = salobj.SalInfo(domain=domain,
                                     name="Script",
                                     index=SalIndex.ONE)
            assert isinstance(salinfo.index, SalIndex)
            assert salinfo.index == SalIndex.ONE
Пример #20
0
    async def test_write_only(self) -> None:
        async with salobj.Domain() as domain:
            salinfo = salobj.SalInfo(domain=domain,
                                     name="Test",
                                     write_only=True)

            # Cannot add a read topic to a write-only SalInfo
            with pytest.raises(RuntimeError):
                salobj.topics.ReadTopic(salinfo=salinfo,
                                        attr_name="evt_summaryState",
                                        max_history=0)

            await salinfo.start()
            assert salinfo._read_loop_task.done()
Пример #21
0
    async def start_cmd(request):
        nonlocal domain
        data = await request.json()
        try:
            assert "csc" in data
            assert "salindex" in data
            assert "cmd" in data
            assert "params" in data
        except AssertionError:
            return web.json_response(
                {
                    "ack": f"Request must have JSON data with the following "
                    f"keys: csc, salindex, cmd_name, params. Received {json.dumps(data)}"
                },
                status=400,
            )

        csc = data["csc"]
        salindex = data["salindex"]
        cmd_name = data["cmd"]
        params = data["params"]
        remote_name = f"{csc}.{salindex}"

        # Only create domain if it does not already exist.
        if domain is None:
            print("Creating salobj.Domain()")
            domain = salobj.Domain()
            domain.default_identity = "LOVE"

        # Only create remote if it does not exist already.
        if remote_name not in remotes:
            print(f"Creating remote {remote_name}.")
            # Create remote for commanding only, exclude all events and
            # telemetry topics
            remotes[remote_name] = salobj.Remote(domain, csc, salindex, include=[])
            await remotes[remote_name].start_task

        cmd = getattr(remotes[remote_name], cmd_name)
        cmd.set(**params)

        try:
            cmd_result = await cmd.start(timeout=5)
            return web.json_response({"ack": cmd_result.result})
        except salobj.AckTimeoutError as e:
            msg = (
                "No ack received from component."
                if e.ackcmd == salobj.SalRetCode.CMD_NOACK
                else f"Last ack received {e.ackcmd}."
            )
            return web.json_response({"ack": f"Command time out. {msg}"}, status=504)
Пример #22
0
    async def test_domain_attr(self) -> None:
        async with salobj.Domain() as domain:
            assert domain.origin == os.getpid()

            assert domain.user_host == salobj.get_user_host()
            assert domain.default_identity == domain.user_host
            assert domain.ackcmd_qos_set.profile_name == "AckcmdProfile"
            assert domain.command_qos_set.profile_name == "CommandProfile"
            assert domain.event_qos_set.profile_name == "EventProfile"
            assert domain.telemetry_qos_set.profile_name == "TelemetryProfile"
            assert domain.ackcmd_qos_set.volatile
            assert domain.command_qos_set.volatile
            assert not domain.event_qos_set.volatile
            assert domain.telemetry_qos_set.volatile
Пример #23
0
 async def test_default_authorize(self) -> None:
     """Test that LSST_DDS_ENABLE_AUTHLIST correctly sets the
     default_authorize attribute.
     """
     async with salobj.Domain() as domain:
         for env_var_value in ("0", "1", None, "2", "", "00"):
             expected_default_authorize = True if env_var_value == "1" else False
             index = next(index_gen)
             with utils.modify_environ(
                     LSST_DDS_ENABLE_AUTHLIST=env_var_value):
                 salinfo = salobj.SalInfo(domain=domain,
                                          name="Test",
                                          index=index)
                 assert salinfo.default_authorize == expected_default_authorize
Пример #24
0
async def test_metadata(client):
    """Test the get metadata response."""
    salobj.set_random_lsst_dds_partition_prefix()
    async with salobj.Domain() as domain:
        domain = salobj.Domain()
        available_idl_files = list(domain.idl_dir.glob(idl_glob))
        names = [
            file.name.split("_", )[-1].replace(".idl", "")
            for file in available_idl_files
        ]
        names = names[:conftest.REMOTES_LEN_LIMIT]

        response = await client.get("/salinfo/metadata")

        assert response.status == 200

        response_data = await response.json()

        for name, data in response_data.items():
            # assert name in names
            assert "sal_version" in data
            assert "xml_version" in data
            assert data["sal_version"].count(".") == 2
            assert data["xml_version"].count(".") == 2
Пример #25
0
    async def test_constructor_error(self):
        async with salobj.Domain() as domain:
            remote = salobj.Remote(domain=domain,
                                   name="Test",
                                   index=self.index,
                                   readonly=True,
                                   start=False)

            for bad_topic_names in (
                ["noprefix"],
                ["evb_incorrectprefix"],
                ["evt_nosuchevent"],
                ["tel_nosuchtelemetry"],
                ["evt_summaryState", "evt_nosuchevent"],
                ["tel_scalars", "tel_nosuchtelemetry"],
            ):
                with self.subTest(bad_topic_names=bad_topic_names):
                    with self.assertRaises(ValueError):
                        watcher.base.RemoteWrapper(remote=remote,
                                                   topic_names=bad_topic_names)
Пример #26
0
def make_maintel_remotes():
    d = salobj.Domain()
    MTMount = salobj.Remote(d, "NewMTMount")
    MTPtg = salobj.Remote(d, "MTPtg")
    MTAOS = salobj.Remote(d, "MTAOS")
    M2 = salobj.Remote(d, "MTM2")
    M1M3 = salobj.Remote(d, "MTM1M3")
    M2Hex = salobj.Remote(d, "Hexapod", index=2)
    CamHex = salobj.Remote(d, "Hexapod", index=1)
    Rotator = salobj.Remote(d, "Rotator")

    return {
        "MTMount": MTMount,
        "MTPtg": MTPtg,
        "MTAOS": MTAOS,
        "M2": M2,
        "M1M3": M1M3,
        "M2Hex": M2Hex,
        "CamHex": CamHex,
        "Rotator": Rotator
    }
Пример #27
0
    async def test_some_names(self):
        """Test wrappers that wrap a subset of names."""
        async with salobj.Domain() as domain:
            remote = salobj.Remote(
                domain=domain,
                name="Test",
                index=self.index,
                readonly=True,
                include=(),
                start=False,
            )
            event_names = [
                f"evt_{name}" for name in remote.salinfo.event_names
            ]
            telemetry_names = [
                f"tel_{name}" for name in remote.salinfo.telemetry_names
            ]

            # Check that no topics have been added yet.
            for name in event_names + telemetry_names:
                self.assertFalse(hasattr(remote, name))

            evt_wrapper = watcher.base.RemoteWrapper(remote=remote,
                                                     topic_names=event_names)
            tel_wrapper = watcher.base.RemoteWrapper(
                remote=remote, topic_names=telemetry_names)

            # Check that all topics have been added to the remote.
            for name in event_names + telemetry_names:
                self.assertTrue(hasattr(remote, name))

            # Check that the event wrapper has all the event names
            # and none of the telemetry names, and vice-versa.
            evt_wrapper_dir = set(dir(evt_wrapper))
            tel_wrapper_dir = set(dir(tel_wrapper))
            self.assertTrue(set(event_names).issubset(evt_wrapper_dir))
            self.assertTrue(set(telemetry_names).issubset(tel_wrapper_dir))
            self.assertEqual(set(event_names) & tel_wrapper_dir, set())
            self.assertEqual(set(telemetry_names) & evt_wrapper_dir, set())
Пример #28
0
    async def test_log_level(self) -> None:
        """Test that log level is decreased (verbosity increased) to INFO."""
        log = logging.getLogger()
        log.setLevel(logging.WARNING)
        salinfos = []
        async with salobj.Domain() as domain:
            try:
                # Log level is WARNING; test that log level is decreased
                # (verbosity increased) to INFO.
                salinfo = salobj.SalInfo(domain=domain, name="Test")
                salinfos.append(salinfo)
                assert salinfo.log.getEffectiveLevel() == logging.INFO

                # Start with log level DEBUG and test that log level
                # is unchanged.
                salinfo.log.setLevel(logging.DEBUG)
                salinfo = salobj.SalInfo(domain=domain, name="Test")
                salinfos.append(salinfo)
                assert salinfo.log.getEffectiveLevel() == logging.DEBUG
            finally:
                for salinfo in salinfos:
                    await salinfo.close()
Пример #29
0
 async def test_ack_error_repr(self) -> None:
     """Test AckError.__str__ and AckError.__repr__"""
     async with salobj.Domain() as domain:
         salinfo = salobj.SalInfo(domain, "Test", index=1)
         msg = "a message"
         private_seqNum = 5
         ack = 23
         error = -6
         result = "a result"
         err = salobj.AckError(
             msg,
             ackcmd=salinfo.make_ackcmd(private_seqNum=private_seqNum,
                                        ack=ack,
                                        error=error,
                                        result=result),
         )
         str_err = str(err)
         for item in (msg, private_seqNum, ack, error, result):
             assert str(item) in str_err
         assert "AckError" not in str_err
         repr_err = repr(err)
         for item in ("AckError", msg, private_seqNum, ack, error, result):
             assert str(item) in repr_err
Пример #30
0
    async def make_remote_and_topic_writer(
        self,
    ) -> typing.AsyncGenerator[salobj.Remote, None]:
        """Make a remote and launch a topic writer in a subprocess.

        Return the remote.
        """
        script_path = self.datadir / "topic_writer.py"
        process = await asyncio.create_subprocess_exec(
            str(script_path), str(self.index)
        )
        try:
            async with salobj.Domain() as domain, salobj.Remote(
                domain=domain, name="Test", index=self.index
            ) as remote:
                yield remote
                await salobj.set_summary_state(
                    remote=remote, state=salobj.State.OFFLINE, timeout=STD_TIMEOUT
                )
                await asyncio.wait_for(process.wait(), timeout=STD_TIMEOUT)
        finally:
            if process.returncode is None:
                print("Warning: killing the topic writer")
                process.kill()