Add a testsuite and fix bugs found with it
authorJ. Ali Harlow <ali@juiblex.co.uk>
Mon Jun 13 12:18:42 2016 +0100 (2016-06-13)
changeset 38a29623b68ca2
parent 37 99d80cbe2eb4
child 39 4af9b57a647f
Add a testsuite and fix bugs found with it
.hgignore
Makefile.am
README
app-manager/app-manager.c
bootstrap.sh
configure.ac
m4/ax_code_coverage.m4
m4/ax_valgrind_check.m4
plover-gtk/Makefile.am
plover-gtk/packagefilestore.c
plover-gtk/software-installation.ui
plover-gtk/stockicons.c
plover-gtk/transactionhelper.c
plover-gtk/transactionhelper.h
plover-open/plover-open.c
plover/Makefile.am
plover/comps.c
plover/log.c
plover/package.c
plover/packageset.c
plover/transaction.c
plover/transaction.h
plover/util.c
pre-inst/pre-inst.c
setup/setup.c
tests/Makefile.am
tests/README
tests/badpostun.spec
tests/comps.xml
tests/filesystem.spec
tests/glib.supp.in
tests/plover-gtk/Makefile.am
tests/plover-gtk/test-packagefilestore.c
tests/plover-gtk/test-packagestore.c
tests/plover-gtk/test-stockicons.c
tests/plover-gtk/test-transactionhelper.c
tests/plover-gtk/treemodel.c
tests/plover-gtk/treemodel.h
tests/plover/Makefile.am
tests/plover/test-comps.c
tests/plover/test-exception-handler.c
tests/plover/test-import-yum.c
tests/plover/test-log.c
tests/plover/test-package.c
tests/plover/test-packageset.c
tests/plover/test-razor.c
tests/plover/test-repository.c
tests/plover/test-transaction.c
tests/plover/test-util.c
tests/plover/test-vector.c
tests/uninstallable.spec
tests/unsatisfiable.spec
tests/xvfb-run
tests/zap.spec
tests/zappy.spec
tests/zappy2.spec
tests/zip.spec
tests/zsh.spec
tests/zsh2.spec
update/update.c
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/.hgignore	Mon Jun 13 12:18:42 2016 +0100
     1.3 @@ -0,0 +1,12 @@
     1.4 +Makefile.in$
     1.5 +.swp$
     1.6 +^m4/libtool.m4$
     1.7 +^m4/ltoptions.m4$
     1.8 +^m4/ltsugar.m4$
     1.9 +^m4/ltversion.m4$
    1.10 +^m4/lt~obsolete.m4$
    1.11 +^configure$
    1.12 +^config/
    1.13 +^config.h.in
    1.14 +^autom4te.cache/
    1.15 +^aclocal.m4$
     2.1 --- a/Makefile.am	Mon Apr 18 15:04:47 2016 +0100
     2.2 +++ b/Makefile.am	Mon Jun 13 12:18:42 2016 +0100
     2.3 @@ -1,1 +1,9 @@
     2.4 -SUBDIRS=plover setup update pre-inst plover-gtk app-manager plover-open
     2.5 +SUBDIRS=plover plover-gtk tests setup update pre-inst app-manager plover-open
     2.6 +
     2.7 +ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
     2.8 +
     2.9 +@CODE_COVERAGE_RULES@
    2.10 +
    2.11 +check-valgrind:
    2.12 +	-(cd tests && $(MAKE) $(AM_MAKEFLAGS) check-valgrind)
    2.13 +	@echo 'Results in tests/test-suite-*.log)'
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/README	Mon Jun 13 12:18:42 2016 +0100
     3.3 @@ -0,0 +1,35 @@
     3.4 +General Information
     3.5 +===================
     3.6 +
     3.7 +Plover is a front-end for the razor library intended to facilitate easy
     3.8 +integration with GLib and Gtk+.
     3.9 +
    3.10 +The official website for project beach (of which plover is one part) is:
    3.11 +
    3.12 +  http://www.juiblex.co.uk/beach/
    3.13 +
    3.14 +Installation
    3.15 +============
    3.16 +
    3.17 +Installation is via the standard procedure:
    3.18 +
    3.19 +% ./configure
    3.20 +% make
    3.21 +# make install              
    3.22 +
    3.23 +Tests
    3.24 +=====
    3.25 +
    3.26 +The main testsuite can be run using:
    3.27 +
    3.28 +% make check
    3.29 +
    3.30 +There are also a number of extended checks that use the main testsuite:
    3.31 +
    3.32 +% make distcheck		# Standard automake target
    3.33 +% make check-code-coverage	# Generate a coverage report for testsuite
    3.34 +% make check-valgrind		# Generate memcheck, etc., reports
    3.35 +
    3.36 +Note that check-valgrind in particular is not expected to pass. That would
    3.37 +require no unsuppressed false positives under all versions of our dependencies,
    3.38 +which is too difficult to achieve.
     4.1 --- a/app-manager/app-manager.c	Mon Apr 18 15:04:47 2016 +0100
     4.2 +++ b/app-manager/app-manager.c	Mon Jun 13 12:18:42 2016 +0100
     4.3 @@ -246,8 +246,8 @@
     4.4      }
     4.5  #endif
     4.6      plover_exception_handler_init();
     4.7 -    razor_set_lua_loader("posix",luaopen_posix);
     4.8 -    razor_set_lua_loader("whelk",luaopen_whelk);
     4.9 +    razor_set_lua_loader("posix",(void (*)())luaopen_posix);
    4.10 +    razor_set_lua_loader("whelk",(void (*)())luaopen_whelk);
    4.11      if (!gtk_init_with_args(&argc,&argv,NULL,options,NULL,&err))
    4.12      {
    4.13  	g_printerr("%s\n",err->message);
     5.1 --- a/bootstrap.sh	Mon Apr 18 15:04:47 2016 +0100
     5.2 +++ b/bootstrap.sh	Mon Jun 13 12:18:42 2016 +0100
     5.3 @@ -2,7 +2,7 @@
     5.4  set -e
     5.5  mkdir -p config
     5.6  autoheader
     5.7 -aclocal
     5.8 +aclocal -I m4
     5.9  libtoolize
    5.10  automake --foreign --add-missing
    5.11  autoconf
     6.1 --- a/configure.ac	Mon Apr 18 15:04:47 2016 +0100
     6.2 +++ b/configure.ac	Mon Jun 13 12:18:42 2016 +0100
     6.3 @@ -6,6 +6,7 @@
     6.4  AC_CONFIG_AUX_DIR([config])
     6.5  AC_CONFIG_SRCDIR([plover/plover.h])
     6.6  AC_CONFIG_HEADER([config.h])
     6.7 +AC_CONFIG_MACRO_DIR([m4])
     6.8  AC_CONFIG_FILES([Makefile
     6.9  plover/Makefile
    6.10  plover/plover.pc
    6.11 @@ -21,6 +22,9 @@
    6.12  app-manager/resources.rc
    6.13  plover-open/Makefile
    6.14  plover-open/resources.rc
    6.15 +tests/Makefile
    6.16 +tests/plover/Makefile
    6.17 +tests/plover-gtk/Makefile
    6.18  ])
    6.19  PLOVER_MSWIN_MANIFEST([setup/setup.exe.manifest:setup/manifest.xml.in
    6.20  update/update.exe.manifest:update/manifest.xml.in
    6.21 @@ -28,7 +32,7 @@
    6.22  app-manager/app-manager.exe.manifest:app-manager/manifest.xml.in
    6.23  plover-open/plover-open.exe.manifest:plover-open/manifest.xml.in
    6.24  ])
    6.25 -AM_INIT_AUTOMAKE(no-define)
    6.26 +AM_INIT_AUTOMAKE(no-define parallel-tests)
    6.27  m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
    6.28  case $VERSION in
    6.29    *.*.*)
    6.30 @@ -98,6 +102,20 @@
    6.31  if test "$RSVG" = no; then
    6.32      AC_MSG_ERROR([no rsvg program found to convert SVG files to bitmaps])
    6.33  fi
    6.34 +AX_VALGRIND_CHECK
    6.35 +AS_IF([test "$enable_valgrind" != "no"],[[
    6.36 +    major=`$VALGRIND --version | \
    6.37 +      sed -e 's/^valgrind-//' -e 's/^[^.]*$/0/' -e 's/\..*//'`
    6.38 +    minor=`$VALGRIND --version | \
    6.39 +      sed -e 's/^valgrind-//' -e 's/.*/&.0.0/' -e 's/[^.]*\.\([^.]*\)\..*/\1/'`
    6.40 +]],[major=0; minor=0])
    6.41 +AM_CONDITIONAL([HAVE_VALGRIND_3_9],[test 0$major -gt 3 -o 0$minor -gt 8])
    6.42 +AX_CODE_COVERAGE
    6.43 +AC_CHECK_TOOL([RAZOR],[razor],[no])
    6.44 +AC_CHECK_TOOL([RPMBUILD],[rpmbuild],[no])
    6.45 +AC_CHECK_TOOL([CREATEREPO],[createrepo],[no])
    6.46 +AM_CONDITIONAL([HAVE_CHECK_TOOLS],
    6.47 +  [test x$RAZOR != xno -a x$RPMBUILD != xno -a x$CREATEREPO != xno])
    6.48  
    6.49  ##################################################
    6.50  # Checks for header files.
    6.51 @@ -119,6 +137,7 @@
    6.52  PKG_CHECK_MODULES(EXPAT,[expat >= 2.1],[:],
    6.53    [PKG_CHECK_MODULES(EXPAT,[expat21],[:],[EXPAT_LIBS=-lexpat])])
    6.54  PKG_CHECK_MODULES(ZLIB,[zlib],[:],[ZLIB_LIBS=-lz])
    6.55 +PKG_CHECK_MODULES(LUA,[lua],[:],[LUA_LIBS=-llua])
    6.56  PKG_CHECK_MODULES(GIO,[gio-2.0])
    6.57  PKG_CHECK_MODULES(GTK,[gtk+-2.0])
    6.58  PKG_CHECK_MODULES(GMODULE_EXPORT,[gmodule-export-2.0])
    6.59 @@ -132,11 +151,15 @@
    6.60  AC_SUBST(PLOVER_GTK_LIBS)
    6.61  save_LIBS="$LIBS"
    6.62  AC_SEARCH_LIBS([crypt],[crypt])
    6.63 +LUA_POSIX_CFLAGS="$LUA_CFLAGS"
    6.64 +LUA_POSIX_LIBS="-llua-posix $LUA_LIBS $LIBS"
    6.65 +LIBS="$save_LIBS"
    6.66 +AC_SUBST(LUA_POSIX_CFLAGS)
    6.67 +AC_SUBST(LUA_POSIX_LIBS)
    6.68  GUI_CFLAGS="$GMODULE_EXPORT_CFLAGS $WHELK_CFLAGS $PLOVER_GTK_CFLAGS \
    6.69 -  $LIBPLOVER_CFLAGS"
    6.70 -GUI_LIBS="-llua-posix $GMODULE_EXPORT_LIBS $WHELK_LIBS $PLOVER_GTK_LIBS \
    6.71 -  $LIBPLOVER_LIBS $LIBS"
    6.72 -LIBS="$save_LIBS"
    6.73 +  $LIBPLOVER_CFLAGS $LUA_POSIX_CFLAGS"
    6.74 +GUI_LIBS="$GMODULE_EXPORT_LIBS $WHELK_LIBS $PLOVER_GTK_LIBS \
    6.75 +  $LIBPLOVER_LIBS $LUA_POSIX_LIBS"
    6.76  AC_SUBST(GUI_CFLAGS)
    6.77  AC_SUBST(GUI_LIBS)
    6.78  save_PKG_CONFIG="$PKG_CONFIG"
    6.79 @@ -150,13 +173,11 @@
    6.80      SETUP_LIBS="$SETUP_LIBS -liconv"
    6.81  fi
    6.82  PKG_CONFIG="$save_PKG_CONFIG"
    6.83 -save_LIBS="$LIBS"
    6.84 -AC_SEARCH_LIBS([crypt],[crypt])
    6.85 -SETUP_LIBS="-llua-posix $SETUP_LIBS $LIBS"
    6.86 -SETUP_CFLAGS="$SETUP_CFLAGS"
    6.87 +SETUP_CFLAGS="$SETUP_CFLAGS $LUA_POSIX_CFLAGS"
    6.88 +SETUP_LIBS="$SETUP_LIBS $LUA_POSIX_LIBS"
    6.89  AC_SUBST(SETUP_LIBS)
    6.90  AC_SUBST(SETUP_CFLAGS)
    6.91 -LIBS="$save_LIBS"
    6.92 +save_LIBS="$LIBS"
    6.93  LIBS="$LIBS -lcrypt32"
    6.94  AC_MSG_CHECKING([for library containing CertEnumCertificatesInStore])
    6.95  AC_LINK_IFELSE([AC_LANG_PROGRAM(
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/m4/ax_code_coverage.m4	Mon Jun 13 12:18:42 2016 +0100
     7.3 @@ -0,0 +1,274 @@
     7.4 +# ===========================================================================
     7.5 +#     http://www.gnu.org/software/autoconf-archive/ax_code_coverage.html
     7.6 +# ===========================================================================
     7.7 +#
     7.8 +# SYNOPSIS
     7.9 +#
    7.10 +#   AX_CODE_COVERAGE()
    7.11 +#
    7.12 +# DESCRIPTION
    7.13 +#
    7.14 +#   Defines CODE_COVERAGE_CPPFLAGS, CODE_COVERAGE_CFLAGS,
    7.15 +#   CODE_COVERAGE_CXXFLAGS and CODE_COVERAGE_LDFLAGS which should be
    7.16 +#   included in the CPPFLAGS, CFLAGS CXXFLAGS and LIBS/LDFLAGS variables of
    7.17 +#   every build target (program or library) which should be built with code
    7.18 +#   coverage support. Also defines CODE_COVERAGE_RULES which should be
    7.19 +#   substituted in your Makefile; and $enable_code_coverage which can be
    7.20 +#   used in subsequent configure output. CODE_COVERAGE_ENABLED is defined
    7.21 +#   and substituted, and corresponds to the value of the
    7.22 +#   --enable-code-coverage option, which defaults to being disabled.
    7.23 +#
    7.24 +#   Test also for gcov program and create GCOV variable that could be
    7.25 +#   substituted.
    7.26 +#
    7.27 +#   Note that all optimisation flags in CFLAGS must be disabled when code
    7.28 +#   coverage is enabled.
    7.29 +#
    7.30 +#   Usage example:
    7.31 +#
    7.32 +#   configure.ac:
    7.33 +#
    7.34 +#     AX_CODE_COVERAGE
    7.35 +#
    7.36 +#   Makefile.am:
    7.37 +#
    7.38 +#     @CODE_COVERAGE_RULES@
    7.39 +#     my_program_LIBS = ... $(CODE_COVERAGE_LDFLAGS) ...
    7.40 +#     my_program_CPPFLAGS = ... $(CODE_COVERAGE_CPPFLAGS) ...
    7.41 +#     my_program_CFLAGS = ... $(CODE_COVERAGE_CFLAGS) ...
    7.42 +#     my_program_CXXFLAGS = ... $(CODE_COVERAGE_CXXFLAGS) ...
    7.43 +#
    7.44 +#   This results in a "check-code-coverage" rule being added to any
    7.45 +#   Makefile.am which includes "@CODE_COVERAGE_RULES@" (assuming the module
    7.46 +#   has been configured with --enable-code-coverage). Running `make
    7.47 +#   check-code-coverage` in that directory will run the module's test suite
    7.48 +#   (`make check`) and build a code coverage report detailing the code which
    7.49 +#   was touched, then print the URI for the report.
    7.50 +#
    7.51 +#   This code was derived from Makefile.decl in GLib, originally licenced
    7.52 +#   under LGPLv2.1+.
    7.53 +#
    7.54 +# LICENSE
    7.55 +#
    7.56 +#   Copyright (c) 2012, 2016 Philip Withnall
    7.57 +#   Copyright (c) 2012 Xan Lopez
    7.58 +#   Copyright (c) 2012 Christian Persch
    7.59 +#   Copyright (c) 2012 Paolo Borelli
    7.60 +#   Copyright (c) 2012 Dan Winship
    7.61 +#   Copyright (c) 2015 Bastien ROUCARIES
    7.62 +#
    7.63 +#   This library is free software; you can redistribute it and/or modify it
    7.64 +#   under the terms of the GNU Lesser General Public License as published by
    7.65 +#   the Free Software Foundation; either version 2.1 of the License, or (at
    7.66 +#   your option) any later version.
    7.67 +#
    7.68 +#   This library is distributed in the hope that it will be useful, but
    7.69 +#   WITHOUT ANY WARRANTY; without even the implied warranty of
    7.70 +#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
    7.71 +#   General Public License for more details.
    7.72 +#
    7.73 +#   You should have received a copy of the GNU Lesser General Public License
    7.74 +#   along with this program. If not, see <http://www.gnu.org/licenses/>.
    7.75 +
    7.76 +#serial 16
    7.77 +
    7.78 +AC_DEFUN([AX_CODE_COVERAGE],[
    7.79 +	dnl Check for --enable-code-coverage
    7.80 +	AC_REQUIRE([AC_PROG_SED])
    7.81 +
    7.82 +	# allow to override gcov location
    7.83 +	AC_ARG_WITH([gcov],
    7.84 +	  [AS_HELP_STRING([--with-gcov[=GCOV]], [use given GCOV for coverage (GCOV=gcov).])],
    7.85 +	  [_AX_CODE_COVERAGE_GCOV_PROG_WITH=$with_gcov],
    7.86 +	  [_AX_CODE_COVERAGE_GCOV_PROG_WITH=gcov])
    7.87 +
    7.88 +	AC_MSG_CHECKING([whether to build with code coverage support])
    7.89 +	AC_ARG_ENABLE([code-coverage],
    7.90 +	  AS_HELP_STRING([--enable-code-coverage],
    7.91 +	  [Whether to enable code coverage support]),,
    7.92 +	  enable_code_coverage=no)
    7.93 +
    7.94 +	AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes])
    7.95 +	AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage])
    7.96 +	AC_MSG_RESULT($enable_code_coverage)
    7.97 +
    7.98 +	AS_IF([ test "$enable_code_coverage" = "yes" ], [
    7.99 +		# check for gcov
   7.100 +		AC_CHECK_TOOL([GCOV],
   7.101 +		  [$_AX_CODE_COVERAGE_GCOV_PROG_WITH],
   7.102 +		  [:])
   7.103 +		AS_IF([test "X$GCOV" = "X:"],
   7.104 +		  [AC_MSG_ERROR([gcov is needed to do coverage])])
   7.105 +		AC_SUBST([GCOV])
   7.106 +
   7.107 +		dnl Check if gcc is being used
   7.108 +		AS_IF([ test "$GCC" = "no" ], [
   7.109 +			AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage])
   7.110 +		])
   7.111 +
   7.112 +		# List of supported lcov versions.
   7.113 +		lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11 1.12"
   7.114 +
   7.115 +		AC_CHECK_PROG([LCOV], [lcov], [lcov])
   7.116 +		AC_CHECK_PROG([GENHTML], [genhtml], [genhtml])
   7.117 +
   7.118 +		AS_IF([ test "$LCOV" ], [
   7.119 +			AC_CACHE_CHECK([for lcov version], ax_cv_lcov_version, [
   7.120 +				ax_cv_lcov_version=invalid
   7.121 +				lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'`
   7.122 +				for lcov_check_version in $lcov_version_list; do
   7.123 +					if test "$lcov_version" = "$lcov_check_version"; then
   7.124 +						ax_cv_lcov_version="$lcov_check_version (ok)"
   7.125 +					fi
   7.126 +				done
   7.127 +			])
   7.128 +		], [
   7.129 +			lcov_msg="To enable code coverage reporting you must have one of the following lcov versions installed: $lcov_version_list"
   7.130 +			AC_MSG_ERROR([$lcov_msg])
   7.131 +		])
   7.132 +
   7.133 +		case $ax_cv_lcov_version in
   7.134 +			""|invalid[)]
   7.135 +				lcov_msg="You must have one of the following versions of lcov: $lcov_version_list (found: $lcov_version)."
   7.136 +				AC_MSG_ERROR([$lcov_msg])
   7.137 +				LCOV="exit 0;"
   7.138 +			;;
   7.139 +		esac
   7.140 +
   7.141 +		AS_IF([ test -z "$GENHTML" ], [
   7.142 +			AC_MSG_ERROR([Could not find genhtml from the lcov package])
   7.143 +		])
   7.144 +
   7.145 +		dnl Build the code coverage flags
   7.146 +		CODE_COVERAGE_CPPFLAGS="-DNDEBUG"
   7.147 +		CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
   7.148 +		CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
   7.149 +		CODE_COVERAGE_LDFLAGS="-lgcov"
   7.150 +
   7.151 +		AC_SUBST([CODE_COVERAGE_CPPFLAGS])
   7.152 +		AC_SUBST([CODE_COVERAGE_CFLAGS])
   7.153 +		AC_SUBST([CODE_COVERAGE_CXXFLAGS])
   7.154 +		AC_SUBST([CODE_COVERAGE_LDFLAGS])
   7.155 +	])
   7.156 +
   7.157 +[CODE_COVERAGE_RULES='
   7.158 +# Code coverage
   7.159 +#
   7.160 +# Optional:
   7.161 +#  - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting.
   7.162 +#    Multiple directories may be specified, separated by whitespace.
   7.163 +#    (Default: $(top_builddir))
   7.164 +#  - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated
   7.165 +#    by lcov for code coverage. (Default:
   7.166 +#    $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info)
   7.167 +#  - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage
   7.168 +#    reports to be created. (Default:
   7.169 +#    $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage)
   7.170 +#  - CODE_COVERAGE_BRANCH_COVERAGE: Set to 1 to enforce branch coverage,
   7.171 +#    set to 0 to disable it and leave empty to stay with the default.
   7.172 +#    (Default: empty)
   7.173 +#  - CODE_COVERAGE_LCOV_SHOPTS_DEFAULT: Extra options shared between both lcov
   7.174 +#    instances. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE)
   7.175 +#  - CODE_COVERAGE_LCOV_SHOPTS: Extra options to shared between both lcov
   7.176 +#    instances. (Default: $CODE_COVERAGE_LCOV_SHOPTS_DEFAULT)
   7.177 +#  - CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH: --gcov-tool pathtogcov
   7.178 +#  - CODE_COVERAGE_LCOV_OPTIONS_DEFAULT: Extra options to pass to the
   7.179 +#    collecting lcov instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH)
   7.180 +#  - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the collecting lcov
   7.181 +#    instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_DEFAULT)
   7.182 +#  - CODE_COVERAGE_LCOV_RMOPTS_DEFAULT: Extra options to pass to the filtering
   7.183 +#    lcov instance. (Default: empty)
   7.184 +#  - CODE_COVERAGE_LCOV_RMOPTS: Extra options to pass to the filtering lcov
   7.185 +#    instance. (Default: $CODE_COVERAGE_LCOV_RMOPTS_DEFAULT)
   7.186 +#  - CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT: Extra options to pass to the
   7.187 +#    genhtml instance. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE)
   7.188 +#  - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml
   7.189 +#    instance. (Default: $CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT)
   7.190 +#  - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore
   7.191 +#
   7.192 +# The generated report will be titled using the $(PACKAGE_NAME) and
   7.193 +# $(PACKAGE_VERSION). In order to add the current git hash to the title,
   7.194 +# use the git-version-gen script, available online.
   7.195 +
   7.196 +# Optional variables
   7.197 +CODE_COVERAGE_DIRECTORY ?= $(top_builddir)
   7.198 +CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info
   7.199 +CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage
   7.200 +CODE_COVERAGE_BRANCH_COVERAGE ?=
   7.201 +CODE_COVERAGE_LCOV_SHOPTS_DEFAULT ?= $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\
   7.202 +--rc lcov_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE))
   7.203 +CODE_COVERAGE_LCOV_SHOPTS ?= $(CODE_COVERAGE_LCOV_SHOPTS_DEFAULT)
   7.204 +CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH ?= --gcov-tool "$(GCOV)"
   7.205 +CODE_COVERAGE_LCOV_OPTIONS_DEFAULT ?= $(CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH)
   7.206 +CODE_COVERAGE_LCOV_OPTIONS ?= $(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT)
   7.207 +CODE_COVERAGE_LCOV_RMOPTS_DEFAULT ?=
   7.208 +CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT)
   7.209 +CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\
   7.210 +$(if $(CODE_COVERAGE_BRANCH_COVERAGE),\
   7.211 +--rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE))
   7.212 +CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULTS)
   7.213 +CODE_COVERAGE_IGNORE_PATTERN ?=
   7.214 +
   7.215 +code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V))
   7.216 +code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY))
   7.217 +code_coverage_v_lcov_cap_0 = @echo "  LCOV   --capture"\
   7.218 + $(CODE_COVERAGE_OUTPUT_FILE);
   7.219 +code_coverage_v_lcov_ign = $(code_coverage_v_lcov_ign_$(V))
   7.220 +code_coverage_v_lcov_ign_ = $(code_coverage_v_lcov_ign_$(AM_DEFAULT_VERBOSITY))
   7.221 +code_coverage_v_lcov_ign_0 = @echo "  LCOV   --remove /tmp/*"\
   7.222 + $(CODE_COVERAGE_IGNORE_PATTERN);
   7.223 +code_coverage_v_genhtml = $(code_coverage_v_genhtml_$(V))
   7.224 +code_coverage_v_genhtml_ = $(code_coverage_v_genhtml_$(AM_DEFAULT_VERBOSITY))
   7.225 +code_coverage_v_genhtml_0 = @echo "  GEN   " $(CODE_COVERAGE_OUTPUT_DIRECTORY);
   7.226 +code_coverage_quiet = $(code_coverage_quiet_$(V))
   7.227 +code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY))
   7.228 +code_coverage_quiet_0 = --quiet
   7.229 +
   7.230 +# sanitizes the test-name: replaces with underscores: dashes and dots
   7.231 +code_coverage_sanitize = $(subst -,_,$(subst .,_,$(1)))
   7.232 +
   7.233 +# Use recursive makes in order to ignore errors during check
   7.234 +check-code-coverage:
   7.235 +ifeq ($(CODE_COVERAGE_ENABLED),yes)
   7.236 +	-$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k check
   7.237 +	$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture
   7.238 +else
   7.239 +	@echo "Need to reconfigure with --enable-code-coverage"
   7.240 +endif
   7.241 +
   7.242 +# Capture code coverage data
   7.243 +code-coverage-capture: code-coverage-capture-hook
   7.244 +ifeq ($(CODE_COVERAGE_ENABLED),yes)
   7.245 +	$(code_coverage_v_lcov_cap)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(call code_coverage_sanitize,$(PACKAGE_NAME)-$(PACKAGE_VERSION))" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_OPTIONS)
   7.246 +	$(code_coverage_v_lcov_ign)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_RMOPTS)
   7.247 +	-@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp
   7.248 +	$(code_coverage_v_genhtml)LANG=C $(GENHTML) $(code_coverage_quiet) $(addprefix --prefix ,$(CODE_COVERAGE_DIRECTORY)) --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "$(PACKAGE_NAME)-$(PACKAGE_VERSION) Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS)
   7.249 +	@echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html"
   7.250 +else
   7.251 +	@echo "Need to reconfigure with --enable-code-coverage"
   7.252 +endif
   7.253 +
   7.254 +# Hook rule executed before code-coverage-capture, overridable by the user
   7.255 +code-coverage-capture-hook:
   7.256 +
   7.257 +ifeq ($(CODE_COVERAGE_ENABLED),yes)
   7.258 +clean: code-coverage-clean
   7.259 +distclean: code-coverage-clean
   7.260 +code-coverage-clean:
   7.261 +	-$(LCOV) --directory $(top_builddir) -z
   7.262 +	-rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY)
   7.263 +	-find . \( -name "*.gcda" -o -name "*.gcno" -o -name "*.gcov" \) -delete
   7.264 +endif
   7.265 +
   7.266 +GITIGNOREFILES ?=
   7.267 +GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY)
   7.268 +
   7.269 +A''M_DISTCHECK_CONFIGURE_FLAGS ?=
   7.270 +A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage
   7.271 +
   7.272 +.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean
   7.273 +']
   7.274 +
   7.275 +	AC_SUBST([CODE_COVERAGE_RULES])
   7.276 +	m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([CODE_COVERAGE_RULES])])
   7.277 +])
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/m4/ax_valgrind_check.m4	Mon Jun 13 12:18:42 2016 +0100
     8.3 @@ -0,0 +1,233 @@
     8.4 +# ===========================================================================
     8.5 +#     http://www.gnu.org/software/autoconf-archive/ax_valgrind_check.html
     8.6 +# ===========================================================================
     8.7 +#
     8.8 +# SYNOPSIS
     8.9 +#
    8.10 +#   AX_VALGRIND_CHECK()
    8.11 +#
    8.12 +# DESCRIPTION
    8.13 +#
    8.14 +#   Checks whether Valgrind is present and, if so, allows running `make
    8.15 +#   check` under a variety of Valgrind tools to check for memory and
    8.16 +#   threading errors.
    8.17 +#
    8.18 +#   Defines VALGRIND_CHECK_RULES which should be substituted in your
    8.19 +#   Makefile; and $enable_valgrind which can be used in subsequent configure
    8.20 +#   output. VALGRIND_ENABLED is defined and substituted, and corresponds to
    8.21 +#   the value of the --enable-valgrind option, which defaults to being
    8.22 +#   enabled if Valgrind is installed and disabled otherwise.
    8.23 +#
    8.24 +#   If unit tests are written using a shell script and automake's
    8.25 +#   LOG_COMPILER system, the $(VALGRIND) variable can be used within the
    8.26 +#   shell scripts to enable Valgrind, as described here:
    8.27 +#
    8.28 +#     https://www.gnu.org/software/gnulib/manual/html_node/Running-self_002dtests-under-valgrind.html
    8.29 +#
    8.30 +#   Usage example:
    8.31 +#
    8.32 +#   configure.ac:
    8.33 +#
    8.34 +#     AX_VALGRIND_CHECK
    8.35 +#
    8.36 +#   Makefile.am:
    8.37 +#
    8.38 +#     @VALGRIND_CHECK_RULES@
    8.39 +#     VALGRIND_SUPPRESSIONS_FILES = my-project.supp
    8.40 +#     EXTRA_DIST = my-project.supp
    8.41 +#
    8.42 +#   This results in a "check-valgrind" rule being added to any Makefile.am
    8.43 +#   which includes "@VALGRIND_CHECK_RULES@" (assuming the module has been
    8.44 +#   configured with --enable-valgrind). Running `make check-valgrind` in
    8.45 +#   that directory will run the module's test suite (`make check`) once for
    8.46 +#   each of the available Valgrind tools (out of memcheck, helgrind, drd and
    8.47 +#   sgcheck), and will output results to test-suite-$toolname.log for each.
    8.48 +#   The target will succeed if there are zero errors and fail otherwise.
    8.49 +#
    8.50 +#   Alternatively, a "check-valgrind-$TOOL" rule will be added, for $TOOL in
    8.51 +#   memcheck, helgrind, drd and sgcheck. These are useful because often only
    8.52 +#   some of those tools can be ran cleanly on a codebase.
    8.53 +#
    8.54 +#   The macro supports running with and without libtool.
    8.55 +#
    8.56 +# LICENSE
    8.57 +#
    8.58 +#   Copyright (c) 2014, 2015, 2016 Philip Withnall <philip.withnall@collabora.co.uk>
    8.59 +#
    8.60 +#   Copying and distribution of this file, with or without modification, are
    8.61 +#   permitted in any medium without royalty provided the copyright notice
    8.62 +#   and this notice are preserved.  This file is offered as-is, without any
    8.63 +#   warranty.
    8.64 +
    8.65 +#serial 9
    8.66 +
    8.67 +AC_DEFUN([AX_VALGRIND_CHECK],[
    8.68 +	dnl Check for --enable-valgrind
    8.69 +	AC_ARG_ENABLE([valgrind],
    8.70 +	              [AS_HELP_STRING([--enable-valgrind], [Whether to enable Valgrind on the unit tests])],
    8.71 +	              [enable_valgrind=$enableval],[enable_valgrind=])
    8.72 +
    8.73 +	AS_IF([test "$enable_valgrind" != "no"],[
    8.74 +		# Check for Valgrind.
    8.75 +		AC_CHECK_PROG([VALGRIND],[valgrind],[valgrind])
    8.76 +		AS_IF([test "$VALGRIND" = ""],[
    8.77 +			AS_IF([test "$enable_valgrind" = "yes"],[
    8.78 +				AC_MSG_ERROR([Could not find valgrind; either install it or reconfigure with --disable-valgrind])
    8.79 +			],[
    8.80 +				enable_valgrind=no
    8.81 +			])
    8.82 +		],[
    8.83 +			enable_valgrind=yes
    8.84 +		])
    8.85 +	])
    8.86 +
    8.87 +	AM_CONDITIONAL([VALGRIND_ENABLED],[test "$enable_valgrind" = "yes"])
    8.88 +	AC_SUBST([VALGRIND_ENABLED],[$enable_valgrind])
    8.89 +
    8.90 +	# Check for Valgrind tools we care about.
    8.91 +	m4_define([valgrind_tool_list],[[memcheck], [helgrind], [drd], [exp-sgcheck]])
    8.92 +
    8.93 +	AS_IF([test "$VALGRIND" != ""],[
    8.94 +		m4_foreach([vgtool],[valgrind_tool_list],[
    8.95 +			m4_define([vgtooln],AS_TR_SH(vgtool))
    8.96 +			m4_define([ax_cv_var],[ax_cv_valgrind_tool_]vgtooln)
    8.97 +			AC_CACHE_CHECK([for Valgrind tool ]vgtool,ax_cv_var,[
    8.98 +				ax_cv_var=
    8.99 +				AS_IF([`$VALGRIND --tool=vgtool --help >/dev/null 2>&1`],[
   8.100 +					ax_cv_var="vgtool"
   8.101 +				])
   8.102 +			])
   8.103 +
   8.104 +			AC_SUBST([VALGRIND_HAVE_TOOL_]vgtooln,[$ax_cv_var])
   8.105 +		])
   8.106 +	])
   8.107 +
   8.108 +[VALGRIND_CHECK_RULES='
   8.109 +# Valgrind check
   8.110 +#
   8.111 +# Optional:
   8.112 +#  - VALGRIND_SUPPRESSIONS_FILES: Space-separated list of Valgrind suppressions
   8.113 +#    files to load. (Default: empty)
   8.114 +#  - VALGRIND_FLAGS: General flags to pass to all Valgrind tools.
   8.115 +#    (Default: --num-callers=30)
   8.116 +#  - VALGRIND_$toolname_FLAGS: Flags to pass to Valgrind $toolname (one of:
   8.117 +#    memcheck, helgrind, drd, sgcheck). (Default: various)
   8.118 +
   8.119 +# Optional variables
   8.120 +VALGRIND_SUPPRESSIONS ?= $(addprefix --suppressions=,$(VALGRIND_SUPPRESSIONS_FILES))
   8.121 +VALGRIND_FLAGS ?= --num-callers=30
   8.122 +VALGRIND_memcheck_FLAGS ?= --leak-check=full --show-reachable=no
   8.123 +VALGRIND_helgrind_FLAGS ?= --history-level=approx
   8.124 +VALGRIND_drd_FLAGS ?=
   8.125 +VALGRIND_sgcheck_FLAGS ?=
   8.126 +
   8.127 +# Internal use
   8.128 +valgrind_tools = memcheck helgrind drd sgcheck
   8.129 +valgrind_log_files = $(addprefix test-suite-,$(addsuffix .log,$(valgrind_tools)))
   8.130 +
   8.131 +valgrind_memcheck_flags = --tool=memcheck $(VALGRIND_memcheck_FLAGS)
   8.132 +valgrind_helgrind_flags = --tool=helgrind $(VALGRIND_helgrind_FLAGS)
   8.133 +valgrind_drd_flags = --tool=drd $(VALGRIND_drd_FLAGS)
   8.134 +valgrind_sgcheck_flags = --tool=exp-sgcheck $(VALGRIND_sgcheck_FLAGS)
   8.135 +
   8.136 +valgrind_quiet = $(valgrind_quiet_$(V))
   8.137 +valgrind_quiet_ = $(valgrind_quiet_$(AM_DEFAULT_VERBOSITY))
   8.138 +valgrind_quiet_0 = --quiet
   8.139 +
   8.140 +# Support running with and without libtool.
   8.141 +ifneq ($(LIBTOOL),)
   8.142 +valgrind_lt = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=execute
   8.143 +else
   8.144 +valgrind_lt =
   8.145 +endif
   8.146 +
   8.147 +# Use recursive makes in order to ignore errors during check
   8.148 +check-valgrind:
   8.149 +ifeq ($(VALGRIND_ENABLED),yes)
   8.150 +	-$(foreach tool,$(valgrind_tools), \
   8.151 +		$(if $(VALGRIND_HAVE_TOOL_$(tool))$(VALGRIND_HAVE_TOOL_exp_$(tool)), \
   8.152 +			$(MAKE) $(AM_MAKEFLAGS) -k check-valgrind-tool VALGRIND_TOOL=$(tool); \
   8.153 +		) \
   8.154 +	)
   8.155 +else
   8.156 +	@echo "Need to reconfigure with --enable-valgrind"
   8.157 +endif
   8.158 +
   8.159 +# Valgrind running
   8.160 +VALGRIND_TESTS_ENVIRONMENT = \
   8.161 +	$(TESTS_ENVIRONMENT) \
   8.162 +	env VALGRIND=$(VALGRIND) \
   8.163 +	G_SLICE=always-malloc,debug-blocks \
   8.164 +	G_DEBUG=fatal-warnings,fatal-criticals,gc-friendly
   8.165 +
   8.166 +VALGRIND_LOG_COMPILER = \
   8.167 +	$(valgrind_lt) \
   8.168 +	$(VALGRIND) $(VALGRIND_SUPPRESSIONS) --error-exitcode=1 $(VALGRIND_FLAGS)
   8.169 +
   8.170 +check-valgrind-tool:
   8.171 +ifeq ($(VALGRIND_ENABLED),yes)
   8.172 +	$(MAKE) check-TESTS \
   8.173 +		TESTS_ENVIRONMENT="$(VALGRIND_TESTS_ENVIRONMENT)" \
   8.174 +		LOG_COMPILER="$(VALGRIND_LOG_COMPILER)" \
   8.175 +		LOG_FLAGS="$(valgrind_$(VALGRIND_TOOL)_flags)" \
   8.176 +		TEST_SUITE_LOG=test-suite-$(VALGRIND_TOOL).log
   8.177 +else
   8.178 +	@echo "Need to reconfigure with --enable-valgrind"
   8.179 +endif
   8.180 +
   8.181 +check-valgrind-memcheck:
   8.182 +ifeq ($(VALGRIND_ENABLED),yes)
   8.183 +	$(MAKE) check-TESTS \
   8.184 +		TESTS_ENVIRONMENT="$(VALGRIND_TESTS_ENVIRONMENT)" \
   8.185 +		LOG_COMPILER="$(VALGRIND_LOG_COMPILER)" \
   8.186 +		LOG_FLAGS="$(valgrind_memcheck_flags)" \
   8.187 +		TEST_SUITE_LOG=test-suite-memcheck.log
   8.188 +else
   8.189 +	@echo "Need to reconfigure with --enable-valgrind"
   8.190 +endif
   8.191 +
   8.192 +check-valgrind-helgrind:
   8.193 +ifeq ($(VALGRIND_ENABLED),yes)
   8.194 +	$(MAKE) check-TESTS \
   8.195 +		TESTS_ENVIRONMENT="$(VALGRIND_TESTS_ENVIRONMENT)" \
   8.196 +		LOG_COMPILER="$(VALGRIND_LOG_COMPILER)" \
   8.197 +		LOG_FLAGS="$(valgrind_helgrind_flags)" \
   8.198 +		TEST_SUITE_LOG=test-suite-helgrind.log
   8.199 +else
   8.200 +	@echo "Need to reconfigure with --enable-valgrind"
   8.201 +endif
   8.202 +
   8.203 +check-valgrind-drd:
   8.204 +ifeq ($(VALGRIND_ENABLED),yes)
   8.205 +	$(MAKE) check-TESTS \
   8.206 +		TESTS_ENVIRONMENT="$(VALGRIND_TESTS_ENVIRONMENT)" \
   8.207 +		LOG_COMPILER="$(VALGRIND_LOG_COMPILER)" \
   8.208 +		LOG_FLAGS="$(valgrind_drd_flags)" \
   8.209 +		TEST_SUITE_LOG=test-suite-drd.log
   8.210 +else
   8.211 +	@echo "Need to reconfigure with --enable-valgrind"
   8.212 +endif
   8.213 +
   8.214 +check-valgrind-sgcheck:
   8.215 +ifeq ($(VALGRIND_ENABLED),yes)
   8.216 +	$(MAKE) check-TESTS \
   8.217 +		TESTS_ENVIRONMENT="$(VALGRIND_TESTS_ENVIRONMENT)" \
   8.218 +		LOG_COMPILER="$(VALGRIND_LOG_COMPILER)" \
   8.219 +		LOG_FLAGS="$(valgrind_sgcheck_flags)" \
   8.220 +		TEST_SUITE_LOG=test-suite-sgcheck.log
   8.221 +else
   8.222 +	@echo "Need to reconfigure with --enable-valgrind"
   8.223 +endif
   8.224 +
   8.225 +A''M_DISTCHECK_CONFIGURE_FLAGS ?=
   8.226 +A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-valgrind
   8.227 +
   8.228 +MOSTLYCLEANFILES ?=
   8.229 +MOSTLYCLEANFILES += $(valgrind_log_files)
   8.230 +
   8.231 +.PHONY: check-valgrind check-valgrind-tool
   8.232 +']
   8.233 +
   8.234 +	AC_SUBST([VALGRIND_CHECK_RULES])
   8.235 +	m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([VALGRIND_CHECK_RULES])])
   8.236 +])
     9.1 --- a/plover-gtk/Makefile.am	Mon Apr 18 15:04:47 2016 +0100
     9.2 +++ b/plover-gtk/Makefile.am	Mon Jun 13 12:18:42 2016 +0100
     9.3 @@ -1,7 +1,9 @@
     9.4 -AM_CFLAGS=-g $(PLOVER_GTK_CFLAGS) -DPLOVER_DATADIR=\""$(pkgdatadir)"\"
     9.5 +AM_CFLAGS=-g $(PLOVER_GTK_CFLAGS) $(CODE_COVERAGE_CFLAGS) \
     9.6 +  -DPLOVER_DATADIR=\""$(pkgdatadir)"\"
     9.7  LIBS=../plover/libplover.la $(PLOVER_GTK_LIBS)
     9.8  INCLUDES=-I$(top_srcdir)
     9.9 -AM_LDFLAGS=-no-undefined -version-info $(PLOVER_GTK_LT_VERSION_INFO)
    9.10 +AM_LDFLAGS=-no-undefined -version-info $(PLOVER_GTK_LT_VERSION_INFO) \
    9.11 +  $(CODE_COVERAGE_LDFLAGS)
    9.12  
    9.13  uidir=$(pkgdatadir)
    9.14  ui_DATA=software-installation.ui
    10.1 --- a/plover-gtk/packagefilestore.c	Mon Apr 18 15:04:47 2016 +0100
    10.2 +++ b/plover-gtk/packagefilestore.c	Mon Jun 13 12:18:42 2016 +0100
    10.3 @@ -265,7 +265,7 @@
    10.4      g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
    10.5      struct razor_file_iterator *iter;
    10.6      iter=plover_package_file_iterator_create(package,FALSE);
    10.7 -    store=GTK_TREE_MODEL(plover_package_file_store_new(iter));
    10.8 +    store=plover_package_file_store_new(iter);
    10.9      razor_file_iterator_destroy(iter);
   10.10      return store;
   10.11  }
    11.1 --- a/plover-gtk/software-installation.ui	Mon Apr 18 15:04:47 2016 +0100
    11.2 +++ b/plover-gtk/software-installation.ui	Mon Jun 13 12:18:42 2016 +0100
    11.3 @@ -21,8 +21,8 @@
    11.4          <property name="ypad">16</property>
    11.5          <property name="label" translatable="yes">&lt;b&gt;Welcome to the Installation Assistant&lt;/b&gt;
    11.6  
    11.7 -The Installation Assistant will install the software.
    11.8 -To continue, click Forward.</property>
    11.9 +The Installation Assistant will make the changes to the
   11.10 +software you have requested. To continue, click Forward.</property>
   11.11          <property name="use_markup">True</property>
   11.12        </object>
   11.13        <packing>
   11.14 @@ -110,7 +110,7 @@
   11.15          <property name="visible">True</property>
   11.16          <property name="orientation">vertical</property>
   11.17          <child>
   11.18 -          <object class="GtkLabel" id="label1">
   11.19 +          <object class="GtkLabel" id="SIProgressLabel">
   11.20              <property name="visible">True</property>
   11.21              <property name="xalign">0</property>
   11.22              <property name="yalign">0</property>
   11.23 @@ -138,7 +138,7 @@
   11.24                  <property name="visible">True</property>
   11.25                  <property name="activity_mode">True</property>
   11.26                  <property name="show_text">True</property>
   11.27 -                <property name="text" translatable="yes">Unpacking files</property>
   11.28 +                <property name="text" translatable="yes">Starting</property>
   11.29                </object>
   11.30              </child>
   11.31            </object>
    12.1 --- a/plover-gtk/stockicons.c	Mon Apr 18 15:04:47 2016 +0100
    12.2 +++ b/plover-gtk/stockicons.c	Mon Jun 13 12:18:42 2016 +0100
    12.3 @@ -34,6 +34,8 @@
    12.4      GSList *tmp_list;
    12.5      static gint found_svg=-1;
    12.6      gchar **mime_types,**mime_type;
    12.7 +    if (g_getenv("PLOVER_IGNORE_SVG_SUPPORT"))
    12.8 +	return FALSE;
    12.9      if (found_svg!=-1)
   12.10  	return found_svg;
   12.11      formats=gdk_pixbuf_get_formats();
   12.12 @@ -55,10 +57,15 @@
   12.13  {
   12.14      int w,h;
   12.15      GdkPixbuf *pixbuf;
   12.16 +    GtkSettings *settings;
   12.17      GtkIconSource *source;
   12.18 -    if (gtk_icon_size_lookup(size,&w,&h))
   12.19 +    GError *err=NULL;
   12.20 +    settings=gtk_settings_get_default();
   12.21 +    if (!settings)
   12.22 +	g_warning("plover: Can't add icons without a default screen");
   12.23 +    else if (gtk_icon_size_lookup_for_settings(settings,size,&w,&h))
   12.24      {
   12.25 -	pixbuf=gdk_pixbuf_new_from_file_at_size(filename,w,h,NULL);
   12.26 +	pixbuf=gdk_pixbuf_new_from_file_at_size(filename,w,h,&err);
   12.27  	if (pixbuf)
   12.28  	{
   12.29  	    source=gtk_icon_source_new();
   12.30 @@ -69,6 +76,11 @@
   12.31  	    gtk_icon_source_free(source);
   12.32  	    g_object_unref(pixbuf);
   12.33  	}
   12.34 +	else
   12.35 +	{
   12.36 +	    g_warning("%s: %s",filename,err->message);
   12.37 +	    g_error_free(err);
   12.38 +	}
   12.39      }
   12.40  }
   12.41  
   12.42 @@ -87,23 +99,30 @@
   12.43   */
   12.44  void plover_icons_add_to_stock(const char *type,const char *name)
   12.45  {
   12.46 -    gchar *prefix,*s,*filename;
   12.47 +    gchar *datadir,*prefix,*s,*filename;
   12.48      GtkIconSource *source;
   12.49      GtkIconSet *icon_set;
   12.50      GtkIconFactory *factory;
   12.51      factory=gtk_icon_factory_new();
   12.52      icon_set=gtk_icon_set_new();
   12.53 +    datadir=g_strdup(g_getenv("PLOVER_ICONS_DATADIR"));
   12.54 +    if (!datadir)
   12.55 +    {
   12.56  #ifdef WIN32
   12.57 -    prefix=g_win32_get_package_installation_directory_of_module(NULL);
   12.58 +	prefix=g_win32_get_package_installation_directory_of_module(NULL);
   12.59  #else
   12.60 -    prefix=NULL;
   12.61 +	prefix=NULL;
   12.62  #endif
   12.63 +	if (!prefix)
   12.64 +	    prefix=g_strdup("/usr");
   12.65 +	datadir=g_strconcat(prefix,"share",NULL);
   12.66 +	g_free(prefix);
   12.67 +    }
   12.68      if (plover_pixbuf_supports_svg())
   12.69      {
   12.70  	source=gtk_icon_source_new();
   12.71  	s=g_strconcat(name,".svg",NULL);
   12.72 -	filename=g_build_filename(prefix?prefix:"/usr",
   12.73 -	  "share/icons/hicolor/scalable",type,s,NULL);
   12.74 +	filename=g_build_filename(datadir,"icons/hicolor/scalable",type,s,NULL);
   12.75  	g_free(s);
   12.76  	gtk_icon_source_set_filename(source,filename);
   12.77  	g_free(filename);
   12.78 @@ -113,8 +132,7 @@
   12.79      else
   12.80      {
   12.81  	s=g_strconcat(name,".png",NULL);
   12.82 -	filename=g_build_filename(prefix?prefix:"/usr",
   12.83 -	  "share/icons/hicolor/24x24",type,s,NULL);
   12.84 +	filename=g_build_filename(datadir,"icons/hicolor/24x24",type,s,NULL);
   12.85  	plover_install_icon_at_size(name,icon_set,GTK_ICON_SIZE_MENU,
   12.86  	  filename);
   12.87  	plover_install_icon_at_size(name,icon_set,GTK_ICON_SIZE_BUTTON,
   12.88 @@ -124,8 +142,7 @@
   12.89  	plover_install_icon_at_size(name,icon_set,GTK_ICON_SIZE_LARGE_TOOLBAR,
   12.90  	  filename);
   12.91  	g_free(filename);
   12.92 -	filename=g_build_filename(prefix?prefix:"/usr",
   12.93 -	  "share/icons/hicolor/48x48",type,s,NULL);
   12.94 +	filename=g_build_filename(datadir,"icons/hicolor/48x48",type,s,NULL);
   12.95  	plover_install_icon_at_size(name,icon_set,GTK_ICON_SIZE_DND,
   12.96  	  filename);
   12.97  	plover_install_icon_at_size(name,icon_set,GTK_ICON_SIZE_DIALOG,
   12.98 @@ -133,6 +150,7 @@
   12.99  	g_free(filename);
  12.100  	g_free(s);
  12.101      }
  12.102 +    g_free(datadir);
  12.103      gtk_icon_factory_add(factory,name,icon_set);
  12.104      gtk_icon_set_unref(icon_set);
  12.105      //icon_set=gtk_icon_factory_lookup(factory,name);
    13.1 --- a/plover-gtk/transactionhelper.c	Mon Apr 18 15:04:47 2016 +0100
    13.2 +++ b/plover-gtk/transactionhelper.c	Mon Jun 13 12:18:42 2016 +0100
    13.3 @@ -31,6 +31,23 @@
    13.4  
    13.5  G_DEFINE_TYPE(PloverTransactionHelper,plover_transaction_helper,G_TYPE_OBJECT)
    13.6  
    13.7 +enum plover_transaction_type {
    13.8 +    TRANSACTION_TYPE_NULL=0,
    13.9 +    TRANSACTION_TYPE_INSTALL=1UL<<0,
   13.10 +    TRANSACTION_TYPE_REMOVE=1UL<<1,
   13.11 +    TRANSACTION_TYPE_UPDATE=TRANSACTION_TYPE_INSTALL|TRANSACTION_TYPE_REMOVE
   13.12 +};
   13.13 +
   13.14 +typedef struct _PloverTransactionHelperPrivate {
   13.15 +    enum plover_transaction_type transaction_type;
   13.16 +    gchar *default_prefix;
   13.17 +} PloverTransactionHelperPrivate;
   13.18 +
   13.19 +#define PLOVER_TRANSACTION_HELPER_GET_PRIVATE(obj)\
   13.20 +                                G_TYPE_INSTANCE_GET_PRIVATE(obj,\
   13.21 +				  PLOVER_TYPE_TRANSACTION_HELPER,\
   13.22 +				  PloverTransactionHelperPrivate)
   13.23 +
   13.24  enum {
   13.25      CLOSE=0,
   13.26      N_SIGNALS
   13.27 @@ -40,6 +57,9 @@
   13.28  
   13.29  static void plover_transaction_helper_finalize(PloverTransactionHelper *helper)
   13.30  {
   13.31 +    PloverTransactionHelperPrivate *priv;
   13.32 +    priv=PLOVER_TRANSACTION_HELPER_GET_PRIVATE(helper);
   13.33 +    g_free(priv->default_prefix);
   13.34      g_free(helper->error_primary_text);
   13.35      g_free(helper->base);
   13.36      g_free(helper->unsatisfied);
   13.37 @@ -80,6 +100,7 @@
   13.38        (void (*)(GObject *))plover_transaction_helper_finalize;
   13.39      gobject_class->dispose=
   13.40        (void (*)(GObject *))plover_transaction_helper_dispose;
   13.41 +    g_type_class_add_private(klass,sizeof(PloverTransactionHelperPrivate));
   13.42      signals[CLOSE]=g_signal_newv("close",
   13.43        G_TYPE_FROM_CLASS(klass),G_SIGNAL_RUN_LAST,NULL,NULL,NULL,
   13.44        g_cclosure_marshal_VOID__VOID,G_TYPE_NONE,0,NULL);
   13.45 @@ -185,6 +206,12 @@
   13.46      }
   13.47      else
   13.48  	plover_transaction_helper_run(helper);
   13.49 +    /*
   13.50 +     * There may be status updates queued by transaction as idle events.
   13.51 +     * Process them now before we disconnect so that we don't lose them.
   13.52 +     */
   13.53 +    while(g_main_context_pending(NULL))
   13.54 +	g_main_context_iteration(NULL,FALSE);
   13.55      g_signal_handlers_disconnect_by_data(transaction,helper);
   13.56      g_object_unref(transaction);
   13.57  }
   13.58 @@ -248,11 +275,35 @@
   13.59      GError *error=NULL;
   13.60      GtkToggleButton *button;
   13.61      PloverTransaction *transaction;
   13.62 +    GSList *save_transactions;
   13.63 +    PloverTransactionHelperPrivate *priv;
   13.64 +    enum plover_transaction_type save_transaction_type;
   13.65 +    priv=PLOVER_TRANSACTION_HELPER_GET_PRIVATE(helper);
   13.66      button=GTK_TOGGLE_BUTTON(gtk_builder_get_object(helper->ui,
   13.67        "SIRemoveExisting"));
   13.68      if (gtk_toggle_button_get_active(button))
   13.69      {
   13.70  	transaction=plover_transaction_new_remove(NULL,&error);
   13.71 +	if (transaction)
   13.72 +	{
   13.73 +	    save_transactions=helper->transactions;
   13.74 +	    helper->transactions=NULL;
   13.75 +	    save_transaction_type=priv->transaction_type;
   13.76 +	    priv->transaction_type=0;
   13.77 +	    if (!plover_transaction_helper_add_transaction(helper,transaction,
   13.78 +	      NULL,PLOVER_TRANSACTION_HELPER_REPORT_REMOVE,&error))
   13.79 +	    {
   13.80 +		g_object_unref(transaction);
   13.81 +		transaction=NULL;
   13.82 +		helper->transactions=save_transactions;
   13.83 +		priv->transaction_type=save_transaction_type;
   13.84 +	    }
   13.85 +	    else
   13.86 +	    {
   13.87 +		g_slist_foreach(save_transactions,(GFunc)g_object_unref,NULL);
   13.88 +		g_slist_free(save_transactions);
   13.89 +	    }
   13.90 +	}
   13.91  	if (!transaction)
   13.92  	{
   13.93  	    if (g_error_matches(error,PLOVER_POSIX_ERROR,ENOENT))
   13.94 @@ -260,14 +311,11 @@
   13.95  	    if (error)
   13.96  	    {
   13.97  		plover_transaction_helper_set_error(helper,error,
   13.98 -		  "Software installation failed");
   13.99 +		  "Failed to remove existing packages");
  13.100  		g_error_free(error);
  13.101  		return;
  13.102  	    }
  13.103  	}
  13.104 -	else
  13.105 -	    helper->transactions=
  13.106 -	      g_slist_prepend(helper->transactions,transaction);
  13.107      }
  13.108      /*
  13.109       * Note that PloverTransaction does support cancelling a transaction, but
  13.110 @@ -427,71 +475,15 @@
  13.111    GError **error)
  13.112  {
  13.113      const char *base;
  13.114 -#if 0
  13.115 -    const char *prefix;
  13.116 -    struct razor_relocations *relocations=NULL;
  13.117 -#endif
  13.118      g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL);
  13.119      if (!helper->upstream)
  13.120      {
  13.121 -#if 0
  13.122 -	prefix=plover_transaction_helper_get_prefix(helper,error);
  13.123 -	if (!prefix)
  13.124 -	    return NULL;
  13.125 -#endif
  13.126  	base=plover_transaction_helper_get_base(helper);
  13.127 -#if 0
  13.128 -	if (prefix)
  13.129 -	{
  13.130 -	    relocations=razor_relocations_create();
  13.131 -	    razor_relocations_add(relocations,"/usr",prefix);
  13.132 -	}
  13.133 -#endif
  13.134  	helper->upstream=plover_repository_new_from_yum(base,error);
  13.135 -#if 0
  13.136 -	if (relocations)
  13.137 -	    razor_relocations_destroy(relocations);
  13.138 -#endif
  13.139      }
  13.140      return helper->upstream;
  13.141  }
  13.142  
  13.143 -static PloverPackageSet *plover_transaction_helper_get_relocated_upstream(
  13.144 -  PloverTransactionHelper *helper,GError **error)
  13.145 -{
  13.146 -    const char *prefix;
  13.147 -    struct razor_relocations *relocations=NULL;
  13.148 -    GError *tmp_error=NULL;
  13.149 -    PloverRepository *upstream;
  13.150 -    PloverPackageSet *set;
  13.151 -    if (!helper->relocated_upstream)
  13.152 -    {
  13.153 -	upstream=plover_transaction_helper_get_upstream(helper,error);
  13.154 -	if (!upstream)
  13.155 -	    return NULL;
  13.156 -	prefix=plover_transaction_helper_get_prefix(helper,&tmp_error);
  13.157 -	if (tmp_error)
  13.158 -	{
  13.159 -	    g_propagate_error(error,tmp_error);
  13.160 -	    return NULL;
  13.161 -	}
  13.162 -	set=plover_repository_get_package_set(upstream);
  13.163 -	if (prefix)
  13.164 -	{
  13.165 -	    relocations=razor_relocations_create();
  13.166 -	    razor_relocations_add(relocations,"/usr",prefix);
  13.167 -	    helper->relocated_upstream=
  13.168 -	      plover_package_set_new_from_repository(upstream,relocations,
  13.169 -	      error);
  13.170 -	    if (relocations)
  13.171 -		razor_relocations_destroy(relocations);
  13.172 -	}
  13.173 -	else
  13.174 -	    helper->relocated_upstream=g_object_ref(set);
  13.175 -    }
  13.176 -    return helper->relocated_upstream;
  13.177 -}
  13.178 -
  13.179  void plover_transaction_helper_set_upstream(PloverTransactionHelper *helper,
  13.180    PloverRepository *upstream)
  13.181  {
  13.182 @@ -541,14 +533,18 @@
  13.183  {
  13.184      const char *prefix;
  13.185      struct comps *comps;
  13.186 +    PloverTransactionHelperPrivate *priv;
  13.187      g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL);
  13.188      g_return_val_if_fail(helper->base != NULL || helper->installed != NULL,NULL);
  13.189 +    priv=PLOVER_TRANSACTION_HELPER_GET_PRIVATE(helper);
  13.190      if (helper->base)
  13.191      {
  13.192  	comps=plover_transaction_helper_get_comps(helper,error);
  13.193  	if (!comps)
  13.194  	    return NULL;
  13.195 -	return plover_default_prefix_for_vendor(comps->vendor);
  13.196 +	g_free(priv->default_prefix);
  13.197 +	priv->default_prefix=plover_default_prefix_for_vendor(comps->vendor);
  13.198 +	return priv->default_prefix;
  13.199      }
  13.200      prefix=plover_package_set_guess_prefix(helper->installed,error);
  13.201      return prefix;
  13.202 @@ -583,7 +579,7 @@
  13.203      int i;
  13.204      gchar *prefix=NULL,*s;
  13.205      struct comps *comps=NULL;
  13.206 -    GtkWidget *container,*page;
  13.207 +    GtkWidget *container,*summary,*page;
  13.208      GtkButton *button;
  13.209      GtkLabel *label;
  13.210      g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE);
  13.211 @@ -598,6 +594,7 @@
  13.212      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),FALSE);
  13.213      container=GTK_WIDGET(gtk_builder_get_object(helper->ui,
  13.214        "SIIncompatibleInstallation"));
  13.215 +    summary=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SISummaryOfWork"));
  13.216      page=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SIConfirm"));
  13.217      if (helper->check_vendor && prefix &&
  13.218        !plover_installed_files_match_prefix(prefix))
  13.219 @@ -615,15 +612,18 @@
  13.220  	gtk_button_set_label(button,s);
  13.221  	g_free(s);
  13.222  	gtk_widget_show(container);
  13.223 +	gtk_widget_hide(summary);
  13.224  	if (helper->assistant)
  13.225  	    gtk_assistant_set_page_complete(helper->assistant,page,FALSE);
  13.226      }
  13.227      else
  13.228      {
  13.229  	gtk_widget_hide(container);
  13.230 +	gtk_widget_show(summary);
  13.231  	if (helper->assistant)
  13.232  	    gtk_assistant_set_page_complete(helper->assistant,page,TRUE);
  13.233      }
  13.234 +    g_free(prefix);
  13.235      return TRUE;
  13.236  }
  13.237  
  13.238 @@ -653,22 +653,31 @@
  13.239      return helper->unsatisfied;
  13.240  }
  13.241  
  13.242 +#define PLOVER_TRANSACTION_HELPER_IS_VALID_REPORT_ACTION(action) \
  13.243 +  ((action)==PLOVER_TRANSACTION_HELPER_REPORT_INSTALL || \
  13.244 +  (action)==PLOVER_TRANSACTION_HELPER_REPORT_REMOVE || \
  13.245 +  (action)==PLOVER_TRANSACTION_HELPER_REPORT_UPDATE)
  13.246 +
  13.247  gboolean
  13.248    plover_transaction_helper_add_transaction(PloverTransactionHelper *helper,
  13.249    PloverTransaction *transaction,struct plover_vector *report_packages,
  13.250 -  enum razor_install_action report_action,GError **error)
  13.251 +  PloverTransactionHelperReportAction report_action,GError **error)
  13.252  {
  13.253      int i,count;
  13.254      gboolean other_packages;
  13.255      const char *s,*name;
  13.256      enum razor_install_action action;
  13.257      struct razor_install_iterator *ii;
  13.258 -    struct razor_set *next;
  13.259 +    struct razor_set *report_set;
  13.260      struct razor_package *package;
  13.261      struct plover_vector *tasked_packages;
  13.262 +    PloverTransactionHelperPrivate *priv;
  13.263 +    GtkWidget *w;
  13.264      g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE);
  13.265      g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),FALSE);
  13.266 -    g_return_val_if_fail(report_action==RAZOR_INSTALL_ACTION_ADD || report_action==RAZOR_INSTALL_ACTION_REMOVE,FALSE);
  13.267 +    g_return_val_if_fail(PLOVER_TRANSACTION_HELPER_IS_VALID_REPORT_ACTION(report_action),FALSE);
  13.268 +    g_return_val_if_fail(plover_transaction_get_system_set(transaction)!=NULL,FALSE);
  13.269 +    priv=PLOVER_TRANSACTION_HELPER_GET_PRIVATE(helper);
  13.270      g_free(helper->unsatisfied);
  13.271      helper->unsatisfied=NULL;
  13.272      if (!plover_transaction_resolve(transaction,error))
  13.273 @@ -680,17 +689,21 @@
  13.274      ii=plover_transaction_get_install_iterator(transaction,error);
  13.275      if (!ii)
  13.276  	return FALSE;
  13.277 -    next=plover_transaction_get_next_set(transaction,error);
  13.278 -    if (!next)
  13.279 +    if (report_action==PLOVER_TRANSACTION_HELPER_REPORT_REMOVE)
  13.280 +	report_set=plover_transaction_get_system_set(transaction);
  13.281 +    else
  13.282 +	report_set=plover_transaction_get_next_set(transaction,error);
  13.283 +    if (!report_set)
  13.284  	return FALSE;
  13.285      tasked_packages=plover_vector_new();
  13.286      other_packages=FALSE;
  13.287      while (razor_install_iterator_next(ii,&package,&action,&count))
  13.288      {
  13.289 -	if (action==report_action)
  13.290 +	if (action==report_action || action==RAZOR_INSTALL_ACTION_ADD &&
  13.291 +	  report_action==PLOVER_TRANSACTION_HELPER_REPORT_UPDATE)
  13.292  	{
  13.293 -	    razor_package_get_details(next,package,RAZOR_DETAIL_NAME,&name,
  13.294 -	      RAZOR_DETAIL_LAST);
  13.295 +	    razor_package_get_details(report_set,package,RAZOR_DETAIL_NAME,
  13.296 +	      &name,RAZOR_DETAIL_LAST);
  13.297  	    if (!report_packages ||
  13.298  	      plover_vector_contains(report_packages,name))
  13.299  		plover_vector_append(tasked_packages,name);
  13.300 @@ -710,8 +723,8 @@
  13.301  	{
  13.302  	    if (action==report_action)
  13.303  	    {
  13.304 -		razor_package_get_details(next,package,RAZOR_DETAIL_NAME,&name,
  13.305 -		  RAZOR_DETAIL_LAST);
  13.306 +		razor_package_get_details(report_set,package,RAZOR_DETAIL_NAME,
  13.307 +		  &name,RAZOR_DETAIL_LAST);
  13.308  		plover_vector_append(tasked_packages,name);
  13.309  	    }
  13.310  	}
  13.311 @@ -720,7 +733,8 @@
  13.312      {
  13.313  	g_set_error(error,PLOVER_GENERAL_ERROR,
  13.314  	  PLOVER_GENERAL_ERROR_NO_WORK,"Transaction includes no %s actions",
  13.315 -	  report_action==RAZOR_INSTALL_ACTION_ADD?"add":"remove");
  13.316 +	  report_action==PLOVER_TRANSACTION_HELPER_REPORT_REMOVE?
  13.317 +	  "remove":"add");
  13.318  	plover_vector_free(tasked_packages);
  13.319  	return FALSE;
  13.320      }
  13.321 @@ -728,8 +742,22 @@
  13.322  	plover_transaction_helper_check_vendor(helper,error);
  13.323      g_object_ref(transaction);
  13.324      helper->transactions=g_slist_append(helper->transactions,transaction);
  13.325 -    if (report_action==RAZOR_INSTALL_ACTION_ADD)
  13.326 +    if (report_action==PLOVER_TRANSACTION_HELPER_REPORT_REMOVE)
  13.327      {
  13.328 +	priv->transaction_type|=TRANSACTION_TYPE_REMOVE;
  13.329 +	for(i=0;i<tasked_packages->len;i++)
  13.330 +	{
  13.331 +	    s=tasked_packages->strings[i];
  13.332 +	    if (!plover_vector_contains(helper->report_removing,s))
  13.333 +		plover_vector_append(helper->report_removing,s);
  13.334 +	}
  13.335 +	helper->report_removing_dependants|=other_packages;
  13.336 +    }
  13.337 +    else
  13.338 +    {
  13.339 +	if (report_action==PLOVER_TRANSACTION_HELPER_REPORT_UPDATE)
  13.340 +	    priv->transaction_type|=TRANSACTION_TYPE_REMOVE;
  13.341 +	priv->transaction_type|=TRANSACTION_TYPE_INSTALL;
  13.342  	for(i=0;i<tasked_packages->len;i++)
  13.343  	{
  13.344  	    s=tasked_packages->strings[i];
  13.345 @@ -738,15 +766,31 @@
  13.346  	}
  13.347  	helper->report_adding_dependencies|=other_packages;
  13.348      }
  13.349 -    else
  13.350 +    w=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SIProgressLabel"));
  13.351 +    switch(priv->transaction_type)
  13.352      {
  13.353 -	for(i=0;i<tasked_packages->len;i++)
  13.354 -	{
  13.355 -	    s=tasked_packages->strings[i];
  13.356 -	    if (!plover_vector_contains(helper->report_removing,s))
  13.357 -		plover_vector_append(helper->report_removing,s);
  13.358 -	}
  13.359 -	helper->report_removing_dependants|=other_packages;
  13.360 +	case TRANSACTION_TYPE_INSTALL:
  13.361 +	    gtk_label_set_markup(GTK_LABEL(w),
  13.362 +	      "<b>Installing the Software</b>\n\n"
  13.363 +	      "Please wait while the Installation Assistant "
  13.364 +	      "installs the software.\n"
  13.365 +	      "This may take several minutes.");
  13.366 +	    break;
  13.367 +	case TRANSACTION_TYPE_REMOVE:
  13.368 +	    gtk_label_set_markup(GTK_LABEL(w),
  13.369 +	      "<b>Removing Packages</b>\n\n"
  13.370 +	      "Please wait while the Installation Assistant "
  13.371 +	      "removes packages.\n"
  13.372 +	      "This may take several minutes.");
  13.373 +	    break;
  13.374 +	default:
  13.375 +	case TRANSACTION_TYPE_UPDATE:
  13.376 +	    gtk_label_set_markup(GTK_LABEL(w),
  13.377 +	      "<b>Updating the Software</b>\n\n"
  13.378 +	      "Please wait while the Installation Assistant "
  13.379 +	      "updates the software.\n"
  13.380 +	      "This may take several minutes.");
  13.381 +	    break;
  13.382      }
  13.383      plover_vector_free(tasked_packages);
  13.384      return TRUE;
  13.385 @@ -761,6 +805,7 @@
  13.386      GError *tmp_error=NULL;
  13.387      PloverTransaction *transaction;
  13.388      g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL);
  13.389 +    g_return_val_if_fail(helper->installed != NULL,NULL);
  13.390      prefix=plover_transaction_helper_get_prefix(helper,&tmp_error);
  13.391      if (tmp_error)
  13.392      {
  13.393 @@ -814,7 +859,7 @@
  13.394  		continue;
  13.395  	    if (pkg->type==COMPS_REQUIREMENT_DEFAULT ||
  13.396  	      pkg->type==COMPS_REQUIREMENT_MANDATORY ||
  13.397 -	      pkg->type==COMPS_REQUIREMENT_CONDITIONAL &&
  13.398 +	      pkg->type==COMPS_REQUIREMENT_CONDITIONAL && pkg->requires &&
  13.399  	      plover_vector_contains(default_packages,pkg->requires))
  13.400  	    {
  13.401  		changed=TRUE;
  13.402 @@ -852,7 +897,7 @@
  13.403  	return FALSE;
  13.404      }
  13.405      retval=plover_transaction_helper_add_transaction(helper,transaction,
  13.406 -      packages,RAZOR_INSTALL_ACTION_ADD,error);
  13.407 +      packages,PLOVER_TRANSACTION_HELPER_REPORT_INSTALL,error);
  13.408      g_object_unref(transaction);
  13.409      return retval;
  13.410  }
  13.411 @@ -896,6 +941,7 @@
  13.412      struct plover_vector *selected_packages;
  13.413      PloverTransaction *transaction;
  13.414      g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE);
  13.415 +    g_return_val_if_fail(helper->installed != NULL,FALSE);
  13.416      selected_packages=plover_transaction_helper_group_get_default_packages(
  13.417        helper,group,error);
  13.418      if (!selected_packages)
  13.419 @@ -917,7 +963,7 @@
  13.420  	return FALSE;
  13.421      }
  13.422      retval=plover_transaction_helper_add_transaction(helper,transaction,
  13.423 -      NULL,RAZOR_INSTALL_ACTION_REMOVE,error);
  13.424 +      NULL,PLOVER_TRANSACTION_HELPER_REPORT_REMOVE,error);
  13.425      g_object_unref(transaction);
  13.426      plover_vector_free(selected_packages);
  13.427      return retval;
  13.428 @@ -942,7 +988,7 @@
  13.429  	return FALSE;
  13.430      }
  13.431      retval=plover_transaction_helper_add_transaction(helper,transaction,
  13.432 -      NULL,RAZOR_INSTALL_ACTION_ADD,error);
  13.433 +      NULL,PLOVER_TRANSACTION_HELPER_REPORT_UPDATE,error);
  13.434      g_object_unref(transaction);
  13.435      return retval;
  13.436  }
    14.1 --- a/plover-gtk/transactionhelper.h	Mon Apr 18 15:04:47 2016 +0100
    14.2 +++ b/plover-gtk/transactionhelper.h	Mon Jun 13 12:18:42 2016 +0100
    14.3 @@ -25,6 +25,12 @@
    14.4  					  PLOVER_TYPE_TRANSACTION_HELPER,\
    14.5  					  PloverTransactionHelperClass)
    14.6  
    14.7 +typedef enum {
    14.8 +    PLOVER_TRANSACTION_HELPER_REPORT_INSTALL=RAZOR_INSTALL_ACTION_ADD,
    14.9 +    PLOVER_TRANSACTION_HELPER_REPORT_REMOVE=RAZOR_INSTALL_ACTION_REMOVE,
   14.10 +    PLOVER_TRANSACTION_HELPER_REPORT_UPDATE
   14.11 +} PloverTransactionHelperReportAction;
   14.12 +
   14.13  typedef struct _PloverTransactionHelper {
   14.14      GObject parent_instance;
   14.15      PloverPackageSet *installed;
   14.16 @@ -77,7 +83,7 @@
   14.17  gboolean
   14.18    plover_transaction_helper_add_transaction(PloverTransactionHelper *helper,
   14.19    PloverTransaction *transaction,struct plover_vector *report_packages,
   14.20 -  enum razor_install_action report_action,GError **error);
   14.21 +  PloverTransactionHelperReportAction report_action,GError **error);
   14.22  struct plover_vector *plover_transaction_helper_group_get_default_packages(
   14.23    PloverTransactionHelper *helper,const char *group,GError **error);
   14.24  gboolean
    15.1 --- a/plover-open/plover-open.c	Mon Apr 18 15:04:47 2016 +0100
    15.2 +++ b/plover-open/plover-open.c	Mon Jun 13 12:18:42 2016 +0100
    15.3 @@ -165,8 +165,8 @@
    15.4      }
    15.5  #endif
    15.6      plover_exception_handler_init();
    15.7 -    razor_set_lua_loader("posix",luaopen_posix);
    15.8 -    razor_set_lua_loader("whelk",luaopen_whelk);
    15.9 +    razor_set_lua_loader("posix",(void (*)())luaopen_posix);
   15.10 +    razor_set_lua_loader("whelk",(void (*)())luaopen_whelk);
   15.11      if (!gtk_init_with_args(&argc,&argv,NULL,options,NULL,&err))
   15.12      {
   15.13  	g_printerr("%s\n",err->message);
    16.1 --- a/plover/Makefile.am	Mon Apr 18 15:04:47 2016 +0100
    16.2 +++ b/plover/Makefile.am	Mon Jun 13 12:18:42 2016 +0100
    16.3 @@ -1,8 +1,9 @@
    16.4 -AM_CFLAGS=-g $(LIBPLOVER_CFLAGS)
    16.5 -AM_CXXFLAGS=-g $(LIBPLOVER_CFLAGS)
    16.6 +AM_CFLAGS=-g $(LIBPLOVER_CFLAGS) $(CODE_COVERAGE_CFLAGS)
    16.7 +AM_CXXFLAGS=-g $(LIBPLOVER_CFLAGS) $(CODE_COVERAGE_CFLAGS)
    16.8  LIBS=$(LIBPLOVER_LIBS)
    16.9  INCLUDES=-I$(top_srcdir)
   16.10 -AM_LDFLAGS=-no-undefined -version-info $(LIBPLOVER_LT_VERSION_INFO)
   16.11 +AM_LDFLAGS=-no-undefined -version-info $(LIBPLOVER_LT_VERSION_INFO) \
   16.12 +  $(CODE_COVERAGE_LDFLAGS)
   16.13  
   16.14  pkginclude_HEADERS=plover.h transaction.h package.h packageset.h repository.h
   16.15  
    17.1 --- a/plover/comps.c	Mon Apr 18 15:04:47 2016 +0100
    17.2 +++ b/plover/comps.c	Mon Jun 13 12:18:42 2016 +0100
    17.3 @@ -57,7 +57,7 @@
    17.4      }
    17.5  }
    17.6  
    17.7 -struct comps_group *comps_group_new(void)
    17.8 +static struct comps_group *comps_group_new(void)
    17.9  {
   17.10      struct comps_group *group;
   17.11      group=calloc(sizeof(*group),1);
   17.12 @@ -78,6 +78,7 @@
   17.13  	free(group);
   17.14      }
   17.15  }
   17.16 +
   17.17  static void comps_group_free(struct comps_group *group)
   17.18  {
   17.19      struct comps_group *next;
    18.1 --- a/plover/log.c	Mon Apr 18 15:04:47 2016 +0100
    18.2 +++ b/plover/log.c	Mon Jun 13 12:18:42 2016 +0100
    18.3 @@ -169,7 +169,7 @@
    18.4  	    data->dir=opendir(s);
    18.5  	    free(s);
    18.6  	}
    18.7 -	data->base=strdup(path+1);
    18.8 +	data->base=strdup(base+1);
    18.9      }
   18.10      else
   18.11      {
   18.12 @@ -194,6 +194,7 @@
   18.13  	closedir(data->dir);
   18.14  	return FALSE;
   18.15      }
   18.16 +    data->suffix=NULL;
   18.17      if (find_suffixed_next(data))
   18.18  	return TRUE;
   18.19      free(data->entry);
   18.20 @@ -203,6 +204,7 @@
   18.21  
   18.22  static void find_suffixed_close(struct find_suffixed_data *data)
   18.23  {
   18.24 +    free(data->base);
   18.25      free(data->suffix);
   18.26      free(data->entry);
   18.27      closedir(data->dir);
   18.28 @@ -248,28 +250,33 @@
   18.29  
   18.30  static int rotate_logfile(const char *path,struct tm *modified)
   18.31  {
   18.32 +    gboolean okay_to_replace;
   18.33      gchar *s;
   18.34      char serial;
   18.35      char suffix[11];			/* -yyyymmdd or -yyyymmdds */
   18.36      sprintf(suffix,"-%04d%02d%02d",modified->tm_year+1900,modified->tm_mon+1,
   18.37        modified->tm_mday);
   18.38      s=g_strconcat(path,suffix,NULL);
   18.39 -    if (rename(path,s))
   18.40 +    if (g_file_test(s,G_FILE_TEST_EXISTS) || g_rename(path,s))
   18.41      {
   18.42  	suffix[10]='\0';
   18.43  	for(serial='a';serial<='z';serial++)
   18.44  	{
   18.45 -	    if (errno!=EACCES || serial=='z')
   18.46 +	    free(s);
   18.47 +	    suffix[9]=serial;
   18.48 +	    s=g_strconcat(path,suffix,NULL);
   18.49 +	    if (serial=='z')
   18.50 +		okay_to_replace=TRUE;
   18.51 +	    else
   18.52 +		okay_to_replace=!g_file_test(s,G_FILE_TEST_EXISTS);
   18.53 +	    if (okay_to_replace && !g_rename(path,s))
   18.54 +		break;
   18.55 +	    else if (serial=='z')
   18.56  	    {
   18.57 -		perror(s);
   18.58 +		fprintf(stderr,"%s%s: Failed to rotate logfile\n",path,suffix);
   18.59  		free(s);
   18.60  		return -1;
   18.61  	    }
   18.62 -	    free(s);
   18.63 -	    suffix[9]=serial;
   18.64 -	    s=g_strconcat(path,suffix,NULL);
   18.65 -	    if (!rename(path,s))
   18.66 -		break;
   18.67  	}
   18.68      }
   18.69      g_free(s);
   18.70 @@ -299,7 +306,10 @@
   18.71  	  razor_atomic_get_error_msg(atomic));
   18.72      razor_atomic_destroy(atomic);
   18.73      if (retval)
   18.74 +    {
   18.75 +	g_free(filename);
   18.76  	return retval;
   18.77 +    }
   18.78      if (stat(filename,&sb)<0)
   18.79      {
   18.80  	if (errno!=ENOENT)
    19.1 --- a/plover/package.c	Mon Apr 18 15:04:47 2016 +0100
    19.2 +++ b/plover/package.c	Mon Jun 13 12:18:42 2016 +0100
    19.3 @@ -28,7 +28,6 @@
    19.4  typedef struct _PloverPackagePrivate {
    19.5      struct razor_set *set;
    19.6      struct razor_package *pkg;
    19.7 -    GObject *file_store;
    19.8      const char **prefixes;
    19.9  } PloverPackagePrivate;
   19.10  
   19.11 @@ -47,17 +46,13 @@
   19.12  {
   19.13      PloverPackagePrivate *priv=PLOVER_PACKAGE_GET_PRIVATE(obj);
   19.14      g_free(priv->prefixes);
   19.15 +    razor_set_unref(priv->set);
   19.16      G_OBJECT_CLASS(plover_package_parent_class)->finalize(obj);
   19.17  }
   19.18  
   19.19  static void plover_package_dispose(GObject *obj)
   19.20  {
   19.21      PloverPackagePrivate *priv=PLOVER_PACKAGE_GET_PRIVATE(obj);
   19.22 -    if (priv->file_store)
   19.23 -    {
   19.24 -	g_object_unref(priv->file_store);
   19.25 -	priv->file_store=NULL;
   19.26 -    }
   19.27      G_OBJECT_CLASS(plover_package_parent_class)->dispose(obj);
   19.28  }
   19.29  
   19.30 @@ -83,7 +78,7 @@
   19.31      PloverPackagePrivate *priv;
   19.32      package=g_object_new(PLOVER_TYPE_PACKAGE,NULL);
   19.33      priv=PLOVER_PACKAGE_GET_PRIVATE(package);
   19.34 -    priv->set=set;
   19.35 +    priv->set=razor_set_ref(set);
   19.36      priv->pkg=pkg;
   19.37      return package;
   19.38  }
   19.39 @@ -241,6 +236,8 @@
   19.40      PloverPackagePrivate *priv;
   19.41      g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
   19.42      priv=PLOVER_PACKAGE_GET_PRIVATE(package);
   19.43 +    g_return_val_if_fail(priv->set!=NULL,NULL);
   19.44 +    g_return_val_if_fail(priv->pkg!=NULL,NULL);
   19.45      return razor_file_iterator_create(priv->set,priv->pkg,reverse);
   19.46  }
   19.47  
   19.48 @@ -265,10 +262,10 @@
   19.49  	prefixes=g_ptr_array_new();
   19.50  	si=razor_install_prefix_iterator_create(priv->set,priv->pkg);
   19.51  	while (razor_string_iterator_next(si,&prefix))
   19.52 -	    g_ptr_array_add(prefixes,prefix);
   19.53 +	    g_ptr_array_add(prefixes,(gpointer)prefix);
   19.54  	razor_string_iterator_destroy(si);
   19.55  	g_ptr_array_add(prefixes,NULL);
   19.56 -	priv->prefixes=g_ptr_array_free(prefixes,FALSE);
   19.57 +	priv->prefixes=(const char **)g_ptr_array_free(prefixes,FALSE);
   19.58      }
   19.59      return priv->prefixes;
   19.60  }
    20.1 --- a/plover/packageset.c	Mon Apr 18 15:04:47 2016 +0100
    20.2 +++ b/plover/packageset.c	Mon Jun 13 12:18:42 2016 +0100
    20.3 @@ -55,12 +55,19 @@
    20.4  {
    20.5      PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(obj);
    20.6      g_free(priv->guessed_prefix);
    20.7 +    g_free(priv->install_root);
    20.8      G_OBJECT_CLASS(plover_package_set_parent_class)->finalize(obj);
    20.9  }
   20.10  
   20.11  static void plover_package_set_dispose(GObject *obj)
   20.12  {
   20.13      PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(obj);
   20.14 +    if (priv->packages)
   20.15 +    {
   20.16 +	g_slist_foreach(priv->packages,(GFunc)g_object_unref,NULL);
   20.17 +	g_slist_free(priv->packages);
   20.18 +	priv->packages=NULL;
   20.19 +    }
   20.20      if (priv->set)
   20.21      {
   20.22  	razor_set_unref(priv->set);
    21.1 --- a/plover/transaction.c	Mon Apr 18 15:04:47 2016 +0100
    21.2 +++ b/plover/transaction.c	Mon Jun 13 12:18:42 2016 +0100
    21.3 @@ -1,5 +1,5 @@
    21.4  /*
    21.5 - * Copyright (C) 2009, 2011, 2012, 2014  J. Ali Harlow <ali@juiblex.co.uk>
    21.6 + * Copyright (C) 2009, 2011, 2012, 2014, 2016  J. Ali Harlow <ali@juiblex.co.uk>
    21.7   *
    21.8   * This program is free software; you can redistribute it and/or modify
    21.9   * it under the terms of the GNU General Public License as published by
   21.10 @@ -32,10 +32,23 @@
   21.11      N_SIGNALS
   21.12  };
   21.13  
   21.14 +typedef struct _PloverTransactionPrivate {
   21.15 +    GMutex mutex;
   21.16 +    gchar *status;
   21.17 +} PloverTransactionPrivate;
   21.18 +
   21.19 +#define PLOVER_TRANSACTION_GET_PRIVATE(obj)\
   21.20 +				G_TYPE_INSTANCE_GET_PRIVATE(obj,\
   21.21 +				  PLOVER_TYPE_TRANSACTION,\
   21.22 +				  PloverTransactionPrivate)
   21.23 +
   21.24  static guint signals[N_SIGNALS];
   21.25  
   21.26  static void plover_transaction_finalize(PloverTransaction *transaction)
   21.27  {
   21.28 +    PloverTransactionPrivate *priv=PLOVER_TRANSACTION_GET_PRIVATE(transaction);
   21.29 +    g_free(priv->status);
   21.30 +    g_mutex_clear(&priv->mutex);
   21.31      g_free(transaction->base);
   21.32      g_free(transaction->prefix);
   21.33      g_free(transaction->unsatisfied);
   21.34 @@ -66,10 +79,13 @@
   21.35      signals[STATUS_CHANGED]=g_signal_new("status-changed",
   21.36        G_TYPE_FROM_CLASS(klass),G_SIGNAL_RUN_LAST,0,NULL,NULL,
   21.37        g_cclosure_marshal_VOID__STRING,G_TYPE_NONE,1,G_TYPE_STRING);
   21.38 +    g_type_class_add_private(klass,sizeof(PloverTransactionPrivate));
   21.39  }
   21.40  
   21.41  static void plover_transaction_init(PloverTransaction *transaction)
   21.42  {
   21.43 +    PloverTransactionPrivate *priv=PLOVER_TRANSACTION_GET_PRIVATE(transaction);
   21.44 +    g_mutex_init(&priv->mutex);
   21.45  }
   21.46  
   21.47  gboolean plover_transaction_resolve(PloverTransaction *transaction,
   21.48 @@ -167,28 +183,73 @@
   21.49      return transaction->install_iterator;
   21.50  }
   21.51  
   21.52 +static gboolean
   21.53 +  plover_transaction_emit_status_changed(PloverTransaction *transaction)
   21.54 +{
   21.55 +    gchar *status;
   21.56 +    PloverTransactionPrivate *priv=PLOVER_TRANSACTION_GET_PRIVATE(transaction);
   21.57 +    g_mutex_lock(&priv->mutex);
   21.58 +    status=g_strdup(priv->status);
   21.59 +    g_mutex_unlock(&priv->mutex);
   21.60 +    g_signal_emit(transaction,signals[STATUS_CHANGED],0,status);
   21.61 +    g_free(status);
   21.62 +    return FALSE;	/* No more calls */
   21.63 +}
   21.64 +
   21.65 +static void plover_transaction_set_status(PloverTransaction *transaction,
   21.66 +  gboolean via_g_idle,const char *status)
   21.67 +{
   21.68 +    PloverTransactionPrivate *priv=PLOVER_TRANSACTION_GET_PRIVATE(transaction);
   21.69 +    g_mutex_lock(&priv->mutex);
   21.70 +    g_free(priv->status);
   21.71 +    priv->status=g_strdup(status);
   21.72 +    g_mutex_unlock(&priv->mutex);
   21.73 +    if (via_g_idle)
   21.74 +	g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
   21.75 +	  (GSourceFunc)plover_transaction_emit_status_changed,
   21.76 +	  g_object_ref(transaction),g_object_unref);
   21.77 +    else
   21.78 +	plover_transaction_emit_status_changed(transaction);
   21.79 +}
   21.80 +
   21.81  gboolean plover_transaction_commit(PloverTransaction *transaction,
   21.82    GCancellable *cancellable,GError **error)
   21.83  {
   21.84 -    int r;
   21.85 +    int r,count;
   21.86 +    unsigned files_action;
   21.87      gboolean retval;
   21.88      size_t pos;
   21.89      struct razor_set *set;
   21.90 +    struct razor_package *pkg;
   21.91 +    enum razor_install_action action;
   21.92      struct razor_install_iterator *ii;
   21.93      struct razor_atomic *atomic;
   21.94      PloverPackageSet *next;
   21.95 +    gboolean via_g_idle;
   21.96      g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),FALSE);
   21.97      if (g_cancellable_set_error_if_cancelled(cancellable,error))
   21.98  	return FALSE;
   21.99      ii=plover_transaction_get_install_iterator(transaction,error);
  21.100      if (!ii)
  21.101  	return FALSE;
  21.102 +    /*
  21.103 +     * If we are called from the default thread it is most useful to
  21.104 +     * emit signals directly however this is not safe when running in
  21.105 +     * a non-default thread and we want to use g_idle to emit signals
  21.106 +     * in the default thread instead.
  21.107 +     *
  21.108 +     * Note that the documentation for g_main_context_get_thread_default()
  21.109 +     * explicitly states that it may return a non-NULL value even when
  21.110 +     * called from the default thread. This would cause us to use g_idle
  21.111 +     * when not strictly necessary, but will still be safe.
  21.112 +     */
  21.113 +    via_g_idle=!!g_main_context_get_thread_default();
  21.114      do
  21.115      {
  21.116  	if (g_cancellable_set_error_if_cancelled(cancellable,error))
  21.117  	    return FALSE;
  21.118  	pos=razor_install_iterator_tell(ii);
  21.119 -	g_signal_emit(transaction,signals[STATUS_CHANGED],0,
  21.120 +	plover_transaction_set_status(transaction,via_g_idle,
  21.121  	  "Running pre-transaction scripts");
  21.122  	atomic=razor_atomic_open("package transaction");
  21.123  	next=plover_package_set_new_from_razor(transaction->next);
  21.124 @@ -198,7 +259,7 @@
  21.125  	  transaction->relocations,RAZOR_STAGE_SCRIPTS_PRE,cancellable);
  21.126  	if (r<0)
  21.127  	{
  21.128 -	    g_signal_emit(transaction,signals[STATUS_CHANGED],0,
  21.129 +	    plover_transaction_set_status(transaction,via_g_idle,
  21.130  	      "Failed in pre-transaction scripts");
  21.131  	    plover_propagate_razor_error_dup(error,
  21.132  	      razor_atomic_get_error(atomic));
  21.133 @@ -208,8 +269,17 @@
  21.134  	}
  21.135  	else
  21.136  	{
  21.137 -	    g_signal_emit(transaction,signals[STATUS_CHANGED],0,
  21.138 -	      "Unpacking files");
  21.139 +	    razor_install_iterator_seek(ii,pos);
  21.140 +	    files_action=0;
  21.141 +	    while (razor_install_iterator_next(ii,&pkg,&action,&count))
  21.142 +		if (action==RAZOR_INSTALL_ACTION_REMOVE)
  21.143 +		    files_action|=1;
  21.144 +		else if (action==RAZOR_INSTALL_ACTION_ADD)
  21.145 +		    files_action|=2;
  21.146 +		else
  21.147 +		    break;
  21.148 +	    plover_transaction_set_status(transaction,via_g_idle,
  21.149 +	      files_action==1?"Removing files":"Unpacking files");
  21.150  	    razor_install_iterator_seek(ii,pos);
  21.151  	    r=plover_run_transaction(transaction->trans,ii,
  21.152  	      plover_package_set_get_install_root(transaction->installed),
  21.153 @@ -232,14 +302,14 @@
  21.154  	    retval=!razor_atomic_commit(atomic);
  21.155  	    if (!retval)
  21.156  	    {
  21.157 -		g_signal_emit(transaction,signals[STATUS_CHANGED],0,
  21.158 +		plover_transaction_set_status(transaction,via_g_idle,
  21.159  		  "Failed to unpack all files correctly");
  21.160  		plover_propagate_razor_error_dup(error,
  21.161  		  razor_atomic_get_error(atomic));
  21.162  	    }
  21.163  	    else
  21.164  	    {
  21.165 -		g_signal_emit(transaction,signals[STATUS_CHANGED],0,
  21.166 +		plover_transaction_set_status(transaction,via_g_idle,
  21.167  		  "Running post-transaction scripts");
  21.168  		razor_install_iterator_seek(ii,pos);
  21.169  		plover_run_transaction(transaction->trans,ii,
  21.170 @@ -252,7 +322,7 @@
  21.171  	razor_atomic_destroy(atomic);
  21.172  	g_object_unref(next);
  21.173      } while(retval && r==1);
  21.174 -    g_signal_emit(transaction,signals[STATUS_CHANGED],0,"Completed");
  21.175 +    plover_transaction_set_status(transaction,via_g_idle,"Completed");
  21.176      return retval;
  21.177  }
  21.178  
  21.179 @@ -261,11 +331,17 @@
  21.180  {
  21.181      PloverTransaction *transaction=source_object;
  21.182      GError *error=NULL;
  21.183 -    if (!plover_transaction_commit(transaction,cancellable,&error))
  21.184 +    GMainContext *context;
  21.185 +    gboolean retval;
  21.186 +    context=g_main_context_new();
  21.187 +    g_main_context_push_thread_default(context);
  21.188 +    retval=plover_transaction_commit(transaction,cancellable,&error);
  21.189 +    g_main_context_pop_thread_default(context);
  21.190 +    g_main_context_unref(context);
  21.191 +    if (!retval)
  21.192  	g_task_return_error(task,error);
  21.193      else
  21.194  	g_task_return_boolean(task,TRUE);
  21.195 -    g_object_unref(task);
  21.196  }
  21.197  
  21.198  void plover_transaction_commit_async(PloverTransaction *transaction,
  21.199 @@ -275,6 +351,7 @@
  21.200      g_return_if_fail(PLOVER_IS_TRANSACTION(transaction));
  21.201      task=g_task_new(transaction,cancellable,callback,user_data);
  21.202      g_task_run_in_thread(task,plover_transaction_commit_async_thread);
  21.203 +    g_object_unref(task);
  21.204  }
  21.205  
  21.206  gboolean plover_transaction_commit_finish(PloverTransaction *transaction,
  21.207 @@ -337,6 +414,11 @@
  21.208  {
  21.209      g_return_if_fail(PLOVER_IS_TRANSACTION(transaction));
  21.210      g_return_if_fail(PLOVER_IS_PACKAGE_SET(installed));
  21.211 +    if (transaction->system)
  21.212 +    {
  21.213 +	razor_set_unref(transaction->system);
  21.214 +	transaction->system=NULL;
  21.215 +    }
  21.216      if (transaction->installed)
  21.217  	g_object_unref(transaction->installed);
  21.218      transaction->installed=g_object_ref(installed);
  21.219 @@ -360,9 +442,7 @@
  21.220  	g_object_unref(installed);
  21.221  	return FALSE;
  21.222      }
  21.223 -    if (transaction->installed)
  21.224 -	g_object_unref(transaction->installed);
  21.225 -    transaction->installed=installed;
  21.226 +    plover_transaction_set_installed(transaction,installed);
  21.227      return TRUE;
  21.228  }
  21.229  
  21.230 @@ -417,6 +497,7 @@
  21.231      system=plover_transaction_get_system_set(transaction);
  21.232      if (!system)
  21.233      {
  21.234 +	/* Impossible */
  21.235  	g_set_error(error,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_FAILED,
  21.236  	  "Internal error: No system set");
  21.237  	return FALSE;
  21.238 @@ -451,6 +532,7 @@
  21.239      system=plover_transaction_get_system_set(transaction);
  21.240      if (!system)
  21.241      {
  21.242 +	/* Impossible */
  21.243  	g_set_error(error,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_FAILED,
  21.244  	  "Internal error: No system set");
  21.245  	return FALSE;
  21.246 @@ -546,6 +628,7 @@
  21.247      system=plover_transaction_get_system_set(transaction);
  21.248      if (!system)
  21.249      {
  21.250 +	/* Impossible */
  21.251  	g_set_error(error,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_FAILED,
  21.252  	  "Internal error: No system set");
  21.253  	return FALSE;
  21.254 @@ -583,36 +666,44 @@
  21.255      return transaction;
  21.256  }
  21.257  
  21.258 -static GList *plover_what_requires(struct razor_set *set,const char *ref_name)
  21.259 +static GList *plover_what_has_property(struct razor_set *set,uint32_t prop_type,
  21.260 +  const char *ref_name)
  21.261  {
  21.262      const char *name,*version;
  21.263      uint32_t flags;
  21.264      GList *list=NULL;
  21.265      struct razor_property *property;
  21.266      struct razor_package *package;
  21.267 -    struct razor_package_iterator *what_requires;
  21.268 +    struct razor_package_iterator *what_has;
  21.269      struct razor_property_iterator *all_props;
  21.270      all_props=razor_property_iterator_create(set,NULL);
  21.271      while (razor_property_iterator_next(all_props,&property,&name,&flags,
  21.272        &version))
  21.273      {
  21.274 -	if ((flags&RAZOR_PROPERTY_TYPE_MASK)!=RAZOR_PROPERTY_REQUIRES)
  21.275 +	if ((flags&RAZOR_PROPERTY_TYPE_MASK)!=prop_type)
  21.276  	    continue;
  21.277  	if (strcmp(name,ref_name))
  21.278  	    continue;
  21.279 -	what_requires=razor_package_iterator_create_for_property(set,property);
  21.280 -	while(razor_package_iterator_next(what_requires,&package,
  21.281 +	what_has=razor_package_iterator_create_for_property(set,property);
  21.282 +	while(razor_package_iterator_next(what_has,&package,
  21.283  	  RAZOR_DETAIL_LAST))
  21.284  	    list=g_list_prepend(list,package);
  21.285 -	razor_package_iterator_destroy(what_requires);
  21.286 +	razor_package_iterator_destroy(what_has);
  21.287      }
  21.288      razor_property_iterator_destroy(all_props);
  21.289      return list;
  21.290  }
  21.291  
  21.292 -/* 
  21.293 - * Warning: This code is untested and probably wrong.
  21.294 - */
  21.295 +static GList *plover_what_provides(struct razor_set *set,const char *ref_name)
  21.296 +{
  21.297 +    return plover_what_has_property(set,RAZOR_PROPERTY_PROVIDES,ref_name);
  21.298 +}
  21.299 +
  21.300 +static GList *plover_what_requires(struct razor_set *set,const char *ref_name)
  21.301 +{
  21.302 +    return plover_what_has_property(set,RAZOR_PROPERTY_REQUIRES,ref_name);
  21.303 +}
  21.304 +
  21.305  PloverTransaction *plover_transaction_new_remove_with_leaves(char **pkgs,
  21.306    GError **error)
  21.307  {
  21.308 @@ -624,6 +715,13 @@
  21.309      struct razor_transaction *trans;
  21.310      PloverPackageSet *installed;
  21.311      PloverTransaction *transaction;
  21.312 +    struct plover_vector *package_names;
  21.313 +    GList *to_remove,*lnk,*lnk2,*what_requires,*what_provides;
  21.314 +    struct razor_package *package,*maybe_unused_package;
  21.315 +    struct razor_property *property;
  21.316 +    struct razor_package_query *query;
  21.317 +    struct razor_package_iterator *all_packages,*removed;
  21.318 +    struct razor_property_iterator *removed_props;
  21.319      if (!pkgs)
  21.320  	return plover_transaction_new_remove(NULL,error);
  21.321      installed=plover_package_set_new();
  21.322 @@ -636,13 +734,6 @@
  21.323  	return NULL;
  21.324      }
  21.325      system=plover_package_set_get_razor(installed);
  21.326 -    struct plover_vector *package_names;
  21.327 -    GList *to_remove,*lnk,*what_requires;
  21.328 -    struct razor_package *package,*maybe_unused_package;
  21.329 -    struct razor_property *property;
  21.330 -    struct razor_package_query *query;
  21.331 -    struct razor_package_iterator *all_packages,*removed,*maybe_unused;
  21.332 -    struct razor_property_iterator *removed_props;
  21.333      package_names=plover_vector_new();
  21.334      for(i=0;pkgs[i];i++)
  21.335  	plover_vector_append(package_names,pkgs[i]);
  21.336 @@ -679,15 +770,15 @@
  21.337  	    {
  21.338  		if ((flags&RAZOR_PROPERTY_TYPE_MASK)!=RAZOR_PROPERTY_REQUIRES)
  21.339  		    continue;
  21.340 -		maybe_unused=razor_package_iterator_create_for_property(system,
  21.341 -		  property);
  21.342 -		while(razor_package_iterator_next(maybe_unused,
  21.343 -		  &maybe_unused_package,RAZOR_DETAIL_NAME,&maybe_unused_name,
  21.344 -		  RAZOR_DETAIL_LAST))
  21.345 +		what_provides=plover_what_provides(system,name);
  21.346 +		for(lnk2=what_provides;lnk2;lnk2=lnk2->next)
  21.347  		{
  21.348 +		    maybe_unused_package=lnk2->data;
  21.349  		    if (g_list_find(to_remove,maybe_unused_package))
  21.350  			continue;
  21.351  		    is_leaf=TRUE;
  21.352 +		    razor_package_get_details(system,maybe_unused_package,
  21.353 +		      RAZOR_DETAIL_NAME,&maybe_unused_name,RAZOR_DETAIL_LAST);
  21.354  		    what_requires=plover_what_requires(system,
  21.355  		      maybe_unused_name);
  21.356  		    for(lnk=what_requires;lnk;lnk=lnk->next)
  21.357 @@ -704,7 +795,6 @@
  21.358  			changed=TRUE;
  21.359  		    }
  21.360  		}
  21.361 -		razor_package_iterator_destroy(maybe_unused);
  21.362  	    }
  21.363  	    razor_property_iterator_destroy(removed_props);
  21.364  	}
    22.1 --- a/plover/transaction.h	Mon Apr 18 15:04:47 2016 +0100
    22.2 +++ b/plover/transaction.h	Mon Jun 13 12:18:42 2016 +0100
    22.3 @@ -40,10 +40,6 @@
    22.4  } PloverTransactionClass;
    22.5  
    22.6  GType plover_transaction_get_type(void) G_GNUC_CONST;
    22.7 -void plover_transaction_commit_async(PloverTransaction *transaction,
    22.8 -  GCancellable *cancellable,GAsyncReadyCallback callback,gpointer user_data);
    22.9 -gboolean plover_transaction_commit_finish(PloverTransaction *transaction,
   22.10 -  GAsyncResult *result,GError **error);
   22.11  PloverTransaction *plover_transaction_new();
   22.12  void plover_transaction_set_prefix(PloverTransaction *transaction,
   22.13    const char *prefix);
   22.14 @@ -52,7 +48,7 @@
   22.15  gboolean plover_transaction_root_open(PloverTransaction *transaction,
   22.16    const char *install_root,GError **error);
   22.17  struct razor_set *plover_transaction_import_yum(PloverTransaction *transaction,
   22.18 -  const char *base,GError **error);
   22.19 +  const char *base,GError **error) G_GNUC_DEPRECATED;
   22.20  gboolean plover_transaction_set_upstream(PloverTransaction *transaction,
   22.21    PloverRepository *upstream,GError **error);
   22.22  gboolean
   22.23 @@ -70,6 +66,8 @@
   22.24    char **pkgs,GError **error);
   22.25  PloverTransaction *plover_transaction_new_remove(char **pkgs,
   22.26    GError **error);
   22.27 +PloverTransaction *plover_transaction_new_remove_with_leaves(char **pkgs,
   22.28 +  GError **error);
   22.29  gboolean plover_transaction_resolve(PloverTransaction *transaction,
   22.30    GError **error);
   22.31  const char *plover_transaction_get_unsatisfied(PloverTransaction *transaction);
   22.32 @@ -83,5 +81,7 @@
   22.33    GCancellable *cancellable,GError **error);
   22.34  void plover_transaction_commit_async(PloverTransaction *transaction,
   22.35    GCancellable *cancellable,GAsyncReadyCallback callback,gpointer user_data);
   22.36 +gboolean plover_transaction_commit_finish(PloverTransaction *transaction,
   22.37 +  GAsyncResult *result,GError **error);
   22.38  
   22.39  #endif /* __PLOVER_TRANSACTION_H__ */
    23.1 --- a/plover/util.c	Mon Apr 18 15:04:47 2016 +0100
    23.2 +++ b/plover/util.c	Mon Jun 13 12:18:42 2016 +0100
    23.3 @@ -57,7 +57,12 @@
    23.4      }
    23.5      return g_strconcat(program_files,"\\",vendor?vendor:"Plover",NULL);
    23.6  #else
    23.7 -    return NULL;
    23.8 +    const char *vendor_prefix;
    23.9 +    vendor_prefix=g_getenv("PLOVER_VENDOR_PREFIX");
   23.10 +    if (!vendor_prefix)
   23.11 +	return NULL;
   23.12 +    else
   23.13 +	return g_build_filename(vendor_prefix,vendor?vendor:"Plover",NULL);
   23.14  #endif
   23.15  }
   23.16  
    24.1 --- a/pre-inst/pre-inst.c	Mon Apr 18 15:04:47 2016 +0100
    24.2 +++ b/pre-inst/pre-inst.c	Mon Jun 13 12:18:42 2016 +0100
    24.3 @@ -141,8 +141,8 @@
    24.4      void *retval;
    24.5  #endif
    24.6      char *path;
    24.7 -    razor_set_lua_loader("posix",luaopen_posix);
    24.8 -    razor_set_lua_loader("whelk",luaopen_whelk);
    24.9 +    razor_set_lua_loader("posix",(void (*)())luaopen_posix);
   24.10 +    razor_set_lua_loader("whelk",(void (*)())luaopen_whelk);
   24.11      path=plover_get_program_directory(argv0);
   24.12  #ifdef WIN32
   24.13      retval=(HANDLE)_beginthreadex(NULL,0,pre_install_thread,path,0,NULL);
   24.14 @@ -194,8 +194,8 @@
   24.15      gboolean success;
   24.16      gchar *s;
   24.17      GError *error=NULL;
   24.18 -    razor_set_lua_loader("posix",luaopen_posix);
   24.19 -    razor_set_lua_loader("whelk",luaopen_whelk);
   24.20 +    razor_set_lua_loader("posix",(void (*)())luaopen_posix);
   24.21 +    razor_set_lua_loader("whelk",(void (*)())luaopen_whelk);
   24.22      prefix=plover_pre_install_prefix();
   24.23      s=g_strconcat(prefix,"/var/lib/razor",NULL);
   24.24      razor_set_database_path(s);
    25.1 --- a/setup/setup.c	Mon Apr 18 15:04:47 2016 +0100
    25.2 +++ b/setup/setup.c	Mon Jun 13 12:18:42 2016 +0100
    25.3 @@ -113,8 +113,8 @@
    25.4  {
    25.5      GError *error=NULL;
    25.6      plover_exception_handler_init();
    25.7 -    razor_set_lua_loader("posix",luaopen_posix);
    25.8 -    razor_set_lua_loader("whelk",luaopen_whelk);
    25.9 +    razor_set_lua_loader("posix",(void (*)())luaopen_posix);
   25.10 +    razor_set_lua_loader("whelk",(void (*)())luaopen_whelk);
   25.11      if (argc>1 && !strcmp(argv[1],"-u"))
   25.12      {
   25.13  	if (!plover_remove(NULL,&error))
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/tests/Makefile.am	Mon Jun 13 12:18:42 2016 +0100
    26.3 @@ -0,0 +1,77 @@
    26.4 +SUBDIRS = . plover plover-gtk
    26.5 +
    26.6 +EXTRA_DIST = zsh.spec zsh2.spec zip.spec zap.spec filesystem.spec zappy.spec \
    26.7 +    zappy2.spec unsatisfiable.spec uninstallable.spec badpostun.spec comps.xml \
    26.8 +    glib.supp.in README xvfb-run
    26.9 +
   26.10 +if HAVE_CHECK_TOOLS
   26.11 +
   26.12 +noinst_DATA = glib.supp yum-repo-test-dir/repodata/primary.xml.gz \
   26.13 +	primary.xml.gz razor-test-dir/var/lib/razor/system.rzdb
   26.14 +
   26.15 +if HAVE_VALGRIND_3_9
   26.16 +%.supp: %.supp.in
   26.17 +	cat $< > $@
   26.18 +else
   26.19 +%.supp: %.supp.in
   26.20 +	grep -v '^ *match-leak-kinds: ' $< > $@
   26.21 +endif
   26.22 +
   26.23 +yum-repo-test-dir/repodata/primary.xml.gz: zsh.spec zsh2.spec zip.spec \
   26.24 +    zap.spec filesystem.spec zappy.spec zappy2.spec unsatisfiable.spec \
   26.25 +    uninstallable.spec badpostun.spec Makefile
   26.26 +	rm -rf rpmbuild yum-repo-test-dir
   26.27 +	mkdir -p rpmbuild/BUILD rpmbuild/RPMS
   26.28 +	$(RPMBUILD) --define "_topdir `pwd`/rpmbuild" -bb $(srcdir)/zap.spec
   26.29 +	$(RPMBUILD) --define "_topdir `pwd`/rpmbuild" --define "_version 1" \
   26.30 +	  -bb $(srcdir)/zip.spec
   26.31 +	$(RPMBUILD) --define "_topdir `pwd`/rpmbuild" -bb $(srcdir)/zsh.spec
   26.32 +	$(RPMBUILD) --define "_topdir `pwd`/rpmbuild" -bb $(srcdir)/zsh2.spec
   26.33 +	$(RPMBUILD) --define "_topdir `pwd`/rpmbuild" -bb \
   26.34 +	  $(srcdir)/filesystem.spec
   26.35 +	$(RPMBUILD) --define "_topdir `pwd`/rpmbuild" -bb $(srcdir)/zappy.spec
   26.36 +	$(RPMBUILD) --define "_topdir `pwd`/rpmbuild" -bb $(srcdir)/zappy2.spec
   26.37 +	$(RPMBUILD) --define "_topdir `pwd`/rpmbuild" -bb \
   26.38 +	  $(srcdir)/unsatisfiable.spec
   26.39 +	$(RPMBUILD) --define "_topdir `pwd`/rpmbuild" -bb \
   26.40 +	  $(srcdir)/uninstallable.spec
   26.41 +	$(RPMBUILD) --define "_topdir `pwd`/rpmbuild" -bb \
   26.42 +	  $(srcdir)/badpostun.spec
   26.43 +	mkdir -p yum-repo-test-dir/rpms
   26.44 +	mv rpmbuild/RPMS/noarch/*.rpm yum-repo-test-dir/rpms
   26.45 +	rm -rf rpmbuild
   26.46 +	cp $(srcdir)/comps.xml yum-repo-test-dir/rpms
   26.47 +	$(CREATEREPO) --simple-md-filenames -g comps.xml -o yum-repo-test-dir \
   26.48 +	  yum-repo-test-dir/rpms
   26.49 +	$(RM) yum-repo-test-dir/rpms/comps.xml
   26.50 +	cp $(srcdir)/comps.xml yum-repo-test-dir/repodata
   26.51 +
   26.52 +primary.xml.gz: yum-repo-test-dir/repodata/primary.xml.gz
   26.53 +	cp yum-repo-test-dir/repodata/primary.xml.gz \
   26.54 +	  yum-repo-test-dir/repodata/filelists.xml.gz .
   26.55 +	rm -rf rpms
   26.56 +	ln -s yum-repo-test-dir/rpms .
   26.57 +
   26.58 +razor-test-dir/var/lib/razor/system.rzdb: primary.xml.gz
   26.59 +	$(RM) -r razor-test-dir
   26.60 +	$(RAZOR) --root=razor-test-dir init
   26.61 +	$(RAZOR) --root=razor-test-dir \
   26.62 +	  --url=file://localhost/`pwd`/yum-repo-test-dir import-yum
   26.63 +	$(RAZOR) --root=razor-test-dir install zap zappy zappy2 zappy-tools
   26.64 +
   26.65 +endif
   26.66 +
   26.67 +check-valgrind:
   26.68 +	$(RM) test-suite-*.log
   26.69 +	-(cd plover && $(MAKE) $(AM_MAKEFLAGS) check-valgrind)
   26.70 +	-(cd plover-gtk && $(MAKE) $(AM_MAKEFLAGS) check-valgrind)
   26.71 +	@for infile in plover/test-suite-*.log plover-gtk/test-suite-*.log; do \
   26.72 +	    outfile=`echo $$infile | sed -e 's:.*/::'`; \
   26.73 +	    cat $$infile >> $$outfile; \
   26.74 +	done
   26.75 +
   26.76 +clean-local:
   26.77 +	rm -rf yum-repo-test-dir razor-test-dir
   26.78 +	rm -f primary.xml.gz filelists.xml.gz rpms rawhide.rzdb
   26.79 +
   26.80 +CLEANFILES = glib.supp
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/tests/README	Mon Jun 13 12:18:42 2016 +0100
    27.3 @@ -0,0 +1,19 @@
    27.4 +There are a number of good sources for valgrind suppression files:
    27.5 +
    27.6 +1) The cockpit project: http://cockpit-project.org
    27.7 +	Suppression files are in the tools directory:
    27.8 +	https://github.com/cockpit-project/cockpit/tree/master/tools
    27.9 +
   27.10 +2) Johan Dahlin's file for the Gtk stack:
   27.11 +	https://people.gnome.org/~johan/gtk.suppression
   27.12 +
   27.13 +3) Daniel Trebbien's GNOME.supp project:
   27.14 +	https://github.com/dtrebbien/GNOME.supp
   27.15 +
   27.16 +At the time of testing, the cockpit project produced far better results
   27.17 +against glib version 2.36.3 and so that is what is included.
   27.18 +
   27.19 +
   27.20 +xvfb-run comes from Debian:
   27.21 +
   27.22 +https://anonscm.debian.org/cgit/pkg-xorg/xserver/xorg-server.git/tree/debian/local/xvfb-run
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/tests/badpostun.spec	Mon Jun 13 12:18:42 2016 +0100
    28.3 @@ -0,0 +1,33 @@
    28.4 +%define _source_payload w9.gzdio
    28.5 +%define _binary_payload w9.gzdio
    28.6 +
    28.7 +Name:      badpostun
    28.8 +Summary:   A package that fails in its postun script
    28.9 +Group:     Test
   28.10 +License:   GPL
   28.11 +URL:       http://www.juiblex.co.uk/beach
   28.12 +Version:   1
   28.13 +Release:   1
   28.14 +Source:    badpostun.tar
   28.15 +BuildArch: noarch
   28.16 +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   28.17 +Prefix:    /usr
   28.18 +
   28.19 +%description
   28.20 +A package that fails in its postun script, triggering a warning on removal.
   28.21 +
   28.22 +%prep
   28.23 +
   28.24 +%build
   28.25 +
   28.26 +%install
   28.27 +mkdir -p $RPM_BUILD_ROOT/usr/bin
   28.28 +echo %{name}-%{version}-%{release} > $RPM_BUILD_ROOT/usr/bin/badpostun
   28.29 +
   28.30 +%clean
   28.31 +
   28.32 +%postun -p <lua>
   28.33 +error("Failed after uninstall")
   28.34 +
   28.35 +%files
   28.36 +/usr/bin/badpostun
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/tests/comps.xml	Mon Jun 13 12:18:42 2016 +0100
    29.3 @@ -0,0 +1,34 @@
    29.4 +<?xml version="1.0" encoding="UTF-8"?>
    29.5 +<!DOCTYPE comps PUBLIC "-//Red Hat, Inc.//DTD Comps info//EN" "comps.dtd">
    29.6 +<comps xmlns:plover="http://project.juiblex.co.uk/plover/ns/2009"
    29.7 +  plover:vendor="Acme Corporation">
    29.8 +  <group>
    29.9 +    <id>base</id>
   29.10 +    <name>Base</name>
   29.11 +    <description>A set of base packages</description>
   29.12 +    <default>true</default>
   29.13 +    <uservisible>true</uservisible>
   29.14 +    <packagelist>
   29.15 +      <packagereq type="default">zsh</packagereq>
   29.16 +      <packagereq type="conditional">zsh2</packagereq>
   29.17 +      <packagereq type="optional">zip</packagereq>
   29.18 +      <packagereq type="default">zap</packagereq>
   29.19 +      <packagereq type="mandatory">filesystem</packagereq>
   29.20 +      <packagereq type="default">zappy</packagereq>
   29.21 +      <packagereq requires="zip">zappy-tools</packagereq>
   29.22 +      <packagereq>zappy2</packagereq>
   29.23 +    </packagelist>
   29.24 +  </group>
   29.25 +  <group>
   29.26 +    <id>zappy</id>
   29.27 +    <name>Zappy</name>
   29.28 +    <description>A set of zappy packages</description>
   29.29 +    <uservisible>true</uservisible>
   29.30 +    <packagelist>
   29.31 +      <packagereq type="mandatory">zap</packagereq>
   29.32 +      <packagereq type="default">zappy</packagereq>
   29.33 +      <packagereq type="optional">zappy2</packagereq>
   29.34 +      <packagereq requires="zappy">zappy-tools</packagereq>
   29.35 +    </packagelist>
   29.36 +  </group>
   29.37 +</comps>
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/tests/filesystem.spec	Mon Jun 13 12:18:42 2016 +0100
    30.3 @@ -0,0 +1,41 @@
    30.4 +%define _source_payload w9.gzdio
    30.5 +%define _binary_payload w9.gzdio
    30.6 +
    30.7 +Name:      filesystem
    30.8 +Summary:   Test package
    30.9 +Group:     Test
   30.10 +License:   GPL
   30.11 +Version:   1
   30.12 +Release:   1
   30.13 +BuildArch: noarch
   30.14 +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   30.15 +
   30.16 +%description
   30.17 +Test package
   30.18 +
   30.19 +%prep
   30.20 +
   30.21 +%build
   30.22 +
   30.23 +%install
   30.24 +mkdir -p %{buildroot}
   30.25 +mkdir -p %{buildroot}%{_sysconfdir}
   30.26 +mkdir -p %{buildroot}/{%{_bindir},%{_prefix}/lib,%{_includedir}}
   30.27 +mkdir -p %{buildroot}/media
   30.28 +
   30.29 +%clean
   30.30 +rm -rf %{buildroot}
   30.31 +
   30.32 +%post -p <lua>
   30.33 +function mkdir_missing(dir)
   30.34 +    if posix.stat(dir) == nil then
   30.35 +        posix.mkdir(dir)
   30.36 +    end
   30.37 +end
   30.38 +mkdir_missing("/media/cdrom")
   30.39 +
   30.40 +%files
   30.41 +%defattr(0755,root,root)
   30.42 +/etc
   30.43 +%{_prefix}
   30.44 +%dir /media
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/tests/glib.supp.in	Mon Jun 13 12:18:42 2016 +0100
    31.3 @@ -0,0 +1,521 @@
    31.4 +# This GLib suppressions file is known to be used at least by:
    31.5 +#
    31.6 +#  - rpm-software-management/libhif
    31.7 +#
    31.8 +# This file should be treated as canonical.
    31.9 +{
   31.10 +   gobject_init_1
   31.11 +   Memcheck:Leak
   31.12 +   ...
   31.13 +   fun:gobject_init
   31.14 +}
   31.15 +{
   31.16 +   g_type_register_static_1
   31.17 +   Memcheck:Leak
   31.18 +   ...
   31.19 +   fun:g_type_register_static
   31.20 +}
   31.21 +{
   31.22 +   g_type_register_fundamental
   31.23 +   Memcheck:Leak
   31.24 +   ...
   31.25 +   fun:g_type_register_fundamental
   31.26 +}
   31.27 +{
   31.28 +   g_type_init_with_debug_flags
   31.29 +   Memcheck:Leak
   31.30 +   ...
   31.31 +   fun:g_type_init_with_debug_flags
   31.32 +}
   31.33 +{
   31.34 +   g_type_class_ref_1
   31.35 +   Memcheck:Leak
   31.36 +   ...
   31.37 +   fun:type_iface_vtable_base_init_Wm
   31.38 +   ...
   31.39 +   fun:g_type_class_ref
   31.40 +}
   31.41 +{
   31.42 +   g_type_class_ref_2
   31.43 +   Memcheck:Leak
   31.44 +   ...
   31.45 +   fun:type_class_init_Wm
   31.46 +   ...
   31.47 +   fun:g_type_class_ref
   31.48 +}
   31.49 +{
   31.50 +   g_type_add_interface_static
   31.51 +   Memcheck:Leak
   31.52 +   ...
   31.53 +   fun:g_type_add_interface_static
   31.54 +}
   31.55 +{
   31.56 +   g_param_spec_internal
   31.57 +   Memcheck:Leak
   31.58 +   ...
   31.59 +   fun:g_type_class_ref
   31.60 +   fun:g_type_create_instance
   31.61 +   fun:g_param_spec_internal
   31.62 +}
   31.63 +{
   31.64 +   g_param_spec_enum
   31.65 +   Memcheck:Leak
   31.66 +   ...
   31.67 +   fun:g_type_class_ref
   31.68 +   fun:g_param_spec_enum
   31.69 +}
   31.70 +{
   31.71 +   g_param_spec_flags
   31.72 +   Memcheck:Leak
   31.73 +   ...
   31.74 +   fun:g_type_class_ref
   31.75 +   fun:g_param_spec_flags
   31.76 +}
   31.77 +{
   31.78 +   g_quark_from_static_string
   31.79 +   Memcheck:Leak
   31.80 +   ...
   31.81 +   fun:g_quark_from_static_string
   31.82 +}
   31.83 +{
   31.84 +   g_quark_from_string
   31.85 +   Memcheck:Leak
   31.86 +   ...
   31.87 +   fun:g_quark_from_string
   31.88 +}
   31.89 +{
   31.90 +   g_value_register_transform_func
   31.91 +   Memcheck:Leak
   31.92 +   ...
   31.93 +   fun:g_value_register_transform_func
   31.94 +}
   31.95 +{
   31.96 +   test_run_seed
   31.97 +   Memcheck:Leak
   31.98 +   ...
   31.99 +   fun:g_rand_new_with_seed_array
  31.100 +   fun:test_run_seed
  31.101 +   ...
  31.102 +   fun:g_test_run_suite
  31.103 +}
  31.104 +{
  31.105 +   g_test_init
  31.106 +   Memcheck:Leak
  31.107 +   ...
  31.108 +   fun:g_rand_new_with_seed_array
  31.109 +   ...
  31.110 +   fun:g_test_init
  31.111 +}
  31.112 +{
  31.113 +   g_intern_static_string
  31.114 +   Memcheck:Leak
  31.115 +   ...
  31.116 +   fun:g_intern_static_string
  31.117 +}
  31.118 +{
  31.119 +   g_main_context_push_thread_default
  31.120 +   Memcheck:Leak
  31.121 +   ...
  31.122 +   fun:g_queue_new
  31.123 +   fun:g_main_context_push_thread_default
  31.124 +}
  31.125 +{
  31.126 +   g_dbus_error_register_error
  31.127 +   Memcheck:Leak
  31.128 +   ...
  31.129 +   fun:g_dbus_error_register_error
  31.130 +}
  31.131 +{
  31.132 +   g_param_spec_pool_insert
  31.133 +   Memcheck:Leak
  31.134 +   ...
  31.135 +   fun:g_param_spec_pool_insert
  31.136 +}
  31.137 +{
  31.138 +   g_main_context_default
  31.139 +   Memcheck:Leak
  31.140 +   ...
  31.141 +   fun:g_main_context_default
  31.142 +}
  31.143 +{
  31.144 +   g_main_context_check
  31.145 +   Memcheck:Leak
  31.146 +   ...
  31.147 +   fun:g_ptr_array_add
  31.148 +   fun:g_main_context_check
  31.149 +}
  31.150 +{
  31.151 +   g_test_run_suite
  31.152 +   Memcheck:Leak
  31.153 +   ...
  31.154 +   fun:g_slist_copy
  31.155 +   fun:g_test_run_suite_internal
  31.156 +   fun:g_test_run_suite
  31.157 +}
  31.158 +{
  31.159 +   g_dbus_interface_info_cache_build
  31.160 +   Memcheck:Leak
  31.161 +   ...
  31.162 +   fun:g_dbus_interface_info_cache_build
  31.163 +}
  31.164 +{
  31.165 +   g_cancellable_push_current
  31.166 +   Memcheck:Leak
  31.167 +   ...
  31.168 +   fun:thread_memory_from_self
  31.169 +   ...
  31.170 +   fun:g_cancellable_push_current
  31.171 +}
  31.172 +{
  31.173 +   _g_io_module_get_default
  31.174 +   Memcheck:Leak
  31.175 +   ...
  31.176 +   fun:g_io_module_new
  31.177 +   fun:g_io_modules_scan_all_in_directory_with_scope
  31.178 +   fun:_g_io_modules_ensure_loaded
  31.179 +   fun:_g_io_module_get_default
  31.180 +}
  31.181 +{
  31.182 +   g_io_scheduler_push_job
  31.183 +   Memcheck:Leak
  31.184 +   ...
  31.185 +   fun:init_scheduler
  31.186 +   fun:g_once_impl
  31.187 +   fun:g_io_scheduler_push_job
  31.188 +}
  31.189 +{
  31.190 +   g_io_scheduler_push_job_2
  31.191 +   Memcheck:Leak
  31.192 +   ...
  31.193 +   fun:g_system_thread_new
  31.194 +   ...
  31.195 +   fun:g_io_scheduler_push_job
  31.196 +}
  31.197 +{
  31.198 +   g_bus_get_sync__available_connections
  31.199 +   Memcheck:Leak
  31.200 +   ...
  31.201 +   fun:g_hash_table_new
  31.202 +   fun:initable_init
  31.203 +   fun:g_initable_init
  31.204 +   fun:g_bus_get_sync
  31.205 +}
  31.206 +{
  31.207 +   g_socket_connection_factory_register_type
  31.208 +   Memcheck:Leak
  31.209 +   ...
  31.210 +   fun:g_socket_connection_factory_register_type
  31.211 +}
  31.212 +{
  31.213 +   g_test_add_vtable
  31.214 +   Memcheck:Leak
  31.215 +   ...
  31.216 +   fun:g_test_add_vtable
  31.217 +}
  31.218 +{
  31.219 +   g_mutex_lock
  31.220 +   Memcheck:Leak
  31.221 +   ...
  31.222 +   fun:g_mutex_impl_new
  31.223 +   fun:g_mutex_get_impl
  31.224 +   fun:g_mutex_lock
  31.225 +}
  31.226 +{
  31.227 +   g_thread_self
  31.228 +   Memcheck:Leak
  31.229 +   ...
  31.230 +   fun:g_thread_self
  31.231 +}
  31.232 +{
  31.233 +   g_rec_mutex_lock
  31.234 +   Memcheck:Leak
  31.235 +   ...
  31.236 +   fun:g_rec_mutex_impl_new
  31.237 +   fun:g_rec_mutex_get_impl
  31.238 +   fun:g_rec_mutex_lock
  31.239 +}
  31.240 +{
  31.241 +   test_case_run
  31.242 +   Memcheck:Leak
  31.243 +   ...
  31.244 +   fun:g_malloc0
  31.245 +   fun:test_case_run
  31.246 +   ...
  31.247 +   fun:g_test_run_suite
  31.248 +}
  31.249 +{
  31.250 +   g_get_charset
  31.251 +   Memcheck:Leak
  31.252 +   ...
  31.253 +   fun:g_get_charset
  31.254 +}
  31.255 +{
  31.256 +   g_test_run_suite__timer_new
  31.257 +   Memcheck:Leak
  31.258 +   ...
  31.259 +   fun:g_timer_new
  31.260 +   fun:test_case_run
  31.261 +   ...
  31.262 +   fun:g_test_run_suite
  31.263 +}
  31.264 +{
  31.265 +   g_test_run_suite__timer_new2
  31.266 +   Memcheck:Leak
  31.267 +   ...
  31.268 +   fun:g_timer_new
  31.269 +   fun:test_case_run_suite_internal
  31.270 +   ...
  31.271 +   fun:g_test_run_suite
  31.272 +}
  31.273 +{
  31.274 +   g_test_run_suite__strconcat
  31.275 +   Memcheck:Leak
  31.276 +   ...
  31.277 +   fun:g_strconcat
  31.278 +   fun:test_case_run
  31.279 +   ...
  31.280 +   fun:g_test_run_suite
  31.281 +   fun:g_test_run
  31.282 +}
  31.283 +{
  31.284 +   g_type_interface_add_prerequisite
  31.285 +   Memcheck:Leak
  31.286 +   ...
  31.287 +   fun:g_type_interface_add_prerequisite
  31.288 +}
  31.289 +{
  31.290 +   <insert_a_suppression_name_here>
  31.291 +   Memcheck:Leak
  31.292 +   ...
  31.293 +   fun:g_slist_copy
  31.294 +   fun:g_test_run_suite_internal
  31.295 +   ...
  31.296 +   fun:g_test_run_suite
  31.297 +}
  31.298 +{
  31.299 +   g_set_prgname
  31.300 +   Memcheck:Leak
  31.301 +   ...
  31.302 +   fun:g_set_prgname
  31.303 +}
  31.304 +{
  31.305 +   g_test_run_suite__strconcat_2
  31.306 +   Memcheck:Leak
  31.307 +   ...
  31.308 +   fun:g_strconcat
  31.309 +   fun:g_test_run_suite_internal
  31.310 +}
  31.311 +{
  31.312 +   g_test_run_suite__strdup
  31.313 +   Memcheck:Leak
  31.314 +   ...
  31.315 +   fun:g_strdup
  31.316 +   fun:g_test_run_suite_internal
  31.317 +}
  31.318 +{
  31.319 +   g_private_get
  31.320 +   Memcheck:Leak
  31.321 +   ...
  31.322 +   fun:g_private_get
  31.323 +}
  31.324 +{
  31.325 +   g_private_set
  31.326 +   Memcheck:Leak
  31.327 +   ...
  31.328 +   fun:g_private_set
  31.329 +}
  31.330 +{
  31.331 +   g_static_mutex_get_mutex_impl
  31.332 +   Memcheck:Leak
  31.333 +   ...
  31.334 +   fun:g_static_mutex_get_mutex_impl
  31.335 +}
  31.336 +{
  31.337 +   g_variant_type_info_unref
  31.338 +   Memcheck:Leak
  31.339 +   ...
  31.340 +   fun:g_hash_table_remove
  31.341 +   fun:g_variant_type_info_unref
  31.342 +}
  31.343 +{
  31.344 +   g_rw_lock_reader_lock
  31.345 +   Memcheck:Leak
  31.346 +   ...
  31.347 +   fun:g_rw_lock_impl_new
  31.348 +   fun:g_rw_lock_get_impl
  31.349 +   fun:g_rw_lock_reader_lock
  31.350 +}
  31.351 +{
  31.352 +   g_child_watch_finalize__rt_sigaction
  31.353 +   Memcheck:Param
  31.354 +   rt_sigaction(act->sa_flags)
  31.355 +   fun:__libc_sigaction
  31.356 +   ...
  31.357 +   fun:g_child_watch_finalize
  31.358 +}
  31.359 +{
  31.360 +   gdbus_shared_thread_func
  31.361 +   Memcheck:Leak
  31.362 +   match-leak-kinds: definite
  31.363 +   ...
  31.364 +   fun:g_malloc
  31.365 +   ...
  31.366 +   fun:gdbus_shared_thread_func
  31.367 +}
  31.368 +{
  31.369 +   g_task_start_task_thread
  31.370 +   Memcheck:Leak
  31.371 +   match-leak-kinds: definite
  31.372 +   fun:malloc
  31.373 +   fun:g_malloc
  31.374 +   fun:g_slice_alloc
  31.375 +   fun:g_slice_alloc0
  31.376 +   ...
  31.377 +   fun:g_thread_pool_push
  31.378 +   fun:g_task_start_task_thread
  31.379 +}
  31.380 +{
  31.381 +   g_get_language_names
  31.382 +   Memcheck:Leak
  31.383 +   match-leak-kinds: definite
  31.384 +   fun:calloc
  31.385 +   fun:g_malloc0
  31.386 +   fun:g_get_language_names
  31.387 +}
  31.388 +{
  31.389 +   g_get_filename_charsets
  31.390 +   Memcheck:Leak
  31.391 +   match-leak-kinds: definite
  31.392 +   ...
  31.393 +   fun:g_get_filename_charsets
  31.394 +   fun:g_filename_display_name
  31.395 +}
  31.396 +{
  31.397 +   g_main_current_source
  31.398 +   Memcheck:Leak
  31.399 +   match-leak-kinds: definite
  31.400 +   fun:malloc
  31.401 +   fun:g_malloc
  31.402 +   ...
  31.403 +   fun:g_main_current_source
  31.404 +   fun:g_task_return
  31.405 +   fun:g_task_thread_pool_thread
  31.406 +}
  31.407 +{
  31.408 +   g_once_init_enter
  31.409 +   Memcheck:Leak
  31.410 +   match-leak-kinds: definite
  31.411 +   ...
  31.412 +   fun:g_once_init_enter
  31.413 +}
  31.414 +{
  31.415 +   g_child_watch_source_new
  31.416 +   Memcheck:Leak
  31.417 +   match-leak-kinds: definite
  31.418 +   ...
  31.419 +   fun:g_thread_new
  31.420 +   ...
  31.421 +   fun:g_child_watch_source_new
  31.422 +}
  31.423 +{
  31.424 +   continue_writing_in_idle_cb
  31.425 +   Memcheck:Leak
  31.426 +   match-leak-kinds: definite
  31.427 +   ...
  31.428 +   fun:g_task_new
  31.429 +   ...
  31.430 +   fun:continue_writing_in_idle_cb
  31.431 +   fun:g_main_context_dispatch
  31.432 +}
  31.433 +{
  31.434 +   g_main_current_source
  31.435 +   Memcheck:Leak
  31.436 +   match-leak-kinds: definite
  31.437 +   fun:malloc
  31.438 +   ...
  31.439 +   fun:g_main_current_source
  31.440 +}
  31.441 +{
  31.442 +   g_thread_pool_push
  31.443 +   Memcheck:Leak
  31.444 +   match-leak-kinds: definite
  31.445 +   fun:malloc
  31.446 +   ...
  31.447 +   fun:g_thread_pool_push
  31.448 +}
  31.449 +{
  31.450 +   leak_test_dbus_dispose
  31.451 +   Memcheck:Leak
  31.452 +   match-leak-kinds: definite
  31.453 +   fun:malloc
  31.454 +   ...
  31.455 +   fun:g_main_loop_run
  31.456 +   fun:g_test_dbus_down
  31.457 +}
  31.458 +{
  31.459 +   leak_test_dbus_down
  31.460 +   Memcheck:Leak
  31.461 +   match-leak-kinds: definite
  31.462 +   fun:calloc
  31.463 +   fun:g_malloc0
  31.464 +   fun:g_main_loop_new
  31.465 +   fun:g_test_dbus_down
  31.466 +}
  31.467 +{
  31.468 +   leak_socket_client_connect
  31.469 +   Memcheck:Leak
  31.470 +   match-leak-kinds: definite
  31.471 +   fun:malloc
  31.472 +   fun:g_malloc
  31.473 +   fun:g_slice_alloc
  31.474 +   fun:g_slice_alloc0
  31.475 +   fun:g_socket_client_connect_async
  31.476 +   fun:g_socket_client_connect_to_uri_async
  31.477 +}
  31.478 +{
  31.479 +   leak_signal_handlers_disconnect_matched
  31.480 +   Memcheck:Leak
  31.481 +   match-leak-kinds: definite
  31.482 +   fun:calloc
  31.483 +   fun:g_malloc0
  31.484 +   ...
  31.485 +   fun:g_slice_alloc
  31.486 +   ...
  31.487 +   fun:g_signal_handlers_disconnect_matched
  31.488 +}
  31.489 +{
  31.490 +   g_tls_connection_gnutls_init_priorities
  31.491 +   Memcheck:Leak
  31.492 +   match-leak-kinds: definite
  31.493 +   fun:malloc
  31.494 +   fun:g_malloc
  31.495 +   fun:g_strdup
  31.496 +   fun:g_tls_connection_gnutls_init_priorities
  31.497 +}
  31.498 +{
  31.499 +   g_tls_connection_gnutls_heisenbug_likely_same_as_above
  31.500 +   Memcheck:Leak
  31.501 +   match-leak-kinds: definite
  31.502 +   fun:malloc
  31.503 +   fun:g_malloc
  31.504 +   fun:g_strdup
  31.505 +   ...
  31.506 +   fun:g_tls_client_connection_new
  31.507 +}
  31.508 +{
  31.509 +   g_unix_signal_add_full
  31.510 +   Memcheck:Leak
  31.511 +   match-leak-kinds: definite
  31.512 +   fun:malloc
  31.513 +   fun:g_malloc
  31.514 +   ...
  31.515 +   fun:g_thread_new
  31.516 +   ...
  31.517 +   fun:g_unix_signal_add_full
  31.518 +}
  31.519 +{
  31.520 +   glib_worker_1
  31.521 +   Memcheck:Leak
  31.522 +   ...
  31.523 +   fun:glib_worker_main
  31.524 +}
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/tests/plover-gtk/Makefile.am	Mon Jun 13 12:18:42 2016 +0100
    32.3 @@ -0,0 +1,45 @@
    32.4 +AM_CFLAGS=-g $(PLOVER_GTK_CFLAGS)
    32.5 +INCLUDES=-I$(top_srcdir)
    32.6 +LDADD=../../plover-gtk/libplover-gtk.la ../../plover/libplover.la \
    32.7 +  $(PLOVER_GTK_LIBS)
    32.8 +
    32.9 +if HAVE_CHECK_TOOLS
   32.10 +
   32.11 +TESTS = $(txt_tests) $(gui_tests:=.xvfb)
   32.12 +TESTS_ENVIRONMENT = gtk_srcdir="$(top_srcdir)/plover-gtk"
   32.13 +TEST_EXTENSIONS = .xvfb
   32.14 +XVFB_LOG_COMPILER = $(top_srcdir)/tests/xvfb-run
   32.15 +XVFB_LOG_FLAGS = --auto-servernum --auth-file .Xauthority
   32.16 +
   32.17 +check_PROGRAMS = $(txt_tests) $(gui_tests)
   32.18 +
   32.19 +txt_tests = test-packagefilestore test-packagestore test-stockicons
   32.20 +gui_tests = test-transactionhelper
   32.21 +
   32.22 +test_packagefilestore_SOURCES = test-packagefilestore.c treemodel.c treemodel.h
   32.23 +test_packagestore_SOURCES = test-packagestore.c treemodel.c treemodel.h
   32.24 +test_stockicons_DEPENDENCIES = \
   32.25 +  icons/hicolor/scalable/mimetypes/application-x-redhat-package-manager.svg
   32.26 +
   32.27 +.c.xvfb:
   32.28 +	$(AM_V_GEN)echo '#!/bin/sh' > $@
   32.29 +	$(AM_V_GEN)echo '$(LOG_COMPILER) $(LOG_FLAGS) ./$*' >> $@
   32.30 +	$(AM_V_GEN)chmod +x $@
   32.31 +	
   32.32 +icons/hicolor/scalable/mimetypes/application-x-redhat-package-manager.svg: \
   32.33 +  $(top_srcdir)/plover-open/mimetypes-application-x-rpm.svg
   32.34 +	$(PLOVER_V_SKIP)mkdir -p icons/hicolor/scalable/mimetypes \
   32.35 +	  icons/hicolor/24x24/mimetypes icons/hicolor/48x48/mimetypes 
   32.36 +	$(AM_V_GEN)cp $< $@
   32.37 +	$(AM_V_GEN)rsvg -w 24 -h 24 -f png $< \
   32.38 +	  icons/hicolor/24x24/mimetypes/application-x-redhat-package-manager.png
   32.39 +	$(AM_V_GEN)rsvg -w 48 -h 48 -f png $< \
   32.40 +	  icons/hicolor/48x48/mimetypes/application-x-redhat-package-manager.png
   32.41 +
   32.42 +endif
   32.43 +
   32.44 +@VALGRIND_CHECK_RULES@
   32.45 +VALGRIND_SUPPRESSIONS_FILES = ../glib.supp
   32.46 +
   32.47 +clean-local:
   32.48 +	rm -rf icons razor-test-dir-* $(gui_tests:=.xvfb) .Xauthority
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/tests/plover-gtk/test-packagefilestore.c	Mon Jun 13 12:18:42 2016 +0100
    33.3 @@ -0,0 +1,112 @@
    33.4 +/*
    33.5 + * Copyright (C) 2016  J. Ali Harlow <ali@juiblex.co.uk>
    33.6 + *
    33.7 + * This program is free software; you can redistribute it and/or modify
    33.8 + * it under the terms of the GNU General Public License as published by
    33.9 + * the Free Software Foundation; either version 2 of the License, or
   33.10 + * (at your option) any later version.
   33.11 + *
   33.12 + * This program is distributed in the hope that it will be useful,
   33.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   33.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   33.15 + * GNU General Public License for more details.
   33.16 + *
   33.17 + * You should have received a copy of the GNU General Public License along
   33.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
   33.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   33.20 + */
   33.21 +
   33.22 +#include <stdlib.h>
   33.23 +#include <string.h>
   33.24 +#include <glib.h>
   33.25 +#include <gtk/gtk.h>
   33.26 +#include <plover/package.h>
   33.27 +#include <plover/packageset.h>
   33.28 +#include <plover-gtk/packagefilestore.h>
   33.29 +#include "treemodel.h"
   33.30 +
   33.31 +static PloverPackage *package_getref(const char *name)
   33.32 +{
   33.33 +    GSList *packages,*lnk;
   33.34 +    GError *err=NULL;
   33.35 +    PloverPackageSet *package_set;
   33.36 +    PloverPackage *package;
   33.37 +    package_set=plover_package_set_new_from_yum("../yum-repo-test-dir",NULL,
   33.38 +      &err);
   33.39 +    if (!package_set)
   33.40 +	g_error("../yum-repo-test-dir: %s",err->message);
   33.41 +    packages=plover_package_set_get_packages(package_set);
   33.42 +    for(lnk=packages;lnk;lnk=lnk->next)
   33.43 +    {
   33.44 +	package=lnk->data;
   33.45 +	if (!strcmp(plover_package_get_name(package),name))
   33.46 +	    break;
   33.47 +    }
   33.48 +    if (!lnk)
   33.49 +	package=NULL;
   33.50 +    if (package)
   33.51 +	g_object_ref(package);
   33.52 +    g_object_unref(package_set);
   33.53 +    return package;
   33.54 +}
   33.55 +
   33.56 +static void test_empty(void)
   33.57 +{
   33.58 +    PloverPackage *package;
   33.59 +    PloverPackageFileStore *store;
   33.60 +    package=package_getref("zappy-tools");
   33.61 +    store=plover_package_file_store_new_from_package(package);
   33.62 +    g_object_unref(package);
   33.63 +    test_tree_model(GTK_TREE_MODEL(store));
   33.64 +    g_object_unref(store);
   33.65 +}
   33.66 +
   33.67 +static void test_basic(void)
   33.68 +{
   33.69 +    int i;
   33.70 +    const char *name;
   33.71 +    GValue value={0,};
   33.72 +    GtkTreeModel *model;
   33.73 +    GtkTreeIter iter;
   33.74 +    PloverPackage *package;
   33.75 +    PloverPackageFileStore *store;
   33.76 +    GList *expected,*lnk;
   33.77 +    package=package_getref("zsh");
   33.78 +    store=plover_package_file_store_new_from_package(package);
   33.79 +    g_object_unref(package);
   33.80 +    model=GTK_TREE_MODEL(store);
   33.81 +    test_tree_model(model);
   33.82 +    expected=g_list_prepend(NULL,(gpointer)g_intern_string("/etc/zsh.conf"));
   33.83 +    expected=g_list_prepend(expected,(gpointer)g_intern_string("/usr/bin/zsh"));
   33.84 +    g_assert_cmpint(gtk_tree_model_get_n_columns(model),==,1);
   33.85 +    g_assert_cmpint(gtk_tree_model_get_column_type(model,0),==,G_TYPE_STRING);
   33.86 +    for(i=0;;i++)
   33.87 +    {
   33.88 +	if (!gtk_tree_model_iter_nth_child(model,&iter,NULL,i))
   33.89 +	    break;
   33.90 +	gtk_tree_model_get_value(model,&iter,0,&value);
   33.91 +	name=g_value_get_string(&value);
   33.92 +	lnk=g_list_find(expected,g_intern_string(name));
   33.93 +	if (!lnk)
   33.94 +	    g_warning("Unexpected file in zsh package: %s",name);
   33.95 +	else
   33.96 +	    expected=g_list_delete_link(expected,lnk);
   33.97 +	g_value_unset(&value);
   33.98 +    }
   33.99 +    if (expected)
  33.100 +	g_warning("%d missing file%s in set, including %s",
  33.101 +	  g_list_length(expected),g_list_length(expected)==1?"":"s",
  33.102 +	  expected->data);
  33.103 +    g_object_unref(store);
  33.104 +}
  33.105 +
  33.106 +int main(int argc,char **argv)
  33.107 +{
  33.108 +    int retval;
  33.109 +    gtk_test_init(&argc,&argv,NULL);
  33.110 +    g_test_bug_base("mailto:ali@juiblex.co.uk");
  33.111 +    g_test_add_func("/packagefilestore/empty",test_empty);
  33.112 +    g_test_add_func("/packagefilestore/basic",test_basic);
  33.113 +    retval=g_test_run();
  33.114 +    return retval;
  33.115 +}
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/tests/plover-gtk/test-packagestore.c	Mon Jun 13 12:18:42 2016 +0100
    34.3 @@ -0,0 +1,215 @@
    34.4 +/*
    34.5 + * Copyright (C) 2016  J. Ali Harlow <ali@juiblex.co.uk>
    34.6 + *
    34.7 + * This program is free software; you can redistribute it and/or modify
    34.8 + * it under the terms of the GNU General Public License as published by
    34.9 + * the Free Software Foundation; either version 2 of the License, or
   34.10 + * (at your option) any later version.
   34.11 + *
   34.12 + * This program is distributed in the hope that it will be useful,
   34.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   34.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   34.15 + * GNU General Public License for more details.
   34.16 + *
   34.17 + * You should have received a copy of the GNU General Public License along
   34.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
   34.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   34.20 + */
   34.21 +
   34.22 +#include <stdlib.h>
   34.23 +#include <string.h>
   34.24 +#include <glib.h>
   34.25 +#include <gdk/gdk.h>
   34.26 +#include <gtk/gtk.h>
   34.27 +#include <razor/razor.h>
   34.28 +#include <plover/package.h>
   34.29 +#include <plover/packageset.h>
   34.30 +#include <plover-gtk/packagestore.h>
   34.31 +#include "treemodel.h"
   34.32 +
   34.33 +static void verify_package_store(PloverPackageStore *store,
   34.34 +  GSList *expected_packages)
   34.35 +{
   34.36 +    int i;
   34.37 +    const char *s;
   34.38 +    gchar *nosummary;
   34.39 +    PloverPackage *package;
   34.40 +    PloverPackageSet *package_set;
   34.41 +    GtkTreeModel *model;
   34.42 +    GtkTreeIter iter;
   34.43 +    GValue value={0,};
   34.44 +    GSList *expected,*lnk;
   34.45 +    GdkPixbuf *icon;
   34.46 +    model=GTK_TREE_MODEL(store);
   34.47 +    test_tree_model(model);
   34.48 +    expected=g_slist_copy(expected_packages);
   34.49 +    g_assert_cmpint(gtk_tree_model_get_n_columns(model),==,PLOVER_PACKAGE_STORE_NO_COLUMNS);
   34.50 +    g_assert_cmpint(gtk_tree_model_get_column_type(model,PLOVER_PACKAGE_STORE_OBJ_COLUMN),==,PLOVER_TYPE_PACKAGE);
   34.51 +    g_assert_cmpint(gtk_tree_model_get_column_type(model,PLOVER_PACKAGE_STORE_INSTALLED_COLUMN),==,G_TYPE_BOOLEAN);
   34.52 +    g_assert_cmpint(gtk_tree_model_get_column_type(model,PLOVER_PACKAGE_STORE_ICON_COLUMN),==,GDK_TYPE_PIXBUF);
   34.53 +    g_assert_cmpint(gtk_tree_model_get_column_type(model,PLOVER_PACKAGE_STORE_NAME_COLUMN),==,G_TYPE_STRING);
   34.54 +    g_assert_cmpint(gtk_tree_model_get_column_type(model,PLOVER_PACKAGE_STORE_VERSION_COLUMN),==,G_TYPE_STRING);
   34.55 +    g_assert_cmpint(gtk_tree_model_get_column_type(model,PLOVER_PACKAGE_STORE_SUMMARY_COLUMN),==,G_TYPE_STRING);
   34.56 +    for(i=0;;i++)
   34.57 +    {
   34.58 +	if (!gtk_tree_model_iter_nth_child(model,&iter,NULL,i))
   34.59 +	    break;
   34.60 +	gtk_tree_model_get_value(model,&iter,PLOVER_PACKAGE_STORE_OBJ_COLUMN,
   34.61 +	  &value);
   34.62 +	package=g_value_dup_object(&value);
   34.63 +	lnk=g_slist_find(expected,package);
   34.64 +	if (!lnk)
   34.65 +	    g_warning("Unexpected package in store: %s",
   34.66 +	      plover_package_get_name(package));
   34.67 +	else
   34.68 +	{
   34.69 +	    g_object_unref(lnk->data);
   34.70 +	    expected=g_slist_delete_link(expected,lnk);
   34.71 +	}
   34.72 +	g_value_unset(&value);
   34.73 +	gtk_tree_model_get_value(model,&iter,
   34.74 +	  PLOVER_PACKAGE_STORE_INSTALLED_COLUMN,&value);
   34.75 +	g_assert_cmpint(G_VALUE_TYPE(&value),==,G_TYPE_BOOLEAN);
   34.76 +	/* Can't check value of installed yet, it
   34.77 +	 * isn't set (or even properly defined).
   34.78 +	 */
   34.79 +	g_value_unset(&value);
   34.80 +	gtk_tree_model_get_value(model,&iter,
   34.81 +	  PLOVER_PACKAGE_STORE_ICON_COLUMN,&value);
   34.82 +	icon=g_value_get_object(&value);
   34.83 +	if (icon)
   34.84 +	    g_assert(GDK_IS_PIXBUF(icon));
   34.85 +	g_value_unset(&value);
   34.86 +	gtk_tree_model_get_value(model,&iter,PLOVER_PACKAGE_STORE_NAME_COLUMN,
   34.87 +	  &value);
   34.88 +	s=g_value_get_string(&value);
   34.89 +	g_assert_cmpstr(plover_package_get_name(package),==,s);
   34.90 +	g_value_unset(&value);
   34.91 +	gtk_tree_model_get_value(model,&iter,
   34.92 +	  PLOVER_PACKAGE_STORE_VERSION_COLUMN,&value);
   34.93 +	s=g_value_get_string(&value);
   34.94 +	g_assert_cmpstr(plover_package_get_version(package),==,s);
   34.95 +	g_value_unset(&value);
   34.96 +	gtk_tree_model_get_value(model,&iter,
   34.97 +	  PLOVER_PACKAGE_STORE_SUMMARY_COLUMN,&value);
   34.98 +	s=g_value_get_string(&value);
   34.99 +	if (*plover_package_get_summary(package))
  34.100 +	    g_assert_cmpstr(plover_package_get_summary(package),==,s);
  34.101 +	else
  34.102 +	{
  34.103 +	    nosummary=g_strconcat("The ",plover_package_get_name(package),
  34.104 +	      " package",NULL);
  34.105 +	    g_assert_cmpstr(nosummary,==,s);
  34.106 +	    g_free(nosummary);
  34.107 +	}
  34.108 +	g_value_unset(&value);
  34.109 +    }
  34.110 +    if (expected)
  34.111 +    {
  34.112 +	package=PLOVER_PACKAGE(expected->data);
  34.113 +	g_warning("%d missing package%s in store, including %s",
  34.114 +	  g_slist_length(expected),g_slist_length(expected)==1?"":"s",
  34.115 +	  plover_package_get_name(package));
  34.116 +    }
  34.117 +}
  34.118 +
  34.119 +static void test_empty(void)
  34.120 +{
  34.121 +    PloverPackageStore *store;
  34.122 +    store=plover_package_store_new();
  34.123 +    g_assert(!plover_package_store_get_sets(store));
  34.124 +    verify_package_store(store,NULL);
  34.125 +    g_object_unref(store);
  34.126 +}
  34.127 +
  34.128 +static void test_basic(void)
  34.129 +{
  34.130 +    PloverPackageSet *package_set;
  34.131 +    PloverPackageStore *store;
  34.132 +    GError *err=NULL;
  34.133 +    GSList *expected;
  34.134 +    package_set=plover_package_set_new_from_yum("../yum-repo-test-dir",NULL,
  34.135 +      &err);
  34.136 +    if (!package_set)
  34.137 +	g_error("../yum-repo-test-dir: %s",err->message);
  34.138 +    store=plover_package_store_new();
  34.139 +    plover_package_store_add_set(store,package_set);
  34.140 +    expected=g_slist_copy(plover_package_set_get_packages(package_set));
  34.141 +    g_slist_foreach(expected,(GFunc)g_object_ref,NULL);
  34.142 +    g_object_unref(package_set);
  34.143 +    verify_package_store(store,expected);
  34.144 +    g_slist_foreach(expected,(GFunc)g_object_unref,NULL);
  34.145 +    g_slist_free(expected);
  34.146 +    g_object_unref(store);
  34.147 +}
  34.148 +
  34.149 +static PloverPackageSet *no_details_new(void)
  34.150 +{
  34.151 +    struct razor_set *set;
  34.152 +    struct razor_importer *importer;
  34.153 +    PloverPackageSet *package_set;
  34.154 +    importer=razor_importer_create();
  34.155 +    razor_importer_begin_package(importer,"no-details","1-1","noarch");
  34.156 +    razor_importer_add_details(importer,"","","","");
  34.157 +    razor_importer_add_property(importer,"no-details",
  34.158 +      RAZOR_PROPERTY_PROVIDES|RAZOR_PROPERTY_EQUAL,"1-1");
  34.159 +    razor_importer_finish_package(importer);
  34.160 +    set=razor_importer_finish(importer);
  34.161 +    package_set=plover_package_set_new_from_razor(set);
  34.162 +    razor_set_unref(set);
  34.163 +    return package_set;
  34.164 +}
  34.165 +
  34.166 +static void test_no_details(void)
  34.167 +{
  34.168 +    PloverPackageSet *package_set;
  34.169 +    PloverPackageStore *store;
  34.170 +    GSList *expected;
  34.171 +    package_set=no_details_new();
  34.172 +    store=plover_package_store_new();
  34.173 +    plover_package_store_add_set(store,package_set);
  34.174 +    expected=g_slist_copy(plover_package_set_get_packages(package_set));
  34.175 +    g_slist_foreach(expected,(GFunc)g_object_ref,NULL);
  34.176 +    g_object_unref(package_set);
  34.177 +    verify_package_store(store,expected);
  34.178 +    g_slist_foreach(expected,(GFunc)g_object_unref,NULL);
  34.179 +    g_slist_free(expected);
  34.180 +    g_object_unref(store);
  34.181 +}
  34.182 +
  34.183 +static void test_remove(void)
  34.184 +{
  34.185 +    PloverPackageSet *yum_set,*nodetails_set;
  34.186 +    PloverPackageStore *store;
  34.187 +    GSList *expected;
  34.188 +    GError *err=NULL;
  34.189 +    store=plover_package_store_new();
  34.190 +    yum_set=plover_package_set_new_from_yum("../yum-repo-test-dir",NULL,&err);
  34.191 +    if (!yum_set)
  34.192 +	g_error("../yum-repo-test-dir: %s",err->message);
  34.193 +    plover_package_store_add_set(store,yum_set);
  34.194 +    nodetails_set=no_details_new();
  34.195 +    expected=g_slist_copy(plover_package_set_get_packages(nodetails_set));
  34.196 +    g_slist_foreach(expected,(GFunc)g_object_ref,NULL);
  34.197 +    plover_package_store_add_set(store,nodetails_set);
  34.198 +    plover_package_store_remove_set(store,yum_set);
  34.199 +    g_object_unref(nodetails_set);
  34.200 +    g_object_unref(yum_set);
  34.201 +    verify_package_store(store,expected);
  34.202 +    g_slist_foreach(expected,(GFunc)g_object_unref,NULL);
  34.203 +    g_slist_free(expected);
  34.204 +    g_object_unref(store);
  34.205 +}
  34.206 +
  34.207 +int main(int argc,char **argv)
  34.208 +{
  34.209 +    int retval;
  34.210 +    gtk_test_init(&argc,&argv,NULL);
  34.211 +    g_test_bug_base("mailto:ali@juiblex.co.uk");
  34.212 +    g_test_add_func("/packagestore/empty",test_empty);
  34.213 +    g_test_add_func("/packagestore/basic",test_basic);
  34.214 +    g_test_add_func("/packagestore/no-details",test_no_details);
  34.215 +    g_test_add_func("/packagestore/remove",test_remove);
  34.216 +    retval=g_test_run();
  34.217 +    return retval;
  34.218 +}
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/tests/plover-gtk/test-stockicons.c	Mon Jun 13 12:18:42 2016 +0100
    35.3 @@ -0,0 +1,68 @@
    35.4 +/*
    35.5 + * Copyright (C) 2016  J. Ali Harlow <ali@juiblex.co.uk>
    35.6 + *
    35.7 + * This program is free software; you can redistribute it and/or modify
    35.8 + * it under the terms of the GNU General Public License as published by
    35.9 + * the Free Software Foundation; either version 2 of the License, or
   35.10 + * (at your option) any later version.
   35.11 + *
   35.12 + * This program is distributed in the hope that it will be useful,
   35.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   35.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   35.15 + * GNU General Public License for more details.
   35.16 + *
   35.17 + * You should have received a copy of the GNU General Public License along
   35.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
   35.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   35.20 + */
   35.21 +
   35.22 +#include <stdlib.h>
   35.23 +#include <string.h>
   35.24 +#include <glib.h>
   35.25 +#include <gdk/gdk.h>
   35.26 +#include <gtk/gtk.h>
   35.27 +#include <plover-gtk/stockicons.h>
   35.28 +
   35.29 +static void test_basic(void)
   35.30 +{
   35.31 +    gchar *cwd;
   35.32 +    cwd=g_get_current_dir();
   35.33 +    g_setenv("PLOVER_ICONS_DATADIR",cwd,TRUE);
   35.34 +    g_free(cwd);
   35.35 +    plover_icons_add_to_stock("mimetypes",
   35.36 +      "application-x-redhat-package-manager");
   35.37 +    g_assert(gtk_icon_factory_lookup_default("application-x-redhat-package-manager"));
   35.38 +    g_unsetenv("PLOVER_ICONS_DATADIR");
   35.39 +}
   35.40 +
   35.41 +static void test_no_svg(void)
   35.42 +{
   35.43 +    gchar *cwd;
   35.44 +    cwd=g_get_current_dir();
   35.45 +    g_setenv("PLOVER_ICONS_DATADIR",cwd,TRUE);
   35.46 +    g_free(cwd);
   35.47 +    g_setenv("PLOVER_IGNORE_SVG_SUPPORT","yes",TRUE);
   35.48 +    plover_icons_add_to_stock("mimetypes",
   35.49 +      "application-x-redhat-package-manager");
   35.50 +    g_assert(gtk_icon_factory_lookup_default("application-x-redhat-package-manager"));
   35.51 +    g_unsetenv("PLOVER_IGNORE_SVG_SUPPORT");
   35.52 +    g_unsetenv("PLOVER_ICONS_DATADIR");
   35.53 +}
   35.54 +
   35.55 +static void test_none_existant(void)
   35.56 +{
   35.57 +    plover_icons_add_to_stock("mimetypes",
   35.58 +      "application-x-plover-test-stockicons");
   35.59 +}
   35.60 +
   35.61 +int main(int argc,char **argv)
   35.62 +{
   35.63 +    int retval;
   35.64 +    gtk_test_init(&argc,&argv,NULL);
   35.65 +    g_test_bug_base("mailto:ali@juiblex.co.uk");
   35.66 +    g_test_add_func("/stockicons/basic",test_basic);
   35.67 +    g_test_add_func("/stockicons/no-svg",test_no_svg);
   35.68 +    g_test_add_func("/stockicons/non-existant",test_none_existant);
   35.69 +    retval=g_test_run();
   35.70 +    return retval;
   35.71 +}
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/tests/plover-gtk/test-transactionhelper.c	Mon Jun 13 12:18:42 2016 +0100
    36.3 @@ -0,0 +1,725 @@
    36.4 +/*
    36.5 + * Copyright (C) 2016  J. Ali Harlow <ali@juiblex.co.uk>
    36.6 + *
    36.7 + * This program is free software; you can redistribute it and/or modify
    36.8 + * it under the terms of the GNU General Public License as published by
    36.9 + * the Free Software Foundation; either version 2 of the License, or
   36.10 + * (at your option) any later version.
   36.11 + *
   36.12 + * This program is distributed in the hope that it will be useful,
   36.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   36.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   36.15 + * GNU General Public License for more details.
   36.16 + *
   36.17 + * You should have received a copy of the GNU General Public License along
   36.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
   36.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   36.20 + */
   36.21 +
   36.22 +#include <stdlib.h>
   36.23 +#include <string.h>
   36.24 +#include <locale.h>
   36.25 +#include <sys/stat.h>
   36.26 +#include <glib.h>
   36.27 +#include <gdk/gdk.h>
   36.28 +#include <gtk/gtk.h>
   36.29 +#include <plover/plover.h>
   36.30 +#include <plover-gtk/transactionhelper.h>
   36.31 +
   36.32 +GtkBuilder *ui;
   36.33 +gboolean manual_mode=FALSE;
   36.34 +
   36.35 +PloverTransactionHelper *get_transaction_helper(void)
   36.36 +{
   36.37 +    const char *dir;
   36.38 +    gchar *s;
   36.39 +    GError *err=NULL;
   36.40 +    PloverTransactionHelper *helper;
   36.41 +    dir=g_getenv("gtk_srcdir");
   36.42 +    s=g_build_filename(dir,"software-installation.ui",NULL);
   36.43 +    ui=gtk_builder_new();
   36.44 +    if (!gtk_builder_add_from_file(ui,s,&err))
   36.45 +	g_error("%s: %s",s,err->message);
   36.46 +    g_free(s);
   36.47 +    helper=plover_transaction_helper_new(ui);
   36.48 +    g_object_unref(ui);
   36.49 +    return helper;
   36.50 +}
   36.51 +
   36.52 +static void test_init(void)
   36.53 +{
   36.54 +    PloverTransactionHelper *helper;
   36.55 +    helper=get_transaction_helper();
   36.56 +    g_object_unref(helper);
   36.57 +}
   36.58 +
   36.59 +static void test_basic_properties(void)
   36.60 +{
   36.61 +    const char *prefix;
   36.62 +    GError *err=NULL;
   36.63 +    struct comps *comps;
   36.64 +    PloverTransactionHelper *helper;
   36.65 +    PloverPackageSet *installed;
   36.66 +    PloverRepository *upstream;
   36.67 +    upstream=plover_repository_new_from_yum("../yum-repo-test-dir",&err);
   36.68 +    if (!upstream)
   36.69 +	g_error("../yum-repo-test-dir: %s",err->message);
   36.70 +    installed=plover_package_set_new_from_installed("../razor-test-dir",&err);
   36.71 +    if (!installed)
   36.72 +	g_error("../razor-test-dir: %s",err->message);
   36.73 +    helper=get_transaction_helper();
   36.74 +    g_assert(!plover_transaction_helper_get_visible(helper));
   36.75 +    plover_transaction_helper_set_installed(helper,installed);
   36.76 +    g_assert(plover_transaction_helper_get_installed(helper)==installed);
   36.77 +    plover_transaction_helper_set_upstream(helper,upstream);
   36.78 +    g_assert(plover_transaction_helper_get_upstream(helper,&err)==upstream);
   36.79 +    g_assert(!err);
   36.80 +    plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
   36.81 +    g_assert_cmpstr(plover_transaction_helper_get_base(helper),==,"../yum-repo-test-dir");
   36.82 +    comps=plover_transaction_helper_get_comps(helper,&err);
   36.83 +    g_assert(!err);
   36.84 +    g_assert(plover_comps_lookup_group(comps,"base"));
   36.85 +    prefix=plover_transaction_helper_get_prefix(helper,&err);
   36.86 +    g_assert(!err);
   36.87 +    g_assert_cmpstr(prefix,==,plover_default_prefix_for_vendor("Acme Corporation"));
   36.88 +    g_assert(!plover_transaction_helper_get_visible(helper));
   36.89 +    g_assert(!plover_transaction_helper_get_error(helper,NULL));
   36.90 +    g_object_unref(upstream);
   36.91 +    g_object_unref(installed);
   36.92 +    g_object_unref(helper);
   36.93 +}
   36.94 +
   36.95 +static void test_install_group(void)
   36.96 +{
   36.97 +    gchar *root;
   36.98 +    GError *err=NULL;
   36.99 +    PloverPackageSet *installed;
  36.100 +    PloverTransactionHelper *helper;
  36.101 +    root=g_strdup("razor-test-dir-XXXXXX");
  36.102 +    g_assert(mkdtemp(root));
  36.103 +    g_setenv("RAZOR_ROOT",root,TRUE);
  36.104 +    g_free(root);
  36.105 +    helper=get_transaction_helper();
  36.106 +    installed=plover_package_set_new_from_installed("../razor-test-dir",&err);
  36.107 +    if (!installed)
  36.108 +	g_error("../razor-test-dir: %s",err->message);
  36.109 +    plover_transaction_helper_set_installed(helper,installed);
  36.110 +    g_object_unref(installed);
  36.111 +    plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
  36.112 +    if (!plover_transaction_helper_install_group(helper,"base",&err))
  36.113 +	g_error("base: %s",err->message);
  36.114 +    g_assert(!err);
  36.115 +    g_object_unref(helper);
  36.116 +    g_unsetenv("RAZOR_ROOT");
  36.117 +}
  36.118 +
  36.119 +static void test_remove_group(void)
  36.120 +{
  36.121 +    gchar *root;
  36.122 +    GError *err=NULL;
  36.123 +    PloverPackageSet *installed;
  36.124 +    PloverTransactionHelper *helper;
  36.125 +    struct plover_vector *packages;
  36.126 +    char *pkgs[]={"zip",NULL};
  36.127 +    root=g_strdup("razor-test-dir-XXXXXX");
  36.128 +    g_assert(mkdtemp(root));
  36.129 +    g_setenv("RAZOR_ROOT",root,TRUE);
  36.130 +    helper=get_transaction_helper();
  36.131 +    plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
  36.132 +    packages=plover_transaction_helper_group_get_default_packages(helper,
  36.133 +      "zappy",&err);
  36.134 +    if (!packages)
  36.135 +	g_error("zappy: %s",err->message);
  36.136 +    if (!plover_install("../yum-repo-test-dir",NULL,packages->strings,&err))
  36.137 +	g_error("plover_install: %s",err->message);
  36.138 +    plover_vector_free(packages);
  36.139 +    installed=plover_package_set_new_from_installed(root,&err);
  36.140 +    if (!installed)
  36.141 +	g_error("%s: %s",root,err->message);
  36.142 +    plover_transaction_helper_set_installed(helper,installed);
  36.143 +    g_object_unref(installed);
  36.144 +    if (!plover_transaction_helper_remove_group(helper,"zappy",&err))
  36.145 +	g_error("zappy: %s",err->message);
  36.146 +    g_assert(!err);
  36.147 +    g_object_unref(helper);
  36.148 +    g_unsetenv("RAZOR_ROOT");
  36.149 +    g_free(root);
  36.150 +}
  36.151 +
  36.152 +static void test_update(void)
  36.153 +{
  36.154 +    gchar *root;
  36.155 +    GError *err=NULL;
  36.156 +    PloverPackageSet *installed;
  36.157 +    PloverTransactionHelper *helper;
  36.158 +    root=g_strdup("razor-test-dir-XXXXXX");
  36.159 +    g_assert(mkdtemp(root));
  36.160 +    g_setenv("RAZOR_ROOT",root,TRUE);
  36.161 +    g_free(root);
  36.162 +    helper=get_transaction_helper();
  36.163 +    installed=plover_package_set_new_from_installed("../razor-test-dir",&err);
  36.164 +    if (!installed)
  36.165 +	g_error("../razor-test-dir: %s",err->message);
  36.166 +    plover_transaction_helper_set_installed(helper,installed);
  36.167 +    g_object_unref(installed);
  36.168 +    plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
  36.169 +    if (plover_transaction_helper_update(helper,&err))
  36.170 +	g_error("plover_transaction_helper_update reports work to be done");
  36.171 +    g_assert_error(err,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_NO_WORK);
  36.172 +    g_object_unref(helper);
  36.173 +    g_unsetenv("RAZOR_ROOT");
  36.174 +}
  36.175 +
  36.176 +struct run_install_baton {
  36.177 +    enum {
  36.178 +	RI_STATE_INIT = 0,
  36.179 +	RI_STATE_SUMMARY,
  36.180 +	RI_STATE_PROGRESS,
  36.181 +	RI_STATE_PROGRESS_DELAY,
  36.182 +	RI_STATE_DONE,
  36.183 +	RI_STATE_FINISH
  36.184 +    } state;
  36.185 +    guint eid;		/* event ID (or 0) */
  36.186 +    PloverTransactionHelper *helper;
  36.187 +};
  36.188 +
  36.189 +gboolean run_install_tick(gpointer data)
  36.190 +{
  36.191 +    gboolean retval=TRUE;
  36.192 +    struct run_install_baton *baton=data;
  36.193 +    GtkWidget *page;
  36.194 +    GtkAssistant *assistant=baton->helper->assistant;
  36.195 +    switch(baton->state)
  36.196 +    {
  36.197 +	case RI_STATE_INIT:
  36.198 +	    if (!assistant || !gtk_widget_get_visible(GTK_WIDGET(assistant)))
  36.199 +		return TRUE;
  36.200 +	    if (!manual_mode)
  36.201 +		gtk_button_clicked(GTK_BUTTON(assistant->forward));
  36.202 +	    break;
  36.203 +	case RI_STATE_SUMMARY:
  36.204 +	    if (gtk_assistant_get_current_page(assistant)<1)
  36.205 +		return TRUE;
  36.206 +	    if (!manual_mode)
  36.207 +		gtk_button_clicked(GTK_BUTTON(assistant->apply));
  36.208 +	    break;
  36.209 +	case RI_STATE_PROGRESS:
  36.210 +	    if (gtk_assistant_get_current_page(assistant)<2)
  36.211 +		return TRUE;
  36.212 +	    page=gtk_assistant_get_nth_page(assistant,2);
  36.213 +	    baton->eid=g_timeout_add_seconds(1,run_install_tick,baton);
  36.214 +	    if (!gtk_assistant_get_page_complete(assistant,page))
  36.215 +		return FALSE;
  36.216 +	    else
  36.217 +		retval=FALSE;
  36.218 +	    break;
  36.219 +	case RI_STATE_PROGRESS_DELAY:
  36.220 +	    retval=FALSE;
  36.221 +	    baton->eid=g_idle_add_full(G_PRIORITY_LOW,run_install_tick,baton,
  36.222 +	      NULL);
  36.223 +	    if (!manual_mode)
  36.224 +		gtk_button_clicked(GTK_BUTTON(assistant->forward));
  36.225 +	    break;
  36.226 +	case RI_STATE_DONE:
  36.227 +	    if (gtk_assistant_get_current_page(assistant)<3)
  36.228 +		return TRUE;
  36.229 +	    if (!manual_mode)
  36.230 +		gtk_button_clicked(GTK_BUTTON(assistant->close));
  36.231 +	    break;
  36.232 +	case RI_STATE_FINISH:
  36.233 +	    if (assistant && gtk_widget_get_visible(GTK_WIDGET(assistant)))
  36.234 +		return TRUE;
  36.235 +	    gtk_main_quit();
  36.236 +	    baton->eid=0;
  36.237 +	    return FALSE;
  36.238 +    }
  36.239 +    baton->state++;
  36.240 +    return retval;
  36.241 +}
  36.242 +
  36.243 +static void test_run_install(void)
  36.244 +{
  36.245 +    gchar *root;
  36.246 +    GError *err=NULL;
  36.247 +    struct plover_vector *packages;
  36.248 +    PloverPackageSet *installed;
  36.249 +    PloverTransactionHelper *helper;
  36.250 +    struct run_install_baton baton={0,};
  36.251 +    root=g_strdup("razor-test-dir-XXXXXX");
  36.252 +    g_assert(mkdtemp(root));
  36.253 +    g_setenv("RAZOR_ROOT",root,TRUE);
  36.254 +    helper=get_transaction_helper();
  36.255 +    installed=plover_package_set_new();
  36.256 +    if (!plover_package_set_open(installed,root,TRUE,&err))
  36.257 +	g_error("%s: %s",root,err->message);
  36.258 +    plover_transaction_helper_set_installed(helper,installed);
  36.259 +    g_object_unref(installed);
  36.260 +    plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
  36.261 +    packages=plover_vector_new();
  36.262 +    plover_vector_append(packages,"zappy-tools");
  36.263 +    if (!plover_transaction_helper_install_packages(helper,packages,&err))
  36.264 +	g_error("zappy-tools: %s",err->message);
  36.265 +    g_assert(!err);
  36.266 +    plover_vector_free(packages);
  36.267 +    plover_transaction_helper_present(helper);
  36.268 +    baton.helper=helper;
  36.269 +    baton.eid=g_idle_add_full(G_PRIORITY_LOW,run_install_tick,&baton,NULL);
  36.270 +    gtk_main();
  36.271 +    g_object_unref(helper);
  36.272 +    g_unsetenv("RAZOR_ROOT");
  36.273 +    g_free(root);
  36.274 +}
  36.275 +
  36.276 +struct run_remove_baton {
  36.277 +    enum {
  36.278 +	RR_STATE_INIT = 0,
  36.279 +	RR_STATE_SUMMARY,
  36.280 +	RR_STATE_PROGRESS,
  36.281 +	RR_STATE_PROGRESS_DELAY,
  36.282 +	RR_STATE_DONE,
  36.283 +	RR_STATE_FINISH
  36.284 +    } state;
  36.285 +    guint eid;		/* event ID (or 0) */
  36.286 +    PloverTransactionHelper *helper;
  36.287 +};
  36.288 +
  36.289 +gboolean run_remove_tick(gpointer data)
  36.290 +{
  36.291 +    gboolean retval=TRUE;
  36.292 +    struct run_remove_baton *baton=data;
  36.293 +    GtkWidget *page;
  36.294 +    GtkAssistant *assistant=baton->helper->assistant;
  36.295 +    switch(baton->state)
  36.296 +    {
  36.297 +	case RR_STATE_INIT:
  36.298 +	    if (!assistant || !gtk_widget_get_visible(GTK_WIDGET(assistant)))
  36.299 +		return TRUE;
  36.300 +	    if (!manual_mode)
  36.301 +		gtk_button_clicked(GTK_BUTTON(assistant->forward));
  36.302 +	    break;
  36.303 +	case RR_STATE_SUMMARY:
  36.304 +	    if (gtk_assistant_get_current_page(assistant)<1)
  36.305 +		return TRUE;
  36.306 +	    if (!manual_mode)
  36.307 +		gtk_button_clicked(GTK_BUTTON(assistant->apply));
  36.308 +	    break;
  36.309 +	case RR_STATE_PROGRESS:
  36.310 +	    if (gtk_assistant_get_current_page(assistant)<2)
  36.311 +		return TRUE;
  36.312 +	    page=gtk_assistant_get_nth_page(assistant,2);
  36.313 +	    baton->eid=g_timeout_add_seconds(1,run_remove_tick,baton);
  36.314 +	    if (!gtk_assistant_get_page_complete(assistant,page))
  36.315 +		return FALSE;
  36.316 +	    else
  36.317 +		retval=FALSE;
  36.318 +	    break;
  36.319 +	case RR_STATE_PROGRESS_DELAY:
  36.320 +	    retval=FALSE;
  36.321 +	    baton->eid=g_idle_add_full(G_PRIORITY_LOW,run_remove_tick,baton,
  36.322 +	      NULL);
  36.323 +	    if (!manual_mode)
  36.324 +		gtk_button_clicked(GTK_BUTTON(assistant->forward));
  36.325 +	    break;
  36.326 +	case RR_STATE_DONE:
  36.327 +	    if (gtk_assistant_get_current_page(assistant)<3)
  36.328 +		return TRUE;
  36.329 +	    if (!manual_mode)
  36.330 +		gtk_button_clicked(GTK_BUTTON(assistant->close));
  36.331 +	    break;
  36.332 +	case RR_STATE_FINISH:
  36.333 +	    if (assistant && gtk_widget_get_visible(GTK_WIDGET(assistant)))
  36.334 +		return TRUE;
  36.335 +	    gtk_main_quit();
  36.336 +	    baton->eid=0;
  36.337 +	    return FALSE;
  36.338 +    }
  36.339 +    baton->state++;
  36.340 +    return retval;
  36.341 +}
  36.342 +
  36.343 +static void test_run_remove(void)
  36.344 +{
  36.345 +    gchar *root;
  36.346 +    GError *err=NULL;
  36.347 +    struct plover_vector *packages;
  36.348 +    PloverPackageSet *installed;
  36.349 +    PloverTransactionHelper *helper;
  36.350 +    struct run_remove_baton baton={0,};
  36.351 +    root=g_strdup("razor-test-dir-XXXXXX");
  36.352 +    g_assert(mkdtemp(root));
  36.353 +    g_setenv("RAZOR_ROOT",root,TRUE);
  36.354 +    helper=get_transaction_helper();
  36.355 +    plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
  36.356 +    packages=
  36.357 +      plover_transaction_helper_group_get_default_packages(helper,"zappy",&err);
  36.358 +    if (!packages)
  36.359 +	g_error("zappy: %s",err->message);
  36.360 +    if (!plover_install("../yum-repo-test-dir",NULL,packages->strings,&err))
  36.361 +	g_error("plover_install: %s",err->message);
  36.362 +    plover_vector_free(packages);
  36.363 +    installed=plover_package_set_new();
  36.364 +    if (!plover_package_set_open(installed,root,TRUE,&err))
  36.365 +	g_error("%s: %s",root,err->message);
  36.366 +    plover_transaction_helper_set_installed(helper,installed);
  36.367 +    g_object_unref(installed);
  36.368 +    if (!plover_transaction_helper_remove_group(helper,"zappy",&err))
  36.369 +	g_error("zappy: %s",err->message);
  36.370 +    g_assert(!err);
  36.371 +    plover_transaction_helper_present(helper);
  36.372 +    baton.helper=helper;
  36.373 +    baton.eid=g_idle_add_full(G_PRIORITY_LOW,run_remove_tick,&baton,NULL);
  36.374 +    gtk_main();
  36.375 +    g_object_unref(helper);
  36.376 +    g_unsetenv("RAZOR_ROOT");
  36.377 +    g_free(root);
  36.378 +}
  36.379 +
  36.380 +struct run_update_baton {
  36.381 +    enum {
  36.382 +	RU_STATE_INIT = 0,
  36.383 +	RU_STATE_SUMMARY,
  36.384 +	RU_STATE_PROGRESS,
  36.385 +	RU_STATE_PROGRESS_DELAY,
  36.386 +	RU_STATE_DONE,
  36.387 +	RU_STATE_FINISH
  36.388 +    } state;
  36.389 +    guint eid;		/* event ID (or 0) */
  36.390 +    PloverTransactionHelper *helper;
  36.391 +};
  36.392 +
  36.393 +gboolean run_update_tick(gpointer data)
  36.394 +{
  36.395 +    gboolean retval=TRUE;
  36.396 +    struct run_update_baton *baton=data;
  36.397 +    GtkWidget *page;
  36.398 +    GtkAssistant *assistant=baton->helper->assistant;
  36.399 +    switch(baton->state)
  36.400 +    {
  36.401 +	case RU_STATE_INIT:
  36.402 +	    if (!assistant || !gtk_widget_get_visible(GTK_WIDGET(assistant)))
  36.403 +		return TRUE;
  36.404 +	    if (!manual_mode)
  36.405 +		gtk_button_clicked(GTK_BUTTON(assistant->forward));
  36.406 +	    break;
  36.407 +	case RU_STATE_SUMMARY:
  36.408 +	    if (gtk_assistant_get_current_page(assistant)<1)
  36.409 +		return TRUE;
  36.410 +	    if (!manual_mode)
  36.411 +		gtk_button_clicked(GTK_BUTTON(assistant->apply));
  36.412 +	    break;
  36.413 +	case RU_STATE_PROGRESS:
  36.414 +	    if (gtk_assistant_get_current_page(assistant)<2)
  36.415 +		return TRUE;
  36.416 +	    page=gtk_assistant_get_nth_page(assistant,2);
  36.417 +	    baton->eid=g_timeout_add_seconds(1,run_update_tick,baton);
  36.418 +	    if (!gtk_assistant_get_page_complete(assistant,page))
  36.419 +		return FALSE;
  36.420 +	    else
  36.421 +		retval=FALSE;
  36.422 +	    break;
  36.423 +	case RU_STATE_PROGRESS_DELAY:
  36.424 +	    retval=FALSE;
  36.425 +	    baton->eid=g_idle_add_full(G_PRIORITY_LOW,run_update_tick,baton,
  36.426 +	      NULL);
  36.427 +	    if (!manual_mode)
  36.428 +		gtk_button_clicked(GTK_BUTTON(assistant->forward));
  36.429 +	    break;
  36.430 +	case RU_STATE_DONE:
  36.431 +	    if (gtk_assistant_get_current_page(assistant)<3)
  36.432 +		return TRUE;
  36.433 +	    if (!manual_mode)
  36.434 +		gtk_button_clicked(GTK_BUTTON(assistant->close));
  36.435 +	    break;
  36.436 +	case RU_STATE_FINISH:
  36.437 +	    if (assistant && gtk_widget_get_visible(GTK_WIDGET(assistant)))
  36.438 +		return TRUE;
  36.439 +	    gtk_main_quit();
  36.440 +	    baton->eid=0;
  36.441 +	    return FALSE;
  36.442 +    }
  36.443 +    baton->state++;
  36.444 +    return retval;
  36.445 +}
  36.446 +
  36.447 +static void test_run_update(void)
  36.448 +{
  36.449 +    gchar *root;
  36.450 +    GError *err=NULL;
  36.451 +    struct razor_importer *importer;
  36.452 +    struct razor_set *downgraded;
  36.453 +    struct razor_atomic *atomic;
  36.454 +    struct plover_vector *packages;
  36.455 +    PloverPackageSet *installed;
  36.456 +    PloverTransactionHelper *helper;
  36.457 +    struct run_update_baton baton={0,};
  36.458 +    root=g_strdup("razor-test-dir-XXXXXX");
  36.459 +    g_assert(mkdtemp(root));
  36.460 +    g_setenv("RAZOR_ROOT",root,TRUE);
  36.461 +    helper=get_transaction_helper();
  36.462 +    plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
  36.463 +    installed=plover_package_set_new();
  36.464 +    if (!plover_package_set_open(installed,root,TRUE,&err))
  36.465 +	g_error("%s: %s",root,err->message);
  36.466 +    importer=razor_importer_create();
  36.467 +    razor_importer_begin_package(importer,"zappy","0-1","noarch");
  36.468 +    razor_importer_add_details(importer,"","","","");
  36.469 +    razor_importer_add_property(importer,"zappy",RAZOR_PROPERTY_PROVIDES,"0-1");
  36.470 +    razor_importer_finish_package(importer);
  36.471 +    downgraded=razor_importer_finish(importer);
  36.472 +    atomic=razor_atomic_open("Add downgraded packages");
  36.473 +    if (!plover_package_set_update(installed,downgraded,atomic) ||
  36.474 +      razor_atomic_commit(atomic))
  36.475 +	g_error("%s: %s",root,razor_atomic_get_error_msg(atomic));
  36.476 +    razor_atomic_destroy(atomic);
  36.477 +    razor_set_unref(downgraded);
  36.478 +    plover_transaction_helper_set_installed(helper,installed);
  36.479 +    g_object_unref(installed);
  36.480 +    if (!plover_transaction_helper_update(helper,&err))
  36.481 +	g_error("update: %s",err->message);
  36.482 +    g_assert(!err);
  36.483 +    plover_transaction_helper_present(helper);
  36.484 +    baton.helper=helper;
  36.485 +    baton.eid=g_idle_add_full(G_PRIORITY_LOW,run_update_tick,&baton,NULL);
  36.486 +    gtk_main();
  36.487 +    g_object_unref(helper);
  36.488 +    g_unsetenv("RAZOR_ROOT");
  36.489 +    g_free(root);
  36.490 +}
  36.491 +
  36.492 +struct check_vendor_baton {
  36.493 +    enum {
  36.494 +	CV_STATE_INIT = 0,
  36.495 +	CV_STATE_SUMMARY,
  36.496 +	CV_STATE_PROGRESS,
  36.497 +	CV_STATE_PROGRESS_DELAY,
  36.498 +	CV_STATE_DONE,
  36.499 +	CV_STATE_FINISH
  36.500 +    } state;
  36.501 +    guint eid;		/* event ID (or 0) */
  36.502 +    PloverTransactionHelper *helper;
  36.503 +};
  36.504 +
  36.505 +gboolean check_vendor_tick(gpointer data)
  36.506 +{
  36.507 +    gboolean retval=TRUE;
  36.508 +    struct check_vendor_baton *baton=data;
  36.509 +    GtkWidget *page,*w;
  36.510 +    GtkAssistant *assistant=baton->helper->assistant;
  36.511 +    switch(baton->state)
  36.512 +    {
  36.513 +	case CV_STATE_INIT:
  36.514 +	    if (!assistant || !gtk_widget_get_visible(GTK_WIDGET(assistant)))
  36.515 +		return TRUE;
  36.516 +	    if (!manual_mode)
  36.517 +		gtk_button_clicked(GTK_BUTTON(assistant->forward));
  36.518 +	    break;
  36.519 +	case CV_STATE_SUMMARY:
  36.520 +	    if (gtk_assistant_get_current_page(assistant)<1)
  36.521 +		return TRUE;
  36.522 +	    g_assert(!gtk_widget_is_sensitive(assistant->apply));
  36.523 +	    w=GTK_WIDGET(gtk_builder_get_object(ui,"SIRemoveExisting"));
  36.524 +	    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),TRUE);
  36.525 +	    g_assert(gtk_widget_is_sensitive(assistant->apply));
  36.526 +	    if (!manual_mode)
  36.527 +		gtk_button_clicked(GTK_BUTTON(assistant->apply));
  36.528 +	    break;
  36.529 +	case CV_STATE_PROGRESS:
  36.530 +	    if (gtk_assistant_get_current_page(assistant)<2)
  36.531 +		return TRUE;
  36.532 +	    page=gtk_assistant_get_nth_page(assistant,2);
  36.533 +	    baton->eid=g_timeout_add_seconds(1,check_vendor_tick,baton);
  36.534 +	    if (!gtk_assistant_get_page_complete(assistant,page))
  36.535 +		return FALSE;
  36.536 +	    else
  36.537 +		retval=FALSE;
  36.538 +	    break;
  36.539 +	case CV_STATE_PROGRESS_DELAY:
  36.540 +	    retval=FALSE;
  36.541 +	    baton->eid=g_idle_add_full(G_PRIORITY_LOW,check_vendor_tick,baton,
  36.542 +	      NULL);
  36.543 +	    if (!manual_mode)
  36.544 +		gtk_button_clicked(GTK_BUTTON(assistant->forward));
  36.545 +	    break;
  36.546 +	case CV_STATE_DONE:
  36.547 +	    if (gtk_assistant_get_current_page(assistant)<3)
  36.548 +		return TRUE;
  36.549 +	    if (!manual_mode)
  36.550 +		gtk_button_clicked(GTK_BUTTON(assistant->close));
  36.551 +	    break;
  36.552 +	case CV_STATE_FINISH:
  36.553 +	    if (assistant && gtk_widget_get_visible(GTK_WIDGET(assistant)))
  36.554 +		return TRUE;
  36.555 +	    gtk_main_quit();
  36.556 +	    baton->eid=0;
  36.557 +	    return FALSE;
  36.558 +    }
  36.559 +    baton->state++;
  36.560 +    return retval;
  36.561 +}
  36.562 +
  36.563 +static void test_check_vendor(void)
  36.564 +{
  36.565 +    int fh;
  36.566 +    gchar *root,*s;
  36.567 +    GError *err=NULL;
  36.568 +    struct razor_importer *importer;
  36.569 +    struct razor_set *downgraded;
  36.570 +    struct razor_atomic *atomic;
  36.571 +    struct plover_vector *packages;
  36.572 +    PloverPackageSet *installed;
  36.573 +    PloverTransactionHelper *helper;
  36.574 +    struct run_update_baton baton={0,};
  36.575 +    g_setenv("PLOVER_VENDOR_PREFIX","/srv",TRUE);
  36.576 +    root=g_strdup("razor-test-dir-XXXXXX");
  36.577 +    g_assert(mkdtemp(root));
  36.578 +    g_setenv("RAZOR_ROOT",root,TRUE);
  36.579 +    helper=get_transaction_helper();
  36.580 +    plover_transaction_helper_set_check_vendor(helper,TRUE);
  36.581 +    plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
  36.582 +    installed=plover_package_set_new();
  36.583 +    if (!plover_package_set_open(installed,root,TRUE,&err))
  36.584 +	g_error("%s: %s",root,err->message);
  36.585 +    importer=razor_importer_create();
  36.586 +    razor_importer_begin_package(importer,"zappy","0-1","noarch");
  36.587 +    razor_importer_add_details(importer,"","","","");
  36.588 +    razor_importer_add_property(importer,"zappy",RAZOR_PROPERTY_PROVIDES,"0-1");
  36.589 +    razor_importer_add_install_prefix(importer,"/test");
  36.590 +    razor_importer_add_file(importer,"/test/bin/zappy");
  36.591 +    razor_importer_finish_package(importer);
  36.592 +    downgraded=razor_importer_finish(importer);
  36.593 +    atomic=razor_atomic_open("Add downgraded packages");
  36.594 +    razor_atomic_make_dirs(atomic,root,"/test/bin/zappy");
  36.595 +    s=g_build_filename(root,"test/bin/zappy",NULL);
  36.596 +    fh=razor_atomic_create_file(atomic,s,S_IRWXU|S_IRWXG|S_IRWXO);
  36.597 +    g_free(s);
  36.598 +    razor_atomic_close(atomic,fh);
  36.599 +    if (!plover_package_set_update(installed,downgraded,atomic) ||
  36.600 +      razor_atomic_commit(atomic))
  36.601 +	g_error("%s: %s",root,razor_atomic_get_error_msg(atomic));
  36.602 +    razor_atomic_destroy(atomic);
  36.603 +    razor_set_unref(downgraded);
  36.604 +    plover_transaction_helper_set_installed(helper,installed);
  36.605 +    g_object_unref(installed);
  36.606 +    if (!plover_transaction_helper_update(helper,&err))
  36.607 +	g_error("update: %s",err->message);
  36.608 +    g_assert(!err);
  36.609 +    plover_transaction_helper_present(helper);
  36.610 +    baton.helper=helper;
  36.611 +    baton.eid=g_idle_add_full(G_PRIORITY_LOW,check_vendor_tick,&baton,NULL);
  36.612 +    gtk_main();
  36.613 +    g_object_unref(helper);
  36.614 +    g_unsetenv("RAZOR_ROOT");
  36.615 +    g_free(root);
  36.616 +    g_unsetenv("PLOVER_VENDOR_PREFIX");
  36.617 +}
  36.618 +
  36.619 +struct set_error_baton {
  36.620 +    enum {
  36.621 +	SE_STATE_INIT = 0,
  36.622 +	SE_STATE_FINISH
  36.623 +    } state;
  36.624 +    PloverTransactionHelper *helper;
  36.625 +};
  36.626 +
  36.627 +/*
  36.628 + * This handler may be called as either an event (ie., idle or timeout)
  36.629 + * or as a (swapped) signal. In the latter case, the return is ignored.
  36.630 + */
  36.631 +gboolean set_error_tick(gpointer data)
  36.632 +{
  36.633 +    struct set_error_baton *baton=data;
  36.634 +    GtkDialog *dlg;
  36.635 +    GtkWidget *button;
  36.636 +    dlg=GTK_DIALOG(baton->helper->error_dialog);
  36.637 +    switch(baton->state)
  36.638 +    {
  36.639 +	case SE_STATE_INIT:
  36.640 +	    if (!dlg || !gtk_widget_get_visible(GTK_WIDGET(dlg)))
  36.641 +		return TRUE;
  36.642 +	    button=gtk_dialog_get_widget_for_response(dlg,GTK_RESPONSE_CLOSE);
  36.643 +	    if (!manual_mode)
  36.644 +		gtk_button_clicked(GTK_BUTTON(button));
  36.645 +	    break;
  36.646 +	case SE_STATE_FINISH:
  36.647 +	    if (dlg && gtk_widget_get_visible(GTK_WIDGET(dlg)))
  36.648 +		return TRUE;
  36.649 +	    gtk_main_quit();
  36.650 +	    return FALSE;
  36.651 +    }
  36.652 +    baton->state++;
  36.653 +    return TRUE;
  36.654 +}
  36.655 +
  36.656 +static void test_set_error(void)
  36.657 +{
  36.658 +    gchar *root;
  36.659 +    const char *errmsg;
  36.660 +    GError *err=NULL;
  36.661 +    const GError *err2=NULL;
  36.662 +    PloverPackageSet *installed;
  36.663 +    PloverTransactionHelper *helper;
  36.664 +    struct set_error_baton baton={0,};
  36.665 +    root=g_strdup("razor-test-dir-XXXXXX");
  36.666 +    g_assert(mkdtemp(root));
  36.667 +    g_setenv("RAZOR_ROOT",root,TRUE);
  36.668 +    g_free(root);
  36.669 +    helper=get_transaction_helper();
  36.670 +    installed=plover_package_set_new_from_installed("../razor-test-dir",&err);
  36.671 +    if (!installed)
  36.672 +	g_error("../razor-test-dir: %s",err->message);
  36.673 +    plover_transaction_helper_set_installed(helper,installed);
  36.674 +    g_object_unref(installed);
  36.675 +    plover_transaction_helper_set_base(helper,"../yum-repo-test-dir");
  36.676 +    if (!plover_transaction_helper_update(helper,&err))
  36.677 +	plover_transaction_helper_set_error(helper,err,"Expected error");
  36.678 +    g_assert(plover_transaction_helper_get_visible(helper));
  36.679 +    errmsg=plover_transaction_helper_get_error(helper,&err2);
  36.680 +    g_assert_cmpstr(errmsg,==,"Expected error");
  36.681 +    g_assert_error(err2,err->domain,err->code);
  36.682 +    plover_transaction_helper_present(helper);
  36.683 +    baton.helper=helper;
  36.684 +    g_idle_add_full(G_PRIORITY_LOW,set_error_tick,&baton,NULL);
  36.685 +    g_error_free(err);
  36.686 +    gtk_main();
  36.687 +    g_object_unref(helper);
  36.688 +    g_unsetenv("RAZOR_ROOT");
  36.689 +}
  36.690 +
  36.691 +int main(int argc,char **argv)
  36.692 +{
  36.693 +    int retval;
  36.694 +    GError *err=NULL;
  36.695 +    /*
  36.696 +     * Note that because g_test_init() handles --help,
  36.697 +     * these options will not appear in the output.
  36.698 +     */
  36.699 +    GOptionEntry options[]={
  36.700 +	{"manual",0,0,G_OPTION_ARG_NONE,&manual_mode,
  36.701 +	  "Disable automatic mode",NULL},
  36.702 +	{NULL}
  36.703 +    };
  36.704 +    g_test_init(&argc,&argv,NULL);
  36.705 +    g_setenv("GTK_MODULES","",TRUE);
  36.706 +    g_setenv("GTK2_RC_FILES","/dev/null",TRUE);
  36.707 +    gtk_disable_setlocale();
  36.708 +    setlocale(LC_ALL,"C");
  36.709 +    g_test_bug_base("mailto:ali@juiblex.co.uk");
  36.710 +    if (!gtk_init_with_args(&argc,&argv,NULL,options,NULL,&err))
  36.711 +    {
  36.712 +	g_printf("%s\n",err->message);
  36.713 +	exit(0);
  36.714 +    }
  36.715 +    g_test_add_func("/transactionhelper/init",test_init);
  36.716 +    g_test_add_func("/transactionhelper/basic-properties",
  36.717 +      test_basic_properties);
  36.718 +    g_test_add_func("/transactionhelper/install-group",test_install_group);
  36.719 +    g_test_add_func("/transactionhelper/remove-group",test_remove_group);
  36.720 +    g_test_add_func("/transactionhelper/update",test_update);
  36.721 +    g_test_add_func("/transactionhelper/run-install",test_run_install);
  36.722 +    g_test_add_func("/transactionhelper/run-remove",test_run_remove);
  36.723 +    g_test_add_func("/transactionhelper/run-update",test_run_update);
  36.724 +    g_test_add_func("/transactionhelper/check-vendor",test_check_vendor);
  36.725 +    g_test_add_func("/transactionhelper/set-error",test_set_error);
  36.726 +    retval=g_test_run();
  36.727 +    return retval;
  36.728 +}
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/tests/plover-gtk/treemodel.c	Mon Jun 13 12:18:42 2016 +0100
    37.3 @@ -0,0 +1,159 @@
    37.4 +/*
    37.5 + * Copyright (C) 2011, 2016  J. Ali Harlow <ali@juiblex.co.uk>
    37.6 + *
    37.7 + * This program is free software; you can redistribute it and/or modify
    37.8 + * it under the terms of the GNU General Public License as published by
    37.9 + * the Free Software Foundation; either version 2 of the License, or
   37.10 + * (at your option) any later version.
   37.11 + *
   37.12 + * This program is distributed in the hope that it will be useful,
   37.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   37.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   37.15 + * GNU General Public License for more details.
   37.16 + *
   37.17 + * You should have received a copy of the GNU General Public License along
   37.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
   37.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   37.20 + */
   37.21 +
   37.22 +#include <stdlib.h>
   37.23 +#include <string.h>
   37.24 +#include <glib.h>
   37.25 +#include <gtk/gtk.h>
   37.26 +
   37.27 +static void test_tree_model_iter(GtkTreeModel *model,GtkTreeIter *iter)
   37.28 +{
   37.29 +    GtkTreePath *path,*path2;
   37.30 +    GtkTreeIter iter2,child;
   37.31 +    gchar *string,*string2,*s;
   37.32 +    int i,n;
   37.33 +    if (iter)   /* Not all tests make sense on the virtual root */
   37.34 +    {
   37.35 +	/* Check we can convert to a path and back */
   37.36 +	path=gtk_tree_model_get_path(model,iter);
   37.37 +	g_assert(path!=NULL);
   37.38 +	g_assert(gtk_tree_model_get_iter(model,&iter2,path));
   37.39 +	path2=gtk_tree_model_get_path(model,&iter2);
   37.40 +	g_assert(path2!=NULL);
   37.41 +	g_assert(gtk_tree_path_compare(path,path2)==0);
   37.42 +	gtk_tree_path_free(path2);
   37.43 +	/* Check we can convert to a path string and back */
   37.44 +	string=gtk_tree_model_get_string_from_iter(model,iter);
   37.45 +	g_assert(string!=NULL);
   37.46 +	g_assert(gtk_tree_model_get_iter_from_string(model,&iter2,string));
   37.47 +	string2=gtk_tree_model_get_string_from_iter(model,&iter2);
   37.48 +	g_assert(string2!=NULL);
   37.49 +	g_assert(strcmp(string,string2)==0);
   37.50 +	g_free(string2);
   37.51 +    }
   37.52 +    else
   37.53 +    {
   37.54 +	path=NULL;
   37.55 +	string=NULL;
   37.56 +    }
   37.57 +    if (string)
   37.58 +	g_debug("Checking iter %s",string);
   37.59 +    else
   37.60 +	g_debug("Checking virtual root iter");
   37.61 +    n=gtk_tree_model_iter_n_children(model,iter);
   37.62 +    g_assert(n>=0);
   37.63 +    if (n>0)
   37.64 +    {
   37.65 +	/* Check that GTK_TREE_MODEL_LIST_ONLY is not set inappropriately */
   37.66 +	if (iter)
   37.67 +	{
   37.68 +	    gboolean list_only_with_grandchildren;
   37.69 +	    list_only_with_grandchildren=
   37.70 +	      gtk_tree_model_get_flags(model)&GTK_TREE_MODEL_LIST_ONLY;
   37.71 +	    g_assert(!list_only_with_grandchildren);
   37.72 +	}
   37.73 +	/* Check that gtk_tree_model_iter_has_child() agrees */
   37.74 +	if (iter)
   37.75 +	    g_assert(gtk_tree_model_iter_has_child(model,iter));
   37.76 +	/* Check that gtk_tree_model_iter_children() returns the first child */
   37.77 +	g_assert(gtk_tree_model_iter_children(model,&child,iter));
   37.78 +	string2=gtk_tree_model_get_string_from_iter(model,&child);
   37.79 +	g_assert(string2!=NULL);
   37.80 +	if (string)
   37.81 +	{
   37.82 +	    g_assert(g_str_has_prefix(string2,string));
   37.83 +	    g_assert(strlen(string2)==strlen(string)+2);
   37.84 +	    g_assert(g_str_has_suffix(string2,":0"));
   37.85 +	}
   37.86 +	else
   37.87 +	    g_assert(strcmp(string2,"0")==0);
   37.88 +	g_free(string2);
   37.89 +	for(i=0;i<n;i++)
   37.90 +	{
   37.91 +	    /*
   37.92 +	     * Check that gtk_tree_model_iter_nth_child() returns the nth child
   37.93 +	     */
   37.94 +	    g_assert(gtk_tree_model_iter_nth_child(model,&child,iter,i));
   37.95 +	    string2=gtk_tree_model_get_string_from_iter(model,&child);
   37.96 +	    g_assert(string2!=NULL);
   37.97 +	    if (string)
   37.98 +		s=g_strdup_printf("%s:%d",string,i);
   37.99 +	    else
  37.100 +		s=g_strdup_printf("%d",i);
  37.101 +	    g_assert(strcmp(string2,s)==0);
  37.102 +	    g_free(s);
  37.103 +	    g_free(string2);
  37.104 +	    /* Check that my son's father is me */
  37.105 +	    if (iter)
  37.106 +	    {
  37.107 +		g_assert(gtk_tree_model_iter_parent(model,&iter2,&child));
  37.108 +		string2=gtk_tree_model_get_string_from_iter(model,&iter2);
  37.109 +		g_assert(strcmp(string,string2)==0);
  37.110 +		g_free(string2);
  37.111 +	    }
  37.112 +	    else
  37.113 +		g_assert(!gtk_tree_model_iter_parent(model,&iter2,&child));
  37.114 +	    /* Check next sibling */
  37.115 +	    if (i+1<n)
  37.116 +	    {
  37.117 +		iter2=child;
  37.118 +		g_assert(gtk_tree_model_iter_next(model,&iter2));
  37.119 +		string2=gtk_tree_model_get_string_from_iter(model,&iter2);
  37.120 +		g_assert(string2!=NULL);
  37.121 +		if (string)
  37.122 +		s=g_strdup_printf("%s:%d",string,i+1);
  37.123 +		    else
  37.124 +		s=g_strdup_printf("%d",i+1);
  37.125 +		g_assert(strcmp(string2,s)==0);
  37.126 +		g_free(s);
  37.127 +		g_free(string2);
  37.128 +	    }
  37.129 +	    else
  37.130 +	    {
  37.131 +		iter2=child;
  37.132 +		g_assert(!gtk_tree_model_iter_next(model,&iter2));
  37.133 +	    }
  37.134 +	    /* Check child */
  37.135 +	    test_tree_model_iter(model,&child);
  37.136 +	}
  37.137 +	/*
  37.138 +	 * Check that gtk_tree_model_iter_nth_child() returns no more children
  37.139 +	 */
  37.140 +	g_assert(!gtk_tree_model_iter_nth_child(model,&child,iter,n));
  37.141 +    }
  37.142 +    else
  37.143 +    {
  37.144 +	/* Check that all APIs agree that iter has no children */
  37.145 +	if (iter)
  37.146 +	    g_assert(!gtk_tree_model_iter_has_child(model,iter));
  37.147 +	g_assert(!gtk_tree_model_iter_children(model,&child,iter));
  37.148 +	g_assert(!gtk_tree_model_iter_nth_child(model,&child,iter,0));
  37.149 +    }
  37.150 +    gtk_tree_path_free(path);
  37.151 +    g_free(string);
  37.152 +}
  37.153 +
  37.154 +void test_tree_model(GtkTreeModel *model)
  37.155 +{
  37.156 +    GtkTreeModelFlags undefined_flags;
  37.157 +    undefined_flags=gtk_tree_model_get_flags(model);
  37.158 +    undefined_flags&=~GTK_TREE_MODEL_ITERS_PERSIST;
  37.159 +    undefined_flags&=~GTK_TREE_MODEL_LIST_ONLY;
  37.160 +    g_assert(!undefined_flags);
  37.161 +    test_tree_model_iter(model,NULL);
  37.162 +}
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/tests/plover-gtk/treemodel.h	Mon Jun 13 12:18:42 2016 +0100
    38.3 @@ -0,0 +1,3 @@
    38.4 +#include <gtk/gtk.h>
    38.5 +
    38.6 +void test_tree_model(GtkTreeModel *model);
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/tests/plover/Makefile.am	Mon Jun 13 12:18:42 2016 +0100
    39.3 @@ -0,0 +1,25 @@
    39.4 +AM_CFLAGS=-g $(LIBPLOVER_CFLAGS)
    39.5 +INCLUDES=-I$(top_srcdir)
    39.6 +LDADD=../../plover/libplover.la $(LIBPLOVER_LIBS)
    39.7 +
    39.8 +if HAVE_CHECK_TOOLS
    39.9 +
   39.10 +TESTS = $(test_programs)
   39.11 +TESTS_ENVIRONMENT = tests_srcdir="$(top_srcdir)/tests"
   39.12 +
   39.13 +check_PROGRAMS = $(test_programs)
   39.14 +
   39.15 +test_programs = test-import-yum test-package test-repository test-packageset \
   39.16 +	test-transaction test-comps test-log test-util test-razor test-vector \
   39.17 +	test-exception-handler
   39.18 +
   39.19 +test_transaction_LDADD = $(LDADD) $(LUA_POSIX_LIBS)
   39.20 +test_razor_LDADD = $(LDADD) $(LUA_POSIX_LIBS)
   39.21 +
   39.22 +endif
   39.23 +
   39.24 +@VALGRIND_CHECK_RULES@
   39.25 +VALGRIND_SUPPRESSIONS_FILES = ../glib.supp
   39.26 +
   39.27 +clean-local:
   39.28 +	rm -rf test-log-rotate razor-test-dir-*
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/tests/plover/test-comps.c	Mon Jun 13 12:18:42 2016 +0100
    40.3 @@ -0,0 +1,56 @@
    40.4 +/*
    40.5 + * Copyright (C) 2016  J. Ali Harlow <ali@juiblex.co.uk>
    40.6 + *
    40.7 + * This program is free software; you can redistribute it and/or modify
    40.8 + * it under the terms of the GNU General Public License as published by
    40.9 + * the Free Software Foundation; either version 2 of the License, or
   40.10 + * (at your option) any later version.
   40.11 + *
   40.12 + * This program is distributed in the hope that it will be useful,
   40.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   40.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   40.15 + * GNU General Public License for more details.
   40.16 + *
   40.17 + * You should have received a copy of the GNU General Public License along
   40.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
   40.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   40.20 + */
   40.21 +
   40.22 +#include <stdlib.h>
   40.23 +#include <razor.h>
   40.24 +#include <plover/plover.h>
   40.25 +
   40.26 +static void test_basic(void)
   40.27 +{
   40.28 +    struct comps *comps;
   40.29 +    comps=plover_comps_new();
   40.30 +    g_assert(comps);
   40.31 +    plover_comps_free(comps);
   40.32 +}
   40.33 +
   40.34 +static void test_from_file(void)
   40.35 +{
   40.36 +    struct comps *comps;
   40.37 +    struct comps_group *group;
   40.38 +    gchar *s;
   40.39 +    s=g_build_filename(g_getenv("tests_srcdir"),"comps.xml",NULL);
   40.40 +    comps=plover_comps_new_from_file(s);
   40.41 +    if (!comps)
   40.42 +	g_error("%s: Failed to read components",s);
   40.43 +    g_free(s);
   40.44 +    group=plover_comps_lookup_group(comps,"base");
   40.45 +    g_assert(group);
   40.46 +    g_assert(!plover_comps_lookup_group(comps,"nonexistant"));
   40.47 +    plover_comps_free(comps);
   40.48 +}
   40.49 +
   40.50 +int main(int argc,char **argv)
   40.51 +{
   40.52 +    int retval;
   40.53 +    g_test_init(&argc,&argv,NULL);
   40.54 +    g_test_bug_base("mailto:ali@juiblex.co.uk");
   40.55 +    g_test_add_func("/comps/basic",test_basic);
   40.56 +    g_test_add_func("/comps/from-file",test_from_file);
   40.57 +    retval=g_test_run();
   40.58 +    return retval;
   40.59 +}
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/tests/plover/test-exception-handler.c	Mon Jun 13 12:18:42 2016 +0100
    41.3 @@ -0,0 +1,37 @@
    41.4 +/*
    41.5 + * Copyright (C) 2016  J. Ali Harlow <ali@juiblex.co.uk>
    41.6 + *
    41.7 + * This program is free software; you can redistribute it and/or modify
    41.8 + * it under the terms of the GNU General Public License as published by
    41.9 + * the Free Software Foundation; either version 2 of the License, or
   41.10 + * (at your option) any later version.
   41.11 + *
   41.12 + * This program is distributed in the hope that it will be useful,
   41.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   41.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   41.15 + * GNU General Public License for more details.
   41.16 + *
   41.17 + * You should have received a copy of the GNU General Public License along
   41.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
   41.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   41.20 + */
   41.21 +
   41.22 +#include <stdlib.h>
   41.23 +#include <glib.h>
   41.24 +#include <razor.h>
   41.25 +#include <plover/plover.h>
   41.26 +
   41.27 +static void test_init(void)
   41.28 +{
   41.29 +    plover_exception_handler_init();
   41.30 +}
   41.31 +
   41.32 +int main(int argc,char **argv)
   41.33 +{
   41.34 +    int retval;
   41.35 +    g_test_init(&argc,&argv,NULL);
   41.36 +    g_test_bug_base("mailto:ali@juiblex.co.uk");
   41.37 +    g_test_add_func("/exception-handler/init",test_init);
   41.38 +    retval=g_test_run();
   41.39 +    return retval;
   41.40 +}
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/tests/plover/test-import-yum.c	Mon Jun 13 12:18:42 2016 +0100
    42.3 @@ -0,0 +1,70 @@
    42.4 +/*
    42.5 + * Copyright (C) 2016  J. Ali Harlow <ali@juiblex.co.uk>
    42.6 + *
    42.7 + * This program is free software; you can redistribute it and/or modify
    42.8 + * it under the terms of the GNU General Public License as published by
    42.9 + * the Free Software Foundation; either version 2 of the License, or
   42.10 + * (at your option) any later version.
   42.11 + *
   42.12 + * This program is distributed in the hope that it will be useful,
   42.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   42.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   42.15 + * GNU General Public License for more details.
   42.16 + *
   42.17 + * You should have received a copy of the GNU General Public License along
   42.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
   42.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   42.20 + */
   42.21 +
   42.22 +#include <stdlib.h>
   42.23 +#include <glib.h>
   42.24 +#include <razor.h>
   42.25 +#include <plover/plover.h>
   42.26 +
   42.27 +const char *yum_packages[]={
   42.28 +    "zsh","zsh2","zip","zap","filesystem","zappy","zappy-tools","zappy2",
   42.29 +    "unsatisfiable","uninstallable","badpostun"
   42.30 +};
   42.31 +
   42.32 +static void test_basic_import(void)
   42.33 +{
   42.34 +    int i;
   42.35 +    struct razor_set *set;
   42.36 +    struct razor_package_iterator *iter;
   42.37 +    struct razor_package *package;
   42.38 +    const char *name;
   42.39 +    GList *expected=NULL,*lnk;
   42.40 +    GError *err=NULL;
   42.41 +    set=plover_razor_set_create_from_yum("../yum-repo-test-dir",&err);
   42.42 +    if (!set && err)
   42.43 +	g_error("../yum-repo-test-dir: %s",err->message);
   42.44 +    g_assert(set != NULL);
   42.45 +    g_assert(err == NULL);
   42.46 +    for(i=0;i<G_N_ELEMENTS(yum_packages);i++)
   42.47 +	expected=g_list_prepend(expected,
   42.48 +	  (gpointer)g_intern_string(yum_packages[i]));
   42.49 +    iter=razor_package_iterator_create(set);
   42.50 +    while(razor_package_iterator_next(iter,&package,RAZOR_DETAIL_NAME,&name,
   42.51 +      RAZOR_DETAIL_LAST))
   42.52 +    {
   42.53 +	lnk=g_list_find(expected,g_intern_string(name));
   42.54 +	if (!lnk)
   42.55 +	    g_warning("Unexpected package in set: %s",name);
   42.56 +	else
   42.57 +	    expected=g_list_remove_link(expected,lnk);
   42.58 +    }
   42.59 +    razor_package_iterator_destroy(iter);
   42.60 +    if (expected)
   42.61 +	g_warning("%d missing package%s in set, including %s",
   42.62 +	  g_list_length(expected),g_list_length(expected)==1?"":"s",
   42.63 +	  expected->data);
   42.64 +    razor_set_unref(set);
   42.65 +}
   42.66 +
   42.67 +int main(int argc,char **argv)
   42.68 +{
   42.69 +    g_test_init(&argc,&argv,NULL);
   42.70 +    g_test_bug_base("mailto:ali@juiblex.co.uk");
   42.71 +    g_test_add_func("/import-yum/basic",test_basic_import);
   42.72 +    return g_test_run();
   42.73 +}
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/tests/plover/test-log.c	Mon Jun 13 12:18:42 2016 +0100
    43.3 @@ -0,0 +1,215 @@
    43.4 +/*
    43.5 + * Copyright (C) 2016  J. Ali Harlow <ali@juiblex.co.uk>
    43.6 + *
    43.7 + * This program is free software; you can redistribute it and/or modify
    43.8 + * it under the terms of the GNU General Public License as published by
    43.9 + * the Free Software Foundation; either version 2 of the License, or
   43.10 + * (at your option) any later version.
   43.11 + *
   43.12 + * This program is distributed in the hope that it will be useful,
   43.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   43.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   43.15 + * GNU General Public License for more details.
   43.16 + *
   43.17 + * You should have received a copy of the GNU General Public License along
   43.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
   43.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   43.20 + */
   43.21 +
   43.22 +#include <stdlib.h>
   43.23 +#include <sys/time.h>
   43.24 +#include <glib.h>
   43.25 +#include <razor.h>
   43.26 +#include <plover/plover.h>
   43.27 +
   43.28 +static gchar *log_file_path(const char *directory,const char *name,
   43.29 +  const char *stamp)
   43.30 +{
   43.31 +    gchar *s,*path;
   43.32 +    if (name)
   43.33 +	s=g_strdup(name);
   43.34 +    else
   43.35 +	s=g_strconcat("test-",stamp,NULL);
   43.36 +    if (directory)
   43.37 +	path=g_build_filename(directory,s,NULL);
   43.38 +    else
   43.39 +	path=g_strdup(s);
   43.40 +    g_free(s);
   43.41 +    return path;
   43.42 +}
   43.43 +
   43.44 +static GDateTime *date_days_ago(int age)
   43.45 +{
   43.46 +    GDateTime *now,*then;
   43.47 +    now=g_date_time_new_now_utc();
   43.48 +    then=g_date_time_add_days(now,-age);
   43.49 +    g_date_time_unref(now);
   43.50 +    return then;
   43.51 +}
   43.52 +
   43.53 +static gchar *date_stamp(int age)
   43.54 +{
   43.55 +    gchar *stamp;
   43.56 +    GDateTime *then;
   43.57 +    then=date_days_ago(age);
   43.58 +    stamp=g_date_time_format(then,"%Y%m%d");
   43.59 +    g_date_time_unref(then);
   43.60 +    return stamp;
   43.61 +}
   43.62 +
   43.63 +static void simulate_log_file(const char *directory,const char *name,int age)
   43.64 +{
   43.65 +    gchar *path,*contents,*stamp;
   43.66 +    GDateTime *then;
   43.67 +    GError *err=NULL;
   43.68 +    struct timeval times[2]={{0,},{0,}};
   43.69 +    stamp=date_stamp(age);
   43.70 +    path=log_file_path(directory,name,stamp);
   43.71 +    contents=g_strdup_printf("Log for %s\n",stamp);
   43.72 +    if (!g_file_set_contents(path,contents,-1,&err))
   43.73 +	g_error("%s: %s",path,err->message);
   43.74 +    g_free(contents);
   43.75 +    then=date_days_ago(age);
   43.76 +    times[0].tv_sec=times[1].tv_sec=g_date_time_to_unix(then);
   43.77 +    utimes(path,times);
   43.78 +    g_date_time_unref(then);
   43.79 +    g_free(path);
   43.80 +    g_free(stamp);
   43.81 +}
   43.82 +
   43.83 +static void verify_log_file(const char *directory,const char *name,int age,
   43.84 +  gboolean should_exist)
   43.85 +{
   43.86 +    gchar *path,*contents,*stamp,*s;
   43.87 +    GError *err=NULL;
   43.88 +    stamp=date_stamp(age);
   43.89 +    path=log_file_path(directory,name,stamp);
   43.90 +    if (!should_exist)
   43.91 +	g_assert(!g_file_test(path,G_FILE_TEST_EXISTS));
   43.92 +    else
   43.93 +    {
   43.94 +	if (!g_file_get_contents(path,&contents,NULL,&err))
   43.95 +	    g_error("%s: %s",path,err->message);
   43.96 +	s=g_strdup_printf("Log for %s\n",stamp);
   43.97 +	g_assert_cmpstr(contents,==,s);
   43.98 +	g_free(s);
   43.99 +	g_free(contents);
  43.100 +    }
  43.101 +    g_free(path);
  43.102 +    g_free(stamp);
  43.103 +}
  43.104 +
  43.105 +static int safe_log_open(const char *s)
  43.106 +{
  43.107 +    int fd1,fd2,result;
  43.108 +    fflush(stdout);
  43.109 +    fflush(stderr);
  43.110 +    fd1=dup(1);
  43.111 +    fd2=dup(2);
  43.112 +    result=plover_log_open(s);
  43.113 +    fflush(stdout);
  43.114 +    fflush(stderr);
  43.115 +    dup2(fd1,1);
  43.116 +    dup2(fd2,2);
  43.117 +    close(fd1);
  43.118 +    close(fd2);
  43.119 +    return result;
  43.120 +}
  43.121 +
  43.122 +static void verify_log_open(const char *directory)
  43.123 +{
  43.124 +    int result;
  43.125 +    gchar *stamp,*s;
  43.126 +    simulate_log_file(directory,"test",1);
  43.127 +    simulate_log_file(directory,NULL,1);
  43.128 +    simulate_log_file(directory,NULL,2);
  43.129 +    simulate_log_file(directory,NULL,3);
  43.130 +    simulate_log_file(directory,NULL,4);
  43.131 +    if (directory)
  43.132 +	s=g_build_filename(directory,"test",NULL);
  43.133 +    else
  43.134 +	s=g_strdup("test");
  43.135 +    result=safe_log_open(s);
  43.136 +    g_free(s);
  43.137 +    g_assert_cmpint(result,==,0);
  43.138 +    stamp=date_stamp(1);
  43.139 +    s=g_strconcat("test-",stamp,"a",NULL);
  43.140 +    g_free(stamp);
  43.141 +    verify_log_file(directory,s,1,TRUE);
  43.142 +    g_free(s);
  43.143 +    verify_log_file(directory,NULL,1,TRUE);
  43.144 +    verify_log_file(directory,NULL,2,TRUE);
  43.145 +    verify_log_file(directory,NULL,3,TRUE);
  43.146 +    verify_log_file(directory,NULL,4,FALSE);
  43.147 +}
  43.148 +
  43.149 +static void test_rotate(void)
  43.150 +{
  43.151 +    system("rm -rf test-log-rotate");
  43.152 +    g_assert(mkdir("test-log-rotate",0777)==0);
  43.153 +    verify_log_open("test-log-rotate");
  43.154 +}
  43.155 +
  43.156 +static void test_rotate_cwd(void)
  43.157 +{
  43.158 +    system("rm -rf test-log-rotate");
  43.159 +    g_assert(mkdir("test-log-rotate",0777)==0);
  43.160 +    g_assert(chdir("test-log-rotate")==0);
  43.161 +    verify_log_open(NULL);
  43.162 +    g_assert(chdir("..")==0);
  43.163 +}
  43.164 +
  43.165 +static void test_rotate_root(void)
  43.166 +{
  43.167 +    gchar *cwd,*s;
  43.168 +    system("rm -rf test-log-rotate");
  43.169 +    g_assert(mkdir("test-log-rotate",0777)==0);
  43.170 +    cwd=g_get_current_dir();
  43.171 +    s=g_strconcat(cwd,"/",NULL);
  43.172 +    g_free(cwd);
  43.173 +    g_setenv("RAZOR_ROOT",s,TRUE);
  43.174 +    g_free(s);
  43.175 +    verify_log_open("test-log-rotate");
  43.176 +    g_unsetenv("RAZOR_ROOT");
  43.177 +}
  43.178 +
  43.179 +static void test_readonly_dir(void)
  43.180 +{
  43.181 +    system("rm -rf test-log-rotate");
  43.182 +    g_assert(mkdir("test-log-rotate",0)==0);
  43.183 +    g_assert(safe_log_open("test-log-rotate/test")!=0);
  43.184 +}
  43.185 +
  43.186 +static void test_directory(void)
  43.187 +{
  43.188 +    system("rm -rf test-log-rotate");
  43.189 +    g_assert(mkdir("test-log-rotate",0777)==0);
  43.190 +    g_assert(mkdir("test-log-rotate/test",0777)==0);
  43.191 +    g_assert(safe_log_open("test-log-rotate/test")!=0);
  43.192 +}
  43.193 +
  43.194 +static void test_readonly_file(void)
  43.195 +{
  43.196 +    GError *err=NULL;
  43.197 +    system("rm -rf test-log-rotate");
  43.198 +    g_assert(mkdir("test-log-rotate",0777)==0);
  43.199 +    if (!g_file_set_contents("test-log-rotate/test","",0,&err))
  43.200 +	g_error("test-log-rotate/test: %s",err->message);
  43.201 +    g_assert(chmod("test-log-rotate/test",0)==0);
  43.202 +    g_assert(safe_log_open("test-log-rotate/test")!=0);
  43.203 +}
  43.204 +
  43.205 +int main(int argc,char **argv)
  43.206 +{
  43.207 +    int retval;
  43.208 +    g_test_init(&argc,&argv,NULL);
  43.209 +    g_test_bug_base("mailto:ali@juiblex.co.uk");
  43.210 +    g_test_add_func("/log/rotate",test_rotate);
  43.211 +    g_test_add_func("/log/rotate-cwd",test_rotate_cwd);
  43.212 +    g_test_add_func("/log/rotate-root",test_rotate_root);
  43.213 +    g_test_add_func("/log/readonly-dir",test_readonly_dir);
  43.214 +    g_test_add_func("/log/directory",test_directory);
  43.215 +    g_test_add_func("/log/readonly-file",test_readonly_file);
  43.216 +    retval=g_test_run();
  43.217 +    return retval;
  43.218 +}
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/tests/plover/test-package.c	Mon Jun 13 12:18:42 2016 +0100
    44.3 @@ -0,0 +1,324 @@
    44.4 +/*
    44.5 + * Copyright (C) 2016  J. Ali Harlow <ali@juiblex.co.uk>
    44.6 + *
    44.7 + * This program is free software; you can redistribute it and/or modify
    44.8 + * it under the terms of the GNU General Public License as published by
    44.9 + * the Free Software Foundation; either version 2 of the License, or
   44.10 + * (at your option) any later version.
   44.11 + *
   44.12 + * This program is distributed in the hope that it will be useful,
   44.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   44.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   44.15 + * GNU General Public License for more details.
   44.16 + *
   44.17 + * You should have received a copy of the GNU General Public License along
   44.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
   44.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   44.20 + */
   44.21 +
   44.22 +#include <stdlib.h>
   44.23 +#include <razor.h>
   44.24 +#include <plover/plover.h>
   44.25 +#include <plover/package.h>
   44.26 +
   44.27 +struct razor_set *test_set=NULL;
   44.28 +struct razor_package *test_pkg=NULL;
   44.29 +
   44.30 +static void finalize(void)
   44.31 +{
   44.32 +    if (test_set)
   44.33 +	razor_set_unref(test_set);
   44.34 +}
   44.35 +
   44.36 +void import_properties(struct razor_importer *importer,
   44.37 +  struct razor_set *set,struct razor_package *pkg)
   44.38 +{
   44.39 +    struct razor_property_iterator *iter;
   44.40 +    struct razor_property *prop;
   44.41 +    uint32_t flags;
   44.42 +    const char *name,*version;
   44.43 +    iter=razor_property_iterator_create(set,pkg);
   44.44 +    while(razor_property_iterator_next(iter,&prop,&name,&flags,&version))
   44.45 +	razor_importer_add_property(importer,name,flags,version);
   44.46 +    razor_property_iterator_destroy(iter);
   44.47 +}
   44.48 +
   44.49 +void import_files(struct razor_importer *importer,
   44.50 +  struct razor_set *set,struct razor_package *pkg)
   44.51 +{
   44.52 +    struct razor_file_iterator *iter;
   44.53 +    const char *name;
   44.54 +    iter=razor_file_iterator_create(set,pkg,FALSE);
   44.55 +    while(razor_file_iterator_next(iter,&name))
   44.56 +	razor_importer_add_file(importer,name);
   44.57 +    razor_file_iterator_destroy(iter);
   44.58 +}
   44.59 +
   44.60 +gboolean import_rpm(struct razor_rpm *rpm)
   44.61 +{
   44.62 +    int i;
   44.63 +    struct razor_importer *importer;
   44.64 +    struct razor_package_iterator *iter;
   44.65 +    struct razor_set *set;
   44.66 +    struct razor_package *pkg=NULL;
   44.67 +    const char *name,*version,*arch,*summary,*description,*url,*license;
   44.68 +    const char *s,*pkg_name;
   44.69 +    const char *const *prefixes;
   44.70 +    /*
   44.71 +     * First pass: get a razor_set and razor_package with everything
   44.72 +     * except the prefixes.
   44.73 +     */
   44.74 +    importer=razor_importer_create();
   44.75 +    if (razor_importer_add_rpm(importer,rpm))
   44.76 +	g_error("../yum-repo-test-dir: Failed to add rpm");
   44.77 +    set=razor_importer_finish(importer);
   44.78 +    if (!set)
   44.79 +	g_error("../yum-repo-test-dir: Failed to import");
   44.80 +    iter=razor_package_iterator_create(set);
   44.81 +    pkg=NULL;
   44.82 +    razor_rpm_get_details(rpm,RAZOR_DETAIL_NAME,&pkg_name,RAZOR_DETAIL_LAST);
   44.83 +    while(razor_package_iterator_next(iter,&pkg,RAZOR_DETAIL_NAME,&s,
   44.84 +      RAZOR_DETAIL_LAST))
   44.85 +	if (!strcmp(s,pkg_name))
   44.86 +	    break;
   44.87 +    razor_package_iterator_destroy(iter);
   44.88 +    if (!pkg)
   44.89 +    {
   44.90 +	razor_set_unref(set);
   44.91 +	return FALSE;
   44.92 +    }
   44.93 +    /*
   44.94 +     * Second pass: use the information from the first pass plus the
   44.95 +     * prefixes to create a final razor_set and razor_package.
   44.96 +     */
   44.97 +    importer=razor_importer_create();
   44.98 +    razor_package_get_details(set,pkg,RAZOR_DETAIL_NAME,&name,
   44.99 +      RAZOR_DETAIL_VERSION,&version,RAZOR_DETAIL_ARCH,&arch,
  44.100 +      RAZOR_DETAIL_SUMMARY,&summary,RAZOR_DETAIL_DESCRIPTION,&description,
  44.101 +      RAZOR_DETAIL_URL,&url,RAZOR_DETAIL_LICENSE,&license,RAZOR_DETAIL_LAST);
  44.102 +    razor_importer_begin_package(importer,name,version,arch);
  44.103 +    razor_importer_add_details(importer,summary,description,url,license);
  44.104 +    import_properties(importer,set,pkg);
  44.105 +    import_files(importer,set,pkg);
  44.106 +    razor_rpm_get_details(rpm,RAZOR_DETAIL_PREFIXES,&prefixes,
  44.107 +      RAZOR_DETAIL_LAST);
  44.108 +    for(i=0;prefixes && prefixes[i];i++)
  44.109 +	razor_importer_add_install_prefix(importer,prefixes[i]);
  44.110 +    razor_importer_finish_package(importer);
  44.111 +    razor_set_unref(set);
  44.112 +    test_set=razor_importer_finish(importer);
  44.113 +    g_assert(test_set != NULL);
  44.114 +    iter=razor_package_iterator_create(test_set);
  44.115 +    test_pkg=NULL;
  44.116 +    while(razor_package_iterator_next(iter,&test_pkg,RAZOR_DETAIL_NAME,&s,
  44.117 +      RAZOR_DETAIL_LAST))
  44.118 +	if (!strcmp(s,pkg_name))
  44.119 +	    break;
  44.120 +    razor_package_iterator_destroy(iter);
  44.121 +    return !!test_pkg;
  44.122 +}
  44.123 +
  44.124 +static PloverPackage *package_getref(const char *name,const char *version)
  44.125 +{
  44.126 +    struct razor_rpm *rpm;
  44.127 +    PloverPackage *package=NULL;
  44.128 +    struct razor_error *err=NULL;
  44.129 +    gchar *filename;
  44.130 +    if (test_set)
  44.131 +    {
  44.132 +	razor_set_unref(test_set);
  44.133 +	test_set=NULL;
  44.134 +    }
  44.135 +    /*
  44.136 +     * yum metadata doesn't include all the information included in
  44.137 +     * a rpm file, so do this the hard way. Unfortunately,
  44.138 +     * razor_importer_add_rpm() doesn't support prefixes so we have
  44.139 +     * to do it the really hard way.
  44.140 +     */
  44.141 +    filename=g_strconcat("../yum-repo-test-dir/rpms/",name,"-",version,
  44.142 +      ".noarch.rpm",NULL);
  44.143 +    rpm=razor_rpm_open(filename,&err);
  44.144 +    if (!rpm)
  44.145 +	g_error("%s: %s",filename,razor_error_get_msg(err));
  44.146 +    g_free(filename);
  44.147 +    if (import_rpm(rpm))
  44.148 +	package=plover_package_new(test_set,test_pkg);
  44.149 +    else
  44.150 +	package=NULL;
  44.151 +    razor_rpm_close(rpm);
  44.152 +    return package;
  44.153 +}
  44.154 +
  44.155 +static void test_basic_properties(void)
  44.156 +{
  44.157 +    PloverPackage *package;
  44.158 +    package=package_getref("zsh","1-1");
  44.159 +    g_assert(package != NULL);
  44.160 +    g_assert(plover_package_get_razor_set(package) == test_set);
  44.161 +    g_assert(plover_package_get_razor_package(package) == test_pkg);
  44.162 +    g_assert_cmpstr(plover_package_get_name(package),==,"zsh");
  44.163 +    g_assert_cmpstr(plover_package_get_summary(package),==,"Test package");
  44.164 +    g_assert_cmpstr(plover_package_get_version(package),==,"1-1");
  44.165 +    g_assert_cmpstr(plover_package_get_license(package),==,"GPL");
  44.166 +    g_assert_cmpstr(plover_package_get_arch(package),==,"noarch");
  44.167 +    g_assert_cmpstr(plover_package_get_description(package),==,"Test package");
  44.168 +    g_assert_cmpstr(plover_package_get_URL(package),==,
  44.169 +      "http://www.juiblex.co.uk/beach");
  44.170 +    g_object_unref(package);
  44.171 +}
  44.172 +
  44.173 +static void test_package_properties(void)
  44.174 +{
  44.175 +    PloverPackage *package;
  44.176 +    struct razor_property_iterator *iter;
  44.177 +    struct razor_property *prop;
  44.178 +    uint32_t flags;
  44.179 +    const char *s,*name,*version;
  44.180 +    GString *str;
  44.181 +    GList *expected,*lnk;
  44.182 +    package=package_getref("zsh","1-1");
  44.183 +    g_assert(package != NULL);
  44.184 +    expected=g_list_prepend(NULL,
  44.185 +      (gpointer)g_intern_string("requires(pre,postun): zip"));
  44.186 +    expected=g_list_prepend(expected,
  44.187 +      (gpointer)g_intern_string("requires: zip"));
  44.188 +    expected=g_list_prepend(expected,
  44.189 +      (gpointer)g_intern_string("provides: zsh = 1-1"));
  44.190 +    iter=plover_package_property_iterator_create(package);
  44.191 +    g_assert(iter != NULL);
  44.192 +    while(razor_property_iterator_next(iter,&prop,&name,&flags,&version))
  44.193 +    {
  44.194 +	if (g_str_has_prefix(name,"rpmlib("))
  44.195 +	    continue;
  44.196 +	s=razor_property_type_to_string(prop);
  44.197 +	g_assert(s != NULL);
  44.198 +	str=g_string_new(s);
  44.199 +	if (flags&RAZOR_PROPERTY_SCRIPT_MASK)
  44.200 +	{
  44.201 +	    g_string_append_c(str,'(');
  44.202 +	    if (flags&RAZOR_PROPERTY_PRE)
  44.203 +		g_string_append(str,"pre");
  44.204 +	    if (flags&RAZOR_PROPERTY_POST)
  44.205 +	    {
  44.206 +		if (str->str[str->len-1]!='(' && str->str[str->len-1]!=',')
  44.207 +		    g_string_append_c(str,',');
  44.208 +		g_string_append(str,"post");
  44.209 +	    }
  44.210 +	    if (flags&RAZOR_PROPERTY_PREUN)
  44.211 +	    {
  44.212 +		if (str->str[str->len-1]!='(' && str->str[str->len-1]!=',')
  44.213 +		    g_string_append_c(str,',');
  44.214 +		g_string_append(str,"preun");
  44.215 +	    }
  44.216 +	    if (flags&RAZOR_PROPERTY_POSTUN)
  44.217 +	    {
  44.218 +		if (str->str[str->len-1]!='(' && str->str[str->len-1]!=',')
  44.219 +		    g_string_append_c(str,',');
  44.220 +		g_string_append(str,"postun");
  44.221 +	    }
  44.222 +	    g_string_append_c(str,')');
  44.223 +	}
  44.224 +	g_string_append(str,": ");
  44.225 +	g_string_append(str,name);
  44.226 +	if (*version)
  44.227 +	{
  44.228 +	    g_string_append_c(str,' ');
  44.229 +	    g_string_append(str,razor_property_relation_to_string(prop));
  44.230 +	    g_string_append_c(str,' ');
  44.231 +	    g_string_append(str,version);
  44.232 +	}
  44.233 +	lnk=g_list_find(expected,g_intern_string(str->str));
  44.234 +	if (!lnk)
  44.235 +	    g_warning("Unexpected property in zsh package: %s",str->str);
  44.236 +	else
  44.237 +	    expected=g_list_delete_link(expected,lnk);
  44.238 +	g_string_free(str,TRUE);
  44.239 +    }
  44.240 +    razor_property_iterator_destroy(iter);
  44.241 +    if (expected)
  44.242 +	g_warning("%d missing propert%s in set, including %s",
  44.243 +	  g_list_length(expected),g_list_length(expected)==1?"y":"ies",
  44.244 +	  expected->data);
  44.245 +    g_object_unref(package);
  44.246 +}
  44.247 +
  44.248 +static void test_package_files(void)
  44.249 +{
  44.250 +    PloverPackage *package;
  44.251 +    struct razor_file_iterator *iter;
  44.252 +    const char *name;
  44.253 +    GList *expected,*lnk;
  44.254 +    package=package_getref("zsh","1-1");
  44.255 +    g_assert(package != NULL);
  44.256 +    expected=g_list_prepend(NULL,(gpointer)g_intern_string("/etc/zsh.conf"));
  44.257 +    expected=g_list_prepend(expected,(gpointer)g_intern_string("/usr/bin/zsh"));
  44.258 +    iter=plover_package_file_iterator_create(package,FALSE);
  44.259 +    g_assert(iter != NULL);
  44.260 +    while(razor_file_iterator_next(iter,&name))
  44.261 +    {
  44.262 +	lnk=g_list_find(expected,g_intern_string(name));
  44.263 +	if (!lnk)
  44.264 +	    g_warning("Unexpected file in zsh package: %s",name);
  44.265 +	else
  44.266 +	    expected=g_list_delete_link(expected,lnk);
  44.267 +    }
  44.268 +    razor_file_iterator_destroy(iter);
  44.269 +    if (expected)
  44.270 +	g_warning("%d missing file%s in set, including %s",
  44.271 +	  g_list_length(expected),g_list_length(expected)==1?"":"s",
  44.272 +	  expected->data);
  44.273 +    g_object_unref(package);
  44.274 +}
  44.275 +
  44.276 +static void test_package_icon(void)
  44.277 +{
  44.278 +    /*
  44.279 +     * icons aren't supported yet.
  44.280 +     */
  44.281 +    PloverPackage *package;
  44.282 +    GInputStream *stream;
  44.283 +    GError *err=NULL;
  44.284 +    package=package_getref("zsh","1-1");
  44.285 +    g_assert(package != NULL);
  44.286 +    stream=plover_package_read_icon(package,&err);
  44.287 +    if (stream)
  44.288 +    {
  44.289 +	/* Unexpected, but hardly an error */
  44.290 +	g_object_unref(stream);
  44.291 +    }
  44.292 +    else
  44.293 +    {
  44.294 +	g_assert(err != NULL);
  44.295 +	g_assert(err->message != NULL);
  44.296 +	g_error_free(err);
  44.297 +    }
  44.298 +    g_object_unref(package);
  44.299 +}
  44.300 +
  44.301 +static void test_package_prefixes(void)
  44.302 +{
  44.303 +    PloverPackage *package;
  44.304 +    const char *const *prefixes;
  44.305 +    package=package_getref("zsh","1-1");
  44.306 +    g_assert(package != NULL);
  44.307 +    prefixes=plover_package_get_prefixes(package);
  44.308 +    g_assert_cmpstr(prefixes[0], ==, "/usr");
  44.309 +    g_assert(prefixes[1] == NULL);
  44.310 +    g_object_unref(package);
  44.311 +}
  44.312 +
  44.313 +int main(int argc,char **argv)
  44.314 +{
  44.315 +    int retval;
  44.316 +    g_test_init(&argc,&argv,NULL);
  44.317 +    g_test_bug_base("mailto:ali@juiblex.co.uk");
  44.318 +    g_test_add_func("/package/basic",test_basic_properties);
  44.319 +    g_test_add_func("/package/icons",test_package_icon);
  44.320 +    g_test_add_func("/package/properties",test_package_properties);
  44.321 +    g_test_add_func("/package/files",test_package_files);
  44.322 +    g_test_add_func("/package/prefixes",test_package_prefixes);
  44.323 +    g_test_message("PloverPackage::changed signal unused and thus untestable");
  44.324 +    retval=g_test_run();
  44.325 +    finalize();
  44.326 +    return retval;
  44.327 +}
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/tests/plover/test-packageset.c	Mon Jun 13 12:18:42 2016 +0100
    45.3 @@ -0,0 +1,369 @@
    45.4 +/*
    45.5 + * Copyright (C) 2016  J. Ali Harlow <ali@juiblex.co.uk>
    45.6 + *
    45.7 + * This program is free software; you can redistribute it and/or modify
    45.8 + * it under the terms of the GNU General Public License as published by
    45.9 + * the Free Software Foundation; either version 2 of the License, or
   45.10 + * (at your option) any later version.
   45.11 + *
   45.12 + * This program is distributed in the hope that it will be useful,
   45.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   45.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   45.15 + * GNU General Public License for more details.
   45.16 + *
   45.17 + * You should have received a copy of the GNU General Public License along
   45.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
   45.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   45.20 + */
   45.21 +
   45.22 +#include <stdlib.h>
   45.23 +#include <glib.h>
   45.24 +#include <razor.h>
   45.25 +#include <plover/plover.h>
   45.26 +#include <plover/packageset.h>
   45.27 +
   45.28 +const char *yum_packages[]={
   45.29 +    "zsh","zsh2","zip","zap","filesystem","zappy","zappy-tools","zappy2",
   45.30 +    "unsatisfiable","uninstallable","badpostun"
   45.31 +};
   45.32 +
   45.33 +const char *zappy_packages[]={
   45.34 +    "zap","zappy","zappy-tools","zappy2"
   45.35 +};
   45.36 +
   45.37 +static struct razor_set *get_dummy_set(void)
   45.38 +{
   45.39 +    struct razor_importer *importer;
   45.40 +    importer=razor_importer_create();
   45.41 +    g_assert(importer != NULL);
   45.42 +    razor_importer_begin_package(importer,"dummy","1-1","noarch");
   45.43 +    razor_importer_add_details(importer,"Dummy package",
   45.44 +      "A dummy package for testing","http://www.juiblex.co.uk/beach","GPL");
   45.45 +    razor_importer_add_property(importer,"dummy",
   45.46 +      RAZOR_PROPERTY_PROVIDES|RAZOR_PROPERTY_EQUAL,"1-1");
   45.47 +    razor_importer_finish_package(importer);
   45.48 +    return razor_importer_finish(importer);
   45.49 +}
   45.50 +
   45.51 +static int verify_empty_set_compar(gconstpointer a,gconstpointer b)
   45.52 +{
   45.53 +    return 0;
   45.54 +}
   45.55 +
   45.56 +static void verify_empty_set(PloverPackageSet *package_set)
   45.57 +{
   45.58 +    struct razor_set *set;
   45.59 +    struct razor_package *pkg;
   45.60 +    struct razor_package_iterator *iter;
   45.61 +    PloverPackage *package;
   45.62 +    GError *err=NULL;
   45.63 +    const char *prefix;
   45.64 +    gchar *default_prefix;
   45.65 +    g_assert(!plover_package_set_get_packages(package_set));
   45.66 +    set=get_dummy_set();
   45.67 +    g_assert(set != NULL);
   45.68 +    iter=razor_package_iterator_create(set);
   45.69 +    g_assert(iter != NULL);
   45.70 +    g_assert(razor_package_iterator_next(iter,&pkg,RAZOR_DETAIL_LAST));
   45.71 +    g_assert(!plover_package_set_lookup(package_set,pkg));
   45.72 +    razor_package_iterator_destroy(iter);
   45.73 +    g_assert(!plover_package_set_find_custom(package_set,NULL,
   45.74 +      verify_empty_set_compar));
   45.75 +    package=plover_package_new(set,pkg);
   45.76 +    g_assert(package != NULL);
   45.77 +    g_assert(!plover_package_set_find_matching(package_set,package));
   45.78 +    g_object_unref(package);
   45.79 +    razor_set_unref(set);
   45.80 +    g_assert(!plover_package_set_get_no_details(package_set));
   45.81 +    prefix=plover_package_set_guess_prefix(package_set,&err);
   45.82 +    if (!prefix && err)
   45.83 +	g_error("plover_package_set_guess_prefix: %s",err->message);
   45.84 +    g_assert(err == NULL);
   45.85 +    default_prefix=plover_default_prefix_for_vendor("Acme Corporation");
   45.86 +    g_assert_cmpstr(prefix,==,default_prefix);
   45.87 +    g_free(default_prefix);
   45.88 +}
   45.89 +
   45.90 +static void test_unopened(void)
   45.91 +{
   45.92 +    PloverPackageSet *package_set;
   45.93 +    package_set=plover_package_set_new();
   45.94 +    g_assert(PLOVER_IS_PACKAGE_SET(package_set));
   45.95 +    g_assert(!plover_package_set_get_header_version(package_set));
   45.96 +    g_assert(!plover_package_set_set_header_version(package_set,1));
   45.97 +    g_assert(!plover_package_set_get_install_root(package_set));
   45.98 +    g_assert(!plover_package_set_get_exclusive(package_set));
   45.99 +    g_assert(!plover_package_set_get_razor(package_set));
  45.100 +    verify_empty_set(package_set);
  45.101 +    plover_package_set_close(package_set);
  45.102 +    g_object_unref(package_set);
  45.103 +}
  45.104 +
  45.105 +static int package_name_compar(gconstpointer a,gconstpointer b)
  45.106 +{
  45.107 +    PloverPackage *package=PLOVER_PACKAGE(a);
  45.108 +    const char *name=b;
  45.109 +    return strcmp(plover_package_get_name(package),name);
  45.110 +}
  45.111 +
  45.112 +static void verify_package_set(PloverPackageSet *package_set,int n_packages,
  45.113 +  const char **package_names,const char *prefix)
  45.114 +{
  45.115 +    int i,ver;
  45.116 +    struct razor_importer *importer;
  45.117 +    struct razor_set *set;
  45.118 +    struct razor_package *pkg;
  45.119 +    struct razor_package_iterator *iter;
  45.120 +    PloverPackage *package,*package0;
  45.121 +    GError *err=NULL;
  45.122 +    const char *guessed_prefix;
  45.123 +    GSList *packages,*lnk2;
  45.124 +    GList *expected=NULL,*lnk;
  45.125 +    ver=plover_package_set_get_header_version(package_set);
  45.126 +    g_assert_cmpint(ver,==,RAZOR_HEADER_VERSION);
  45.127 +    g_assert(plover_package_set_set_header_version(package_set,
  45.128 +      RAZOR_HEADER_VERSION_MIN));
  45.129 +    g_assert(plover_package_set_set_header_version(package_set,ver));
  45.130 +    g_assert(!plover_package_set_get_exclusive(package_set));
  45.131 +    set=plover_package_set_get_razor(package_set);
  45.132 +    g_assert(set != NULL);
  45.133 +    for(i=0;i<n_packages;i++)
  45.134 +	expected=g_list_prepend(expected,
  45.135 +	  (gpointer)g_intern_string(package_names[i]));
  45.136 +    packages=plover_package_set_get_packages(package_set);
  45.137 +    package0=NULL;
  45.138 +    for(lnk2=packages;lnk2;lnk2=lnk2->next)
  45.139 +    {
  45.140 +	package=PLOVER_PACKAGE(lnk2->data);
  45.141 +	if (!strcmp(plover_package_get_name(package),package_names[0]))
  45.142 +	    package0=package;
  45.143 +	lnk=g_list_find(expected,
  45.144 +	  g_intern_string(plover_package_get_name(package)));
  45.145 +	if (!lnk)
  45.146 +	    g_warning("Unexpected package in set: %s",
  45.147 +	      plover_package_get_name(package));
  45.148 +	else
  45.149 +	    expected=g_list_delete_link(expected,lnk);
  45.150 +    }
  45.151 +    if (expected)
  45.152 +	g_warning("%d missing package%s in set, including %s",
  45.153 +	  g_list_length(expected),g_list_length(expected)==1?"":"s",
  45.154 +	  expected->data);
  45.155 +    pkg=plover_package_get_razor_package(package0);
  45.156 +    g_assert(plover_package_set_lookup(package_set,pkg)==package0);
  45.157 +    g_assert(plover_package_set_find_custom(package_set,package_names[0],
  45.158 +      package_name_compar)==package0);
  45.159 +    g_assert(plover_package_set_find_matching(package_set,package0)==package0);
  45.160 +    g_assert(!plover_package_set_get_no_details(package_set));
  45.161 +    guessed_prefix=plover_package_set_guess_prefix(package_set,&err);
  45.162 +    if (!guessed_prefix && err)
  45.163 +	g_error("plover_package_set_guess_prefix: %s",err->message);
  45.164 +    g_assert(err == NULL);
  45.165 +    g_assert_cmpstr(guessed_prefix,==,prefix);
  45.166 +}
  45.167 +
  45.168 +static void verify_zappy_set(PloverPackageSet *package_set)
  45.169 +{
  45.170 +    verify_package_set(package_set,G_N_ELEMENTS(zappy_packages),zappy_packages,
  45.171 +      NULL);
  45.172 +    g_assert_cmpstr(plover_package_set_get_install_root(package_set),==,
  45.173 +      "../razor-test-dir");
  45.174 +}
  45.175 +
  45.176 +static void test_open(void)
  45.177 +{
  45.178 +    PloverPackageSet *package_set;
  45.179 +    GError *err=NULL;
  45.180 +    package_set=plover_package_set_new();
  45.181 +    g_assert(PLOVER_IS_PACKAGE_SET(package_set));
  45.182 +    if (!plover_package_set_open(package_set,"../razor-test-dir",FALSE,&err))
  45.183 +    {
  45.184 +	g_assert(err && err->message);
  45.185 +	g_error("../razor-test-dir: %s",err->message);
  45.186 +    }
  45.187 +    g_assert(!err);
  45.188 +    verify_zappy_set(package_set);
  45.189 +    plover_package_set_close(package_set);
  45.190 +    g_object_unref(package_set);
  45.191 +}
  45.192 +
  45.193 +static void test_update(void)
  45.194 +{
  45.195 +    int ver;
  45.196 +    struct razor_importer *importer;
  45.197 +    struct razor_set *set,*dummy_set;
  45.198 +    struct razor_package *pkg;
  45.199 +    struct razor_package_iterator *iter;
  45.200 +    struct razor_atomic *atomic;
  45.201 +    PloverPackageSet *package_set;
  45.202 +    PloverPackage *package;
  45.203 +    GError *err=NULL;
  45.204 +    const char *prefix;
  45.205 +    gchar *root;
  45.206 +    GSList *packages;
  45.207 +    package_set=plover_package_set_new();
  45.208 +    g_assert(PLOVER_IS_PACKAGE_SET(package_set));
  45.209 +    root=g_strdup("razor-test-dir-XXXXXX");
  45.210 +    g_assert(mkdtemp(root));
  45.211 +    if (!plover_package_set_open(package_set,root,TRUE,&err))
  45.212 +    {
  45.213 +	g_assert(err && err->message);
  45.214 +	g_error("%s: %s",root,err->message);
  45.215 +    }
  45.216 +    g_assert(!err);
  45.217 +    ver=plover_package_set_get_header_version(package_set);
  45.218 +    g_assert_cmpint(ver,==,RAZOR_HEADER_VERSION);
  45.219 +    g_assert(plover_package_set_set_header_version(package_set,
  45.220 +      RAZOR_HEADER_VERSION_MIN));
  45.221 +    g_assert(plover_package_set_set_header_version(package_set,ver));
  45.222 +    g_assert_cmpstr(plover_package_set_get_install_root(package_set),==,root);
  45.223 +    g_free(root);
  45.224 +    g_assert(plover_package_set_get_exclusive(package_set));
  45.225 +    set=plover_package_set_get_razor(package_set);
  45.226 +    g_assert(set != NULL);
  45.227 +    verify_empty_set(package_set);
  45.228 +    dummy_set=get_dummy_set();
  45.229 +    atomic=razor_atomic_open("packageset-update");
  45.230 +    if (!plover_package_set_update(package_set,dummy_set,atomic))
  45.231 +	g_error("plover_package_set_update: %s",
  45.232 +	  razor_atomic_get_error_msg(atomic));
  45.233 +    if (razor_atomic_commit(atomic))
  45.234 +	g_error("plover_package_set_update: commit: %s",
  45.235 +	  razor_atomic_get_error_msg(atomic));
  45.236 +    razor_atomic_destroy(atomic);
  45.237 +    razor_set_unref(dummy_set);
  45.238 +    packages=plover_package_set_get_packages(package_set);
  45.239 +    g_assert_cmpint(g_slist_length(packages),==,1);
  45.240 +    package=PLOVER_PACKAGE(packages->data);
  45.241 +    g_assert_cmpstr(plover_package_get_name(package),==,"dummy");
  45.242 +    pkg=plover_package_get_razor_package(package);
  45.243 +    g_assert(plover_package_set_lookup(package_set,pkg)==package);
  45.244 +    g_assert(plover_package_set_find_custom(package_set,"dummy",
  45.245 +      package_name_compar)==package);
  45.246 +    g_assert(plover_package_set_find_matching(package_set,package)==package);
  45.247 +    g_assert(!plover_package_set_get_no_details(package_set));
  45.248 +    prefix=plover_package_set_guess_prefix(package_set,&err);
  45.249 +    if (!prefix && err)
  45.250 +	g_error("plover_package_set_guess_prefix: %s",err->message);
  45.251 +    g_assert(err == NULL);
  45.252 +    g_assert_cmpstr(prefix,==,
  45.253 +      plover_default_prefix_for_vendor("Acme Corporation"));
  45.254 +    plover_package_set_close(package_set);
  45.255 +    g_object_unref(package_set);
  45.256 +}
  45.257 +
  45.258 +static void test_from_installed(void)
  45.259 +{
  45.260 +    PloverPackageSet *package_set;
  45.261 +    PloverPackage *package;
  45.262 +    GError *err=NULL;
  45.263 +    package_set=plover_package_set_new_from_installed("../razor-test-dir",&err);
  45.264 +    if (!package_set && err)
  45.265 +	g_error("../razor-test-dir: %s",err->message);
  45.266 +    g_assert(PLOVER_IS_PACKAGE_SET(package_set));
  45.267 +    g_assert(!err);
  45.268 +    verify_zappy_set(package_set);
  45.269 +    plover_package_set_close(package_set);
  45.270 +    g_object_unref(package_set);
  45.271 +}
  45.272 +
  45.273 +static void test_from_razor(void)
  45.274 +{
  45.275 +    struct razor_set *set;
  45.276 +    PloverPackageSet *package_set;
  45.277 +    PloverPackage *package;
  45.278 +    set=razor_set_create_without_root();
  45.279 +    package_set=plover_package_set_new_from_razor(set);
  45.280 +    g_assert(PLOVER_IS_PACKAGE_SET(package_set));
  45.281 +    verify_empty_set(package_set);
  45.282 +    plover_package_set_close(package_set);
  45.283 +    g_object_unref(package_set);
  45.284 +    razor_set_unref(set);
  45.285 +}
  45.286 +
  45.287 +static void verify_yum_set(PloverPackageSet *package_set,const char *prefix)
  45.288 +{
  45.289 +    verify_package_set(package_set,G_N_ELEMENTS(yum_packages),yum_packages,
  45.290 +      prefix);
  45.291 +    g_assert(!plover_package_set_get_install_root(package_set));
  45.292 +}
  45.293 +
  45.294 +static void test_from_repository(void)
  45.295 +{
  45.296 +    PloverRepository *repository;
  45.297 +    PloverPackageSet *package_set;
  45.298 +    PloverPackage *package;
  45.299 +    GError *err=NULL;
  45.300 +    repository=plover_repository_new_from_yum("../yum-repo-test-dir",&err);
  45.301 +    if (!repository && err)
  45.302 +	g_error("../yum-repo-test-dir: %s",err->message);
  45.303 +    g_assert(PLOVER_IS_REPOSITORY(repository));
  45.304 +    g_assert(!err);
  45.305 +    package_set=plover_package_set_new_from_repository(repository,NULL,&err);
  45.306 +    if (!package_set && err)
  45.307 +	g_error("../yum-repo-test-dir: %s",err->message);
  45.308 +    g_assert(PLOVER_IS_PACKAGE_SET(package_set));
  45.309 +    g_assert(!err);
  45.310 +    g_object_unref(repository);
  45.311 +    verify_yum_set(package_set,NULL);
  45.312 +    plover_package_set_close(package_set);
  45.313 +    g_object_unref(package_set);
  45.314 +}
  45.315 +
  45.316 +static void test_from_yum(void)
  45.317 +{
  45.318 +    struct razor_relocations *relocations;
  45.319 +    PloverPackageSet *package_set;
  45.320 +    PloverPackage *package;
  45.321 +    GError *err=NULL;
  45.322 +    relocations=razor_relocations_create();
  45.323 +    razor_relocations_add(relocations,"/usr","/test");
  45.324 +    package_set=plover_package_set_new_from_yum("../yum-repo-test-dir",
  45.325 +      relocations,&err);
  45.326 +    if (!package_set && err)
  45.327 +	g_error("../yum-repo-test-dir: %s",err->message);
  45.328 +    g_assert(PLOVER_IS_PACKAGE_SET(package_set));
  45.329 +    g_assert(!err);
  45.330 +    razor_relocations_destroy(relocations);
  45.331 +    verify_yum_set(package_set,"/test");
  45.332 +    plover_package_set_close(package_set);
  45.333 +    g_object_unref(package_set);
  45.334 +}
  45.335 +
  45.336 +static void test_from_rpms(void)
  45.337 +{
  45.338 +    int i;
  45.339 +    PloverPackageSet *package_set;
  45.340 +    PloverPackage *package;
  45.341 +    GError *err=NULL;
  45.342 +    gchar **filenames;
  45.343 +    filenames=g_new(char *,G_N_ELEMENTS(yum_packages)+1);
  45.344 +    for(i=0;i<G_N_ELEMENTS(yum_packages);i++)
  45.345 +	filenames[i]=g_strconcat("../yum-repo-test-dir/rpms/",
  45.346 +	  yum_packages[i],"-1-1.noarch.rpm",NULL);
  45.347 +    filenames[i]=NULL;
  45.348 +    package_set=plover_package_set_new_from_rpms((const char **)filenames,&err);
  45.349 +    if (!package_set && err)
  45.350 +	g_error("../yum-repo-test-dir: %s",err->message);
  45.351 +    g_assert(PLOVER_IS_PACKAGE_SET(package_set));
  45.352 +    g_assert(!err);
  45.353 +    g_strfreev(filenames);
  45.354 +    verify_yum_set(package_set,NULL);
  45.355 +    plover_package_set_close(package_set);
  45.356 +    g_object_unref(package_set);
  45.357 +}
  45.358 +
  45.359 +int main(int argc,char **argv)
  45.360 +{
  45.361 +    g_test_init(&argc,&argv,NULL);
  45.362 +    g_test_bug_base("mailto:ali@juiblex.co.uk");
  45.363 +    g_test_add_func("/packageset/unopened",test_unopened);
  45.364 +    g_test_add_func("/packageset/open",test_open);
  45.365 +    g_test_add_func("/packageset/update",test_update);
  45.366 +    g_test_add_func("/packageset/from-installed",test_from_installed);
  45.367 +    g_test_add_func("/packageset/from-razor",test_from_razor);
  45.368 +    g_test_add_func("/packageset/from-repository",test_from_repository);
  45.369 +    g_test_add_func("/packageset/from-yum",test_from_yum);
  45.370 +    g_test_add_func("/packageset/from-rpms",test_from_rpms);
  45.371 +    return g_test_run();
  45.372 +}
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/tests/plover/test-razor.c	Mon Jun 13 12:18:42 2016 +0100
    46.3 @@ -0,0 +1,206 @@
    46.4 +/*
    46.5 + * Copyright (C) 2016  J. Ali Harlow <ali@juiblex.co.uk>
    46.6 + *
    46.7 + * This program is free software; you can redistribute it and/or modify
    46.8 + * it under the terms of the GNU General Public License as published by
    46.9 + * the Free Software Foundation; either version 2 of the License, or
   46.10 + * (at your option) any later version.
   46.11 + *
   46.12 + * This program is distributed in the hope that it will be useful,
   46.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   46.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   46.15 + * GNU General Public License for more details.
   46.16 + *
   46.17 + * You should have received a copy of the GNU General Public License along
   46.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
   46.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   46.20 + */
   46.21 +
   46.22 +#include <stdlib.h>
   46.23 +#include <glib.h>
   46.24 +#include <lua.h>
   46.25 +#include <razor.h>
   46.26 +#include <plover/plover.h>
   46.27 +
   46.28 +LUALIB_API int luaopen_posix(lua_State *L);
   46.29 +
   46.30 +static void test_install(void)
   46.31 +{
   46.32 +    char *pkgs[]={"zip",NULL};
   46.33 +    gchar *root;
   46.34 +    GError *err=NULL;
   46.35 +    root=g_strdup("razor-test-dir-XXXXXX");
   46.36 +    g_assert(mkdtemp(root));
   46.37 +    g_setenv("RAZOR_ROOT",root,TRUE);
   46.38 +    if (!plover_install("../yum-repo-test-dir","/test",pkgs,&err))
   46.39 +    {
   46.40 +	g_assert(err && err->message);
   46.41 +	g_error("test-install: %s",err->message);
   46.42 +    }
   46.43 +    g_assert(!err);
   46.44 +    g_unsetenv("RAZOR_ROOT");
   46.45 +    g_free(root);
   46.46 +}
   46.47 +
   46.48 +static void test_install_bad_rpm(void)
   46.49 +{
   46.50 +    gboolean installed_bad_rpm;
   46.51 +    char *pkgs[]={"zip",NULL};
   46.52 +    gchar *root;
   46.53 +    GError *err=NULL;
   46.54 +    root=g_strdup("razor-test-dir-XXXXXX");
   46.55 +    g_assert(mkdtemp(root));
   46.56 +    g_setenv("RAZOR_ROOT",root,TRUE);
   46.57 +    chmod("../yum-repo-test-dir/rpms/zip-1-1.noarch.rpm",0);
   46.58 +    installed_bad_rpm=plover_install("../yum-repo-test-dir","/test",pkgs,&err);
   46.59 +    chmod("../yum-repo-test-dir/rpms/zip-1-1.noarch.rpm",0666);
   46.60 +    g_assert(!installed_bad_rpm);
   46.61 +    g_assert(err && err->message);
   46.62 +    g_unsetenv("RAZOR_ROOT");
   46.63 +    g_free(root);
   46.64 +}
   46.65 +
   46.66 +static void test_update_noop(void)
   46.67 +{
   46.68 +    gchar *root;
   46.69 +    GError *err=NULL;
   46.70 +    root=g_strdup("razor-test-dir-XXXXXX");
   46.71 +    g_assert(mkdtemp(root));
   46.72 +    g_setenv("RAZOR_ROOT",root,TRUE);
   46.73 +    if (!plover_update("../yum-repo-test-dir","/test",NULL,&err))
   46.74 +    {
   46.75 +	g_assert(err && err->message);
   46.76 +	g_error("test-update-noop: %s",err->message);
   46.77 +    }
   46.78 +    g_assert(!err);
   46.79 +    g_unsetenv("RAZOR_ROOT");
   46.80 +    g_free(root);
   46.81 +}
   46.82 +
   46.83 +static void test_update_nonexistant(void)
   46.84 +{
   46.85 +    char *pkgs[]={"nonexistant",NULL};
   46.86 +    gchar *root;
   46.87 +    GError *err=NULL;
   46.88 +    root=g_strdup("razor-test-dir-XXXXXX");
   46.89 +    g_assert(mkdtemp(root));
   46.90 +    g_setenv("RAZOR_ROOT",root,TRUE);
   46.91 +    g_assert(!plover_update("../yum-repo-test-dir","/test",pkgs,&err));
   46.92 +    g_assert(g_error_matches(err,PLOVER_GENERAL_ERROR,
   46.93 +      PLOVER_GENERAL_ERROR_NO_SUCH_PACKAGE));
   46.94 +    g_clear_error(&err);
   46.95 +    g_unsetenv("RAZOR_ROOT");
   46.96 +    g_free(root);
   46.97 +}
   46.98 +
   46.99 +static void test_remove(void)
  46.100 +{
  46.101 +    char *pkgs[]={"zip",NULL};
  46.102 +    gchar *root;
  46.103 +    GError *err=NULL;
  46.104 +    root=g_strdup("razor-test-dir-XXXXXX");
  46.105 +    g_assert(mkdtemp(root));
  46.106 +    g_setenv("RAZOR_ROOT",root,TRUE);
  46.107 +    if (!plover_install("../yum-repo-test-dir","/test",pkgs,&err))
  46.108 +	g_error("test-remove: %s",err->message);
  46.109 +    if (!plover_remove(pkgs,&err))
  46.110 +    {
  46.111 +	g_assert(err && err->message);
  46.112 +	g_error("test-remove: %s",err->message);
  46.113 +    }
  46.114 +    g_assert(!err);
  46.115 +    g_unsetenv("RAZOR_ROOT");
  46.116 +    g_free(root);
  46.117 +}
  46.118 +
  46.119 +static void test_remove_noop(void)
  46.120 +{
  46.121 +    gchar *root;
  46.122 +    GError *err=NULL;
  46.123 +    root=g_strdup("razor-test-dir-XXXXXX");
  46.124 +    g_assert(mkdtemp(root));
  46.125 +    g_setenv("RAZOR_ROOT",root,TRUE);
  46.126 +    if (!plover_remove(NULL,&err))
  46.127 +    {
  46.128 +	g_assert(err && err->message);
  46.129 +	g_error("test-remove-noop: %s",err->message);
  46.130 +    }
  46.131 +    g_assert(!err);
  46.132 +    g_unsetenv("RAZOR_ROOT");
  46.133 +    g_free(root);
  46.134 +}
  46.135 +
  46.136 +static void test_remove_nonexistant(void)
  46.137 +{
  46.138 +    char *pkgs[]={"nonexistant",NULL};
  46.139 +    gchar *root;
  46.140 +    GError *err=NULL;
  46.141 +    root=g_strdup("razor-test-dir-XXXXXX");
  46.142 +    g_assert(mkdtemp(root));
  46.143 +    g_setenv("RAZOR_ROOT",root,TRUE);
  46.144 +    g_assert(!plover_remove(pkgs,&err));
  46.145 +    g_assert(g_error_matches(err,PLOVER_GENERAL_ERROR,
  46.146 +      PLOVER_GENERAL_ERROR_NO_SUCH_PACKAGE));
  46.147 +    g_clear_error(&err);
  46.148 +    g_unsetenv("RAZOR_ROOT");
  46.149 +    g_free(root);
  46.150 +}
  46.151 +
  46.152 +static void test_remove_warning(void)
  46.153 +{
  46.154 +    char *pkgs[]={"badpostun",NULL};
  46.155 +    gchar *root;
  46.156 +    GError *err=NULL;
  46.157 +    root=g_strdup("razor-test-dir-XXXXXX");
  46.158 +    g_assert(mkdtemp(root));
  46.159 +    g_setenv("RAZOR_ROOT",root,TRUE);
  46.160 +    if (!plover_install("../yum-repo-test-dir","/test",pkgs,&err))
  46.161 +	g_error("test-remove-warning: %s",err->message);
  46.162 +    if (!plover_remove(pkgs,&err))
  46.163 +    {
  46.164 +	g_assert(err && err->message);
  46.165 +	g_error("test-remove-warning: %s",err->message);
  46.166 +    }
  46.167 +    g_assert(!err);
  46.168 +    g_unsetenv("RAZOR_ROOT");
  46.169 +    g_free(root);
  46.170 +}
  46.171 +
  46.172 +static void test_prefix(void)
  46.173 +{
  46.174 +    g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE);
  46.175 +    g_assert(plover_installed_files_match_prefix("/usr//"));
  46.176 +    g_assert(!plover_installed_files_match_prefix("/tmp"));
  46.177 +    g_unsetenv("RAZOR_ROOT");
  46.178 +}
  46.179 +
  46.180 +static void test_prefix_none(void)
  46.181 +{
  46.182 +    gchar *root;
  46.183 +    root=g_strdup("razor-test-dir-XXXXXX");
  46.184 +    g_assert(mkdtemp(root));
  46.185 +    g_setenv("RAZOR_ROOT",root,TRUE);
  46.186 +    g_assert(plover_installed_files_match_prefix("/any-prefix"));
  46.187 +    g_unsetenv("RAZOR_ROOT");
  46.188 +    g_free(root);
  46.189 +}
  46.190 +
  46.191 +int main(int argc,char **argv)
  46.192 +{
  46.193 +    int retval;
  46.194 +    g_test_init(&argc,&argv,NULL);
  46.195 +    razor_set_lua_loader("posix",(void (*)())luaopen_posix);
  46.196 +    g_test_bug_base("mailto:ali@juiblex.co.uk");
  46.197 +    g_test_add_func("/razor/install",test_install);
  46.198 +    g_test_add_func("/razor/install-bad-rpm",test_install_bad_rpm);
  46.199 +    g_test_add_func("/razor/update-noop",test_update_noop);
  46.200 +    g_test_add_func("/razor/update-nonexistant",test_update_nonexistant);
  46.201 +    g_test_add_func("/razor/remove",test_remove);
  46.202 +    g_test_add_func("/razor/remove-noop",test_remove_noop);
  46.203 +    g_test_add_func("/razor/remove-nonexistant",test_remove_nonexistant);
  46.204 +    g_test_add_func("/razor/remove-warning",test_remove_warning);
  46.205 +    g_test_add_func("/razor/prefix",test_prefix);
  46.206 +    g_test_add_func("/razor/prefix-none",test_prefix_none);
  46.207 +    retval=g_test_run();
  46.208 +    return retval;
  46.209 +}
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/tests/plover/test-repository.c	Mon Jun 13 12:18:42 2016 +0100
    47.3 @@ -0,0 +1,155 @@
    47.4 +/*
    47.5 + * Copyright (C) 2016  J. Ali Harlow <ali@juiblex.co.uk>
    47.6 + *
    47.7 + * This program is free software; you can redistribute it and/or modify
    47.8 + * it under the terms of the GNU General Public License as published by
    47.9 + * the Free Software Foundation; either version 2 of the License, or
   47.10 + * (at your option) any later version.
   47.11 + *
   47.12 + * This program is distributed in the hope that it will be useful,
   47.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   47.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   47.15 + * GNU General Public License for more details.
   47.16 + *
   47.17 + * You should have received a copy of the GNU General Public License along
   47.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
   47.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   47.20 + */
   47.21 +
   47.22 +#include <stdlib.h>
   47.23 +#include <glib.h>
   47.24 +#include <razor.h>
   47.25 +#include <plover/repository.h>
   47.26 +
   47.27 +const char *test_repo_packages[]={
   47.28 +    "zsh","zsh2","zip","zap","filesystem","zappy","zappy-tools","zappy2",
   47.29 +    "unsatisfiable","uninstallable","badpostun"
   47.30 +};
   47.31 +
   47.32 +static void test_from_files(void)
   47.33 +{
   47.34 +    int i;
   47.35 +    struct razor_set *set;
   47.36 +    struct razor_package_iterator *iter;
   47.37 +    struct razor_package *package;
   47.38 +    PloverRepository *repository;
   47.39 +    PloverPackageSet *package_set;
   47.40 +    char **filenames;
   47.41 +    const char *name;
   47.42 +    GList *expected=NULL,*lnk;
   47.43 +    GError *err=NULL;
   47.44 +    filenames=g_new(char *,G_N_ELEMENTS(test_repo_packages)+1);
   47.45 +    for(i=0;i<G_N_ELEMENTS(test_repo_packages);i++)
   47.46 +	filenames[i]=g_strconcat("../yum-repo-test-dir/rpms/",
   47.47 +	  test_repo_packages[i],"-1-1.noarch.rpm",NULL);
   47.48 +    filenames[i]=NULL;
   47.49 +    repository=plover_repository_new_from_files((const char **)filenames,&err);
   47.50 +    g_strfreev(filenames);
   47.51 +    if (!repository && err)
   47.52 +	g_error("../yum-repo-test-dir: %s",err->message);
   47.53 +    g_assert(repository != NULL);
   47.54 +    g_assert(err == NULL);
   47.55 +    package_set=plover_repository_get_package_set(repository);
   47.56 +    g_assert(package_set != NULL);
   47.57 +    set=plover_package_set_get_razor(package_set);
   47.58 +    g_assert(set != NULL);
   47.59 +    for(i=0;i<G_N_ELEMENTS(test_repo_packages);i++)
   47.60 +	expected=g_list_prepend(expected,
   47.61 +	  (gpointer)g_intern_string(test_repo_packages[i]));
   47.62 +    iter=razor_package_iterator_create(set);
   47.63 +    while(razor_package_iterator_next(iter,&package,RAZOR_DETAIL_NAME,&name,
   47.64 +      RAZOR_DETAIL_LAST))
   47.65 +    {
   47.66 +	lnk=g_list_find(expected,g_intern_string(name));
   47.67 +	if (!lnk)
   47.68 +	    g_warning("Unexpected package in set: %s",name);
   47.69 +	else
   47.70 +	    expected=g_list_delete_link(expected,lnk);
   47.71 +    }
   47.72 +    razor_package_iterator_destroy(iter);
   47.73 +    if (expected)
   47.74 +	g_warning("%d missing package%s in set, including %s",
   47.75 +	  g_list_length(expected),g_list_length(expected)==1?"":"s",
   47.76 +	  expected->data);
   47.77 +    g_object_unref(repository);
   47.78 +}
   47.79 +
   47.80 +static void test_from_yum(void)
   47.81 +{
   47.82 +    int i;
   47.83 +    struct razor_set *set;
   47.84 +    struct razor_package_iterator *iter;
   47.85 +    struct razor_package *package;
   47.86 +    PloverRepository *repository;
   47.87 +    PloverPackageSet *package_set;
   47.88 +    const char *name;
   47.89 +    GList *expected=NULL,*lnk;
   47.90 +    GError *err=NULL;
   47.91 +    repository=plover_repository_new_from_yum("../yum-repo-test-dir",&err);
   47.92 +    if (!repository && err)
   47.93 +	g_error("../yum-repo-test-dir: %s",err->message);
   47.94 +    g_assert(repository != NULL);
   47.95 +    g_assert(err == NULL);
   47.96 +    package_set=plover_repository_get_package_set(repository);
   47.97 +    g_assert(package_set != NULL);
   47.98 +    set=plover_package_set_get_razor(package_set);
   47.99 +    g_assert(set != NULL);
  47.100 +    for(i=0;i<G_N_ELEMENTS(test_repo_packages);i++)
  47.101 +	expected=g_list_prepend(expected,
  47.102 +	  (gpointer)g_intern_string(test_repo_packages[i]));
  47.103 +    iter=razor_package_iterator_create(set);
  47.104 +    while(razor_package_iterator_next(iter,&package,RAZOR_DETAIL_NAME,&name,
  47.105 +      RAZOR_DETAIL_LAST))
  47.106 +    {
  47.107 +	lnk=g_list_find(expected,g_intern_string(name));
  47.108 +	if (!lnk)
  47.109 +	    g_warning("Unexpected package in set: %s",name);
  47.110 +	else
  47.111 +	    expected=g_list_delete_link(expected,lnk);
  47.112 +    }
  47.113 +    razor_package_iterator_destroy(iter);
  47.114 +    if (expected)
  47.115 +	g_warning("%d missing package%s in set, including %s",
  47.116 +	  g_list_length(expected),g_list_length(expected)==1?"":"s",
  47.117 +	  expected->data);
  47.118 +    g_object_unref(repository);
  47.119 +}
  47.120 +
  47.121 +static void test_open_rpm(void)
  47.122 +{
  47.123 +    struct razor_rpm *rpm;
  47.124 +    PloverRepository *repository;
  47.125 +    PloverPackageSet *package_set;
  47.126 +    PloverPackage *package;
  47.127 +    const char *name;
  47.128 +    GSList *packages,*lnk;
  47.129 +    GError *err=NULL;
  47.130 +    repository=plover_repository_new_from_yum("../yum-repo-test-dir",&err);
  47.131 +    if (!repository)
  47.132 +	g_error("../yum-repo-test-dir: %s",err->message);
  47.133 +    package_set=plover_repository_get_package_set(repository);
  47.134 +    packages=plover_package_set_get_packages(package_set);
  47.135 +    for(lnk=packages;lnk;lnk=lnk->next)
  47.136 +    {
  47.137 +	package=PLOVER_PACKAGE(lnk->data);
  47.138 +	rpm=plover_repository_open_rpm(repository,package,&err);
  47.139 +	if (!rpm && err)
  47.140 +	    g_error("%s: %s",plover_package_get_name(package),err->message);
  47.141 +	g_assert(rpm != NULL);
  47.142 +	g_assert(err == NULL);
  47.143 +	razor_rpm_get_details(rpm,RAZOR_DETAIL_NAME,&name,RAZOR_DETAIL_LAST);
  47.144 +	g_assert_cmpstr(plover_package_get_name(package),==,name);
  47.145 +	razor_rpm_close(rpm);
  47.146 +    }
  47.147 +    g_object_unref(repository);
  47.148 +}
  47.149 +
  47.150 +int main(int argc,char **argv)
  47.151 +{
  47.152 +    g_test_init(&argc,&argv,NULL);
  47.153 +    g_test_bug_base("mailto:ali@juiblex.co.uk");
  47.154 +    g_test_add_func("/repository/from-files",test_from_files);
  47.155 +    g_test_add_func("/repository/from-yum",test_from_yum);
  47.156 +    g_test_add_func("/repository/open-rpm",test_open_rpm);
  47.157 +    return g_test_run();
  47.158 +}
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/tests/plover/test-transaction.c	Mon Jun 13 12:18:42 2016 +0100
    48.3 @@ -0,0 +1,441 @@
    48.4 +/*
    48.5 + * Copyright (C) 2016  J. Ali Harlow <ali@juiblex.co.uk>
    48.6 + *
    48.7 + * This program is free software; you can redistribute it and/or modify
    48.8 + * it under the terms of the GNU General Public License as published by
    48.9 + * the Free Software Foundation; either version 2 of the License, or
   48.10 + * (at your option) any later version.
   48.11 + *
   48.12 + * This program is distributed in the hope that it will be useful,
   48.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   48.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   48.15 + * GNU General Public License for more details.
   48.16 + *
   48.17 + * You should have received a copy of the GNU General Public License along
   48.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
   48.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   48.20 + */
   48.21 +
   48.22 +#include <stdlib.h>
   48.23 +#include <glib.h>
   48.24 +#include <lua.h>
   48.25 +#include <razor.h>
   48.26 +#include <plover/plover.h>
   48.27 +#include <plover/packageset.h>
   48.28 +#include <plover/transaction.h>
   48.29 +
   48.30 +LUALIB_API int luaopen_posix(lua_State *L);
   48.31 +
   48.32 +const char *zappy_packages[]={
   48.33 +    "zap","zappy","zappy-tools","zappy2"
   48.34 +};
   48.35 +
   48.36 +static void test_installed_system_set(void)
   48.37 +{
   48.38 +    PloverTransaction *transaction;
   48.39 +    PloverPackageSet *package_set;
   48.40 +    struct razor_set *set;
   48.41 +    GError *err=NULL;
   48.42 +    transaction=plover_transaction_new();
   48.43 +    g_assert(PLOVER_IS_TRANSACTION(transaction));
   48.44 +    package_set=plover_package_set_new_from_yum("../yum-repo-test-dir",NULL,
   48.45 +      &err);
   48.46 +    if (!package_set)
   48.47 +	g_error("../yum-repo-test-dir: %s",err->message);
   48.48 +    plover_transaction_set_installed(transaction,package_set);
   48.49 +    set=plover_transaction_get_system_set(transaction);
   48.50 +    g_assert(set == plover_package_set_get_razor(package_set));
   48.51 +    g_object_unref(package_set);
   48.52 +    g_object_unref(transaction);
   48.53 +}
   48.54 +
   48.55 +static PloverTransaction *update_noop(void)
   48.56 +{
   48.57 +    PloverTransaction *transaction;
   48.58 +    struct razor_install_iterator *iter;
   48.59 +    struct razor_package *pkg;
   48.60 +    enum razor_install_action action;
   48.61 +    int count;
   48.62 +    GError *err=NULL;
   48.63 +    g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE);
   48.64 +    transaction=plover_transaction_new_update("../yum-repo-test-dir","/test",
   48.65 +      NULL,&err);
   48.66 +    if (!transaction && err)
   48.67 +	g_error("../yum-repo-test-dir: %s",err->message);
   48.68 +    g_assert(PLOVER_IS_TRANSACTION(transaction));
   48.69 +    g_assert(!err);
   48.70 +    g_assert(!plover_transaction_get_unsatisfied(transaction));
   48.71 +    iter=plover_transaction_get_install_iterator(transaction,&err);
   48.72 +    if (!iter && err)
   48.73 +	g_error("plover_transaction_get_install_iterator: %s",err->message);
   48.74 +    g_assert(iter);
   48.75 +    g_assert(!err);
   48.76 +    g_assert(!razor_install_iterator_next(iter,&pkg,&action,&count));
   48.77 +    return transaction;
   48.78 +}
   48.79 +
   48.80 +static void test_update_noop(void)
   48.81 +{
   48.82 +    PloverTransaction *transaction;
   48.83 +    transaction=update_noop();
   48.84 +    g_object_unref(transaction);
   48.85 +}
   48.86 +
   48.87 +static void test_update_nonexistant(void)
   48.88 +{
   48.89 +    PloverTransaction *transaction;
   48.90 +    char *pkgs[]={"nonexistant",NULL};
   48.91 +    GError *err=NULL;
   48.92 +    g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE);
   48.93 +    transaction=plover_transaction_new_update("../yum-repo-test-dir","/test",
   48.94 +      pkgs,&err);
   48.95 +    g_assert(!transaction);
   48.96 +    g_assert(g_error_matches(err,PLOVER_GENERAL_ERROR,
   48.97 +      PLOVER_GENERAL_ERROR_NO_SUCH_PACKAGE));
   48.98 +    g_clear_error(&err);
   48.99 +}
  48.100 +
  48.101 +static void test_install(void)
  48.102 +{
  48.103 +    PloverTransaction *transaction;
  48.104 +    struct razor_set *next;
  48.105 +    struct razor_install_iterator *iter;
  48.106 +    struct razor_package *pkg;
  48.107 +    enum razor_install_action action;
  48.108 +    int count;
  48.109 +    char *name;
  48.110 +    char *pkgs[]={"zip",NULL};
  48.111 +    GError *err=NULL;
  48.112 +    g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE);
  48.113 +    transaction=plover_transaction_new_install("../yum-repo-test-dir","/test",
  48.114 +      pkgs,&err);
  48.115 +    if (!transaction && err)
  48.116 +	g_error("../yum-repo-test-dir: %s",err->message);
  48.117 +    g_assert(PLOVER_IS_TRANSACTION(transaction));
  48.118 +    g_assert(!err);
  48.119 +    g_assert(!plover_transaction_get_unsatisfied(transaction));
  48.120 +    next=plover_transaction_get_next_set(transaction,&err);
  48.121 +    if (!next && err)
  48.122 +	g_error("plover_transaction_get_next_set: %s",err->message);
  48.123 +    g_assert(next);
  48.124 +    g_assert(!err);
  48.125 +    iter=plover_transaction_get_install_iterator(transaction,&err);
  48.126 +    if (!iter && err)
  48.127 +	g_error("plover_transaction_get_install_iterator: %s",err->message);
  48.128 +    g_assert(iter);
  48.129 +    g_assert(!err);
  48.130 +    g_assert(razor_install_iterator_next(iter,&pkg,&action,&count));
  48.131 +    g_assert_cmpint(action,==,RAZOR_INSTALL_ACTION_ADD);
  48.132 +    g_assert_cmpint(count,==,1);
  48.133 +    razor_package_get_details(next,pkg,RAZOR_DETAIL_NAME,&name,
  48.134 +      RAZOR_DETAIL_LAST);
  48.135 +    g_assert_cmpstr(name,==,"zip");
  48.136 +    g_assert(!razor_install_iterator_next(iter,&pkg,&action,&count));
  48.137 +    g_object_unref(transaction);
  48.138 +}
  48.139 +
  48.140 +static void test_install_nonexistant(void)
  48.141 +{
  48.142 +    PloverTransaction *transaction;
  48.143 +    char *pkgs[]={"nonexistant",NULL};
  48.144 +    GError *err=NULL;
  48.145 +    g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE);
  48.146 +    transaction=plover_transaction_new_install("../yum-repo-test-dir","/test",
  48.147 +      pkgs,&err);
  48.148 +    g_assert(!transaction);
  48.149 +    g_assert(g_error_matches(err,PLOVER_GENERAL_ERROR,
  48.150 +      PLOVER_GENERAL_ERROR_NO_SUCH_PACKAGE));
  48.151 +    g_clear_error(&err);
  48.152 +}
  48.153 +
  48.154 +static void test_install_uninstallable(void)
  48.155 +{
  48.156 +    PloverTransaction *transaction;
  48.157 +    struct razor_set *next;
  48.158 +    struct razor_install_iterator *iter;
  48.159 +    struct razor_package *pkg;
  48.160 +    enum razor_install_action action;
  48.161 +    int count;
  48.162 +    char *name;
  48.163 +    char *pkgs[]={"uninstallable",NULL};
  48.164 +    GError *err=NULL;
  48.165 +    g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE);
  48.166 +    transaction=plover_transaction_new_install("../yum-repo-test-dir","/test",
  48.167 +      pkgs,&err);
  48.168 +    if (!transaction && err)
  48.169 +	g_error("../yum-repo-test-dir: %s",err->message);
  48.170 +    g_assert(PLOVER_IS_TRANSACTION(transaction));
  48.171 +    g_assert(!err);
  48.172 +    g_assert_cmpstr(plover_transaction_get_unsatisfied(transaction),==,NULL);
  48.173 +    next=plover_transaction_get_next_set(transaction,&err);
  48.174 +    if (!next && err)
  48.175 +	g_error("plover_transaction_get_next_set: %s",err->message);
  48.176 +    g_assert(next);
  48.177 +    g_assert(!err);
  48.178 +    iter=plover_transaction_get_install_iterator(transaction,&err);
  48.179 +    if (!iter && err)
  48.180 +	g_error("plover_transaction_get_install_iterator: %s",err->message);
  48.181 +    g_assert(iter);
  48.182 +    g_assert(!err);
  48.183 +    g_assert(razor_install_iterator_next(iter,&pkg,&action,&count));
  48.184 +    g_assert_cmpint(action,==,RAZOR_INSTALL_ACTION_ADD);
  48.185 +    g_assert_cmpint(count,==,1);
  48.186 +    razor_package_get_details(next,pkg,RAZOR_DETAIL_NAME,&name,
  48.187 +      RAZOR_DETAIL_LAST);
  48.188 +    g_assert_cmpstr(name,==,"uninstallable");
  48.189 +    g_assert(!razor_install_iterator_next(iter,&pkg,&action,&count));
  48.190 +    g_assert(!plover_transaction_commit(transaction,NULL,&err));
  48.191 +    g_assert_cmpint(err->domain,==,PLOVER_RAZOR_ERROR);
  48.192 +    g_assert_cmpint(err->code,==,RAZOR_GENERAL_ERROR_FAILED);
  48.193 +    g_clear_error(&err);
  48.194 +    g_object_unref(transaction);
  48.195 +}
  48.196 +
  48.197 +static void test_unsatisfied(void)
  48.198 +{
  48.199 +    PloverTransaction *transaction;
  48.200 +    struct razor_install_iterator *iter;
  48.201 +    char *pkgs[]={"unsatisfiable",NULL};
  48.202 +    const char *s;
  48.203 +    GError *err=NULL;
  48.204 +    g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE);
  48.205 +    transaction=plover_transaction_new_install("../yum-repo-test-dir","/test",
  48.206 +      pkgs,&err);
  48.207 +    if (!transaction && err)
  48.208 +	g_error("../yum-repo-test-dir: %s",err->message);
  48.209 +    g_assert(PLOVER_IS_TRANSACTION(transaction));
  48.210 +    g_assert(!err);
  48.211 +    iter=plover_transaction_get_install_iterator(transaction,&err);
  48.212 +    g_assert(!iter);
  48.213 +    g_assert(g_error_matches(err,PLOVER_GENERAL_ERROR,
  48.214 +      PLOVER_GENERAL_ERROR_REQUIREMENTS_NOT_MET));
  48.215 +    g_clear_error(&err);
  48.216 +    s=plover_transaction_get_unsatisfied(transaction);
  48.217 +    g_assert_cmpstr(s,!=,NULL);
  48.218 +    g_assert_cmpstr(s,!=,"");
  48.219 +    g_object_unref(transaction);
  48.220 +}
  48.221 +
  48.222 +static void test_remove(void)
  48.223 +{
  48.224 +    PloverTransaction *transaction;
  48.225 +    struct razor_set *system;
  48.226 +    struct razor_install_iterator *iter;
  48.227 +    struct razor_package *pkg;
  48.228 +    enum razor_install_action action;
  48.229 +    int count;
  48.230 +    char *name;
  48.231 +    char *pkgs[]={"zappy-tools",NULL};
  48.232 +    GError *err=NULL;
  48.233 +    g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE);
  48.234 +    transaction=plover_transaction_new_remove(pkgs,&err);
  48.235 +    if (!transaction && err)
  48.236 +	g_error("zappy-tools: %s",err->message);
  48.237 +    g_assert(PLOVER_IS_TRANSACTION(transaction));
  48.238 +    g_assert(!err);
  48.239 +    system=plover_transaction_get_system_set(transaction);
  48.240 +    g_assert(system);
  48.241 +    iter=plover_transaction_get_install_iterator(transaction,&err);
  48.242 +    if (!iter && err)
  48.243 +	g_error("plover_transaction_get_install_iterator: %s",err->message);
  48.244 +    g_assert(iter);
  48.245 +    g_assert(!err);
  48.246 +    g_assert(razor_install_iterator_next(iter,&pkg,&action,&count));
  48.247 +    g_assert_cmpint(action,==,RAZOR_INSTALL_ACTION_REMOVE);
  48.248 +    g_assert_cmpint(count,==,0);
  48.249 +    razor_package_get_details(system,pkg,RAZOR_DETAIL_NAME,&name,
  48.250 +      RAZOR_DETAIL_LAST);
  48.251 +    g_assert_cmpstr(name,==,"zappy-tools");
  48.252 +    g_assert(!razor_install_iterator_next(iter,&pkg,&action,&count));
  48.253 +    g_object_unref(transaction);
  48.254 +}
  48.255 +
  48.256 +static void test_remove_nonexistant(void)
  48.257 +{
  48.258 +    PloverTransaction *transaction;
  48.259 +    char *pkgs[]={"nonexistant",NULL};
  48.260 +    GError *err=NULL;
  48.261 +    g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE);
  48.262 +    transaction=plover_transaction_new_remove(pkgs,&err);
  48.263 +    g_assert(!transaction);
  48.264 +    g_assert(g_error_matches(err,PLOVER_GENERAL_ERROR,
  48.265 +      PLOVER_GENERAL_ERROR_NO_SUCH_PACKAGE));
  48.266 +    g_clear_error(&err);
  48.267 +}
  48.268 +
  48.269 +GMainLoop *test_commit_mainloop;
  48.270 +
  48.271 +static void test_commit_callback(GObject *source,GAsyncResult *result,
  48.272 +  gpointer user_data)
  48.273 +{
  48.274 +    PloverTransaction *transaction=user_data;
  48.275 +    GError *err=NULL;
  48.276 +    if (!plover_transaction_commit_finish(transaction,result,&err))
  48.277 +    {
  48.278 +	g_assert(err && err->message);
  48.279 +	g_error("test-commit: %s",err->message);
  48.280 +    }
  48.281 +    g_assert(!err);
  48.282 +    g_main_loop_quit(test_commit_mainloop);
  48.283 +}
  48.284 +
  48.285 +static void test_commit(void)
  48.286 +{
  48.287 +    PloverTransaction *transaction;
  48.288 +    test_commit_mainloop=g_main_loop_new(NULL,FALSE);
  48.289 +    transaction=update_noop();
  48.290 +    plover_transaction_commit_async(transaction,NULL,test_commit_callback,
  48.291 +      transaction);
  48.292 +    g_main_loop_run(test_commit_mainloop);
  48.293 +    g_main_loop_unref(test_commit_mainloop);
  48.294 +    g_object_unref(transaction);
  48.295 +}
  48.296 +
  48.297 +static void test_remove_with_leaves(void)
  48.298 +{
  48.299 +    PloverTransaction *transaction;
  48.300 +    struct razor_set *system;
  48.301 +    struct razor_install_iterator *iter;
  48.302 +    struct razor_package *pkg;
  48.303 +    enum razor_install_action action;
  48.304 +    int count;
  48.305 +    char *name;
  48.306 +    char *pkgs[]={"zappy-tools",NULL};
  48.307 +    GError *err=NULL;
  48.308 +    g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE);
  48.309 +    transaction=plover_transaction_new_remove_with_leaves(pkgs,&err);
  48.310 +    if (!transaction && err)
  48.311 +	g_error("zappy-tools: %s",err->message);
  48.312 +    g_assert(PLOVER_IS_TRANSACTION(transaction));
  48.313 +    g_assert(!err);
  48.314 +    system=plover_transaction_get_system_set(transaction);
  48.315 +    g_assert(system);
  48.316 +    iter=plover_transaction_get_install_iterator(transaction,&err);
  48.317 +    if (!iter && err)
  48.318 +	g_error("plover_transaction_get_install_iterator: %s",err->message);
  48.319 +    g_assert(iter);
  48.320 +    g_assert(!err);
  48.321 +    g_assert(razor_install_iterator_next(iter,&pkg,&action,&count));
  48.322 +    g_assert_cmpint(action,==,RAZOR_INSTALL_ACTION_REMOVE);
  48.323 +    g_assert_cmpint(count,==,0);
  48.324 +    razor_package_get_details(system,pkg,RAZOR_DETAIL_NAME,&name,
  48.325 +      RAZOR_DETAIL_LAST);
  48.326 +    g_assert(!strcmp(name,"zappy-tools") || !strcmp(name,"zappy"));
  48.327 +    g_assert(razor_install_iterator_next(iter,&pkg,&action,&count));
  48.328 +    g_assert_cmpint(action,==,RAZOR_INSTALL_ACTION_REMOVE);
  48.329 +    g_assert_cmpint(count,==,0);
  48.330 +    razor_package_get_details(system,pkg,RAZOR_DETAIL_NAME,&name,
  48.331 +      RAZOR_DETAIL_LAST);
  48.332 +    g_assert(!strcmp(name,"zappy-tools") || !strcmp(name,"zappy"));
  48.333 +    g_assert(!razor_install_iterator_next(iter,&pkg,&action,&count));
  48.334 +    g_object_unref(transaction);
  48.335 +}
  48.336 +
  48.337 +static void test_remove_nonexistant_with_leaves(void)
  48.338 +{
  48.339 +    PloverTransaction *transaction;
  48.340 +    char *pkgs[]={"nonexistant",NULL};
  48.341 +    GError *err=NULL;
  48.342 +    g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE);
  48.343 +    transaction=plover_transaction_new_remove_with_leaves(pkgs,&err);
  48.344 +    g_assert(!transaction);
  48.345 +    g_assert(g_error_matches(err,PLOVER_GENERAL_ERROR,
  48.346 +      PLOVER_GENERAL_ERROR_NO_SUCH_PACKAGE));
  48.347 +    g_clear_error(&err);
  48.348 +}
  48.349 +
  48.350 +static void test_remove_all(void)
  48.351 +{
  48.352 +    int i;
  48.353 +    PloverTransaction *transaction;
  48.354 +    struct razor_set *system;
  48.355 +    struct razor_install_iterator *iter;
  48.356 +    struct razor_package *pkg;
  48.357 +    enum razor_install_action action;
  48.358 +    int count;
  48.359 +    char *name;
  48.360 +    GError *err=NULL;
  48.361 +    GList *expected=NULL,*lnk;
  48.362 +    g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE);
  48.363 +    transaction=plover_transaction_new_remove_with_leaves(NULL,&err);
  48.364 +    if (!transaction && err)
  48.365 +	g_error("remove-all: %s",err->message);
  48.366 +    g_assert(PLOVER_IS_TRANSACTION(transaction));
  48.367 +    g_assert(!err);
  48.368 +    system=plover_transaction_get_system_set(transaction);
  48.369 +    g_assert(system);
  48.370 +    for(i=0;i<G_N_ELEMENTS(zappy_packages);i++)
  48.371 +	expected=g_list_prepend(expected,
  48.372 +	  (gpointer)g_intern_string(zappy_packages[i]));
  48.373 +    iter=plover_transaction_get_install_iterator(transaction,&err);
  48.374 +    if (!iter && err)
  48.375 +	g_error("plover_transaction_get_install_iterator: %s",err->message);
  48.376 +    g_assert(iter);
  48.377 +    g_assert(!err);
  48.378 +    while(razor_install_iterator_next(iter,&pkg,&action,&count))
  48.379 +    {
  48.380 +	g_assert_cmpint(action,==,RAZOR_INSTALL_ACTION_REMOVE);
  48.381 +	g_assert_cmpint(count,==,0);
  48.382 +	razor_package_get_details(system,pkg,RAZOR_DETAIL_NAME,&name,
  48.383 +	  RAZOR_DETAIL_LAST);
  48.384 +	lnk=g_list_find(expected,g_intern_string(name));
  48.385 +	if (!lnk)
  48.386 +	    g_warning("Unexpected package to be removed: %s",name);
  48.387 +	else
  48.388 +	    expected=g_list_delete_link(expected,lnk);
  48.389 +    }
  48.390 +    if (expected)
  48.391 +	g_warning("%d package%s not removed, including %s",
  48.392 +	  g_list_length(expected),g_list_length(expected)==1?"":"s",
  48.393 +	  expected->data);
  48.394 +    g_object_unref(transaction);
  48.395 +}
  48.396 +
  48.397 +static void test_change_installed(void)
  48.398 +{
  48.399 +    PloverTransaction *transaction;
  48.400 +    PloverPackageSet *package_set;
  48.401 +    GError *err=NULL;
  48.402 +    transaction=plover_transaction_new();
  48.403 +    g_assert(PLOVER_IS_TRANSACTION(transaction));
  48.404 +    if (!plover_transaction_root_open(transaction,"../razor-test-dir",&err))
  48.405 +    {
  48.406 +	g_assert(err && err->message);
  48.407 +	g_error("../razor-test-dir: %s",err->message);
  48.408 +    }
  48.409 +    g_assert(!err);
  48.410 +    g_assert(plover_transaction_get_system_set(transaction));
  48.411 +    package_set=plover_package_set_new_from_yum("../yum-repo-test-dir",NULL,
  48.412 +      &err);
  48.413 +    if (!package_set)
  48.414 +	g_error("../yum-repo-test-dir: %s",err->message);
  48.415 +    plover_transaction_set_installed(transaction,package_set);
  48.416 +    g_object_unref(package_set);
  48.417 +    g_object_unref(transaction);
  48.418 +}
  48.419 +
  48.420 +int main(int argc,char **argv)
  48.421 +{
  48.422 +    g_test_init(&argc,&argv,NULL);
  48.423 +    razor_set_lua_loader("posix",(void (*)())luaopen_posix);
  48.424 +    g_test_bug_base("mailto:ali@juiblex.co.uk");
  48.425 +    g_test_add_func("/transaction/installed-system-set",
  48.426 +      test_installed_system_set);
  48.427 +    g_test_add_func("/transaction/update-noop",test_update_noop);
  48.428 +    g_test_add_func("/transaction/update-nonexistant",test_update_nonexistant);
  48.429 +    g_test_add_func("/transaction/install",test_install);
  48.430 +    g_test_add_func("/transaction/install-nonexistant",
  48.431 +      test_install_nonexistant);
  48.432 +    g_test_add_func("/transaction/install-uninstallable",
  48.433 +      test_install_uninstallable);
  48.434 +    g_test_add_func("/transaction/unsatisfied",test_unsatisfied);
  48.435 +    g_test_add_func("/transaction/remove",test_remove);
  48.436 +    g_test_add_func("/transaction/remove-nonexistant",test_remove_nonexistant);
  48.437 +    g_test_add_func("/transaction/commit",test_commit);
  48.438 +    g_test_add_func("/transaction/remove-with-leaves",test_remove_with_leaves);
  48.439 +    g_test_add_func("/transaction/remove-nonexistant-with-leaves",
  48.440 +      test_remove_nonexistant_with_leaves);
  48.441 +    g_test_add_func("/transaction/remove-all",test_remove_all);
  48.442 +    g_test_add_func("/transaction/change-installed",test_change_installed);
  48.443 +    return g_test_run();
  48.444 +}
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/tests/plover/test-util.c	Mon Jun 13 12:18:42 2016 +0100
    49.3 @@ -0,0 +1,136 @@
    49.4 +/*
    49.5 + * Copyright (C) 2016  J. Ali Harlow <ali@juiblex.co.uk>
    49.6 + *
    49.7 + * This program is free software; you can redistribute it and/or modify
    49.8 + * it under the terms of the GNU General Public License as published by
    49.9 + * the Free Software Foundation; either version 2 of the License, or
   49.10 + * (at your option) any later version.
   49.11 + *
   49.12 + * This program is distributed in the hope that it will be useful,
   49.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   49.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   49.15 + * GNU General Public License for more details.
   49.16 + *
   49.17 + * You should have received a copy of the GNU General Public License along
   49.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
   49.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   49.20 + */
   49.21 +
   49.22 +#include <stdlib.h>
   49.23 +#ifdef WIN32
   49.24 +#include <windows.h>
   49.25 +#endif
   49.26 +#include <sys/time.h>
   49.27 +#include <sys/errno.h>
   49.28 +#include <glib.h>
   49.29 +#include <zlib.h>
   49.30 +#include <razor.h>
   49.31 +#include <plover/plover.h>
   49.32 +
   49.33 +static void test_pre_install_prefix(void)
   49.34 +{
   49.35 +    gchar *pre_install_prefix;
   49.36 +    pre_install_prefix=plover_pre_install_prefix();
   49.37 +    g_assert_cmpstr(pre_install_prefix,!=,NULL);
   49.38 +    g_assert_cmpstr(pre_install_prefix,!=,"");
   49.39 +    g_free(pre_install_prefix);
   49.40 +}
   49.41 +
   49.42 +static void test_reports_directory(void)
   49.43 +{
   49.44 +    gchar *reports_directory;
   49.45 +    reports_directory=plover_get_reports_directory();
   49.46 +    g_assert_cmpstr(reports_directory,!=,NULL);
   49.47 +    g_assert_cmpstr(reports_directory,!=,"");
   49.48 +    g_free(reports_directory);
   49.49 +}
   49.50 +
   49.51 +static void test_program_directory(void)
   49.52 +{
   49.53 +    gchar *program_directory;
   49.54 +    program_directory=plover_get_program_directory("test-util");
   49.55 +    g_assert_cmpstr(program_directory,!=,NULL);
   49.56 +    g_assert_cmpstr(program_directory,!=,"");
   49.57 +    free(program_directory);
   49.58 +    program_directory=plover_get_program_directory("./test-util");
   49.59 +    g_assert_cmpstr(program_directory,!=,NULL);
   49.60 +    g_assert_cmpstr(program_directory,!=,"");
   49.61 +    free(program_directory);
   49.62 +}
   49.63 +
   49.64 +static void verify_error_propagation(int domain,int code)
   49.65 +{
   49.66 +    GError *src,*dest=NULL;
   49.67 +    struct razor_error *tmp=NULL;
   49.68 +    src=g_error_new_literal(domain,code,"test error");
   49.69 +    plover_propagate_g_error(&tmp,src);
   49.70 +    g_assert(tmp!=NULL);
   49.71 +    plover_propagate_razor_error(&dest,tmp);
   49.72 +    g_assert(dest!=NULL);
   49.73 +    g_assert_cmpint(dest->domain,==,domain);
   49.74 +    g_assert_cmpint(dest->code,==,code);
   49.75 +    g_assert_cmpstr(dest->message,==,"test error");
   49.76 +    g_error_free(dest);
   49.77 +}
   49.78 +
   49.79 +static void test_propagate_razor_error(void)
   49.80 +{
   49.81 +    verify_error_propagation(PLOVER_RAZOR_ERROR,RAZOR_GENERAL_ERROR_FAILED);
   49.82 +}
   49.83 +
   49.84 +static void test_propagate_posix_error(void)
   49.85 +{
   49.86 +    verify_error_propagation(PLOVER_POSIX_ERROR,ENOENT);
   49.87 +}
   49.88 +
   49.89 +static void test_propagate_mswin_error(void)
   49.90 +{
   49.91 +#ifdef WIN32
   49.92 +    verify_error_propagation(PLOVER_MSWIN_ERROR,ERROR_NOT_SUPPORTED);
   49.93 +#else
   49.94 +    verify_error_propagation(PLOVER_MSWIN_ERROR,0);
   49.95 +#endif
   49.96 +}
   49.97 +
   49.98 +static void test_propagate_zlib_error(void)
   49.99 +{
  49.100 +    verify_error_propagation(PLOVER_ZLIB_ERROR,Z_VERSION_ERROR);
  49.101 +}
  49.102 +
  49.103 +static void test_propagate_cancelled(void)
  49.104 +{
  49.105 +    verify_error_propagation(G_IO_ERROR,G_IO_ERROR_CANCELLED);
  49.106 +}
  49.107 +
  49.108 +static void test_propagate_other_error(void)
  49.109 +{
  49.110 +    GError *src,*dest=NULL;
  49.111 +    struct razor_error *tmp=NULL;
  49.112 +    src=g_error_new_literal(G_SHELL_ERROR,G_SHELL_ERROR_FAILED,"test error");
  49.113 +    plover_propagate_g_error(&tmp,src);
  49.114 +    g_assert(tmp!=NULL);
  49.115 +    plover_propagate_razor_error(&dest,tmp);
  49.116 +    g_assert(dest!=NULL);
  49.117 +    g_assert_cmpint(dest->domain,==,PLOVER_RAZOR_ERROR);
  49.118 +    g_assert_cmpint(dest->code,==,RAZOR_GENERAL_ERROR_FAILED);
  49.119 +    g_assert_cmpstr(dest->message,==,"test error");
  49.120 +    g_error_free(dest);
  49.121 +}
  49.122 +
  49.123 +int main(int argc,char **argv)
  49.124 +{
  49.125 +    int retval;
  49.126 +    g_test_init(&argc,&argv,NULL);
  49.127 +    g_test_bug_base("mailto:ali@juiblex.co.uk");
  49.128 +    g_test_add_func("/util/pre-install-prefix",test_pre_install_prefix);
  49.129 +    g_test_add_func("/util/reports-directory",test_reports_directory);
  49.130 +    g_test_add_func("/util/program-directory",test_program_directory);
  49.131 +    g_test_add_func("/util/propagate-razor-error",test_propagate_razor_error);
  49.132 +    g_test_add_func("/util/propagate-posix-error",test_propagate_posix_error);
  49.133 +    g_test_add_func("/util/propagate-mswin-error",test_propagate_mswin_error);
  49.134 +    g_test_add_func("/util/propagate-zlib-error",test_propagate_zlib_error);
  49.135 +    g_test_add_func("/util/propagate-cancelled",test_propagate_cancelled);
  49.136 +    g_test_add_func("/util/propagate-other-error",test_propagate_other_error);
  49.137 +    retval=g_test_run();
  49.138 +    return retval;
  49.139 +}
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/tests/plover/test-vector.c	Mon Jun 13 12:18:42 2016 +0100
    50.3 @@ -0,0 +1,165 @@
    50.4 +/*
    50.5 + * Copyright (C) 2016  J. Ali Harlow <ali@juiblex.co.uk>
    50.6 + *
    50.7 + * This program is free software; you can redistribute it and/or modify
    50.8 + * it under the terms of the GNU General Public License as published by
    50.9 + * the Free Software Foundation; either version 2 of the License, or
   50.10 + * (at your option) any later version.
   50.11 + *
   50.12 + * This program is distributed in the hope that it will be useful,
   50.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   50.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   50.15 + * GNU General Public License for more details.
   50.16 + *
   50.17 + * You should have received a copy of the GNU General Public License along
   50.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
   50.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   50.20 + */
   50.21 +
   50.22 +#include <stdlib.h>
   50.23 +#include <glib.h>
   50.24 +#include <razor.h>
   50.25 +#include <plover/plover.h>
   50.26 +
   50.27 +static void test_empty(void)
   50.28 +{
   50.29 +    struct plover_vector *vector;
   50.30 +    char *display;
   50.31 +    vector=plover_vector_new();
   50.32 +    g_assert(vector);
   50.33 +    display=plover_vector_format_for_display(vector);
   50.34 +    g_assert_cmpstr(display,==,"none");
   50.35 +    free(display);
   50.36 +    plover_vector_free(vector);
   50.37 +}
   50.38 +
   50.39 +static void test_single(void)
   50.40 +{
   50.41 +    struct plover_vector *vector;
   50.42 +    char *display;
   50.43 +    vector=plover_vector_new();
   50.44 +    g_assert(vector);
   50.45 +    plover_vector_append(vector,"single");
   50.46 +    display=plover_vector_format_for_display(vector);
   50.47 +    g_assert_cmpstr(display,==,"single");
   50.48 +    free(display);
   50.49 +    plover_vector_free(vector);
   50.50 +}
   50.51 +
   50.52 +static void test_pair(void)
   50.53 +{
   50.54 +    struct plover_vector *vector;
   50.55 +    char *display;
   50.56 +    vector=plover_vector_new();
   50.57 +    g_assert(vector);
   50.58 +    plover_vector_append(vector,"one");
   50.59 +    plover_vector_append(vector,"two");
   50.60 +    display=plover_vector_format_for_display(vector);
   50.61 +    g_assert_cmpstr(display,==,"one and two");
   50.62 +    free(display);
   50.63 +    plover_vector_free(vector);
   50.64 +}
   50.65 +
   50.66 +static void test_triple(void)
   50.67 +{
   50.68 +    struct plover_vector *vector;
   50.69 +    char *display;
   50.70 +    vector=plover_vector_new();
   50.71 +    g_assert(vector);
   50.72 +    plover_vector_append(vector,"one");
   50.73 +    plover_vector_append(vector,"two");
   50.74 +    plover_vector_append(vector,"three");
   50.75 +    display=plover_vector_format_for_display(vector);
   50.76 +    g_assert_cmpstr(display,==,"one, two and three");
   50.77 +    free(display);
   50.78 +    plover_vector_free(vector);
   50.79 +}
   50.80 +
   50.81 +static void test_sort(void)
   50.82 +{
   50.83 +    struct plover_vector *vector;
   50.84 +    char *display;
   50.85 +    vector=plover_vector_new();
   50.86 +    g_assert(vector);
   50.87 +    plover_vector_append(vector,"one");
   50.88 +    plover_vector_append(vector,"two");
   50.89 +    plover_vector_append(vector,"three");
   50.90 +    plover_vector_sort(vector);
   50.91 +    display=plover_vector_format_for_display(vector);
   50.92 +    g_assert_cmpstr(display,==,"one, three and two");
   50.93 +    free(display);
   50.94 +    plover_vector_free(vector);
   50.95 +}
   50.96 +
   50.97 +static void test_dup(void)
   50.98 +{
   50.99 +    struct plover_vector *vector,*vector2;
  50.100 +    char *display;
  50.101 +    vector=plover_vector_new();
  50.102 +    g_assert(vector);
  50.103 +    plover_vector_append(vector,"one");
  50.104 +    plover_vector_append(vector,"two");
  50.105 +    plover_vector_append(vector,"three");
  50.106 +    vector2=plover_vector_dup(vector);
  50.107 +    plover_vector_sort(vector2);
  50.108 +    display=plover_vector_format_for_display(vector);
  50.109 +    g_assert_cmpstr(display,==,"one, two and three");
  50.110 +    free(display);
  50.111 +    display=plover_vector_format_for_display(vector2);
  50.112 +    g_assert_cmpstr(display,==,"one, three and two");
  50.113 +    free(display);
  50.114 +    plover_vector_free(vector);
  50.115 +    plover_vector_free(vector2);
  50.116 +}
  50.117 +
  50.118 +static void test_contains(void)
  50.119 +{
  50.120 +    struct plover_vector *vector;
  50.121 +    vector=plover_vector_new();
  50.122 +    g_assert(vector);
  50.123 +    plover_vector_append(vector,"one");
  50.124 +    plover_vector_append(vector,"two");
  50.125 +    plover_vector_append(vector,"three");
  50.126 +    g_assert(plover_vector_contains(vector,"one"));
  50.127 +    g_assert(plover_vector_contains(vector,"two"));
  50.128 +    g_assert(plover_vector_contains(vector,"three"));
  50.129 +    g_assert(!plover_vector_contains(vector,"four"));
  50.130 +    plover_vector_free(vector);
  50.131 +}
  50.132 +
  50.133 +static void test_long(void)
  50.134 +{
  50.135 +    int i;
  50.136 +    struct plover_vector *vector;
  50.137 +    char letter[2],*display;
  50.138 +    vector=plover_vector_new();
  50.139 +    g_assert(vector);
  50.140 +    letter[1]=0;
  50.141 +    for(i=0;i<26;i++)
  50.142 +    {
  50.143 +	letter[0]='a'+i;
  50.144 +	plover_vector_append(vector,letter);
  50.145 +    }
  50.146 +    display=plover_vector_format_for_display(vector);
  50.147 +    g_assert_cmpstr(display,==,"a, b, c, d, e, f, g, h, i, j, k, l, "
  50.148 +      "m, n, o, p, q, r, s, t, u, v, w, x, y and z");
  50.149 +    free(display);
  50.150 +    plover_vector_free(vector);
  50.151 +}
  50.152 +
  50.153 +int main(int argc,char **argv)
  50.154 +{
  50.155 +    int retval;
  50.156 +    g_test_init(&argc,&argv,NULL);
  50.157 +    g_test_bug_base("mailto:ali@juiblex.co.uk");
  50.158 +    g_test_add_func("/vector/empty",test_empty);
  50.159 +    g_test_add_func("/vector/single",test_single);
  50.160 +    g_test_add_func("/vector/pair",test_pair);
  50.161 +    g_test_add_func("/vector/triple",test_triple);
  50.162 +    g_test_add_func("/vector/sort",test_sort);
  50.163 +    g_test_add_func("/vector/dup",test_dup);
  50.164 +    g_test_add_func("/vector/contains",test_contains);
  50.165 +    g_test_add_func("/vector/long",test_long);
  50.166 +    retval=g_test_run();
  50.167 +    return retval;
  50.168 +}
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/tests/uninstallable.spec	Mon Jun 13 12:18:42 2016 +0100
    51.3 @@ -0,0 +1,30 @@
    51.4 +%define _source_payload w9.gzdio
    51.5 +%define _binary_payload w9.gzdio
    51.6 +
    51.7 +Name:      uninstallable
    51.8 +Summary:   A package that cannot be installed
    51.9 +Group:     Test
   51.10 +License:   GPL
   51.11 +URL:       http://www.juiblex.co.uk/beach
   51.12 +Version:   1
   51.13 +Release:   1
   51.14 +Source:    uninstallable.tar
   51.15 +BuildArch: noarch
   51.16 +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   51.17 +Prefix:    /usr
   51.18 +
   51.19 +%description
   51.20 +A package that cannot be installed because its pre script always fails.
   51.21 +
   51.22 +%prep
   51.23 +
   51.24 +%build
   51.25 +
   51.26 +%install
   51.27 +
   51.28 +%clean
   51.29 +
   51.30 +%pre -p <lua>
   51.31 +error("Package is uninstallable")
   51.32 +
   51.33 +%files
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/tests/unsatisfiable.spec	Mon Jun 13 12:18:42 2016 +0100
    52.3 @@ -0,0 +1,31 @@
    52.4 +%define _source_payload w9.gzdio
    52.5 +%define _binary_payload w9.gzdio
    52.6 +
    52.7 +Name:      unsatisfiable
    52.8 +Summary:   A package that cannot be installed
    52.9 +Group:     Test
   52.10 +License:   GPL
   52.11 +URL:       http://www.juiblex.co.uk/beach
   52.12 +Version:   1
   52.13 +Release:   1
   52.14 +Source:    unsatisfiable.tar
   52.15 +BuildArch: noarch
   52.16 +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   52.17 +Prefix:    /usr
   52.18 +Requires:  pony > 0, pony-tail >= 1, pony-feet <= 4, pony-lame < 1
   52.19 +Conflicts: money
   52.20 +Obsoletes: life
   52.21 +
   52.22 +%description
   52.23 +A package that cannot be installed because it requires a property (pony)
   52.24 +that is not provided by any package.
   52.25 +
   52.26 +%prep
   52.27 +
   52.28 +%build
   52.29 +
   52.30 +%install
   52.31 +
   52.32 +%clean
   52.33 +
   52.34 +%files
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/tests/xvfb-run	Mon Jun 13 12:18:42 2016 +0100
    53.3 @@ -0,0 +1,190 @@
    53.4 +#!/bin/sh
    53.5 +
    53.6 +# This script starts an instance of Xvfb, the "fake" X server, runs a command
    53.7 +# with that server available, and kills the X server when done.  The return
    53.8 +# value of the command becomes the return value of this script.
    53.9 +#
   53.10 +# If anyone is using this to build a Debian package, make sure the package
   53.11 +# Build-Depends on xvfb and xauth.
   53.12 +
   53.13 +set -e
   53.14 +
   53.15 +PROGNAME=xvfb-run
   53.16 +SERVERNUM=99
   53.17 +AUTHFILE=
   53.18 +ERRORFILE=/dev/null
   53.19 +XVFBARGS="-screen 0 640x480x8"
   53.20 +LISTENTCP="-nolisten tcp"
   53.21 +XAUTHPROTO=.
   53.22 +
   53.23 +# Query the terminal to establish a default number of columns to use for
   53.24 +# displaying messages to the user.  This is used only as a fallback in the event
   53.25 +# the COLUMNS variable is not set.  ($COLUMNS can react to SIGWINCH while the
   53.26 +# script is running, and this cannot, only being calculated once.)
   53.27 +DEFCOLUMNS=$(stty size 2>/dev/null | awk '{print $2}') || true
   53.28 +if ! expr "$DEFCOLUMNS" : "[[:digit:]]\+$" >/dev/null 2>&1; then
   53.29 +    DEFCOLUMNS=80
   53.30 +fi
   53.31 +
   53.32 +# Display a message, wrapping lines at the terminal width.
   53.33 +message () {
   53.34 +    echo "$PROGNAME: $*" | fmt -t -w ${COLUMNS:-$DEFCOLUMNS}
   53.35 +}
   53.36 +
   53.37 +# Display an error message.
   53.38 +error () {
   53.39 +    message "error: $*" >&2
   53.40 +}
   53.41 +
   53.42 +# Display a usage message.
   53.43 +usage () {
   53.44 +    if [ -n "$*" ]; then
   53.45 +        message "usage error: $*"
   53.46 +    fi
   53.47 +    cat <<EOF
   53.48 +Usage: $PROGNAME [OPTION ...] COMMAND
   53.49 +Run COMMAND (usually an X client) in a virtual X server environment.
   53.50 +Options:
   53.51 +-a        --auto-servernum          try to get a free server number, starting at
   53.52 +                                    --server-num
   53.53 +-e FILE   --error-file=FILE         file used to store xauth errors and Xvfb
   53.54 +                                    output (default: $ERRORFILE)
   53.55 +-f FILE   --auth-file=FILE          file used to store auth cookie
   53.56 +                                    (default: ./.Xauthority)
   53.57 +-h        --help                    display this usage message and exit
   53.58 +-n NUM    --server-num=NUM          server number to use (default: $SERVERNUM)
   53.59 +-l        --listen-tcp              enable TCP port listening in the X server
   53.60 +-p PROTO  --xauth-protocol=PROTO    X authority protocol name to use
   53.61 +                                    (default: xauth command's default)
   53.62 +-s ARGS   --server-args=ARGS        arguments (other than server number and
   53.63 +                                    "-nolisten tcp") to pass to the Xvfb server
   53.64 +                                    (default: "$XVFBARGS")
   53.65 +EOF
   53.66 +}
   53.67 +
   53.68 +# Find a free server number by looking at .X*-lock files in /tmp.
   53.69 +find_free_servernum() {
   53.70 +    # Sadly, the "local" keyword is not POSIX.  Leave the next line commented in
   53.71 +    # the hope Debian Policy eventually changes to allow it in /bin/sh scripts
   53.72 +    # anyway.
   53.73 +    #local i
   53.74 +
   53.75 +    i=$SERVERNUM
   53.76 +    while [ -f /tmp/.X$i-lock ]; do
   53.77 +        i=$(($i + 1))
   53.78 +    done
   53.79 +    echo $i
   53.80 +}
   53.81 +
   53.82 +# Clean up files
   53.83 +clean_up() {
   53.84 +    if [ -e "$AUTHFILE" ]; then
   53.85 +        XAUTHORITY=$AUTHFILE xauth remove ":$SERVERNUM" >>"$ERRORFILE" 2>&1
   53.86 +    fi
   53.87 +    if [ -n "$XVFB_RUN_TMPDIR" ]; then
   53.88 +        if ! rm -r "$XVFB_RUN_TMPDIR"; then
   53.89 +            error "problem while cleaning up temporary directory"
   53.90 +            exit 5
   53.91 +        fi
   53.92 +    fi
   53.93 +    if [ -n "$XVFBPID" ]; then
   53.94 +        kill "$XVFBPID" >>"$ERRORFILE" 2>&1
   53.95 +    fi
   53.96 +}
   53.97 +
   53.98 +# Parse the command line.
   53.99 +ARGS=$(getopt --options +ae:f:hn:lp:s:w: \
  53.100 +       --long auto-servernum,error-file:,auth-file:,help,server-num:,listen-tcp,xauth-protocol:,server-args:,wait: \
  53.101 +       --name "$PROGNAME" -- "$@")
  53.102 +GETOPT_STATUS=$?
  53.103 +
  53.104 +if [ $GETOPT_STATUS -ne 0 ]; then
  53.105 +    error "internal error; getopt exited with status $GETOPT_STATUS"
  53.106 +    exit 6
  53.107 +fi
  53.108 +
  53.109 +eval set -- "$ARGS"
  53.110 +
  53.111 +while :; do
  53.112 +    case "$1" in
  53.113 +        -a|--auto-servernum) SERVERNUM=$(find_free_servernum); AUTONUM="yes" ;;
  53.114 +        -e|--error-file) ERRORFILE="$2"; shift ;;
  53.115 +        -f|--auth-file) AUTHFILE="$2"; shift ;;
  53.116 +        -h|--help) SHOWHELP="yes" ;;
  53.117 +        -n|--server-num) SERVERNUM="$2"; shift ;;
  53.118 +        -l|--listen-tcp) LISTENTCP="" ;;
  53.119 +        -p|--xauth-protocol) XAUTHPROTO="$2"; shift ;;
  53.120 +        -s|--server-args) XVFBARGS="$2"; shift ;;
  53.121 +        -w|--wait) shift ;;
  53.122 +        --) shift; break ;;
  53.123 +        *) error "internal error; getopt permitted \"$1\" unexpectedly"
  53.124 +           exit 6
  53.125 +           ;;
  53.126 +    esac
  53.127 +    shift
  53.128 +done
  53.129 +
  53.130 +if [ "$SHOWHELP" ]; then
  53.131 +    usage
  53.132 +    exit 0
  53.133 +fi
  53.134 +
  53.135 +if [ -z "$*" ]; then
  53.136 +    usage "need a command to run" >&2
  53.137 +    exit 2
  53.138 +fi
  53.139 +
  53.140 +if ! which xauth >/dev/null; then
  53.141 +    error "xauth command not found"
  53.142 +    exit 3
  53.143 +fi
  53.144 +
  53.145 +# tidy up after ourselves
  53.146 +trap clean_up EXIT
  53.147 +
  53.148 +# If the user did not specify an X authorization file to use, set up a temporary
  53.149 +# directory to house one.
  53.150 +if [ -z "$AUTHFILE" ]; then
  53.151 +    XVFB_RUN_TMPDIR="$(mktemp -d -t $PROGNAME.XXXXXX)"
  53.152 +    # Create empty file to avoid xauth warning
  53.153 +    AUTHFILE=$(tempfile -n "$XVFB_RUN_TMPDIR/Xauthority")
  53.154 +fi
  53.155 +
  53.156 +# Start Xvfb.
  53.157 +MCOOKIE=$(mcookie)
  53.158 +tries=10
  53.159 +while [ $tries -gt 0 ]; do
  53.160 +    tries=$(( $tries - 1 ))
  53.161 +    XAUTHORITY=$AUTHFILE xauth source - << EOF >>"$ERRORFILE" 2>&1
  53.162 +add :$SERVERNUM $XAUTHPROTO $MCOOKIE
  53.163 +EOF
  53.164 +    # handle SIGUSR1 so Xvfb knows to send a signal when it's ready to accept
  53.165 +    # connections
  53.166 +    trap : USR1
  53.167 +    (trap '' USR1; exec Xvfb ":$SERVERNUM" $XVFBARGS $LISTENTCP -auth $AUTHFILE >>"$ERRORFILE" 2>&1) &
  53.168 +    XVFBPID=$!
  53.169 +
  53.170 +    wait || :
  53.171 +    if kill -0 $XVFBPID 2>/dev/null; then
  53.172 +        break
  53.173 +    elif [ -n "$AUTONUM" ]; then
  53.174 +        # The display is in use so try another one (if '-a' was specified).
  53.175 +        SERVERNUM=$((SERVERNUM + 1))
  53.176 +        SERVERNUM=$(find_free_servernum)
  53.177 +        continue
  53.178 +    fi
  53.179 +    error "Xvfb failed to start" >&2
  53.180 +    XVFBPID=
  53.181 +    exit 1
  53.182 +done
  53.183 +
  53.184 +# Start the command and save its exit status.
  53.185 +set +e
  53.186 +DISPLAY=:$SERVERNUM XAUTHORITY=$AUTHFILE "$@" 2>&1
  53.187 +RETVAL=$?
  53.188 +set -e
  53.189 +
  53.190 +# Return the executed command's exit status.
  53.191 +exit $RETVAL
  53.192 +
  53.193 +# vim:set ai et sts=4 sw=4 tw=80:
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/tests/zap.spec	Mon Jun 13 12:18:42 2016 +0100
    54.3 @@ -0,0 +1,29 @@
    54.4 +%define _source_payload w9.gzdio
    54.5 +%define _binary_payload w9.gzdio
    54.6 +
    54.7 +Name:      zap
    54.8 +Summary:   Test package
    54.9 +Group:     Test
   54.10 +License:   GPL
   54.11 +Version:   1
   54.12 +Release:   1
   54.13 +Source:    zap.tar
   54.14 +BuildArch: noarch
   54.15 +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   54.16 +Prefix:    /usr
   54.17 +
   54.18 +%description
   54.19 +Test package
   54.20 +
   54.21 +%prep
   54.22 +
   54.23 +%build
   54.24 +
   54.25 +%install
   54.26 +mkdir -p $RPM_BUILD_ROOT/usr/bin
   54.27 +touch $RPM_BUILD_ROOT/usr/bin/zap
   54.28 +
   54.29 +%clean
   54.30 +
   54.31 +%files
   54.32 +/usr/bin/zap
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/tests/zappy.spec	Mon Jun 13 12:18:42 2016 +0100
    55.3 @@ -0,0 +1,40 @@
    55.4 +%define _source_payload w9.gzdio
    55.5 +%define _binary_payload w9.gzdio
    55.6 +
    55.7 +Name:      zappy
    55.8 +Summary:   Test package
    55.9 +Group:     Test
   55.10 +License:   GPL
   55.11 +Version:   1
   55.12 +Release:   1
   55.13 +Source:    zappy.tar
   55.14 +BuildArch: noarch
   55.15 +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   55.16 +Prefix:    /usr
   55.17 +Requires:  zap
   55.18 +
   55.19 +%description
   55.20 +Test package
   55.21 +
   55.22 +%package tools
   55.23 +Summary: Tools for using zappy
   55.24 +Group: Test
   55.25 +Requires: zappy
   55.26 +
   55.27 +%description tools
   55.28 +Test package
   55.29 +
   55.30 +%prep
   55.31 +
   55.32 +%build
   55.33 +
   55.34 +%install
   55.35 +mkdir -p $RPM_BUILD_ROOT/usr/bin
   55.36 +echo %{name}-%{version}-%{release} > $RPM_BUILD_ROOT/usr/bin/zappy
   55.37 +
   55.38 +%clean
   55.39 +
   55.40 +%files
   55.41 +/usr/bin/zappy
   55.42 +
   55.43 +%files tools
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/tests/zappy2.spec	Mon Jun 13 12:18:42 2016 +0100
    56.3 @@ -0,0 +1,30 @@
    56.4 +%define _source_payload w9.gzdio
    56.5 +%define _binary_payload w9.gzdio
    56.6 +
    56.7 +Name:      zappy2
    56.8 +Summary:   Test package
    56.9 +Group:     Test
   56.10 +License:   GPL
   56.11 +Version:   1
   56.12 +Release:   1
   56.13 +Source:    zappy2.tar
   56.14 +BuildArch: noarch
   56.15 +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   56.16 +Prefix:    /usr
   56.17 +Requires:  zap
   56.18 +
   56.19 +%description
   56.20 +Test package
   56.21 +
   56.22 +%prep
   56.23 +
   56.24 +%build
   56.25 +
   56.26 +%install
   56.27 +mkdir -p $RPM_BUILD_ROOT/usr/bin
   56.28 +echo %{name}-%{version}-%{release} > $RPM_BUILD_ROOT/usr/bin/zappy2
   56.29 +
   56.30 +%clean
   56.31 +
   56.32 +%files
   56.33 +/usr/bin/zappy2
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/tests/zip.spec	Mon Jun 13 12:18:42 2016 +0100
    57.3 @@ -0,0 +1,60 @@
    57.4 +%define _source_payload w9.gzdio
    57.5 +%define _binary_payload w9.gzdio
    57.6 +
    57.7 +Name:      zip
    57.8 +Summary:   Test package
    57.9 +Group:     Test
   57.10 +License:   GPL
   57.11 +Version:   %{_version}
   57.12 +Release:   1
   57.13 +Source:    zip.tar
   57.14 +BuildArch: noarch
   57.15 +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   57.16 +Prefix:    /usr
   57.17 +Requires:  zap
   57.18 +Requires(pre,postun):  zap
   57.19 +
   57.20 +%description
   57.21 +Test package
   57.22 +
   57.23 +%prep
   57.24 +
   57.25 +%build
   57.26 +
   57.27 +%install
   57.28 +mkdir -p $RPM_BUILD_ROOT/usr/bin
   57.29 +echo %{name}-%{version}-%{release} > $RPM_BUILD_ROOT/usr/bin/zip
   57.30 +
   57.31 +%clean
   57.32 +
   57.33 +%pre -p <lua>
   57.34 +function mkdir_missing(dir)
   57.35 +    if posix.stat(dir)==nil then
   57.36 +	posix.mkdir(dir)
   57.37 +    end
   57.38 +end
   57.39 +prefix=posix.getenv("RPM_INSTALL_PREFIX0")
   57.40 +if prefix==nil then
   57.41 +    prefix="/usr"
   57.42 +end
   57.43 +if arg[2]==1 and posix.stat(prefix.."/bin/zap")~=nil then
   57.44 +    mkdir_missing(prefix.."/var")
   57.45 +    mkdir_missing(prefix.."/var/lib")
   57.46 +    posix.mkdir(prefix.."/var/lib/zip")
   57.47 +    io.output(prefix.."/var/lib/zip/data.zap")
   57.48 +    io.write("Important data\n");
   57.49 +    io.close()
   57.50 +end
   57.51 +
   57.52 +%postun -p <lua>
   57.53 +prefix=posix.getenv("RPM_INSTALL_PREFIX0")
   57.54 +if prefix==nil then
   57.55 +    prefix="/usr"
   57.56 +end
   57.57 +if arg[2]==0 and posix.stat(prefix.."/bin/zap")~=nil then
   57.58 +    os.remove(prefix.."/var/lib/zip/data.zap")
   57.59 +    os.remove(prefix.."/var/lib/zip")
   57.60 +end
   57.61 +
   57.62 +%files
   57.63 +/usr/bin/zip
    58.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.2 +++ b/tests/zsh.spec	Mon Jun 13 12:18:42 2016 +0100
    58.3 @@ -0,0 +1,64 @@
    58.4 +%define _source_payload w9.gzdio
    58.5 +%define _binary_payload w9.gzdio
    58.6 +
    58.7 +Name:      zsh
    58.8 +Summary:   Test package
    58.9 +Group:     Test
   58.10 +License:   GPL
   58.11 +URL:       http://www.juiblex.co.uk/beach
   58.12 +Version:   1
   58.13 +Release:   1
   58.14 +Source:    zsh.tar
   58.15 +BuildArch: noarch
   58.16 +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   58.17 +Prefix:    /usr
   58.18 +Requires:  zip
   58.19 +Requires(pre,postun):  zip
   58.20 +
   58.21 +%description
   58.22 +Test package
   58.23 +
   58.24 +%prep
   58.25 +
   58.26 +%build
   58.27 +
   58.28 +%install
   58.29 +mkdir -p $RPM_BUILD_ROOT/usr/bin
   58.30 +mkdir -p $RPM_BUILD_ROOT/etc
   58.31 +touch $RPM_BUILD_ROOT/usr/bin/zsh
   58.32 +echo "DEVICE /dev/tty" > $RPM_BUILD_ROOT/etc/zsh.conf
   58.33 +
   58.34 +%clean
   58.35 +
   58.36 +%pre -p <lua>
   58.37 +function mkdir_missing(dir)
   58.38 +    if posix.stat(dir)==nil then
   58.39 +	posix.mkdir(dir)
   58.40 +    end
   58.41 +end
   58.42 +prefix=posix.getenv("RPM_INSTALL_PREFIX0")
   58.43 +if prefix==nil then
   58.44 +    prefix="/usr"
   58.45 +end
   58.46 +if arg[2]==1 and posix.stat(prefix.."/bin/zip")~=nil then
   58.47 +    mkdir_missing(prefix.."/var")
   58.48 +    mkdir_missing(prefix.."/var/lib")
   58.49 +    posix.mkdir(prefix.."/var/lib/zsh")
   58.50 +    io.output(prefix.."/var/lib/zsh/data.zip")
   58.51 +    io.write("Important data\n");
   58.52 +    io.close()
   58.53 +end
   58.54 +
   58.55 +%postun -p <lua>
   58.56 +prefix=posix.getenv("RPM_INSTALL_PREFIX0")
   58.57 +if prefix==nil then
   58.58 +    prefix="/usr"
   58.59 +end
   58.60 +if arg[2]==0 and posix.stat(prefix.."/bin/zip")~=nil then
   58.61 +    os.remove(prefix.."/var/lib/zsh/data.zip")
   58.62 +    os.remove(prefix.."/var/lib/zsh")
   58.63 +end
   58.64 +
   58.65 +%files
   58.66 +/usr/bin/zsh
   58.67 +/etc/zsh.conf
    59.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.2 +++ b/tests/zsh2.spec	Mon Jun 13 12:18:42 2016 +0100
    59.3 @@ -0,0 +1,33 @@
    59.4 +%define _source_payload w9.gzdio
    59.5 +%define _binary_payload w9.gzdio
    59.6 +
    59.7 +Name:      zsh2
    59.8 +Summary:   Test package
    59.9 +Group:     Test
   59.10 +License:   GPL
   59.11 +Version:   1
   59.12 +Release:   1
   59.13 +Source:    zsh2.tar
   59.14 +BuildArch: noarch
   59.15 +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
   59.16 +Prefix:    /usr
   59.17 +Requires:  zip
   59.18 +
   59.19 +%description
   59.20 +New and improved test package
   59.21 +
   59.22 +%prep
   59.23 +
   59.24 +%build
   59.25 +
   59.26 +%install
   59.27 +mkdir -p $RPM_BUILD_ROOT/usr/bin
   59.28 +mkdir -p $RPM_BUILD_ROOT/etc
   59.29 +touch $RPM_BUILD_ROOT/usr/bin/zsh2
   59.30 +echo "DEVICE /dev/tty" > $RPM_BUILD_ROOT/etc/zsh.conf
   59.31 +
   59.32 +%clean
   59.33 +
   59.34 +%files
   59.35 +/usr/bin/zsh2
   59.36 +/etc/zsh.conf
    60.1 --- a/update/update.c	Mon Apr 18 15:04:47 2016 +0100
    60.2 +++ b/update/update.c	Mon Jun 13 12:18:42 2016 +0100
    60.3 @@ -73,8 +73,8 @@
    60.4  int main(int argc,char **argv)
    60.5  {
    60.6      plover_exception_handler_init();
    60.7 -    razor_set_lua_loader("posix",luaopen_posix);
    60.8 -    razor_set_lua_loader("whelk",luaopen_whelk);
    60.9 +    razor_set_lua_loader("posix",(void (*)())luaopen_posix);
   60.10 +    razor_set_lua_loader("whelk",(void (*)())luaopen_whelk);
   60.11      update(argv[0]);
   60.12      exit(0);
   60.13  }