diff --git a/changelogs/fragments/2204-Update_zos_job_query_module.yml b/changelogs/fragments/2204-Update_zos_job_query_module.yml index 0e2a79c186..b3a2270c37 100644 --- a/changelogs/fragments/2204-Update_zos_job_query_module.yml +++ b/changelogs/fragments/2204-Update_zos_job_query_module.yml @@ -1,3 +1,3 @@ breaking_changes: - - zos_job_query - Return value ``message`` is deprecated in favor of ``msg``. Return value ``steps`` are no longer under `` but is now included under jobs. + - zos_job_query - Return field ``message`` is deprecated in favor of ``msg``. Return field ``steps`` is no longer under ``ret_code`` but is now included under ``jobs``. (https://github.com/ansible-collections/ibm_zos_core/pull/2204). \ No newline at end of file diff --git a/changelogs/fragments/2208_update_job_modules_interfaces.yml b/changelogs/fragments/2208_update_job_modules_interfaces.yml new file mode 100644 index 0000000000..e84fc8d9cf --- /dev/null +++ b/changelogs/fragments/2208_update_job_modules_interfaces.yml @@ -0,0 +1,12 @@ +breaking_changes: + - zos_job_output - Option name ``ddname`` is substituted for ``dd_name``, but ``ddname`` is kept as an alias. Return value ``changed`` is always returned and return value ``steps`` are no longer under ``ret_code`` + but is now included under `jobs`. Return value ``ddnames`` is replaced by ``dds`` and value ``ddname`` under ``ddnames`` is replaced by ``dd_name``. + (https://github.com/ansible-collections/ibm_zos_core/pull/2208). + - zos_job_submit - Interface value ``location`` is replace for ``remote_src`` in a bool value and ``wait_time_s`` is replaced for ``wait_time``. + Return value ``ddnames`` replaced by ``dds`` and value ``ddname`` under ``ddnames`` is replace by ``dd_name``. Now all values are returned under ``jobs`` except ``changed``. + (https://github.com/ansible-collections/ibm_zos_core/pull/2208). + +trivial: + - test/zos_job_query_func.py - Update test validation to new values for job submit. Return value ``steps`` are no longer under `ret_code` + but is now included under `jobs`. + (https://github.com/ansible-collections/ibm_zos_core/pull/2208). \ No newline at end of file diff --git a/plugins/action/zos_job_submit.py b/plugins/action/zos_job_submit.py index 1f8cdf465a..5456fb3ec7 100644 --- a/plugins/action/zos_job_submit.py +++ b/plugins/action/zos_job_submit.py @@ -45,16 +45,16 @@ def run(self, tmp=None, task_vars=None): module_args = self._task.args.copy() use_template = _process_boolean(module_args.get("use_template")) - location = module_args.get("location") - if use_template and location != "local": + remote_src = module_args.get("remote_src") + if use_template and remote_src: result.update(dict( failed=True, changed=False, - msg="Use of Jinja2 templates is only valid for local files. Location is set to '{0}' but should be 'local'".format(location) + msg="Use of Jinja2 templates is only valid for local files. remote_src is set to '{0}' but should be False".format(remote_src) )) return result - if location == "local": + if not remote_src: source = self._task.args.get("src", None) diff --git a/plugins/module_utils/job.py b/plugins/module_utils/job.py index 1b0351d682..d3f2fce065 100644 --- a/plugins/module_utils/job.py +++ b/plugins/module_utils/job.py @@ -167,6 +167,7 @@ def _job_not_found(job_id, owner, job_name, dd_name): job_not_found_msg = "with the name {0}".format(job_name.upper()) job = {} + job["job_not_found"] = True job["job_id"] = job_id job["job_name"] = job_name job["subsystem"] = None @@ -175,24 +176,36 @@ def _job_not_found(job_id, owner, job_name, dd_name): job["cpu_time"] = None job["execution_node"] = None job["origin_node"] = None + job["content_type"] = None + job["creation_date"] = None + job["creation_time"] = None + job["execution_time"] = None + job["job_class"] = None + job["svc_class"] = None + job["priority"] = None + job["asid"] = None + job["queue_position"] = None + job["program_name"] = None job["ret_code"] = {} job["ret_code"]["msg"] = None job["ret_code"]["code"] = None job["ret_code"]["msg_code"] = None job["ret_code"]["msg_txt"] = "The job {0} could not be found.".format(job_not_found_msg) + job["steps"] = [] - job["class"] = "" + job["class"] = None - job["ddnames"] = [] + job["dds"] = [] dd = {} - dd["ddname"] = dd_name - dd["record_count"] = "0" - dd["id"] = "" + dd["dd_name"] = dd_name + dd["record_count"] = 0 + dd["id"] = None dd["stepname"] = None - dd["procstep"] = "" - dd["byte_count"] = "0" - job["ddnames"].append(dd) + dd["procstep"] = None + dd["byte_count"] = 0 + dd["content"] = None + job["dds"].append(dd) jobs.append(job) @@ -351,8 +364,8 @@ def _get_job_status(job_id="*", owner="*", job_name="*", dd_name=None, dd_scan=T job = {} job["job_id"] = entry.job_id job["job_name"] = entry.name - job["subsystem"] = "" - job["system"] = "" + job["subsystem"] = None + job["system"] = None job["owner"] = entry.owner job["cpu_time"] = None job["execution_node"] = None @@ -380,9 +393,9 @@ def _get_job_status(job_id="*", owner="*", job_name="*", dd_name=None, dd_scan=T job["creation_time"] = str(entry.creation_datetime)[12:] job["queue_position"] = entry.queue_position job["program_name"] = entry.program_name - job["class"] = "" + job["class"] = None job["steps"] = [] - job["ddnames"] = [] + job["dds"] = [] job["duration"] = duration if hasattr(entry, "execution_time"): job["execution_time"] = entry.execution_time @@ -444,7 +457,7 @@ def _get_job_status(job_id="*", owner="*", job_name="*", dd_name=None, dd_scan=T if dd_name not in single_dd["dd_name"]: continue else: - dd["ddname"] = single_dd["dd_name"] + dd["dd_name"] = single_dd["dd_name"] if "records" in single_dd: dd["record_count"] = single_dd["records"] @@ -495,8 +508,8 @@ def _get_job_status(job_id="*", owner="*", job_name="*", dd_name=None, dd_scan=T job["steps"].extend(_parse_steps(tmpcont)) - job["ddnames"].append(dd) - if len(job["class"]) < 1: + job["dds"].append(dd) + if job["class"] is None: job["class"] = entry.job_class if job["system"] is None: @@ -545,7 +558,7 @@ def _ddname_pattern(contents, resolve_dependencies): re.IGNORECASE, ): raise ValueError( - 'Invalid argument type for "{0}". Expected "ddname_pattern"'.format( + 'Invalid argument type for "{0}". Expected "dd_name_pattern"'.format( contents ) ) diff --git a/plugins/modules/zos_job_output.py b/plugins/modules/zos_job_output.py index 19be248566..70451c7cae 100644 --- a/plugins/modules/zos_job_output.py +++ b/plugins/modules/zos_job_output.py @@ -31,7 +31,7 @@ such as "TCP*" or "*". - The owner can be specific such as "IBMUSER", or one that uses a pattern like "*". - - If there is no ddname, or if ddname="?", output of all the ddnames under + - If there is no dd_name, or if dd_name="?", output of all the dds under the given job will be displayed. version_added: "1.0.0" author: @@ -55,12 +55,13 @@ - The owner who ran the job. (e.g "IBMUSER", "*") type: str required: false - ddname: + dd_name: description: - Data definition name (show only this DD on a found job). (e.g "JESJCL", "?") type: str required: false + aliases: [ ddname ] attributes: action: @@ -75,21 +76,21 @@ """ EXAMPLES = r""" -- name: Job output with ddname +- name: Job output with dd_name zos_job_output: job_id: "STC02560" - ddname: "JESMSGLG" + dd_name: "JESMSGLG" -- name: JES Job output without ddname +- name: JES Job output without dd_name zos_job_output: job_id: "STC02560" -- name: JES Job output with all ddnames +- name: JES Job output with all dd_name zos_job_output: job_id: "STC*" job_name: "*" owner: "IBMUSER" - ddname: "?" + dd_name: "?" """ RETURN = r""" @@ -139,7 +140,7 @@ sample: "STL1" class: description: - Identifies the data set used in a system output data set, usually called a sysout data set. + Identifies the data set used in a system output data set, usually called a sysout data set. type: str sample: content_type: @@ -169,15 +170,15 @@ it represents the time elapsed from the job execution start and current time. type: str sample: 00:00:10 - ddnames: + dds: description: - Data definition names. + Data definition names. type: list elements: dict contains: - ddname: + dd_name: description: - Data definition name. + Data definition name. type: str sample: JESMSGLG record_count: @@ -187,7 +188,7 @@ sample: 17 id: description: - The file ID. + The file ID. type: str sample: 2 stepname: @@ -198,8 +199,8 @@ sample: JES2 procstep: description: - Identifies the set of statements inside JCL grouped together to - perform a particular function. + Identifies the set of statements inside JCL grouped together to + perform a particular function. type: str sample: PROC1 byte_count: @@ -209,7 +210,7 @@ sample: 574 content: description: - The ddname content. + The dd content. type: list elements: str sample: @@ -227,7 +228,7 @@ " 5 //SYSUT1 DD * ", " 6 //SYSUT2 DD SYSOUT=* ", " 7 // " - ] + ] job_class: description: Job class for this job. @@ -261,7 +262,7 @@ sample: "IEBGENER" ret_code: description: - Return code output collected from job log. + Return code output collected from job log. type: dict contains: msg: @@ -277,48 +278,48 @@ sample: S0C4 msg_txt: description: - Returns additional information related to the job. + Returns additional information related to the job. type: str sample: "No job can be located with this job name: HELLO" code: description: - Return code converted to integer value (when possible). + Return code converted to integer value (when possible). type: int sample: 00 - steps: - description: - Series of JCL steps that were executed and their return codes. - type: list - elements: dict - contains: - step_name: - description: - Name of the step shown as "was executed" in the DD section. - type: str - sample: "STEP0001" - step_cc: - description: - The CC returned for this step in the DD section. - type: int - sample: 0 sample: ret_code: { "code": 0, "msg": "CC 0000", "msg_code": "0000", "msg_txt": "", - "steps": [ - { "step_name": "STEP0001", - "step_cc": 0 - } - ] } + steps: + description: + Series of JCL steps that were executed and their return codes. + type: list + elements: dict + contains: + step_name: + description: + Name of the step shown as "was executed" in the DD section. + type: str + sample: "STEP0001" + step_cc: + description: + The CC returned for this step in the DD section. + type: int + sample: 0 + sample: [ + { "step_name": "STEP0001", + "step_cc": 0 + } + ] sample: [ { "class": "R", "content_type": "JOB", - "ddnames": [ + "dds": [ { "byte_count": "775", "content": [ @@ -340,7 +341,7 @@ "- 6 SYSOUT SPOOL KBYTES", "- 0.00 MINUTES EXECUTION TIME" ], - "ddname": "JESMSGLG", + "dd_name": "JESMSGLG", "id": "2", "procstep": "", "record_count": "17", @@ -364,7 +365,7 @@ " 6 //SYSUT2 DD SYSOUT=* ", " 7 // " ], - "ddname": "JESJCL", + "dd_name": "JESJCL", "id": "3", "procstep": "", "record_count": "14", @@ -393,7 +394,7 @@ " IEF033I JOB/HELLO /STOP 2020049.1025 ", " CPU: 0 HR 00 MIN 00.00 SEC SRB: 0 HR 00 MIN 00.00 SEC " ], - "ddname": "JESYSMSG", + "dd_name": "JESYSMSG", "id": "4", "procstep": "", "record_count": "19", @@ -407,7 +408,7 @@ " ", " PROCESSING ENDED AT EOD " ], - "ddname": "SYSPRINT", + "dd_name": "SYSPRINT", "id": "102", "procstep": "", "record_count": "4", @@ -418,7 +419,7 @@ "content": [ " HELLO, WORLD " ], - "ddname": "SYSUT2", + "dd_name": "SYSUT2", "id": "103", "procstep": "", "record_count": "1", @@ -439,12 +440,12 @@ "msg": "CC 0000", "msg_code": "0000", "msg_txt": "", - "steps": [ - { "step_name": "STEP0001", - "step_cc": 0 - } - ] }, + "steps": [ + { "step_name": "STEP0001", + "step_cc": 0 + } + ], "system": "STL1", "subsystem": "STL1", "cpu_time": 1414, @@ -456,7 +457,7 @@ description: Indicates if any changes were made during module operation type: bool - returned: on success + returned: always """ @@ -495,7 +496,7 @@ def run_module(): job_id=dict(type="str", required=False), job_name=dict(type="str", required=False), owner=dict(type="str", required=False), - ddname=dict(type="str", required=False), + dd_name=dict(type="str", required=False, aliases=['ddname']), ) module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) @@ -504,7 +505,7 @@ def run_module(): job_id=dict(type="job_identifier", required=False), job_name=dict(type="job_identifier", required=False), owner=dict(type="str", required=False), - ddname=dict(type="str", required=False), + dd_name=dict(type="str", required=False, aliases=['ddname']), ) try: @@ -517,27 +518,34 @@ def run_module(): stderr=str(err) ) + results = {} + results["changed"] = False + job_id = module.params.get("job_id") job_name = module.params.get("job_name") owner = module.params.get("owner") - ddname = module.params.get("ddname") + dd_name = module.params.get("dd_name") if not job_id and not job_name and not owner: - module.fail_json(msg="Please provide a job_id or job_name or owner") + module.fail_json(msg="Please provide a job_id or job_name or owner", stderr="", **results) try: results = {} - results["jobs"] = job_output(job_id=job_id, owner=owner, job_name=job_name, dd_name=ddname) - results["changed"] = False + results["jobs"] = job_output(job_id=job_id, owner=owner, job_name=job_name, dd_name=dd_name) + for job in results["jobs"]: + if "job_not_found" in job: + results["changed"] = False + del job['job_not_found'] + else: + results["changed"] = True except zoau_exceptions.JobFetchException as fetch_exception: module.fail_json( - msg="ZOAU exception", - rc=fetch_exception.response.rc, - stdout=fetch_exception.response.stdout_response, + msg=f"ZOAU exception {fetch_exception.response.stdout_response} rc {fetch_exception.response.rc}", stderr=fetch_exception.response.stderr_response, + changed=False ) except Exception as e: - module.fail_json(msg=repr(e)) + module.fail_json(msg=repr(e), **results) module.exit_json(**results) diff --git a/plugins/modules/zos_job_submit.py b/plugins/modules/zos_job_submit.py index 1852327ec5..d347efcc33 100644 --- a/plugins/modules/zos_job_submit.py +++ b/plugins/modules/zos_job_submit.py @@ -46,35 +46,31 @@ - When using a generation data set, only already created generations are valid. If either the relative name is positive, or negative but not found, the module will fail. - location: + remote_src: required: false - default: data_set - type: str - choices: - - data_set - - uss - - local + default: true + type: bool description: - - The JCL location. Supported choices are C(data_set), C(uss) or C(local). - - C(data_set) can be a PDS, PDSE, sequential data set, or a generation data set. - - C(uss) means the JCL location is located in UNIX System Services (USS). - - C(local) means locally to the Ansible control node. - wait_time_s: + - If set to C(false), the module searches for C(src) in the controller node. + - If set to C(true), the module searches for the file C(src) in the managed node. + wait_time: required: false default: 10 type: int description: - - Option I(wait_time_s) is the total time that module + - Option I(wait_time) is the total time that module L(zos_job_submit,./zos_job_submit.html) will wait for a submitted job to complete. The time begins when the module is executed on the managed node. - - I(wait_time_s) is measured in seconds and must be a value greater than 0 + - I(wait_time) is measured in seconds and must be a value greater than 0 and less than 86400. - - The module can submit and forget jobs by setting I(wait_time_s) to 0. This way the + - The module can submit and forget jobs by setting I(wait_time) to 0. This way the module will not try to retrieve the job details other than job id. Job details and contents can be retrieved later by using L(zos_job_query,./zos_job_query.html) or L(zos_job_output,./zos_job_output.html) if needed. + - If I(remote_src=False) and I(wait_time=0), the module will not clean the copy + of the file on the remote system, to avoid problems with job submission. max_rc: required: false type: int @@ -86,7 +82,7 @@ type: bool description: - Whether to print the DD output. - - If false, an empty list will be returned in the ddnames field. + - If false, an empty list will be returned in the dds field. volume: required: false type: str @@ -96,12 +92,12 @@ - When configured, the L(zos_job_submit,./zos_job_submit.html) will try to catalog the data set for the volume serial. If it is not able to, the module will fail. - - Ignored for I(location=uss) and I(location=local). + - Ignored for I(remote_src=False). encoding: description: - Specifies which encoding the local JCL file should be converted from and to, before submitting the job. - - This option is only supported for when I(location=local). + - This option is only supported for when I(remote_src=False). - If this parameter is not provided, and the z/OS systems default encoding can not be identified, the JCL file will be converted from UTF-8 to IBM-1047 by default, otherwise the module will detect the z/OS system @@ -194,13 +190,13 @@ description: Total duration time of the job execution, if it has finished. type: str sample: 00:00:10 - ddnames: + dds: description: Data definition names. type: list elements: dict contains: - ddname: + dd_name: description: Data definition name. type: str @@ -234,7 +230,7 @@ sample: 574 content: description: - The ddname content. + The dd content. type: list elements: str sample: @@ -298,34 +294,35 @@ is the case of a job that errors or is active. type: int sample: 0 - steps: - description: - Series of JCL steps that were executed and their return codes. - type: list - elements: dict - contains: - step_name: - description: - Name of the step shown as "was executed" in the DD section. - type: str - sample: "STEP0001" - step_cc: - description: - The CC returned for this step in the DD section. - type: int - sample: 0 sample: ret_code: { "code": 0, "msg": "CC 0000", "msg_code": "0000", "msg_txt": "", - "steps": [ - { "step_name": "STEP0001", - "step_cc": 0 - }, - ] } + steps: + description: + Series of JCL steps that were executed and their return codes. + type: list + elements: dict + contains: + step_name: + description: + Name of the step shown as "was executed" in the DD section. + type: str + sample: "STEP0001" + step_cc: + description: + The CC returned for this step in the DD section. + type: int + sample: 0 + sample: + "steps": [ + { "step_name": "STEP0001", + "step_cc": 0 + } + ] job_class: description: Job class for this job. @@ -369,12 +366,12 @@ sample: "IEBGENER" system: description: - The job entry system that MVS uses to do work. + The job entry system that MVS uses to do work. type: str sample: STL1 subsystem: description: - The job entry subsystem that MVS uses to do work. + The job entry subsystem that MVS uses to do work. type: str sample: STL1 cpu_time: @@ -392,13 +389,11 @@ Origin node that submitted the job. type: str sample: "STL1" - sample: [ { - "class": "K", "content_type": "JOB", - "ddnames": [ + "dds": [ { "byte_count": "677", "content": [ @@ -419,7 +414,7 @@ "- 12 SYSOUT SPOOL KBYTES", "- 0.00 MINUTES EXECUTION TIME" ], - "ddname": "JESMSGLG", + "dd_name": "JESMSGLG", "id": "2", "procstep": "", "record_count": "16", @@ -476,7 +471,7 @@ " 15 ++SYSPRINT DD SYSOUT=* ", " ++* " ], - "ddname": "JESJCL", + "dd_name": "JESJCL", "id": "3", "procstep": "", "record_count": "47", @@ -530,7 +525,7 @@ " IEF033I JOB/DBDGEN00/STOP 2020073.1250 ", " CPU: 0 HR 00 MIN 00.03 SEC SRB: 0 HR 00 MIN 00.00 SEC " ], - "ddname": "JESYSMSG", + "dd_name": "JESYSMSG", "id": "4", "procstep": "", "record_count": "44", @@ -585,7 +580,7 @@ " **** END OF MESSAGE SUMMARY REPORT **** ", " " ], - "ddname": "SYSPRINT", + "dd_name": "SYSPRINT", "id": "102", "procstep": "L", "record_count": "45", @@ -594,18 +589,17 @@ ], "job_id": "JOB00361", "job_name": "DBDGEN00", - "owner": "OMVSADM", "ret_code": { "code": 0, "msg": "CC 0000", "msg_code": "0000", "msg_txt": "", - "steps": [ - { "step_name": "DLORD6", - "step_cc": 0 - } - ] }, + "steps": [ + { "step_name": "DLORD6", + "step_cc": 0 + } + ], "job_class": "K", "execution_time": "00:00:10", "svc_class": "?", @@ -628,19 +622,19 @@ - name: Submit JCL in a PDSE member. zos_job_submit: src: HLQ.DATA.LLQ(SAMPLE) - location: data_set + remote_src: true register: response - name: Submit JCL in USS with no DDs in the output. zos_job_submit: src: /u/tester/demo/sample.jcl - location: uss + remote_src: true return_output: false - name: Convert local JCL to IBM-037 and submit the job. zos_job_submit: src: /Users/maxy/ansible-playbooks/provision/sample.jcl - location: local + remote_src: false encoding: from: ISO8859-1 to: IBM-037 @@ -648,36 +642,36 @@ - name: Submit JCL in an uncataloged PDSE on volume P2SS01. zos_job_submit: src: HLQ.DATA.LLQ(SAMPLE) - location: data_set + remote_src: true volume: P2SS01 - name: Submit a long running PDS job and wait up to 30 seconds for completion. zos_job_submit: src: HLQ.DATA.LLQ(LONGRUN) - location: data_set - wait_time_s: 30 + remote_src: true + wait_time: 30 - name: Submit a long running PDS job and wait up to 30 seconds for completion. zos_job_submit: src: HLQ.DATA.LLQ(LONGRUN) - location: data_set - wait_time_s: 30 + remote_src: true + wait_time: 30 - name: Submit JCL and set the max return code the module should fail on to 16. zos_job_submit: src: HLQ.DATA.LLQ - location: data_set + remote_src: true max_rc: 16 - name: Submit JCL from the latest generation data set in a generation data group. zos_job_submit: src: HLQ.DATA.GDG(0) - location: data_set + remote_src: true - name: Submit JCL from a previous generation data set in a generation data group. zos_job_submit: src: HLQ.DATA.GDG(-2) - location: data_set + remote_src: true """ from ansible_collections.ibm.ibm_zos_core.plugins.module_utils.encode import ( @@ -820,7 +814,7 @@ def submit_src_jcl(module, src, src_name=None, timeout=0, is_unix=True, start_ti job_fetched = jobs.fetch_multiple(job_submitted.job_id)[0] job_fetch_rc = job_fetched.return_code job_fetch_status = job_fetched.status - # Allow for jobs that need more time to be fectched to run the wait_time_s + # Allow for jobs that need more time to be fectched to run the wait_time except zoau_exceptions.JobFetchException as err: if duration >= timeout: raise err @@ -885,52 +879,6 @@ def submit_src_jcl(module, src, src_name=None, timeout=0, is_unix=True, start_ti return job_submitted.job_id if job_submitted else None, duration -def build_return_schema(result): - """ Builds return values schema with empty values. - - Parameters - ---------- - result : dict - Dictionary used to return values at execution finalization. - - Returns - ------- - dict - Dictionary used to return values at execution finalization. - """ - result = { - "jobs": [], - "job_id": None, - "job_name": None, - "duration": None, - "execution_time": None, - "ddnames": { - "ddname": None, - "record_count": None, - "id": None, - "stepname": None, - "procstep": None, - "byte_count": None, - "content": [], - }, - "ret_code": { - "code": None, - "msg": None, - "msg_code": None, - "msg_txt": None, - "steps": [], - }, - "job_class": None, - "svc_class": None, - "priority": None, - "asid": None, - "creation_date": None, - "queue_position": None, - "program_name": None, - } - return result - - def run_module(): """Initialize module. @@ -939,14 +887,14 @@ def run_module(): fail_json Parameter verification failed. fail_json - The value for option 'wait_time_s' is not valid. + The value for option 'wait_time' is not valid. """ module_args = dict( src=dict(type="str", required=True), - location=dict( - type="str", - default="data_set", - choices=["data_set", "uss", "local"], + remote_src=dict( + type="bool", + default=True, + required=False ), encoding=dict( type="dict", @@ -966,7 +914,7 @@ def run_module(): ), volume=dict(type="str", required=False), return_output=dict(type="bool", required=False, default=True), - wait_time_s=dict(type="int", default=10), + wait_time=dict(type="int", default=10), max_rc=dict(type="int", required=False), use_template=dict(type='bool', default=False), template_parameters=dict( @@ -1014,10 +962,10 @@ def run_module(): arg_defs = dict( src=dict(arg_type="data_set_or_path", required=True), - location=dict( - arg_type="str", - default="data_set", - choices=["data_set", "uss", "local"], + remote_src=dict( + arg_type="bool", + default=True, + required=False ), from_encoding=dict( arg_type="encoding", default=Defaults.DEFAULT_ASCII_CHARSET, required=False), @@ -1026,7 +974,7 @@ def run_module(): ), volume=dict(arg_type="volume", required=False), return_output=dict(arg_type="bool", default=True), - wait_time_s=dict(arg_type="int", required=False, default=10), + wait_time=dict(arg_type="int", required=False, default=10), max_rc=dict(arg_type="int", required=False), ) @@ -1042,22 +990,21 @@ def run_module(): msg="Parameter verification failed", stderr=str(err)) # Extract values from set module options - location = parsed_args.get("location") + remote_src = parsed_args.get("remote_src") volume = parsed_args.get("volume") src = parsed_args.get("src") return_output = parsed_args.get("return_output") - wait_time_s = parsed_args.get("wait_time_s") + wait_time = parsed_args.get("wait_time") max_rc = parsed_args.get("max_rc") - temp_file = parsed_args.get("src") if location == "local" else None + temp_file = parsed_args.get("src") if not remote_src else None # Default 'changed' is False in case the module is not able to execute result = dict(changed=False) # Builds return value schema to make sure we return the return values schema. - result = build_return_schema(result) - if wait_time_s < 0 or wait_time_s > MAX_WAIT_TIME_S: + if wait_time < 0 or wait_time > MAX_WAIT_TIME_S: result["failed"] = True - result["msg"] = ("The value for option 'wait_time_s' is not valid, it must " + result["msg"] = ("The value for option 'wait_time' is not valid, it must " "be greater than 0 and less than {0}.".format(str(MAX_WAIT_TIME_S))) module.fail_json(**result) @@ -1065,68 +1012,72 @@ def run_module(): duration = 0 start_time = timer() - if location == "data_set": - # Resolving a relative GDS name and escaping special symbols if needed. - src_data = data_set.MVSDataSet(src) - - # Checking that the source is actually present on the system. - if volume is not None: - volumes = [volume] - # Get the data set name to catalog it. - src_ds_name = data_set.extract_dsname(src_data.name) - present, changed = DataSet.attempt_catalog_if_necessary(src_ds_name, volumes) - - if not present: - module.fail_json( - msg=(f"Unable to submit job {src_data.name} because the data set could " - f"not be cataloged on the volume {volume}.") - ) - elif data_set.is_member(src_data.name): - if not DataSet.data_set_member_exists(src_data.name): - module.fail_json(msg=f"Cannot submit job, the data set member {src_data.raw_name} was not found.") + if remote_src: + if "/" in src: + if path.exists(src): + if path.isfile(src): + job_submitted_id, duration = submit_src_jcl( + module, src, src_name=src, timeout=wait_time, is_unix=True) + else: + module.fail_json(msg=f"Unable to submit job {src} is a folder, must be a file.", **result) + else: + module.fail_json(msg=f"Unable to submit job {src} does not exists.", **result) else: - if not DataSet.data_set_exists(src_data.name): - module.fail_json(msg=f"Cannot submit job, the data set {src_data.raw_name} was not found.") + # Resolving a relative GDS name and escaping special symbols if needed. + src_data = data_set.MVSDataSet(src) + + # Checking that the source is actually present on the system. + if volume is not None: + volumes = [volume] + # Get the data set name to catalog it. + src_ds_name = data_set.extract_dsname(src_data.name) + present, changed = DataSet.attempt_catalog_if_necessary(src_ds_name, volumes) + + if not present: + module.fail_json( + msg=(f"Unable to submit job {src_data.name} because the data set could " + f"not be cataloged on the volume {volume}."), **result + ) + elif data_set.is_member(src_data.name): + if not DataSet.data_set_member_exists(src_data.name): + module.fail_json(msg=f"Cannot submit job, the data set member {src_data.raw_name} was not found.", **result) + else: + if not DataSet.data_set_exists(src_data.name): + module.fail_json(msg=f"Cannot submit job, the data set {src_data.raw_name} was not found.", **result) + job_submitted_id, duration = submit_src_jcl( + module, src_data.name, src_name=src_data.raw_name, timeout=wait_time, is_unix=False, start_time=start_time) + else: job_submitted_id, duration = submit_src_jcl( - module, src_data.name, src_name=src_data.raw_name, timeout=wait_time_s, is_unix=False, start_time=start_time) - elif location == "uss": - job_submitted_id, duration = submit_src_jcl( - module, src, src_name=src, timeout=wait_time_s, is_unix=True) - elif location == "local": - job_submitted_id, duration = submit_src_jcl( - module, src, src_name=src, timeout=wait_time_s, is_unix=True) + module, src, src_name=src, timeout=wait_time, is_unix=True) # Explictly pass None for the unused args else a default of '*' will be # used and return undersirable results job_output_txt = None - result['job_id'] = job_submitted_id is_changed = True # If wait_time_s is 0, we do a deploy and forget strategy. - if wait_time_s != 0: + if wait_time != 0: try: job_output_txt = job_output( job_id=job_submitted_id, owner=None, job_name=None, dd_name=None, - dd_scan=return_output, duration=duration, timeout=wait_time_s, start_time=start_time) + dd_scan=return_output, duration=duration, timeout=wait_time, start_time=start_time) # This is resolvig a bug where the duration coming from job_output is passed by value, duration # being an immutable type can not be changed and must be returned or accessed from the job.py. - if job_output is not None: + if job_output_txt is not None: duration = job_output_txt[0].get("duration") if not None else duration - result["execution_time"] = job_output_txt[0].get("execution_time") + job_output_txt = parsing_job_response(job_output_txt, duration) - result["duration"] = duration - - if duration >= wait_time_s: + if duration >= wait_time: result["failed"] = True result["changed"] = False _msg = ("The JCL submitted with job id {0} but appears to be a long " "running job that exceeded its maximum wait time of {1} " "second(s). Consider using module zos_job_query to poll for " - "a long running job or increase option 'wait_time_s' to a value " - "greater than {2}.".format(str(job_submitted_id), str(wait_time_s), str(duration))) + "a long running job or increase option 'wait_time' to a value " + "greater than {2}.".format(str(job_submitted_id), str(wait_time), str(duration))) _msg_suffix = ("Consider using module zos_job_query to poll for " - "a long running job or increase option 'wait_time_s' to a value " + "a long running job or increase option 'wait_time' to a value " "greater than {0}.".format(str(duration))) if job_output_txt is not None: @@ -1142,6 +1093,7 @@ def run_module(): if job_output_txt: result["jobs"] = job_output_txt job_ret_code = job_output_txt[0].get("ret_code") + steps = job_output_txt[0].get("steps") if job_ret_code: job_ret_code_msg = job_ret_code.get("msg") @@ -1149,7 +1101,7 @@ def run_module(): job_ret_code_msg_code = job_ret_code.get("msg_code") if return_output is True and max_rc is not None: - is_changed = assert_valid_return_code(max_rc, job_ret_code_code, job_ret_code, result) + is_changed = assert_valid_return_code(max_rc, job_ret_code_code, job_ret_code, steps, result) if job_ret_code_msg is not None: if re.search("^(?:{0})".format("|".join(JOB_STATUSES)), job_ret_code_msg): @@ -1162,8 +1114,8 @@ def run_module(): raise Exception(_msg) if job_ret_code_code is not None and job_ret_code_msg == 'NOEXEC': - job_dd_names = job_output_txt[0].get("ddnames") - jes_jcl_dd = search_dictionaries("ddname", "JESJCL", job_dd_names) + job_dd_names = job_output_txt[0].get("dds") + jes_jcl_dd = search_dictionaries("dd_name", "JESJCL", job_dd_names) # These are the conditions for a job run with TYPRUN=COPY. if not jes_jcl_dd: job_ret_code.update({"msg": "TYPRUN=COPY"}) @@ -1179,8 +1131,8 @@ def run_module(): # so further analyze the # JESJCL DD to figure out if its a TYPRUN job - job_dd_names = job_output_txt[0].get("ddnames") - jes_jcl_dd = search_dictionaries("ddname", "JESJCL", job_dd_names) + job_dd_names = job_output_txt[0].get("dds") + jes_jcl_dd = search_dictionaries("dd_name", "JESJCL", job_dd_names) # Its possible jobs don't have a JESJCL which are active and this would # cause an index out of range error. @@ -1228,7 +1180,7 @@ def run_module(): if not return_output: for job in result.get("jobs", []): - job["ddnames"] = [] + job["dds"] = [] else: _msg = "The 'ret_code' dictionary was unavailable in the job log." result["ret_code"] = None @@ -1237,7 +1189,7 @@ def run_module(): else: _msg = "The job output log is unavailable." result["stderr"] = _msg - result["jobs"] = None + result["jobs"] = [] raise Exception(_msg) except Exception as err: result["failed"] = True @@ -1251,14 +1203,15 @@ def run_module(): finally: if temp_file is not None: shutil.rmtree(path.dirname(temp_file)) + else: + result["jobs"] = build_empty_response(job_submitted_id) # If max_rc is set, we don't want to default to changed=True, rely on 'is_changed' result["changed"] = True if is_changed else False - result["failed"] = False module.exit_json(**result) -def assert_valid_return_code(max_rc, job_rc, ret_code, result): +def assert_valid_return_code(max_rc, job_rc, ret_code, steps, result): """Asserts valid return code. Parameters @@ -1301,7 +1254,7 @@ def assert_valid_return_code(max_rc, job_rc, ret_code, result): result["stderr"] = _msg raise Exception(_msg) - for step in ret_code["steps"]: + for step in steps: step_cc_rc = int(step["step_cc"]) step_name_for_rc = step["step_name"] if step_cc_rc > max_rc: @@ -1325,6 +1278,76 @@ def assert_valid_return_code(max_rc, job_rc, ret_code, result): return True +def parsing_job_response(jobs_raw, duration): + """_summary_ + + Args: + jobs_raw (_type_): _description_ + """ + job = jobs_raw[0] + jobs = [] + for job in jobs_raw: + job_dict = { + "job_id": job.get("job_id"), + "job_name": job.get("job_name"), + "content_type": job.get("content_type"), + "duration": duration, + "execution_time": job.get("execution_time"), + "dds": job.get("dds"), + "ret_code": job.get("ret_code"), + "steps": job.get("steps"), + "job_class": job.get("job_class"), + "svc_class": job.get("svc_class"), + "system": job.get("system"), + "subsystem": job.get("subsystem"), + "origin_node": job.get("origin_node"), + "cpu_time": job.get("cpu_time"), + "execution_node": job.get("execution_node"), + "priority": job.get("priority"), + "asid": job.get("asid"), + "creation_date": job.get("creation_date"), + "creation_time": job.get("creation_time"), + "queue_position": job.get("queue_position"), + "program_name": job.get("program_name"), + } + jobs.append(job_dict) + return jobs + + +def build_empty_response(job_submitted_id): + """_summary_ + + Args: + jobs_raw (_type_): _description_ + """ + jobs = [] + job_dict = { + "job_id": job_submitted_id, + "job_name": None, + "content_type": None, + "duration": None, + "execution_time": None, + "dds": [], + "ret_code": {"code": None, "msg": None, "msg_code": None, "msg_txt": None}, + "steps": [], + "job_class": None, + "svc_class": None, + "system": None, + "subsystem": None, + "origin_node": None, + "cpu_time": None, + "execution_node": None, + "priority": None, + "asid": None, + "creation_date": None, + "creation_time": None, + "queue_position": None, + "program_name": None, + } + jobs.append(job_dict) + return jobs + + def main(): run_module() diff --git a/tests/functional/modules/test_zos_job_output_func.py b/tests/functional/modules/test_zos_job_output_func.py index e1db120d2f..64caf0f3ec 100644 --- a/tests/functional/modules/test_zos_job_output_func.py +++ b/tests/functional/modules/test_zos_job_output_func.py @@ -37,6 +37,9 @@ def test_zos_job_output_no_job_id(ansible_zos_module): results = hosts.all.zos_job_output(job_id="") for result in results.contacted.values(): assert result.get("changed") is False + assert result.get("stderr") is not None + assert result.get("msg") is not None + assert result.get("failed") is True assert result.get("jobs") is None @@ -46,7 +49,9 @@ def test_zos_job_output_invalid_job_id(ansible_zos_module): for result in results.contacted.values(): assert result.get("changed") is False assert result.get("stderr") is not None + assert result.get("msg") is not None assert result.get("failed") is True + assert result.get("jobs") is None def test_zos_job_output_no_job_name(ansible_zos_module): @@ -54,6 +59,9 @@ def test_zos_job_output_no_job_name(ansible_zos_module): results = hosts.all.zos_job_output(job_name="") for result in results.contacted.values(): assert result.get("changed") is False + assert result.get("stderr") is not None + assert result.get("msg") is not None + assert result.get("failed") is True assert result.get("jobs") is None @@ -62,7 +70,46 @@ def test_zos_job_output_invalid_job_name(ansible_zos_module): results = hosts.all.zos_job_output(job_name="INVALID") for result in results.contacted.values(): assert result.get("changed") is False - assert result.get("jobs")[0].get("ret_code").get("msg_txt") is not None + assert result.get("msg", False) is False + assert result.get("jobs") is not None + + job = result.get("jobs")[0] + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("subsystem") is None + assert job.get("system") is None + assert job.get("owner") is not None + assert job.get("cpu_time") is None + assert job.get("execution_node") is None + assert job.get("origin_node") is None + assert job.get("content_type") is None + assert job.get("creation_date") is None + assert job.get("creation_time") is None + assert job.get("execution_time") is None + assert job.get("job_class") is None + assert job.get("svc_class") is None + assert job.get("priority") is None + assert job.get("asid") is None + assert job.get("queue_position") is None + assert job.get("program_name") is None + assert job.get("class") is None + assert job.get("steps") is not None + assert job.get("dds") is not None + + rc = job.get("ret_code") + assert rc.get("msg") is None + assert rc.get("code") is None + assert rc.get("msg_code") is None + assert rc.get("msg_txt") is not None + + dds = job.get("dds")[0] + assert dds.get("dd_name") == "unavailable" + assert dds.get("record_count") == 0 + assert dds.get("id") is None + assert dds.get("stepname") is None + assert dds.get("procstep") is None + assert dds.get("byte_count") == 0 + assert dds.get("content") is None def test_zos_job_output_no_owner(ansible_zos_module): @@ -71,14 +118,20 @@ def test_zos_job_output_no_owner(ansible_zos_module): for result in results.contacted.values(): assert result.get("changed") is False assert result.get("msg") is not None + assert result.get("stderr") is not None + assert result.get("failed") is True + assert result.get("jobs") is None def test_zos_job_output_invalid_owner(ansible_zos_module): hosts = ansible_zos_module results = hosts.all.zos_job_output(owner="INVALID") for result in results.contacted.values(): - assert result.get("failed") is True + assert result.get("changed") is False assert result.get("stderr") is not None + assert result.get("msg") is not None + assert result.get("failed") is True + assert result.get("jobs") is None def test_zos_job_output_reject(ansible_zos_module): @@ -87,6 +140,9 @@ def test_zos_job_output_reject(ansible_zos_module): for result in results.contacted.values(): assert result.get("changed") is False assert result.get("msg") is not None + assert result.get("stderr") is not None + assert result.get("failed") is True + assert result.get("jobs") is None def test_zos_job_output_job_exists(ansible_zos_module): @@ -99,29 +155,96 @@ def test_zos_job_output_job_exists(ansible_zos_module): ) jobs = hosts.all.zos_job_submit( - src=f"{TEMP_PATH}/SAMPLE", location="uss", volume=None + src=f"{TEMP_PATH}/SAMPLE", remote_src=True, volume=None ) for job in jobs.contacted.values(): - print(job) + assert job.get("changed") is True + assert job.get("msg", False) is False assert job.get("jobs") is not None - for job in jobs.contacted.values(): - submitted_job_id = job.get("jobs")[0].get("job_id") - assert submitted_job_id is not None + job_ = job.get("jobs")[0] + assert job_.get("job_id") is not None + submitted_job_id = job_.get("job_id") + assert job_.get("job_name") is not None + assert job_.get("content_type") is not None + assert job_.get("duration") is not None + assert job_.get("execution_time") is not None + assert job_.get("job_class") is not None + assert job_.get("svc_class") is None + assert job_.get("priority") is not None + assert job_.get("asid") is not None + assert job_.get("creation_date") is not None + assert job_.get("creation_time") is not None + assert job_.get("queue_position") is not None + assert job_.get("program_name") is not None + + dds = job_.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None + + step = job_.get("steps")[0] + assert step.get("step_name") is not None + assert step.get("step_cc") is not None + + rc = job_.get("ret_code") + assert rc.get("msg") == "CC" + assert rc.get("code") == 0 + assert rc.get("msg_code") == "0000" + assert rc.get("msg_txt") == "CC" results = hosts.all.zos_job_output(job_id=submitted_job_id) # was SAMPLE?! for result in results.contacted.values(): - assert result.get("changed") is False + assert result.get("changed") is True + assert result.get("msg", False) is False assert result.get("jobs") is not None - assert result.get("jobs")[0].get("ret_code").get("steps") is not None - assert result.get("jobs")[0].get("ret_code").get("steps")[0].get("step_name") == "STEP0001" - assert result.get("jobs")[0].get("content_type") == "JOB" - assert result.get("jobs")[0].get("execution_time") is not None - assert "system" in result.get("jobs")[0] - assert "subsystem" in result.get("jobs")[0] - assert "cpu_time" in result.get("jobs")[0] - assert "execution_node" in result.get("jobs")[0] - assert "origin_node" in result.get("jobs")[0] + + job = result.get("jobs")[0] + assert job.get("job_id") == submitted_job_id + assert job.get("job_name") is not None + assert job.get("subsystem") is not None + assert job.get("system") is not None + assert job.get("owner") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("origin_node") is not None + assert job.get("content_type") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("execution_time") is not None + assert job.get("job_class") is not None + assert job.get("svc_class") is None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is not None + assert job.get("class") is not None + assert job.get("steps") is not None + assert job.get("dds") is not None + + step = job.get("steps")[0] + assert step.get("step_name") is not None + assert step.get("step_cc") is not None + + rc = job.get("ret_code") + assert rc.get("msg") == "CC" + assert rc.get("code") == 0 + assert rc.get("msg_code") == "0000" + assert rc.get("msg_txt") == "CC" + + dds = job.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None + finally: hosts.all.file(path=TEMP_PATH, state="absent") @@ -134,17 +257,55 @@ def test_zos_job_output_job_exists_with_filtered_ddname(ansible_zos_module): cmd=f"echo {quote(JCL_FILE_CONTENTS)} > {TEMP_PATH}/SAMPLE" ) result = hosts.all.zos_job_submit( - src=f"{TEMP_PATH}/SAMPLE", location="uss", volume=None + src=f"{TEMP_PATH}/SAMPLE", remote_src=True, volume=None ) hosts.all.file(path=TEMP_PATH, state="absent") dd_name = "JESMSGLG" results = hosts.all.zos_job_output(job_name="HELLO", ddname=dd_name) for result in results.contacted.values(): - assert result.get("changed") is False + assert result.get("changed") is True + assert result.get("msg", False) is False assert result.get("jobs") is not None - for job in result.get("jobs"): - assert len(job.get("ddnames")) == 1 - assert job.get("ddnames")[0].get("ddname") == dd_name + + job = result.get("jobs")[0] + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("subsystem") is not None + assert job.get("system") is not None + assert job.get("owner") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("origin_node") is not None + assert job.get("content_type") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("execution_time") is not None + assert job.get("job_class") is not None + assert job.get("svc_class") is None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is not None + assert job.get("class") is not None + assert job.get("steps") is not None + assert job.get("dds") is not None + assert len(job.get("dds")) == 1 + + rc = job.get("ret_code") + assert rc.get("msg") == "CC" + assert rc.get("code") == 0 + assert rc.get("msg_code") == "0000" + assert rc.get("msg_txt") == "CC" + + dds = job.get("dds")[0] + assert dds.get("dd_name") == dd_name + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None + finally: hosts.all.file(path=TEMP_PATH, state="absent") @@ -153,4 +314,44 @@ def test_zos_job_submit_job_id_and_owner_included(ansible_zos_module): hosts = ansible_zos_module results = hosts.all.zos_job_output(job_id="STC00*", owner="MASTER") for result in results.contacted.values(): - assert result.get("jobs")[0].get("ret_code").get("msg_txt") is not None + assert result.get("changed") is False + assert result.get("msg", False) is False + assert result.get("jobs") is not None + + job = result.get("jobs")[0] + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("subsystem") is None + assert job.get("system") is None + assert job.get("owner") is not None + assert job.get("cpu_time") is None + assert job.get("execution_node") is None + assert job.get("origin_node") is None + assert job.get("content_type") is None + assert job.get("creation_date") is None + assert job.get("creation_time") is None + assert job.get("execution_time") is None + assert job.get("job_class") is None + assert job.get("svc_class") is None + assert job.get("priority") is None + assert job.get("asid") is None + assert job.get("queue_position") is None + assert job.get("program_name") is None + assert job.get("class") is None + assert job.get("steps") is not None + assert job.get("dds") is not None + + rc = job.get("ret_code") + assert rc.get("msg") is None + assert rc.get("code") is None + assert rc.get("msg_code") is None + assert rc.get("msg_txt") is not None + + dds = job.get("dds")[0] + assert dds.get("dd_name") == "unavailable" + assert dds.get("record_count") == 0 + assert dds.get("id") is None + assert dds.get("stepname") is None + assert dds.get("procstep") is None + assert dds.get("byte_count") == 0 + assert dds.get("content") is None diff --git a/tests/functional/modules/test_zos_job_query_func.py b/tests/functional/modules/test_zos_job_query_func.py index 929200a748..b9160d7d2f 100644 --- a/tests/functional/modules/test_zos_job_query_func.py +++ b/tests/functional/modules/test_zos_job_query_func.py @@ -111,41 +111,45 @@ def test_zos_job_id_query_multi_wildcards_func(ansible_zos_module): cmd=f"cp {temp_path}/SAMPLE \"//'{jdata_set_name}(SAMPLE)'\"" ) results = hosts.all.zos_job_submit( - src=f"{jdata_set_name}(SAMPLE)", location="data_set", wait_time_s=10 + src=f"{jdata_set_name}(SAMPLE)", remote_src=True, wait_time=10 ) for result in results.contacted.values(): - # Default validation assert result.get("changed") is True - assert result.get("jobs") is not None assert result.get("msg", False) is False + assert result.get("jobs") is not None job = result.get("jobs")[0] - assert job.get("job_name") is not None - assert job.get("owner") is not None assert job.get("job_id") is not None + assert job.get("job_name") is not None assert job.get("content_type") is not None - assert job.get("system") is not None - assert job.get("subsystem") is not None - assert job.get("origin_node") is not None - assert job.get("execution_node") is not None - assert job.get("cpu_time") is not None + assert job.get("duration") is not None + assert job.get("execution_time") is not None assert job.get("job_class") is not None + assert job.get("svc_class") is None assert job.get("priority") is not None assert job.get("asid") is not None assert job.get("creation_date") is not None assert job.get("creation_time") is not None + assert job.get("queue_position") is not None assert job.get("program_name") is not None - assert job.get("svc_class") is None - assert job.get("steps") is not None + + dds = job.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None step = job.get("steps")[0] assert step.get("step_name") is not None assert step.get("step_cc") is not None rc = job.get("ret_code") - assert rc.get("msg") is not None - assert rc.get("msg_code") == "0000" + assert rc.get("msg") == "CC" assert rc.get("code") == 0 + assert rc.get("msg_code") == "0000" assert rc.get("msg_txt") == "CC" fulljobid = job.get("job_id") @@ -204,40 +208,45 @@ def test_zos_job_name_query_multi_wildcards_func(ansible_zos_module): cmd=f"cp {temp_path}/SAMPLE \"//'{ndata_set_name}(SAMPLE)'\"" ) results = hosts.all.zos_job_submit( - src=f"{ndata_set_name}(SAMPLE)", location="data_set", wait_time_s=10 + src=f"{ndata_set_name}(SAMPLE)", remote_src=True, wait_time=10 ) for result in results.contacted.values(): assert result.get("changed") is True - assert result.get("jobs") is not None assert result.get("msg", False) is False + assert result.get("jobs") is not None job = result.get("jobs")[0] - assert job.get("job_name") is not None - assert job.get("owner") is not None assert job.get("job_id") is not None + assert job.get("job_name") is not None assert job.get("content_type") is not None - assert job.get("system") is not None - assert job.get("subsystem") is not None - assert job.get("origin_node") is not None - assert job.get("execution_node") is not None - assert job.get("cpu_time") is not None + assert job.get("duration") is not None + assert job.get("execution_time") is not None assert job.get("job_class") is not None + assert job.get("svc_class") is None assert job.get("priority") is not None assert job.get("asid") is not None assert job.get("creation_date") is not None assert job.get("creation_time") is not None + assert job.get("queue_position") is not None assert job.get("program_name") is not None - assert job.get("svc_class") is None - assert job.get("steps") is not None + + dds = job.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None step = job.get("steps")[0] assert step.get("step_name") is not None assert step.get("step_cc") is not None rc = job.get("ret_code") - assert rc.get("msg") is not None - assert rc.get("msg_code") == "0000" + assert rc.get("msg") == "CC" assert rc.get("code") == 0 + assert rc.get("msg_code") == "0000" assert rc.get("msg_txt") == "CC" jobname = "HE*L*" diff --git a/tests/functional/modules/test_zos_job_submit_func.py b/tests/functional/modules/test_zos_job_submit_func.py index fca001a3ec..efa4140794 100644 --- a/tests/functional/modules/test_zos_job_submit_func.py +++ b/tests/functional/modules/test_zos_job_submit_func.py @@ -416,7 +416,7 @@ - name: Submit async job. ibm.ibm_zos_core.zos_job_submit: src: {3} - location: local + remote_src: false async: 45 poll: 0 register: job_task @@ -475,22 +475,56 @@ def test_job_submit_pds(ansible_zos_module, location): ) if bool(location.get("default_location")): results = hosts.all.zos_job_submit( - src="{0}(SAMPLE)".format(data_set_name), wait_time_s=30 + src="{0}(SAMPLE)".format(data_set_name), remote_src=True, wait_time=30 ) else: results = hosts.all.zos_job_submit( - src="{0}(SAMPLE)".format(data_set_name), location="data_set", wait_time_s=30 + src="{0}(SAMPLE)".format(data_set_name), remote_src=True, wait_time=30 ) for result in results.contacted.values(): - assert result.get("jobs")[0].get("ret_code").get("msg_code") == "0000" - assert result.get("jobs")[0].get("ret_code").get("code") == 0 assert result.get("changed") is True - assert "system" in result.get("jobs")[0] - assert "subsystem" in result.get("jobs")[0] - assert "cpu_time" in result.get("jobs")[0] - assert "execution_node" in result.get("jobs")[0] - assert "origin_node" in result.get("jobs")[0] + assert result.get("msg", False) is False + assert result.get("jobs") is not None + + job = result.get("jobs")[0] + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("content_type") is not None + assert job.get("duration") is not None + assert job.get("execution_time") is not None + assert job.get("job_class") is not None + assert job.get("svc_class") is None + assert job.get("system") is not None + assert job.get("subsystem") is not None + assert job.get("origin_node") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is not None + + dds = job.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None + + step = job.get("steps")[0] + assert step.get("step_name") is not None + assert step.get("step_cc") is not None + + rc = job.get("ret_code") + assert rc.get("msg") == "CC" + assert rc.get("code") == 0 + assert rc.get("msg_code") == "0000" + assert rc.get("msg_txt") == "CC" finally: hosts.all.file(path=temp_path, state="absent") hosts.all.zos_data_set(name=data_set_name, state="absent") @@ -515,12 +549,51 @@ def test_job_submit_pds_special_characters(ansible_zos_module): ) results = hosts.all.zos_job_submit( src="{0}(SAMPLE)".format(data_set_name_special_chars), - location="data_set", + remote_src=True, ) for result in results.contacted.values(): - assert result.get("jobs")[0].get("ret_code").get("msg_code") == "0000" - assert result.get("jobs")[0].get("ret_code").get("code") == 0 assert result.get("changed") is True + assert result.get("msg", False) is False + assert result.get("jobs") is not None + + job = result.get("jobs")[0] + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("content_type") is not None + assert job.get("duration") is not None + assert job.get("execution_time") is not None + assert job.get("job_class") is not None + assert job.get("svc_class") is None + assert job.get("system") is not None + assert job.get("subsystem") is not None + assert job.get("origin_node") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is not None + + dds = job.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None + + step = job.get("steps")[0] + assert step.get("step_name") is not None + assert step.get("step_cc") is not None + + rc = job.get("ret_code") + assert rc.get("msg") == "CC" + assert rc.get("code") == 0 + assert rc.get("msg_code") == "0000" + assert rc.get("msg_txt") == "CC" finally: hosts.all.file(path=temp_path, state="absent") hosts.all.zos_data_set(name=data_set_name_special_chars, state="absent") @@ -535,13 +608,51 @@ def test_job_submit_uss(ansible_zos_module): cmd="echo {0} > {1}/SAMPLE".format(quote(JCL_FILE_CONTENTS), temp_path) ) results = hosts.all.zos_job_submit( - src=f"{temp_path}/SAMPLE", location="uss", volume=None + src=f"{temp_path}/SAMPLE", remote_src=True, volume=None ) for result in results.contacted.values(): - assert result.get("jobs")[0].get("ret_code").get("msg_code") == "0000" - assert result.get("jobs")[0].get("ret_code").get("code") == 0 - assert result.get("jobs")[0].get("content_type") == "JOB" assert result.get("changed") is True + assert result.get("msg", False) is False + assert result.get("jobs") is not None + + job = result.get("jobs")[0] + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("content_type") is not None + assert job.get("duration") is not None + assert job.get("execution_time") is not None + assert job.get("job_class") is not None + assert job.get("svc_class") is None + assert job.get("system") is not None + assert job.get("subsystem") is not None + assert job.get("origin_node") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is not None + + dds = job.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None + + step = job.get("steps")[0] + assert step.get("step_name") is not None + assert step.get("step_cc") is not None + + rc = job.get("ret_code") + assert rc.get("msg") == "CC" + assert rc.get("code") == 0 + assert rc.get("msg_code") == "0000" + assert rc.get("msg_txt") == "CC" finally: hosts.all.file(path=temp_path, state="absent") @@ -555,35 +666,41 @@ def test_job_submit_and_forget_uss(ansible_zos_module): cmd="echo {0} > {1}/SAMPLE".format(quote(JCL_FILE_CONTENTS), temp_path) ) results = hosts.all.zos_job_submit( - src=f"{temp_path}/SAMPLE", location="uss", volume=None, wait_time_s=0, + src=f"{temp_path}/SAMPLE", remote_src=True, volume=None, wait_time=0, ) for result in results.contacted.values(): - assert result.get("job_id") is not None assert result.get("changed") is True - assert len(result.get("jobs")) == 0 - assert result.get("job_name") is None - assert result.get("duration") is None - assert result.get("execution_time") is None - assert result.get("ddnames") is not None - assert result.get("ddnames").get("ddname") is None - assert result.get("ddnames").get("record_count") is None - assert result.get("ddnames").get("id") is None - assert result.get("ddnames").get("stepname") is None - assert result.get("ddnames").get("procstep") is None - assert result.get("ddnames").get("byte_count") is None - assert len(result.get("ddnames").get("content")) == 0 - assert result.get("ret_code") is not None - assert result.get("ret_code").get("msg") is None - assert result.get("ret_code").get("msg_code") is None - assert result.get("ret_code").get("code") is None - assert len(result.get("ret_code").get("steps")) == 0 - assert result.get("job_class") is None - assert result.get("svc_class") is None - assert result.get("priority") is None - assert result.get("asid") is None - assert result.get("creation_time") is None - assert result.get("queue_position") is None - assert result.get("program_name") is None + assert result.get("msg", False) is False + assert result.get("jobs") is not None + + job = result.get("jobs")[0] + assert job.get("job_id") is not None + assert job.get("job_name") is None + assert job.get("content_type") is None + assert job.get("duration") is None + assert job.get("execution_time") is None + assert job.get("job_class") is None + assert job.get("svc_class") is None + assert job.get("system") is None + assert job.get("subsystem") is None + assert job.get("origin_node") is None + assert job.get("cpu_time") is None + assert job.get("execution_node") is None + assert job.get("priority") is None + assert job.get("asid") is None + assert job.get("creation_date") is None + assert job.get("creation_time") is None + assert job.get("queue_position") is None + assert job.get("program_name") is None + assert job.get("dds") is not None + assert len(job.get("dds")) == 0 + assert job.get("steps") is not None + assert len(job.get("steps")) == 0 + rc = job.get("ret_code") + assert rc.get("msg") is None + assert rc.get("code") is None + assert rc.get("msg_code") is None + assert rc.get("msg_txt") is None finally: hosts.all.file(path=temp_path, state="absent") @@ -593,13 +710,51 @@ def test_job_submit_local(ansible_zos_module): with open(tmp_file.name, "w",encoding="utf-8") as f: f.write(JCL_FILE_CONTENTS) hosts = ansible_zos_module - results = hosts.all.zos_job_submit(src=tmp_file.name, location="local", wait_time_s=10) + results = hosts.all.zos_job_submit(src=tmp_file.name, remote_src=False, wait_time=10) for result in results.contacted.values(): - print(result) - assert result.get("jobs")[0].get("ret_code").get("msg_code") == "0000" - assert result.get("jobs")[0].get("ret_code").get("code") == 0 assert result.get("changed") is True + assert result.get("msg", False) is False + assert result.get("jobs") is not None + + job = result.get("jobs")[0] + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("content_type") is not None + assert job.get("duration") is not None + assert job.get("execution_time") is not None + assert job.get("job_class") is not None + assert job.get("svc_class") is None + assert job.get("system") is not None + assert job.get("subsystem") is not None + assert job.get("origin_node") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is not None + + dds = job.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None + + step = job.get("steps")[0] + assert step.get("step_name") is not None + assert step.get("step_cc") is not None + + rc = job.get("ret_code") + assert rc.get("msg") == "CC" + assert rc.get("code") == 0 + assert rc.get("msg_code") == "0000" + assert rc.get("msg_txt") == "CC" def test_job_submit_local_extra_r(ansible_zos_module): @@ -607,12 +762,51 @@ def test_job_submit_local_extra_r(ansible_zos_module): with open(tmp_file.name, "w",encoding="utf-8") as f: f.write(JCL_FILE_CONTENTS_BACKSLASH_R) hosts = ansible_zos_module - results = hosts.all.zos_job_submit(src=tmp_file.name, location="local", wait_time_s=10) + results = hosts.all.zos_job_submit(src=tmp_file.name, remote_src=False, wait_time=10) for result in results.contacted.values(): - assert result.get("jobs")[0].get("ret_code").get("msg_code") == "0000" - assert result.get("jobs")[0].get("ret_code").get("code") == 0 assert result.get("changed") is True + assert result.get("msg", False) is False + assert result.get("jobs") is not None + + job = result.get("jobs")[0] + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("content_type") is not None + assert job.get("duration") is not None + assert job.get("execution_time") is not None + assert job.get("job_class") is not None + assert job.get("svc_class") is None + assert job.get("system") is not None + assert job.get("subsystem") is not None + assert job.get("origin_node") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is not None + + dds = job.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None + + step = job.get("steps")[0] + assert step.get("step_name") is not None + assert step.get("step_cc") is not None + + rc = job.get("ret_code") + assert rc.get("msg") == "CC" + assert rc.get("code") == 0 + assert rc.get("msg_code") == "0000" + assert rc.get("msg_txt") == "CC" def test_job_submit_local_badjcl(ansible_zos_module): @@ -620,11 +814,12 @@ def test_job_submit_local_badjcl(ansible_zos_module): with open(tmp_file.name, "w",encoding="utf-8") as f: f.write(JCL_FILE_CONTENTS_BAD) hosts = ansible_zos_module - results = hosts.all.zos_job_submit(src=tmp_file.name, location="local", wait_time_s=10) + results = hosts.all.zos_job_submit(src=tmp_file.name, remote_src=False, wait_time=10) for result in results.contacted.values(): - # Expecting: The job completion code (CC) was not in the job log....." assert result.get("changed") is False + assert result.get("msg") is not None + assert result.get("failed") is True assert re.search(r'completion code', repr(result.get("msg"))) @@ -655,13 +850,52 @@ def test_job_submit_pds_volume(ansible_zos_module, volumes_on_systems): results = hosts.all.zos_job_submit( src=data_set_name+"(SAMPLE)", - location="data_set", + remote_src=True, volume=volume_1 ) for result in results.contacted.values(): - assert result.get("jobs")[0].get("ret_code").get("msg_code") == "0000" - assert result.get("jobs")[0].get("ret_code").get("code") == 0 - assert result.get('changed') is True + assert result.get("changed") is True + assert result.get("msg", False) is False + assert result.get("jobs") is not None + + job = result.get("jobs")[0] + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("content_type") is not None + assert job.get("duration") is not None + assert job.get("execution_time") is not None + assert job.get("job_class") is not None + assert job.get("svc_class") is None + assert job.get("system") is not None + assert job.get("subsystem") is not None + assert job.get("origin_node") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is not None + + dds = job.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None + + step = job.get("steps")[0] + assert step.get("step_name") is not None + assert step.get("step_cc") is not None + + rc = job.get("ret_code") + assert rc.get("msg") == "CC" + assert rc.get("code") == 0 + assert rc.get("msg_code") == "0000" + assert rc.get("msg_txt") == "CC" finally: hosts.all.file(path=temp_path, state="absent") hosts.all.zos_data_set(name=data_set_name, state="absent") @@ -689,14 +923,51 @@ def test_job_submit_pds_5_sec_job_wait_15(ansible_zos_module): hosts = ansible_zos_module results = hosts.all.zos_job_submit(src=data_set_name+"(BPXSLEEP)", - location="data_set", wait_time_s=wait_time_s) + remote_src=True, wait_time=wait_time_s) for result in results.contacted.values(): - assert result.get("jobs")[0].get("ret_code").get("msg_code") == "0000" - assert result.get("jobs")[0].get("ret_code").get("code") == 0 - assert result.get('changed') is True - assert result.get('duration') <= wait_time_s - assert result.get('execution_time') is not None + assert result.get("changed") is True + assert result.get("msg", False) is False + assert result.get("jobs") is not None + + job = result.get("jobs")[0] + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("content_type") is not None + assert job.get("duration") <= wait_time_s + assert job.get("execution_time") is not None + assert job.get("job_class") is not None + assert job.get("svc_class") is None + assert job.get("system") is not None + assert job.get("subsystem") is not None + assert job.get("origin_node") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is not None + + dds = job.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None + + step = job.get("steps")[0] + assert step.get("step_name") is not None + assert step.get("step_cc") is not None + + rc = job.get("ret_code") + assert rc.get("msg") == "CC" + assert rc.get("code") == 0 + assert rc.get("msg_code") == "0000" + assert rc.get("msg_txt") == "CC" finally: hosts.all.file(path=temp_path, state="absent") hosts.all.zos_data_set(name=data_set_name, state="absent") @@ -724,18 +995,56 @@ def test_job_submit_pds_30_sec_job_wait_60(ansible_zos_module): hosts = ansible_zos_module results = hosts.all.zos_job_submit(src=data_set_name+"(BPXSLEEP)", - location="data_set", wait_time_s=wait_time_s) + remote_src=True, wait_time=wait_time_s) for result in results.contacted.values(): - assert result.get("jobs")[0].get("ret_code").get("msg_code") == "0000" - assert result.get("jobs")[0].get("ret_code").get("code") == 0 - assert result.get('changed') is True - assert result.get('duration') <= wait_time_s - assert result.get('execution_time') is not None + assert result.get("changed") is True + assert result.get("msg", False) is False + assert result.get("jobs") is not None + + job = result.get("jobs")[0] + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("content_type") is not None + assert job.get("duration") <= wait_time_s + assert job.get("execution_time") is not None + assert job.get("job_class") is not None + assert job.get("svc_class") is None + assert job.get("system") is not None + assert job.get("subsystem") is not None + assert job.get("origin_node") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is not None + + dds = job.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None + + step = job.get("steps")[0] + assert step.get("step_name") is not None + assert step.get("step_cc") is not None + + rc = job.get("ret_code") + assert rc.get("msg") == "CC" + assert rc.get("code") == 0 + assert rc.get("msg_code") == "0000" + assert rc.get("msg_txt") == "CC" finally: hosts.all.file(path=temp_path, state="absent") hosts.all.zos_data_set(name=data_set_name, state="absent") + def test_job_submit_pds_30_sec_job_wait_10_negative(ansible_zos_module): """This submits a 30 second job and only waits 10 seconds""" try: @@ -759,15 +1068,50 @@ def test_job_submit_pds_30_sec_job_wait_10_negative(ansible_zos_module): hosts = ansible_zos_module results = hosts.all.zos_job_submit(src=data_set_name+"(BPXSLEEP)", - location="data_set", wait_time_s=wait_time_s) + remote_src=True, wait_time=wait_time_s) for result in results.contacted.values(): + assert result.get("changed") is False assert result.get("msg") is not None - assert result.get('changed') is False - assert result.get('duration') >= wait_time_s - # expecting at least "long running job that exceeded its maximum wait" + assert result.get("failed") is True assert re.search(r'exceeded', repr(result.get("msg"))) - assert result.get('execution_time') is not None + assert result.get("jobs") is not None + job = result.get("jobs")[0] + + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("content_type") is not None + assert job.get("duration") >= wait_time_s + assert job.get("execution_time") is not None + assert job.get("job_class") is not None + assert job.get("svc_class") is not None + assert job.get("system") is not None + assert job.get("subsystem") is not None + assert job.get("origin_node") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is None + assert len(job.get("steps")) == 0 + + dds = job.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") == 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") == 0 + assert dds.get("content") is not None + + rc = job.get("ret_code") + assert rc.get("msg") == "AC" + assert rc.get("code") is None + assert rc.get("msg_code") is None + assert rc.get("msg_txt") is not None finally: hosts.all.file(path=temp_path, state="absent") hosts.all.zos_data_set(name=data_set_name, state="absent") @@ -797,22 +1141,23 @@ def test_job_submit_max_rc(ansible_zos_module, args): results = hosts.all.zos_job_submit( src=tmp_file.name, - location="local", + remote_src=False, max_rc=args["max_rc"], - wait_time_s=args["wait_time_s"] + wait_time=args["wait_time_s"] ) for result in results.contacted.values(): # Should fail normally as a non-zero RC will result in job submit failure if args["max_rc"] is None: + assert result.get("changed") is False assert result.get("msg") is not None - assert result.get('changed') is False + assert result.get("failed") is True # On busy systems, it is possible that the duration even for a job with a non-zero return code # will take considerable time to obtain the job log and thus you could see either error msg below #Expecting: - "The job return code 8 was non-zero in the job output, this job has failed" # - Consider using module zos_job_query to poll for a long running job or # increase option \\'wait_times_s` to a value greater than 10.", - duration = result.get('duration') + duration = result.get("jobs")[0].get('duration') if duration >= args["wait_time_s"]: re.search(r'long running job', repr(result.get("msg"))) @@ -821,13 +1166,14 @@ def test_job_submit_max_rc(ansible_zos_module, args): # Should fail with normally as well, job fails with an RC 8 yet max is set to 4 elif args["max_rc"] == 4: - assert result.get("msg") is not None - assert result.get('changed') is False # Expecting "The job return code, # 'ret_code[code]' 8 for the submitted job is greater # than the value set for option 'max_rc' 4. # Increase the value for 'max_rc' otherwise # this job submission has failed. + assert result.get("changed") is False + assert result.get("msg") is not None + assert result.get("failed") is True assert re.search( r'the submitted job is greater than the value set for option', repr(result.get("msg")) @@ -837,9 +1183,48 @@ def test_job_submit_max_rc(ansible_zos_module, args): # Will not fail and as the max_rc is set to 12 and the rc is 8 is a change true # there are other possibilities like an ABEND or JCL ERROR will fail this even # with a MAX RC - assert result.get("msg") is None - assert result.get('changed') is True - assert result.get("jobs")[0].get("ret_code").get("code") < 12 + assert result.get("changed") is True + assert result.get("msg", False) is False + assert result.get("jobs") is not None + + job = result.get("jobs")[0] + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("content_type") is not None + assert job.get("duration") is not None + assert job.get("execution_time") is not None + assert job.get("job_class") is not None + assert job.get("svc_class") is None + assert job.get("system") is not None + assert job.get("subsystem") is not None + assert job.get("origin_node") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is not None + + dds = job.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None + + step = job.get("steps")[0] + assert step.get("step_name") is not None + assert step.get("step_cc") is not None + + rc = job.get("ret_code") + assert rc.get("msg") == "CC" + assert rc.get("code") < 12 + assert rc.get("msg_code") != "0000" + assert rc.get("msg_txt") == "CC" finally: hosts.all.file(path=tmp_file.name, state="absent") @@ -909,15 +1294,54 @@ def test_job_submit_jinja_template(ansible_zos_module, args): results = hosts.all.zos_job_submit( src=tmp_file.name, - location="local", + remote_src=False, use_template=True, template_parameters=args["options"] ) for result in results.contacted.values(): - assert result.get('changed') is True - assert result.get("jobs")[0].get("ret_code").get("msg_code") == "0000" - assert result.get("jobs")[0].get("ret_code").get("code") == 0 + assert result.get("changed") is True + assert result.get("msg", False) is False + assert result.get("jobs") is not None + + job = result.get("jobs")[0] + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("content_type") is not None + assert job.get("duration") is not None + assert job.get("execution_time") is not None + assert job.get("job_class") is not None + assert job.get("svc_class") is None + assert job.get("system") is not None + assert job.get("subsystem") is not None + assert job.get("origin_node") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is not None + + dds = job.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None + + step = job.get("steps")[0] + assert step.get("step_name") is not None + assert step.get("step_cc") is not None + + rc = job.get("ret_code") + assert rc.get("msg") == "CC" + assert rc.get("code") == 0 + assert rc.get("msg_code") == "0000" + assert rc.get("msg_txt") == "CC" finally: os.remove(tmp_file.name) @@ -933,16 +1357,55 @@ def test_job_submit_full_input(ansible_zos_module): ) results = hosts.all.zos_job_submit( src=f"{temp_path}/SAMPLE", - location="uss", + remote_src=True, volume=None, # This job used to set wait=True, but since it has been deprecated # and removed, it now waits up to 30 seconds. - wait_time_s=30 + wait_time=30 ) for result in results.contacted.values(): - assert result.get("jobs")[0].get("ret_code").get("msg_code") == "0000" - assert result.get("jobs")[0].get("ret_code").get("code") == 0 assert result.get("changed") is True + assert result.get("msg", False) is False + assert result.get("jobs") is not None + + job = result.get("jobs")[0] + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("content_type") is not None + assert job.get("duration") is not None + assert job.get("execution_time") is not None + assert job.get("job_class") is not None + assert job.get("svc_class") is None + assert job.get("system") is not None + assert job.get("subsystem") is not None + assert job.get("origin_node") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is not None + + dds = job.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None + + step = job.get("steps")[0] + assert step.get("step_name") is not None + assert step.get("step_cc") is not None + + rc = job.get("ret_code") + assert rc.get("msg") == "CC" + assert rc.get("code") == 0 + assert rc.get("msg_code") == "0000" + assert rc.get("msg_txt") == "CC" finally: hosts.all.file(path=temp_path, state="absent") @@ -952,11 +1415,49 @@ def test_negative_job_submit_local_jcl_no_dsn(ansible_zos_module): with open(tmp_file.name, "w",encoding="utf-8") as f: f.write(JCL_FILE_CONTENTS_NO_DSN) hosts = ansible_zos_module - results = hosts.all.zos_job_submit(src=tmp_file.name, wait_time_s=20, location="local") + results = hosts.all.zos_job_submit(src=tmp_file.name, wait_time=20, remote_src=False) for result in results.contacted.values(): assert result.get("changed") is False + assert result.get("msg") is not None assert re.search(r'completion code', repr(result.get("msg"))) - assert result.get("jobs")[0].get("job_id") is not None + assert result.get("failed") is True + assert result.get("jobs") is not None + job = result.get("jobs")[0] + + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("content_type") is not None + assert job.get("duration") is not None + assert job.get("execution_time") is not None + assert job.get("job_class") is not None + assert job.get("svc_class") is None + assert job.get("system") is not None + assert job.get("subsystem") is not None + assert job.get("origin_node") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is not None + assert len(job.get("steps")) == 0 + + dds = job.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None + + rc = job.get("ret_code") + assert rc.get("msg") == "JCLERR" + assert rc.get("code") is None + assert rc.get("msg_code") is None + assert rc.get("msg_txt") is not None def test_negative_job_submit_local_jcl_invalid_user(ansible_zos_module): @@ -964,16 +1465,53 @@ def test_negative_job_submit_local_jcl_invalid_user(ansible_zos_module): with open(tmp_file.name, "w",encoding="utf-8") as f: f.write(JCL_FILE_CONTENTS_INVALID_USER) hosts = ansible_zos_module - results = hosts.all.zos_job_submit(src=tmp_file.name, location="local") + results = hosts.all.zos_job_submit(src=tmp_file.name, remote_src=False) for result in results.contacted.values(): assert result.get("changed") is False assert re.search(r'please review the error for further details', repr(result.get("msg"))) assert re.search(r'please review the job log for status SEC', repr(result.get("msg"))) - assert result.get("jobs")[0].get("job_id") is not None + assert result.get("failed") is True + assert result.get("jobs") is not None + job = result.get("jobs")[0] + + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("content_type") is not None + assert job.get("duration") is not None + assert job.get("execution_time") is None + assert job.get("job_class") is not None + assert job.get("svc_class") is None + assert job.get("system") is not None + assert job.get("subsystem") is not None + assert job.get("origin_node") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is None + assert len(job.get("steps")) == 0 + + dds = job.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None + + rc = job.get("ret_code") + assert rc.get("msg") == "SEC" + assert rc.get("code") is None + assert rc.get("msg_code") is None + assert rc.get("msg_txt") is not None assert re.search( r'please review the job log for status SEC', - repr(result.get("jobs")[0].get("ret_code").get("msg_txt")) + repr(rc.get("msg_txt")) ) @@ -983,22 +1521,55 @@ def test_job_submit_local_jcl_typrun_scan(ansible_zos_module): f.write(JCL_FILE_CONTENTS_TYPRUN_SCAN) hosts = ansible_zos_module results = hosts.all.zos_job_submit(src=tmp_file.name, - location="local", - wait_time_s=20, + remote_src=False, + wait_time=20, encoding={ "from": "UTF-8", "to": "IBM-1047" },) for result in results.contacted.values(): assert result.get("changed") is False - assert result.get("jobs")[0].get("job_id") is not None + assert result.get("jobs") is not None + job = result.get("jobs")[0] + + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("content_type") is not None + assert job.get("duration") is not None + assert job.get("execution_time") is None + assert job.get("job_class") is not None + assert job.get("svc_class") is None + assert job.get("system") is not None + assert job.get("subsystem") is not None + assert job.get("origin_node") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is None + assert len(job.get("steps")) == 0 + + dds = job.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None + + rc = job.get("ret_code") + assert rc.get("msg") == "TYPRUN=SCAN" + assert rc.get("code") is None + assert rc.get("msg_code") is None + assert rc.get("msg_txt") is not None assert re.search( r'run with special job processing TYPRUN=SCAN', - repr(result.get("jobs")[0].get("ret_code").get("msg_txt")) + repr(rc.get("msg_txt")) ) - assert result.get("jobs")[0].get("ret_code").get("code") is None - assert result.get("jobs")[0].get("ret_code").get("msg") == "TYPRUN=SCAN" - assert result.get("jobs")[0].get("ret_code").get("msg_code") is None def test_job_submit_local_jcl_typrun_copy(ansible_zos_module): @@ -1007,8 +1578,8 @@ def test_job_submit_local_jcl_typrun_copy(ansible_zos_module): f.write(JCL_FILE_CONTENTS_TYPRUN_COPY) hosts = ansible_zos_module results = hosts.all.zos_job_submit(src=tmp_file.name, - location="local", - wait_time_s=20, + remote_src=False, + wait_time=20, encoding={ "from": "UTF-8", "to": "IBM-1047" @@ -1018,18 +1589,48 @@ def test_job_submit_local_jcl_typrun_copy(ansible_zos_module): # assert result.get("changed") is False # When running a job with TYPRUN=COPY, a copy of the JCL will be kept in the JES spool, so # effectively, the system is changed even though the job didn't run. - assert result.get("changed") is True - assert result.get("jobs")[0].get("job_id") is not None + assert result.get("changed") is False + assert result.get("jobs") is not None + job = result.get("jobs")[0] + + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("content_type") is not None + assert job.get("duration") is not None + assert job.get("execution_time") is None + assert job.get("job_class") is not None + assert job.get("svc_class") is None + assert job.get("system") is not None + assert job.get("subsystem") is not None + assert job.get("origin_node") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is None + assert len(job.get("steps")) == 0 + + dds = job.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None + + rc = job.get("ret_code") + assert rc.get("msg") == "NOEXEC" + assert rc.get("code") == None + assert rc.get("msg_code") is None + assert rc.get("msg_txt") is not None assert re.search( - r'The job was run with TYPRUN=COPY.', - repr(result.get("jobs")[0].get("ret_code").get("msg_txt")) + r'NOEXEC.', + repr(rc.get("msg_txt")) ) - assert result.get("jobs")[0].get("ret_code").get("code") == 0 - assert result.get("jobs")[0].get("ret_code").get("msg") == 'TYPRUN=COPY' - assert result.get("jobs")[0].get("ret_code").get("msg_code") == '0000' - # assert result.get("jobs")[0].get("ret_code").get("code") is None - # assert result.get("jobs")[0].get("ret_code").get("msg") is None - # assert result.get("jobs")[0].get("ret_code").get("msg_code") is None def test_job_submit_local_jcl_typrun_hold(ansible_zos_module): @@ -1038,22 +1639,47 @@ def test_job_submit_local_jcl_typrun_hold(ansible_zos_module): f.write(JCL_FILE_CONTENTS_TYPRUN_HOLD) hosts = ansible_zos_module results = hosts.all.zos_job_submit(src=tmp_file.name, - location="local", - wait_time_s=20, + remote_src=False, + wait_time=20, encoding={ "from": "UTF-8", "to": "IBM-1047" },) for result in results.contacted.values(): + print(result) assert result.get("changed") is False - assert result.get("jobs")[0].get("job_id") is not None + assert result.get("jobs") is not None + job = result.get("jobs")[0] + + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("content_type") is not None + assert job.get("duration") is not None + assert job.get("execution_time") is None + assert job.get("job_class") is not None + assert job.get("svc_class") is not None + assert job.get("system") is None + assert job.get("subsystem") is not None + assert job.get("origin_node") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is None + assert len(job.get("steps")) == 0 + assert len(job.get("dds")) == 0 + + rc = job.get("ret_code") assert re.search( r'long running job', - repr(result.get("jobs")[0].get("ret_code").get("msg_txt")) + repr(rc.get("msg_txt")) ) - assert result.get("jobs")[0].get("ret_code").get("code") is None - assert result.get("jobs")[0].get("ret_code").get("msg") == "AC" - assert result.get("jobs")[0].get("ret_code").get("msg_code") is None + assert rc.get("code") is None + assert rc.get("msg") == "HOLD" + assert rc.get("msg_code") is None def test_job_submit_local_jcl_typrun_jclhold(ansible_zos_module): @@ -1062,22 +1688,47 @@ def test_job_submit_local_jcl_typrun_jclhold(ansible_zos_module): f.write(JCL_FILE_CONTENTS_TYPRUN_JCLHOLD) hosts = ansible_zos_module results = hosts.all.zos_job_submit(src=tmp_file.name, - location="local", - wait_time_s=20, + remote_src=False, + wait_time=20, encoding={ "from": "UTF-8", "to": "IBM-1047" },) for result in results.contacted.values(): + print(result) assert result.get("changed") is False - assert result.get("jobs")[0].get("job_id") is not None + assert result.get("jobs") is not None + job = result.get("jobs")[0] + + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("content_type") is not None + assert job.get("duration") is not None + assert job.get("execution_time") is None + assert job.get("job_class") is not None + assert job.get("svc_class") is None + assert job.get("system") is None + assert job.get("subsystem") is not None + assert job.get("origin_node") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is None + assert len(job.get("steps")) == 0 + assert len(job.get("dds")) == 0 + + rc = job.get("ret_code") assert re.search( r'long running job', - repr(result.get("jobs")[0].get("ret_code").get("msg_txt")) + repr(rc.get("msg_txt")) ) - assert result.get("jobs")[0].get("ret_code").get("code") is None - assert result.get("jobs")[0].get("ret_code").get("msg") == "AC" - assert result.get("jobs")[0].get("ret_code").get("msg_code") is None + assert rc.get("code") is None + assert rc.get("msg") == "HOLD" + assert rc.get("msg_code") is None @pytest.mark.parametrize("generation", ["0", "-1"]) @@ -1102,11 +1753,50 @@ def test_job_from_gdg_source(ansible_zos_module, generation): cmd="dcp '{0}/SAMPLE' '{1}'".format(temp_path, gds_name) ) - results = hosts.all.zos_job_submit(src=gds_name, location="data_set") + results = hosts.all.zos_job_submit(src=gds_name, remote_src=True) for result in results.contacted.values(): - assert result.get("jobs")[0].get("ret_code").get("msg_code") == "0000" - assert result.get("jobs")[0].get("ret_code").get("code") == 0 assert result.get("changed") is True + assert result.get("msg", False) is False + assert result.get("jobs") is not None + + job = result.get("jobs")[0] + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("content_type") is not None + assert job.get("duration") is not None + assert job.get("execution_time") is not None + assert job.get("job_class") is not None + assert job.get("svc_class") is None + assert job.get("system") is not None + assert job.get("subsystem") is not None + assert job.get("origin_node") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is not None + + dds = job.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None + + step = job.get("steps")[0] + assert step.get("step_name") is not None + assert step.get("step_cc") is not None + + rc = job.get("ret_code") + assert rc.get("msg") == "CC" + assert rc.get("code") == 0 + assert rc.get("msg_code") == "0000" + assert rc.get("msg_txt") == "CC" finally: hosts.all.file(path=temp_path, state="absent") hosts.all.zos_data_set(name=f"{source}(0)", state="absent") @@ -1125,10 +1815,12 @@ def test_inexistent_negative_gds(ansible_zos_module): # Only creating generation 0. hosts.all.zos_data_set(name=f"{source}(+1)", state="present", type="seq") - results = hosts.all.zos_job_submit(src=gds_name, location="data_set") + results = hosts.all.zos_job_submit(src=gds_name, remote_src=True) for result in results.contacted.values(): assert result.get("changed") is False - assert "was not found" in result.get("msg") + assert result.get("msg") is not None + assert result.get("failed") is True + assert re.search(r'was not found', repr(result.get("msg"))) finally: hosts.all.zos_data_set(name=f"{source}(0)", state="absent") hosts.all.zos_data_set(name=source, state="absent") @@ -1145,10 +1837,12 @@ def test_inexistent_positive_gds(ansible_zos_module): # Only creating generation 0. hosts.all.zos_data_set(name=gds_name, state="present", type="seq") - results = hosts.all.zos_job_submit(src=gds_name, location="data_set") + results = hosts.all.zos_job_submit(src=gds_name, remote_src=True) for result in results.contacted.values(): assert result.get("changed") is False - assert "was not found" in result.get("msg") + assert result.get("msg") is not None + assert result.get("failed") is True + assert re.search(r'was not found', repr(result.get("msg"))) finally: hosts.all.zos_data_set(name=f"{source}(0)", state="absent") hosts.all.zos_data_set(name=source, state="absent") @@ -1176,16 +1870,55 @@ def test_zoau_bugfix_invalid_utf8_chars(ansible_zos_module): results = hosts.all.zos_job_submit( src=tmp_file.name, - location="local", - wait_time_s=15 + remote_src=False, + wait_time=15 ) for result in results.contacted.values(): # We shouldn't get an error now that ZOAU handles invalid/unprintable # UTF-8 chars correctly. - assert result.get("jobs")[0].get("ret_code").get("msg_code") == "0000" - assert result.get("jobs")[0].get("ret_code").get("code") == 0 assert result.get("changed") is True + assert result.get("msg", False) is False + assert result.get("jobs") is not None + + job = result.get("jobs")[0] + assert job.get("job_id") is not None + assert job.get("job_name") is not None + assert job.get("content_type") is not None + assert job.get("duration") is not None + assert job.get("execution_time") is not None + assert job.get("job_class") is not None + assert job.get("svc_class") is None + assert job.get("system") is not None + assert job.get("subsystem") is not None + assert job.get("origin_node") is not None + assert job.get("cpu_time") is not None + assert job.get("execution_node") is not None + assert job.get("priority") is not None + assert job.get("asid") is not None + assert job.get("creation_date") is not None + assert job.get("creation_time") is not None + assert job.get("queue_position") is not None + assert job.get("program_name") is not None + + dds = job.get("dds")[0] + assert dds.get("dd_name") is not None + assert dds.get("record_count") != 0 + assert dds.get("id") is not None + assert dds.get("stepname") is not None + assert dds.get("procstep") is not None + assert dds.get("byte_count") != 0 + assert dds.get("content") is not None + + step = job.get("steps")[0] + assert step.get("step_name") is not None + assert step.get("step_cc") is not None + + rc = job.get("ret_code") + assert rc.get("msg") == "CC" + assert rc.get("code") == 0 + assert rc.get("msg_code") == "0000" + assert rc.get("msg_txt") == "CC" finally: hosts.all.file(path=temp_path, state="absent") @@ -1218,7 +1951,7 @@ def test_job_submit_async(get_config): cut_python_path, python_version, tmp_file.name - )), + )), playbook.name )) @@ -1228,7 +1961,7 @@ def test_job_submit_async(get_config): ssh_key, user, python_path - )), + )), inventory.name ))