Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

automatic tests for TUI (ncurses) #251

Merged
merged 16 commits into from
Oct 27, 2020
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions package/yast2-ruby-bindings.changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
-------------------------------------------------------------------
Tue Oct 13 14:42:52 UTC 2020 - Martin Vidner <[email protected]>

- Add automatic TUI (ncurses) tests using tmux (bsc#1165388).
- 4.3.5

-------------------------------------------------------------------
Thu Sep 24 19:46:00 UTC 2020 - [email protected]

Expand Down
8 changes: 4 additions & 4 deletions package/yast2-ruby-bindings.spec
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@


Name: yast2-ruby-bindings
Version: 4.3.4
Version: 4.3.5
Release: 0
URL: https://github.com/yast/yast-ruby-bindings
BuildRoot: %{_tmppath}/%{name}-%{version}-build
Expand Down Expand Up @@ -46,9 +46,9 @@ BuildRequires: yast2-ycp-ui-bindings-devel >= 4.3.1
# The test suite includes a regression test (std_streams_spec.rb) for a
# libyui-ncurses bug fixed in 2.47.3
BuildRequires: libyui-ncurses >= 2.47.3
# The mentioned test requires to check if tmux is there, because tmux is
# needed to execute the test in headless systems
BuildRequires: which
# The mentioned test requires tmux in order to be executed in headless systems
# Also many other libyui tests to come
BuildRequires: tmux

# only a soft dependency, the Ruby debugger is optional
Suggests: rubygem(%{rb_default_ruby_abi}:byebug)
Expand Down
16 changes: 13 additions & 3 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#
# CMakeLists.txt for yast2/ruby-bindings/tests/ruby
#
# CMakeLists.txt for yast-ruby-bindings/tests

# use
# make test
# or, for verbose output,
# make test ARGS=-V
# ARGS is passed to ctest; see also
# man ctest

ENABLE_TESTING()

Expand All @@ -12,3 +17,8 @@ endforeach(test)

ADD_TEST("integration" ruby ${CMAKE_CURRENT_SOURCE_DIR}/integration/run.rb)
ADD_TEST("translations" rspec --format doc ${CMAKE_CURRENT_SOURCE_DIR}/integration/translations_spec.rb)

file(GLOB libyui_tests "libyui/*.test")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, tests are in tmux which I do not know much, but fine for me. I have other issues:

  1. why it lives in yast2-ruby-bindings? it should be in libyui itself or libyui-bindings if you really want to use ruby and not write it as example program in C++. Do you really expect that libyui contributors search for it here and also run it on their magei/buntu/etc? Ideally it should be make && make check in libyui itself

  2. It tests too late. What happens here? It needs libyui, its bindings, then ycp-ui-bindings, then yast2-core and then yast2-ruby-bindings and then you can see what failed. To be honest I think it will be in comparable speed to get result from openqa itself. It is too slow for unit testing and looks more like full integration testing, where openqa is a better as it test more and has more tests.

foreach(test ${libyui_tests})
ADD_TEST(${test} ${test})
endforeach()
3 changes: 3 additions & 0 deletions tests/libyui/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

- `foo.test` - main script of the test case
- `foo.rb` - UI set up
37 changes: 37 additions & 0 deletions tests/libyui/menu_hotkeys_1177760.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/sh

# Test https://bugzilla.suse.com/show_bug.cgi?id=1177760
# Menu items lose their hotkeys

set -u # unset variables are an error
MYDIR=$(dirname "$0")
# shellcheck source=/dev/null # that file is checked separately
. "$MYDIR"/tmux-uitest.sh
BUG=1177760
BASE=menu_hotkeys_$BUG

tmux_new_session "${MYDIR}/yast_ncurses /usr/share/doc/packages/yast2-ycp-ui-bindings/examples/MenuBar1.rb" || exit
trap tmux_cleanup EXIT

tmux_await "File.*Edit.*View" || exit
sleep 0.1 # draw the rest of the screen
tmux_capture_pane_to "${BASE}-1-initial"

tmux_send_keys M-V # &View
tmux_capture_pane_to "${BASE}-2-view-menu-activated"

tmux_send_keys M-N # &Normal
tmux_capture_pane_to "${BASE}-3-normal-menu-item-activated"

if ! tmux_grep "Last Event"; then
echo "The script does not echo what it should"
exit 1
fi

if ! tmux_grep "view_normal"; then
echo "view_normal was not activated, bug boo#$BUG exists"
exit 1
fi

tmux_send_keys M-Q # &Quit
exit 0
12 changes: 12 additions & 0 deletions tests/libyui/shellcheck.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash
set -e
set -u

if ! type -P shellcheck >/dev/null; then
echo "SKIP https://www.shellcheck.net/ is not installed"
exit 0
fi

MYDIR=$(dirname "$0")
FILES=("$MYDIR"/*.test "$MYDIR"/tmux-uitest.sh)
shellcheck --wiki-link-count=99 "${FILES[@]}"
106 changes: 106 additions & 0 deletions tests/libyui/tmux-uitest.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#!/bin/bash
# tmux-uitest.sh - a shell library to test Text User Interface using tmux

SESSION=uitest
: "${VERBOSE=false}"

# $1 shell command for sh -c
tmux_new_session() {
if $VERBOSE; then
echo Starting session
fi
# -s session name
# -x width -y height,
# -d detached
# FIXME: sleep to be able to see errors when running $1
tmux new-session -s "$SESSION" -x 80 -y 24 -d sh -c "$1; sleep 9999"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lslezak you asked "How can I get more details about the failures?"

This sleep lets us capture the screen after a command fails and exits.

Tmux has a remain-on-exit option but I haven't figured out how to enable it yet :-(

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha! Totally intuitive for a beginner... NOT

tmux set-hook -g session-created 'set remain-on-exit on' \; new-session sh -c ...

Found in tmux/tmux#787

}

# A --quiet grep
# $1 regex (POSIX ERE) to find in captured pane
# retcode: true or false
tmux_grep() {
local REGEX="$1"
tmux capture-pane -t "$SESSION" -p | grep -E --quiet "$REGEX"
RESULT=("${PIPESTATUS[@]}")

if [ "${RESULT[0]}" != 0 ]; then
# capturing the pane failed; the session may have exited already
return 2
fi

# capturing went fine, pass on the grep result
test "${RESULT[1]}" = 0
}

# $1 regex (POSIX ERE) to find in captured pane
tmux_await() {
local REGEX="$1"

local SLEEPS=(0.1 0.2 0.2 0.5 1 2 2 5)
for SL in "${SLEEPS[@]}"; do
tmux_grep "$REGEX" && return 0
if [ $? = 2 ]; then return 2; fi # session not found
# text not found, continue waiting for it
sleep "$SL"
done
# text not found, timed out
false
}

# capture the session to stdout
tmux_capture_pane() {
tmux capture-pane -t "$SESSION" -p
}

# $1
# $1.txt plain text
# $1.esc text with escape sequences for colors
tmux_capture_pane_to() {
local OUT="$1"

# -t target-pane, -p to stdout,
# -e escape sequences for text and background attributes
tmux capture-pane -t "$SESSION" -p -e > "$OUT.esc"
tmux capture-pane -t "$SESSION" -p > "$OUT.txt"
# this is racy. if it is a problem we should make .txt from .esc
# by filtering out the escape sequences
}

# $1 keys ("C-X" for Ctrl-X, "M-X" for Alt-X, think "Meta"); for details see:
# man tmux | less +/"^KEY BINDINGS"
tmux_send_keys() {
if $VERBOSE; then
echo Sending "$1"
fi
# -t target-pane
tmux send-keys -t "$SESSION" "$1"
}

# usage: trap tmux_cleanup EXIT
tmux_cleanup() {
if tmux_has_session; then
echo "SCREEN BEGIN (non-empty lines only)"
tmux_capture_pane | grep .
echo "SCREEN END"
tmux_kill_session
fi
}

# ret code: true or false
tmux_has_session() {
if $VERBOSE; then
echo Detecting the session
fi
# -t target-session
tmux has-session -t "$SESSION"
}


tmux_kill_session() {
if $VERBOSE; then
echo Killing the session
fi
# -t target-session
tmux kill-session -t "$SESSION"
}
5 changes: 5 additions & 0 deletions tests/libyui/yast_ncurses
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#! /usr/bin/env ruby
require_relative "../test_helper"
require "yast"
Yast.ui_component = "ncurses"
load ARGV[0]