test_bad_icepap_host fails
This test currently always fails on my computer (current master):
(/users/denolf/virtualenvs/bliss_env) denolf@lindenolf:~/dev/bliss$ pytest tests/config/test_config.py::test_bad_icepap_host
=========================================================== test session starts ============================================================
platform linux -- Python 3.7.9, pytest-5.3.5, py-1.9.0, pluggy-0.13.1 -- /home/denolf/virtualenvs/bliss_env/bin/python
cachedir: .pytest_cache
rootdir: /home/denolf/dev/bliss, inifile: setup.cfg
plugins: typeguard-2.6.1, profiling-1.7.0, cov-2.10.1, rerunfailures-9.1.1, mock-3.3.1
collected 1 item
tests/config/test_config.py::test_bad_icepap_host FAILED [100%]
================================================================= FAILURES =================================================================
___________________________________________________________ test_bad_icepap_host ___________________________________________________________
self = <bliss.controllers.motors.icepap.Icepap object at 0x7ffb8ecab510>, axis = <bliss.common.axis.Axis object at 0x7ffb8eaad710>
def set_on(self, axis):
"""
Put the axis power on
"""
try:
> self._power(axis, True)
bliss/controllers/motors/icepap/__init__.py:144:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <bliss.controllers.motors.icepap.Icepap object at 0x7ffb8ecab510>, axis = <bliss.common.axis.Axis object at 0x7ffb8eaad710>
power = True
def _power(self, axis, power):
if isinstance(axis, TrajectoryAxis):
return
> _ackcommand(self._cnx, "POWER %s %s" % ("ON" if power else "OFF", axis.address))
bliss/controllers/motors/icepap/__init__.py:158:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cnx = <bliss.comm.tcp.Command object at 0x7ffb8eaad750>, cmd = '#POWER ON 1', data = None, pre_cmd = None
def _ackcommand(cnx, cmd, data=None, pre_cmd=None):
if not cmd.startswith("#") and not cmd.startswith("?"):
cmd = "#" + cmd
> return _command(cnx, cmd, data, pre_cmd)
bliss/controllers/motors/icepap/comm.py:157:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
args = (<bliss.comm.tcp.Command object at 0x7ffb8eaad750>, '#POWER ON 1', None, None), kwargs = {}
@wraps(fu)
def func(*args, **kwargs):
with KillMask():
> return fu(*args, **kwargs)
bliss/common/greenlet_utils.py:69:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cnx = <bliss.comm.tcp.Command object at 0x7ffb8eaad750>, cmd = '#POWER ON 1', data = None, pre_cmd = None, timeout = None
@protect_from_kill
def _command(cnx, cmd, data=None, pre_cmd=None, timeout=None):
try:
return _command_raw(cnx, cmd, data, pre_cmd, timeout=timeout)
except IOError as ioex:
if ioex.errno == 113:
_msg = f"IOError {ioex.errno}:{errno.errorcode[ioex.errno]}"
_msg += f"\nmessage={os.strerror(ioex.errno)} "
_msg += f"\nPlease check that icepap controller '{cnx._host}' is ON"
raise RuntimeError(_msg)
elif ioex.errno == -2:
_msg = f"IOError {ioex.errno}"
_msg += f"\nPlease check icepap controller: '{cnx._host}'"
raise RuntimeError(_msg)
else:
> raise ioex
bliss/controllers/motors/icepap/comm.py:92:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cnx = <bliss.comm.tcp.Command object at 0x7ffb8eaad750>, cmd = '#POWER ON 1', data = None, pre_cmd = None, timeout = None
@protect_from_kill
def _command(cnx, cmd, data=None, pre_cmd=None, timeout=None):
try:
> return _command_raw(cnx, cmd, data, pre_cmd, timeout=timeout)
bliss/controllers/motors/icepap/comm.py:80:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cnx = <bliss.comm.tcp.Command object at 0x7ffb8eaad750>, cmd = b'#POWER ON 1', data = None, pre_cmd = None, timeout = None
def _command_raw(cnx, cmd, data=None, pre_cmd=None, timeout=None):
reply_flag = _check_reply.match(cmd)
cmd = cmd.encode()
if data is not None:
uint16_view = data.view(dtype=numpy.uint16)
data_checksum = uint16_view.sum()
header = struct.pack(
"<III",
0xA5AA555A, # Header key
len(uint16_view),
int(data_checksum) & 0xFFFFFFFF,
)
data_test = data.newbyteorder("<")
if len(data_test) and data_test[0] != data[0]: # not good endianness
data = data.byteswap()
full_cmd = b"%s\n%s%s" % (cmd, header, data.tostring())
transaction = cnx._write(full_cmd)
else:
if pre_cmd:
full_cmd = b"%s%s\n" % (pre_cmd.encode(), cmd)
else:
full_cmd = b"%s\n" % cmd
> transaction = cnx._write(full_cmd)
bliss/controllers/motors/icepap/comm.py:124:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <bliss.comm.tcp.Command object at 0x7ffb8eaad750>, args = (b'#POWER ON 1\n',), kwarg = {}, timeout = None
def rfunc(self, *args, **kwarg):
timeout = kwarg.get("timeout")
if not self._connected:
> self.connect(timeout=timeout)
bliss/comm/tcp.py:387:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <bliss.comm.tcp.Command object at 0x7ffb8eaad750>, host = None, port = None, timeout = None
def connect(self, host=None, port=None, timeout=None):
curr_host = host or self._host
curr_port = port or self._port
local_timeout = timeout if timeout is not None else self._timeout
log_debug(self, "connect to %s:%s", curr_host, curr_port)
log_debug(self, "timeout=%s ; eol=%a", local_timeout, self._eol)
if self._connected:
prev_ip_host, prev_port = self._socket.getpeername()
try:
prev_host, aliaslist, _ = socket.gethostbyaddr(prev_ip_host)
except socket.herror:
prev_host = prev_ip_host
aliaslist = []
fqdn_host = socket.getfqdn(curr_host)
if curr_port != prev_port or (
fqdn_host != prev_host and prev_host not in aliaslist
):
self.close()
with self._lock:
if self._connected:
return True
self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
err_msg = "timeout on command(%s, %d)" % (curr_host, curr_port)
with gevent.Timeout(local_timeout, CommandTimeout(err_msg)):
> self._socket.connect((curr_host, curr_port))
bliss/comm/tcp.py:518:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <gevent._socket3.socket at 0x7ffb8ea532f0 object, fd=25, family=2, type=1, proto=0>, address = ('iceid666', 5000)
def connect(self, address):
"""
Connect to *address*.
.. versionchanged:: 20.6.0
If the host part of the address includes an IPv6 scope ID,
it will be used instead of ignored, if the platform supplies
:func:`socket.inet_pton`.
"""
if self.timeout == 0.0:
return _socket.socket.connect(self._sock, address)
> address = _socketcommon._resolve_addr(self._sock, address)
../../virtualenvs/bliss_env/lib/python3.7/site-packages/gevent/_socket3.py:402:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
sock = <socket object, fd=25, family=2, type=1, proto=0>, address = ('iceid666', 5000)
def _resolve_addr(sock, address):
# Internal method: resolve the AF_INET[6] address using
# getaddrinfo.
if sock.family not in _RESOLVABLE_FAMILIES or not isinstance(address, tuple):
return address
# address is (host, port) (ipv4) or (host, port, flowinfo, scopeid) (ipv6).
# If it's already resolved, no need to go through getaddrinfo() again.
# That can lose precision (e.g., on IPv6, it can lose scopeid). The standard library
# does this in socketmodule.c:setipaddr. (This is only part of the logic, the real
# thing is much more complex.)
try:
if __socket__.inet_pton(sock.family, address[0]):
return address
except AttributeError: # pragma: no cover
# inet_pton might not be available.
pass
except __socket__.error:
# Not parseable, needs resolved.
pass
# We don't pass the port to getaddrinfo because the C
# socket module doesn't either (on some systems its
# illegal to do that without also passing socket type and
# protocol). Instead we join the port back at the end.
# See https://github.com/gevent/gevent/issues/1252
host, port = address[:2]
> r = getaddrinfo(host, None, sock.family)
../../virtualenvs/bliss_env/lib/python3.7/site-packages/gevent/_socketcommon.py:427:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
host = 'iceid666', port = None, family = 2, type = 0, proto = 0, flags = 0
def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0):
# pylint:disable=function-redefined, undefined-variable
# Also, on Python 3, we need to translate into the special enums.
# Our lower-level resolvers, including the thread and blocking, which use _socket,
# function simply with integers.
> addrlist = get_hub().resolver.getaddrinfo(host, port, family, type, proto, flags)
../../virtualenvs/bliss_env/lib/python3.7/site-packages/gevent/_socketcommon.py:230:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <gevent.resolver.thread.Resolver at 0x7ffb8ec5a190 pool=<ThreadPool at 0x7ffb8ebe7440 tasks=0 size=1 maxsize=10 hub=<Hub at 0x7ffbb9814d50 thread_ident=0x7ffbbfdb6740>>>
args = ('iceid666', None, 2, 0, 0, 0), kwargs = {}
def getaddrinfo(self, *args, **kwargs):
> return self.pool.apply(_socket.getaddrinfo, args, kwargs)
../../virtualenvs/bliss_env/lib/python3.7/site-packages/gevent/resolver/thread.py:63:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <ThreadPool at 0x7ffb8ebe7440 tasks=0 size=1 maxsize=10 hub=<Hub at 0x7ffbb9814d50 thread_ident=0x7ffbbfdb6740>>
func = <built-in function getaddrinfo>, args = ('iceid666', None, 2, 0, 0, 0), kwds = {}
def apply(self, func, args=None, kwds=None):
"""
Rough quivalent of the :func:`apply()` builtin function blocking until
the result is ready and returning it.
The ``func`` will *usually*, but not *always*, be run in a way
that allows the current greenlet to switch out (for example,
in a new greenlet or thread, depending on implementation). But
if the current greenlet or thread is already one that was
spawned by this pool, the pool may choose to immediately run
the `func` synchronously.
Any exception ``func`` raises will be propagated to the caller of ``apply`` (that is,
this method will raise the exception that ``func`` raised).
"""
if args is None:
args = ()
if kwds is None:
kwds = {}
if self._apply_immediately():
return func(*args, **kwds)
> return self.spawn(func, *args, **kwds).get()
../../virtualenvs/bliss_env/lib/python3.7/site-packages/gevent/pool.py:161:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> ???
src/gevent/event.py:305:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> ???
src/gevent/event.py:335:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> ???
src/gevent/event.py:323:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> ???
src/gevent/event.py:303:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
t = <class 'socket.gaierror'>, value = gaierror(-3, 'Temporary failure in name resolution'), tb = <traceback object at 0x7ffb8ea5d690>
def reraise(t, value, tb=None): # pylint:disable=unused-argument
if value.__traceback__ is not tb and tb is not None:
> raise value.with_traceback(tb)
../../virtualenvs/bliss_env/lib/python3.7/site-packages/gevent/_compat.py:65:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> thread_result.set(func(*args, **kwargs))
E socket.gaierror: [Errno -3] Temporary failure in name resolution
../../virtualenvs/bliss_env/lib/python3.7/site-packages/gevent/threadpool.py:142: gaierror
During handling of the above exception, another exception occurred:
self = <bliss.controllers.motors.icepap.Icepap object at 0x7ffb8ecab510>, axis = <bliss.common.axis.Axis object at 0x7ffb8eaad710>
def initialize_hardware_axis(self, axis):
if axis.config.get("autopower", converter=bool, default=True):
try:
> self.set_on(axis)
bliss/controllers/motors/icepap/__init__.py:120:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <bliss.controllers.motors.icepap.Icepap object at 0x7ffb8ecab510>, axis = <bliss.common.axis.Axis object at 0x7ffb8eaad710>
def set_on(self, axis):
"""
Put the axis power on
"""
try:
self._power(axis, True)
except Exception as e:
> raise type(e)("Axis '%s`: %s" % (axis.name, str(e)))
E socket.gaierror: Axis 'v6biturbo`: [Errno -3] Temporary failure in name resolution
bliss/controllers/motors/icepap/__init__.py:146: gaierror
During handling of the above exception, another exception occurred:
beacon = <bliss.config.static.Config object at 0x7ffb8ec0a950>
def test_bad_icepap_host(beacon):
bad_mot = beacon.get("v6biturbo")
with pytest.raises(RuntimeError):
> a = bad_mot.position
tests/config/test_config.py:246:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
bliss/common/axis.py:648: in func_wrapper
self.controller._initialize_axis(self)
bliss/controllers/motor.py:181: in _initialize_axis
self.initialize_hardware_axis(axis)
bliss/controllers/motors/icepap/__init__.py:125: in initialize_hardware_axis
axis._update_settings(AxisState(("DISABLED", "OFF")))
bliss/common/axis.py:1572: in _update_settings
self._update_dial()
bliss/common/axis.py:649: in func_wrapper
return func(self, *args, **kwargs)
bliss/common/axis.py:1070: in _update_dial
dial_pos = self._hw_position
bliss/common/axis.py:649: in func_wrapper
return func(self, *args, **kwargs)
bliss/common/axis.py:1084: in _hw_position
curr_pos = self.__controller.read_position(self) / self.steps_per_unit
bliss/controllers/motors/icepap/__init__.py:166: in read_position
return int(_command(self._cnx, "?%s %s" % (pos_cmd, axis.address)))
bliss/common/greenlet_utils.py:69: in func
return fu(*args, **kwargs)
bliss/controllers/motors/icepap/comm.py:92: in _command
raise ioex
bliss/controllers/motors/icepap/comm.py:80: in _command
return _command_raw(cnx, cmd, data, pre_cmd, timeout=timeout)
bliss/controllers/motors/icepap/comm.py:124: in _command_raw
transaction = cnx._write(full_cmd)
bliss/comm/tcp.py:387: in rfunc
self.connect(timeout=timeout)
bliss/comm/tcp.py:518: in connect
self._socket.connect((curr_host, curr_port))
../../virtualenvs/bliss_env/lib/python3.7/site-packages/gevent/_socket3.py:402: in connect
address = _socketcommon._resolve_addr(self._sock, address)
../../virtualenvs/bliss_env/lib/python3.7/site-packages/gevent/_socketcommon.py:427: in _resolve_addr
r = getaddrinfo(host, None, sock.family)
../../virtualenvs/bliss_env/lib/python3.7/site-packages/gevent/_socketcommon.py:230: in getaddrinfo
addrlist = get_hub().resolver.getaddrinfo(host, port, family, type, proto, flags)
../../virtualenvs/bliss_env/lib/python3.7/site-packages/gevent/resolver/thread.py:63: in getaddrinfo
return self.pool.apply(_socket.getaddrinfo, args, kwargs)
../../virtualenvs/bliss_env/lib/python3.7/site-packages/gevent/pool.py:161: in apply
return self.spawn(func, *args, **kwds).get()
src/gevent/event.py:305: in gevent._gevent_cevent.AsyncResult.get
???
src/gevent/event.py:335: in gevent._gevent_cevent.AsyncResult.get
???
src/gevent/event.py:323: in gevent._gevent_cevent.AsyncResult.get
???
src/gevent/event.py:303: in gevent._gevent_cevent.AsyncResult._raise_exception
???
../../virtualenvs/bliss_env/lib/python3.7/site-packages/gevent/_compat.py:65: in reraise
raise value.with_traceback(tb)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> thread_result.set(func(*args, **kwargs))
E socket.gaierror: [Errno -3] Temporary failure in name resolution
../../virtualenvs/bliss_env/lib/python3.7/site-packages/gevent/threadpool.py:142: gaierror
---------------------------------------------------------- Captured stdout setup -----------------------------------------------------------
* Serving Flask app "bliss.config.conductor.web.configuration.config_app" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Serving Flask app "bliss.config.conductor.web.homepage.homepage_app" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off