Skip to content

Commit

Permalink
Changes for fixing testing of ast.parse
Browse files Browse the repository at this point in the history
ExecutionEngine
  removed double import of ast
  added ast_parse_eval function to handle ast.parse with mode eval
  change usage of ast.parse to ast_parse_eval
Unit tests for ExecutionEngine
  updated current parse_config tests to mock new function call
  added test for ast_parse_eval
  NOTE: this test has the same issue, but should never need to change
  • Loading branch information
asgibson committed Sep 15, 2023
1 parent 0500300 commit 7e40cdf
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 17 deletions.
9 changes: 5 additions & 4 deletions onair/src/run_scripts/execution_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
import ast
import shutil
from distutils.dir_util import copy_tree
from time import gmtime, strftime
import ast
from time import gmtime, strftime

from ...data_handling.time_synchronizer import TimeSynchronizer
from ..run_scripts.sim import Simulator
Expand Down Expand Up @@ -83,7 +82,7 @@ def parse_configs(self, config_filepath):

## Parse Required Data: Plugin name to path dict
config_plugin_list = config['DEFAULT']['PluginList']
ast_plugin_list = ast.parse(config_plugin_list, mode='eval')
ast_plugin_list = self.ast_parse_eval(config_plugin_list)
if isinstance(ast_plugin_list.body, ast.Dict) and len(ast_plugin_list.body.keys) > 0:
temp_plugin_list = ast.literal_eval(config_plugin_list)
else:
Expand Down Expand Up @@ -165,10 +164,12 @@ def save_results(self, save_name):
os.mkdir(save_path)
copy_tree(os.environ['ONAIR_TMP_SAVE_PATH'], save_path)

""" Getters and setters """
def set_run_param(self, name, val):
setattr(self, name, val)

def ast_parse_eval(self, config_list):
return ast.parse(config_list, mode='eval')




Expand Down
42 changes: 29 additions & 13 deletions test/onair/src/run_scripts/test_execution_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def test_ExecutionEngine_parse_configs_raises_ValueError_when_PluginList_from_co

mocker.patch(execution_engine.__name__ + '.configparser.ConfigParser', return_value=fake_config)
mocker.patch.object(fake_config, 'read', return_value=fake_config_read_result)
mocker.patch(execution_engine.__name__ + '.ast.parse', return_value=fake_plugin_list)
mocker.patch.object(cut, 'ast_parse_eval', return_value=fake_plugin_list)
mocker.patch(execution_engine.__name__ + '.isinstance', return_value=False)

# Act
Expand All @@ -183,9 +183,8 @@ def test_ExecutionEngine_parse_configs_raises_ValueError_when_PluginList_from_co

# Assert
assert e_info.match(f"{fake_plugin_list} is an invalid PluginList. It must be a dict of at least 1 key/value pair.")
assert execution_engine.ast.parse.call_count == 1
assert execution_engine.ast.parse.call_args_list[0].args == (fake_plugin_list,)
assert execution_engine.ast.parse.call_args_list[0].kwargs == {'mode':'eval'}
assert cut.ast_parse_eval.call_count == 1
assert cut.ast_parse_eval.call_args_list[0].args == (fake_plugin_list,)
assert execution_engine.isinstance.call_count == 1
assert execution_engine.isinstance.call_args_list[0].args == (fake_plugin_list.body, execution_engine.ast.Dict, )

Expand All @@ -209,7 +208,7 @@ def test_ExecutionEngine_parse_configs_raises_ValueError_when_PluginList_from_co

mocker.patch(execution_engine.__name__ + '.configparser.ConfigParser', return_value=fake_config)
mocker.patch.object(fake_config, 'read', return_value=fake_config_read_result)
mocker.patch(execution_engine.__name__ + '.ast.parse', return_value=fake_plugin_list)
mocker.patch.object(cut, 'ast_parse_eval', return_value=fake_plugin_list)
mocker.patch(execution_engine.__name__ + '.isinstance', return_value=True)

# Act
Expand All @@ -218,9 +217,8 @@ def test_ExecutionEngine_parse_configs_raises_ValueError_when_PluginList_from_co

# Assert
assert e_info.match(f"{fake_plugin_list} is an invalid PluginList. It must be a dict of at least 1 key/value pair.")
assert execution_engine.ast.parse.call_count == 1
assert execution_engine.ast.parse.call_args_list[0].args == (fake_plugin_list,)
assert execution_engine.ast.parse.call_args_list[0].kwargs == {'mode':'eval'}
assert cut.ast_parse_eval.call_count == 1
assert cut.ast_parse_eval.call_args_list[0].args == (fake_plugin_list,)
assert execution_engine.isinstance.call_count == 1
assert execution_engine.isinstance.call_args_list[0].args == (fake_plugin_list.body, execution_engine.ast.Dict, )

Expand All @@ -247,7 +245,7 @@ def test_ExecutionEngine_parse_configs_raises_FileNotFoundError_when_given_plugi

mocker.patch(execution_engine.__name__ + '.configparser.ConfigParser', return_value=fake_config)
mocker.patch.object(fake_config, 'read', return_value=fake_config_read_result)
mocker.patch(execution_engine.__name__ + '.ast.parse', return_value=fake_plugin_list)
mocker.patch.object(cut, 'ast_parse_eval', return_value=fake_plugin_list)
mocker.patch(execution_engine.__name__ + '.isinstance', return_value=True)
mocker.patch(execution_engine.__name__ + '.ast.literal_eval', return_value=fake_temp_plugin_list)
mocker.patch.object(fake_temp_plugin_list, 'values', return_value=fake_temp_iter)
Expand All @@ -258,9 +256,8 @@ def test_ExecutionEngine_parse_configs_raises_FileNotFoundError_when_given_plugi

# Assert
assert e_info.match(f"In config file '{arg_config_filepath}', path '{fake_plugin_name}' does not exist or is formatted incorrectly.")
assert execution_engine.ast.parse.call_count == 1
assert execution_engine.ast.parse.call_args_list[0].args == (fake_plugin_list,)
assert execution_engine.ast.parse.call_args_list[0].kwargs == {'mode':'eval'}
assert cut.ast_parse_eval.call_count == 1
assert cut.ast_parse_eval.call_args_list[0].args == (fake_plugin_list,)
assert execution_engine.isinstance.call_count == 1
assert execution_engine.isinstance.call_args_list[0].args == (fake_plugin_list.body, execution_engine.ast.Dict, )

Expand Down Expand Up @@ -311,7 +308,7 @@ def test_ExecutionEngine_parse_configs_sets_all_items_without_error(mocker):
mocker.patch(execution_engine.__name__ + '.configparser.ConfigParser', return_value=fake_config)
mocker.patch.object(fake_config, 'read', return_value=fake_config_read_result)
mocker.patch.object(fake_run_flags, 'getboolean', side_effect=[fake_IO_flags, fake_Dev_flags, fake_SBN_flags, fake_Viz_flags])
mocker.patch(execution_engine.__name__ + '.ast.parse', return_value=fake_plugin_list)
mocker.patch.object(cut, 'ast_parse_eval', return_value=fake_plugin_list)
mocker.patch(execution_engine.__name__ + '.isinstance', return_value=True)
mocker.patch(execution_engine.__name__ + '.ast.literal_eval', return_value=fake_temp_plugin_list)
mocker.patch.object(fake_temp_plugin_list, 'values', return_value=fake_temp_iter)
Expand Down Expand Up @@ -789,3 +786,22 @@ def test_ExecutionEngine_set_run_param_passes_given_arguments_to_setattr(mocker)
# Assert
assert execution_engine.setattr.call_count == 1
assert execution_engine.setattr.call_args_list[0].args == (cut, arg_name, arg_val, )

# ast_parse_eval tests
def test_ExecutionEngine_ast_parse_eval_returns_call_to_ast_parse_with_mode_eval(mocker):
# Arrange
arg_config_list = MagicMock()
expected_result = MagicMock()
cut = ExecutionEngine.__new__(ExecutionEngine)

mocker.patch(execution_engine.__name__ + ".ast.parse", return_value=expected_result)

# Act
result = cut.ast_parse_eval(arg_config_list)

# Assert
assert result == expected_result
assert execution_engine.ast.parse.call_count == 1
assert execution_engine.ast.parse.call_args_list[0].args == (arg_config_list, )
assert execution_engine.ast.parse.call_args_list[0].kwargs == {'mode':'eval'}

0 comments on commit 7e40cdf

Please sign in to comment.