Skip to content

Commit c10e1e8

Browse files
Merge pull request #154 from rosswhitfield/make_some_debug_logging_more_useful
Add better debug info from ServiceResponseMessage
2 parents 4988459 + 79b9655 commit c10e1e8

File tree

8 files changed

+77
-28
lines changed

8 files changed

+77
-28
lines changed

.github/workflows/conda_env/environment_linux.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ dependencies:
66
- pytest-timeout
77
- psutil
88
- mpi4py
9-
- dask=2021.11.2
9+
- dask=2021.12.0
1010
- dakota

.github/workflows/conda_env/environment_macos.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ dependencies:
55
- pytest-cov
66
- pytest-timeout
77
- psutil
8-
- dask=2021.11.2
8+
- dask=2021.12.0

.github/workflows/conda_env/environment_static_analysis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ dependencies:
77
- pylint=2.11.1
88
- bandit=1.7.1
99
- codespell=2.1.0
10-
- dask=2021.11.2
10+
- dask=2021.12.0
1111
- pytest

ipsframework/ips.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -350,8 +350,7 @@ def _invoke_framework_comps(self, fwk_comps, method_name):
350350
self._dispatch_service_request(msg)
351351
continue
352352
elif msg.__class__.__name__ == 'MethodResultMessage':
353-
self.debug('Received Result for call %s' %
354-
(msg.call_id))
353+
self.debug('Received Result for call %s', msg.call_id)
355354
if msg.call_id not in outstanding_fwk_calls:
356355
self.task_manager.return_call(msg)
357356
else:

ipsframework/messages.py

+4
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ def __init__(self, sender_id, receiver_id, request_msg_id, status, *args):
7676
self.args = args
7777
self.message_id = self.get_message_id()
7878

79+
def __repr__(self):
80+
return (f'ServiceResponseMessage(sender_id={self.sender_id}, receiver_id={self.receiver_id}, request_msg_id={self.request_msg_id},'
81+
f'status={self.status}, args={self.args}, message_id={self.message_id})')
82+
7983

8084
class MethodInvokeMessage(Message):
8185
r"""

ipsframework/services.py

+15-21
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ def __initialize__(self, component_ref):
229229
elif pn_compconf.upper() == 'EXCLUSIVE':
230230
self.shared_nodes = False
231231
else:
232-
self.fwk.error("Bad 'NODE_ALLOCATION_MODE' value %s" % pn_compconf)
232+
self.fwk.error("Bad 'NODE_ALLOCATION_MODE' value %s", pn_compconf)
233233
raise Exception("Bad 'NODE_ALLOCATION_MODE' value %s")
234234
except Exception:
235235
self.shared_nodes = self.sim_conf['NODE_ALLOCATION_MODE'] == 'SHARED'
@@ -306,13 +306,12 @@ def _wait_msg_response(self, msg_id, block=True):
306306
:py:meth:`messages.ServiceResponseMessage` when available, otherwise
307307
``None``.
308308
"""
309-
if msg_id in list(self.finished_calls.keys()):
310-
response = self.finished_calls[msg_id]
311-
del self.finished_calls[msg_id]
312-
return response
313-
elif msg_id not in self.incomplete_calls:
314-
self.error('Invalid call ID : %s ', str(msg_id))
315-
raise Exception('Invalid message request ID argument')
309+
try:
310+
return self.finished_calls.pop(msg_id)
311+
except KeyError:
312+
if msg_id not in self.incomplete_calls:
313+
self.error('Invalid call ID : %s ', str(msg_id))
314+
raise Exception('Invalid message request ID argument')
316315

317316
keep_going = True
318317
while keep_going:
@@ -340,11 +339,7 @@ def _wait_msg_response(self, msg_id, block=True):
340339
if not block:
341340
keep_going = False
342341
# if this message corresponds to a finish invocation, return the response message
343-
if msg_id in list(self.finished_calls.keys()):
344-
response = self.finished_calls[msg_id]
345-
del self.finished_calls[msg_id]
346-
return response
347-
return None
342+
return self.finished_calls.pop(msg_id, None)
348343

349344
def _invoke_service(self, component_id, method_name, *args, **keywords):
350345
r"""
@@ -612,7 +607,7 @@ def launch_task(self, nproc, working_dir, binary, *args, **keywords):
612607
except KeyError:
613608
binary_fullpath = ipsutil.which(binary)
614609
if not binary_fullpath:
615-
self.error("Program %s is not in path or is not executable" % binary)
610+
self.error("Program %s is not in path or is not executable", binary)
616611
raise Exception("Program %s is not in path or is not executable" % binary)
617612
else:
618613
self.binary_fullpath_cache[binary] = binary_fullpath
@@ -987,18 +982,17 @@ def get_time_loop(self):
987982
"""
988983
if self.time_loop is not None:
989984
return self.time_loop
990-
sim_conf = self.sim_conf
991985
tlist = []
992-
time_conf = sim_conf['TIME_LOOP']
986+
time_conf = self.sim_conf['TIME_LOOP']
993987

994988
def safe(nums):
995989
return len(set(str(nums)).difference(set("1234567890-+/*.e "))) == 0
996990
# generate tlist in regular mode (start, finish, step)
997991
if time_conf['MODE'] == 'REGULAR':
998992
for entry in ['FINISH', 'START', 'NSTEP']:
999993
if not safe(time_conf[entry]):
1000-
self.error('Invalid TIME_LOOP value of %s = %s' % (entry, time_conf[entry]))
1001-
raise Exception('Invalid TIME_LOOP value of %s = %s' % (entry, time_conf[entry]))
994+
self.error('Invalid TIME_LOOP value of %s = %s', entry, time_conf[entry])
995+
raise ValueError('Invalid TIME_LOOP value of %s = %s' % (entry, time_conf[entry]))
1002996
finish = float(eval(time_conf['FINISH']))
1003997
start = float(eval(time_conf['START']))
1004998
nstep = int(eval(time_conf['NSTEP']))
@@ -1628,7 +1622,7 @@ def merge_current_state(self, partial_state_file, logfile=None, merge_binary=Non
16281622
bin_name = merge_binary if merge_binary else "update_state"
16291623
full_path_binary = ipsutil.which(bin_name)
16301624
if not full_path_binary:
1631-
self.error("Missing executable %s in PATH" % bin_name)
1625+
self.error("Missing executable %s in PATH", bin_name)
16321626
raise FileNotFoundError("Missing executable file %s in PATH" % bin_name)
16331627
try:
16341628
msg_id = self._invoke_service(self.fwk.component_id,
@@ -1827,7 +1821,7 @@ def create_sub_workflow(self, sub_name, config_file, override=None, input_dir=No
18271821
sub_conf_new = ConfigObj(infile=config_file, interpolation='template', file_error=True)
18281822
sub_conf_old = ConfigObj(infile=config_file, interpolation='template', file_error=True)
18291823
except Exception:
1830-
self.exception("Error accessing sub-workflow config file %s" % config_file)
1824+
self.exception("Error accessing sub-workflow config file %s", config_file)
18311825
raise
18321826
# Update undefined sub workflow configuration entries using top level configuration
18331827
# only applicable to non-component entries (ones with non-dictionary values)
@@ -1983,7 +1977,7 @@ def add_task(self, task_name, nproc, working_dir, binary, *args, **keywords):
19831977
except KeyError:
19841978
binary_fullpath = ipsutil.which(binary)
19851979
if not binary_fullpath:
1986-
self.services.error("Program %s is not in path or is not executable" % binary)
1980+
self.services.error("Program %s is not in path or is not executable", binary)
19871981
raise Exception("Program %s is not in path or is not executable" % binary)
19881982
else:
19891983
self.services.binary_fullpath_cache[binary] = binary_fullpath

tests/dakota/test_dakota.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def copy_config_and_replace(infile, outfile, tmpdir):
2121

2222
@pytest.mark.skipif(shutil.which('dakota') is None,
2323
reason="Requires dakota to run this test")
24-
@pytest.mark.timeout(120)
24+
@pytest.mark.timeout(200)
2525
def test_dakota(tmpdir):
2626
data_dir = os.path.dirname(__file__)
2727
copy_config_and_replace(os.path.join(data_dir, "dakota_test_Gaussian.ips"), tmpdir.join("dakota_test_Gaussian.ips"), tmpdir)

tests/new/test_timeloop_checkpoint.py

+53-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
from ipsframework import Framework
1+
from unittest.mock import MagicMock
2+
import pytest
3+
from ipsframework import Framework, ServicesProxy
24

35

46
def write_basic_config_and_platform_files(tmpdir, restart=False):
@@ -275,3 +277,53 @@ def test_timeloop_checkpoint_restart(tmpdir):
275277
assert results_dir.join('TIMELOOP_COMP__timeloop_comp_8').join(f'w1_2_{time}.dat').exists()
276278
assert results_dir.join('TIMELOOP_COMP2__timeloop_comp_9').join(f'w2_1_{time}.dat').exists()
277279
assert results_dir.join('TIMELOOP_COMP2__timeloop_comp_9').join(f'w2_2_{time}.dat').exists()
280+
281+
282+
def test_TIME_LOOP():
283+
sim_conf = {'TIME_LOOP': {'MODE': 'REGULAR',
284+
'START': '0',
285+
'FINISH': '10',
286+
'NSTEP': '10'}}
287+
servicesProxy = ServicesProxy(None, None, None, sim_conf, None)
288+
tl = servicesProxy.get_time_loop()
289+
assert tl == list(range(11))
290+
291+
sim_conf = {'TIME_LOOP': {'MODE': 'REGULAR',
292+
'START': '0 + 20 / 2',
293+
'FINISH': '13 - 1',
294+
'NSTEP': '2'}}
295+
servicesProxy = ServicesProxy(None, None, None, sim_conf, None)
296+
tl = servicesProxy.get_time_loop()
297+
assert tl == [10, 11, 12]
298+
299+
sim_conf = {'TIME_LOOP': {'MODE': 'REGULAR',
300+
'START': '10 * 2',
301+
'FINISH': '10 ** 2',
302+
'NSTEP': '2'}}
303+
servicesProxy = ServicesProxy(None, None, None, sim_conf, None)
304+
tl = servicesProxy.get_time_loop()
305+
assert tl == [20, 60, 100]
306+
307+
sim_conf = {'TIME_LOOP': {'MODE': 'REGULAR',
308+
'START': '1e2',
309+
'FINISH': '5e1',
310+
'NSTEP': '2'}}
311+
servicesProxy = ServicesProxy(None, None, None, sim_conf, None)
312+
tl = servicesProxy.get_time_loop()
313+
assert tl == [100, 75, 50]
314+
315+
sim_conf = {'TIME_LOOP': {'MODE': 'EXPLICIT',
316+
'VALUES': '7 13 -42 1000'}}
317+
servicesProxy = ServicesProxy(None, None, None, sim_conf, None)
318+
tl = servicesProxy.get_time_loop()
319+
assert tl == [7, 13, -42, 1000]
320+
321+
sim_conf = {'TIME_LOOP': {'MODE': 'REGULAR',
322+
'START': '1p2',
323+
'FINISH': '10',
324+
'NSTEP': '2'}}
325+
servicesProxy = ServicesProxy(None, None, None, sim_conf, None)
326+
servicesProxy.error = MagicMock(name='error')
327+
with pytest.raises(ValueError) as excinfo:
328+
servicesProxy.get_time_loop()
329+
assert str(excinfo.value) == "Invalid TIME_LOOP value of START = 1p2"

0 commit comments

Comments
 (0)