[pacman-dev] [PATCH 4/4] add basic makepkg test

brainpower brainpower at mailbox.org
Sat Feb 25 19:09:01 UTC 2017


On 25.02.2017 18:21, Andrew Gregory wrote:
> ---
>  Makefile.am                         |   6 +-
>  configure.ac                        |   2 +
>  test/makepkg/Makefile.am            |   9 +++
>  test/makepkg/README                 |  15 ++++
>  test/makepkg/test_functions.sh      | 143 ++++++++++++++++++++++++++++++++++++
>  test/makepkg/tests/Makefile.am      |   7 ++
>  test/makepkg/tests/TESTS            |   4 +
>  test/makepkg/tests/dbfiles.sh       |  35 +++++++++
>  test/makepkg/tests/dotfiles.sh      |  33 +++++++++
>  test/makepkg/tests/pkgbuild.sh      |  53 +++++++++++++
>  test/makepkg/tests/util-pkgbuild.sh |  35 +++++++++
>  11 files changed, 341 insertions(+), 1 deletion(-)
>  create mode 100644 test/makepkg/Makefile.am
>  create mode 100644 test/makepkg/README
>  create mode 100644 test/makepkg/test_functions.sh
>  create mode 100644 test/makepkg/tests/Makefile.am
>  create mode 100644 test/makepkg/tests/TESTS
>  create mode 100755 test/makepkg/tests/dbfiles.sh
>  create mode 100755 test/makepkg/tests/dotfiles.sh
>  create mode 100755 test/makepkg/tests/pkgbuild.sh
>  create mode 100755 test/makepkg/tests/util-pkgbuild.sh
> 
> diff --git a/Makefile.am b/Makefile.am
> index 67ffc6b4..7b877a6c 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -1,4 +1,4 @@
> -SUBDIRS = lib/libalpm src/util src/pacman scripts etc test/pacman test/util test/scripts
> +SUBDIRS = lib/libalpm src/util src/pacman scripts etc test/makepkg test/pacman test/util test/scripts
>  if WANT_DOC
>  SUBDIRS += doc
>  endif
> @@ -26,11 +26,15 @@ dist_pkgdata_DATA = \
>  $(top_srcdir)/test/pacman/tests/TESTS: $(wildcard test/pacman/tests/*.py)
>  	@printf "TESTS += %s\n" $^ | LC_ALL=C sort -u > "$@"
>  
> +$(top_srcdir)/test/makepkg/tests/TESTS: $(wildcard test/makepkg/tests/*.sh)
> +	@printf "TESTS += %s\n" $^ | LC_ALL=C sort -u > "$@"
> +
>  TESTS =  test/scripts/parseopts_test.sh \
>  				 test/scripts/human_to_size_test.sh \
>  				 test/scripts/makepkg-template_test.sh \
>  				 test/scripts/pacman-db-upgrade-v9.py \
>  				 test/util/vercmptest.sh
> +include $(top_srcdir)/test/makepkg/tests/TESTS
>  include $(top_srcdir)/test/pacman/tests/TESTS
>  
>  TEST_SUITE_LOG = test/test-suite.log
> diff --git a/configure.ac b/configure.ac
> index 10e4415c..d7e2c9ff 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -530,6 +530,8 @@ scripts/Makefile
>  scripts/po/Makefile.in
>  doc/Makefile
>  etc/Makefile
> +test/makepkg/Makefile
> +test/makepkg/tests/Makefile
>  test/pacman/Makefile
>  test/pacman/tests/Makefile
>  test/scripts/Makefile
> diff --git a/test/makepkg/Makefile.am b/test/makepkg/Makefile.am
> new file mode 100644
> index 00000000..835030c0
> --- /dev/null
> +++ b/test/makepkg/Makefile.am
> @@ -0,0 +1,9 @@
> +SUBDIRS = tests
> +
> +check_SCRIPTS = test_functions.sh
> +
> +noinst_SCRIPTS = $(check_SCRIPTS)
> +
> +EXTRA_DIST = $(check_SCRIPTS)
> +
> +# vim:set noet:
> diff --git a/test/makepkg/README b/test/makepkg/README
> new file mode 100644
> index 00000000..70c6872b
> --- /dev/null
> +++ b/test/makepkg/README
> @@ -0,0 +1,15 @@
> +README
> +======
> +
> +Running Tests
> +-------------
> +
> +Environment Variables
> +---------------------
> +
> +PMTEST_SCRIPT_DIR - location of the makepkg executable; defaults to "$(dirname "$0")/../../../scripts)"
> +PMTEST_LIBMAKEPKG_DIR - base directory of the makepkg library; defaults to "$PMTEST_SCRIPT_DIR/libmakepkg"
> +VERBOSE - enable additional test output for debugging
> +
> +Adding New Tests
> +----------------
> diff --git a/test/makepkg/test_functions.sh b/test/makepkg/test_functions.sh
> new file mode 100644
> index 00000000..a6f07bcd
> --- /dev/null
> +++ b/test/makepkg/test_functions.sh
> @@ -0,0 +1,143 @@
> +# basic setup to run before every test
> +# tap_init
> +tap_init() {
> +	set +e
> +	set -u
> +	set -o pipefail
> +}
> +
> +# wrapper around tap_bail that immediately causes the test to exit non-zero
> +# tap_xbail $reason...
> +tap_xbail() {
> +	tap_bail "$@"
> +	exit 1;
> +}
> +
> +# read from stdin and reprint as diagnostic messages if VERBOSE is set and
> +# non-zero, otherwise, discard
> +# $command |& tap_filter
> +tap_filter() {
> +	local v=${VERBOSE:-0}
> +	if (( $v )); then
> +		while IFS= read line; do
> +			tap_diag "$line"
> +		done
> +	else
> +		while IFS= read line; do
> +			:
> +		done
> +	fi
> +}
> +
> +# locate the script that should be tested
> +locate_bin() {
> +	local scriptdir="${PMTEST_SCRIPT_DIR:-"$(dirname "$0")/../../../scripts"}"
> +	local script="$(realpath "${1:-"$scriptdir/makepkg-wrapper"}")"
> +	if ! type -p "$script" &>/dev/null; then
> +		tap_xbail "makepkg executable (%s) could not be located" "${script}"
> +		exit 1

Isn't this exit unnecessary if xbail already exits?


> +	fi
> +	printf "%s" "$script"
> +}
> +
> +# locate an source libmakepkg files
> +source_libmakepkg_file() {
> +	local file=$1; shift 1
> +	local scriptdir="${PMTEST_SCRIPT_DIR:-"$(dirname "$0")/../../../scripts"}"
> +	local libdir="${PMTEST_LIBMAKEPKG_DIR:-"$scriptdir/libmakepkg"}"
> +	source "$(realpath "$libdir/$file")"
> +}
> +
> +# eval a piece of code and test the return value
> +# tap_eval $code $test_name...
> +tap_eval() {
> +	local t=$1; shift 1
> +	eval "$t"
> +	tap_ok $? "$@"
> +}
> +
> +# extract ls-style information about a file:
> +# mode nhardlinks user group size month date time/year filename
> +_ar_stat() {
> +	local ar=$1 path=$2; shift 2
> +	bsdtar --fast-read -tvf "$ar" "$@" "$path"  2>/dev/null
> +}
> +
> +# same as _ar_stat but with numeric owner ids
> +_ar_nstat() {
> +	local ar=$1 path=$2; shift 2
> +	_ar_stat "$ar" "$path" --numeric-owner "$@"
> +}
> +
> +# check the owner of a given file, owner may be a numeric id or user name
> +# tap_ar_is_owner $path_to_archive $file $expected_owner $test_name...
> +tap_ar_is_owner() {
> +	local ar=$1 path=$2 expect=$3; shift 3
> +	local statfun="_ar_stat" owner unused
> +	[[ $expect =~ ^[0-9]+$ ]] && statfun="_ar_nstat"
> +	if ! read -r unused unused owner unused < <($statfun "$ar" "$path"); then
> +		tap_ok 1 "$@"
> +		tap_diag "         got: invalid path"
> +		tap_diag "    expected: '%s'" "$expect"
> +	elif [[ $owner != $expect ]]; then
> +		tap_ok 1 "$@"
> +		tap_diag "         got: '%s'" "$owner"
> +		tap_diag "    expected: '%s'" "$expect"
> +	else
> +		tap_ok 0 "$@"
> +	fi
> +}
> +
> +# check the group of a given file, group may be a numeric id or user name
> +# tap_ar_is_group $path_to_archive $file $expected_group $test_name...
> +tap_ar_is_group() {
> +	local ar=$1 path=$2 expect=$3; shift 3
> +	local statfun="_ar_stat" group unused
> +	[[ $expect =~ ^[0-9]+$ ]] && statfun="_ar_nstat"
> +	if ! read -r unused unused unused group unused < <($statfun "$ar" "$path"); then
> +		tap_ok 1 "$@"
> +		tap_diag "         got: invalid path"
> +		tap_diag "    expected: '%s'" "$expect"
> +	elif [[ $group != $expect ]]; then
> +		tap_ok 1 "$@"
> +		tap_diag "         got: '%s'" "$group"
> +		tap_diag "    expected: '%s'" "$expect"
> +	else
> +		tap_ok 0 "$@"
> +	fi
> +}
> +
> +# check if a path within an archive refers to a file
> +# tap_ar_is_file $path_to_archive $file $test_name...
> +tap_ar_is_file() {
> +	local ar=$1 path=$2; shift 2
> +	local stat="$(_ar_stat "$ar" "$path")"
> +	if [[ ${stat:0:1} != '-' ]]; then
> +		tap_ok 1 "$@"
> +		tap_diag "         got: not a file"
> +		tap_diag "    expected: '%s'" "$path"
> +	else
> +		tap_ok 0 "$@"
> +	fi
> +}
> +
> +# check if a path within an archive refers to a symbolic link
> +# tap_ar_is_link $path_to_archive $file $expected_destination $test_name...
> +tap_ar_is_link() {
> +	local ar=$1 path=$2 dest=$3; shift 3
> +	local stat="$(_ar_stat "$ar" "$path")"
> +	if [[ ${stat:0:1} != 'l' ]]; then
> +		tap_ok 1 "$@"
> +		tap_diag "         got: not a link"
> +		tap_diag "    expected: '%s'" "$dest"
> +	elif [[ ${stat##*$path -> } != $dest ]]; then
> +		tap_ok 1 "$@"
> +		tap_diag "         got: '%s'" "${stat##*$path -> }"
> +		tap_diag "    expected: '%s'" "$dest"
> +	else
> +		tap_ok 0 "$@"
> +	fi
> +}
> +
> +source "$(dirname "$0")"/../../tap.sh || exit 1
> +tap_init
> diff --git a/test/makepkg/tests/Makefile.am b/test/makepkg/tests/Makefile.am
> new file mode 100644
> index 00000000..fb59d11c
> --- /dev/null
> +++ b/test/makepkg/tests/Makefile.am
> @@ -0,0 +1,7 @@
> +check_SCRIPTS = $(wildcard *.sh)
> +
> +noinst_SCRIPTS = $(check_SCRIPTS)
> +
> +EXTRA_DIST = $(check_SCRIPTS)
> +
> +# vim:set noet:
> diff --git a/test/makepkg/tests/TESTS b/test/makepkg/tests/TESTS
> new file mode 100644
> index 00000000..f167e594
> --- /dev/null
> +++ b/test/makepkg/tests/TESTS
> @@ -0,0 +1,4 @@
> +TESTS += test/makepkg/tests/dbfiles.sh
> +TESTS += test/makepkg/tests/dotfiles.sh
> +TESTS += test/makepkg/tests/pkgbuild.sh
> +TESTS += test/makepkg/tests/util-pkgbuild.sh
> diff --git a/test/makepkg/tests/dbfiles.sh b/test/makepkg/tests/dbfiles.sh
> new file mode 100755
> index 00000000..72e196ef
> --- /dev/null
> +++ b/test/makepkg/tests/dbfiles.sh
> @@ -0,0 +1,35 @@
> +#!/bin/bash
> +
> +source "$(dirname "$0")"/../test_functions.sh || exit 1
> +
> +script="$(locate_bin "${1:-}")"
> +
> +TMPDIR="$(mktemp -d --tmpdir "${0##*/}.XXXXXX")"
> +trap "rm -rf '${TMPDIR}'" EXIT TERM
> +
> +tap_note "check that required metadata files are created"
> +tap_note "testing '%s'" "$script"
> +tap_note "using test dir '%s'" "$TMPDIR"
> +
> +(
> +	set -e
> +	cd "$TMPDIR"
> +	cat >PKGBUILD <<-'PKGBUILD'
> +		pkgname=foo
> +		pkgver=1
> +		pkgrel=1
> +		arch=(any)
> +		PKGBUILD
> +	MAKEPKG_CONF="/dev/null" PKGEXT=".pkg.tar" $script
> +) |& tap_filter
> +[[ $? -eq 0 ]] || tap_xbail "test setup failed"
> +
> +pkgfile="$TMPDIR/foo-1-1-any.pkg.tar"

Shouldn't this, like the test below, check if foo-1-1-any.pkg.tar actually exists?
Or does the test below run earlier than this, so it's tested already and can be assumed to be created?

Is it the same for all other tests below, which don't check if $pkgfile exists?

> +
> +tap_plan 10
> +for f in .BUILDINFO .PKGINFO .MTREE; do
> +	tap_ar_is_file "$pkgfile" "$f" "pkg contains %s" "$f"
> +	tap_ar_is_owner "$pkgfile" "$f" "0" "%s owner is root" "$f"
> +	tap_ar_is_group "$pkgfile" "$f" "0" "%s group is root" "$f"
> +done
> +tap_is_int "$(bsdtar -tf "$pkgfile" | wc -l)" 3 "pkg only contains known metainfo files"
> diff --git a/test/makepkg/tests/dotfiles.sh b/test/makepkg/tests/dotfiles.sh
> new file mode 100755
> index 00000000..9fa81258
> --- /dev/null
> +++ b/test/makepkg/tests/dotfiles.sh
> @@ -0,0 +1,33 @@
> +#!/bin/bash
> +
> +source "$(dirname "$0")"/../test_functions.sh || exit 1
> +
> +script="$(locate_bin "${1:-}")"
> +
> +TMPDIR="$(mktemp -d --tmpdir "${0##*/}.XXXXXX")"
> +[[ ${KEEPFILES:-0} == 0 ]] || trap "rm -rf '${TMPDIR}'" EXIT TERM
> +
> +tap_note "test that dotfiles don't make it into the package root"
> +tap_note "testing '%s'" "$script"
> +tap_note "using test dir '%s'" "$TMPDIR"
> +
> +output="$(
> +	set -e
> +	cd "$TMPDIR"
> +	cat >PKGBUILD <<-'PKGBUILD'
> +		pkgname=foo
> +		pkgver=1
> +		pkgrel=1
> +		arch=(any)
> +		package() {
> +			touch "$pkgdir"/.dotfile
> +		}
> +		PKGBUILD
> +	MAKEPKG_CONF="/dev/null" PKGEXT=".pkg.tar" $script 2>&1
> +)"
> +ret=$?
> +
> +tap_plan 3
> +tap_eval "[[ '$ret' -ne 0 ]]"  "makepkg exited non-zero"
> +tap_eval "[[ ! -f '$TMPDIR/foo-1-1-any.pkg.tar' ]]" "no package was built"
> +tap_eval "[[ '$output' = *'Dotfile found in package root'* ]]" "error message references dotfile"
> diff --git a/test/makepkg/tests/pkgbuild.sh b/test/makepkg/tests/pkgbuild.sh
> new file mode 100755
> index 00000000..5dc8d46f
> --- /dev/null
> +++ b/test/makepkg/tests/pkgbuild.sh
> @@ -0,0 +1,53 @@
> +#!/bin/bash
> +
> +source "$(dirname "$0")"/../test_functions.sh || exit 1
> +
> +script="$(locate_bin "${1:-}")"
> +
> +TMPDIR="$(mktemp -d --tmpdir "${0##*/}.XXXXXX")"
> +trap "rm -rf '${TMPDIR}'" EXIT TERM
> +
> +tap_note "basic package building test"
> +tap_note "testing '%s'" "$script"
> +tap_note "using test dir '%s'" "$TMPDIR"
> +
> +(
> +	set -e
> +	cd "$TMPDIR"
> +	cat >PKGBUILD <<-'PKGBUILD'
> +		pkgname=foo
> +		pkgver=1
> +		pkgrel=1
> +		arch=(any)
> +		package() {
> +			touch "$pkgdir/!first"
> +			touch "$pkgdir/target"
> +			ln -s target "$pkgdir/link"
> +			mkdir "$pkgdir/dir"
> +			touch "$pkgdir/dir/.dotfile"
> +		}
> +		PKGBUILD
> +	MAKEPKG_CONF="/dev/null" PKGEXT=".pkg.tar" $script
> +) |& tap_filter
> +[[ $? -eq 0 ]] || tap_xbail "test setup failed"
> +
> +pkgfile="$TMPDIR/foo-1-1-any.pkg.tar"
> +
> +tap_plan 10
> +tap_ar_is_file "$pkgfile" "!first" "pkg contains !first"
> +tap_ar_is_file "$pkgfile" "target" "pkg contains target"
> +tap_ar_is_file "$pkgfile" "dir/.dotfile" "pkg contains dir/.dotfile"
> +tap_ar_is_link "$pkgfile" "link" "target" "pkg contains link to target"
> +tap_ar_is_owner "$pkgfile" "target" "0" "target owner is root"
> +tap_ar_is_group "$pkgfile" "target" "0" "target group is root"
> +
> +tap_eval "! bsdtar -tf '$pkgfile' | grep -qE '^\\.?\\.?/'" \
> +	"package paths are relative without leading dot dirs"
> +tap_eval "bsdtar -tf '$pkgfile' | grep -v '^\\.' | LANG=C sort -Cu" \
> +	"package files are sorted"
> +tap_eval "bsdtar -tf '$pkgfile' | LANG=C sort | LANG=C sort -Cu" \
> +	"package files are unique"
> +tap_eval "bsdtar -tf '$pkgfile' | head -n1 | grep -q '^\\.'" \
> +	"db files are placed at the beginning of the package"
> +
> +tap_finish
> diff --git a/test/makepkg/tests/util-pkgbuild.sh b/test/makepkg/tests/util-pkgbuild.sh
> new file mode 100755
> index 00000000..3fd970c8
> --- /dev/null
> +++ b/test/makepkg/tests/util-pkgbuild.sh
> @@ -0,0 +1,35 @@
> +#!/bin/bash
> +
> +source "$(dirname "$0")"/../test_functions.sh || exit 1
> +
> +tap_note "testing libmakepkg/util/pkgbuild.sh"
> +
> +source_libmakepkg_file 'util/pkgbuild.sh'
> +
> +test_foo() {
> +	myarray=(foo bar)
> +	myarray+=(baz)
> +	#myarray+=(this should be ignored)
> +	myscalar=baz
> +	myscalar=quux
> +	#myscalar=ignored
> +}
> +
> +declare -a oarray
> +declare oscalar
> +
> +tap_plan 9
> +
> +tap_eval 'have_function test_foo' 'detected existing function test_foo'
> +tap_eval '! have_function test_bar' 'detected missing function test_bar'
> +
> +tap_eval 'extract_function_variable test_foo myarray 1 oarray' 'extract array variable'
> +tap_is_int "${#oarray[@]}" 3 'extracted array length'
> +tap_is_str "${oarray[0]}" 'foo' 'extracted array contents'
> +tap_is_str "${oarray[1]}" 'bar' 'extracted array contents'
> +tap_is_str "${oarray[2]}" 'baz' 'extracted array contents'
> +
> +tap_eval 'extract_function_variable test_foo myscalar 0 oscalar' 'extract scalar variable'
> +tap_is_str "$oscalar" 'quux' 'extracted scalar value'
> +
> +tap_finish
> 

-- 
regards,
brainpower

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 866 bytes
Desc: OpenPGP digital signature
URL: <https://lists.archlinux.org/pipermail/pacman-dev/attachments/20170225/bcec3aac/attachment.asc>


More information about the pacman-dev mailing list