diff --git a/setup.py b/setup.py index 34157bce..1b70ecd2 100644 --- a/setup.py +++ b/setup.py @@ -41,6 +41,7 @@ ] devIocStats_src = os.path.join("softioc", "iocStats", "devIocStats") +devIocStats_posix = os.path.join(devIocStats_src, "os", "posix") devIocStats_os = os.path.join(devIocStats_src, "os", get_config_var('OS_CLASS')) devIocStats_default = os.path.join(devIocStats_src, "os", "default") @@ -52,14 +53,26 @@ else: sources.append(os.path.join(devIocStats_default, f)) +include_dirs = [ + epicscorelibs.path.include_path, + devIocStats_src, + devIocStats_os, + devIocStats_default +] + +if get_config_var("POSIX"): + # If we're on a POSIX system, insert the POSIX folder into the list after + # the os-specific one so that os-specific header files are used first. + include_dirs.insert( + include_dirs.index(devIocStats_os) + 1, + devIocStats_posix + ) + # Extension with all our C code ext = Extension( name='softioc._extension', sources = sources, - include_dirs=[ - epicscorelibs.path.include_path, - devIocStats_src, devIocStats_os, devIocStats_default - ], + include_dirs = include_dirs, dsos = [ 'epicscorelibs.lib.qsrv', 'epicscorelibs.lib.pvAccessIOC', diff --git a/tests/test_deviocstats.py b/tests/test_deviocstats.py new file mode 100644 index 00000000..ae345457 --- /dev/null +++ b/tests/test_deviocstats.py @@ -0,0 +1,70 @@ +# File for tests related to devIocStats support module, which at time of writing +# is built alongside PythonSoftIOC and optionally turned on at runtime + +import multiprocessing +import pytest + +from conftest import ( + create_random_prefix, + TIMEOUT, + select_and_recv, + get_multiprocessing_context +) + +from softioc import asyncio_dispatcher, builder, softioc + +def deviocstats_test_func( + device_name, + child_conn): + """Start the IOC with the specified validate method""" + + builder.SetDeviceName(device_name) + + dispatcher = asyncio_dispatcher.AsyncioDispatcher() + builder.LoadDatabase() + softioc.devIocStats(device_name) + softioc.iocInit(dispatcher) + + child_conn.send("R") + + # Keep process alive while main thread runs CAGET + if child_conn.poll(TIMEOUT): + val = child_conn.recv() + assert val == "D", "Did not receive expected Done character" + +def test_deviocstats(): + + ctx = get_multiprocessing_context() + + parent_conn, child_conn = ctx.Pipe() + + device_name = create_random_prefix() + + process = ctx.Process( + target=deviocstats_test_func, + args=(device_name, child_conn), + ) + + process.start() + + from cothread.catools import caget, _channel_cache + + try: + # Wait for message that IOC has started + select_and_recv(parent_conn, "R") + + # Suppress potential spurious warnings + _channel_cache.purge() + + cpu_cnt = caget(device_name + ":CPU_CNT") + assert cpu_cnt == multiprocessing.cpu_count() + + ioc_cpu_load = caget(device_name + ":IOC_CPU_LOAD") + assert ioc_cpu_load == pytest.approx(0, abs=1e-2) + + + finally: + # Suppress potential spurious warnings + _channel_cache.purge() + parent_conn.send("D") # "Done" + process.join(timeout=TIMEOUT)