diff --git a/changelogs/fragments/2232_Update_zos_copy_interface.yml b/changelogs/fragments/2232_Update_zos_copy_interface.yml new file mode 100644 index 000000000..2e850186e --- /dev/null +++ b/changelogs/fragments/2232_Update_zos_copy_interface.yml @@ -0,0 +1,6 @@ +breaking_changes: + - zos_copy - Option ``force_lock`` is deprecated in favor of ``force`` for using datasets on dsp=shr. + Option ``force`` is deprecated in favor of ``replace`` for cases you want to replace a dest already exists. + Option ``executable`` is deprecated in favor of ``is_executable``. + Now return value ``dest_created`` is always return with bool value. + (https://github.com/ansible-collections/ibm_zos_core/pull/2232). \ No newline at end of file diff --git a/plugins/action/zos_copy.py b/plugins/action/zos_copy.py index 1c19b31de..bd6335017 100644 --- a/plugins/action/zos_copy.py +++ b/plugins/action/zos_copy.py @@ -51,13 +51,13 @@ def run(self, tmp=None, task_vars=None): dest = task_args.get('dest', None) content = task_args.get('content', None) - force = _process_boolean(task_args.get('force'), default=True) + replace = _process_boolean(task_args.get('replace'), default=True) backup = _process_boolean(task_args.get('backup'), default=False) local_follow = _process_boolean(task_args.get('local_follow'), default=False) remote_src = _process_boolean(task_args.get('remote_src'), default=False) is_binary = _process_boolean(task_args.get('is_binary'), default=False) - force_lock = _process_boolean(task_args.get('force_lock'), default=False) - executable = _process_boolean(task_args.get('executable'), default=False) + force = _process_boolean(task_args.get('force'), default=False) + is_executable = _process_boolean(task_args.get('is_executable'), default=False) asa_text = _process_boolean(task_args.get('asa_text'), default=False) ignore_sftp_stderr = _process_boolean(task_args.get("ignore_sftp_stderr"), default=True) backup_name = task_args.get("backup_name", None) @@ -116,8 +116,8 @@ def run(self, tmp=None, task_vars=None): msg = "Both 'is_binary' and 'asa_text' are True. Unable to copy binary data as an ASA text file." return self._exit_action(result, msg, failed=True) - if executable and asa_text: - msg = "Both 'executable' and 'asa_text' are True. Unable to copy an executable as an ASA text file." + if is_executable and asa_text: + msg = "Both 'is_executable' and 'asa_text' are True. Unable to copy an is_executable as an ASA text file." return self._exit_action(result, msg, failed=True) use_template = _process_boolean(task_args.get("use_template"), default=False) @@ -130,9 +130,9 @@ def run(self, tmp=None, task_vars=None): msg = "Cannot specify 'mode', 'owner' or 'group' for MVS destination" return self._exit_action(result, msg, failed=True) - if force_lock: + if force: display.warning( - msg="Using force_lock uses operations that are subject to race conditions and can lead to data loss, use with caution.") + msg="Using force uses operations that are subject to race conditions and can lead to data loss, use with caution.") template_dir = None if not remote_src: @@ -293,7 +293,7 @@ def run(self, tmp=None, task_vars=None): path = os.path.normpath(f"{self.tmp_dir}/ansible-zos-copy") rm_res = self._connection.exec_command(f"rm -rf {path}*") - if copy_res.get("note") and not force: + if copy_res.get("note") and not replace: result["note"] = copy_res.get("note") return result diff --git a/plugins/module_utils/copy.py b/plugins/module_utils/copy.py index f5fd19448..1e8691786 100644 --- a/plugins/module_utils/copy.py +++ b/plugins/module_utils/copy.py @@ -209,7 +209,7 @@ def copy_vsam_ps(src, dest, tmphlq=None): return rc, out, err -def copy_asa_uss2mvs(src, dest, tmphlq=None, force_lock=False): +def copy_asa_uss2mvs(src, dest, tmphlq=None, force=False): """Copy a file from USS to an ASA sequential data set or PDS/E member. Parameters @@ -220,7 +220,7 @@ def copy_asa_uss2mvs(src, dest, tmphlq=None, force_lock=False): The MVS destination data set or member. tmphlq : str High Level Qualifier for temporary datasets. - force_lock : bool + force : bool Whether to open the destination in SHR mode. Returns @@ -236,7 +236,7 @@ def copy_asa_uss2mvs(src, dest, tmphlq=None, force_lock=False): # Removes escaping to execute this command dest = dest.replace('\\', '') src = src.replace('\\', '') - dest_dsp = "shr" if force_lock else "old" + dest_dsp = "shr" if force else "old" ocopy_cmd = "OCOPY INDD(DSSRC) OUTDD(DSTAR) TEXT" ocopy_dds = { diff --git a/plugins/modules/zos_copy.py b/plugins/modules/zos_copy.py index 0a9c0d090..c73aea295 100644 --- a/plugins/modules/zos_copy.py +++ b/plugins/modules/zos_copy.py @@ -45,7 +45,7 @@ format (FBA) or Variable Block with ANSI format (VBA), the module will fail. - This option is only valid for text files. If C(is_binary) is C(true) - or C(executable) is C(true) as well, the module will fail. + or C(is_executable) is C(true) as well, the module will fail. type: bool default: false required: false @@ -116,7 +116,7 @@ C(src). If C(src) is a USS file, C(dest) will have a Fixed Block (FB) record format and the remaining attributes will be computed. If I(is_binary=true), C(dest) will have a Fixed Block (FB) record format with a record length of 80, block size of 32720, and the remaining - attributes will be computed. If I(executable=true),C(dest) will have an Undefined (U) record + attributes will be computed. If I(is_executable=true),C(dest) will have an Undefined (U) record format with a record length of 0, block size of 32760, and the remaining attributes will be computed. - If C(src) is a file and C(dest) a partitioned data set, C(dest) does not need to include @@ -176,7 +176,7 @@ that is not available, then the value C(TMPHLQ) is used. required: false type: str - force: + replace: description: - If set to C(true) and the remote file or data set C(dest) is empty, the C(dest) will be reused. @@ -193,14 +193,14 @@ type: bool default: false required: false - force_lock: + force: description: - By default, when C(dest) is a MVS data set and is being used by another - process with DISP=SHR or DISP=OLD the module will fail. Use C(force_lock) + process with DISP=SHR or DISP=OLD the module will fail. Use C(force) to bypass DISP=SHR and continue with the copy operation. - If set to C(true) and destination is a MVS data set opened by another process then zos_copy will try to copy using DISP=SHR. - - Using C(force_lock) uses operations that are subject to race conditions + - Using C(force) uses operations that are subject to race conditions and can lead to data loss, use with caution. - If a data set member has aliases, and is not a program object, copying that member to a dataset that is in use will result in @@ -236,10 +236,10 @@ type: bool default: false required: false - executable: + is_executable: description: - If set to C(true), indicates that the file or library to be copied is an executable. - - If I(executable=true), and C(dest) is a data set, it must be a PDS or PDSE (library). + - If I(is_executable=true), and C(dest) is a data set, it must be a PDS or PDSE (library). - If C(dest) is a nonexistent data set, the library attributes assigned will be Undefined (U) record format with a record length of 0, block size of 32760 and the remaining attributes will be computed. @@ -253,7 +253,7 @@ - If set to C(true), indicates that any aliases found in the source (USS file, USS dir, PDS/E library or member) are to be preserved during the copy operation. - Aliases are implicitly preserved when libraries are copied over to USS destinations. - That is, when C(executable=True) and C(dest) is a USS file or directory, this option will be ignored. + That is, when C(is_executable=True) and C(dest) is a USS file or directory, this option will be ignored. - Copying of aliases for text-based data sets from USS sources or to USS destinations is not currently supported. - If the C(dest) is Unix, the alias is not visible in Unix, even though the information is there and will be visible if copied to a library. @@ -566,7 +566,7 @@ transfers, if not available, the module will fail. - Beginning in version 1.8.x, zos_copy will no longer attempt to correct a copy of a data type member into a PDSE that contains program objects. You can control this - behavior using module option C(executable) that will signify an executable is being + behavior using module option C(is_executable) that will signify an executable is being copied into a PDSE with other executables. Mixing data type members with program objects will result in a (FSUM8976,./zos_copy.html) error. - It is the playbook author or user's responsibility to ensure they have @@ -682,14 +682,14 @@ src: HLQ.SAMPLE.PDSE dest: HLQ.EXISTING.PDSE remote_src: true - force: true + replace: true - name: Copy PDS member to a new PDS member. Replace if it already exists zos_copy: src: HLQ.SAMPLE.PDSE(SRCMEM) dest: HLQ.NEW.PDSE(DESTMEM) remote_src: true - force: true + replace: true - name: Copy a USS file to a PDSE member. If PDSE does not exist, allocate it zos_copy: @@ -753,7 +753,7 @@ src: HLQ.COBOLSRC.PDSE(TESTPGM) dest: HLQ.NEW.PDSE(MYCOBOL) remote_src: true - executable: true + is_executable: true aliases: true - name: Copy a Load Library from a USS directory /home/loadlib to a new PDSE @@ -761,7 +761,7 @@ src: '/home/loadlib/' dest: HLQ.LOADLIB.NEW remote_src: true - executable: true + is_executable: true aliases: true - name: Copy a file with ASA characters to a new sequential data set. @@ -897,7 +897,7 @@ sample: file note: description: A note to the user after module terminates. - returned: When ``force=true`` and ``dest`` exists + returned: When ``replace=true`` and ``dest`` exists type: str sample: No data was copied msg: @@ -987,11 +987,11 @@ def __init__( self, module, is_binary=False, - executable=False, + is_executable=False, aliases=False, asa_text=False, backup_name=None, - force_lock=False, + force=False, identical_gdg_copy=False, tmphlq=None ): @@ -1008,7 +1008,7 @@ def __init__( is_binary : bool Whether the file or data set to be copied contains binary data. - executable : bool + is_executable : bool Whether the file or data set to be copied is executable. asa_text : bool @@ -1018,7 +1018,7 @@ def __init__( backup_name : str The USS path or data set name of destination backup. - force_lock : str + force : str Whether the dest data set should be copied into using disp=shr when is opened by another process. @@ -1033,7 +1033,7 @@ def __init__( is_binary : bool Whether the file or data set to be copied contains binary data. - executable : bool + is_executable : bool Whether the file or data set to be copied is executable. asa_text : bool @@ -1043,7 +1043,7 @@ def __init__( backup_name : str The USS path or data set name of destination backup. - force_lock : str + force : str Whether the dest data set should be copied into using disp=shr when is opened by another process. @@ -1052,11 +1052,11 @@ def __init__( """ self.module = module self.is_binary = is_binary - self.executable = executable + self.is_executable = is_executable self.asa_text = asa_text self.aliases = aliases self.backup_name = backup_name - self.force_lock = force_lock + self.force = force self.identical_gdg_copy = identical_gdg_copy self.tmphlq = tmphlq @@ -1110,7 +1110,7 @@ def copy_to_seq( copy_args["options"] = "" if src_type == 'USS' and self.asa_text: - response = copy.copy_asa_uss2mvs(new_src, dest, tmphlq=self.tmphlq, force_lock=self.force_lock) + response = copy.copy_asa_uss2mvs(new_src, dest, tmphlq=self.tmphlq, force=self.force) if response.rc != 0: raise CopyOperationError( @@ -1126,7 +1126,7 @@ def copy_to_seq( copy_args["options"] = "-B" try: - datasets.copy(new_src, dest, force=self.force_lock, **copy_args) + datasets.copy(new_src, dest, force=self.force, **copy_args) except zoau_exceptions.ZOAUException as copy_exception: raise CopyOperationError( msg="Unable to copy source {0} to {1}".format(new_src, dest), @@ -1150,7 +1150,7 @@ def copy_to_vsam(self, src, dest): CopyOperationError When REPRO fails to copy the data set. """ - out_dsp = "shr" if self.force_lock else "old" + out_dsp = "shr" if self.force else "old" dds = {"OUT": "{0},{1}".format(dest.upper(), out_dsp)} repro_cmd = """ REPRO - INDATASET('{0}') - @@ -1564,7 +1564,7 @@ def __init__( self, module, is_binary=False, - executable=False, + is_executable=False, asa_text=False, aliases=False, common_file_args=None, @@ -1600,7 +1600,7 @@ def __init__( super().__init__( module, is_binary=is_binary, - executable=executable, + is_executable=is_executable, asa_text=asa_text, aliases=aliases, backup_name=backup_name, @@ -1616,7 +1616,7 @@ def copy_to_uss( src_ds_type, src_member, member_name, - force, + replace, content_copy, ): """Copy a file or data set to a USS location. @@ -1638,7 +1638,7 @@ def copy_to_uss( Whether src is a data set member. member_name : str The name of the source data set member. - force : bool + replace : bool Whether to copy files to an already existing directory. content_copy : bool Whether copy is using content option or not. @@ -1655,7 +1655,7 @@ def copy_to_uss( src, dest, src_ds_type, src_member, member_name=member_name ) - if self.executable: + if self.is_executable: status = os.stat(dest) os.chmod(dest, status.st_mode | stat.S_IEXEC) else: @@ -1682,7 +1682,7 @@ def copy_to_uss( dest = self._copy_to_file(src, dest, content_copy, conv_path) changed_files = None else: - dest, changed_files = self._copy_to_dir(src, dest, conv_path, force) + dest, changed_files = self._copy_to_dir(src, dest, conv_path, replace) if self.common_file_args is not None: mode = self.common_file_args.get("mode") @@ -1740,7 +1740,7 @@ def _copy_to_file(self, src, dest, content_copy, conv_path): datasets.copy(new_src, dest, **opts) shutil.copystat(new_src, dest, follow_symlinks=True) # shutil.copy(new_src, dest) - if self.executable: + if self.is_executable: status = os.stat(dest) os.chmod(dest, status.st_mode | stat.S_IEXEC) except zoau_exceptions.ZOAUException as err: @@ -1765,7 +1765,7 @@ def _copy_to_dir( src_dir, dest_dir, conv_path, - force + replace ): """Helper function to copy a USS directory to another USS directory. If the path for dest_dir does not end with a trailing slash ("/"), @@ -1779,7 +1779,7 @@ def _copy_to_dir( USS dest directory. conv_path : str Path to the converted source directory. - force :bool + replace :bool Whether to copy files to an already existing directory. Returns @@ -1804,7 +1804,7 @@ def _copy_to_dir( if copy_directory: dest = os.path.join(validation.validate_safe_path(dest_dir), validation.validate_safe_path(os.path.basename(os.path.normpath(src_dir)))) # dest = shutil.copytree(new_src_dir, dest, dirs_exist_ok=force) - dest = self.copy_tree(new_src_dir, dest, dirs_exist_ok=force) + dest = self.copy_tree(new_src_dir, dest, dirs_exist_ok=replace) # Restoring permissions for preexisting files and subdirectories. for filepath, permissions in original_permissions: @@ -1953,7 +1953,7 @@ def _mvs_copy_to_uss( if self.asa_text: response = copy.copy_asa_mvs2uss(src, dest, tmphlq=self.tmphlq) rc = response.rc - elif self.executable: + elif self.is_executable: try: rc = datasets.copy(src, dest, alias=True, executable=True) except zoau_exceptions.ZOAUException as copy_exception: @@ -1986,7 +1986,7 @@ def _mvs_copy_to_uss( raise CopyOperationError( msg=f"Error while copying GDG {src} to {dest}" ) - elif self.executable: + elif self.is_executable: try: datasets.copy(src, dest, alias=True, executable=True) except zoau_exceptions.ZOAUException as copy_exception: @@ -2023,11 +2023,11 @@ def __init__( self, module, is_binary=False, - executable=False, + is_executable=False, aliases=False, asa_text=False, backup_name=None, - force_lock=False, + force=False, tmphlq=None ): """ Utility class to handle copying to partitioned data sets or @@ -2052,11 +2052,11 @@ def __init__( super().__init__( module, is_binary=is_binary, - executable=executable, + is_executable=is_executable, aliases=aliases, asa_text=asa_text, backup_name=backup_name, - force_lock=force_lock, + force=force, tmphlq=tmphlq ) @@ -2107,7 +2107,7 @@ def copy_to_pdse( path, dirs, files = next(os.walk(new_src)) src_members = [ - os.path.normpath("{0}/{1}".format(path, file)) if (self.is_binary or self.executable) + os.path.normpath("{0}/{1}".format(path, file)) if (self.is_binary or self.is_executable) else normalize_line_endings("{0}/{1}".format(path, file), encoding) for file in files ] @@ -2229,7 +2229,7 @@ def copy_to_member( opts["options"] = "" if src_type == 'USS' and self.asa_text: - response = copy.copy_asa_uss2mvs(src, dest, tmphlq=self.tmphlq, force_lock=self.force_lock) + response = copy.copy_asa_uss2mvs(src, dest, tmphlq=self.tmphlq, force=self.force) rc, out, err = response.rc, response.stdout_response, response.stderr_response else: # While ASA files are just text files, we do a binary copy @@ -2238,7 +2238,7 @@ def copy_to_member( opts["options"] = "-B" try: - rc = datasets.copy(src, dest, alias=self.aliases, executable=self.executable, force=self.force_lock, **opts) + rc = datasets.copy(src, dest, alias=self.aliases, executable=self.is_executable, force=self.force, **opts) out = "" err = "" except zoau_exceptions.ZOAUException as copy_exception: @@ -2419,7 +2419,7 @@ def get_data_set_attributes( def create_seq_dataset_from_file( file, dest, - force, + replace, is_binary, asa_text, record_length=None, @@ -2435,7 +2435,7 @@ def create_seq_dataset_from_file( Path of the source file. dest : str Name of the data set. - force : bool + replace : bool Whether to replace an existing data set. is_binary : bool Whether the file has binary data. @@ -2479,7 +2479,7 @@ def create_seq_dataset_from_file( volume=volume ) - data_set.DataSet.ensure_present(replace=force, tmp_hlq=tmphlq, **dest_params) + data_set.DataSet.ensure_present(replace=replace, tmp_hlq=tmphlq, **dest_params) def backup_data(ds_name, ds_type, backup_name, tmphlq=None): @@ -2523,7 +2523,7 @@ def is_compatible( src_member, is_src_dir, is_src_inline, - executable, + is_executable, asa_text, src_has_asa_chars, dest_has_asa_chars, @@ -2547,7 +2547,7 @@ def is_compatible( Whether the src is a USS directory. is_src_inline : bool Whether the src comes from inline content. - executable : bool + is_executable : bool Whether the src is a executable to be copied. asa_text : bool Whether the copy operation will handle ASA control characters. @@ -2577,7 +2577,7 @@ def is_compatible( # If source or destination is a sequential data set and executable as true # is incompatible to execute the copy. # ******************************************************************** - if executable: + if is_executable: if src_type in data_set.DataSet.MVS_SEQ or dest_type in data_set.DataSet.MVS_SEQ: return False @@ -2692,7 +2692,7 @@ def does_destination_allow_copy( member_exists, dest_type, is_uss, - force, + replace, volume=None, tmphlq=None ): @@ -2715,7 +2715,7 @@ def does_destination_allow_copy( Type of the destination (SEQ/PARTITIONED/VSAM/USS). is_uss : bool Whether or not the destination is inside USS. - force : bool + replace : bool Whether or not the module can replace existing destinations. volume : str, optional Volume where the destination should be. @@ -2731,21 +2731,21 @@ def does_destination_allow_copy( # If the destination is inside USS and the module doesn't have permission to replace it, # it fails. if is_uss and dest_exists: - if src_type == "USS" and os.path.isdir(dest) and os.path.isdir(src) and not force: + if src_type == "USS" and os.path.isdir(dest) and os.path.isdir(src) and not replace: return False - elif os.path.isfile(dest) and not force: + elif os.path.isfile(dest) and not replace: return False # If the destination is a sequential or VSAM data set and is empty, the module will try to use it, # otherwise, force needs to be True to continue and replace it. if (dest_type in data_set.DataSet.MVS_SEQ or dest_type in data_set.DataSet.MVS_VSAM) and dest_exists: is_dest_empty = data_set.DataSet.is_empty(dest, volume, tmphlq=tmphlq) - if not (is_dest_empty or force): + if not (is_dest_empty or replace): return False # When the destination is a partitioned data set, the module will have to be able to replace # existing members inside of it, if needed. - if dest_type in data_set.DataSet.MVS_PARTITIONED and dest_exists and member_exists and not force: + if dest_type in data_set.DataSet.MVS_PARTITIONED and dest_exists and member_exists and not replace: return False # When the destination is an existing GDG, we'll check that we have enough free generations @@ -2920,9 +2920,9 @@ def allocate_destination_data_set( src_ds_type, dest_ds_type, dest_exists, - force, + replace, is_binary, - executable, + is_executable, asa_text, is_gds, is_active_gds, @@ -2946,11 +2946,11 @@ def allocate_destination_data_set( Type of the destination data set. dest_exists : bool Whether the destination data set already exists. - force : bool + replace : bool Whether to replace an existent data set. is_binary : bool Whether the data set will contain binary data. - executable : bool + is_executable : bool Whether the data to copy is an executable dataset or file. asa_text : bool Whether the data to copy has ASA control characters. @@ -2977,7 +2977,8 @@ def allocate_destination_data_set( src_name = data_set.extract_dsname(src) is_dest_empty = data_set.DataSet.is_empty(dest) if dest_exists else True - # Replacing an existing dataset only when it's not empty. We don't know whether that + # Replace in datasets. + # Reuse empty datasets when replace is not true. We don't know whether that # empty dataset was created for the user by an admin/operator, and they don't have permissions # to create new datasets. # These rules assume that source and destination types are compatible. @@ -2987,6 +2988,8 @@ def allocate_destination_data_set( if dest_exists and (is_dest_empty or dest_ds_type == "GDG"): return False, dest_params, dest + if dest_exists and is_dest_empty and not replace: + return False, dest_params, dest # Giving more priority to the parameters given by the user. # Cover case the user set executable to true to create dataset valid. if dest_data_set: @@ -3018,14 +3021,14 @@ def allocate_destination_data_set( del dest_params["purge"] del dest_params["extended"] del dest_params["fifo"] - data_set.DataSet.ensure_present(replace=force, tmp_hlq=tmphlq, **dest_params) + data_set.DataSet.ensure_present(replace=replace, tmp_hlq=tmphlq, **dest_params) elif dest_ds_type in data_set.DataSet.MVS_SEQ: volumes = [volume] if volume else None data_set.DataSet.ensure_absent(dest, volumes=volumes) if src_ds_type == "USS": # Taking the temp file when a local file was copied with sftp. - create_seq_dataset_from_file(src, dest, force, is_binary, asa_text, volume=volume, tmphlq=tmphlq) + create_seq_dataset_from_file(src, dest, replace, is_binary, asa_text, volume=volume, tmphlq=tmphlq) elif src_ds_type in data_set.DataSet.MVS_SEQ: # Only applying the GDS special case when we don't have an absolute name. if is_gds and not is_active_gds: @@ -3043,7 +3046,7 @@ def allocate_destination_data_set( create_seq_dataset_from_file( temp_dump, dest, - force, + replace, is_binary, asa_text, record_length=record_length, @@ -3060,7 +3063,7 @@ def allocate_destination_data_set( if is_gds and not is_active_gds: data_set.DataSet.allocate_gds_model_data_set(ds_name=dest, model=src_name, asa_text=asa_text, vol=volume) else: - data_set.DataSet.allocate_model_data_set(ds_name=dest, model=src_name, executable=executable, asa_text=asa_text, vol=volume, tmphlq=tmphlq) + data_set.DataSet.allocate_model_data_set(ds_name=dest, model=src_name, executable=is_executable, asa_text=asa_text, vol=volume, tmphlq=tmphlq) elif src_ds_type in data_set.DataSet.MVS_SEQ: src_attributes = datasets.list_datasets(src_name)[0] # The size returned by listing is in bytes. @@ -3077,7 +3080,7 @@ def allocate_destination_data_set( type="PDSE", volume=volume ) - data_set.DataSet.ensure_present(replace=force, tmp_hlq=tmphlq, **dest_params) + data_set.DataSet.ensure_present(replace=replace, tmp_hlq=tmphlq, **dest_params) elif src_ds_type == "USS": if os.path.isfile(src): # This is almost the same as allocating a sequential dataset. @@ -3097,7 +3100,7 @@ def allocate_destination_data_set( if asa_text: record_length += 1 - if executable: + if is_executable: record_format = "U" record_length = 0 type_ds = "LIBRARY" @@ -3117,7 +3120,7 @@ def allocate_destination_data_set( size = sum(os.stat("{0}/{1}".format(src, member)).st_size for member in os.listdir(src)) # This PDSE will be created with record format VB and a record length of 1028. - if executable: + if is_executable: dest_params = get_data_set_attributes( dest, size, is_binary, record_format='U', @@ -3135,7 +3138,7 @@ def allocate_destination_data_set( volume=volume ) - data_set.DataSet.ensure_present(replace=force, tmp_hlq=tmphlq, **dest_params) + data_set.DataSet.ensure_present(replace=replace, tmp_hlq=tmphlq, **dest_params) elif dest_ds_type in data_set.DataSet.MVS_VSAM: # If dest_data_set is not available, always create the destination using the src VSAM # as a model. @@ -3271,15 +3274,18 @@ def update_result(res_args, original_args): src = res_args.get("src") note = res_args.get("note") backup_name = res_args.get("backup_name") + dest_created = res_args.get("dest_created") dest_data_set_attrs = res_args.get("dest_data_set_attrs") + updated_result = dict( dest=res_args.get("dest"), - is_binary=original_args.get("is_binary"), changed=res_args.get("changed"), invocation=dict(module_args=original_args), + dest_created=dest_created, ) + if src: - updated_result["src"] = original_args.get("src") + updated_result["src"] = src if note: updated_result["note"] = note if backup_name: @@ -3353,7 +3359,7 @@ def run_module(module, arg_def): fail_json Cannot write a partitioned data set (PDS) to a USS file. fail_json - Destination already exists on the system, unable to overwrite unless force=True is specified. + Destination already exists on the system, unable to overwrite unless replace=True is specified. fail_json Unable to allocate destination data set. """ @@ -3387,7 +3393,7 @@ def run_module(module, arg_def): dest = module.params.get('dest') remote_src = module.params.get('remote_src') is_binary = module.params.get('is_binary') - executable = module.params.get('executable') + is_executable = module.params.get('is_executable') asa_text = module.params.get('asa_text') aliases = module.params.get('aliases') backup = module.params.get('backup') @@ -3399,8 +3405,8 @@ def run_module(module, arg_def): encoding = module.params.get('encoding') volume = module.params.get('volume') tmphlq = module.params.get('tmp_hlq') + replace = module.params.get('replace') force = module.params.get('force') - force_lock = module.params.get('force_lock') content = module.params.get('content') identical_gdg_copy = module.params.get('identical_gdg_copy', False) @@ -3512,7 +3518,7 @@ def run_module(module, arg_def): # When the destination is a dataset, we'll normalize the source # file to UTF-8 for the record length computation as Python # generally uses UTF-8 as the default encoding. - if not is_binary and not is_uss and not executable: + if not is_binary and not is_uss and not is_executable: new_src = src new_src = os.path.normpath(new_src) # Normalizing encoding when src is a USS file (only). @@ -3597,7 +3603,7 @@ def run_module(module, arg_def): # dest_data_set.type overrides `dest_ds_type` given precedence rules if dest_data_set and dest_data_set.get("type"): dest_ds_type = dest_data_set.get("type").upper() - elif executable: + elif is_executable: # When executable is selected and dest_exists is false means an executable PDSE was copied to remote, # so we need to provide the correct dest_ds_type that will later be transformed into LIBRARY. # Not using LIBRARY at this step since there are many checks with dest_ds_type in data_set.DataSet.MVS_PARTITIONED @@ -3664,7 +3670,7 @@ def run_module(module, arg_def): src_member, is_src_dir, (src_ds_type == "USS" and src is None), - executable, + is_executable, asa_text, src_has_asa_chars, dest_has_asa_chars, @@ -3688,7 +3694,7 @@ def run_module(module, arg_def): # for try to write in dest and if both src and dest are in lock. # ******************************************************************** if dest_exists and dest_ds_type != "USS": - if not force_lock: + if not force: is_dest_lock = data_set.DataSetUtils.verify_dataset_disposition(data_set=data_set.extract_dsname(dest_name), disposition="old") if is_dest_lock: module.fail_json( @@ -3701,11 +3707,11 @@ def run_module(module, arg_def): # Alias support is not avaiable to and from USS for text-based data sets. # ******************************************************************** if aliases: - if (src_ds_type == 'USS' or dest_ds_type == 'USS') and not executable: + if (src_ds_type == 'USS' or dest_ds_type == 'USS') and not is_executable: module.fail_json( msg="Alias support for text-based data sets is not available " + "for USS sources (src) or targets (dest). " - + "Try setting executable=True or aliases=False." + + "Try setting is_executable=True or aliases=False." ) # ******************************************************************** @@ -3786,12 +3792,12 @@ def run_module(module, arg_def): dest_member_exists, dest_ds_type, is_uss, - force, + replace, volume, tmphlq ): module.fail_json( - msg="{0} already exists on the system, unable to overwrite unless force=True is specified.".format(raw_dest), + msg="{0} already exists on the system, unable to overwrite unless replace=True is specified.".format(raw_dest), changed=False, dest=dest ) @@ -3811,9 +3817,9 @@ def run_module(module, arg_def): src_ds_type, dest_ds_type, dest_exists, - force, + replace, is_binary, - executable, + is_executable, asa_text, is_dest_gds, is_dest_gds_active, @@ -3821,6 +3827,10 @@ def run_module(module, arg_def): volume=volume, tmphlq=tmphlq ) + if res_args["changed"]: + res_args["dest_created"] = True + else: + res_args["dest_created"] = False except Exception as err: if converted_src: src = original_src @@ -3843,10 +3853,10 @@ def run_module(module, arg_def): copy_handler = CopyHandler( module, is_binary=is_binary, - executable=executable, + is_executable=is_executable, asa_text=asa_text, backup_name=backup_name, - force_lock=force_lock, + force=force, identical_gdg_copy=module.params.get('identical_gdg_copy', False), tmphlq=tmphlq ) @@ -3864,14 +3874,14 @@ def run_module(module, arg_def): # --------------------------------------------------------------------- if is_uss: # Removing the carriage return characters - if src_ds_type == "USS" and not is_binary and not executable: + if src_ds_type == "USS" and not is_binary and not is_executable: new_src = conv_path or src if os.path.isfile(new_src): conv_path = copy_handler.remove_cr_endings(new_src) uss_copy_handler = USSCopyHandler( module, is_binary=is_binary, - executable=executable, + is_executable=is_executable, asa_text=asa_text, aliases=aliases, common_file_args=dict(mode=mode, group=group, owner=owner), @@ -3881,7 +3891,10 @@ def run_module(module, arg_def): original_checksum = None if dest_exists: + res_args["dest_created"] = False original_checksum = get_file_checksum(dest) + else: + res_args["dest_created"] = True dest = uss_copy_handler.copy_to_uss( src, @@ -3890,7 +3903,7 @@ def run_module(module, arg_def): src_ds_type, src_member, member_name, - force, + replace, bool(content) ) res_args['size'] = os.stat(dest).st_size @@ -3939,11 +3952,11 @@ def run_module(module, arg_def): pdse_copy_handler = PDSECopyHandler( module, is_binary=is_binary, - executable=executable, + is_executable=is_executable, asa_text=asa_text, aliases=aliases, backup_name=backup_name, - force_lock=force_lock, + force=force, tmphlq=tmphlq ) @@ -4002,7 +4015,7 @@ def main(): src=dict(type='str'), dest=dict(required=True, type='str'), is_binary=dict(type='bool', default=False), - executable=dict(type='bool', default=False), + is_executable=dict(type='bool', default=False), asa_text=dict(type='bool', default=False), aliases=dict(type='bool', default=False, required=False), identical_gdg_copy=dict(type='bool', default=False), @@ -4094,8 +4107,8 @@ def main(): autoescape=dict(type='bool', default=True), ) ), + replace=dict(type='bool', default=False), force=dict(type='bool', default=False), - force_lock=dict(type='bool', default=False), mode=dict(type='str', required=False), owner=dict(type='str', required=False), group=dict(type='str', required=False), @@ -4107,18 +4120,20 @@ def main(): src=dict(arg_type='data_set_or_path', required=False), dest=dict(arg_type='data_set_or_path', required=True), is_binary=dict(arg_type='bool', required=False, default=False), - executable=dict(arg_type='bool', required=False, default=False), + is_executable=dict(arg_type='bool', required=False, default=False), asa_text=dict(arg_type='bool', required=False, default=False), aliases=dict(arg_type='bool', required=False, default=False), + identical_gdg_copy=dict(type='bool', default=False), content=dict(arg_type='str', required=False), backup=dict(arg_type='bool', default=False, required=False), backup_name=dict(arg_type='data_set_or_path', required=False), local_follow=dict(arg_type='bool', default=True, required=False), remote_src=dict(arg_type='bool', default=False, required=False), - checksum=dict(arg_type='str', required=False), + ignore_sftp_stderr=dict(type='bool', default=True), validate=dict(arg_type='bool', required=False), volume=dict(arg_type='str', required=False), - force_lock=dict(type='bool', default=False), + replace=dict(type='bool', default=False), + force=dict(type='bool', default=False), dest_data_set=dict( arg_type='dict', @@ -4174,7 +4189,7 @@ def main(): not module.params.get("encoding").get("to") and not module.params.get("remote_src") and not module.params.get("is_binary") - and not module.params.get("executable") + and not module.params.get("is_executable") ): module.params["encoding"]["to"] = encode.Defaults.get_default_system_charset() elif ( @@ -4211,7 +4226,6 @@ def main(): shutil.rmtree(path) elif os.path.exists(default_path): shutil.rmtree(default_path) - res_args = update_result(res_args=res_args, original_args=module.params) module.exit_json(**res_args) except CopyOperationError as err: diff --git a/tests/functional/modules/test_zos_copy_func.py b/tests/functional/modules/test_zos_copy_func.py index a660d7576..3bfb1b14d 100644 --- a/tests/functional/modules/test_zos_copy_func.py +++ b/tests/functional/modules/test_zos_copy_func.py @@ -247,7 +247,7 @@ zos_copy: src: /etc/profile remote_src: True - force: True + replace: True dest: {3} async: 50 poll: 0 @@ -408,13 +408,13 @@ def link_loadlib_from_cobol(hosts, cobol_src_pds, cobol_src_mem, loadlib_pds, lo cp_res = hosts.all.zos_copy( content=LINK_JCL.format(cobol_src_pds, cobol_src_mem, loadlib_pds, loadlib_mem, loadlib_alias_mem), dest=temp_jcl_uss_path, - force=True, + replace=True, ) # Submit link JCL. job_result = hosts.all.zos_job_submit( src=temp_jcl_uss_path, - location="uss", - wait_time_s=60 + remote_src=True, + wait_time=60 ) for result in job_result.contacted.values(): print(result) @@ -462,8 +462,8 @@ def generate_loadlib(hosts, cobol_src_pds, cobol_src_mems, loadlib_pds, loadlib_ def generate_executable_uss(hosts, dir, src, src_jcl_call): - hosts.all.zos_copy(content=hello_world, dest=src, force=True) - hosts.all.zos_copy(content=call_c_hello_jcl.format(dir), dest=src_jcl_call, force=True) + hosts.all.zos_copy(content=hello_world, dest=src, replace=True) + hosts.all.zos_copy(content=call_c_hello_jcl.format(dir), dest=src_jcl_call, replace=True) hosts.all.shell(cmd="xlc -o hello_world hello_world.c", chdir=dir) hosts.all.shell(cmd="submit {0}".format(src_jcl_call)) verify_exe_src = hosts.all.shell(cmd="{0}/hello_world".format(dir)) @@ -496,10 +496,13 @@ def test_copy_file_to_non_existing_uss_file(ansible_zos_module, src): stat_res = hosts.all.stat(path=dest_path) for result in copy_res.contacted.values(): + print(result) assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest_path assert result.get("state") == "file" + assert result.get("src") is not None + assert result.get("dest_created") is not None for result in stat_res.contacted.values(): assert result.get("stat").get("exists") is True finally: @@ -508,12 +511,12 @@ def test_copy_file_to_non_existing_uss_file(ansible_zos_module, src): @pytest.mark.uss @pytest.mark.parametrize("src", [ - dict(src="/etc/profile", is_file=True, force=False, is_remote=False), - dict(src="/etc/profile", is_file=True, force=True, is_remote=False), - dict(src="Example inline content", is_file=False, force=False, is_remote=False), - dict(src="Example inline content", is_file=False, force=True, is_remote=False), - dict(src="/etc/profile", is_file=True, force=False, is_remote=True), - dict(src="/etc/profile", is_file=True, force=True, is_remote=True), + dict(src="/etc/profile", is_file=True, replace=False, is_remote=False), + dict(src="/etc/profile", is_file=True, replace=True, is_remote=False), + dict(src="Example inline content", is_file=False, replace=False, is_remote=False), + dict(src="Example inline content", is_file=False, replace=True, is_remote=False), + dict(src="/etc/profile", is_file=True, replace=False, is_remote=True), + dict(src="/etc/profile", is_file=True, replace=True, is_remote=True), ]) def test_copy_file_to_existing_uss_file(ansible_zos_module, src): hosts = ansible_zos_module @@ -526,18 +529,20 @@ def test_copy_file_to_existing_uss_file(ansible_zos_module, src): assert timestamp is not None if src["is_file"]: - copy_res = hosts.all.zos_copy(src=src["src"], dest=dest_path, force=src["force"], remote_src=src["is_remote"]) + copy_res = hosts.all.zos_copy(src=src["src"], dest=dest_path, replace=src["replace"], remote_src=src["is_remote"]) else: - copy_res = hosts.all.zos_copy(content=src["src"], dest=dest_path, force=src["force"]) + copy_res = hosts.all.zos_copy(content=src["src"], dest=dest_path, replace=src["replace"]) stat_res = hosts.all.stat(path=dest_path) for result in copy_res.contacted.values(): - if src["force"]: + if src["replace"]: assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest_path assert result.get("state") == "file" + assert result.get("src") is not None + assert result.get("dest_created") is not None else: assert result.get("msg") is not None assert result.get("changed") is False @@ -570,6 +575,8 @@ def test_copy_file_to_uss_dir(ansible_zos_module, src): assert result.get("changed") is True assert result.get("dest") == dest_path assert result.get("state") == "file" + assert result.get("src") is not None + assert result.get("dest_created") is not None for st in stat_res.contacted.values(): assert st.get("stat").get("exists") is True finally: @@ -592,7 +599,8 @@ def test_copy_file_to_uss_dir_missing_parents(ansible_zos_module): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest - assert result.get("state") == "file" + assert result.get("src") is not None + assert result.get("dest_created") is not None for st in stat_res.contacted.values(): assert st.get("stat").get("exists") is True finally: @@ -616,6 +624,11 @@ def test_copy_local_symlink_to_uss_file(ansible_zos_module): stat_res = hosts.all.stat(path=dest_path) for result in copy_res.contacted.values(): assert result.get("msg") is None + assert result.get("changed") is True + assert result.get("dest") is not None + assert result.get("state") == "file" + assert result.get("src") is not None + assert result.get("dest_created") is not None for result in stat_res.contacted.values(): assert result.get("stat").get("exists") is True for result in verify_copy.contacted.values(): @@ -642,6 +655,8 @@ def test_copy_local_file_to_uss_file_convert_encoding(ansible_zos_module): assert result.get("changed") is True assert result.get("dest") == dest_path assert result.get("state") == "file" + assert result.get("src") is not None + assert result.get("dest_created") is not None for result in stat_res.contacted.values(): assert result.get("stat").get("exists") is True finally: @@ -665,6 +680,8 @@ def test_copy_local_file_to_uss_file_with_absent_remote_tmp_dir(ansible_zos_modu assert result.get("changed") is True assert result.get("dest") == dest_path assert result.get("state") == "file" + assert result.get("src") is not None + assert result.get("dest_created") is not None for result in stat_res.contacted.values(): assert result.get("stat").get("exists") is True finally: @@ -685,6 +702,8 @@ def test_copy_inline_content_to_uss_dir(ansible_zos_module): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest_path + assert result.get("src") is not None + assert result.get("dest_created") is not None for result in stat_res.contacted.values(): assert result.get("stat").get("exists") is True finally: @@ -708,11 +727,10 @@ def test_copy_dir_to_existing_uss_dir_not_forced(ansible_zos_module): src=src_dir, dest=dest_dir, remote_src=True, - force=False + replace=False ) for result in copy_result.contacted.values(): - print(result) assert result.get("msg") is not None assert result.get("changed") is False assert "Error" in result.get("msg") @@ -799,6 +817,9 @@ def test_copy_subdirs_folders_and_validate_recursive_encoding(ansible_zos_module for result in copy_res.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True + assert result.get("dest") is not None + assert result.get("src") is not None + assert result.get("dest_created") is not None # File z/OS dest is now UTF-8, dump the hex value and compare it to an # expected big-endian version, can't run delegate_to local host so expected @@ -840,6 +861,9 @@ def test_copy_subdirs_folders_and_validate_recursive_encoding_local(ansible_zos_ for result in copy_res.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True + assert result.get("dest") is not None + assert result.get("src") is not None + assert result.get("dest_created") is not None full_outer_file= "{0}/{1}/file3".format(dest_path, level_1) full_iner_file= "{0}/{1}/{2}/file3".format(dest_path, level_1, level_2) @@ -847,10 +871,8 @@ def test_copy_subdirs_folders_and_validate_recursive_encoding_local(ansible_zos_ verify_copy_2 = hosts.all.shell(cmd="cat {0}".format(full_iner_file)) for result in verify_copy_1.contacted.values(): - print(result) assert result.get("stdout") == DUMMY_DATA for result in verify_copy_2.contacted.values(): - print(result) assert result.get("stdout") == DUMMY_DATA finally: hosts.all.file(name=dest_path, state="absent") @@ -888,6 +910,9 @@ def test_copy_local_dir_to_non_existing_dir(ansible_zos_module, copy_directory): for result in copy_result.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True + assert result.get("dest") is not None + assert result.get("src") is not None + assert result.get("dest_created") is not None if copy_directory: assert result.get("dest") == "{0}/{1}".format(dest_path, src_basename) @@ -938,6 +963,9 @@ def test_copy_uss_dir_to_non_existing_dir(ansible_zos_module, copy_directory): for result in copy_result.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True + assert result.get("dest") is not None + assert result.get("src") is not None + assert result.get("dest_created") is not None if copy_directory: assert result.get("dest") == "{0}/{1}".format(dest_dir, src_basename) @@ -981,7 +1009,7 @@ def test_copy_local_dir_to_existing_dir_forced(ansible_zos_module, copy_director copy_result = hosts.all.zos_copy( src=source_path, dest=dest_path, - force=True + replace=True ) stat_source_res = hosts.all.stat(path="{0}/{1}".format(dest_path, source_basename)) @@ -994,6 +1022,9 @@ def test_copy_local_dir_to_existing_dir_forced(ansible_zos_module, copy_director for result in copy_result.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True + assert result.get("dest") is not None + assert result.get("src") is not None + assert result.get("dest_created") is not None if copy_directory: assert result.get("dest") == "{0}/{1}".format(dest_path, source_basename) @@ -1042,7 +1073,7 @@ def test_copy_uss_dir_to_existing_dir_forced(ansible_zos_module, copy_directory) src=src_dir, dest=dest_dir, remote_src=True, - force=True + replace=True ) stat_dir_res = hosts.all.stat(path="{0}/{1}".format(dest_dir, src_basename)) @@ -1055,6 +1086,9 @@ def test_copy_uss_dir_to_existing_dir_forced(ansible_zos_module, copy_directory) for result in copy_result.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True + assert result.get("dest") is not None + assert result.get("src") is not None + assert result.get("dest_created") is not None if copy_directory: assert result.get("dest") == "{0}/{1}".format(dest_dir, src_basename) @@ -1105,7 +1139,7 @@ def test_copy_local_nested_dir_to_uss(ansible_zos_module, create_dest): copy_result = hosts.all.zos_copy( src=source_path, dest=dest_path, - force=create_dest + replace=create_dest ) stat_subdir_a_res = hosts.all.stat(path="{0}/subdir_a".format(dest_path)) @@ -1115,6 +1149,8 @@ def test_copy_local_nested_dir_to_uss(ansible_zos_module, create_dest): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest_path + assert result.get("src") is not None + assert result.get("dest_created") is not None for result in stat_subdir_a_res.contacted.values(): assert result.get("stat").get("exists") is True assert result.get("stat").get("isdir") is True @@ -1147,7 +1183,7 @@ def test_copy_uss_nested_dir_to_uss(ansible_zos_module, create_dest): src=source_path, dest=dest_path, remote_src=True, - force=create_dest + replace=create_dest ) stat_subdir_a_res = hosts.all.stat(path="{0}/subdir_a".format(dest_path)) @@ -1157,6 +1193,8 @@ def test_copy_uss_nested_dir_to_uss(ansible_zos_module, create_dest): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest_path + assert result.get("src") is not None + assert result.get("dest_created") is not None for result in stat_subdir_a_res.contacted.values(): assert result.get("stat").get("exists") is True assert result.get("stat").get("isdir") is True @@ -1202,7 +1240,7 @@ def test_copy_local_dir_and_change_mode(ansible_zos_module, copy_directory): copy_result = hosts.all.zos_copy( src=source_path, dest=dest_path, - force=True, + replace=True, mode=mode ) @@ -1218,6 +1256,9 @@ def test_copy_local_dir_and_change_mode(ansible_zos_module, copy_directory): for result in copy_result.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True + assert result.get("dest") is not None + assert result.get("src") is not None + assert result.get("dest_created") is not None if copy_directory: assert result.get("dest") == dest_subdir @@ -1295,7 +1336,7 @@ def test_copy_uss_dir_and_change_mode(ansible_zos_module, copy_directory): copy_result = hosts.all.zos_copy( src=source_path, dest=dest_path, - force=True, + replace=True, remote_src=True, mode=mode ) @@ -1312,6 +1353,9 @@ def test_copy_uss_dir_and_change_mode(ansible_zos_module, copy_directory): for result in copy_result.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True + assert result.get("dest") is not None + assert result.get("src") is not None + assert result.get("dest_created") is not None if copy_directory: assert result.get("dest") == dest_subdir @@ -1370,13 +1414,17 @@ def test_backup_uss_file(ansible_zos_module, backup): if backup: backup_name = get_random_file_name(dir=TMP_DIRECTORY) - copy_res = hosts.all.zos_copy(src=src, dest=dest, force=True, backup=True, backup_name=backup_name) + copy_res = hosts.all.zos_copy(src=src, dest=dest, replace=True, backup=True, backup_name=backup_name) else: - copy_res = hosts.all.zos_copy(src=src, dest=dest, force=True, backup=True) + copy_res = hosts.all.zos_copy(src=src, dest=dest, replace=True, backup=True) for result in copy_res.contacted.values(): assert result.get("msg") is None backup_name_result = result.get("backup_name") + assert result.get("changed") is True + assert result.get("dest") is not None + assert result.get("src") is not None + assert result.get("dest_created") is not None if backup: assert backup_name_result == backup_name @@ -1474,6 +1522,8 @@ def test_copy_template_file(ansible_zos_module, encoding): assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert cp_res.get("dest") == dest_template + assert cp_res.get("src") is not None + assert cp_res.get("dest_created") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 # Checking that all markers got replaced. @@ -1534,7 +1584,7 @@ def test_copy_template_dir(ansible_zos_module): src=temp_dir, dest=dest_path, use_template=True, - force=True + replace=True ) verify_copy_a = hosts.all.shell( @@ -1550,6 +1600,8 @@ def test_copy_template_dir(ansible_zos_module): assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert cp_res.get("dest") == dest_path + assert cp_res.get("src") is not None + assert cp_res.get("dest_created") is not None for v_cp in verify_copy_a.contacted.values(): assert v_cp.get("rc") == 0 # Checking that all markers got replaced. @@ -1620,6 +1672,8 @@ def test_copy_template_file_with_non_default_markers(ansible_zos_module): assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert cp_res.get("dest") == dest_template + assert cp_res.get("src") is not None + assert cp_res.get("dest_created") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 # Checking that all markers got replaced. @@ -1671,6 +1725,8 @@ def test_copy_template_file_to_dataset(ansible_zos_module): assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert cp_res.get("dest") == dest_dataset + assert cp_res.get("src") is not None + assert cp_res.get("dest_created") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 # Checking that all markers got replaced. @@ -1719,6 +1775,7 @@ def test_copy_asa_file_to_asa_sequential(ansible_zos_module): assert cp_res.get("changed") is True assert cp_res.get("dest") == dest assert cp_res.get("dest_created") is True + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 assert v_cp.get("stdout") == ASA_SAMPLE_RETURN @@ -1754,11 +1811,11 @@ def test_copy_asa_file_to_asa_partitioned(ansible_zos_module): ) for cp_res in copy_result.contacted.values(): - print(cp_res) assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert cp_res.get("dest") == full_dest assert cp_res.get("dest_created") is True + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): print(v_cp) assert v_cp.get("rc") == 0 @@ -1813,6 +1870,7 @@ def test_copy_seq_data_set_to_seq_asa(ansible_zos_module): assert cp_res.get("changed") is True assert cp_res.get("dest") == dest assert cp_res.get("dest_created") is True + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 assert v_cp.get("stdout") == ASA_SAMPLE_RETURN @@ -1869,6 +1927,7 @@ def test_copy_seq_data_set_to_partitioned_asa(ansible_zos_module): assert cp_res.get("changed") is True assert cp_res.get("dest") == full_dest assert cp_res.get("dest_created") is True + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 assert v_cp.get("stdout") == ASA_SAMPLE_RETURN @@ -1925,6 +1984,7 @@ def test_copy_partitioned_data_set_to_seq_asa(ansible_zos_module): assert cp_res.get("changed") is True assert cp_res.get("dest") == dest assert cp_res.get("dest_created") is True + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 assert v_cp.get("stdout") == ASA_SAMPLE_RETURN @@ -1982,6 +2042,7 @@ def test_copy_partitioned_data_set_to_partitioned_asa(ansible_zos_module): assert cp_res.get("changed") is True assert cp_res.get("dest") == full_dest assert cp_res.get("dest_created") is True + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 assert v_cp.get("stdout") == ASA_SAMPLE_RETURN @@ -2033,6 +2094,8 @@ def test_copy_asa_data_set_to_text_file(ansible_zos_module): assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert cp_res.get("dest") == dest + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 # Since OPUT preserves all blank spaces associated @@ -2058,9 +2121,16 @@ def test_ensure_copy_file_does_not_change_permission_on_dest(ansible_zos_module, try: hosts.all.file(path=dest_path, state="directory", mode=mode) permissions_before = hosts.all.stat(path=dest_path) - hosts.all.zos_copy(src=src["src"], dest=dest_path, mode=other_mode) + cp_bef_result = hosts.all.zos_copy(src=src["src"], dest=dest_path, mode=other_mode) permissions = hosts.all.stat(path=dest_path) + for cp_res in cp_bef_result.contacted.values(): + assert cp_res.get("msg") is None + assert cp_res.get("changed") is True + assert cp_res.get("dest") is not None + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None + for before in permissions_before.contacted.values(): permissions_be_copy = before.get("stat").get("mode") @@ -2070,7 +2140,15 @@ def test_ensure_copy_file_does_not_change_permission_on_dest(ansible_zos_module, assert permissions_be_copy == permissions_af_copy # Extra asserts to ensure change mode rewrite a copy - hosts.all.zos_copy(src=src["src"], dest=dest_path, mode=mode_overwrite) + af_bef_result = hosts.all.zos_copy(src=src["src"], dest=dest_path, mode=mode_overwrite) + + for cp_res in af_bef_result.contacted.values(): + assert cp_res.get("msg") is None + assert cp_res.get("changed") is False + assert cp_res.get("dest") is not None + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None + permissions_overwriten = hosts.all.stat(path = full_path) for over in permissions_overwriten.contacted.values(): assert over.get("stat").get("mode") == mode_overwrite @@ -2079,7 +2157,7 @@ def test_ensure_copy_file_does_not_change_permission_on_dest(ansible_zos_module, @pytest.mark.seq -@pytest.mark.parametrize("ds_type, f_lock",[ +@pytest.mark.parametrize("ds_type, force",[ ("pds", True), # Success path, pds locked, force_lock enabled and user authorized ("pdse", True), # Success path, pdse locked, force_lock enabled and user authorized ("seq", True), # Success path, seq locked, force_lock enabled and user authorized @@ -2087,7 +2165,7 @@ def test_ensure_copy_file_does_not_change_permission_on_dest(ansible_zos_module, ("pdse", False), # Module exits with: Unable to write to dest '{0}' because a task is accessing the data set." ("seq", False), # Module exits with: Unable to write to dest '{0}' because a task is accessing the data set." ]) -def test_copy_dest_lock_wrapper(ansible_zos_module, ds_type, f_lock): +def test_copy_dest_lock_wrapper(ansible_zos_module, ds_type, force): retries = 0 max_retries = 5 success = False @@ -2095,8 +2173,8 @@ def test_copy_dest_lock_wrapper(ansible_zos_module, ds_type, f_lock): # Not adding a try/except block here so a real exception can bubble up # and stop pytest immediately (if using -x or --stop). while retries < max_retries: - print(f'Trying dest lock for {ds_type}. Expecting success? {f_lock}. Retry: {retries}.') - result = copy_dest_lock(ansible_zos_module, ds_type, f_lock) + print(f'Trying dest lock for {ds_type}. Expecting success? {force}. Retry: {retries}.') + result = copy_dest_lock(ansible_zos_module, ds_type, force) if result: success = True @@ -2107,7 +2185,7 @@ def test_copy_dest_lock_wrapper(ansible_zos_module, ds_type, f_lock): assert success is True -def copy_dest_lock(ansible_zos_module, ds_type, f_lock): +def copy_dest_lock(ansible_zos_module, ds_type, force): hosts = ansible_zos_module assert_msg = "" @@ -2177,34 +2255,38 @@ def copy_dest_lock(ansible_zos_module, ds_type, f_lock): decho_result = hosts.all.shell(cmd="decho \"{0}\" \"{1}\"".format(DUMMY_DATA, src_data_set)) for result in decho_result.contacted.values(): assert_msg = result.get("stdout", "") - print(result) assert result.get("changed") is True assert result.get("failed", False) is False # copy/compile c program and copy jcl to hold data set lock for n seconds in background(&) temp_dir = get_random_file_name(dir=TMP_DIRECTORY) - c_src_result = hosts.all.zos_copy(content=c_pgm, dest=f'{temp_dir}/pdse-lock.c', force=True) + c_src_result = hosts.all.zos_copy(content=c_pgm, dest=f'{temp_dir}/pdse-lock.c', replace=True) for result in c_src_result.contacted.values(): assert_msg = result.get("stdout", "") - print(result) assert result.get("changed") is True assert result.get("failed", False) is False + assert result.get("msg") is None + assert result.get("dest") is not None + assert result.get("dest_created") is not None + assert result.get("src") is not None jcl_result = hosts.all.zos_copy( content=call_c_jcl.format(temp_dir, dest_data_set), dest=f'{temp_dir}/call_c_pgm.jcl', - force=True + replace=True ) for result in jcl_result.contacted.values(): assert_msg = result.get("stdout", "") - print(result) - assert result.get("changed") is True assert result.get("failed", False) is False + assert result.get("msg") is None + assert result.get("changed") is True + assert result.get("dest") is not None + assert result.get("dest_created") is not None + assert result.get("src") is not None subproc_result = hosts.all.shell(cmd="xlc -o pdse-lock pdse-lock.c", chdir=f"{temp_dir}/") for result in subproc_result.contacted.values(): assert_msg = result.get("stdout", "") - print(result) assert result.get("changed") is True assert result.get("failed", False) is False @@ -2212,7 +2294,6 @@ def copy_dest_lock(ansible_zos_module, ds_type, f_lock): job_result = hosts.all.shell(cmd="submit call_c_pgm.jcl", chdir=f"{temp_dir}/") for result in job_result.contacted.values(): assert_msg = result.get("stdout", "") - print(result) assert result.get("changed") is True assert result.get("failed", False) is False @@ -2222,23 +2303,25 @@ def copy_dest_lock(ansible_zos_module, ds_type, f_lock): src = src_data_set, dest = dest_data_set, remote_src = True, - force=True, - force_lock=f_lock, + replace=True, + force=force, ) for result in results.contacted.values(): assert_msg = result.get("stdout", "") - print(result) - if f_lock: #and apf_auth_user: + if force: #and apf_auth_user: + print(result) assert result.get("changed") == True assert result.get("msg") is None + assert result.get("dest") is not None + assert result.get("dest_created") is not None + assert result.get("src") is not None # verify that the content is the same verify_copy = hosts.all.shell( cmd="dcat \'{0}\'".format(dest_data_set), executable=SHELL_EXECUTABLE, ) for vp_result in verify_copy.contacted.values(): - print(vp_result) verify_copy_2 = hosts.all.shell( cmd="dcat \'{0}\'".format(src_data_set), executable=SHELL_EXECUTABLE, @@ -2246,7 +2329,7 @@ def copy_dest_lock(ansible_zos_module, ds_type, f_lock): for vp_result_2 in verify_copy_2.contacted.values(): print(vp_result_2) assert vp_result_2.get("stdout") == vp_result.get("stdout") - elif not f_lock: + elif not force: assert result.get("failed") is True assert result.get("changed") == False assert "because a task is accessing the data set" in result.get("msg") @@ -2256,7 +2339,7 @@ def copy_dest_lock(ansible_zos_module, ds_type, f_lock): except AssertionError: # Checking for the error code from when the system thinks both data sets # are identical. - if "FSUM8977" in assert_msg: + if "FSUM8977" in str(assert_msg): return False else: raise @@ -2277,7 +2360,7 @@ def copy_dest_lock(ansible_zos_module, ds_type, f_lock): @pytest.mark.seq @pytest.mark.pdse @pytest.mark.asa -@pytest.mark.parametrize("ds_type, f_lock",[ +@pytest.mark.parametrize("ds_type, force",[ ("pds", True), # Success path, pds locked, force_lock enabled and user authorized ("pdse", True), # Success path, pdse locked, force_lock enabled and user authorized ("seq", True), # Success path, seq locked, force_lock enabled and user authorized @@ -2285,7 +2368,7 @@ def copy_dest_lock(ansible_zos_module, ds_type, f_lock): ("pdse", False), # Module exits with: Unable to write to dest '{0}' because a task is accessing the data set." ("seq", False), # Module exits with: Unable to write to dest '{0}' because a task is accessing the data set." ]) -def test_copy_dest_lock_wrapper_asa(ansible_zos_module, ds_type, f_lock): +def test_copy_dest_lock_wrapper_asa(ansible_zos_module, ds_type, force): retries = 0 max_retries = 5 success = False @@ -2293,8 +2376,8 @@ def test_copy_dest_lock_wrapper_asa(ansible_zos_module, ds_type, f_lock): # Not adding a try/except block here so a real exception can bubble up # and stop pytest immediately (if using -x or --stop). while retries < max_retries: - print(f'Trying dest lock for {ds_type}. Expecting success? {f_lock}. Retry: {retries}.') - result = copy_asa_dest_lock(ansible_zos_module, ds_type, f_lock) + print(f'Trying dest lock for {ds_type}. Expecting success? {force}. Retry: {retries}.') + result = copy_asa_dest_lock(ansible_zos_module, ds_type, force) if result: success = True @@ -2305,7 +2388,7 @@ def test_copy_dest_lock_wrapper_asa(ansible_zos_module, ds_type, f_lock): assert success is True -def copy_asa_dest_lock(ansible_zos_module, ds_type, f_lock): +def copy_asa_dest_lock(ansible_zos_module, ds_type, force): hosts = ansible_zos_module assert_msg = "" @@ -2348,23 +2431,30 @@ def copy_asa_dest_lock(ansible_zos_module, ds_type, f_lock): # copy/compile c program and copy jcl to hold data set lock for n seconds in background(&) temp_dir = get_random_file_name(dir=TMP_DIRECTORY) - c_src_result = hosts.all.zos_copy(content=c_pgm, dest=f'{temp_dir}/pdse-lock.c', force=True) + c_src_result = hosts.all.zos_copy(content=c_pgm, dest=f'{temp_dir}/pdse-lock.c', replace=True) for result in c_src_result.contacted.values(): assert_msg = result.get("stdout", "") - print(result) assert result.get("changed") is True assert result.get("failed", False) is False + assert result.get("msg") is None + assert result.get("dest") is not None + assert result.get("dest_created") is not None + assert result.get("src") is not None jcl_result = hosts.all.zos_copy( content=call_c_jcl.format(temp_dir, dest_data_set), dest=f'{temp_dir}/call_c_pgm.jcl', - force=True + replace=True ) for result in jcl_result.contacted.values(): assert_msg = result.get("stdout", "") print(result) assert result.get("changed") is True assert result.get("failed", False) is False + assert result.get("msg") is None + assert result.get("dest") is not None + assert result.get("dest_created") is not None + assert result.get("src") is not None subproc_result = hosts.all.shell(cmd="xlc -o pdse-lock pdse-lock.c", chdir=f"{temp_dir}/") for result in subproc_result.contacted.values(): @@ -2389,16 +2479,19 @@ def copy_asa_dest_lock(ansible_zos_module, ds_type, f_lock): dest=dest_data_set, remote_src=False, asa_text=True, - force=True, - force_lock=f_lock + replace=True, + force=force ) for result in results.contacted.values(): assert_msg = result.get("stdout", "") print(result) - if f_lock: #and apf_auth_user: + if force: #and apf_auth_user: assert result.get("changed") is True assert result.get("msg") is None + assert result.get("dest") is not None + assert result.get("dest_created") is not None + assert result.get("src") is not None # We need to escape the data set name because we are using cat, using dcat will # bring the trailing empty spaces according to the data set record length. @@ -2474,6 +2567,8 @@ def test_copy_file_record_length_to_sequential_data_set(ansible_zos_module): assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert cp_res.get("dest") == dest + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 for v_recl in verify_recl.contacted.values(): @@ -2527,6 +2622,8 @@ def test_copy_file_crlf_endings_to_sequential_data_set(ansible_zos_module): assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert cp_res.get("dest") == dest + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 assert len(v_cp.get("stdout_lines")) == 2 @@ -2585,6 +2682,8 @@ def test_copy_file_crlf_endings_and_pound_to_seq_data_set(ansible_zos_module): assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert cp_res.get("dest") == dest + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): print(v_cp) assert v_cp.get("rc") == 0 @@ -2630,6 +2729,8 @@ def test_copy_local_binary_file_without_encoding_conversion(ansible_zos_module): assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert cp_res.get("dest") == dest + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None finally: hosts.all.zos_data_set(name=dest, state="absent") os.remove(src) @@ -2672,6 +2773,8 @@ def test_copy_remote_binary_file_without_encoding_conversion(ansible_zos_module) assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert cp_res.get("dest") == dest + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None finally: hosts.all.zos_data_set(name=dest, state="absent") hosts.all.file(path=src, state="absent") @@ -2709,7 +2812,7 @@ def test_copy_file_to_non_existing_sequential_data_set(ansible_zos_module, src): assert cp_res.get("changed") is True assert cp_res.get("dest") == dest assert cp_res.get("dest_created") is True - assert cp_res.get("is_binary") == src["is_binary"] + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 finally: @@ -2719,12 +2822,12 @@ def test_copy_file_to_non_existing_sequential_data_set(ansible_zos_module, src): @pytest.mark.uss @pytest.mark.seq @pytest.mark.parametrize("src", [ - dict(src="/etc/profile", is_file=True, force=True, is_remote=False), - dict(src="Example inline content", is_file=False, force=True, is_remote=False), - dict(src="/etc/profile", is_file=True, force=True, is_remote=True), - dict(src="/etc/profile", is_file=True, force=False, is_remote=False), - dict(src="Example inline content", is_file=False, force=False, is_remote=False), - dict(src="/etc/profile", is_file=True, force=False, is_remote=True), + dict(src="/etc/profile", is_file=True, replace=True, is_remote=False), + dict(src="Example inline content", is_file=False, replace=True, is_remote=False), + dict(src="/etc/profile", is_file=True, replace=True, is_remote=True), + dict(src="/etc/profile", is_file=True, replace=False, is_remote=False), + dict(src="Example inline content", is_file=False, replace=False, is_remote=False), + dict(src="/etc/profile", is_file=True, replace=False, is_remote=True), ]) def test_copy_file_to_empty_sequential_data_set(ansible_zos_module, src): hosts = ansible_zos_module @@ -2734,14 +2837,16 @@ def test_copy_file_to_empty_sequential_data_set(ansible_zos_module, src): hosts.all.zos_data_set(name=dest, type="seq", state="present") if src["is_file"]: - copy_result = hosts.all.zos_copy(src=src["src"], dest=dest, remote_src=src["is_remote"], force=src["force"]) + copy_result = hosts.all.zos_copy(src=src["src"], dest=dest, remote_src=src["is_remote"], replace=src["replace"]) else: - copy_result = hosts.all.zos_copy(content=src["src"], dest=dest, remote_src=src["is_remote"], force=src["force"]) + copy_result = hosts.all.zos_copy(content=src["src"], dest=dest, remote_src=src["is_remote"], replace=src["replace"]) for result in copy_result.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest + assert result.get("dest_created") is not None + assert result.get("src") is not None finally: hosts.all.zos_data_set(name=dest, state="absent") @@ -2749,10 +2854,10 @@ def test_copy_file_to_empty_sequential_data_set(ansible_zos_module, src): @pytest.mark.uss @pytest.mark.seq @pytest.mark.parametrize("src", [ - dict(src="/etc/profile", force=False, is_remote=False), - dict(src="/etc/profile", force=True, is_remote=False), - dict(src="/etc/profile", force=False, is_remote=True), - dict(src="/etc/profile", force=True, is_remote=True), + dict(src="/etc/profile", replace=False, is_remote=False), + dict(src="/etc/profile", replace=True, is_remote=False), + dict(src="/etc/profile", replace=False, is_remote=True), + dict(src="/etc/profile", replace=True, is_remote=True), ]) def test_copy_file_to_non_empty_sequential_data_set(ansible_zos_module, src): hosts = ansible_zos_module @@ -2762,13 +2867,15 @@ def test_copy_file_to_non_empty_sequential_data_set(ansible_zos_module, src): hosts.all.zos_data_set(name=dest, type="seq", state="absent") hosts.all.zos_copy(content="Inline content", dest=dest) - copy_result = hosts.all.zos_copy(src=src["src"], dest=dest, remote_src=src["is_remote"], force=src["force"]) + copy_result = hosts.all.zos_copy(src=src["src"], dest=dest, remote_src=src["is_remote"], replace=src["replace"]) for result in copy_result.contacted.values(): - if src["force"]: + if src["replace"]: assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest + assert result.get("dest_created") is not None + assert result.get("src") is not None else: assert result.get("msg") is not None assert result.get("changed") is False @@ -2795,6 +2902,8 @@ def test_copy_ps_to_non_existing_uss_file(ansible_zos_module): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest + assert result.get("dest_created") is not None + assert result.get("src") is not None for result in stat_res.contacted.values(): assert result.get("stat").get("exists") is True for result in verify_copy.contacted.values(): @@ -2807,8 +2916,8 @@ def test_copy_ps_to_non_existing_uss_file(ansible_zos_module): @pytest.mark.uss @pytest.mark.seq -@pytest.mark.parametrize("force", [False, True]) -def test_copy_ps_to_existing_uss_file(ansible_zos_module, force): +@pytest.mark.parametrize("replace", [False, True]) +def test_copy_ps_to_existing_uss_file(ansible_zos_module, replace): hosts = ansible_zos_module src_ds = get_tmp_ds_name() dest = get_random_file_name(dir=TMP_DIRECTORY) @@ -2818,17 +2927,19 @@ def test_copy_ps_to_existing_uss_file(ansible_zos_module, force): hosts.all.file(path=dest, state="touch") hosts.all.shell(cmd=f"decho 'test line' '{src_ds}' ") - copy_res = hosts.all.zos_copy(src=src_ds, dest=dest, remote_src=True, force=force) + copy_res = hosts.all.zos_copy(src=src_ds, dest=dest, remote_src=True, replace=replace) stat_res = hosts.all.stat(path=dest) verify_copy = hosts.all.shell( cmd="cat {0}".format(dest), executable=SHELL_EXECUTABLE ) for result in copy_res.contacted.values(): - if force: + if replace: assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest + assert result.get("dest_created") is not None + assert result.get("src") is not None else: assert result.get("msg") is not None assert result.get("changed") is False @@ -2861,6 +2972,9 @@ def test_copy_ps_to_existing_uss_dir(ansible_zos_module): for result in copy_res.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True + assert result.get("dest") is not None + assert result.get("dest_created") is not None + assert result.get("src") is not None for result in stat_res.contacted.values(): assert result.get("stat").get("exists") is True for result in verify_copy.contacted.values(): @@ -2888,6 +3002,7 @@ def test_copy_ps_to_non_existing_ps(ansible_zos_module): assert result.get("changed") is True assert result.get("dest") == dest assert result.get("dest_created") is True + assert result.get("src") is not None for result in verify_copy.contacted.values(): assert result.get("rc") == 0 assert result.get("stdout") != "" @@ -2896,8 +3011,8 @@ def test_copy_ps_to_non_existing_ps(ansible_zos_module): @pytest.mark.seq -@pytest.mark.parametrize("force", [False, True]) -def test_copy_ps_to_empty_ps(ansible_zos_module, force): +@pytest.mark.parametrize("replace", [False, True]) +def test_copy_ps_to_empty_ps(ansible_zos_module, replace): hosts = ansible_zos_module src_ds = get_tmp_ds_name() dest = get_tmp_ds_name() @@ -2906,7 +3021,7 @@ def test_copy_ps_to_empty_ps(ansible_zos_module, force): hosts.all.shell(cmd=f"decho 'test line ' '{src_ds}'") hosts.all.shell(cmd=f"dtouch -tseq '{src_ds}'") - copy_res = hosts.all.zos_copy(src=src_ds, dest=dest, remote_src=True, force=force) + copy_res = hosts.all.zos_copy(src=src_ds, dest=dest, remote_src=True, replace=replace) verify_copy = hosts.all.shell( cmd="cat \"//'{0}'\"".format(dest), executable=SHELL_EXECUTABLE ) @@ -2915,6 +3030,8 @@ def test_copy_ps_to_empty_ps(ansible_zos_module, force): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest + assert result.get("dest_created") is not None + assert result.get("src") is not None for result in verify_copy.contacted.values(): assert result.get("rc") == 0 assert result.get("stdout") != "" @@ -2923,8 +3040,8 @@ def test_copy_ps_to_empty_ps(ansible_zos_module, force): @pytest.mark.seq -@pytest.mark.parametrize("force", [False, True]) -def test_copy_ps_to_non_empty_ps(ansible_zos_module, force): +@pytest.mark.parametrize("replace", [False, True]) +def test_copy_ps_to_non_empty_ps(ansible_zos_module, replace): hosts = ansible_zos_module src_ds = get_tmp_ds_name() dest = get_tmp_ds_name() @@ -2933,16 +3050,18 @@ def test_copy_ps_to_non_empty_ps(ansible_zos_module, force): hosts.all.shell(cmd=f"decho 'This is a test ' '{src_ds}' ") hosts.all.shell(cmd=f"decho 'This is a test ' '{dest}' ") - copy_res = hosts.all.zos_copy(src=src_ds, dest=dest, remote_src=True, force=force) + copy_res = hosts.all.zos_copy(src=src_ds, dest=dest, remote_src=True, replace=replace) verify_copy = hosts.all.shell( cmd="cat \"//'{0}'\"".format(dest), executable=SHELL_EXECUTABLE ) for result in copy_res.contacted.values(): - if force: + if replace: assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest + assert result.get("dest_created") is not None + assert result.get("src") is not None else: assert result.get("msg") is not None assert result.get("changed") is False @@ -2955,8 +3074,8 @@ def test_copy_ps_to_non_empty_ps(ansible_zos_module, force): @pytest.mark.seq -@pytest.mark.parametrize("force", [False, True]) -def test_copy_ps_to_non_empty_ps_with_special_chars(ansible_zos_module, force): +@pytest.mark.parametrize("replace", [False, True]) +def test_copy_ps_to_non_empty_ps_with_special_chars(ansible_zos_module, replace): hosts = ansible_zos_module src_ds = get_tmp_ds_name() dest = get_tmp_ds_name() @@ -2965,16 +3084,18 @@ def test_copy_ps_to_non_empty_ps_with_special_chars(ansible_zos_module, force): hosts.all.shell(cmd=f"decho '{DUMMY_DATA_SPECIAL_CHARS}' '{src_ds}' ") hosts.all.shell(cmd=f"decho '{DUMMY_DATA_SPECIAL_CHARS}' '{dest}' ") - copy_res = hosts.all.zos_copy(src=src_ds, dest=dest, remote_src=True, force=force) + copy_res = hosts.all.zos_copy(src=src_ds, dest=dest, remote_src=True, replace=replace) verify_copy = hosts.all.shell( cmd="cat \"//'{0}'\"".format(dest), executable=SHELL_EXECUTABLE ) for result in copy_res.contacted.values(): - if force: + if replace: assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest + assert result.get("dest_created") is not None + assert result.get("src") is not None else: assert result.get("msg") is not None assert result.get("changed") is False @@ -2997,13 +3118,17 @@ def test_backup_sequential_data_set(ansible_zos_module, backup): if backup: backup_name = get_tmp_ds_name() - copy_res = hosts.all.zos_copy(src=src, dest=dest, force=True, backup=True, backup_name=backup_name) + copy_res = hosts.all.zos_copy(src=src, dest=dest, replace=True, backup=True, backup_name=backup_name) else: - copy_res = hosts.all.zos_copy(src=src, dest=dest, force=True, backup=True) + copy_res = hosts.all.zos_copy(src=src, dest=dest, replace=True, backup=True) for result in copy_res.contacted.values(): assert result.get("msg") is None assert result.get("backup_name") is not None + assert result.get("changed") is True + assert result.get("dest") is not None + assert result.get("dest_created") is not None + assert result.get("src") is not None result_backup_name = result.get("backup_name") if backup: assert backup_name == result.get("backup_name") @@ -3063,6 +3188,8 @@ def test_copy_file_to_non_existing_member(ansible_zos_module, src): assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert cp_res.get("dest") == dest + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 finally: @@ -3103,6 +3230,8 @@ def test_copy_file_to_non_existing_member_implicit(ansible_zos_module): assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert cp_res.get("dest") == dest_member + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 finally: @@ -3112,12 +3241,12 @@ def test_copy_file_to_non_existing_member_implicit(ansible_zos_module): @pytest.mark.uss @pytest.mark.pdse @pytest.mark.parametrize("src", [ - dict(src="/etc/profile", is_file=True, force=False, is_remote=False), - dict(src="/etc/profile", is_file=True, force=True, is_remote=False), - dict(src="Example inline content", is_file=False, force=False, is_remote=False), - dict(src="Example inline content", is_file=False, force=True, is_remote=False), - dict(src="/etc/profile", is_file=True, force=False, is_remote=True), - dict(src="/etc/profile", is_file=True, force=True, is_remote=True) + dict(src="/etc/profile", is_file=True, replace=False, is_remote=False), + dict(src="/etc/profile", is_file=True, replace=True, is_remote=False), + dict(src="Example inline content", is_file=False, replace=False, is_remote=False), + dict(src="Example inline content", is_file=False, replace=True, is_remote=False), + dict(src="/etc/profile", is_file=True, replace=False, is_remote=True), + dict(src="/etc/profile", is_file=True, replace=True, is_remote=True) ]) def test_copy_file_to_existing_member(ansible_zos_module, src): hosts = ansible_zos_module @@ -3137,9 +3266,9 @@ def test_copy_file_to_existing_member(ansible_zos_module, src): hosts.all.zos_data_set(name=dest, type="member", state="present") if src["is_file"]: - copy_result = hosts.all.zos_copy(src=src["src"], dest=dest, force=src["force"], remote_src=src["is_remote"]) + copy_result = hosts.all.zos_copy(src=src["src"], dest=dest, replace=src["replace"], remote_src=src["is_remote"]) else: - copy_result = hosts.all.zos_copy(content=src["src"], dest=dest, force=src["force"]) + copy_result = hosts.all.zos_copy(content=src["src"], dest=dest, replace=src["replace"]) verify_copy = hosts.all.shell( cmd="cat \"//'{0}'\" > /dev/null 2>/dev/null".format(dest), @@ -3147,10 +3276,12 @@ def test_copy_file_to_existing_member(ansible_zos_module, src): ) for cp_res in copy_result.contacted.values(): - if src["force"]: + if src["replace"]: assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert cp_res.get("dest") == dest + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None else: assert cp_res.get("msg") is not None assert cp_res.get("changed") is False @@ -3199,6 +3330,8 @@ def test_copy_data_set_to_non_existing_member(ansible_zos_module, args): assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert cp_res.get("dest") == dest + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 assert v_cp.get("stdout") != "" @@ -3210,12 +3343,12 @@ def test_copy_data_set_to_non_existing_member(ansible_zos_module, args): @pytest.mark.seq @pytest.mark.pdse @pytest.mark.parametrize("args", [ - dict(type="seq", force=False), - dict(type="seq", force=True), - dict(type="pds", force=False), - dict(type="pds", force=True), - dict(type="pdse", force=False), - dict(type="pdse", force=True) + dict(type="seq", replace=False), + dict(type="seq", replace=True), + dict(type="pds", replace=False), + dict(type="pds", replace=True), + dict(type="pdse", replace=False), + dict(type="pdse", replace=True) ]) def test_copy_data_set_to_existing_member(ansible_zos_module, args): hosts = ansible_zos_module @@ -3236,7 +3369,7 @@ def test_copy_data_set_to_existing_member(ansible_zos_module, args): hosts.all.zos_data_set(name=dest_data_set, type="pdse", replace=True) hosts.all.zos_data_set(name=dest, type="member") - copy_result = hosts.all.zos_copy(src=src, dest=dest, force=args["force"], remote_src=True) + copy_result = hosts.all.zos_copy(src=src, dest=dest, replace=args["replace"], remote_src=True) verify_copy = hosts.all.shell( cmd="cat \"//'{0}'\"".format(dest), @@ -3244,16 +3377,18 @@ def test_copy_data_set_to_existing_member(ansible_zos_module, args): ) for cp_res in copy_result.contacted.values(): - if args["force"]: + if args["replace"]: assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert cp_res.get("dest") == dest + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None else: assert cp_res.get("msg") is not None assert cp_res.get("changed") is False for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 - if args["force"]: + if args["replace"]: assert v_cp.get("stdout") != "" finally: hosts.all.zos_data_set(name=src_data_set, state="absent") @@ -3283,6 +3418,7 @@ def test_copy_file_to_non_existing_pdse(ansible_zos_module, is_remote): assert cp_res.get("changed") is True assert cp_res.get("dest") == dest_path assert cp_res.get("dest_created") is True + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 finally: @@ -3312,6 +3448,7 @@ def test_copy_dir_to_non_existing_pdse(ansible_zos_module): assert result.get("changed") is True assert result.get("dest") == dest assert result.get("dest_created") is True + assert result.get("src") is not None for result in verify_copy.contacted.values(): assert result.get("rc") == 0 finally: @@ -3344,6 +3481,7 @@ def test_copy_dir_crlf_endings_to_non_existing_pdse(ansible_zos_module): assert result.get("changed") is True assert result.get("dest") == dest assert result.get("dest_created") is True + assert result.get("src") is not None for result in verify_copy.contacted.values(): assert result.get("rc") == 0 assert len(result.get("stdout_lines")) == 2 @@ -3384,6 +3522,8 @@ def test_copy_dir_to_existing_pdse(ansible_zos_module, src_type): assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert cp_res.get("dest") == dest + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 finally: @@ -3424,6 +3564,7 @@ def test_copy_data_set_to_non_existing_pdse(ansible_zos_module, src_type): assert cp_res.get("changed") is True assert cp_res.get("dest") == dest assert cp_res.get("dest_created") is True + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 assert v_cp.get("stdout") != "" @@ -3458,6 +3599,8 @@ def test_copy_pds_to_existing_pds(ansible_zos_module, args): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest + assert result.get("dest_created") is not None + assert result.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 @@ -3548,7 +3691,7 @@ def test_copy_pds_loadlib_member_to_pds_loadlib_member(ansible_zos_module, is_cr src="{0}({1})".format(src_lib, pgm_mem), dest="{0}({1})".format(dest_lib, pgm_mem), remote_src=True, - executable=True, + is_executable=True, aliases=False ) # zos_copy w an executables and its alias: @@ -3556,7 +3699,7 @@ def test_copy_pds_loadlib_member_to_pds_loadlib_member(ansible_zos_module, is_cr src="{0}({1})".format(src_lib, pgm_mem), dest="{0}({1})".format(dest_lib_aliases, pgm_mem), remote_src=True, - executable=True, + is_executable=True, aliases=True ) @@ -3564,11 +3707,15 @@ def test_copy_pds_loadlib_member_to_pds_loadlib_member(ansible_zos_module, is_cr assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == "{0}({1})".format(dest_lib, pgm_mem) + assert result.get("dest_created") is not None + assert result.get("src") is not None for result in copy_res_aliases.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == "{0}({1})".format(dest_lib_aliases, pgm_mem) + assert result.get("dest_created") is not None + assert result.get("src") is not None # check ALIAS keyword and name in mls output verify_copy_mls = hosts.all.shell( @@ -3676,11 +3823,14 @@ def test_copy_pds_loadlib_member_to_uss_to_loadlib(ansible_zos_module): src="{0}({1})".format(src_lib, pgm_mem), dest=uss_dest, remote_src=True, - executable=True, - force=True) + is_executable=True, + replace=True) for result in copy_uss_res.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True + assert result.get("dest") is not None + assert result.get("dest_created") is not None + assert result.get("src") is not None # run executable on USS verify_exe_uss = hosts.all.shell( @@ -3696,7 +3846,7 @@ def test_copy_pds_loadlib_member_to_uss_to_loadlib(ansible_zos_module): src="{0}".format(uss_dest), dest="{0}({1})".format(dest_lib, pgm_mem), remote_src=True, - executable=True, + is_executable=True, aliases=False ) # zos_copy from USS file w an executables and its alias: @@ -3704,7 +3854,7 @@ def test_copy_pds_loadlib_member_to_uss_to_loadlib(ansible_zos_module): src="{0}".format(uss_dest), dest="{0}({1})".format(dest_lib_aliases, pgm_mem), remote_src=True, - executable=True, + is_executable=True, aliases=True ) @@ -3712,10 +3862,14 @@ def test_copy_pds_loadlib_member_to_uss_to_loadlib(ansible_zos_module): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == "{0}({1})".format(dest_lib, pgm_mem) + assert result.get("dest_created") is not None + assert result.get("src") is not None for result in copy_res_aliases.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == "{0}({1})".format(dest_lib_aliases, pgm_mem) + assert result.get("dest_created") is not None + assert result.get("src") is not None # check ALIAS keyword and name in mls output verify_copy_mls = hosts.all.shell( @@ -3844,7 +3998,7 @@ def test_copy_pds_loadlib_to_pds_loadlib(ansible_zos_module, is_created): src="{0}".format(src_lib), dest="{0}".format(dest_lib), remote_src=True, - executable=True, + is_executable=True, aliases=False, dest_data_set={ 'type': "library", @@ -3860,7 +4014,7 @@ def test_copy_pds_loadlib_to_pds_loadlib(ansible_zos_module, is_created): src="{0}".format(src_lib), dest="{0}".format(dest_lib_aliases), remote_src=True, - executable=True, + is_executable=True, aliases=True, dest_data_set={ 'type': "library", @@ -3878,7 +4032,7 @@ def test_copy_pds_loadlib_to_pds_loadlib(ansible_zos_module, is_created): src="{0}".format(src_lib), dest="{0}".format(dest_lib), remote_src=True, - executable=True, + is_executable=True, aliases=False ) # copy src loadlib to dest library pds w aliases @@ -3886,7 +4040,7 @@ def test_copy_pds_loadlib_to_pds_loadlib(ansible_zos_module, is_created): src="{0}".format(src_lib), dest="{0}".format(dest_lib_aliases), remote_src=True, - executable=True, + is_executable=True, aliases=True ) @@ -3894,11 +4048,15 @@ def test_copy_pds_loadlib_to_pds_loadlib(ansible_zos_module, is_created): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == "{0}".format(dest_lib) + assert result.get("dest_created") is not None + assert result.get("src") is not None for result in copy_res_aliases.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == "{0}".format(dest_lib_aliases) + assert result.get("dest_created") is not None + assert result.get("src") is not None # check ALIAS keyword and name in mls output verify_copy_mls = hosts.all.shell( @@ -4055,7 +4213,7 @@ def test_copy_local_pds_loadlib_to_pds_loadlib(ansible_zos_module, is_created): copy_res = hosts.all.zos_copy( src=source_path, dest="{0}".format(dest_lib), - executable=True, + is_executable=True, aliases=False, dest_data_set={ 'type': "pdse", @@ -4071,7 +4229,7 @@ def test_copy_local_pds_loadlib_to_pds_loadlib(ansible_zos_module, is_created): copy_res = hosts.all.zos_copy( src=source_path, dest="{0}".format(dest_lib), - executable=True, + is_executable=True, aliases=False ) @@ -4079,6 +4237,8 @@ def test_copy_local_pds_loadlib_to_pds_loadlib(ansible_zos_module, is_created): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == "{0}".format(dest_lib) + assert result.get("dest_created") is not None + assert result.get("src") is not None # check ALIAS keyword and name in mls output verify_copy_mls = hosts.all.shell( @@ -4193,12 +4353,14 @@ def test_copy_pds_loadlib_to_uss_to_pds_loadlib(ansible_zos_module): src="{0}".format(src_lib), dest="{0}".format(uss_dir_path), remote_src=True, - executable=True, + is_executable=True, ) for result in copy_res_uss.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == "{0}".format(uss_dir_path) + assert result.get("dest_created") is not None + assert result.get("src") is not None # inspect USS dir contents verify_exe_uss_ls = hosts.all.shell( @@ -4229,7 +4391,7 @@ def test_copy_pds_loadlib_to_uss_to_pds_loadlib(ansible_zos_module): src="{0}/{1}".format(uss_dir_path, src_lib.upper()), dest="{0}".format(dest_lib), remote_src=True, - executable=True, + is_executable=True, aliases=False ) # copy USS dir to dest library pds w aliases @@ -4237,7 +4399,7 @@ def test_copy_pds_loadlib_to_uss_to_pds_loadlib(ansible_zos_module): src="{0}/{1}".format(uss_dir_path, src_lib.upper()), dest="{0}".format(dest_lib_aliases), remote_src=True, - executable=True, + is_executable=True, aliases=True ) @@ -4245,11 +4407,16 @@ def test_copy_pds_loadlib_to_uss_to_pds_loadlib(ansible_zos_module): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == "{0}".format(dest_lib) + assert result.get("dest_created") is not None + assert result.get("src") is not None for result in copy_res_aliases.contacted.values(): + print(result) assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == "{0}".format(dest_lib_aliases) + assert result.get("dest_created") is not None + assert result.get("src") is not None # check ALIAS keyword and name in mls output verify_copy_mls = hosts.all.shell( @@ -4313,13 +4480,16 @@ def test_copy_executables_uss_to_uss(ansible_zos_module): src=f"{c_dir}/hello_world", dest=dest_uss, remote_src=True, - executable=True, - force=True + is_executable=True, + replace=True ) verify_exe_dst = hosts.all.shell(cmd=f"{c_dir}/hello_world_2") for result in copy_uss_res.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True + assert result.get("dest") is not None + assert result.get("dest_created") is not None + assert result.get("src") is not None for res in verify_exe_dst.contacted.values(): assert res.get("rc") == 0 stdout = res.get("stdout") @@ -4357,8 +4527,8 @@ def test_copy_executables_uss_to_member(ansible_zos_module, is_created): src=f"{c_dir}/hello_world", dest="{0}({1})".format(dest, member), remote_src=True, - executable=True, - force=True + is_executable=True, + replace=True ) cmd = "mvscmd --pgm={0} --steplib={1} --sysprint=* --stderr=* --stdout=*" exec_res = hosts.all.shell( @@ -4367,6 +4537,9 @@ def test_copy_executables_uss_to_member(ansible_zos_module, is_created): for result in copy_uss_to_mvs_res.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True + assert result.get("dest") is not None + assert result.get("dest_created") is not None + assert result.get("src") is not None for res in exec_res.contacted.values(): assert res.get("rc") == 0 stdout = res.get("stdout") @@ -4410,6 +4583,8 @@ def test_copy_pds_member_with_system_symbol(ansible_zos_module): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest + assert result.get("dest_created") is not None + assert result.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 @@ -4446,6 +4621,8 @@ def test_copy_multiple_data_set_members(ansible_zos_module): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest + assert result.get("dest_created") is not None + assert result.get("src") is not None verify_copy = hosts.all.shell( cmd="mls {0}".format(dest), @@ -4493,6 +4670,8 @@ def test_copy_multiple_data_set_members_in_loop(ansible_zos_module): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest_member + assert result.get("dest_created") is not None + assert result.get("src") is not None verify_copy = hosts.all.shell( cmd="mls {0}".format(dest), @@ -4537,6 +4716,8 @@ def test_copy_member_to_non_existing_uss_file(ansible_zos_module, ds_type): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest + assert result.get("dest_created") is not None + assert result.get("src") is not None for result in stat_res.contacted.values(): assert result.get("stat").get("exists") is True for result in verify_copy.contacted.values(): @@ -4550,10 +4731,10 @@ def test_copy_member_to_non_existing_uss_file(ansible_zos_module, ds_type): @pytest.mark.uss @pytest.mark.pdse @pytest.mark.parametrize("args", [ - dict(ds_type="pds", force=False), - dict(ds_type="pds", force=True), - dict(ds_type="pdse", force=False), - dict(ds_type="pdse", force=True) + dict(ds_type="pds", replace=False), + dict(ds_type="pds", replace=True), + dict(ds_type="pdse", replace=False), + dict(ds_type="pdse", replace=True) ]) def test_copy_member_to_existing_uss_file(ansible_zos_module, args): hosts = ansible_zos_module @@ -4569,17 +4750,19 @@ def test_copy_member_to_existing_uss_file(ansible_zos_module, args): executable=SHELL_EXECUTABLE ) - copy_res = hosts.all.zos_copy(src=src, dest=dest, remote_src=True, force=args["force"]) + copy_res = hosts.all.zos_copy(src=src, dest=dest, remote_src=True, replace=args["replace"]) stat_res = hosts.all.stat(path=dest) verify_copy = hosts.all.shell( cmd="head {0}".format(dest), executable=SHELL_EXECUTABLE ) for result in copy_res.contacted.values(): - if args["force"]: + if args["replace"]: assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest + assert result.get("dest_created") is not None + assert result.get("src") is not None else: assert result.get("msg") is not None assert result.get("changed") is False @@ -4587,7 +4770,7 @@ def test_copy_member_to_existing_uss_file(ansible_zos_module, args): assert result.get("stat").get("exists") is True for result in verify_copy.contacted.values(): assert result.get("rc") == 0 - if args["force"]: + if args["replace"]: assert result.get("stdout") != "" finally: hosts.all.zos_data_set(name=data_set, state="absent") @@ -4631,6 +4814,8 @@ def test_copy_pdse_to_uss_dir(ansible_zos_module, src_type): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest + assert result.get("dest_created") is not None + assert result.get("src") is not None for result in stat_res.contacted.values(): assert result.get("stat").get("exists") is True assert result.get("stat").get("isdir") is True @@ -4677,6 +4862,8 @@ def test_copy_member_to_uss_dir(ansible_zos_module, src_type): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest + assert result.get("dest_created") is not None + assert result.get("src") is not None for result in stat_res.contacted.values(): assert result.get("stat").get("exists") is True for result in verify_copy.contacted.values(): @@ -4714,6 +4901,7 @@ def test_copy_member_to_non_existing_seq_data_set(ansible_zos_module, src_type): assert result.get("changed") is True assert result.get("dest") == dest assert result.get("dest_created") is True + assert result.get("src") is not None for result in verify_copy.contacted.values(): assert result.get("rc") == 0 assert result.get("stdout") != "" @@ -4725,10 +4913,10 @@ def test_copy_member_to_non_existing_seq_data_set(ansible_zos_module, src_type): @pytest.mark.seq @pytest.mark.pdse @pytest.mark.parametrize("args", [ - dict(type="pds", force=False), - dict(type="pds", force=True), - dict(type="pdse", force=False), - dict(type="pdse", force=True), + dict(type="pds", replace=False), + dict(type="pds", replace=True), + dict(type="pdse", replace=False), + dict(type="pdse", replace=True), ]) def test_copy_member_to_existing_seq_data_set(ansible_zos_module, args): hosts = ansible_zos_module @@ -4746,22 +4934,24 @@ def test_copy_member_to_existing_seq_data_set(ansible_zos_module, args): executable=SHELL_EXECUTABLE ) - copy_res = hosts.all.zos_copy(src=src, dest=dest, force=args["force"], remote_src=True) + copy_res = hosts.all.zos_copy(src=src, dest=dest, replace=args["replace"], remote_src=True) verify_copy = hosts.all.shell( cmd="head \"//'{0}'\"".format(dest), executable=SHELL_EXECUTABLE ) for result in copy_res.contacted.values(): - if args["force"]: + if args["replace"]: assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest + assert result.get("dest_created") is not None + assert result.get("src") is not None else: assert result.get("msg") is not None assert result.get("changed") is False for result in verify_copy.contacted.values(): assert result.get("rc") == 0 - if args["force"]: + if args["replace"]: assert result.get("stdout") != "" finally: hosts.all.zos_data_set(name=src_ds, state="absent") @@ -4804,6 +4994,8 @@ def test_copy_file_to_member_convert_encoding(ansible_zos_module, dest_type): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest + assert result.get("dest_created") is not None + assert result.get("src") is not None for result in verify_copy.contacted.values(): assert result.get("rc") == 0 assert result.get("stdout") != "" @@ -4831,14 +5023,16 @@ def test_backup_pds(ansible_zos_module, args): if args["backup"]: backup_name = get_tmp_ds_name() - copy_res = hosts.all.zos_copy(src=src, dest=dest, force=True, backup=True, backup_name=backup_name) + copy_res = hosts.all.zos_copy(src=src, dest=dest, replace=True, backup=True, backup_name=backup_name) else: - copy_res = hosts.all.zos_copy(src=src, dest=dest, force=True, backup=True) + copy_res = hosts.all.zos_copy(src=src, dest=dest, replace=True, backup=True) for result in copy_res.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest + assert result.get("dest_created") is not None + assert result.get("src") is not None result_backup_name = result.get("backup_name") assert result_backup_name is not None @@ -4893,6 +5087,8 @@ def test_copy_data_set_to_volume(ansible_zos_module, volumes_on_systems, src_typ assert cp.get('msg') is None assert cp.get('changed') is True assert cp.get('dest') == dest + assert cp.get("dest_created") is not None + assert cp.get("src") is not None check_vol = hosts.all.shell( cmd="tsocmd \"LISTDS '{0}'\"".format(dest), @@ -4922,6 +5118,8 @@ def test_copy_ksds_to_non_existing_ksds(ansible_zos_module): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest_ds + assert result.get("dest_created") is not None + assert result.get("src") is not None for result in verify_copy.contacted.values(): assert result.get("dd_names") is not None dd_names = result.get("dd_names") @@ -4938,8 +5136,8 @@ def test_copy_ksds_to_non_existing_ksds(ansible_zos_module): ) @pytest.mark.vsam -@pytest.mark.parametrize("force", [False, True]) -def test_copy_ksds_to_existing_ksds(ansible_zos_module, force): +@pytest.mark.parametrize("replace", [False, True]) +def test_copy_ksds_to_existing_ksds(ansible_zos_module, replace): hosts = ansible_zos_module src_ds = get_tmp_ds_name() dest_ds = get_tmp_ds_name() @@ -4948,14 +5146,16 @@ def test_copy_ksds_to_existing_ksds(ansible_zos_module, force): create_vsam_data_set(hosts, src_ds, "ksds", add_data=True, key_length=12, key_offset=0) create_vsam_data_set(hosts, dest_ds, "ksds", add_data=True, key_length=12, key_offset=0) - copy_res = hosts.all.zos_copy(src=src_ds, dest=dest_ds, remote_src=True, force=force) + copy_res = hosts.all.zos_copy(src=src_ds, dest=dest_ds, remote_src=True, replace=replace) verify_copy = get_listcat_information(hosts, dest_ds, "ksds") for result in copy_res.contacted.values(): - if force: + if replace: assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest_ds + assert result.get("dest_created") is not None + assert result.get("src") is not None else: assert result.get("msg") is not None assert result.get("changed") is False @@ -4986,13 +5186,16 @@ def test_backup_ksds(ansible_zos_module, backup): if backup: backup_name = get_tmp_ds_name() - copy_res = hosts.all.zos_copy(src=src, dest=dest, backup=True, backup_name=backup_name, remote_src=True, force=True) + copy_res = hosts.all.zos_copy(src=src, dest=dest, backup=True, backup_name=backup_name, remote_src=True, replace=True) else: - copy_res = hosts.all.zos_copy(src=src, dest=dest, backup=True, remote_src=True, force=True) + copy_res = hosts.all.zos_copy(src=src, dest=dest, backup=True, remote_src=True, replace=True) for result in copy_res.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True + assert result.get("dest") is not None + assert result.get("dest_created") is not None + assert result.get("src") is not None result_backup_name = result.get("backup_name") assert result_backup_name is not None @@ -5042,6 +5245,12 @@ def test_copy_ksds_to_volume(ansible_zos_module, volumes_on_systems): ) verify_copy = get_listcat_information(hosts, dest_ds, "ksds") + for result in copy_res.contacted.values(): + assert result.get("msg") is None + assert result.get("changed") is True + assert result.get("dest") is not None + assert result.get("dest_created") is not None + assert result.get("src") is not None for result in verify_copy.contacted.values(): assert result.get("dd_names") is not None dd_names = result.get("dd_names") @@ -5098,6 +5307,8 @@ def test_dest_data_set_parameters(ansible_zos_module, volumes_on_systems): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == dest + assert result.get("dest_created") is not None + assert result.get("src") is not None for result in verify_copy.contacted.values(): # The tsocmd returns 5 lines like this: # USER.TEST.DEST @@ -5136,6 +5347,9 @@ def test_ensure_tmp_cleanup(ansible_zos_module): for result in copy_res.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True + assert result.get("dest") is not None + assert result.get("dest_created") is not None + assert result.get("src") is not None stat_dir = hosts.all.shell( cmd="ls", @@ -5153,32 +5367,36 @@ def test_ensure_tmp_cleanup(ansible_zos_module): @pytest.mark.vsam -@pytest.mark.parametrize("force", [False, True]) -def test_copy_uss_file_to_existing_sequential_data_set_twice_with_tmphlq_option(ansible_zos_module, force): +@pytest.mark.parametrize("replace", [False, True]) +def test_copy_uss_file_to_existing_sequential_data_set_twice_with_tmphlq_option(ansible_zos_module, replace): hosts = ansible_zos_module dest = get_tmp_ds_name() src_file = "/etc/profile" tmphlq = "TMPHLQ" try: hosts.all.zos_data_set(name=dest, type="seq", state="present") - copy_result = hosts.all.zos_copy(src=src_file, dest=dest, remote_src=True, force=force) - copy_result = hosts.all.zos_copy(src=src_file, dest=dest, remote_src=True, backup=True, tmp_hlq=tmphlq, force=force) + copy_result = hosts.all.zos_copy(src=src_file, dest=dest, remote_src=True, replace=replace) + copy_result = hosts.all.zos_copy(src=src_file, dest=dest, remote_src=True, backup=True, tmp_hlq=tmphlq, replace=replace) verify_copy = None - if force: + if replace: verify_copy = hosts.all.shell( cmd="cat \"//'{0}'\" > /dev/null 2>/dev/null".format(dest), executable=SHELL_EXECUTABLE, ) for cp_res in copy_result.contacted.values(): - if force: + if replace: assert cp_res.get("msg") is None assert cp_res.get("backup_name")[:6] == tmphlq + assert cp_res.get("changed") is True + assert cp_res.get("dest") is not None + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None else: assert cp_res.get("msg") is not None assert cp_res.get("changed") is False - if force: + if replace: for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 finally: @@ -5188,11 +5406,11 @@ def test_copy_uss_file_to_existing_sequential_data_set_twice_with_tmphlq_option( @pytest.mark.parametrize("options", [ dict(src="/etc/profile", - force=True, is_remote=False, verbosity="-vvvvv", verbosity_level=5), - dict(src="/etc/profile", force=True, + replace=True, is_remote=False, verbosity="-vvvvv", verbosity_level=5), + dict(src="/etc/profile", replace=True, is_remote=False, verbosity="-vvvv", verbosity_level=4), dict(src="/etc/profile", - force=True, is_remote=False, verbosity="", verbosity_level=0), + replace=True, is_remote=False, verbosity="", verbosity_level=0), ]) def test_display_verbosity_in_zos_copy_plugin(ansible_zos_module, options): """Test the display verbosity, ensure it matches the verbosity_level. @@ -5271,6 +5489,8 @@ def test_copy_seq_gds_to_data_set(ansible_zos_module): assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert cp_res.get("dest") == dest_data_set + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 assert v_cp.get("stdout") != "" @@ -5308,6 +5528,8 @@ def test_copy_data_set_to_new_gds(ansible_zos_module): assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert re.fullmatch(gds_pattern, dest.split(".")[-1]) + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 assert v_cp.get("stdout") != "" @@ -5343,6 +5565,8 @@ def test_copy_uss_file_to_new_gds(ansible_zos_module): assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert re.fullmatch(gds_pattern, dest.split(".")[-1]) + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 assert v_cp.get("stdout") != "" @@ -5381,6 +5605,8 @@ def test_copy_pds_to_new_gds(ansible_zos_module): assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert re.fullmatch(gds_pattern, dest.split(".")[-1]) + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 assert v_cp.get("stdout") != "" @@ -5408,7 +5634,7 @@ def test_copy_data_set_to_previous_gds(ansible_zos_module): src=src_data_set, dest=f"{dest_data_set}(0)", remote_src=True, - force=True + replace=True ) verify_copy = hosts.all.shell(cmd=f"""dcat "{dest_data_set}(0)" """) @@ -5422,6 +5648,8 @@ def test_copy_data_set_to_previous_gds(ansible_zos_module): assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert re.fullmatch(gds_pattern, dest.split(".")[-1]) + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 assert v_cp.get("stdout") != "" @@ -5446,7 +5674,7 @@ def test_copy_uss_file_to_previous_gds(ansible_zos_module): src=src_file, dest=f"{dest_data_set}(0)", remote_src=True, - force=True + replace=True ) verify_copy = hosts.all.shell(cmd=f"""dcat "{dest_data_set}(0)" """) @@ -5460,6 +5688,8 @@ def test_copy_uss_file_to_previous_gds(ansible_zos_module): assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert re.fullmatch(gds_pattern, dest.split(".")[-1]) + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 assert v_cp.get("stdout") != "" @@ -5487,7 +5717,7 @@ def test_copy_pds_member_to_previous_gds(ansible_zos_module): src=member_src, dest=f"{dest_data_set}(0)", remote_src=True, - force=True + replace=True ) verify_copy = hosts.all.shell(cmd=f"""dcat "{dest_data_set}(0)" """) @@ -5501,6 +5731,8 @@ def test_copy_pds_member_to_previous_gds(ansible_zos_module): assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert re.fullmatch(gds_pattern, dest.split(".")[-1]) + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 assert v_cp.get("stdout") != "" @@ -5528,7 +5760,7 @@ def test_copy_pds_to_previous_gds(ansible_zos_module): src=src_data_set, dest=f"{dest_data_set}(0)", remote_src=True, - force=True + replace=True ) verify_copy = hosts.all.shell(cmd=f"""mls "{dest_data_set}(0)" """) @@ -5542,6 +5774,8 @@ def test_copy_pds_to_previous_gds(ansible_zos_module): assert cp_res.get("msg") is None assert cp_res.get("changed") is True assert re.fullmatch(gds_pattern, dest.split(".")[-1]) + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 assert v_cp.get("stdout") != "" @@ -5569,7 +5803,7 @@ def test_copy_data_set_to_previous_gds_no_force(ansible_zos_module): src=src_data_set, dest=f"{dest_data_set}(0)", remote_src=True, - force=False + replace=False ) for cp_res in copy_results.contacted.values(): @@ -5602,7 +5836,7 @@ def test_copy_data_set_to_previous_non_existent_gds(ansible_zos_module, generati # Copying to a previous generation that doesn't exist. dest=f"{dest_data_set}({generation})", remote_src=True, - force=True + replace=True ) for cp_res in copy_results.contacted.values(): @@ -5640,6 +5874,9 @@ def test_copy_gdg_to_uss_dir(ansible_zos_module): for cp_res in copy_results.contacted.values(): assert cp_res.get("msg") is None assert cp_res.get("changed") is True + assert cp_res.get("dest") is not None + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None for v_res in verify_dest.contacted.values(): assert v_res.get("rc") == 0 assert len(v_res.get("stdout_lines", [])) > 0 @@ -5676,6 +5913,9 @@ def test_copy_gdg_to_gdg(ansible_zos_module, new_gdg): for cp_res in copy_results.contacted.values(): assert cp_res.get("msg") is None assert cp_res.get("changed") is True + assert cp_res.get("dest") is not None + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None finally: hosts.all.shell(cmd=f"""drm "{src_data_set}(-1)" """) hosts.all.shell(cmd=f"""drm "{src_data_set}(0)" """) @@ -5714,6 +5954,9 @@ def test_identical_gdg_copy(ansible_zos_module): for result in copy_results.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True + assert result.get("dest") is not None + assert result.get("dest_created") is not None + assert result.get("src") is not None finally: src_gdg_result = hosts.all.shell(cmd=f"dls {src_data_set}.*") src_gdgs = [] @@ -5767,6 +6010,9 @@ def test_copy_gdg_to_gdg_dest_attributes(ansible_zos_module): for cp_res in copy_results.contacted.values(): assert cp_res.get("msg") is None assert cp_res.get("changed") is True + assert cp_res.get("dest") is not None + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None finally: hosts.all.shell(cmd=f"""drm "{src_data_set}(-1)" """) hosts.all.shell(cmd=f"""drm "{src_data_set}(0)" """) @@ -5796,7 +6042,7 @@ def test_backup_gds(ansible_zos_module): src=src_data_set, dest=dest_data_set, remote_src=True, - force=True, + replace=True, backup=True, backup_name=f"{backup_data_set}(+1)", ) @@ -5808,6 +6054,9 @@ def test_backup_gds(ansible_zos_module): for result in results.contacted.values(): assert result.get("changed") is True assert result.get("msg") is None + assert result.get("dest") is not None + assert result.get("dest_created") is not None + assert result.get("src") is not None for result in backup_check.contacted.values(): assert result.get("rc") == 0 @@ -5841,7 +6090,7 @@ def test_backup_gds_invalid_generation(ansible_zos_module): src=src_data_set, dest=dest_data_set, remote_src=True, - force=True, + replace=True, backup=True, backup_name=f"{backup_data_set}(0)", ) @@ -5878,6 +6127,9 @@ def test_copy_to_dataset_with_special_symbols(ansible_zos_module): for result in results.contacted.values(): assert result.get("changed") is True assert result.get("msg") is None + assert result.get("dest") is not None + assert result.get("dest_created") is not None + assert result.get("src") is not None finally: hosts.all.zos_data_set(name=src_data_set, state="absent") @@ -5987,6 +6239,10 @@ def test_copy_data_set_seq_with_aliases(ansible_zos_module, volumes_on_systems): for result in zos_copy_result.contacted.values(): assert result.get('changed') is True assert result.get('failed', False) is False + assert result.get("msg") is None + assert result.get("dest") is not None + assert result.get("dest_created") is not None + assert result.get("src") is not None verify_copy = hosts.all.shell( cmd="cat \"//'{0}'\"".format(dest), executable=SHELL_EXECUTABLE, @@ -6027,6 +6283,9 @@ def test_copy_pds_to_pds_using_dest_alias(ansible_zos_module): for cp_res in copy_results.contacted.values(): assert cp_res.get("msg") is None assert cp_res.get("changed") is True + assert cp_res.get("dest") is not None + assert cp_res.get("dest_created") is not None + assert cp_res.get("src") is not None verify_dest = hosts.all.shell( cmd=f"""dcat "{dest_pds}(MEMBER)" """, @@ -6123,7 +6382,7 @@ def test_copy_pdse_loadlib_to_pdse_loadlib_using_aliases(ansible_zos_module): src="{0}".format(src_lib_aliases), dest="{0}".format(dest_lib_aliases), remote_src=True, - executable=True, + is_executable=True, aliases=True, dest_data_set={ 'type': "library", @@ -6139,6 +6398,8 @@ def test_copy_pdse_loadlib_to_pdse_loadlib_using_aliases(ansible_zos_module): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == "{0}".format(dest_lib_aliases) + assert result.get("dest_created") is not None + assert result.get("src") is not None verify_copy_mls_aliases = hosts.all.shell( cmd="mls {0}".format(dest_lib), @@ -6201,6 +6462,7 @@ def test_copy_asa_file_to_asa_sequential_with_pound(ansible_zos_module): assert cp_res.get("changed") is True assert cp_res.get("dest") == dest assert cp_res.get("dest_created") is True + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 assert v_cp.get("stdout") == ASA_SAMPLE_RETURN @@ -6254,6 +6516,7 @@ def test_copy_seq_data_set_to_seq_asa_with_pounds(ansible_zos_module): assert cp_res.get("changed") is True assert cp_res.get("dest") == dest assert cp_res.get("dest_created") is True + assert cp_res.get("src") is not None for v_cp in verify_copy.contacted.values(): assert v_cp.get("rc") == 0 assert v_cp.get("stdout") == ASA_SAMPLE_RETURN @@ -6344,7 +6607,7 @@ def test_copy_pds_loadlib_member_to_pds_loadlib_member_with_pound(ansible_zos_mo src="{0}({1})".format(src_lib, pgm_mem), dest="{0}({1})".format(dest_lib, dest_pgm_mem), remote_src=True, - executable=True, + is_executable=True, aliases=False ) # zos_copy w an executables and its alias: @@ -6352,7 +6615,7 @@ def test_copy_pds_loadlib_member_to_pds_loadlib_member_with_pound(ansible_zos_mo src="{0}({1})".format(src_lib, pgm_mem), dest="{0}({1})".format(dest_lib_aliases, dest_pgm_mem), remote_src=True, - executable=True, + is_executable=True, aliases=True ) @@ -6360,11 +6623,15 @@ def test_copy_pds_loadlib_member_to_pds_loadlib_member_with_pound(ansible_zos_mo assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == "{0}({1})".format(dest_lib, dest_pgm_mem) + assert result.get("dest_created") is not None + assert result.get("src") is not None for result in copy_res_aliases.contacted.values(): assert result.get("msg") is None assert result.get("changed") is True assert result.get("dest") == "{0}({1})".format(dest_lib_aliases, dest_pgm_mem) + assert result.get("dest_created") is not None + assert result.get("src") is not None # check ALIAS keyword and name in mls output verify_copy_mls = hosts.all.shell( @@ -6400,4 +6667,3 @@ def test_copy_pds_loadlib_member_to_pds_loadlib_member_with_pound(ansible_zos_mo hosts.all.zos_data_set(name=src_lib, state="absent") hosts.all.zos_data_set(name=dest_lib, state="absent") hosts.all.zos_data_set(name=dest_lib_aliases, state="absent") - \ No newline at end of file