13
13
14
14
from __future__ import absolute_import , division , print_function
15
15
16
+ from ibm_zos_core .tests .helpers .users import ManagedUserType , ManagedUser
16
17
import pytest
17
18
import os
18
19
import shutil
@@ -365,6 +366,7 @@ def link_loadlib_from_cobol(hosts, cobol_src_pds, cobol_src_mem, loadlib_pds, lo
365
366
wait_time_s = 60
366
367
)
367
368
for result in job_result .contacted .values ():
369
+ print (result )
368
370
rc = result .get ("jobs" )[0 ].get ("ret_code" ).get ("code" )
369
371
finally :
370
372
hosts .all .file (path = temp_jcl_uss_path , state = "absent" )
@@ -1960,8 +1962,15 @@ def test_ensure_copy_file_does_not_change_permission_on_dest(ansible_zos_module,
1960
1962
1961
1963
1962
1964
@pytest .mark .seq
1963
- @pytest .mark .parametrize ("ds_type" , [ "pds" , "pdse" , "seq" ])
1964
- def test_copy_dest_lock (ansible_zos_module , ds_type ):
1965
+ @pytest .mark .parametrize ("ds_type, f_lock" ,[
1966
+ ( "pds" , True ), # Success path, pds locked, force_lock enabled and user authorized
1967
+ ( "pdse" , True ), # Success path, pdse locked, force_lock enabled and user authorized
1968
+ ( "seq" , True ), # Success path, seq locked, force_lock enabled and user authorized
1969
+ ( "pds" , False ), # Module exits with: Unable to write to dest '{0}' because a task is accessing the data set."
1970
+ ( "pdse" , False ), # Module exits with: Unable to write to dest '{0}' because a task is accessing the data set."
1971
+ ( "seq" , False ), # Module exits with: Unable to write to dest '{0}' because a task is accessing the data set."
1972
+ ])
1973
+ def test_copy_dest_lock (ansible_zos_module , ds_type , f_lock ):
1965
1974
hosts = ansible_zos_module
1966
1975
data_set_1 = get_tmp_ds_name ()
1967
1976
data_set_2 = get_tmp_ds_name ()
@@ -1973,7 +1982,6 @@ def test_copy_dest_lock(ansible_zos_module, ds_type):
1973
1982
src_data_set = data_set_1
1974
1983
dest_data_set = data_set_2
1975
1984
try :
1976
- hosts = ansible_zos_module
1977
1985
hosts .all .zos_data_set (name = data_set_1 , state = "present" , type = ds_type , replace = True )
1978
1986
hosts .all .zos_data_set (name = data_set_2 , state = "present" , type = ds_type , replace = True )
1979
1987
if ds_type == "pds" or ds_type == "pdse" :
@@ -1999,27 +2007,139 @@ def test_copy_dest_lock(ansible_zos_module, ds_type):
1999
2007
dest = dest_data_set ,
2000
2008
remote_src = True ,
2001
2009
force = True ,
2002
- force_lock = True ,
2010
+ force_lock = f_lock ,
2003
2011
)
2004
2012
for result in results .contacted .values ():
2005
2013
print (result )
2006
- assert result .get ("changed" ) == True
2007
- assert result .get ("msg" ) is None
2008
- # verify that the content is the same
2009
- verify_copy = hosts .all .shell (
2010
- cmd = "dcat \" {0}\" " .format (dest_data_set ),
2011
- executable = SHELL_EXECUTABLE ,
2012
- )
2013
- for vp_result in verify_copy .contacted .values ():
2014
- print (vp_result )
2015
- verify_copy_2 = hosts .all .shell (
2016
- cmd = "dcat \" {0}\" " .format (src_data_set ),
2014
+ if f_lock : #and apf_auth_user:
2015
+ assert result .get ("changed" ) == True
2016
+ assert result .get ("msg" ) is None
2017
+ # verify that the content is the same
2018
+ verify_copy = hosts .all .shell (
2019
+ cmd = "dcat \" {0}\" " .format (dest_data_set ),
2017
2020
executable = SHELL_EXECUTABLE ,
2018
2021
)
2019
- for vp_result_2 in verify_copy_2 .contacted .values ():
2020
- print (vp_result_2 )
2021
- assert vp_result_2 .get ("stdout" ) == vp_result .get ("stdout" )
2022
+ for vp_result in verify_copy .contacted .values ():
2023
+ print (vp_result )
2024
+ verify_copy_2 = hosts .all .shell (
2025
+ cmd = "dcat \" {0}\" " .format (src_data_set ),
2026
+ executable = SHELL_EXECUTABLE ,
2027
+ )
2028
+ for vp_result_2 in verify_copy_2 .contacted .values ():
2029
+ print (vp_result_2 )
2030
+ assert vp_result_2 .get ("stdout" ) == vp_result .get ("stdout" )
2031
+ elif not f_lock :
2032
+ assert result .get ("failed" ) is True
2033
+ assert result .get ("changed" ) == False
2034
+ assert "because a task is accessing the data set" in result .get ("msg" )
2035
+ assert result .get ("rc" ) is None
2036
+ finally :
2037
+ # extract pid
2038
+ ps_list_res = hosts .all .shell (cmd = "ps -e | grep -i 'pdse-lock'" )
2039
+ # kill process - release lock - this also seems to end the job
2040
+ pid = list (ps_list_res .contacted .values ())[0 ].get ('stdout' ).strip ().split (' ' )[0 ]
2041
+ hosts .all .shell (cmd = "kill 9 {0}" .format (pid .strip ()))
2042
+ # clean up c code/object/executable files, jcl
2043
+ hosts .all .shell (cmd = f'rm -r { temp_dir } ' )
2044
+ # remove pdse
2045
+ hosts .all .zos_data_set (name = data_set_1 , state = "absent" )
2046
+ hosts .all .zos_data_set (name = data_set_2 , state = "absent" )
2047
+
2048
+
2049
+ def test_copy_dest_lock_test_with_no_opercmd_access_pds_without_force_lock (ansible_zos_module ):
2050
+ """
2051
+ This tests the module exeception raised 'msg="Unable to determine if the source {0} is in use.".format(dataset_name)'.
2052
+ This this a wrapper for the actual test case `managed_user_copy_dest_lock_test_with_no_opercmd_access`.
2053
+ """
2054
+ managed_user = None
2055
+ managed_user_test_case_name = "managed_user_copy_dest_lock_test_with_no_opercmd_access"
2056
+ try :
2057
+ # Initialize the Managed user API from the pytest fixture.
2058
+ managed_user = ManagedUser .from_fixture (ansible_zos_module )
2059
+
2060
+ # Important: Execute the test case with the managed users execution utility.
2061
+ managed_user .execute_managed_user_test (
2062
+ managed_user_test_case = managed_user_test_case_name ,debug = True ,
2063
+ verbose = False , managed_user_type = ManagedUserType .ZOAU_LIMITED_ACCESS_OPERCMD )
2064
+
2065
+ finally :
2066
+ # Delete the managed user on the remote host to avoid proliferation of users.
2067
+ managed_user .delete_managed_user ()
2068
+
2069
+ @pytest .mark .parametrize ("ds_type, f_lock" ,[
2070
+ ( "pds" , False ), # Module exception raised msg="Unable to determine if the source {0} is in use.".format(dataset_name)
2071
+ ( "pdse" , False ), # Module exception raised msg="Unable to determine if the source {0} is in use.".format(dataset_name)
2072
+ ( "seq" , False ), # Module exception raised msg="Unable to determine if the source {0} is in use.".format(dataset_name)
2073
+ ( "seq" , True ), # Opercmd is not called so a user with limited UACC will not matter and will succeed
2074
+ ])
2075
+ def managed_user_copy_dest_lock_test_with_no_opercmd_access (ansible_zos_module , ds_type , f_lock ):
2076
+ """
2077
+ When force_lock option is false, it exercises the opercmd call which requires RACF universal access.
2078
+ This negative test will ensure that if the user does not have RACF universal access that the module
2079
+ not halt execution and instead bubble up the ZOAU exception.
2080
+ """
2081
+ hosts = ansible_zos_module
2022
2082
2083
+ data_set_1 = get_tmp_ds_name ()
2084
+ data_set_2 = get_tmp_ds_name ()
2085
+ member_1 = "MEM1"
2086
+
2087
+ if ds_type == "pds" or ds_type == "pdse" :
2088
+ src_data_set = data_set_1 + "({0})" .format (member_1 )
2089
+ dest_data_set = data_set_2 + "({0})" .format (member_1 )
2090
+ else :
2091
+ src_data_set = data_set_1
2092
+ dest_data_set = data_set_2
2093
+ try :
2094
+ hosts .all .zos_data_set (name = data_set_1 , state = "present" , type = ds_type , replace = True )
2095
+ hosts .all .zos_data_set (name = data_set_2 , state = "present" , type = ds_type , replace = True )
2096
+ if ds_type == "pds" or ds_type == "pdse" :
2097
+ hosts .all .zos_data_set (name = src_data_set , state = "present" , type = "member" , replace = True )
2098
+ hosts .all .zos_data_set (name = dest_data_set , state = "present" , type = "member" , replace = True )
2099
+ # copy text_in source
2100
+ hosts .all .shell (cmd = "decho \" {0}\" \" {1}\" " .format (DUMMY_DATA , src_data_set ))
2101
+ # copy/compile c program and copy jcl to hold data set lock for n seconds in background(&)
2102
+ temp_dir = get_random_file_name (dir = TMP_DIRECTORY )
2103
+ hosts .all .zos_copy (content = c_pgm , dest = f'{ temp_dir } /pdse-lock.c' , force = True )
2104
+ hosts .all .zos_copy (
2105
+ content = call_c_jcl .format (temp_dir , dest_data_set ),
2106
+ dest = f'{ temp_dir } /call_c_pgm.jcl' ,
2107
+ force = True
2108
+ )
2109
+ hosts .all .shell (cmd = "xlc -o pdse-lock pdse-lock.c" , chdir = f"{ temp_dir } /" )
2110
+ # submit jcl
2111
+ hosts .all .shell (cmd = "submit call_c_pgm.jcl" , chdir = f"{ temp_dir } /" )
2112
+ # pause to ensure c code acquires lock
2113
+ time .sleep (10 )
2114
+ results = hosts .all .zos_copy (
2115
+ src = src_data_set ,
2116
+ dest = dest_data_set ,
2117
+ remote_src = True ,
2118
+ force = True ,
2119
+ force_lock = f_lock ,
2120
+ )
2121
+ for result in results .contacted .values ():
2122
+ if f_lock :
2123
+ assert result .get ("changed" ) == True
2124
+ assert result .get ("msg" ) is None
2125
+ # verify that the content is the same
2126
+ verify_copy = hosts .all .shell (
2127
+ cmd = "dcat \" {0}\" " .format (dest_data_set ),
2128
+ executable = SHELL_EXECUTABLE ,
2129
+ )
2130
+ for vp_result in verify_copy .contacted .values ():
2131
+ verify_copy_2 = hosts .all .shell (
2132
+ cmd = "dcat \" {0}\" " .format (src_data_set ),
2133
+ executable = SHELL_EXECUTABLE ,
2134
+ )
2135
+ for vp_result_2 in verify_copy_2 .contacted .values ():
2136
+ assert vp_result_2 .get ("stdout" ) == vp_result .get ("stdout" )
2137
+ elif not f_lock :
2138
+ assert result .get ("failed" ) is True
2139
+ assert result .get ("changed" ) == False
2140
+ assert "Unable to determine if the dest" in result .get ("msg" )
2141
+ assert "BGYSC0819E Insufficient security authorization for resource MVS.MCSOPER.ZOAU in class OPERCMDS" in result .get ("stderr" )
2142
+ assert result .get ("rc" ) == 6
2023
2143
finally :
2024
2144
# extract pid
2025
2145
ps_list_res = hosts .all .shell (cmd = "ps -e | grep -i 'pdse-lock'" )
0 commit comments