Skip to content

Commit 11cd5c3

Browse files
committed
Test should error out if pulling from guest fails
When the guest becomes unresponsive, make sure the test errors out instead of staying in `pending` state. Resolves #3647 Signed-off-by: Miroslav Vadkerti <[email protected]>
1 parent 718c4e4 commit 11cd5c3

File tree

6 files changed

+74
-26
lines changed

6 files changed

+74
-26
lines changed

docs/releases.rst

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
Releases
55
======================
66

7+
tmt-1.47.0
8+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9+
10+
Fixed a bug that caused executed tests to remain in the
11+
``pending`` state when the machine became unresponsive. Tests will
12+
now correctly transition to the ``error`` state.
713

814
tmt-1.46.0
915
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/test:
2+
test: shutdown -h now && sleep 60
3+
duration: 5s
4+
5+
/error:
6+
/pending:
7+
8+
/plan:
9+
discover:
10+
how: fmf
11+
execute:
12+
how: tmt

tests/execute/unresponsive/main.fmf

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
summary: Verify that test is marked as errored if machine becomes unresponsive.
2+
duration: 5m
3+
tag+:
4+
- provision-only
5+
- provision-virtual

tests/execute/unresponsive/test.sh

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/bin/bash
2+
. /usr/share/beakerlib/beakerlib.sh || exit 1
3+
4+
rlJournalStart
5+
rlPhaseStartSetup
6+
rlRun "tmp=\$(mktemp -d)" 0 "Creating tmp directory"
7+
rlRun "export TMT_WORKDIR_ROOT=$tmp"
8+
rlRun "pushd data"
9+
rlPhaseEnd
10+
11+
rlPhaseStartTest "Test must error out if machine becomes unresponsive during execution (#3630)."
12+
rlRun -s "tmt run -vv -a provision -h $PROVISION_HOW -i ~/temp/Fedora-Cloud-Base-Generic-42-1.1.x86_64.qcow2" "2"
13+
rlAssertGrep 'fail: Failed to pull workdir from the guest.' $rlRun_LOG '-F'
14+
rlAssertGrep 'errr /unresponsive/test/error' $rlRun_LOG '-F'
15+
rlAssertGrep 'pending /unresponsive/test/pending' $rlRun_LOG '-F'
16+
rlPhaseEnd
17+
18+
rlPhaseStartCleanup
19+
rlRun "popd"
20+
rlRun "rm -rf $tmp" 0 "Removing tmp directory"
21+
rlPhaseEnd
22+
rlJournalEnd

tmt/steps/execute/internal.py

+28-26
Original file line numberDiff line numberDiff line change
@@ -631,20 +631,33 @@ def _save_process(
631631
# overwrite it.
632632
self.write(invocation.path / TEST_OUTPUT_FILENAME, stdout or '', mode='a', level=3)
633633

634+
def pull_from_guest() -> None:
635+
if not invocation.is_guest_healthy:
636+
return
637+
638+
try:
639+
guest.pull(
640+
source=invocation.path,
641+
extend_options=[
642+
*test.test_framework.get_pull_options(invocation, logger),
643+
'--exclude',
644+
str(invocation.path / TEST_OUTPUT_FILENAME),
645+
],
646+
)
647+
648+
# Fetch plan data content as well in order to prevent
649+
# losing logs if the guest becomes later unresponsive.
650+
guest.pull(source=self.step.plan.data_directory)
651+
652+
# Handle failing to pull test artifacts after guest becoming
653+
# unresponsive. If not handled test would stay in 'pending' state.
654+
# See issue https://github.com/teemtee/tmt/issues/3647.
655+
except tmt.utils.RunError:
656+
pass
657+
634658
# Fetch #1: we need logs and everything the test produced so we could
635659
# collect its results.
636-
if invocation.is_guest_healthy:
637-
guest.pull(
638-
source=invocation.path,
639-
extend_options=[
640-
*test.test_framework.get_pull_options(invocation, logger),
641-
'--exclude',
642-
str(invocation.path / TEST_OUTPUT_FILENAME),
643-
],
644-
)
645-
# Fetch plan data content as well in order to prevent
646-
# losing logs if the guest becomes later unresponsive.
647-
guest.pull(source=self.step.plan.data_directory)
660+
pull_from_guest()
648661

649662
# Run after-test checks before extracting results
650663
invocation.check_results += self.run_checks_after_test(
@@ -656,20 +669,9 @@ def _save_process(
656669
# results after a successful reboot in the middle of a test.
657670
invocation.results = self.extract_results(invocation, logger)
658671

659-
if invocation.is_guest_healthy:
660-
# Fetch #2: after-test checks might have produced remote files as well,
661-
# we need to fetch them too.
662-
guest.pull(
663-
source=invocation.path,
664-
extend_options=[
665-
*test.test_framework.get_pull_options(invocation, logger),
666-
'--exclude',
667-
str(invocation.path / TEST_OUTPUT_FILENAME),
668-
],
669-
)
670-
# Fetch plan data content as well in order to prevent
671-
# losing logs if the guest becomes later unresponsive.
672-
guest.pull(source=self.step.plan.data_directory)
672+
# Fetch #2: after-test checks might have produced remote files as well,
673+
# we need to fetch them too.
674+
pull_from_guest()
673675

674676
# Attach check results to every test result. There might be more than one,
675677
# and it's hard to pick the main one, who knows what custom results might

0 commit comments

Comments
 (0)