Skip to content

Commit dc2ef9c

Browse files
rexeminfernandofloresgAndreMarcel99
authored
[Enabler] [zos_copy] Add retries when performing dest lock tests (#1986)
* Wrap main dest lock test * Add wrapped to second dest lock test * Updated dest lock tests * Add changelog fragment * Change name of one test --------- Co-authored-by: Fernando Flores <[email protected]> Co-authored-by: André Marcel Gutiérrez Benítez <[email protected]>
1 parent 9d182de commit dc2ef9c

File tree

2 files changed

+225
-31
lines changed

2 files changed

+225
-31
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
trivial:
2+
- test_zos_copy_func.py - Add a wrapper that retries two specific tests when
3+
getting an intermittent error from `cp`.
4+
(https://github.com/ansible-collections/ibm_zos_core/pull/1986)

tests/functional/modules/test_zos_copy_func.py

Lines changed: 221 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2055,15 +2055,38 @@ def test_ensure_copy_file_does_not_change_permission_on_dest(ansible_zos_module,
20552055

20562056
@pytest.mark.seq
20572057
@pytest.mark.parametrize("ds_type, f_lock",[
2058-
( "pds", True), # Success path, pds locked, force_lock enabled and user authorized
2059-
( "pdse", True), # Success path, pdse locked, force_lock enabled and user authorized
2060-
( "seq", True), # Success path, seq locked, force_lock enabled and user authorized
2061-
( "pds", False), # Module exits with: Unable to write to dest '{0}' because a task is accessing the data set."
2062-
( "pdse", False), # Module exits with: Unable to write to dest '{0}' because a task is accessing the data set."
2063-
( "seq", False), # Module exits with: Unable to write to dest '{0}' because a task is accessing the data set."
2058+
("pds", True), # Success path, pds locked, force_lock enabled and user authorized
2059+
("pdse", True), # Success path, pdse locked, force_lock enabled and user authorized
2060+
("seq", True), # Success path, seq locked, force_lock enabled and user authorized
2061+
("pds", False), # Module exits with: Unable to write to dest '{0}' because a task is accessing the data set."
2062+
("pdse", False), # Module exits with: Unable to write to dest '{0}' because a task is accessing the data set."
2063+
("seq", False), # Module exits with: Unable to write to dest '{0}' because a task is accessing the data set."
20642064
])
2065-
def test_copy_dest_lock(ansible_zos_module, ds_type, f_lock ):
2065+
def test_copy_dest_lock_wrapper(ansible_zos_module, ds_type, f_lock):
2066+
retries = 0
2067+
max_retries = 5
2068+
success = False
2069+
2070+
# Not adding a try/except block here so a real exception can bubble up
2071+
# and stop pytest immediately (if using -x or --stop).
2072+
while retries < max_retries:
2073+
print(f'Trying dest lock for {ds_type}. Expecting success? {f_lock}. Retry: {retries}.')
2074+
result = copy_dest_lock(ansible_zos_module, ds_type, f_lock)
2075+
2076+
if result:
2077+
success = True
2078+
break
2079+
2080+
retries += 1
2081+
2082+
assert success is True
2083+
2084+
2085+
def copy_dest_lock(ansible_zos_module, ds_type, f_lock):
20662086
hosts = ansible_zos_module
2087+
assert_msg = ""
2088+
2089+
temp_dir = None
20672090
data_set_1 = get_tmp_ds_name()
20682091
data_set_2 = get_tmp_ds_name(llq_size=4)
20692092
data_set_2 = f"{data_set_2}$#@"
@@ -2074,25 +2097,100 @@ def test_copy_dest_lock(ansible_zos_module, ds_type, f_lock ):
20742097
else:
20752098
src_data_set = data_set_1
20762099
dest_data_set = data_set_2
2100+
20772101
try:
2078-
hosts.all.zos_data_set(name=data_set_1, state="present", type=ds_type, replace=True)
2079-
hosts.all.zos_data_set(name=data_set_2, state="present", type=ds_type, replace=True)
2102+
ds_creation_result = hosts.all.zos_data_set(
2103+
name=data_set_1,
2104+
state="present",
2105+
type=ds_type,
2106+
replace=True
2107+
)
2108+
for result in ds_creation_result.contacted.values():
2109+
assert_msg = result.get("stdout", "")
2110+
print(result)
2111+
assert result.get("changed") is True
2112+
assert result.get("failed", False) is False
2113+
2114+
ds_creation_result = hosts.all.zos_data_set(
2115+
name=data_set_2,
2116+
state="present",
2117+
type=ds_type,
2118+
replace=True
2119+
)
2120+
for result in ds_creation_result.contacted.values():
2121+
assert_msg = result.get("stdout", "")
2122+
print(result)
2123+
assert result.get("changed") is True
2124+
assert result.get("failed", False) is False
2125+
20802126
if ds_type == "pds" or ds_type == "pdse":
2081-
hosts.all.zos_data_set(name=src_data_set, state="present", type="member", replace=True)
2082-
hosts.all.zos_data_set(name=dest_data_set, state="present", type="member", replace=True)
2127+
member_creation_result = hosts.all.zos_data_set(
2128+
name=src_data_set,
2129+
state="present",
2130+
type="member",
2131+
replace=True
2132+
)
2133+
for result in member_creation_result.contacted.values():
2134+
assert_msg = result.get("stdout", "")
2135+
print(result)
2136+
assert result.get("changed") is True
2137+
assert result.get("failed", False) is False
2138+
2139+
member_creation_result = hosts.all.zos_data_set(
2140+
name=dest_data_set,
2141+
state="present",
2142+
type="member",
2143+
replace=True
2144+
)
2145+
for result in member_creation_result.contacted.values():
2146+
assert_msg = result.get("stdout", "")
2147+
print(result)
2148+
assert result.get("changed") is True
2149+
assert result.get("failed", False) is False
2150+
20832151
# copy text_in source
2084-
hosts.all.shell(cmd="decho \"{0}\" \"{1}\"".format(DUMMY_DATA, src_data_set))
2152+
decho_result = hosts.all.shell(cmd="decho \"{0}\" \"{1}\"".format(DUMMY_DATA, src_data_set))
2153+
for result in decho_result.contacted.values():
2154+
assert_msg = result.get("stdout", "")
2155+
print(result)
2156+
assert result.get("changed") is True
2157+
assert result.get("failed", False) is False
2158+
20852159
# copy/compile c program and copy jcl to hold data set lock for n seconds in background(&)
20862160
temp_dir = get_random_file_name(dir=TMP_DIRECTORY)
2087-
hosts.all.zos_copy(content=c_pgm, dest=f'{temp_dir}/pdse-lock.c', force=True)
2088-
hosts.all.zos_copy(
2161+
c_src_result = hosts.all.zos_copy(content=c_pgm, dest=f'{temp_dir}/pdse-lock.c', force=True)
2162+
for result in c_src_result.contacted.values():
2163+
assert_msg = result.get("stdout", "")
2164+
print(result)
2165+
assert result.get("changed") is True
2166+
assert result.get("failed", False) is False
2167+
2168+
jcl_result = hosts.all.zos_copy(
20892169
content=call_c_jcl.format(temp_dir, dest_data_set),
20902170
dest=f'{temp_dir}/call_c_pgm.jcl',
20912171
force=True
20922172
)
2093-
hosts.all.shell(cmd="xlc -o pdse-lock pdse-lock.c", chdir=f"{temp_dir}/")
2173+
for result in jcl_result.contacted.values():
2174+
assert_msg = result.get("stdout", "")
2175+
print(result)
2176+
assert result.get("changed") is True
2177+
assert result.get("failed", False) is False
2178+
2179+
subproc_result = hosts.all.shell(cmd="xlc -o pdse-lock pdse-lock.c", chdir=f"{temp_dir}/")
2180+
for result in subproc_result.contacted.values():
2181+
assert_msg = result.get("stdout", "")
2182+
print(result)
2183+
assert result.get("changed") is True
2184+
assert result.get("failed", False) is False
2185+
20942186
# submit jcl
2095-
hosts.all.shell(cmd="submit call_c_pgm.jcl", chdir=f"{temp_dir}/")
2187+
job_result = hosts.all.shell(cmd="submit call_c_pgm.jcl", chdir=f"{temp_dir}/")
2188+
for result in job_result.contacted.values():
2189+
assert_msg = result.get("stdout", "")
2190+
print(result)
2191+
assert result.get("changed") is True
2192+
assert result.get("failed", False) is False
2193+
20962194
# pause to ensure c code acquires lock
20972195
time.sleep(5)
20982196
results = hosts.all.zos_copy(
@@ -2102,7 +2200,9 @@ def test_copy_dest_lock(ansible_zos_module, ds_type, f_lock ):
21022200
force=True,
21032201
force_lock=f_lock,
21042202
)
2203+
21052204
for result in results.contacted.values():
2205+
assert_msg = result.get("stdout", "")
21062206
print(result)
21072207
if f_lock: #and apf_auth_user:
21082208
assert result.get("changed") == True
@@ -2126,14 +2226,24 @@ def test_copy_dest_lock(ansible_zos_module, ds_type, f_lock ):
21262226
assert result.get("changed") == False
21272227
assert "because a task is accessing the data set" in result.get("msg")
21282228
assert result.get("rc") is None
2229+
2230+
return True
2231+
except AssertionError:
2232+
# Checking for the error code from when the system thinks both data sets
2233+
# are identical.
2234+
if "FSUM8977" in assert_msg:
2235+
return False
2236+
else:
2237+
raise
21292238
finally:
21302239
# extract pid
21312240
ps_list_res = hosts.all.shell(cmd="ps -e | grep -i 'pdse-lock'")
21322241
# kill process - release lock - this also seems to end the job
21332242
pid = list(ps_list_res.contacted.values())[0].get('stdout').strip().split(' ')[0]
21342243
hosts.all.shell(cmd="kill 9 {0}".format(pid.strip()))
21352244
# clean up c code/object/executable files, jcl
2136-
hosts.all.shell(cmd=f'rm -r {temp_dir}')
2245+
if temp_dir is not None:
2246+
hosts.all.shell(cmd=f'rm -r {temp_dir}')
21372247
# remove pdse
21382248
hosts.all.zos_data_set(name=data_set_1, state="absent")
21392249
hosts.all.zos_data_set(name=data_set_2, state="absent")
@@ -2143,15 +2253,38 @@ def test_copy_dest_lock(ansible_zos_module, ds_type, f_lock ):
21432253
@pytest.mark.pdse
21442254
@pytest.mark.asa
21452255
@pytest.mark.parametrize("ds_type, f_lock",[
2146-
( "pds", True), # Success path, pds locked, force_lock enabled and user authorized
2147-
( "pdse", True), # Success path, pdse locked, force_lock enabled and user authorized
2148-
( "seq", True), # Success path, seq locked, force_lock enabled and user authorized
2149-
( "pds", False), # Module exits with: Unable to write to dest '{0}' because a task is accessing the data set."
2150-
( "pdse", False), # Module exits with: Unable to write to dest '{0}' because a task is accessing the data set."
2151-
( "seq", False), # Module exits with: Unable to write to dest '{0}' because a task is accessing the data set."
2256+
("pds", True), # Success path, pds locked, force_lock enabled and user authorized
2257+
("pdse", True), # Success path, pdse locked, force_lock enabled and user authorized
2258+
("seq", True), # Success path, seq locked, force_lock enabled and user authorized
2259+
("pds", False), # Module exits with: Unable to write to dest '{0}' because a task is accessing the data set."
2260+
("pdse", False), # Module exits with: Unable to write to dest '{0}' because a task is accessing the data set."
2261+
("seq", False), # Module exits with: Unable to write to dest '{0}' because a task is accessing the data set."
21522262
])
2153-
def test_copy_asa_dest_lock(ansible_zos_module, ds_type, f_lock ):
2263+
def test_copy_dest_lock_wrapper_asa(ansible_zos_module, ds_type, f_lock):
2264+
retries = 0
2265+
max_retries = 5
2266+
success = False
2267+
2268+
# Not adding a try/except block here so a real exception can bubble up
2269+
# and stop pytest immediately (if using -x or --stop).
2270+
while retries < max_retries:
2271+
print(f'Trying dest lock for {ds_type}. Expecting success? {f_lock}. Retry: {retries}.')
2272+
result = copy_asa_dest_lock(ansible_zos_module, ds_type, f_lock)
2273+
2274+
if result:
2275+
success = True
2276+
break
2277+
2278+
retries += 1
2279+
2280+
assert success is True
2281+
2282+
2283+
def copy_asa_dest_lock(ansible_zos_module, ds_type, f_lock):
21542284
hosts = ansible_zos_module
2285+
assert_msg = ""
2286+
2287+
temp_dir = None
21552288
data_set = get_tmp_ds_name(llq_size=4)
21562289
data_set = f"{data_set}$#@"
21572290
member_name = "MEM1"
@@ -2162,21 +2295,67 @@ def test_copy_asa_dest_lock(ansible_zos_module, ds_type, f_lock ):
21622295
dest_data_set = data_set
21632296

21642297
try:
2165-
hosts.all.zos_data_set(name=data_set, state="present", type=ds_type, replace=True, record_format="fba")
2298+
ds_creation_result = hosts.all.zos_data_set(
2299+
name=data_set,
2300+
state="present",
2301+
type=ds_type,
2302+
replace=True,
2303+
record_format="fba"
2304+
)
2305+
for result in ds_creation_result.contacted.values():
2306+
assert_msg = result.get("stdout", "")
2307+
print(result)
2308+
assert result.get("changed") is True
2309+
assert result.get("failed", False) is False
2310+
21662311
if ds_type == "pds" or ds_type == "pdse":
2167-
hosts.all.zos_data_set(name=dest_data_set, state="present", type="member", replace=True)
2312+
member_creation_result = hosts.all.zos_data_set(
2313+
name=dest_data_set,
2314+
state="present",
2315+
type="member",
2316+
replace=True
2317+
)
2318+
for result in member_creation_result.contacted.values():
2319+
assert_msg = result.get("stdout", "")
2320+
print(result)
2321+
assert result.get("changed") is True
2322+
assert result.get("failed", False) is False
21682323

21692324
# copy/compile c program and copy jcl to hold data set lock for n seconds in background(&)
21702325
temp_dir = get_random_file_name(dir=TMP_DIRECTORY)
2171-
hosts.all.zos_copy(content=c_pgm, dest=f'{temp_dir}/pdse-lock.c', force=True)
2172-
hosts.all.zos_copy(
2326+
c_src_result = hosts.all.zos_copy(content=c_pgm, dest=f'{temp_dir}/pdse-lock.c', force=True)
2327+
for result in c_src_result.contacted.values():
2328+
assert_msg = result.get("stdout", "")
2329+
print(result)
2330+
assert result.get("changed") is True
2331+
assert result.get("failed", False) is False
2332+
2333+
jcl_result = hosts.all.zos_copy(
21732334
content=call_c_jcl.format(temp_dir, dest_data_set),
21742335
dest=f'{temp_dir}/call_c_pgm.jcl',
21752336
force=True
21762337
)
2177-
hosts.all.shell(cmd="xlc -o pdse-lock pdse-lock.c", chdir=f"{temp_dir}/")
2338+
for result in jcl_result.contacted.values():
2339+
assert_msg = result.get("stdout", "")
2340+
print(result)
2341+
assert result.get("changed") is True
2342+
assert result.get("failed", False) is False
2343+
2344+
subproc_result = hosts.all.shell(cmd="xlc -o pdse-lock pdse-lock.c", chdir=f"{temp_dir}/")
2345+
for result in subproc_result.contacted.values():
2346+
assert_msg = result.get("stdout", "")
2347+
print(result)
2348+
assert result.get("changed") is True
2349+
assert result.get("failed", False) is False
2350+
21782351
# submit jcl
2179-
hosts.all.shell(cmd="submit call_c_pgm.jcl", chdir=f"{temp_dir}/")
2352+
job_result = hosts.all.shell(cmd="submit call_c_pgm.jcl", chdir=f"{temp_dir}/")
2353+
for result in job_result.contacted.values():
2354+
assert_msg = result.get("stdout", "")
2355+
print(result)
2356+
assert result.get("changed") is True
2357+
assert result.get("failed", False) is False
2358+
21802359
# pause to ensure c code acquires lock
21812360
time.sleep(5)
21822361

@@ -2190,6 +2369,7 @@ def test_copy_asa_dest_lock(ansible_zos_module, ds_type, f_lock ):
21902369
)
21912370

21922371
for result in results.contacted.values():
2372+
assert_msg = result.get("stdout", "")
21932373
print(result)
21942374
if f_lock: #and apf_auth_user:
21952375
assert result.get("changed") is True
@@ -2212,14 +2392,24 @@ def test_copy_asa_dest_lock(ansible_zos_module, ds_type, f_lock ):
22122392
assert result.get("changed") is False
22132393
assert "because a task is accessing the data set" in result.get("msg")
22142394
assert result.get("rc") is None
2395+
2396+
return True
2397+
except AssertionError:
2398+
# Checking for the error code from when the system thinks both data sets
2399+
# are identical.
2400+
if "FSUM8977" in assert_msg:
2401+
return False
2402+
else:
2403+
raise
22152404
finally:
22162405
# extract pid
22172406
ps_list_res = hosts.all.shell(cmd="ps -e | grep -i 'pdse-lock'")
22182407
# kill process - release lock - this also seems to end the job
22192408
pid = list(ps_list_res.contacted.values())[0].get('stdout').strip().split(' ')[0]
22202409
hosts.all.shell(cmd="kill 9 {0}".format(pid.strip()))
22212410
# clean up c code/object/executable files, jcl
2222-
hosts.all.shell(cmd=f'rm -r {temp_dir}')
2411+
if temp_dir is not None:
2412+
hosts.all.shell(cmd=f'rm -r {temp_dir}')
22232413
# remove destination data set.
22242414
hosts.all.zos_data_set(name=data_set, state="absent")
22252415

0 commit comments

Comments
 (0)