Skip to content

Commit 4014707

Browse files
Add tests for issue #37 and fix other test fails
Other fails appear to be the spawned Validate Process not correctly updating, or possibly not being removed from previous test run, on each iteration. Workaround is to give each one a unique device prefix and add logging to work out what it might be for future issues.
1 parent 5f14ca3 commit 4014707

File tree

3 files changed

+65
-15
lines changed

3 files changed

+65
-15
lines changed

Diff for: tests/conftest.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@
1919
# Length picked to match string record length, so we can re-use test strings.
2020
WAVEFORM_LENGTH = 40
2121

22+
def create_random_prefix():
23+
"""Create 12-character random string, for generating unique Device Names"""
24+
return "".join(random.choice(string.ascii_uppercase) for _ in range(12))
25+
2226
class SubprocessIOC:
2327
def __init__(self, ioc_py):
24-
self.pv_prefix = "".join(
25-
random.choice(string.ascii_uppercase) for _ in range(12)
26-
)
28+
self.pv_prefix = create_random_prefix()
2729
sim_ioc = os.path.join(os.path.dirname(__file__), ioc_py)
2830
cmd = [sys.executable, sim_ioc, self.pv_prefix]
2931
self.proc = subprocess.Popen(

Diff for: tests/test_record_values.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -824,7 +824,7 @@ def test_string_rejects_overlong_strings(self):
824824

825825
def test_long_string_rejects_overlong_strings(self):
826826
"""Test that longStringIn & longStringOut records reject
827-
strings >=39 chars"""
827+
strings >=`WAVEFORM_LENGTH` chars"""
828828
OVERLONG_STR = MAX_LEN_STR + "A"
829829

830830
with pytest.raises(AssertionError):
@@ -847,7 +847,7 @@ def test_long_string_rejects_overlong_strings(self):
847847
lso = builder.longStringIn("LSTROUT2", length=WAVEFORM_LENGTH)
848848
lso.set(OVERLONG_STR)
849849

850-
# And a different way to initialise the records to trigger same behaviour:
850+
# And a different way to initialise records to trigger same behaviour:
851851
with pytest.raises(AssertionError):
852852
lsi = builder.longStringIn("LSTRIN3", initial_value="ABC")
853853
lsi.set(OVERLONG_STR)
@@ -869,7 +869,7 @@ def test_waveform_rejects_zero_length(self):
869869
with pytest.raises(AssertionError):
870870
builder.longStringOut("L_OUT", length=0)
871871

872-
def test_waveform_rejects_overlonglong_values(self):
872+
def test_waveform_rejects_overlong_values(self):
873873
"""Test that Waveform records throw an exception when an overlong
874874
value is written"""
875875
w_in = builder.WaveformIn("W_IN", [1, 2, 3])

Diff for: tests/test_records.py

+57-9
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22
import numpy
33
import os
44
import pytest
5-
import asyncio
65

7-
from conftest import requires_cothread, _clear_records, WAVEFORM_LENGTH
6+
from conftest import (
7+
create_random_prefix,
8+
requires_cothread,
9+
_clear_records,
10+
WAVEFORM_LENGTH,
11+
)
812

913
from softioc import asyncio_dispatcher, builder, softioc
1014

@@ -85,6 +89,44 @@ def test_DISP_can_be_overridden():
8589
# Note: DISP attribute won't exist if field not specified
8690
assert record.DISP.Value() == 0
8791

92+
93+
def test_waveform_construction():
94+
"""Test the various ways to construct a Waveform records all produce
95+
correct results"""
96+
97+
wi = builder.WaveformIn("WI1", [1, 2, 3])
98+
assert wi.NELM.Value() == 3
99+
100+
wi = builder.WaveformIn("WI2", initial_value=[1, 2, 3, 4])
101+
assert wi.NELM.Value() == 4
102+
103+
wi = builder.WaveformIn("WI3", length=5)
104+
assert wi.NELM.Value() == 5
105+
106+
wi = builder.WaveformIn("WI4", NELM=6)
107+
assert wi.NELM.Value() == 6
108+
109+
wi = builder.WaveformIn("WI5", [1, 2, 3], length=7)
110+
assert wi.NELM.Value() == 7
111+
112+
wi = builder.WaveformIn("WI6", initial_value=[1, 2, 3], length=8)
113+
assert wi.NELM.Value() == 8
114+
115+
wi = builder.WaveformIn("WI7", [1, 2, 3], NELM=9)
116+
assert wi.NELM.Value() == 9
117+
118+
wi = builder.WaveformIn("WI8", initial_value=[1, 2, 3], NELM=10)
119+
assert wi.NELM.Value() == 10
120+
121+
# Specifying neither value nor length should produce an error
122+
with pytest.raises(AssertionError):
123+
builder.WaveformIn("WI9")
124+
125+
# Specifying both value and initial_value should produce an error
126+
with pytest.raises(AssertionError):
127+
builder.WaveformIn("WI10", [1, 2, 4], initial_value=[5, 6])
128+
129+
88130
def validate_fixture_names(params):
89131
"""Provide nice names for the out_records fixture in TestValidate class"""
90132
return params[0].__name__
@@ -238,14 +280,15 @@ def out_records(self, request):
238280
"""The list of Out records to test """
239281
return request.param
240282

241-
def on_update_test_func(self, record_func, queue, always_update):
242-
283+
def on_update_test_func(
284+
self, device_name, record_func, queue, always_update
285+
):
243286
def on_update_func(new_val):
244287
"""Increments li record each time main out record receives caput"""
245288
nonlocal li
246289
li.set(li.get() + 1)
247290

248-
builder.SetDeviceName(DEVICE_NAME)
291+
builder.SetDeviceName(device_name)
249292

250293
kwarg = {}
251294
if record_func is builder.WaveformOut:
@@ -271,9 +314,11 @@ def on_update_func(new_val):
271314
def on_update_runner(self, creation_func, always_update, put_same_value):
272315
queue = multiprocessing.Queue()
273316

317+
device_name = create_random_prefix()
318+
274319
process = multiprocessing.Process(
275320
target=self.on_update_test_func,
276-
args=(creation_func, queue, always_update),
321+
args=(device_name, creation_func, queue, always_update),
277322
)
278323

279324
process.start()
@@ -293,17 +338,20 @@ def on_update_runner(self, creation_func, always_update, put_same_value):
293338

294339
while count < 4:
295340
put_ret = caput(
296-
DEVICE_NAME + ":ON-UPDATE-RECORD",
341+
device_name + ":ON-UPDATE-RECORD",
297342
9 if put_same_value else count,
298343
wait=True,
299344
)
300-
assert put_ret.ok, "caput did not succeed"
345+
assert put_ret.ok, f"caput did not succeed: {put_ret.errorcode}"
301346
count += 1
302347

303348
ret_val = caget(
304-
DEVICE_NAME + ":ON-UPDATE-COUNTER-RECORD",
349+
device_name + ":ON-UPDATE-COUNTER-RECORD",
305350
timeout=3,
306351
)
352+
assert ret_val.ok, \
353+
f"caget did not succeed: {ret_val.errorcode}, {ret_val}"
354+
307355

308356
# Expected value is either 3 (incremented once per caput)
309357
# or 1 (incremented on first caput and not subsequent ones)

0 commit comments

Comments
 (0)