Skip to content

Commit

Permalink
Implement tmt try for interactive sessions
Browse files Browse the repository at this point in the history
Basic functionality for the new `tmt try` command to be used for
test development in an interactive session. Supports running tests
from the current working directory as well as quick experimenting
with selected distro image and provision method. Simple user plan
config is included as well.
  • Loading branch information
psss committed Dec 5, 2023
1 parent 45cafe6 commit 5b7f892
Show file tree
Hide file tree
Showing 49 changed files with 948 additions and 82 deletions.
4 changes: 4 additions & 0 deletions docs/overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,10 @@ TMT_PLUGINS
Path to a directory with additional plugins. Multiple paths
separated with the ``:`` character can be provided as well.

TMT_CONFIG_DIR
Path to an alternative directory with config files. By default
``~/.config/tmt`` is used.

TMT_WORKDIR_ROOT
Path to root directory containing run workdirs. Defaults to
``/var/tmp/tmt``.
Expand Down
8 changes: 8 additions & 0 deletions docs/releases.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@
tmt-1.30
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The new :ref:`tmt try</stories/cli/try>` command provides an
interactive session which allows to easily run tests and
experiment with the provisioned guest. The functionality might
still change. This is the very first proof of concept included in
the release as a **tech preview** to gather early feedback and
finalize the outlined design. Give it a :ref:`/stories/cli/try`
and let us know what you think! :)

The :ref:`/spec/core/contact` key has been moved from the
:ref:`/spec/tests` specification to the :ref:`/spec/core`
attributes so now it can be used with plans and stories as well.
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ ignore = [
"tmt/lint.py",
"tmt/queue.py",
"tmt/templates.py",
"tmt/trying.py",
"tmt/utils.py"
]

Expand Down
4 changes: 2 additions & 2 deletions stories/cli/run.fmf
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ story: 'As a user I want to execute tests easily'
For example use ``execute -h beakerlib`` to execute
tests using the beakerlib method.
example: |
/plans/default:
/default/plan:
summary:
Default plan when fmf metadata found
discover:
how: fmf
execute:
how: shell

/plans/default:
/default/plan:
summary:
Default plan when no fmf metadata around
discover:
Expand Down
129 changes: 129 additions & 0 deletions stories/cli/try.fmf
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
story:
As a tester or developer I want an easy and comfortable way to
run tests and experiment with various versions of the
operating system.

link:
- implemented-by: /tmt/trying.py
- verified-by: /tests/try

/test:
story:
As a test developer I want an easy way to run a single
test on a freshly provisioned guest.

description: |
One of the most common scenarios is to run a single test
in a given environment so that the test developer can

* verify the newly created test works as expected
* debug failures discovered during testing and fix them

.. versionadded:: 1.30

example:
- |
# Run test stored in the current working directory using
# the default provision method and image
cd tests/core/smoke
tmt try

- |
# By default we run in verbose level 3, choose a lower
# level if more concise output is enough for you
cd tests/core/smoke
tmt -v try
tmt -vv try

- |
# Run it against the specified distro image
cd tests/core/smoke
tmt try fedora-37

- |
# Run it using given provision method and image
cd tests/core/smoke
tmt try fedora:38@container

- |
# Use custom filter to select tests instead of the current
# working directory
cd tests/core/smoke
tmt try --test feature

- |
# Select plan from the repository instead of default
cd tests/core/smoke
tmt try --plan plan

/guest:
story:
As a user I want to quickly experiment with a freshly
provisioned guest.

description: |
Sometimes it's handy to be able to quickly spawn a new
clean guest and start experimeting in the sand box. Run
the ``tmt try`` command in a directory without tests or
explicitly ask for interactive shell with ``--login``.

.. versionadded:: 1.30

example:
- |
# Provision default distro, log into it for experimenting
# (make sure there are no tests in the current directory)
tmt try

- |
# Provision desired distro, log into it for experimenting
# (make sure there are no tests in the current directory)
tmt try rhel-9

- |
# Explicitly ask for login only if there are tests around
tmt try --login
tmt try -l

- |
# Do nothing, just provision the guest and ask what to do
tmt try --ask
tmt try -a

/config:
story:
As a tester I usually run tests using my preferred
provision method and I don't want to write it on the
command line again and again.

description: |
Define your custom user plan to be used by default when
using the ``tmt try`` command and store it under the
config directory ``~/.config/tmt``. All plans starting
with ``/user/plan`` will be used for experimenting.

Note that the config directory is a tmt :ref:`Tree<tree>`
so don't forget to initialize it. You can copy & paste the
following commands to get quickly started:

.. code-block:: shell

mkdir -p ~/.config/tmt
cd ~/.config/tmt
tmt init
tmt plan create --template full /user/plan

.. versionadded:: 1.30

example: |
# ~/.config/tmt/user/plan.fmf
discover:
how: fmf
provision:
how: container
image: "fedora:fresh"
prepare:
how: install
package: vim
execute:
how: tmt
24 changes: 12 additions & 12 deletions tests/discover/distgit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ done
) > $MOCK_SOURCES_FILENAME

WORKDIR=/var/tmp/tmt/XXX
WORKDIR_SOURCE=$WORKDIR/plans/default/discover/default-0/source
WORKDIR_TESTS=$WORKDIR/plans/default/discover/default-0/tests
WORKDIR_SOURCE=$WORKDIR/default/plan/discover/default-0/source
WORKDIR_TESTS=$WORKDIR/default/plan/discover/default-0/tests

rlRun -s "tmt run --keep --id $WORKDIR --scratch plans --default \
discover -vvv -ddd --how fmf --dist-git-source \
Expand Down Expand Up @@ -196,8 +196,8 @@ done
echo "simple-1.tgz" > $MOCK_SOURCES_FILENAME

WORKDIR=/var/tmp/tmt/XXX
WORKDIR_SOURCE=$WORKDIR/plans/default/discover/default-0/source
WORKDIR_TESTS=$WORKDIR/plans/default/discover/default-0/tests
WORKDIR_SOURCE=$WORKDIR/default/plan/discover/default-0/source
WORKDIR_TESTS=$WORKDIR/default/plan/discover/default-0/tests

rlRun -s 'tmt run --id $WORKDIR --scratch plans --default \
discover -vvv -ddd --how fmf --dist-git-source \
Expand Down Expand Up @@ -226,8 +226,8 @@ done
echo "simple-1.tgz" > $MOCK_SOURCES_FILENAME

WORKDIR=/var/tmp/tmt/XXX
WORKDIR_SOURCE=$WORKDIR/plans/default/discover/default-0/source
WORKDIR_TESTS=$WORKDIR/plans/default/discover/default-0/tests
WORKDIR_SOURCE=$WORKDIR/default/plan/discover/default-0/source
WORKDIR_TESTS=$WORKDIR/default/plan/discover/default-0/tests

rlRun -s 'tmt run --id $WORKDIR --scratch plans --default \
discover -v --how fmf --dist-git-source \
Expand Down Expand Up @@ -255,8 +255,8 @@ done
echo "simple-1.tgz renamed_simple.tgz" > $MOCK_SOURCES_FILENAME

WORKDIR=/var/tmp/tmt/XXX
WORKDIR_SOURCE=$WORKDIR/plans/default/discover/default-0/source
WORKDIR_TESTS=$WORKDIR/plans/default/discover/default-0/tests
WORKDIR_SOURCE=$WORKDIR/default/plan/discover/default-0/source
WORKDIR_TESTS=$WORKDIR/default/plan/discover/default-0/tests

rlRun -s 'tmt run --id $WORKDIR --scratch plans --default \
discover -v --how fmf --dist-git-source \
Expand Down Expand Up @@ -284,8 +284,8 @@ done
echo "simple-1.tgz simple.tgz" > $MOCK_SOURCES_FILENAME

WORKDIR=/var/tmp/tmt/XXX
WORKDIR_SOURCE=$WORKDIR/plans/default/discover/default-0/source
WORKDIR_TESTS=$WORKDIR/plans/default/discover/default-0/tests
WORKDIR_SOURCE=$WORKDIR/default/plan/discover/default-0/source
WORKDIR_TESTS=$WORKDIR/default/plan/discover/default-0/tests

rlRun -s 'tmt run --id $WORKDIR --scratch plans --default \
discover -v --how fmf --dist-git-source \
Expand Down Expand Up @@ -369,8 +369,8 @@ done
rlRun "tmt init"

WORKDIR=/var/tmp/tmt/XXX
WORKDIR_SOURCE=$WORKDIR/plans/default/discover/default-0/source
WORKDIR_TESTS=$WORKDIR/plans/default/discover/default-0/tests
WORKDIR_SOURCE=$WORKDIR/default/plan/discover/default-0/source
WORKDIR_TESTS=$WORKDIR/default/plan/discover/default-0/tests

rlRun -s "tmt run --keep --id $WORKDIR --scratch plans --default \
discover -vvv -ddd --how fmf --dist-git-source \
Expand Down
2 changes: 1 addition & 1 deletion tests/discover/force.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ rlJournalStart
rlPhaseEnd

plan="plans --default"
test_yaml="$workdir/run/plans/default/discover/tests.yaml"
test_yaml="$workdir/run/default/plan/discover/tests.yaml"

rlPhaseStartTest
# Fresh run with no required packages
Expand Down
2 changes: 1 addition & 1 deletion tests/discover/serial-number.sh
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ rlJournalStart
rlPhaseStartTest "Single '/' test"
rlRun 'pushd serial-number-root-test'
rlRun "tmt -vv run --scratch --id $workdir discover -h fmf"
rlRun -s "yq -er '.[] | \"\\(.name) \\(.\"serial-number\")\"' $workdir/plans/default/discover/tests.yaml"
rlRun -s "yq -er '.[] | \"\\(.name) \\(.\"serial-number\")\"' $workdir/default/plan/discover/tests.yaml"
rlAssertGrep "/ 1" $rlRun_LOG
rlRun 'popd'
rlPhaseEnd
Expand Down
2 changes: 1 addition & 1 deletion tests/execute/filesubmit/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ rlJournalStart
rlPhaseEnd

# would be set by TMT_TEST_DATA
tmt_test_data="plans/default/execute/data/guest/default-0/default-1/data"
tmt_test_data="default/plan/execute/data/guest/default-0/default-1/data"

rlPhaseStartTest
rlRun "tmt run -vfi $tmp -a provision -h container"
Expand Down
2 changes: 1 addition & 1 deletion tests/execute/result/basic.sh
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ EOF

rlPhaseStartTest "Verify fmf context lands in results"
rlRun -s "tmt -c foo=bar run --id ${run} --scratch -a provision --how local test -n '/pass'"
rlAssertEquals "Context is stored in result" "$(yq -r ".[] | .context | to_entries[] | \"\\(.key)=\\(.value[])\"" $run/plans/default/execute/results.yaml)" "foo=bar"
rlAssertEquals "Context is stored in result" "$(yq -r ".[] | .context | to_entries[] | \"\\(.key)=\\(.value[])\"" $run/default/plan/execute/results.yaml)" "foo=bar"
rlPhaseEnd

rlPhaseStartCleanup
Expand Down
4 changes: 2 additions & 2 deletions tests/execute/result/custom.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ rlJournalStart
rlAssertExists "$(sed -n 's/ *another_log: \(.\+\)/\1/p' $rlRun_LOG)"
rlAssertExists "$(sed -n 's/ *slash_log: \(.\+\)/\1/p' $rlRun_LOG)"

rlRun -s "yq -er '.[] | \"\\(.name) \\(.\"serial-number\") \\(.result) \\(.guest.name)\"' $run/plans/default/execute/results.yaml"
rlRun -s "yq -er '.[] | \"\\(.name) \\(.\"serial-number\") \\(.result) \\(.guest.name)\"' $run/default/plan/execute/results.yaml"
rlAssertGrep "/test/custom-results/test/passing 1 pass default-0" $rlRun_LOG
rlAssertGrep "/test/custom-results/test/failing 1 fail default-0" $rlRun_LOG
rlAssertGrep "/test/custom-results 1 pass default-0" $rlRun_LOG
Expand All @@ -51,7 +51,7 @@ rlJournalStart
testName="/test/missing-custom-results"
rlPhaseStartTest "${testName}"
rlRun -s "${tmt_command} ${testName} 2>&1 >/dev/null" 2 "Test does not provide 'results.yaml' file"
rlAssertGrep "custom results file not found in '/tmp/.*/plans/default/execute/data/guest/default-0/test/missing-custom-results-1/data" $rlRun_LOG
rlAssertGrep "custom results file not found in '/tmp/.*/default/plan/execute/data/guest/default-0/test/missing-custom-results-1/data" $rlRun_LOG
rlPhaseEnd

testName="/test/empty-custom-results-file"
Expand Down
2 changes: 1 addition & 1 deletion tests/full/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ rlJournalStart


rlRun "su -l -c 'tmt run --id $CONNECT_RUN plans --default provision -h virtual' $USER"
CONNECT_TO=$CONNECT_RUN/plans/default/provision/guests.yaml
CONNECT_TO=$CONNECT_RUN/default/plan/provision/guests.yaml
rlAssertExists $CONNECT_TO

# Create new plans/provision/connect.fmf
Expand Down
12 changes: 6 additions & 6 deletions tests/login/when.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ rlJournalStart
rlPhaseEnd

rlPhaseStartTest "Skipped"
rlRun "$tmt true login -w fail -c true 2>&1 >/dev/null | tee output"
rlAssertGrep "Skipping interactive" "output"
rlAssertNotGrep "Starting interactive" "output"
rlRun -s "$tmt true login -w fail -c true"
rlAssertGrep "Skipping interactive" $rlRun_LOG
rlAssertNotGrep "Starting interactive" $rlRun_LOG
rlPhaseEnd

rlPhaseStartTest "Enabled"
rlRun "$tmt false login -w fail -c true 2>&1 >/dev/null | tee output" 1
rlAssertNotGrep "Skipping interactive" "output"
rlAssertGrep "Starting interactive" "output"
rlRun -s "$tmt false login -w fail -c true" 1
rlAssertNotGrep "Skipping interactive" $rlRun_LOG
rlAssertGrep "Starting interactive" $rlRun_LOG
rlPhaseEnd

rlPhaseStartCleanup
Expand Down
2 changes: 1 addition & 1 deletion tests/plan/import/basic.sh
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ rlJournalStart
rlAssertGrep "/plans/minimal" $rlRun_LOG
rlAssertGrep "/lint/tests" $rlRun_LOG
rlAssertGrep "/lint/plans" $rlRun_LOG
rlAssertNotGrep "/plans/default" $rlRun_LOG
rlAssertNotGrep "/default/plan" $rlRun_LOG
# logging import plan details in verbose mode
rlAssertGrep "import url: https:/teemtee/tmt" $rlRun_LOG
rlAssertGrep "import ref: 1.16.0" $rlRun_LOG
Expand Down
2 changes: 1 addition & 1 deletion tests/run/default/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ rlJournalStart
rlPhaseStartTest "Explicit default"
rlRun "tmt plan create -t mini plans/plan"
rlRun "tmt run $options plan --default 2>&1 >/dev/null | tee output"
rlAssertGrep "/plans/default" "output"
rlAssertGrep "/default/plan" "output"
rlAssertNotgrep "/plans/plan" "output"
rlPhaseEnd

Expand Down
2 changes: 1 addition & 1 deletion tests/run/follow/data/main.fmf
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
how: tmt

/test:
test: for i in {00..05}; do echo step-$i; sleep 1; done
test: for i in {00..10}; do echo step-$i; sleep 1; done
6 changes: 3 additions & 3 deletions tests/run/follow/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ rlJournalStart
rlPhaseStartTest
rlRun "tmt run --id $run &>/dev/null &" 0 "Start a tmt run in background"
rlRun "sleep 1" 0 "Ignore logging during the first second"
rlRun -s "timeout -s INT 3 tmt run --id $run --follow" 124 "Follow logs for 3 seconds"
rlRun -s "timeout -s INT 5 tmt run --id $run --follow" 124 "Follow logs for 5 seconds"
rlAssertGrep "step-01" $rlRun_LOG
rlAssertGrep "step-02" $rlRun_LOG
rlAssertNotGrep "step-04" $rlRun_LOG
rlAssertNotGrep "step-05" $rlRun_LOG
rlAssertNotGrep "step-09" $rlRun_LOG
rlAssertNotGrep "step-10" $rlRun_LOG
rlRun "wait $!" 0 "Wait until the run is finished"
rlPhaseEnd

Expand Down
1 change: 1 addition & 0 deletions tests/try/config/.fmf/version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
10 changes: 10 additions & 0 deletions tests/try/config/user.fmf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/plan:
discover:
how: fmf
provision:
how: local
prepare:
how: shell
script: echo custom-prepare
execute:
how: tmt
1 change: 1 addition & 0 deletions tests/try/data/.fmf/version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
7 changes: 7 additions & 0 deletions tests/try/data/keep.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/expect -f
# Select a plan and keep the run

spawn tmt try -p plan
expect "What do we do next?"
send -- "k\r"
expect eof
Loading

0 comments on commit 5b7f892

Please sign in to comment.