From 693b4a105f7fa3fc605b507ced0be130e9b0bb38 Mon Sep 17 00:00:00 2001 From: Thomas Latham Date: Mon, 28 Oct 2024 14:04:34 +0000 Subject: [PATCH] Change RMUTL to use ZOAU shell commands for compatibility --- galaxy.yml | 2 +- plugins/module_utils/_data_set_utils.py | 82 +++++++- plugins/module_utils/_global_catalog.py | 87 ++++---- .../cics_cmci/playbooks/cmci_bas_install.yml | 2 +- tests/unit/helpers/data_set_helper.py | 65 ++++++ .../unit/module_utils/test_global_catalog.py | 193 ++++++++---------- tests/unit/modules/test_global_catalog.py | 45 ++-- 7 files changed, 317 insertions(+), 159 deletions(-) diff --git a/galaxy.yml b/galaxy.yml index 7efd517f..0611c132 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -8,7 +8,7 @@ namespace: ibm name: ibm_zos_cics # The collection version -version: 2.1.0 +version: 2.2.0 # Collection README file readme: README.md diff --git a/plugins/module_utils/_data_set_utils.py b/plugins/module_utils/_data_set_utils.py index 3b203d8a..057f378e 100644 --- a/plugins/module_utils/_data_set_utils.py +++ b/plugins/module_utils/_data_set_utils.py @@ -13,7 +13,8 @@ from ansible_collections.ibm.ibm_zos_core.plugins.module_utils.ansible_module import AnsibleModuleHelper from ansible_collections.ibm.ibm_zos_cics.plugins.module_utils._response import _execution, MVSExecutionException from ansible_collections.ibm.ibm_zos_core.plugins.module_utils.zos_mvs_raw import MVSCmd -from ansible_collections.ibm.ibm_zos_core.plugins.module_utils.dd_statement import DDStatement, StdoutDefinition, DatasetDefinition, StdinDefinition +from ansible_collections.ibm.ibm_zos_core.plugins.module_utils.dd_statement import DDStatement, StdoutDefinition, StdinDefinition +from ansible_collections.ibm.ibm_zos_core.plugins.module_utils.job import job_output MVS_CMD_RETRY_ATTEMPTS = 10 @@ -273,6 +274,85 @@ def _execute_command(command): module = AnsibleModuleHelper(argument_spec={}) return module.run_command(command) +def _submit_jcl(jcl_uss_path, job_name): + executions =[] + command = "jsub -f '{0}'".format(jcl_uss_path) + + rc, stdout,stderr = _execute_command(command) + executions.append( + _execution( + name="Submit jcl job {0} for {1}".format(jcl_uss_path, job_name), + rc=rc, + stdout=stdout, + stderr=stderr)) + if rc != 0: + raise MVSExecutionException( + "RC {0} when submitting jcl from {1}".format( + rc, jcl_uss_path), executions) + return executions + + +def _get_job_output(job_id, job_name): + executions = [] + + try: + jobs = job_output(job_id=job_id, job_name=job_name) + + #There should only be one job found for the JCL submitted + if (len(jobs) != 1): + raise MVSExecutionException( + "Query for job status for {0} with job id {1} returned more than one result. Jobs returned: {2}".format( + job_name, + job_id, + jobs), executions) + + executions.append( + _execution( + name="Get job output for {0}".format(job_id), + rc=jobs[0].get("ret_code").get("code"), + stdout=jobs[0].get("ret_code").get("msg", ""), + stderr=jobs[0].get("ret_code").get("msg_txt", ""))) + except Exception as e: + raise MVSExecutionException( + "Query for {0} job submitted under Job ID {1} failed. An exception occured: {2}".format( + job_name, + job_id, + e), executions) + + try: + # job output fails to get the ddname content in its response. Call direct into zoau to do it + for i in range(len(jobs[0].get("ddnames"))): + dd_executions, job_stdout = _get_job_dd(job_id, jobs[0]["ddnames"][i]["ddname"]) + + #Put the content back in the job response object + jobs[0]["ddnames"][i]["content"] = job_stdout + executions.append(dd_executions) + + return jobs[0], executions + except Exception as e: + raise MVSExecutionException( + "Could not get all job DDs for {0}. An exception occured: {1}".format( + job_name, + e), executions) + + +def _get_job_dd(job_id, dd_name): + executions = [] + command = "pjdd {0} {1}".format(job_id, dd_name) + + rc, stdout, stderr = _execute_command(command) + executions.append( + _execution( + name="Get job dd {0} output for {1}".format(dd_name, job_id), + rc=rc, + stdout=stdout, + stderr=stderr)) + if rc != 0: + raise MVSExecutionException( + "RC {0} when getting job output for {1} from {2}".format( + rc, dd_name, job_id), executions) + return executions, stdout + def _read_data_set_content(data_set_name): executions = [] diff --git a/plugins/module_utils/_global_catalog.py b/plugins/module_utils/_global_catalog.py index afd3a8e0..75466fc3 100644 --- a/plugins/module_utils/_global_catalog.py +++ b/plugins/module_utils/_global_catalog.py @@ -9,11 +9,10 @@ __metaclass__ = type -from ansible_collections.ibm.ibm_zos_core.plugins.module_utils.zos_mvs_raw import MVSCmd, MVSCmdResponse -from ansible_collections.ibm.ibm_zos_core.plugins.module_utils.dd_statement import StdoutDefinition, DatasetDefinition, DDStatement, InputDefinition from ansible_collections.ibm.ibm_zos_cics.plugins.module_utils._response import MVSExecutionException, _execution -from ansible_collections.ibm.ibm_zos_cics.plugins.module_utils._data_set_utils import MVS_CMD_RETRY_ATTEMPTS +from ansible_collections.ibm.ibm_zos_cics.plugins.module_utils._data_set_utils import MVS_CMD_RETRY_ATTEMPTS, _submit_jcl, _get_job_output import tempfile +from time import sleep def _get_value_from_line(line): # type: (list[str]) -> str | None val = None @@ -26,18 +25,6 @@ def _get_filtered_list(elements, target): # type: (list[str],str) -> list[str] return list(filter(lambda x: target in x, elements)) -def _get_rmutl_dds( - location, - sdfhload, - cmd): # type: (str, str, str) -> list[DDStatement] - return [ - DDStatement('steplib', DatasetDefinition(sdfhload)), - DDStatement('dfhgcd', DatasetDefinition(location)), - DDStatement('sysin', InputDefinition(content=cmd)), - DDStatement('sysprint', StdoutDefinition()), - ] - - def _get_reason_code(stdout_lines_arr): # type: (list[str]) -> str | None if len(stdout_lines_arr) == 0: return None @@ -74,16 +61,27 @@ def _create_dfhrmutl_jcl(location, sdfhload, cmd=""): _validate_line_length(steplib_line, sdfhload) _validate_line_length(dfhgcd_line, location) - jcl = f''' -//RMUTL1 JOB + jcl = "" + if (cmd ==""): + jcl = f''' +//DFHRMUTL JOB +//RMUTL EXEC PGM=DFHRMUTL,REGION=1M +{steplib_line} +//SYSPRINT DD SYSOUT=* +{dfhgcd_line} +//SYSIN DD * +/* +''' + else: + jcl = f''' +//DFHRMUTL JOB //RMUTL EXEC PGM=DFHRMUTL,REGION=1M {steplib_line} -//SYSPRINT DD SYSOUT=A +//SYSPRINT DD SYSOUT=* {dfhgcd_line} //SYSIN DD * {cmd} /* -// ''' # Create a temporary file @@ -127,22 +125,35 @@ def _run_dfhrmutl( executions = [] for x in range(MVS_CMD_RETRY_ATTEMPTS): - dfhrmutl_response = _execute_dfhrmutl(location, sdfhload, cmd) + dfhrmutl_response, jcl_executions = _execute_dfhrmutl(qualified_file_path) + dfhrmutl_rc = dfhrmutl_response.get("ret_code").get("code") + + allContent = [] + for ddname in dfhrmutl_response.get("ddnames"): + allContent += ddname.get("content") + stdout_raw = "".join(allContent) + + executions.append(jcl_executions) executions.append( _execution( name="DFHRMUTL - {0} - Run {1}".format( "Get current catalog" if cmd == "" else "Updating autostart override", x + 1), - rc=dfhrmutl_response.rc, - stdout=dfhrmutl_response.stdout, - stderr=dfhrmutl_response.stderr)) + rc=dfhrmutl_rc, + stdout=stdout_raw, + stderr=dfhrmutl_response.get("ret_code").get("msg_txt", ""))) + + if dfhrmutl_rc not in (0, 16): + raise MVSExecutionException( + "DFHRMUTL failed with RC {0}".format( + dfhrmutl_rc), executions) - if dfhrmutl_response.rc == 0: + if dfhrmutl_rc == 0: break - if dfhrmutl_response.rc == 16: + if dfhrmutl_rc == 16: formatted_stdout_lines = [ "{0}".format(element.replace(" ", "").upper()) - for element in dfhrmutl_response.stdout.split("\n") + for element in stdout_raw.split("\n") ] stdout_with_rc = list(filter(lambda x: "REASON:X" in x, formatted_stdout_lines)) @@ -157,23 +168,23 @@ def _run_dfhrmutl( executions, ) - else: - raise MVSExecutionException( - "DFHRMUTL failed with RC {0}".format( - dfhrmutl_response.rc), executions) - if cmd != "": return executions - return executions, _get_catalog_records(dfhrmutl_response.stdout) + return executions, _get_catalog_records(stdout_raw) + + +def _execute_dfhrmutl(rmutl_jcl_path, job_name="DFHRMUTL"): + executions = _submit_jcl(rmutl_jcl_path, job_name) + job_id = executions[0].get("stdout").strip() + + #Give RMUTL a second to run + sleep(1) + job, job_executions = _get_job_output(job_id, job_name) + executions.append(job_executions) -def _execute_dfhrmutl(location, sdfhload, cmd=""): # type: (str, str, str) -> MVSCmdResponse - return MVSCmd.execute( - pgm="DFHRMUTL", - dds=_get_rmutl_dds(location=location, sdfhload=sdfhload, cmd=cmd), - verbose=True, - debug=False) + return job, executions def _get_idcams_cmd_gcd(dataset): # type: (dict) -> dict diff --git a/tests/integration/targets/cics_cmci/playbooks/cmci_bas_install.yml b/tests/integration/targets/cics_cmci/playbooks/cmci_bas_install.yml index 32d96e5d..90ffacff 100644 --- a/tests/integration/targets/cics_cmci/playbooks/cmci_bas_install.yml +++ b/tests/integration/targets/cics_cmci/playbooks/cmci_bas_install.yml @@ -496,7 +496,7 @@ - result.cpsm_response == 'OK' - result.record_count == 1 - result.records[0].group == target_scope_special_char - - result.records[0].changeusrid == cmci_user + - result.records[0].changeusrid == cmci_user | upper - name: Delete System group with special chars delegate_to: localhost diff --git a/tests/unit/helpers/data_set_helper.py b/tests/unit/helpers/data_set_helper.py index ce1cb612..2b310e40 100644 --- a/tests/unit/helpers/data_set_helper.py +++ b/tests/unit/helpers/data_set_helper.py @@ -418,6 +418,71 @@ def CSDUP_add_group_stdout(data_set_name): DFH5109 I END OF DFHCSDUP UTILITY JOB. HIGHEST RETURN CODE WAS: 0 """.format(data_set_name) +def get_sample_job_output(content="", rc=0, err="CC"): + return { + "class": "", + "content_type": "", + "ddnames": [ + { + "byte_count": 0, + "content": [ + "{0}".format(content) + ], + "ddname": "JESMSGLG", + "id": "?", + "proctep": "", + "record_count": "", + "stepname": "JES2" + }, + { + "byte_count": 0, + "content": [ + "" + ], + "ddname": "JESJCL", + "id": "?", + "proctep": "", + "record_count": "", + "stepname": "JES2" + }, + { + "byte_count": 0, + "content": [ + "" + ], + "ddname": "JESYSMSG", + "id": "?", + "proctep": "", + "record_count": "", + "stepname": "JES2" + }, + { + "byte_count": 0, + "content": [ + "" + ], + "ddname": "SYSPRINT", + "id": "?", + "proctep": "", + "record_count": "", + "stepname": "RMUTL" + } + ], + "duration": 0, + "job_id": "JOB12345", + "job_name": "DFHRMUTL", + "owner": "IBMUSER", + "ret_code": { + "code": rc, + "msg": "CC", + "msg_code": "0000", + "msg_txt": err, + "steps": [] + }, + "subsystem": "", + "system": "" + } + def read_data_set_content_run_name(data_set_name): return "Read data set {0}".format(data_set_name) diff --git a/tests/unit/module_utils/test_global_catalog.py b/tests/unit/module_utils/test_global_catalog.py index 2f706c2c..d482d3d1 100644 --- a/tests/unit/module_utils/test_global_catalog.py +++ b/tests/unit/module_utils/test_global_catalog.py @@ -10,7 +10,8 @@ PYTHON_LANGUAGE_FEATURES_MESSAGE, RMUTL_get_run_name, RMUTL_stdout, - RMUTL_update_run_name + RMUTL_update_run_name, + get_sample_job_output as JOB_OUTPUT ) __metaclass__ = type from ansible_collections.ibm.ibm_zos_cics.plugins.module_utils import _data_set_utils as data_set_utils @@ -204,17 +205,21 @@ def test_global_catalog_get_records_autocold_emergency(): def test_global_catalog_run_rmutl_with_cmd(): executions = [ + [], _execution( name=RMUTL_update_run_name(1), rc=0, stdout="", - stderr="", + stderr="CC" ) ] - global_catalog.MVSCmd.execute = MagicMock( - return_value=MVSCmdResponse(rc=0, stdout="", stderr="") - ) - global_catalog._get_rmutl_dds = MagicMock(return_value=[]) + + global_catalog._execute_dfhrmutl = MagicMock( + return_value=( + JOB_OUTPUT(), + [] + )) + result = global_catalog._run_dfhrmutl( location="DATA.SET", sdfhload="SDFH.LOAD", cmd="HI" ) @@ -224,26 +229,26 @@ def test_global_catalog_run_rmutl_with_cmd(): def test_global_catalog_run_rmutl_with_cmd_and_failure(): executions = [ + [], _execution( name=RMUTL_update_run_name(1), rc=16, stdout=" ABC \n REASON: X'A8'", - stderr="", + stderr="CC", ), + [], _execution( name=RMUTL_update_run_name(2), rc=0, stdout="", - stderr="", + stderr="CC", ), ] - global_catalog.MVSCmd.execute = MagicMock( + global_catalog._execute_dfhrmutl = MagicMock( side_effect=[ - MVSCmdResponse(rc=16, stdout=" ABC \n REASON: X'A8'", stderr=""), - MVSCmdResponse(rc=0, stdout="", stderr=""), - ] - ) - global_catalog._get_rmutl_dds = MagicMock(return_value=[]) + (JOB_OUTPUT(" ABC \n REASON: X'A8'", 16), []), + (JOB_OUTPUT(), []) + ]) result = global_catalog._run_dfhrmutl( location="DATA.SET", sdfhload="SDFH.LOAD", cmd="HI" ) @@ -252,23 +257,24 @@ def test_global_catalog_run_rmutl_with_cmd_and_failure(): def test_global_catalog_run_rmutl_no_cmd(): - rmutl_response = MVSCmdResponse( - rc=0, - stdout=RMUTL_stdout("AUTOASIS", "EMERGENCY"), - stderr="", - ) + rmutl_stdout = RMUTL_stdout("AUTOASIS", "EMERGENCY") + + global_catalog._execute_dfhrmutl = MagicMock( + return_value=( + JOB_OUTPUT(rmutl_stdout), + [] + )) expected_executions = [ + [], _execution( name=RMUTL_get_run_name(1), - rc=rmutl_response.rc, - stdout=rmutl_response.stdout, - stderr=rmutl_response.stderr, + rc=0, + stdout=rmutl_stdout, + stderr="CC", ) ] expected_details = ("AUTOASIS", "EMERGENCY") - global_catalog.MVSCmd.execute = MagicMock(return_value=rmutl_response) - global_catalog._get_rmutl_dds = MagicMock(return_value=[]) actual_executions, actual_details = global_catalog._run_dfhrmutl( location="DATA.SET", sdfhload="SDFH.LOAD" ) @@ -278,34 +284,31 @@ def test_global_catalog_run_rmutl_no_cmd(): def test_global_catalog_run_rmutl_no_cmd_with_failure(): - rmutl_response = MVSCmdResponse( - rc=0, - stdout=RMUTL_stdout("AUTOASIS", "EMERGENCY"), - stderr="", - ) + rmutl_stdout = RMUTL_stdout("AUTOASIS", "EMERGENCY") expected_executions = [ + [], _execution( name=RMUTL_get_run_name(1), rc=16, stdout=" ABC \n REASON: X'A8'", - stderr="", + stderr="CC", ), + [], _execution( name=RMUTL_get_run_name(2), - rc=rmutl_response.rc, - stdout=rmutl_response.stdout, - stderr=rmutl_response.stderr, + rc=0, + stdout=rmutl_stdout, + stderr="CC", ), ] expected_details = ("AUTOASIS", "EMERGENCY") - global_catalog.MVSCmd.execute = MagicMock( + global_catalog._execute_dfhrmutl = MagicMock( side_effect=[ - MVSCmdResponse(rc=16, stdout=" ABC \n REASON: X'A8'", stderr=""), - rmutl_response, + (JOB_OUTPUT(" ABC \n REASON: X'A8'", 16), []), + (JOB_OUTPUT(rmutl_stdout), []) ] ) - global_catalog._get_rmutl_dds = MagicMock(return_value=[]) actual_executions, actual_details = global_catalog._run_dfhrmutl( location="DATA.SET", sdfhload="SDFH.LOAD" ) @@ -315,59 +318,61 @@ def test_global_catalog_run_rmutl_no_cmd_with_failure(): def test_global_catalog_run_rmutl_no_cmd_many_failures(): - rmutl_response = MVSCmdResponse( - rc=0, - stdout=RMUTL_stdout("AUTOINIT", "UNKNOWN"), - stderr="", - ) + rmutl_stdout = RMUTL_stdout("AUTOINIT", "UNKNOWN") expected_executions = [ + [], _execution( name=RMUTL_get_run_name(1), rc=16, stdout=" ABC \n REASON: X'A8'", - stderr="", + stderr="CC", ), + [], _execution( name=RMUTL_get_run_name(2), rc=16, stdout="\n\n\n REASON: X'A8'", - stderr="", + stderr="CC", ), + [], _execution( name=RMUTL_get_run_name(3), rc=16, stdout="REASON:X'A8'", - stderr="", + stderr="CC", ), + [], _execution( name=RMUTL_get_run_name(4), rc=16, stdout="\n REASON:X'A8'", - stderr="", + stderr="CC", ), + [], _execution( name=RMUTL_get_run_name(5), rc=16, stdout=" ABC \n REASON: X 'A8'", - stderr="", + stderr="CC", ), + [], _execution( name=RMUTL_get_run_name(6), - rc=rmutl_response.rc, - stdout=rmutl_response.stdout, - stderr=rmutl_response.stderr, + rc=0, + stdout=rmutl_stdout, + stderr="CC", ), ] expected_details = ("AUTOINIT", "UNKNOWN") - global_catalog.MVSCmd.execute = MagicMock( + global_catalog._execute_dfhrmutl = MagicMock( side_effect=[ - MVSCmdResponse(rc=16, stdout=" ABC \n REASON: X'A8'", stderr=""), - MVSCmdResponse(rc=16, stdout="\n\n\n REASON: X'A8'", stderr=""), - MVSCmdResponse(rc=16, stdout="REASON:X'A8'", stderr=""), - MVSCmdResponse(rc=16, stdout="\n REASON:X'A8'", stderr=""), - MVSCmdResponse(rc=16, stdout=" ABC \n REASON: X 'A8'", stderr=""), - rmutl_response, + (JOB_OUTPUT(" ABC \n REASON: X'A8'", 16), []), + (JOB_OUTPUT("\n\n\n REASON: X'A8'", 16), []), + (JOB_OUTPUT("REASON:X'A8'", 16), []), + (JOB_OUTPUT("\n REASON:X'A8'", 16), []), + (JOB_OUTPUT(" ABC \n REASON: X 'A8'", 16), []), + (JOB_OUTPUT(rmutl_stdout), []) ] ) global_catalog._get_rmutl_dds = MagicMock(return_value=[]) @@ -380,107 +385,83 @@ def test_global_catalog_run_rmutl_no_cmd_many_failures(): def test_global_catalog_run_rmutl_rc16_error(): - global_catalog.MVSCmd.execute = MagicMock( - return_value=MVSCmdResponse(rc=16, stdout=" ABC \n REASON: X'12'", stderr="") + global_catalog._execute_dfhrmutl = MagicMock( + return_value=(JOB_OUTPUT(" ABC \n REASON: X'12'", 16), []) ) - global_catalog._get_rmutl_dds = MagicMock(return_value=[]) expected_executions = [ + [], _execution( name=RMUTL_update_run_name(1), rc=16, stdout=" ABC \n REASON: X'12'", - stderr="" + stderr="CC" ) ] - error_raised = False - try: + with pytest.raises(MVSExecutionException) as e: global_catalog._run_dfhrmutl( location="DATA.SET", sdfhload="SDFH.LOAD", cmd="HI" ) - except MVSExecutionException as e: - error_raised = True assert e.message == "DFHRMUTL failed with RC 16 - REASON:X'12'" assert e.executions == expected_executions - assert error_raised is True - def test_global_catalog_run_rmutl_many_rc16_error(): - global_catalog.MVSCmd.execute = MagicMock( + global_catalog._execute_dfhrmutl = MagicMock( side_effect=[ - MVSCmdResponse(rc=16, stdout=" ABC \n REASON: X'A8'", stderr=""), - MVSCmdResponse(rc=16, stdout="\n\n\n REASON: X'A8'", stderr=""), - MVSCmdResponse(rc=16, stdout="REASON:X'B2'", stderr=""), + (JOB_OUTPUT(" ABC \n REASON: X'A8'", 16), []), + (JOB_OUTPUT("\n\n\n REASON: X'A8'", 16), []), + (JOB_OUTPUT("REASON:X'B2'", 16), []) ] ) - global_catalog._get_rmutl_dds = MagicMock(return_value=[]) expected_executions = [ - _execution(name=RMUTL_update_run_name(1), rc=16, stdout=" ABC \n REASON: X'A8'", stderr=""), - _execution(name=RMUTL_update_run_name(2), rc=16, stdout="\n\n\n REASON: X'A8'", stderr=""), - _execution(name=RMUTL_update_run_name(3), rc=16, stdout="REASON:X'B2'", stderr=""), + [], _execution(name=RMUTL_update_run_name(1), rc=16, stdout=" ABC \n REASON: X'A8'", stderr="CC"), + [], _execution(name=RMUTL_update_run_name(2), rc=16, stdout="\n\n\n REASON: X'A8'", stderr="CC"), + [], _execution(name=RMUTL_update_run_name(3), rc=16, stdout="REASON:X'B2'", stderr="CC"), ] - error_raised = False - try: + with pytest.raises(MVSExecutionException) as e: global_catalog._run_dfhrmutl( location="DATA.SET", sdfhload="SDFH.LOAD", cmd="HI" ) - except MVSExecutionException as e: - error_raised = True assert e.message == "DFHRMUTL failed with RC 16 - REASON:X'B2'" assert e.executions == expected_executions - assert error_raised is True - def test_global_catalog_run_rmutl_many_rc_error(): - global_catalog.MVSCmd.execute = MagicMock( + global_catalog._execute_dfhrmutl = MagicMock( side_effect=[ - MVSCmdResponse(rc=16, stdout=" ABC \n REASON: X'A8'", stderr=""), - MVSCmdResponse(rc=16, stdout="\n\n\n REASON: X'A8'", stderr=""), - MVSCmdResponse(rc=15, stdout="REASON:X'A8'", stderr=""), + (JOB_OUTPUT(" ABC \n REASON: X'A8'", 16), []), + (JOB_OUTPUT("\n\n\n REASON: X'A8'", 16), []), + (JOB_OUTPUT("REASON:X'A8'", 15), []) ] ) - global_catalog._get_rmutl_dds = MagicMock(return_value=[]) expected_executions = [ - _execution(name=RMUTL_update_run_name(1), rc=16, stdout=" ABC \n REASON: X'A8'", stderr=""), - _execution(name=RMUTL_update_run_name(2), rc=16, stdout="\n\n\n REASON: X'A8'", stderr=""), - _execution(name=RMUTL_update_run_name(3), rc=15, stdout="REASON:X'A8'", stderr="") + [], _execution(name=RMUTL_update_run_name(1), rc=16, stdout=" ABC \n REASON: X'A8'", stderr="CC"), + [], _execution(name=RMUTL_update_run_name(2), rc=16, stdout="\n\n\n REASON: X'A8'", stderr="CC"), + [], _execution(name=RMUTL_update_run_name(3), rc=15, stdout="REASON:X'A8'", stderr="CC") ] - error_raised = False - try: + with pytest.raises(MVSExecutionException) as e: global_catalog._run_dfhrmutl( location="DATA.SET", sdfhload="SDFH.LOAD", cmd="HI" ) - except MVSExecutionException as e: - error_raised = True assert e.message == "DFHRMUTL failed with RC 15" assert e.executions == expected_executions - assert error_raised is True - def test_global_catalog_run_rmutl_rc_not_0(): - global_catalog.MVSCmd.execute = MagicMock( - return_value=MVSCmdResponse(rc=123, stdout="", stderr="") + global_catalog._execute_dfhrmutl = MagicMock( + return_value=(JOB_OUTPUT(rc=123), []) ) - global_catalog._get_rmutl_dds = MagicMock(return_value=[]) - - expected_executions = [_execution(name=RMUTL_update_run_name(1), rc=123, stdout="", stderr="")] + expected_executions = [[], _execution(name=RMUTL_update_run_name(1), rc=123, stdout="", stderr="CC")] - error_raised = False - try: + with pytest.raises(MVSExecutionException) as e: global_catalog._run_dfhrmutl( location="DATA.SET", sdfhload="SDFH.LOAD", cmd="HI" ) - except MVSExecutionException as e: - error_raised = True assert e.message == "DFHRMUTL failed with RC 123" assert e.executions == expected_executions - - assert error_raised is True diff --git a/tests/unit/modules/test_global_catalog.py b/tests/unit/modules/test_global_catalog.py index 0c9985c0..846eb115 100644 --- a/tests/unit/modules/test_global_catalog.py +++ b/tests/unit/modules/test_global_catalog.py @@ -22,7 +22,8 @@ RMUTL_stderr, RMUTL_stdout, RMUTL_update_run_name, - set_module_args + set_module_args, + get_sample_job_output as JOB_OUTPUT ) from ansible_collections.ibm.ibm_zos_cics.plugins.modules import global_catalog from ansible_collections.ibm.ibm_zos_cics.plugins.module_utils import _icetool as icetool @@ -84,7 +85,7 @@ def test_create_an_intial_global_catalog(): ] ) global_catalog_utils._execute_dfhrmutl = MagicMock( - return_value=MVSCmdResponse(rc=0, stdout=RMUTL_stdout("AUTOINIT", "UNKNOWN"), stderr=RMUTL_stderr(NAME)) + return_value=(JOB_OUTPUT(RMUTL_stdout("AUTOINIT", "UNKNOWN"), err=RMUTL_stderr(NAME)), []) ) gcd_module.main() @@ -102,6 +103,7 @@ def test_create_an_intial_global_catalog(): stdout=IDCAMS_create_stdout(NAME), stderr="", ), + [], _execution( name=RMUTL_update_run_name(1), rc=0, @@ -114,6 +116,7 @@ def test_create_an_intial_global_catalog(): stdout=LISTDS_data_set(NAME, "VSAM"), stderr="", ), + [], _execution( name=RMUTL_get_run_name(1), rc=0, @@ -164,7 +167,7 @@ def test_delete_an_existing_global_catalog(): ) ) global_catalog_utils._execute_dfhrmutl = MagicMock( - return_value=MVSCmdResponse(rc=0, stdout=RMUTL_stdout("AUTOINIT", "UNKNOWN"), stderr=RMUTL_stderr(NAME)) + return_value=(JOB_OUTPUT(RMUTL_stdout("AUTOINIT", "UNKNOWN"), err=RMUTL_stderr(NAME)), []) ) gcd_module.main() @@ -176,6 +179,7 @@ def test_delete_an_existing_global_catalog(): stdout=LISTDS_data_set(NAME, "VSAM"), stderr="", ), + [], _execution( name=RMUTL_get_run_name(1), rc=0, @@ -272,7 +276,7 @@ def test_warm_start_a_global_catalog(): ) ) global_catalog_utils._execute_dfhrmutl = MagicMock( - return_value=MVSCmdResponse(rc=0, stdout=RMUTL_stdout("AUTOASIS", "UNKNOWN"), stderr=RMUTL_stderr(NAME)) + return_value=(JOB_OUTPUT(RMUTL_stdout("AUTOASIS", "UNKNOWN"), err=RMUTL_stderr(NAME)), []) ) icetool._execute_icetool = MagicMock( return_value=MVSCmdResponse( @@ -289,7 +293,9 @@ def test_warm_start_a_global_catalog(): name=LISTDS_run_name(1), rc=0, stdout=LISTDS_data_set(NAME, "VSAM"), - stderr=""), + stderr="" + ), + [], _execution( name=RMUTL_get_run_name(1), rc=0, @@ -302,6 +308,7 @@ def test_warm_start_a_global_catalog(): stdout=ICETOOL_stdout(52), stderr=ICETOOL_stderr() ), + [], _execution( name=RMUTL_update_run_name(1), rc=0, @@ -312,7 +319,9 @@ def test_warm_start_a_global_catalog(): name=LISTDS_run_name(1), rc=0, stdout=LISTDS_data_set(NAME, "VSAM"), - stderr=""), + stderr="" + ), + [], _execution( name=RMUTL_get_run_name(1), rc=0, @@ -353,7 +362,7 @@ def test_error_warm_start_a_unused_global_catalog(): ) ) global_catalog_utils._execute_dfhrmutl = MagicMock( - return_value=MVSCmdResponse(rc=0, stdout=RMUTL_stdout("AUTOINIT", "UNKNOWN"), stderr=RMUTL_stderr(NAME)) + return_value=(JOB_OUTPUT(RMUTL_stdout("AUTOINIT", "UNKNOWN"), err=RMUTL_stderr(NAME)), []) ) icetool._execute_icetool = MagicMock( return_value=MVSCmdResponse( @@ -372,6 +381,7 @@ def test_error_warm_start_a_unused_global_catalog(): stdout=LISTDS_data_set(NAME, "VSAM"), stderr="" ), + [], _execution( name=RMUTL_get_run_name(1), rc=0, @@ -382,7 +392,9 @@ def test_error_warm_start_a_unused_global_catalog(): name=ICETOOL_name(1), rc=0, stdout=ICETOOL_stdout(0), - stderr=ICETOOL_stderr()), + stderr=ICETOOL_stderr() + ), + [], _execution( name=RMUTL_update_run_name(1), rc=0, @@ -395,6 +407,7 @@ def test_error_warm_start_a_unused_global_catalog(): stdout=LISTDS_data_set(NAME, "VSAM"), stderr="" ), + [], _execution( name=RMUTL_get_run_name(1), rc=0, @@ -431,7 +444,7 @@ def test_error_warm_start_a_non_existent_global_catalog(): return_value=MVSCmdResponse(8, LISTDS_data_set_doesnt_exist(NAME), "") ) global_catalog_utils._execute_dfhrmutl = MagicMock( - return_value=MVSCmdResponse(rc=0, stdout=RMUTL_stdout("AUTOINIT", "UNKNOWN"), stderr=RMUTL_stderr(NAME)) + return_value=(JOB_OUTPUT(RMUTL_stdout("AUTOINIT", "UNKNOWN"), err=RMUTL_stderr(NAME)), []) ) gcd_module.main() @@ -443,6 +456,7 @@ def test_error_warm_start_a_non_existent_global_catalog(): stdout=LISTDS_data_set_doesnt_exist(NAME), stderr="" ), + [], _execution( name=RMUTL_update_run_name(1), rc=0, @@ -485,7 +499,7 @@ def tests_cold_start_non_existent_catalog(): return_value=MVSCmdResponse(8, LISTDS_data_set_doesnt_exist(NAME), "") ) global_catalog_utils._execute_dfhrmutl = MagicMock( - return_value=MVSCmdResponse(rc=0, stdout=RMUTL_stdout("AUTOCOLD", "UNKNOWN"), stderr=RMUTL_stderr(NAME)) + return_value=(JOB_OUTPUT(RMUTL_stdout("AUTOCOLD", "UNKNOWN"), err=RMUTL_stderr(NAME)), []) ) gcd_module.main() @@ -497,6 +511,7 @@ def tests_cold_start_non_existent_catalog(): stdout=LISTDS_data_set_doesnt_exist(NAME), stderr="" ), + [], _execution( name=RMUTL_update_run_name(1), rc=0, @@ -539,7 +554,7 @@ def test_cold_start_unused_catalog(): return_value=MVSCmdResponse(0, LISTDS_data_set(NAME, "VSAM"), "") ) global_catalog_utils._execute_dfhrmutl = MagicMock( - return_value=MVSCmdResponse(rc=0, stdout=RMUTL_stdout("AUTOINIT", "UNKNOWN"), stderr=RMUTL_stderr(NAME)) + return_value=(JOB_OUTPUT(RMUTL_stdout("AUTOINIT", "UNKNOWN"), err=RMUTL_stderr(NAME)), []) ) gcd_module.main() @@ -551,12 +566,14 @@ def test_cold_start_unused_catalog(): stdout=LISTDS_data_set(NAME, "VSAM"), stderr="", ), + [], _execution( name=RMUTL_get_run_name(1), rc=0, stdout=RMUTL_stdout("AUTOINIT", "UNKNOWN"), stderr=RMUTL_stderr(NAME) ), + [], _execution( name=RMUTL_update_run_name(1), rc=0, @@ -569,6 +586,7 @@ def test_cold_start_unused_catalog(): stdout=LISTDS_data_set(NAME, "VSAM"), stderr="", ), + [], _execution( name=RMUTL_get_run_name(1), rc=0, @@ -605,7 +623,7 @@ def test_cold_start_global_catalog(): return_value=MVSCmdResponse(0, LISTDS_data_set(NAME, "VSAM"), "") ) global_catalog_utils._execute_dfhrmutl = MagicMock( - return_value=MVSCmdResponse(rc=0, stdout=RMUTL_stdout("AUTOCOLD", "UNKNOWN"), stderr=RMUTL_stderr(NAME)) + return_value=(JOB_OUTPUT(RMUTL_stdout("AUTOCOLD", "UNKNOWN"), err=RMUTL_stderr(NAME)), []) ) gcd_module.main() @@ -617,12 +635,14 @@ def test_cold_start_global_catalog(): stdout=LISTDS_data_set(NAME, "VSAM"), stderr="" ), + [], _execution( name=RMUTL_get_run_name(1), rc=0, stdout=RMUTL_stdout("AUTOCOLD", "UNKNOWN"), stderr=RMUTL_stderr(NAME) ), + [], _execution( name=RMUTL_update_run_name(1), rc=0, @@ -635,6 +655,7 @@ def test_cold_start_global_catalog(): stdout=LISTDS_data_set(NAME, "VSAM"), stderr="" ), + [], _execution( name=RMUTL_get_run_name(1), rc=0,