From a50a7d17d709f916ddc38f3f5155bac25ab38c24 Mon Sep 17 00:00:00 2001 From: Davide Madrisan Date: Sat, 19 May 2012 14:16:01 +0200 Subject: [PATCH] libtest.lib: new library for test framework Signed-off-by: Davide Madrisan --- ChangeLog | 13 +++ lib/Makefile | 5 +- lib/libtest.lib.in | 156 ++++++++++++++++++++++++++++++++++++ plugins/pck-update.in | 93 ++------------------- po/it/libtest.po | 47 +++++++++++ tests/test01_pkgquality.in | 80 ++++++++++-------- tests/test02_pkgsecurity.in | 20 +++-- 7 files changed, 285 insertions(+), 129 deletions(-) create mode 100644 lib/libtest.lib.in create mode 100644 po/it/libtest.po diff --git a/ChangeLog b/ChangeLog index cd55e75..eedd853 100644 --- a/ChangeLog +++ b/ChangeLog @@ -67,6 +67,19 @@ Changes in version 1.12.0 * pck-update - Davide Madrisan: Do not reinitialize the tests counter before executing a new test battery. ++ improvement + * lib/libtest.lib - Davide Madrisan: + New library containing the test framwork code and functions. + + * lib/Makefile - Davide Madrisan: + Updated by adding the library libtest.lib. + + * pck-update - Davide Madrisan: + Move code for test to the new library libtest.lib. + + * i18n - Davide Madrisan: + Updated. Add a .po file for libtest.lib. + ------------------------------------------------------------------------------- Changes in version 1.10.0 diff --git a/lib/Makefile b/lib/Makefile index 8794488..d69cf81 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,5 +1,5 @@ # Makefile for autospec -# Copyright (C) 2008,2010 by Davide Madrisan +# Copyright (C) 2008,2010,2012 by Davide Madrisan # This program is free software; you can redistribute it and/or modify it under # the terms of version 2 of the GNU General Public License as published by the @@ -18,7 +18,8 @@ srcdir = .. include $(srcdir)/Makefile.env -pck_libs := libapse.lib libcfg.lib libmsgmng.lib libnetwork.lib libspec.lib README.API +pck_libs := libapse.lib libcfg.lib libmsgmng.lib libnetwork.lib libspec.lib \ + libtest.lib README.API pck_libs_infiles := $(wildcard *.in) all: diff --git a/lib/libtest.lib.in b/lib/libtest.lib.in new file mode 100644 index 0000000..c7a53cf --- /dev/null +++ b/lib/libtest.lib.in @@ -0,0 +1,156 @@ +#!/bin/bash +# libtest.lib -- @package@ library used by the test framework +# Copyright (C) 2012 Davide Madrisan + +[ -z "$BASH" ] || [ ${BASH_VERSION:0:1} -lt 3 ] && + { echo $"this script requires bash version 3 or better" >&2 && exit 1; } + +me=(${0##*/} "@version@" "@date@") + +[ -r @libdir@/libmsgmng.lib ] || + { echo "$me: "$"library not found"": @libdir@/libmsgmng.lib" 1>&2 + exit 1; } +. @libdir@/libmsgmng.lib + +if [[ -z "$LANG" && -r /etc/sysconfig/i18n ]]; then + . /etc/sysconfig/i18n + [ "$LANG" ] && export LANG +fi +TEXTDOMAIN="libtest"; export TEXTDOMAIN + +[ -n "$testdir" ] || + notify.error "\`testdir': "$"unset in the configuration files" +[ -d "$testdir" ] || + notify.error $"no such file or directory"": \`$testdir'" + +# do parse the list of skipped test to set 'ignore_test_list_value[]' +ignore_test_list_value=() +OIFS="$IFS"; IFS=',' +for token in $ignore_test_list; do + IFS='='; set -- $token + ignore_test_list_value[${#ignore_test_list_value[*]}]="$1"; + IFS=',' +done +IFS="$OIFS" +notify.debug "ignore_test_list_value = (${ignore_test_list_value[*]})" + +# function test.rpms_extract() +# extract the files contained in all the rpm archives build by +# by a single specfile +# args: +# -i|--infofile the file containing infos about packages to extract +# -t|--tmpdir the directory where the files will be extracted to +function test.rpms_extract() { + local rpminfofile tmpextractdir + TEMP=`LC_ALL=C getopt \ + -o i:t: --long infofile:,tmpdir: -n "$FUNCNAME" -- "$@"` + [[ $? = 0 ]] || return 1 + eval set -- "$TEMP" + + while :; do + case "$1" in + -i|--infofile) + rpminfofile="$2" + shift + ;; + -t|--tmpdir) + tmpextractdir="$2" + shift + ;; + --) shift; break ;; + *) notify.error $"\ +(bug)"" -- $FUNCNAME: "$"\`getopt' error" ;; + esac + shift + done + + [ "$rpminfofile" ] || notify.error $"\ +(bug)"" -- $FUNCNAME: "$"missing mandatory arg"" (--infofile)" + [ -r "$rpminfofile" ] || notify.error $"\ +(bug)"" -- $FUNCNAME: "$"cannot read"" \`$rpminfofile'" + + [ "$tmpextractdir" ] || notify.error $"\ +(bug)"" -- $FUNCNAME: "$"missing mandatory arg"" (--tmpdir)" + [ -d "$tmpextractdir" ] || notify.error $"\ +(bug)"" -- $FUNCNAME: "$"no such file or directory"" \`$tmpextractdir'" + + . $rpminfofile + + local i=0 + for pck in ${rpmpkg_name[@]}; do + [[ -e "$pck" ]] || notify.error $"package not found"": \`$pck'" + + mkdir -p $tmpextractdir/$i 2>/dev/null + [ $? -eq 0 ] || notify.error $"\ +can't create temporary directory"": $tmpextractdir/$i" + + pushd $tmpextractdir/$i >/dev/null + rpm2cpio $pck > rpm_extract_tmp.cpio + [ $? -eq 0 ] || + notify --error $"cannot extract files from rpm archive" + + cpio --quiet --extract --make-directories < rpm_extract_tmp.cpio + [ $? -eq 0 ] || + notify --error $"cannot extract files from cpio archive" + + rm -f rpm_extract_tmp.cpio + popd >/dev/null + let "i += 1" + done +} + +function test.skip() { + local test n found + + test="$1" + let "found = 0" + + for n in ${ignore_test_list_value[*]}; do + [ "$n" = "$test" ] && let "found = 1" + done + + return $((!$found)) +} + +function test.num2str() { + [ $test_number -le 9 ] && echo " $test_number" || echo " $test_number" +} + +function test.runall() { + local ARGS + ARGS=`LC_ALL=C getopt \ + -o d: --long testdir: \ + -n "$FUNCNAME" -- "$@"` + [ $? = 0 ] || notify.error $"(bug)"" -- $FUNCNAME: "$"\`getopt' error" + + local testdir + + eval set -- "$ARGS" + while :; do + case "$1" in + -d|--testdir) + testdir="$2" + shift + ;; + --) shift; break ;; + *) notify.error $"\ +(bug)"" -- $FUNCNAME: "$"\`getopt' error: bad command \`$1'" ;; + esac + shift + done + + [ -n "$testdir" ] || + notify.error "\`testdir': "$"unset in the configuration files" + [ -d "$testdir" ] || + notify.error $"no such file or directory"": \`$testdir'" + + local test_number=1 + local fname + + for fname in $testdir/*; do + notify.debug "$FUNCNAME: running test: \`$fname'" + . $fname + alltests --infofile "$tmpextractdir/rpmpkg.info" \ + --tmpdir "$tmpextractdir" + done +} diff --git a/plugins/pck-update.in b/plugins/pck-update.in index 20e7e53..c099aa1 100644 --- a/plugins/pck-update.in +++ b/plugins/pck-update.in @@ -2629,8 +2629,6 @@ pck_newver = \"$pck_newver\", pck_newrel = \"$pck_newrel\"" [[ "$pck_newver" != $SPEC_VERSION ]] && notify.error $"release for new package required" - local i - local pck_rpmversion # use the value provided by user via command line when available pck_rpmversion=${pck_newver:-$SPEC_VERSION} @@ -2652,6 +2650,7 @@ pck_newver = \"$pck_newver\", pck_newrel = \"$pck_newrel\"" # - rpmpkg_name[] : name of the rpm packages # - data saved in '$infofile' + local i local pcknew_name > $tmpextractdir/rpmpkg.info i=0 @@ -2677,95 +2676,17 @@ $pck-$pck_rpmversion-$pck_rpmrelease$DISTRO_rpm.$target_cpu.rpm" let "i += 1" done - # function rpms.extract() - # extract the files contained in all the rpm archives build by - # by a single specfile - # args: - # -i|--infofile the file containing infos about packages to extract - # -t|--tmpdir the directory where the files will be extracted to - function rpms.extract() { - local rpminfofile tmpextractdir - TEMP=`LC_ALL=C getopt \ - -o i:t: --long infofile:,tmpdir: -n "$FUNCNAME" -- "$@"` - [[ $? = 0 ]] || return 1 - eval set -- "$TEMP" + [ -r @libdir@/libtest.lib ] || + { echo "$me: "$"library not found"": @libdir@/libtest.lib" 1>&2 + exit 1; } + . @libdir@/libtest.lib - while :; do - case "$1" in - -i|--infofile) - rpminfofile="$2" - shift - ;; - -t|--tmpdir) - tmpextractdir="$2" - shift - ;; - --) shift; break ;; - *) notify.error $"\ -(bug)"" -- $FUNCNAME: "$"\`getopt' error" ;; - esac - shift - done - - [ "$rpminfofile" ] || notify.error $"\ -(bug)"" -- $FUNCNAME: "$"missing mandatory arg"" (--infofile)" - [ -r "$rpminfofile" ] || notify.error $"\ -(bug)"" -- $FUNCNAME: "$"cannot read"" \`$rpminfofile'" - - [ "$tmpextractdir" ] || notify.error $"\ -(bug)"" -- $FUNCNAME: "$"missing mandatory arg"" (--tmpdir)" - [ -d "$tmpextractdir" ] || notify.error $"\ -(bug)"" -- $FUNCNAME: "$"no such file or directory"" \`$tmpextractdir'" - - . $rpminfofile - - i=0 - for pck in ${rpmpkg_name[@]}; do - [[ -e "$pck" ]] || notify.error $"\ -package not found"": \`$pck'" - - mkdir -p $tmpextractdir/$i 2>/dev/null - [ $? -eq 0 ] || notify.error $"\ -can't create temporary directory"": $tmpextractdir/$i" - - pushd $tmpextractdir/$i >/dev/null - rpm2cpio $pck > rpm_extract_tmp.cpio - [ $? -eq 0 ] || - notify --error $"cannot extract files from rpm archive" - - cpio --quiet --extract --make-directories < rpm_extract_tmp.cpio - [ $? -eq 0 ] || - notify --error $"cannot extract files from cpio archive" - - rm -f rpm_extract_tmp.cpio - popd >/dev/null - let "i += 1" - done - } - - rpms.extract \ + test.rpms_extract \ --infofile "$tmpextractdir/rpmpkg.info" \ --tmpdir "$tmpextractdir" || exit 1 # execute all the available tests... - - [ -n "$testdir" ] || - notify.error "\`testdir': "$"unset in the configuration files" - [ -d "$testdir" ] || - notify.error $"no such file or directory"": \`$testdir'" - - function test_number_str() { - [ $test_number -le 9 ] && - echo " $test_number" || echo " $test_number" - } - - ( local test_number=1 - for fname in $testdir/*; do - notify.debug "$FUNCNAME: running test: \`$fname'" - . $fname - alltests --infofile "$tmpextractdir/rpmpkg.info" \ - --tmpdir "$tmpextractdir" - done ) + test.runall --testdir "$testdir" # temporary files cleanup rm -fr $tmpextractdir diff --git a/po/it/libtest.po b/po/it/libtest.po new file mode 100644 index 0000000..118cdef --- /dev/null +++ b/po/it/libtest.po @@ -0,0 +1,47 @@ +# translation of it.po to Italiana +# Copyright (C) 2012 Davide Madrisan +# Davide Madrisan + +msgid "" +msgstr "" +"Project-Id-Version: it\n" +"POT-Creation-Date: 2012-05-19 12:04+0200\n" +"PO-Revision-Date: 2012-05-19 12:04+0200\n" +"Last-Translator: Davide Madrisan \n" +"Language-Team: Italiana \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +# lib/libtest + +msgid "\\`getopt' error" +msgstr "errore in \\`getopt'" + +msgid "\\`getopt' error: bad command \\`$1'" +msgstr "errore in \\`getopt': comando errato \\`$1'" + +msgid "missing mandatory arg" +msgstr "parametro mancante" + +msgid "cannot read" +msgstr "impossibile leggere" + +msgid "no such file or directory" +msgstr "file o cartella non trovata" + +msgid "package not found" +msgstr "pacchetto non trovato" + +msgid "can't create temporary directory" +msgstr "impossibile creare la cartella temporanea" + +msgid "cannot extract files from rpm archive" +msgstr "impossibile estrarre i file dall'archivio rpm" + +msgid "cannot extract files from cpio archive" +msgstr "impossibile estrarre i file dall'archivio cpio" + +msgid "unset in the configuration files" +msgstr "non configurato nei file di configurazione" + diff --git a/tests/test01_pkgquality.in b/tests/test01_pkgquality.in index 04dad9d..75ad172 100644 --- a/tests/test01_pkgquality.in +++ b/tests/test01_pkgquality.in @@ -69,7 +69,9 @@ function alltests() { # - symlinks to files in the buildroot directory for rpm # (usable for a symlink attacks) # - symlinks not pointing to existing files - notify.note "$(test_number_str). ${NOTE}"\ + + test.skip $test_number || { + notify.note "$(test.num2str). ${NOTE}"\ $"checking for wrong symbolic links""${NORM}..." # local rpmbuildroot=`sed -n "/%description/q;{ @@ -107,21 +109,24 @@ wrong symlink"": \`${NOTE}${f/./}${NORM}' --> \`${NOTE}$(readlink $f)${NORM}'" done popd >/dev/null let "i += 1" - done + done; } test_number=$(($test_number + 1)) # check for `%buildroot' strings + test.skip $test_number || { if [ "$rpm_ignores_buildroot" = 1 ]; then - [ "$SPEC_BUILDROOT" ] && + if [ "$SPEC_BUILDROOT" ]; then notify.note \ -"$(test_number_str). ${NOTE}"\ +"$(test.num2str). ${NOTE}"\ $"checking for \`$SPEC_BUILDROOT' (%buildroot) strings"\ -"${NORM}... "$"skipped" || +"${NORM}... "$"skipped" + else notify.note \ -"$(test_number_str). ${NOTE}"\ +"$(test.num2str). ${NOTE}"\ $"checking for %buildroot strings""${NORM}... "$"N/A" + fi else - notify.note "$(test_number_str). "\ + notify.note "$(test.num2str). "\ $"checking for \`$SPEC_BUILDROOT' (%buildroot) strings" [ "$SPEC_BUILDROOT" ] || notify.error \ @@ -143,12 +148,13 @@ sed "s,$SPEC_BUILDROOT\(.*\), - [%buildroot]\1,")" popd >/dev/null let "i += 1" done - fi + fi; } test_number=$(($test_number + 1)) # check for `%_builddir' strings BUILDDIR="$(rpm --eval=%_builddir 2>/dev/null)" - notify.note "$(test_number_str). ${NOTE}"\ + test.skip $test_number || { + notify.note "$(test.num2str). ${NOTE}"\ $"checking for \`$BUILDDIR' (%_builddir) strings""${NORM}... " [ "$BUILDDIR" ] || @@ -169,13 +175,14 @@ sed "s,$BUILDDIR,[%_builddir],g;s,.*, - &,")" done popd >/dev/null let "i += 1" - done + done; } test_number=$(($test_number + 1)) # check for suspected plugins (.la, .so) in devel packages # note: pure plugins must be in the main package, not in devel - notify.note "$(test_number_str). ${NOTE}"$"\ -checking for suspicious plugins in devel packages""${NORM}..." + test.skip $test_number || { + notify.note "$(test.num2str). ${NOTE}"\ +$"checking for suspicious plugins in devel packages""${NORM}..." let "i = 0" for pck in ${rpmpkg_name[@]}; do @@ -193,12 +200,13 @@ grep ' shared object,' | sed -n 's/.\(.*\):.*/\1/p'`; do done popd >/dev/null let "i += 1" - done + done; } test_number=$(($test_number + 1)) # check for wrong file attributes in lib and bin dirs - notify.note "$(test_number_str). ${NOTE}"$"\ -checking for wrong file attributes in bin and lib directories""${NORM}..." + test.skip $test_number || { + notify.note "$(test.num2str). ${NOTE}"\ +$"checking for wrong file attributes in bin and lib directories""${NORM}..." warning=0 let "i = 0" @@ -231,12 +239,13 @@ ${NOTE}"$"Hint"":${NORM} %defattr(-,root,root) ... %attr(0755,root,root) %{_bindir}/ ------------------------------" +-----------------------------"; } test_number=$(($test_number + 1)) # check for libraries with undefined symbols - notify.note "$(test_number_str). ${NOTE}"$"\ -checking for libraries with undefined symbols after relocation""${NORM}..." + test.skip $test_number || { + notify.note "$(test.num2str). ${NOTE}"\ +$"checking for libraries with undefined symbols after relocation""${NORM}..." let "i = 0" local undefsyms @@ -261,12 +270,13 @@ $(LC_ALL=C ldd -d -r "$f" 2>/dev/null |& grep "undefined symbol")" done popd >/dev/null let "i += 1" - done + done; } test_number=$(($test_number + 1)) # check for binary files in etc (see FHS-2.2) - notify.note "$(test_number_str). ${NOTE}"$"\ -checking for binary files installed in /etc (see FHS)""${NORM}..." + test.skip $test_number || { + notify.note "$(test.num2str). ${NOTE}"\ +$"checking for binary files installed in /etc (see FHS)""${NORM}..." warning=0 let "i = 0" @@ -292,12 +302,13 @@ ${NOTE}"$"Hint"":${NORM} %defattr(-,root,root) ... %attr(0644,root,root) %{_sysconfdir}/<...file> ------------------------------" #|| exit 1 +-----------------------------"; } #|| exit 1 test_number=$(($test_number + 1)) # check for installation code needed by info pages - notify.note "$(test_number_str). ${NOTE}"$"\ -checking if the info catalog is updated when necessary""${NORM}..." + test.skip $test_number || { + notify.note "$(test.num2str). ${NOTE}"\ +$"checking if the info catalog is updated when necessary""${NORM}..." error=0 let "i = 0" @@ -338,12 +349,13 @@ $([[ "$rpm_macro_uninstallinfo" ]] && exit 0 ---------------------------------------" let "total_issues += $error"; } - done + done; } test_number=$(($test_number + 1)) # check packages for wrong user and/or group ownerships - notify.note "$(test_number_str). ${NOTE}"$"\ -checking packages for wrong user and/or group ownerships""${NORM}..." + test.skip $test_number || { + notify.note "$(test.num2str). ${NOTE}"\ +$"checking packages for wrong user and/or group ownerships""${NORM}..." error=0 idun="$(id -un)" idgn="$(id -gn)" @@ -363,12 +375,13 @@ package not found"": \`${pck##*/}'" let "total_issues += 1" fi done ) - done + done; } test_number=$(($test_number + 1)) # check for desktop files installed in non standard applnk dir - notify.note "$(test_number_str). ${NOTE}"$"\ -checking packages for desktop files installed in the applnk dir""${NORM}..." + test.skip $test_number || { + notify.note "$(test.num2str). ${NOTE}"\ +$"checking packages for desktop files installed in the applnk dir""${NORM}..." warning=0 rpmdatadir=$(rpm --eval %_datadir 2>/dev/null) @@ -393,11 +406,12 @@ checking packages for desktop files installed in the applnk dir""${NORM}..." ${NOTE}"$"Hint"":${NORM} "$"create desktop files for:"" ${rpmdatadir}/applications "$"see:"" ------------------------------" +-----------------------------"; } test_number=$(($test_number + 1)) # check if a package that do not contains binaries is tagged noarch - notify.note "$(test_number_str). ${NOTE}"\ + test.skip $test_number || { + notify.note "$(test.num2str). ${NOTE}"\ $"checking for packages with bad BuildArch tag""${NORM}..." warning=0 @@ -421,7 +435,7 @@ ${NOTE}"$"Hint"":${NORM} BuildArch: noarch -----------------------------" let "total_issues += 1"; } - fi + fi; } test_number=$(($test_number + 1)) notify.note " diff --git a/tests/test02_pkgsecurity.in b/tests/test02_pkgsecurity.in index 1b5dbbc..0c17889 100644 --- a/tests/test02_pkgsecurity.in +++ b/tests/test02_pkgsecurity.in @@ -70,7 +70,8 @@ function alltests() { local total_issues=0 - notify.note "$(test_number_str). ${NOTE}"\ + test.skip $test_number || { + notify.note "$(test.num2str). ${NOTE}"\ $"checking for RPATH vulnerabilities""${NORM}..." let "i = 0" @@ -91,10 +92,11 @@ $"checking for RPATH vulnerabilities""${NORM}..." done popd >/dev/null let "i += 1" - done + done; } test_number=$(($test_number + 1)) - notify.note "$(test_number_str). ${NOTE}"\ + test.skip $test_number || { + notify.note "$(test.num2str). ${NOTE}"\ $"checking for setuid binaries""${NORM}..." let "i = 0" @@ -108,10 +110,11 @@ $"checking for setuid binaries""${NORM}..." done popd >/dev/null let "i += 1" - done + done; } test_number=$(($test_number + 1)) - notify.note "$(test_number_str). ${NOTE}"\ + test.skip $test_number || { + notify.note "$(test.num2str). ${NOTE}"\ $"checking for setgid directories""${NORM}..." let "i = 0" @@ -123,11 +126,12 @@ $"checking for setgid directories""${NORM}..." done popd >/dev/null let "i += 1" - done + done; } test_number=$(($test_number + 1)) # checking for unsecure use of $$ as random source in shell scripts - notify.note "$(test_number_str). ${NOTE}"\ + test.skip $test_number || { + notify.note "$(test.num2str). ${NOTE}"\ $"checking for unsecure use of \`\$\$' in shell and perl scripts""${NORM}..." vulnerable=0 @@ -165,7 +169,7 @@ ${NOTE}"$"Hint for bash scripts (\`mktemp' required)"":${NORM} ${NOTE}"$"Hint for perl scripts"":${NORM} use File::Temp qw/ tempfile /; (\$fh,\$file) = tempfile ('.XXXXXX'); ------------------------------" +-----------------------------"; } test_number=$(($test_number + 1)) notify.note "