Skip to content

Commit bfc376f

Browse files
Allow users to reset the list of created records
Implemented a "ClearRecords" function that performs logic that was previously only in some code for tests.
1 parent dc4a63f commit bfc376f

File tree

6 files changed

+40
-17
lines changed

6 files changed

+40
-17
lines changed

CHANGELOG.rst

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Unreleased_
1111
-----------
1212

1313
- `Allow "status" and "severity" on In record init <../../pull/111>`_
14+
- `Allow users to reset the list of created records <../../pull/114>`_
1415

1516
4.1.0_ - 2022-08-05
1617
-------------------

docs/reference/api.rst

+4
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,10 @@ The following attributes allow more direct access to record creation.
426426

427427
See `../how-to/use-soft-records` for a full example of its usage.
428428

429+
.. function:: ClearRecords()
430+
This can be used to remove all created records. This means the same record
431+
names can be re-used for different record types.
432+
429433
Finally, the following function is used to load record definitions before
430434
starting the IOC.
431435

softioc/builder.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import numpy
33

4+
from .device_core import RecordLookup
45
from .softioc import dbLoadDatabase
56

67
from epicsdbbuilder import *
@@ -290,6 +291,12 @@ def LoadDatabase():
290291
pythonSoftIoc.RecordWrapper.reset_builder()
291292

292293

294+
def ClearRecords():
295+
"""Delete all created record information, allowing new record creation"""
296+
RecordLookup._RecordDirectory.clear()
297+
ResetRecords()
298+
299+
293300
# ----------------------------------------------------------------------------
294301
# Record name configuration. A device name prefix must be specified.
295302

@@ -317,7 +324,7 @@ def UnsetDevice():
317324
'longStringIn', 'longStringOut',
318325
'Action',
319326
# Other builder support functions
320-
'LoadDatabase',
327+
'LoadDatabase', 'ClearRecords',
321328
'SetDeviceName', 'UnsetDevice',
322329
# Device support functions
323330
'SetBlocking'

softioc/softioc.py

-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
from ctypes import *
55
from tempfile import NamedTemporaryFile
66

7-
from epicsdbbuilder.recordset import recordset
8-
97
from . import imports, device
108
from . import cothread_dispatcher
119

tests/conftest.py

+3-12
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
import pytest
1111

1212
# Must import softioc before epicsdbbuilder
13-
from softioc.device_core import RecordLookup
14-
from epicsdbbuilder import ResetRecords
13+
from softioc.builder import ClearRecords
1514

1615
requires_cothread = pytest.mark.skipif(
1716
sys.platform.startswith("win"), reason="Cothread doesn't work on windows"
@@ -88,20 +87,12 @@ def asyncio_ioc_override():
8887
ioc.kill()
8988
aioca_cleanup()
9089

91-
def _clear_records():
92-
# Remove any records created at epicsdbbuilder layer
93-
ResetRecords()
94-
# And at pythonSoftIoc level
95-
# TODO: Remove this hack and use use whatever comes out of
96-
# https://github.com/dls-controls/pythonSoftIOC/issues/56
97-
RecordLookup._RecordDirectory.clear()
98-
9990
@pytest.fixture(autouse=True)
10091
def clear_records():
10192
"""Deletes all records before and after every test"""
102-
_clear_records()
93+
ClearRecords()
10394
yield
104-
_clear_records()
95+
ClearRecords()
10596

10697
@pytest.fixture(autouse=True)
10798
def enable_code_coverage():

tests/test_records.py

+24-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
log,
1010
create_random_prefix,
1111
requires_cothread,
12-
_clear_records,
1312
WAVEFORM_LENGTH,
1413
TIMEOUT,
1514
select_and_recv,
@@ -19,6 +18,7 @@
1918
from softioc import asyncio_dispatcher, builder, softioc
2019
from softioc import alarm
2120
from softioc.device import SetBlocking
21+
from softioc.device_core import LookupRecord, LookupRecordList
2222

2323
# Test file for miscellaneous tests related to records
2424

@@ -38,7 +38,6 @@ def test_records(tmp_path):
3838
# Ensure we definitely unload all records that may be hanging over from
3939
# previous tests, then create exactly one instance of expected records.
4040
from sim_records import create_records
41-
_clear_records()
4241
create_records()
4342

4443
path = str(tmp_path / "records.db")
@@ -228,6 +227,29 @@ def test_setting_alarm_invalid_keywords(creation_func):
228227

229228
assert e.value.args[0] == 'Can\'t specify both status and STAT'
230229

230+
def test_clear_records():
231+
"""Test that clearing the known records allows creation of a record of the
232+
same name afterwards"""
233+
record_name = "NEW-RECORD"
234+
235+
builder.aOut(record_name)
236+
237+
# First check that we cannot create two of the same name
238+
with pytest.raises(AssertionError):
239+
builder.aOut(record_name)
240+
241+
builder.ClearRecords()
242+
243+
# Then confirm we can create one of this name
244+
builder.aOut(record_name)
245+
246+
# Finally prove that the underlying record holder contains only one record
247+
assert LookupRecord(record_name)
248+
assert len(LookupRecordList()) == 1
249+
for key, val in LookupRecordList():
250+
assert key == record_name
251+
252+
231253

232254
def validate_fixture_names(params):
233255
"""Provide nice names for the out_records fixture in TestValidate class"""

0 commit comments

Comments
 (0)