Skip to content

Commit ece9e79

Browse files
committed
test(bash_env_saved): continue restoring on restoring error
`bash_env_saved' now tries to proceed the process of the restoration of the shell environment even when some of restoration operations fail in order to reduce later errors caused by incomplete restoration.
1 parent 5264bd1 commit ece9e79

File tree

1 file changed

+63
-25
lines changed

1 file changed

+63
-25
lines changed

test/t/conftest.py

Lines changed: 63 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,9 @@ def __init__(self, bash: pexpect.spawn, sendintr: bool = False):
406406
self.saved_variables: Dict[str, int] = {}
407407
self.sendintr = sendintr
408408

409+
self.noexcept: bool = False
410+
self.captured_error: Optional[Exception] = None
411+
409412
def __enter__(self):
410413
return self
411414

@@ -418,55 +421,87 @@ def __exit__(
418421
self._restore_env()
419422
return None
420423

424+
def _safe_sendintr(self):
425+
try:
426+
self.bash.sendintr()
427+
self.bash.expect_exact(PS1)
428+
except Exception as e:
429+
if self.noexcept:
430+
self.captured_error = e
431+
else:
432+
raise
433+
434+
def _safe_exec(self, cmd: str):
435+
try:
436+
self.bash.sendline(cmd)
437+
self.bash.expect_exact(cmd)
438+
self.bash.expect_exact("\r\n" + PS1)
439+
except Exception as e:
440+
if self.noexcept:
441+
self._safe_sendintr()
442+
self.captured_error = e
443+
else:
444+
raise
445+
446+
def _safe_assert(self, cmd: str):
447+
try:
448+
assert_bash_exec(self.bash, cmd, want_output=None)
449+
except Exception as e:
450+
if self.noexcept:
451+
self._safe_sendintr()
452+
self.captured_error = e
453+
else:
454+
raise
455+
421456
def _copy_variable(self, src_var: str, dst_var: str):
422-
assert_bash_exec(
423-
self.bash,
457+
self._safe_exec(
424458
"if [[ ${%s+set} ]]; then %s=${%s}; else unset -v %s; fi"
425459
% (src_var, dst_var, src_var, dst_var),
426460
)
427461

428462
def _unset_variable(self, varname: str):
429-
assert_bash_exec(self.bash, "unset -v %s" % varname)
463+
self._safe_exec("unset -v %s" % varname)
430464

431465
def _save_cwd(self):
432466
if not self.cwd_changed:
433467
self.cwd_changed = True
434468
self._copy_variable("PWD", "_BASHCOMP_TEST_OLDPWD")
435469

436470
def _check_shopt(self, name: str):
437-
assert_bash_exec(
438-
self.bash,
471+
self._safe_assert(
439472
'[[ $(shopt -p %s) == "${_BASHCOMP_TEST_NEWSHOPT_%s}" ]]'
440473
% (name, name),
441474
)
442475

443476
def _unprotect_shopt(self, name: str):
444477
if name not in self.saved_shopt:
445478
self.saved_shopt[name] = 1
446-
assert_bash_exec(
447-
self.bash,
448-
"_BASHCOMP_TEST_OLDSHOPT_%s=$(shopt -p %s; true)"
479+
self._safe_exec(
480+
"_BASHCOMP_TEST_OLDSHOPT_%s=$(shopt -p %s || true)"
449481
% (name, name),
450482
)
451483
else:
452484
self._check_shopt(name)
453485

454486
def _protect_shopt(self, name: str):
455-
assert_bash_exec(
456-
self.bash,
457-
"_BASHCOMP_TEST_NEWSHOPT_%s=$(shopt -p %s; true)" % (name, name),
487+
self._safe_exec(
488+
"_BASHCOMP_TEST_NEWSHOPT_%s=$(shopt -p %s || true)" % (name, name),
458489
)
459490

460491
def _check_variable(self, varname: str):
461492
try:
462-
assert_bash_exec(
463-
self.bash,
493+
self._safe_assert(
464494
'[[ ${%s-%s} == "${_BASHCOMP_TEST_NEWVAR_%s-%s}" ]]'
465495
% (varname, MAGIC_MARK2, varname, MAGIC_MARK2),
466496
)
467-
except AssertionError:
497+
except Exception:
468498
self._copy_variable("_BASHCOMP_TEST_NEWVAR_" + varname, varname)
469499
raise
500+
else:
501+
if self.noexcept and self.captured_error:
502+
self._copy_variable(
503+
"_BASHCOMP_TEST_NEWVAR_" + varname, varname
504+
)
470505

471506
def _unprotect_variable(self, varname: str):
472507
if varname not in self.saved_variables:
@@ -479,24 +514,23 @@ def _protect_variable(self, varname: str):
479514
self._copy_variable(varname, "_BASHCOMP_TEST_NEWVAR_" + varname)
480515

481516
def _restore_env(self):
517+
self.noexcept = True
518+
482519
if self.sendintr:
483-
self.bash.sendintr()
484-
self.bash.expect_exact(PS1)
520+
self._safe_sendintr()
485521

486522
# We first go back to the original directory before restoring
487523
# variables because "cd" affects "OLDPWD".
488524
if self.cwd_changed:
489525
self._unprotect_variable("OLDPWD")
490-
assert_bash_exec(self.bash, 'cd "$_BASHCOMP_TEST_OLDPWD"')
526+
self._safe_exec('cd "$_BASHCOMP_TEST_OLDPWD"' % self.prefix)
491527
self._protect_variable("OLDPWD")
492528
self._unset_variable("_BASHCOMP_TEST_OLDPWD")
493529
self.cwd_changed = False
494530

495531
for name in self.saved_shopt:
496532
self._check_shopt(name)
497-
assert_bash_exec(
498-
self.bash, 'eval "$_BASHCOMP_TEST_OLDSHOPT_%s"' % name
499-
)
533+
self._safe_exec('eval "$_BASHCOMP_TEST_OLDSHOPT_%s"' % name)
500534
self._unset_variable("_BASHCOMP_TEST_OLDSHOPT_" + name)
501535
self._unset_variable("_BASHCOMP_TEST_NEWSHOPT_" + name)
502536
self.saved_shopt = {}
@@ -508,26 +542,30 @@ def _restore_env(self):
508542
self._unset_variable("_BASHCOMP_TEST_NEWVAR_" + varname)
509543
self.saved_variables = {}
510544

545+
self.noexcept = False
546+
if self.captured_error:
547+
raise self.captured_error
548+
511549
def chdir(self, path: str):
512550
self._save_cwd()
513551
self.cwd_changed = True
514552
self._unprotect_variable("OLDPWD")
515-
assert_bash_exec(self.bash, "cd %s" % shlex.quote(path))
553+
self._safe_exec("cd %s" % shlex.quote(path))
516554
self._protect_variable("OLDPWD")
517555

518556
def shopt(self, name: str, value: bool):
519557
self._unprotect_shopt(name)
520558
if value:
521-
assert_bash_exec(self.bash, "shopt -s %s" % name)
559+
self._safe_exec("shopt -s %s" % name)
522560
else:
523-
assert_bash_exec(self.bash, "shopt -u %s" % name)
561+
self._safe_exec("shopt -u %s" % name)
524562
self._protect_shopt(name)
525563

526564
def write_variable(self, varname: str, new_value: str, quote: bool = True):
527565
if quote:
528566
new_value = shlex.quote(new_value)
529567
self._unprotect_variable(varname)
530-
assert_bash_exec(self.bash, "%s=%s" % (varname, new_value))
568+
self._safe_exec("%s=%s" % (varname, new_value))
531569
self._protect_variable(varname)
532570

533571
# TODO: We may restore the "export" attribute as well though it is
@@ -536,7 +574,7 @@ def write_env(self, envname: str, new_value: str, quote: bool = True):
536574
if quote:
537575
new_value = shlex.quote(new_value)
538576
self._unprotect_variable(envname)
539-
assert_bash_exec(self.bash, "export %s=%s" % (envname, new_value))
577+
self._safe_exec("export %s=%s" % (envname, new_value))
540578
self._protect_variable(envname)
541579

542580

0 commit comments

Comments
 (0)