Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix devIocStats by including posix headers #134

Merged
merged 1 commit into from
Jun 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ Changed:

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

Fixed:

- `Fix devIocStats by including posix headers <../../pull/134>`

4.3.0_ - 2023-04-04
-------------------

Expand Down
21 changes: 17 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")

Expand All @@ -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',
Expand Down
71 changes: 71 additions & 0 deletions tests/test_deviocstats.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# 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"

@pytest.mark.asyncio
async 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 aioca import caget, purge_channel_caches

try:
# Wait for message that IOC has started
select_and_recv(parent_conn, "R")

# Suppress potential spurious warnings
purge_channel_caches()

cpu_cnt = await caget(device_name + ":CPU_CNT")
assert cpu_cnt == multiprocessing.cpu_count()

ioc_cpu_load = await caget(device_name + ":IOC_CPU_LOAD")
assert ioc_cpu_load == pytest.approx(0, abs=1e-2)


finally:
# Suppress potential spurious warnings
purge_channel_caches()
parent_conn.send("D") # "Done"
process.join(timeout=TIMEOUT)