Commit 8aca7ef4 authored by Cyril Guilloud's avatar Cyril Guilloud

Merge branch 'handel-bump' into 'master'

Update to handel >= 1.2.19

See merge request !1
parents 77f71098 3c2a5430
Pipeline #8321 passed with stages
in 1 minute and 45 seconds
"""CFFI binding.""" """CFFI binding."""
import os
import cffi import cffi
ffi = cffi.FFI() ffi = cffi.FFI()
...@@ -48,4 +49,4 @@ int xiaSetLogOutput(char *fileName); ...@@ -48,4 +49,4 @@ int xiaSetLogOutput(char *fileName);
void xiaGetVersionInfo(int *rel, int *min, int *maj, char *pretty); void xiaGetVersionInfo(int *rel, int *min, int *maj, char *pretty);
""") """)
handel = ffi.dlopen("handel.dll") handel = ffi.dlopen('handel.dll' if os.name == 'nt' else 'libhandel.so')
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
from __future__ import absolute_import from __future__ import absolute_import
import os import os
import warnings
from functools import reduce from functools import reduce
import numpy import numpy
...@@ -37,8 +38,8 @@ __all__ = ['init', 'init_handel', 'exit', ...@@ -37,8 +38,8 @@ __all__ = ['init', 'init_handel', 'exit',
'get_master_channels', 'get_trigger_channels', 'get_master_channels', 'get_trigger_channels',
'set_acquisition_value', 'get_acquisition_value', 'set_acquisition_value', 'get_acquisition_value',
'remove_acquisition_value', 'apply_acquisition_values', 'remove_acquisition_value', 'apply_acquisition_values',
'get_handel_version', 'get_handel_version', 'get_config_files', 'get_config',
'get_config_files', 'get_config'] 'HandelError']
MAX_STRING_LENGTH = 80 MAX_STRING_LENGTH = 80
...@@ -184,14 +185,6 @@ def is_running(): ...@@ -184,14 +185,6 @@ def is_running():
def get_module_statistics(module): def get_module_statistics(module):
channels = get_module_channels(module) channels = get_module_channels(module)
# FalconX requires a spectrum read for the statistics to be updated
if get_module_type(module).startswith(u'falconx'):
for channel in channels:
if channel >= 0:
try:
get_spectrum(channel)
except HandelError:
pass
# Prepare buffer # Prepare buffer
data_size = 9 * len(channels) data_size = 9 * len(channels)
master = next(c for c in channels if c >= 0) master = next(c for c in channels if c >= 0)
...@@ -341,7 +334,7 @@ def get_all_buffer_data(buffer_id): ...@@ -341,7 +334,7 @@ def get_all_buffer_data(buffer_id):
return merge_buffer_data(*data) return merge_buffer_data(*data)
def synchronized_poll_data(done=set()): def synchronized_poll_data():
"""Convenient helper for buffer management in mapping mode. """Convenient helper for buffer management in mapping mode.
It assumes that all the modules are configured with the same number It assumes that all the modules are configured with the same number
...@@ -369,14 +362,6 @@ def synchronized_poll_data(done=set()): ...@@ -369,14 +362,6 @@ def synchronized_poll_data(done=set()):
# Overrun from hardware # Overrun from hardware
if any_buffer_overrun(): if any_buffer_overrun():
raise overrun_error raise overrun_error
# FalconX hack
# The buffer_done command does not reset the full flag.
# It's only reset when the buffer starts being filled up again.
# For this reason, we need to remember full flags from the previous call.
# This is exactly what the done set does.
done &= full # Reset done flags
full -= done # Don't read twice
done |= full # Set done flags
# Read data from buffers # Read data from buffers
for x in full: for x in full:
data[x] = get_all_buffer_data(x) data[x] = get_all_buffer_data(x)
...@@ -697,3 +682,12 @@ def get_config(*path): ...@@ -697,3 +682,12 @@ def get_config(*path):
filename = os.path.join(*path) filename = os.path.join(*path)
with open(filename) as f: with open(filename) as f:
return parse_xia_ini_file(f.read()) return parse_xia_ini_file(f.read())
# Check version at import time
if get_handel_version() < (1, 2, 19):
warnings.warn("""\
The current handel version is older than 1.2.19.
This might cause bugs, especially with the FalconX.
Please consider upgrading to a more recent version.""")
import mock
import pytest
@pytest.fixture(scope='session')
def interface_import():
with mock.patch('cffi.FFI.dlopen') as dlopen:
with mock.patch('os.name', new='nt'):
# Set up get version info to trigger a warning
m = dlopen.return_value.xiaGetVersionInfo
def side_effect(a, b, c, d):
# v1.2.18 is too old!
d[0], c[0], b[0], a[0] = b'v', 1, 2, 18
m.side_effect = side_effect
# Perform the import only once
with pytest.warns(UserWarning) as record:
from handel import interface
assert len(record) == 1
assert "older than 1.2.19" in str(record[0].message)
# Remove mock
del dlopen.return_value.xiaGetVersionInfo
# Work around for https://bugs.python.org/issue31177
dlopen.return_value._mock_children.clear()
# Check dlopen
dlopen.assert_called_once_with('handel.dll')
assert interface.handel == dlopen.return_value
yield interface
@pytest.fixture
def interface(interface_import):
with mock.patch('handel.interface.check_error'):
try:
# Reset mock
handel = interface_import.handel
handel.reset_mock()
yield interface_import
finally:
# Revert gevent patch
interface_import.handel = handel
import mock
def test_gevent_compatibility(interface):
# Declare xiaSomeFunction
handel = interface.handel
original = handel.xiaSomeFunction
original.__name__ = 'xiaSomeFunction'
original.return_value = 'Some result'
def test_gevent_compatibility(): # Patching
with mock.patch('cffi.FFI.dlopen') as dlopen: from handel.gevent import patch
# Declare xiaSomeFunction assert patch() is None
handel = dlopen.return_value
original = handel.xiaSomeFunction
original.__name__ = 'xiaSomeFunction'
original.return_value = 'Some result'
# Patching # Checking
from handel.gevent import patch assert interface.handel.xiaSomeFunction.__name__ == 'xiaSomeFunction'
from handel import interface assert interface.handel.xiaSomeFunction(1, a=2) is 'Some result'
assert patch() is None original.assert_called_once_with(1, a=2)
# Checking
assert interface.handel.xiaSomeFunction.__name__ == 'xiaSomeFunction'
assert interface.handel.xiaSomeFunction(1, a=2) is 'Some result'
original.assert_called_once_with(1, a=2)
...@@ -3,16 +3,6 @@ import numpy ...@@ -3,16 +3,6 @@ import numpy
import pytest import pytest
from handel.stats import Stats from handel.stats import Stats
from handel.error import HandelError
@pytest.fixture
def interface():
with mock.patch('cffi.FFI.dlopen') as dlopen:
with mock.patch('handel.interface.check_error'):
from handel import interface
interface.handel = dlopen.return_value
yield interface
# Initializing handel # Initializing handel
...@@ -310,28 +300,23 @@ def test_get_module_statistics(interface): ...@@ -310,28 +300,23 @@ def test_get_module_statistics(interface):
m.side_effect = side_effect m.side_effect = side_effect
with mock.patch('handel.interface.get_module_channels') as m2: with mock.patch('handel.interface.get_module_channels') as m2:
with mock.patch('handel.interface.get_module_type') as m3: m2.return_value = [-1, -1, -1, 8]
with mock.patch('handel.interface.get_spectrum') as m4:
m2.return_value = [-1, -1, -1, 8] # First test
m3.return_value = u'falconxn' assert interface.get_module_statistics('module3') == expected
m4.side_effect = HandelError(12, 'hello') m2.assert_called_once_with('module3')
arg = m.call_args[0][2]
# First test m.assert_called_once_with(8, b'module_statistics_2', arg)
assert interface.get_module_statistics('module3') == expected
m2.assert_called_once_with('module3') # Second test
arg = m.call_args[0][2] raw[5] = 4.56 # ICR inconsistency
m.assert_called_once_with(8, b'module_statistics_2', arg) raw[6] = 1.23 # OCR inconsistency
m4.assert_called_once_with(8) with pytest.warns(UserWarning) as ctx:
interface.get_module_statistics('module3')
# Second test assert ctx[0].message.args[0].startswith(
raw[5] = 4.56 # ICR inconsistency 'ICR buffer inconsistency: 4.56 != 3131.7208')
raw[6] = 1.23 # OCR inconsistency assert ctx[1].message.args[0].startswith(
with pytest.warns(UserWarning) as ctx: 'OCR buffer inconsistency: 1.23 != 2724.3282')
interface.get_module_statistics('module3')
assert ctx[0].message.args[0].startswith(
'ICR buffer inconsistency: 4.56 != 3131.7208')
assert ctx[1].message.args[0].startswith(
'OCR buffer inconsistency: 1.23 != 2724.3282')
# Make sure errors have been checked # Make sure errors have been checked
interface.check_error.assert_called_with(0) interface.check_error.assert_called_with(0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment