Add test/release notes for command-less controllers

See eaa1b44b00 for the actual change.
This commit is contained in:
David Nadlinger 2019-02-07 21:51:08 +00:00
parent eaa1b44b00
commit ef934ad958
3 changed files with 48 additions and 1 deletions

View File

@ -13,12 +13,16 @@ ARTIQ-5
:class:`~artiq.coredevice.ad9914.AD9914` phase reference timestamp parameters :class:`~artiq.coredevice.ad9914.AD9914` phase reference timestamp parameters
have been renamed to ``ref_time_mu`` for consistency, as they are in machine have been renamed to ``ref_time_mu`` for consistency, as they are in machine
units. units.
* :func:`~artiq.tools.verbosity_args` renamed to :func:`~artiq.tools.add_common_args`. New feature: adds an option to print the ARTIQ version. * :func:`~artiq.tools.verbosity_args` has been renamed to
:func:`~artiq.tools.add_common_args`, and now adds a ``--version`` flag.
* A gateware-level input edge counter has been added, which offers higher * A gateware-level input edge counter has been added, which offers higher
throughput and increased flexibility over the usual TTL input PHYs where throughput and increased flexibility over the usual TTL input PHYs where
edge timestamps are not required. See :mod:`artiq.coredevice.edge_counter` for edge timestamps are not required. See :mod:`artiq.coredevice.edge_counter` for
the core device driver and :mod:`artiq.gateware.rtio.phy.edge_counter`/ the core device driver and :mod:`artiq.gateware.rtio.phy.edge_counter`/
:meth:`artiq.gateware.eem.DIO.add_std` for the gateware components. :meth:`artiq.gateware.eem.DIO.add_std` for the gateware components.
* The controller manager now ignores device database entries without the
``"command"`` key set to facilitate sharing of devices between multiple
masters.
ARTIQ-4 ARTIQ-4

View File

@ -6,6 +6,7 @@ import asyncio
from artiq.devices.ctlmgr import Controllers from artiq.devices.ctlmgr import Controllers
from artiq.protocols.pc_rpc import AsyncioClient from artiq.protocols.pc_rpc import AsyncioClient
from artiq.tools import expect_no_log_messages
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -70,3 +71,13 @@ class ControllerCase(unittest.TestCase):
await remote.ping() await remote.ping()
self.loop.run_until_complete(test()) self.loop.run_until_complete(test())
def test_no_command_controller(self):
entry = {
"type": "controller",
"host": "::1",
"port": 3253
}
with expect_no_log_messages(logging.ERROR):
self.controllers["lda_sim"] = entry
self.assertTrue(self.controllers.queue.empty())

View File

@ -1,6 +1,7 @@
import asyncio import asyncio
import atexit import atexit
import collections import collections
import contextlib
import importlib.machinery import importlib.machinery
import logging import logging
import os import os
@ -16,6 +17,7 @@ from artiq.protocols import pyon
__all__ = ["parse_arguments", "elide", "short_format", "file_import", __all__ = ["parse_arguments", "elide", "short_format", "file_import",
"get_experiment", "add_common_args", "simple_network_args", "get_experiment", "add_common_args", "simple_network_args",
"UnexpectedLogMessageError", "expect_no_log_messages",
"multiline_log_config", "init_logger", "bind_address_from_args", "multiline_log_config", "init_logger", "bind_address_from_args",
"atexit_register_coroutine", "exc_to_warning", "atexit_register_coroutine", "exc_to_warning",
"asyncio_wait_or_cancel", "TaskObject", "Condition", "asyncio_wait_or_cancel", "TaskObject", "Condition",
@ -142,6 +144,36 @@ def simple_network_args(parser, default_port):
help=h) help=h)
class UnexpectedLogMessageError(Exception):
pass
class FailingLogHandler(logging.Handler):
def emit(self, record):
raise UnexpectedLogMessageError("Unexpected log message: '{}'".format(
record.getMessage()))
@contextlib.contextmanager
def expect_no_log_messages(level, logger=None):
"""Raise an UnexpectedLogMessageError if a log message of the given level
(or above) is emitted while the context is active.
Example: ::
with expect_no_log_messages(logging.ERROR):
do_stuff_that_should_not_log_errors()
"""
if logger is None:
logger = logging.getLogger()
handler = FailingLogHandler(level)
logger.addHandler(handler)
try:
yield
finally:
logger.removeHandler(handler)
class MultilineFormatter(logging.Formatter): class MultilineFormatter(logging.Formatter):
def __init__(self): def __init__(self):
logging.Formatter.__init__( logging.Formatter.__init__(