Skip to content

Commit c826477

Browse files
Fix devIocStats by including posix headers
This relies on the config_var "POSIX" being defined as True/False for the current platform. The test is pretty simple, just the CPU count and IOC CPU load as they're fairly easy to calculate
1 parent 289897e commit c826477

File tree

3 files changed

+92
-4
lines changed

3 files changed

+92
-4
lines changed

CHANGELOG.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ Changed:
1414

1515
- `Improve string representation of RecordWrapper instances <../../pull/130>`
1616

17+
Fixed:
18+
19+
- `Fix devIocStats by including posix headers <../../pull/134>`
20+
1721
4.3.0_ - 2023-04-04
1822
-------------------
1923

setup.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
]
4242

4343
devIocStats_src = os.path.join("softioc", "iocStats", "devIocStats")
44+
devIocStats_posix = os.path.join(devIocStats_src, "os", "posix")
4445
devIocStats_os = os.path.join(devIocStats_src, "os", get_config_var('OS_CLASS'))
4546
devIocStats_default = os.path.join(devIocStats_src, "os", "default")
4647

@@ -52,14 +53,26 @@
5253
else:
5354
sources.append(os.path.join(devIocStats_default, f))
5455

56+
include_dirs = [
57+
epicscorelibs.path.include_path,
58+
devIocStats_src,
59+
devIocStats_os,
60+
devIocStats_default
61+
]
62+
63+
if get_config_var("POSIX"):
64+
# If we're on a POSIX system, insert the POSIX folder into the list after
65+
# the os-specific one so that os-specific header files are used first.
66+
include_dirs.insert(
67+
include_dirs.index(devIocStats_os) + 1,
68+
devIocStats_posix
69+
)
70+
5571
# Extension with all our C code
5672
ext = Extension(
5773
name='softioc._extension',
5874
sources = sources,
59-
include_dirs=[
60-
epicscorelibs.path.include_path,
61-
devIocStats_src, devIocStats_os, devIocStats_default
62-
],
75+
include_dirs = include_dirs,
6376
dsos = [
6477
'epicscorelibs.lib.qsrv',
6578
'epicscorelibs.lib.pvAccessIOC',

tests/test_deviocstats.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# File for tests related to devIocStats support module, which at time of writing
2+
# is built alongside PythonSoftIOC and optionally turned on at runtime
3+
4+
import multiprocessing
5+
import pytest
6+
7+
from conftest import (
8+
create_random_prefix,
9+
TIMEOUT,
10+
select_and_recv,
11+
get_multiprocessing_context
12+
)
13+
14+
from softioc import asyncio_dispatcher, builder, softioc
15+
16+
def deviocstats_test_func(
17+
device_name,
18+
child_conn):
19+
"""Start the IOC with the specified validate method"""
20+
21+
builder.SetDeviceName(device_name)
22+
23+
dispatcher = asyncio_dispatcher.AsyncioDispatcher()
24+
builder.LoadDatabase()
25+
softioc.devIocStats(device_name)
26+
softioc.iocInit(dispatcher)
27+
28+
child_conn.send("R")
29+
30+
# Keep process alive while main thread runs CAGET
31+
if child_conn.poll(TIMEOUT):
32+
val = child_conn.recv()
33+
assert val == "D", "Did not receive expected Done character"
34+
35+
@pytest.mark.asyncio
36+
async def test_deviocstats():
37+
38+
ctx = get_multiprocessing_context()
39+
40+
parent_conn, child_conn = ctx.Pipe()
41+
42+
device_name = create_random_prefix()
43+
44+
process = ctx.Process(
45+
target=deviocstats_test_func,
46+
args=(device_name, child_conn),
47+
)
48+
49+
process.start()
50+
51+
from aioca import caget, purge_channel_caches
52+
53+
try:
54+
# Wait for message that IOC has started
55+
select_and_recv(parent_conn, "R")
56+
57+
# Suppress potential spurious warnings
58+
purge_channel_caches()
59+
60+
cpu_cnt = await caget(device_name + ":CPU_CNT")
61+
assert cpu_cnt == multiprocessing.cpu_count()
62+
63+
ioc_cpu_load = await caget(device_name + ":IOC_CPU_LOAD")
64+
assert ioc_cpu_load == pytest.approx(0, abs=1e-2)
65+
66+
67+
finally:
68+
# Suppress potential spurious warnings
69+
purge_channel_caches()
70+
parent_conn.send("D") # "Done"
71+
process.join(timeout=TIMEOUT)

0 commit comments

Comments
 (0)