Skip to content

Commit 27119ba

Browse files
Merge pull request #109 from ISISComputingGroup/Ticket8378_add_ruff_formatting
Ticket8378 add ruff formatting
2 parents 624b5c9 + 0c2dbfd commit 27119ba

16 files changed

+1044
-504
lines changed

.git-blame-ignore-revs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
adc8be0517795a04d559236949315f101fde9dc6
2+
fdec7664460c9b21e33e61ab604410ce1a0165e1

.github/workflows/linter.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
name: Linter
2+
on: [pull_request]
3+
jobs:
4+
call-workflow:
5+
uses: ISISComputingGroup/reusable-workflows/.github/workflows/linters.yml@main
6+
with:
7+
compare-branch: origin/master

TODO_test_start_stop_ioc_through_proc_control.py

Lines changed: 78 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""
22
System tests for starting or stopping iocs through Proc server
33
"""
4+
45
import os
56
import unittest
67
import xml.etree.ElementTree as ET
@@ -10,48 +11,56 @@
1011
from hamcrest import assert_that, less_than
1112
from six.moves import range
1213

13-
from utilities.utilities import g, as_seconds, start_ioc, stop_ioc, wait_for_ioc_start_stop, \
14-
load_config_if_not_already_loaded, bulk_start_ioc, bulk_stop_ioc
14+
from utilities.utilities import (
15+
as_seconds,
16+
bulk_start_ioc,
17+
bulk_stop_ioc,
18+
g,
19+
load_config_if_not_already_loaded,
20+
start_ioc,
21+
stop_ioc,
22+
wait_for_ioc_start_stop,
23+
)
1524

1625
# The following iocs are ignored in the test which starts/stops all iocs
1726
# This is usually because they don't build by default, or have some complex dependency,
1827
# or are special in some way (e.g. psctrl).
1928
# we also ignore ISISDAE, INSTETC and RUNCTRL as testing them here messed up subsequent tests
2029
# by leaving these IOCs permanently stopped. We could re-enable testing them if this test was either
21-
# always ran last or could re-enabel autostart on these ioc afterwards
30+
# always ran last or could re-enabel autostart on these ioc afterwards
2231
IOCS_TO_IGNORE_START_STOP = [
23-
'ASTRIUM_01',
24-
'ASTRIUM_02',
25-
'BGRSCRPT_01', # Won't keep running unless it has a config file
26-
'BGRSCRPT_02',
27-
'CHOPPERSIM', # Simulation ioc
28-
'CAENMCA', # currently fails to start, and is not used so skip
29-
'DELFTDCMAG_01', # Delft iocs have a weird build/run process?
30-
'DELFTDCMAG_02',
31-
'DELFTSHEAR_01',
32-
'ECLAB_01',
33-
'INSTETC',
34-
'ISISDAE',
35-
'LSICORR_01', # Needs vendor library in correct place to keep running
36-
'LSICORR_02',
37-
'MOTORSIM', # Simulation ioc
38-
'MOXA12XX_01',
39-
'MOXA12XX_02',
40-
'MOXA12XX_03',
41-
'MK3CHOPR_01',
42-
'NANODAC_01',
43-
'OERCONE_02',
44-
'PIXELMAN',
45-
'PSCTRL', # Special, controls other IOCs
46-
'REFL_01', # Won't run correctly without a config
47-
'RUNCTRL',
48-
'SECI2IBEX', # requires labview
49-
'SEPRTR', # relies on daqMX
50-
'TC_01', # relies on twincat
51-
'ZFMAGFLD' # relies on daqMX
32+
"ASTRIUM_01",
33+
"ASTRIUM_02",
34+
"BGRSCRPT_01", # Won't keep running unless it has a config file
35+
"BGRSCRPT_02",
36+
"CHOPPERSIM", # Simulation ioc
37+
"CAENMCA", # currently fails to start, and is not used so skip
38+
"DELFTDCMAG_01", # Delft iocs have a weird build/run process?
39+
"DELFTDCMAG_02",
40+
"DELFTSHEAR_01",
41+
"ECLAB_01",
42+
"INSTETC",
43+
"ISISDAE",
44+
"LSICORR_01", # Needs vendor library in correct place to keep running
45+
"LSICORR_02",
46+
"MOTORSIM", # Simulation ioc
47+
"MOXA12XX_01",
48+
"MOXA12XX_02",
49+
"MOXA12XX_03",
50+
"MK3CHOPR_01",
51+
"NANODAC_01",
52+
"OERCONE_02",
53+
"PIXELMAN",
54+
"PSCTRL", # Special, controls other IOCs
55+
"REFL_01", # Won't run correctly without a config
56+
"RUNCTRL",
57+
"SECI2IBEX", # requires labview
58+
"SEPRTR", # relies on daqMX
59+
"TC_01", # relies on twincat
60+
"ZFMAGFLD", # relies on daqMX
5261
]
5362

54-
GLOBALS_FILENAME = os.path.join(os.environ['ICPCONFIGROOT'], "globals.txt")
63+
GLOBALS_FILENAME = os.path.join(os.environ["ICPCONFIGROOT"], "globals.txt")
5564

5665

5766
class TestProcControl(unittest.TestCase):
@@ -104,20 +113,29 @@ def test_GIVEN_ioc_is_stopped_WHEN_call_start_multiple_times_quickly_THEN_ioc_is
104113
g.waitfor_time(seconds=5) # wait just in case it is starting
105114
wait_for_ioc_start_stop(timeout=30, is_start=True, ioc_name="SIMPLE")
106115

107-
def test_GIVEN_ioc_is_running_WHEN_call_restart_multiple_times_quickly_THEN_ioc_is_restarted(self):
116+
def test_GIVEN_ioc_is_running_WHEN_call_restart_multiple_times_quickly_THEN_ioc_is_restarted(
117+
self,
118+
):
108119
time_to_restart_and_read_uptime = 10
109120
start_ioc(ioc_name="SIMPLE")
110-
while as_seconds(g.get_pv("CS:IOC:SIMPLE:DEVIOS:UPTIME", is_local=True)) < time_to_restart_and_read_uptime:
121+
while (
122+
as_seconds(g.get_pv("CS:IOC:SIMPLE:DEVIOS:UPTIME", is_local=True))
123+
< time_to_restart_and_read_uptime
124+
):
111125
g.waitfor_time(seconds=1)
112126
for _ in range(20):
113127
g.set_pv("CS:PS:SIMPLE:RESTART", 1, is_local=True, wait=False)
114128

115129
wait_for_ioc_start_stop(timeout=30, is_start=True, ioc_name="SIMPLE")
116-
assert_that(as_seconds(g.get_pv("CS:IOC:SIMPLE:DEVIOS:UPTIME", is_local=True)),
117-
less_than(time_to_restart_and_read_uptime), "Uptime")
118-
119-
def test_GIVEN_ioc_is_off_WHEN_call_restart_multiple_times_quickly_THEN_ioc_is_still_stopped(self):
130+
assert_that(
131+
as_seconds(g.get_pv("CS:IOC:SIMPLE:DEVIOS:UPTIME", is_local=True)),
132+
less_than(time_to_restart_and_read_uptime),
133+
"Uptime",
134+
)
120135

136+
def test_GIVEN_ioc_is_off_WHEN_call_restart_multiple_times_quickly_THEN_ioc_is_still_stopped(
137+
self,
138+
):
121139
stop_ioc(ioc_name="SIMPLE")
122140

123141
for _ in range(20):
@@ -126,7 +144,6 @@ def test_GIVEN_ioc_is_off_WHEN_call_restart_multiple_times_quickly_THEN_ioc_is_s
126144
wait_for_ioc_start_stop(timeout=30, is_start=False, ioc_name="SIMPLE")
127145

128146
def test_WHEN_start_iocs_THEN_iocs_started_WHEN_stop_iocs_THEN_iocs_stopped(self):
129-
130147
# A test to check all IOCs start and stop correctly
131148
# Implemented to test for the error we encountered where we met our procserv limit and some iocs didn't start
132149

@@ -137,16 +154,17 @@ def test_WHEN_start_iocs_THEN_iocs_started_WHEN_stop_iocs_THEN_iocs_stopped(self
137154
number_to_run = 40
138155

139156
## disable for moment
140-
#iocs_to_test = self._prepare_ioc_list()
157+
# iocs_to_test = self._prepare_ioc_list()
141158
iocs_to_test = []
142159

143160
# Test handles Channel access exceptions, so set us to handle it to reduce prints.
144161
g.toggle.exceptions_raised(True)
145162
for chunk in self._chunk_iocs(iocs_to_test, number_to_run):
146163
start_time = time()
147164
failed_to_start, not_in_proc_serv = bulk_start_ioc(chunk)
148-
failed_to_stop = bulk_stop_ioc([ioc for ioc in chunk if ioc not in failed_to_start
149-
and ioc not in not_in_proc_serv])
165+
failed_to_stop = bulk_stop_ioc(
166+
[ioc for ioc in chunk if ioc not in failed_to_start and ioc not in not_in_proc_serv]
167+
)
150168
for ioc in failed_to_start + failed_to_stop:
151169
if not self._retry_in_recsim(ioc):
152170
error_iocs.append(ioc)
@@ -167,25 +185,36 @@ def _prepare_ioc_list(self):
167185
:return: The list of IOCs to test, sorted alphanumerically.
168186
"""
169187
iocs_to_test = []
170-
tree = ET.parse(os.path.join("C:\\", "Instrument", "Apps", "EPICS", "iocstartup", "config.xml"))
188+
tree = ET.parse(
189+
os.path.join("C:\\", "Instrument", "Apps", "EPICS", "iocstartup", "config.xml")
190+
)
171191
root = tree.getroot()
172192

173193
# IOCs are listed in the above XML file under two different schemas, we need both
174194
schemas = (
175195
"{http://epics.isis.rl.ac.uk/schema/ioc_config/1.0}",
176-
"{http://epics.isis.rl.ac.uk/schema/ioc_configs/1.0}"
196+
"{http://epics.isis.rl.ac.uk/schema/ioc_configs/1.0}",
177197
)
178198

179199
for schema in schemas:
180-
iocs_to_test.extend([ioc_config.attrib["name"] for ioc_config in root.iter(f"{schema}ioc_config")])
200+
iocs_to_test.extend(
201+
[ioc_config.attrib["name"] for ioc_config in root.iter(f"{schema}ioc_config")]
202+
)
181203

182204
# Check parsed IOCs are a sensible length check there's at least one known ioc in the list
183205
if not len(iocs_to_test) > 100:
184-
if not any(item in iocs_to_test for item in ["SIMPLE", "AMINT2L_01", "EUROTHRM_01", "INSTETC_01"]):
206+
if not any(
207+
item in iocs_to_test
208+
for item in ["SIMPLE", "AMINT2L_01", "EUROTHRM_01", "INSTETC_01"]
209+
):
185210
# Fairly long test so error out early if IOCs aren't in a sensible state
186211
raise ValueError("List of IOCs not in a sensible state. Have you run IOC startups?")
187212
# Check IOC 1 and IOC2, but not other IOCs as they should follow the same format as IOC 2.
188-
iocs_to_test = [ioc for ioc in iocs_to_test if self._skip_high_ioc_nums(ioc) and not self._ignore_ioc(ioc)]
213+
iocs_to_test = [
214+
ioc
215+
for ioc in iocs_to_test
216+
if self._skip_high_ioc_nums(ioc) and not self._ignore_ioc(ioc)
217+
]
189218
iocs_to_test.sort()
190219
return iocs_to_test
191220

@@ -216,7 +245,7 @@ def _chunk_iocs(ioc_list: List[str], chunk_size: int):
216245
:return: an iterator that gives the next chunk of the list.
217246
"""
218247
for i in range(0, len(ioc_list), chunk_size):
219-
yield ioc_list[i:i + chunk_size]
248+
yield ioc_list[i : i + chunk_size]
220249

221250
@staticmethod
222251
def _retry_in_recsim(ioc: str):

run_tests.py

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,42 +17,61 @@
1717
Run system tests for genie_python. Copies across needed configs before running the tests.
1818
"""
1919

20+
import argparse
2021
import os
22+
import shutil
2123
import sys
2224
import time
2325
import unittest
2426

25-
import shutil
2627
import xmlrunner
27-
import argparse
28-
from utilities import utilities
2928
from genie_python import genie as g
3029

30+
from utilities import utilities
3131

3232
SCRIPT_DIRECTORY = os.path.abspath(os.path.join(os.path.dirname(__file__)))
33-
DEFAULT_DIRECTORY = os.path.join(SCRIPT_DIRECTORY, 'test-reports')
34-
CONFIGS_DIRECTORY = os.path.join(SCRIPT_DIRECTORY, 'configs')
33+
DEFAULT_DIRECTORY = os.path.join(SCRIPT_DIRECTORY, "test-reports")
34+
CONFIGS_DIRECTORY = os.path.join(SCRIPT_DIRECTORY, "configs")
3535

3636
NUM_RETRY_DELETION = 5
3737

3838
# default icp config path
39-
default_configs_path = os.path.join("C:\\", "Instrument", "Settings", "config",
40-
os.environ.get("COMPUTERNAME", "NAME"), "configurations")
39+
default_configs_path = os.path.join(
40+
"C:\\",
41+
"Instrument",
42+
"Settings",
43+
"config",
44+
os.environ.get("COMPUTERNAME", "NAME"),
45+
"configurations",
46+
)
4147
# path to ICP CONFIG ROOT
4248
PATH_TO_ICPCONFIGROOT = os.environ.get("ICPCONFIGROOT", default_configs_path)
4349

44-
if __name__ == '__main__':
50+
if __name__ == "__main__":
4551
# get output directory from command line arguments
4652
parser = argparse.ArgumentParser()
47-
parser.add_argument('-o', '--output_dir', default=DEFAULT_DIRECTORY,
48-
help='The directory to save the test reports')
49-
parser.add_argument('-t', '--tests', default=None, nargs='+',
50-
help="""Dotted names of tests to run. These are of the form module.class.method.
53+
parser.add_argument(
54+
"-o",
55+
"--output_dir",
56+
default=DEFAULT_DIRECTORY,
57+
help="The directory to save the test reports",
58+
)
59+
parser.add_argument(
60+
"-t",
61+
"--tests",
62+
default=None,
63+
nargs="+",
64+
help="""Dotted names of tests to run. These are of the form module.class.method.
5165
Module just runs the tests in a module.
5266
Module.class runs the the test class in Module.
53-
Module.class.method runs a specific test.""")
54-
parser.add_argument('-f', '--failfast', action='store_true',
55-
help="""Determines if the rest of tests are skipped after the first failure""")
67+
Module.class.method runs a specific test.""",
68+
)
69+
parser.add_argument(
70+
"-f",
71+
"--failfast",
72+
action="store_true",
73+
help="""Determines if the rest of tests are skipped after the first failure""",
74+
)
5675

5776
arguments = parser.parse_args()
5877
xml_dir = arguments.output_dir
@@ -64,8 +83,11 @@
6483
else:
6584
test_suite = unittest.TestLoader().discover(SCRIPT_DIRECTORY, pattern="test_*.py")
6685

67-
config_dirs = [name for name in os.listdir(CONFIGS_DIRECTORY)
68-
if os.path.isdir(os.path.join(CONFIGS_DIRECTORY, name))]
86+
config_dirs = [
87+
name
88+
for name in os.listdir(CONFIGS_DIRECTORY)
89+
if os.path.isdir(os.path.join(CONFIGS_DIRECTORY, name))
90+
]
6991

7092
for config_dir in config_dirs:
7193
dest = os.path.join(PATH_TO_ICPCONFIGROOT, config_dir)
@@ -99,10 +121,15 @@
99121
utilities.load_config_if_not_already_loaded("empty_for_system_tests")
100122
utilities.wait_for_iocs_to_be_up(["ISISDAE_01"], 300)
101123

102-
103124
print("\n\n------ BEGINNING genie_python SYSTEM TESTS ------")
104125
ret_vals = list()
105-
ret_vals.append(xmlrunner.XMLTestRunner(output=xml_dir, stream=sys.stdout, failfast=failfast_switch, verbosity=3).run(test_suite).wasSuccessful())
126+
ret_vals.append(
127+
xmlrunner.XMLTestRunner(
128+
output=xml_dir, stream=sys.stdout, failfast=failfast_switch, verbosity=3
129+
)
130+
.run(test_suite)
131+
.wasSuccessful()
132+
)
106133
print("------ UNIT TESTS COMPLETE ------\n\n")
107134

108135
# Return failure exit code if a test failed

0 commit comments

Comments
 (0)