# HG changeset patch # User J. Ali Harlow # Date 1465816722 -3600 # Node ID a29623b68ca26656e85e3d5412e18c2db00f6305 # Parent 99d80cbe2eb4fe32c8c977e4463a20a90b5b4203 Add a testsuite and fix bugs found with it diff -r 99d80cbe2eb4 -r a29623b68ca2 .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,12 @@ +Makefile.in$ +.swp$ +^m4/libtool.m4$ +^m4/ltoptions.m4$ +^m4/ltsugar.m4$ +^m4/ltversion.m4$ +^m4/lt~obsolete.m4$ +^configure$ +^config/ +^config.h.in +^autom4te.cache/ +^aclocal.m4$ diff -r 99d80cbe2eb4 -r a29623b68ca2 Makefile.am --- a/Makefile.am Mon Apr 18 15:04:47 2016 +0100 +++ b/Makefile.am Mon Jun 13 12:18:42 2016 +0100 @@ -1,1 +1,9 @@ -SUBDIRS=plover setup update pre-inst plover-gtk app-manager plover-open +SUBDIRS=plover plover-gtk tests setup update pre-inst app-manager plover-open + +ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} + +@CODE_COVERAGE_RULES@ + +check-valgrind: + -(cd tests && $(MAKE) $(AM_MAKEFLAGS) check-valgrind) + @echo 'Results in tests/test-suite-*.log)' diff -r 99d80cbe2eb4 -r a29623b68ca2 README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,35 @@ +General Information +=================== + +Plover is a front-end for the razor library intended to facilitate easy +integration with GLib and Gtk+. + +The official website for project beach (of which plover is one part) is: + + http://www.juiblex.co.uk/beach/ + +Installation +============ + +Installation is via the standard procedure: + +% ./configure +% make +# make install + +Tests +===== + +The main testsuite can be run using: + +% make check + +There are also a number of extended checks that use the main testsuite: + +% make distcheck # Standard automake target +% make check-code-coverage # Generate a coverage report for testsuite +% make check-valgrind # Generate memcheck, etc., reports + +Note that check-valgrind in particular is not expected to pass. That would +require no unsuppressed false positives under all versions of our dependencies, +which is too difficult to achieve. diff -r 99d80cbe2eb4 -r a29623b68ca2 app-manager/app-manager.c --- a/app-manager/app-manager.c Mon Apr 18 15:04:47 2016 +0100 +++ b/app-manager/app-manager.c Mon Jun 13 12:18:42 2016 +0100 @@ -246,8 +246,8 @@ } #endif plover_exception_handler_init(); - razor_set_lua_loader("posix",luaopen_posix); - razor_set_lua_loader("whelk",luaopen_whelk); + razor_set_lua_loader("posix",(void (*)())luaopen_posix); + razor_set_lua_loader("whelk",(void (*)())luaopen_whelk); if (!gtk_init_with_args(&argc,&argv,NULL,options,NULL,&err)) { g_printerr("%s\n",err->message); diff -r 99d80cbe2eb4 -r a29623b68ca2 bootstrap.sh --- a/bootstrap.sh Mon Apr 18 15:04:47 2016 +0100 +++ b/bootstrap.sh Mon Jun 13 12:18:42 2016 +0100 @@ -2,7 +2,7 @@ set -e mkdir -p config autoheader -aclocal +aclocal -I m4 libtoolize automake --foreign --add-missing autoconf diff -r 99d80cbe2eb4 -r a29623b68ca2 configure.ac --- a/configure.ac Mon Apr 18 15:04:47 2016 +0100 +++ b/configure.ac Mon Jun 13 12:18:42 2016 +0100 @@ -6,6 +6,7 @@ AC_CONFIG_AUX_DIR([config]) AC_CONFIG_SRCDIR([plover/plover.h]) AC_CONFIG_HEADER([config.h]) +AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_FILES([Makefile plover/Makefile plover/plover.pc @@ -21,6 +22,9 @@ app-manager/resources.rc plover-open/Makefile plover-open/resources.rc +tests/Makefile +tests/plover/Makefile +tests/plover-gtk/Makefile ]) PLOVER_MSWIN_MANIFEST([setup/setup.exe.manifest:setup/manifest.xml.in update/update.exe.manifest:update/manifest.xml.in @@ -28,7 +32,7 @@ app-manager/app-manager.exe.manifest:app-manager/manifest.xml.in plover-open/plover-open.exe.manifest:plover-open/manifest.xml.in ]) -AM_INIT_AUTOMAKE(no-define) +AM_INIT_AUTOMAKE(no-define parallel-tests) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) case $VERSION in *.*.*) @@ -98,6 +102,20 @@ if test "$RSVG" = no; then AC_MSG_ERROR([no rsvg program found to convert SVG files to bitmaps]) fi +AX_VALGRIND_CHECK +AS_IF([test "$enable_valgrind" != "no"],[[ + major=`$VALGRIND --version | \ + sed -e 's/^valgrind-//' -e 's/^[^.]*$/0/' -e 's/\..*//'` + minor=`$VALGRIND --version | \ + sed -e 's/^valgrind-//' -e 's/.*/&.0.0/' -e 's/[^.]*\.\([^.]*\)\..*/\1/'` +]],[major=0; minor=0]) +AM_CONDITIONAL([HAVE_VALGRIND_3_9],[test 0$major -gt 3 -o 0$minor -gt 8]) +AX_CODE_COVERAGE +AC_CHECK_TOOL([RAZOR],[razor],[no]) +AC_CHECK_TOOL([RPMBUILD],[rpmbuild],[no]) +AC_CHECK_TOOL([CREATEREPO],[createrepo],[no]) +AM_CONDITIONAL([HAVE_CHECK_TOOLS], + [test x$RAZOR != xno -a x$RPMBUILD != xno -a x$CREATEREPO != xno]) ################################################## # Checks for header files. @@ -119,6 +137,7 @@ PKG_CHECK_MODULES(EXPAT,[expat >= 2.1],[:], [PKG_CHECK_MODULES(EXPAT,[expat21],[:],[EXPAT_LIBS=-lexpat])]) PKG_CHECK_MODULES(ZLIB,[zlib],[:],[ZLIB_LIBS=-lz]) +PKG_CHECK_MODULES(LUA,[lua],[:],[LUA_LIBS=-llua]) PKG_CHECK_MODULES(GIO,[gio-2.0]) PKG_CHECK_MODULES(GTK,[gtk+-2.0]) PKG_CHECK_MODULES(GMODULE_EXPORT,[gmodule-export-2.0]) @@ -132,11 +151,15 @@ AC_SUBST(PLOVER_GTK_LIBS) save_LIBS="$LIBS" AC_SEARCH_LIBS([crypt],[crypt]) +LUA_POSIX_CFLAGS="$LUA_CFLAGS" +LUA_POSIX_LIBS="-llua-posix $LUA_LIBS $LIBS" +LIBS="$save_LIBS" +AC_SUBST(LUA_POSIX_CFLAGS) +AC_SUBST(LUA_POSIX_LIBS) GUI_CFLAGS="$GMODULE_EXPORT_CFLAGS $WHELK_CFLAGS $PLOVER_GTK_CFLAGS \ - $LIBPLOVER_CFLAGS" -GUI_LIBS="-llua-posix $GMODULE_EXPORT_LIBS $WHELK_LIBS $PLOVER_GTK_LIBS \ - $LIBPLOVER_LIBS $LIBS" -LIBS="$save_LIBS" + $LIBPLOVER_CFLAGS $LUA_POSIX_CFLAGS" +GUI_LIBS="$GMODULE_EXPORT_LIBS $WHELK_LIBS $PLOVER_GTK_LIBS \ + $LIBPLOVER_LIBS $LUA_POSIX_LIBS" AC_SUBST(GUI_CFLAGS) AC_SUBST(GUI_LIBS) save_PKG_CONFIG="$PKG_CONFIG" @@ -150,13 +173,11 @@ SETUP_LIBS="$SETUP_LIBS -liconv" fi PKG_CONFIG="$save_PKG_CONFIG" -save_LIBS="$LIBS" -AC_SEARCH_LIBS([crypt],[crypt]) -SETUP_LIBS="-llua-posix $SETUP_LIBS $LIBS" -SETUP_CFLAGS="$SETUP_CFLAGS" +SETUP_CFLAGS="$SETUP_CFLAGS $LUA_POSIX_CFLAGS" +SETUP_LIBS="$SETUP_LIBS $LUA_POSIX_LIBS" AC_SUBST(SETUP_LIBS) AC_SUBST(SETUP_CFLAGS) -LIBS="$save_LIBS" +save_LIBS="$LIBS" LIBS="$LIBS -lcrypt32" AC_MSG_CHECKING([for library containing CertEnumCertificatesInStore]) AC_LINK_IFELSE([AC_LANG_PROGRAM( diff -r 99d80cbe2eb4 -r a29623b68ca2 m4/ax_code_coverage.m4 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/m4/ax_code_coverage.m4 Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,274 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_code_coverage.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CODE_COVERAGE() +# +# DESCRIPTION +# +# Defines CODE_COVERAGE_CPPFLAGS, CODE_COVERAGE_CFLAGS, +# CODE_COVERAGE_CXXFLAGS and CODE_COVERAGE_LDFLAGS which should be +# included in the CPPFLAGS, CFLAGS CXXFLAGS and LIBS/LDFLAGS variables of +# every build target (program or library) which should be built with code +# coverage support. Also defines CODE_COVERAGE_RULES which should be +# substituted in your Makefile; and $enable_code_coverage which can be +# used in subsequent configure output. CODE_COVERAGE_ENABLED is defined +# and substituted, and corresponds to the value of the +# --enable-code-coverage option, which defaults to being disabled. +# +# Test also for gcov program and create GCOV variable that could be +# substituted. +# +# Note that all optimisation flags in CFLAGS must be disabled when code +# coverage is enabled. +# +# Usage example: +# +# configure.ac: +# +# AX_CODE_COVERAGE +# +# Makefile.am: +# +# @CODE_COVERAGE_RULES@ +# my_program_LIBS = ... $(CODE_COVERAGE_LDFLAGS) ... +# my_program_CPPFLAGS = ... $(CODE_COVERAGE_CPPFLAGS) ... +# my_program_CFLAGS = ... $(CODE_COVERAGE_CFLAGS) ... +# my_program_CXXFLAGS = ... $(CODE_COVERAGE_CXXFLAGS) ... +# +# This results in a "check-code-coverage" rule being added to any +# Makefile.am which includes "@CODE_COVERAGE_RULES@" (assuming the module +# has been configured with --enable-code-coverage). Running `make +# check-code-coverage` in that directory will run the module's test suite +# (`make check`) and build a code coverage report detailing the code which +# was touched, then print the URI for the report. +# +# This code was derived from Makefile.decl in GLib, originally licenced +# under LGPLv2.1+. +# +# LICENSE +# +# Copyright (c) 2012, 2016 Philip Withnall +# Copyright (c) 2012 Xan Lopez +# Copyright (c) 2012 Christian Persch +# Copyright (c) 2012 Paolo Borelli +# Copyright (c) 2012 Dan Winship +# Copyright (c) 2015 Bastien ROUCARIES +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or (at +# your option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . + +#serial 16 + +AC_DEFUN([AX_CODE_COVERAGE],[ + dnl Check for --enable-code-coverage + AC_REQUIRE([AC_PROG_SED]) + + # allow to override gcov location + AC_ARG_WITH([gcov], + [AS_HELP_STRING([--with-gcov[=GCOV]], [use given GCOV for coverage (GCOV=gcov).])], + [_AX_CODE_COVERAGE_GCOV_PROG_WITH=$with_gcov], + [_AX_CODE_COVERAGE_GCOV_PROG_WITH=gcov]) + + AC_MSG_CHECKING([whether to build with code coverage support]) + AC_ARG_ENABLE([code-coverage], + AS_HELP_STRING([--enable-code-coverage], + [Whether to enable code coverage support]),, + enable_code_coverage=no) + + AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes]) + AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage]) + AC_MSG_RESULT($enable_code_coverage) + + AS_IF([ test "$enable_code_coverage" = "yes" ], [ + # check for gcov + AC_CHECK_TOOL([GCOV], + [$_AX_CODE_COVERAGE_GCOV_PROG_WITH], + [:]) + AS_IF([test "X$GCOV" = "X:"], + [AC_MSG_ERROR([gcov is needed to do coverage])]) + AC_SUBST([GCOV]) + + dnl Check if gcc is being used + AS_IF([ test "$GCC" = "no" ], [ + AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage]) + ]) + + # List of supported lcov versions. + lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11 1.12" + + AC_CHECK_PROG([LCOV], [lcov], [lcov]) + AC_CHECK_PROG([GENHTML], [genhtml], [genhtml]) + + AS_IF([ test "$LCOV" ], [ + AC_CACHE_CHECK([for lcov version], ax_cv_lcov_version, [ + ax_cv_lcov_version=invalid + lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'` + for lcov_check_version in $lcov_version_list; do + if test "$lcov_version" = "$lcov_check_version"; then + ax_cv_lcov_version="$lcov_check_version (ok)" + fi + done + ]) + ], [ + lcov_msg="To enable code coverage reporting you must have one of the following lcov versions installed: $lcov_version_list" + AC_MSG_ERROR([$lcov_msg]) + ]) + + case $ax_cv_lcov_version in + ""|invalid[)] + lcov_msg="You must have one of the following versions of lcov: $lcov_version_list (found: $lcov_version)." + AC_MSG_ERROR([$lcov_msg]) + LCOV="exit 0;" + ;; + esac + + AS_IF([ test -z "$GENHTML" ], [ + AC_MSG_ERROR([Could not find genhtml from the lcov package]) + ]) + + dnl Build the code coverage flags + CODE_COVERAGE_CPPFLAGS="-DNDEBUG" + CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" + CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" + CODE_COVERAGE_LDFLAGS="-lgcov" + + AC_SUBST([CODE_COVERAGE_CPPFLAGS]) + AC_SUBST([CODE_COVERAGE_CFLAGS]) + AC_SUBST([CODE_COVERAGE_CXXFLAGS]) + AC_SUBST([CODE_COVERAGE_LDFLAGS]) + ]) + +[CODE_COVERAGE_RULES=' +# Code coverage +# +# Optional: +# - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting. +# Multiple directories may be specified, separated by whitespace. +# (Default: $(top_builddir)) +# - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated +# by lcov for code coverage. (Default: +# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info) +# - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage +# reports to be created. (Default: +# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage) +# - CODE_COVERAGE_BRANCH_COVERAGE: Set to 1 to enforce branch coverage, +# set to 0 to disable it and leave empty to stay with the default. +# (Default: empty) +# - CODE_COVERAGE_LCOV_SHOPTS_DEFAULT: Extra options shared between both lcov +# instances. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) +# - CODE_COVERAGE_LCOV_SHOPTS: Extra options to shared between both lcov +# instances. (Default: $CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) +# - CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH: --gcov-tool pathtogcov +# - CODE_COVERAGE_LCOV_OPTIONS_DEFAULT: Extra options to pass to the +# collecting lcov instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) +# - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the collecting lcov +# instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) +# - CODE_COVERAGE_LCOV_RMOPTS_DEFAULT: Extra options to pass to the filtering +# lcov instance. (Default: empty) +# - CODE_COVERAGE_LCOV_RMOPTS: Extra options to pass to the filtering lcov +# instance. (Default: $CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) +# - CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT: Extra options to pass to the +# genhtml instance. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) +# - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml +# instance. (Default: $CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT) +# - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore +# +# The generated report will be titled using the $(PACKAGE_NAME) and +# $(PACKAGE_VERSION). In order to add the current git hash to the title, +# use the git-version-gen script, available online. + +# Optional variables +CODE_COVERAGE_DIRECTORY ?= $(top_builddir) +CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info +CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage +CODE_COVERAGE_BRANCH_COVERAGE ?= +CODE_COVERAGE_LCOV_SHOPTS_DEFAULT ?= $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ +--rc lcov_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) +CODE_COVERAGE_LCOV_SHOPTS ?= $(CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) +CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH ?= --gcov-tool "$(GCOV)" +CODE_COVERAGE_LCOV_OPTIONS_DEFAULT ?= $(CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) +CODE_COVERAGE_LCOV_OPTIONS ?= $(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) +CODE_COVERAGE_LCOV_RMOPTS_DEFAULT ?= +CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) +CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\ +$(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ +--rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) +CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULTS) +CODE_COVERAGE_IGNORE_PATTERN ?= + +code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V)) +code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY)) +code_coverage_v_lcov_cap_0 = @echo " LCOV --capture"\ + $(CODE_COVERAGE_OUTPUT_FILE); +code_coverage_v_lcov_ign = $(code_coverage_v_lcov_ign_$(V)) +code_coverage_v_lcov_ign_ = $(code_coverage_v_lcov_ign_$(AM_DEFAULT_VERBOSITY)) +code_coverage_v_lcov_ign_0 = @echo " LCOV --remove /tmp/*"\ + $(CODE_COVERAGE_IGNORE_PATTERN); +code_coverage_v_genhtml = $(code_coverage_v_genhtml_$(V)) +code_coverage_v_genhtml_ = $(code_coverage_v_genhtml_$(AM_DEFAULT_VERBOSITY)) +code_coverage_v_genhtml_0 = @echo " GEN " $(CODE_COVERAGE_OUTPUT_DIRECTORY); +code_coverage_quiet = $(code_coverage_quiet_$(V)) +code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY)) +code_coverage_quiet_0 = --quiet + +# sanitizes the test-name: replaces with underscores: dashes and dots +code_coverage_sanitize = $(subst -,_,$(subst .,_,$(1))) + +# Use recursive makes in order to ignore errors during check +check-code-coverage: +ifeq ($(CODE_COVERAGE_ENABLED),yes) + -$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k check + $(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture +else + @echo "Need to reconfigure with --enable-code-coverage" +endif + +# Capture code coverage data +code-coverage-capture: code-coverage-capture-hook +ifeq ($(CODE_COVERAGE_ENABLED),yes) + $(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) + $(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) + -@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp + $(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) + @echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html" +else + @echo "Need to reconfigure with --enable-code-coverage" +endif + +# Hook rule executed before code-coverage-capture, overridable by the user +code-coverage-capture-hook: + +ifeq ($(CODE_COVERAGE_ENABLED),yes) +clean: code-coverage-clean +distclean: code-coverage-clean +code-coverage-clean: + -$(LCOV) --directory $(top_builddir) -z + -rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY) + -find . \( -name "*.gcda" -o -name "*.gcno" -o -name "*.gcov" \) -delete +endif + +GITIGNOREFILES ?= +GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY) + +A''M_DISTCHECK_CONFIGURE_FLAGS ?= +A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage + +.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean +'] + + AC_SUBST([CODE_COVERAGE_RULES]) + m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([CODE_COVERAGE_RULES])]) +]) diff -r 99d80cbe2eb4 -r a29623b68ca2 m4/ax_valgrind_check.m4 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/m4/ax_valgrind_check.m4 Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,233 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_valgrind_check.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_VALGRIND_CHECK() +# +# DESCRIPTION +# +# Checks whether Valgrind is present and, if so, allows running `make +# check` under a variety of Valgrind tools to check for memory and +# threading errors. +# +# Defines VALGRIND_CHECK_RULES which should be substituted in your +# Makefile; and $enable_valgrind which can be used in subsequent configure +# output. VALGRIND_ENABLED is defined and substituted, and corresponds to +# the value of the --enable-valgrind option, which defaults to being +# enabled if Valgrind is installed and disabled otherwise. +# +# If unit tests are written using a shell script and automake's +# LOG_COMPILER system, the $(VALGRIND) variable can be used within the +# shell scripts to enable Valgrind, as described here: +# +# https://www.gnu.org/software/gnulib/manual/html_node/Running-self_002dtests-under-valgrind.html +# +# Usage example: +# +# configure.ac: +# +# AX_VALGRIND_CHECK +# +# Makefile.am: +# +# @VALGRIND_CHECK_RULES@ +# VALGRIND_SUPPRESSIONS_FILES = my-project.supp +# EXTRA_DIST = my-project.supp +# +# This results in a "check-valgrind" rule being added to any Makefile.am +# which includes "@VALGRIND_CHECK_RULES@" (assuming the module has been +# configured with --enable-valgrind). Running `make check-valgrind` in +# that directory will run the module's test suite (`make check`) once for +# each of the available Valgrind tools (out of memcheck, helgrind, drd and +# sgcheck), and will output results to test-suite-$toolname.log for each. +# The target will succeed if there are zero errors and fail otherwise. +# +# Alternatively, a "check-valgrind-$TOOL" rule will be added, for $TOOL in +# memcheck, helgrind, drd and sgcheck. These are useful because often only +# some of those tools can be ran cleanly on a codebase. +# +# The macro supports running with and without libtool. +# +# LICENSE +# +# Copyright (c) 2014, 2015, 2016 Philip Withnall +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 9 + +AC_DEFUN([AX_VALGRIND_CHECK],[ + dnl Check for --enable-valgrind + AC_ARG_ENABLE([valgrind], + [AS_HELP_STRING([--enable-valgrind], [Whether to enable Valgrind on the unit tests])], + [enable_valgrind=$enableval],[enable_valgrind=]) + + AS_IF([test "$enable_valgrind" != "no"],[ + # Check for Valgrind. + AC_CHECK_PROG([VALGRIND],[valgrind],[valgrind]) + AS_IF([test "$VALGRIND" = ""],[ + AS_IF([test "$enable_valgrind" = "yes"],[ + AC_MSG_ERROR([Could not find valgrind; either install it or reconfigure with --disable-valgrind]) + ],[ + enable_valgrind=no + ]) + ],[ + enable_valgrind=yes + ]) + ]) + + AM_CONDITIONAL([VALGRIND_ENABLED],[test "$enable_valgrind" = "yes"]) + AC_SUBST([VALGRIND_ENABLED],[$enable_valgrind]) + + # Check for Valgrind tools we care about. + m4_define([valgrind_tool_list],[[memcheck], [helgrind], [drd], [exp-sgcheck]]) + + AS_IF([test "$VALGRIND" != ""],[ + m4_foreach([vgtool],[valgrind_tool_list],[ + m4_define([vgtooln],AS_TR_SH(vgtool)) + m4_define([ax_cv_var],[ax_cv_valgrind_tool_]vgtooln) + AC_CACHE_CHECK([for Valgrind tool ]vgtool,ax_cv_var,[ + ax_cv_var= + AS_IF([`$VALGRIND --tool=vgtool --help >/dev/null 2>&1`],[ + ax_cv_var="vgtool" + ]) + ]) + + AC_SUBST([VALGRIND_HAVE_TOOL_]vgtooln,[$ax_cv_var]) + ]) + ]) + +[VALGRIND_CHECK_RULES=' +# Valgrind check +# +# Optional: +# - VALGRIND_SUPPRESSIONS_FILES: Space-separated list of Valgrind suppressions +# files to load. (Default: empty) +# - VALGRIND_FLAGS: General flags to pass to all Valgrind tools. +# (Default: --num-callers=30) +# - VALGRIND_$toolname_FLAGS: Flags to pass to Valgrind $toolname (one of: +# memcheck, helgrind, drd, sgcheck). (Default: various) + +# Optional variables +VALGRIND_SUPPRESSIONS ?= $(addprefix --suppressions=,$(VALGRIND_SUPPRESSIONS_FILES)) +VALGRIND_FLAGS ?= --num-callers=30 +VALGRIND_memcheck_FLAGS ?= --leak-check=full --show-reachable=no +VALGRIND_helgrind_FLAGS ?= --history-level=approx +VALGRIND_drd_FLAGS ?= +VALGRIND_sgcheck_FLAGS ?= + +# Internal use +valgrind_tools = memcheck helgrind drd sgcheck +valgrind_log_files = $(addprefix test-suite-,$(addsuffix .log,$(valgrind_tools))) + +valgrind_memcheck_flags = --tool=memcheck $(VALGRIND_memcheck_FLAGS) +valgrind_helgrind_flags = --tool=helgrind $(VALGRIND_helgrind_FLAGS) +valgrind_drd_flags = --tool=drd $(VALGRIND_drd_FLAGS) +valgrind_sgcheck_flags = --tool=exp-sgcheck $(VALGRIND_sgcheck_FLAGS) + +valgrind_quiet = $(valgrind_quiet_$(V)) +valgrind_quiet_ = $(valgrind_quiet_$(AM_DEFAULT_VERBOSITY)) +valgrind_quiet_0 = --quiet + +# Support running with and without libtool. +ifneq ($(LIBTOOL),) +valgrind_lt = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=execute +else +valgrind_lt = +endif + +# Use recursive makes in order to ignore errors during check +check-valgrind: +ifeq ($(VALGRIND_ENABLED),yes) + -$(foreach tool,$(valgrind_tools), \ + $(if $(VALGRIND_HAVE_TOOL_$(tool))$(VALGRIND_HAVE_TOOL_exp_$(tool)), \ + $(MAKE) $(AM_MAKEFLAGS) -k check-valgrind-tool VALGRIND_TOOL=$(tool); \ + ) \ + ) +else + @echo "Need to reconfigure with --enable-valgrind" +endif + +# Valgrind running +VALGRIND_TESTS_ENVIRONMENT = \ + $(TESTS_ENVIRONMENT) \ + env VALGRIND=$(VALGRIND) \ + G_SLICE=always-malloc,debug-blocks \ + G_DEBUG=fatal-warnings,fatal-criticals,gc-friendly + +VALGRIND_LOG_COMPILER = \ + $(valgrind_lt) \ + $(VALGRIND) $(VALGRIND_SUPPRESSIONS) --error-exitcode=1 $(VALGRIND_FLAGS) + +check-valgrind-tool: +ifeq ($(VALGRIND_ENABLED),yes) + $(MAKE) check-TESTS \ + TESTS_ENVIRONMENT="$(VALGRIND_TESTS_ENVIRONMENT)" \ + LOG_COMPILER="$(VALGRIND_LOG_COMPILER)" \ + LOG_FLAGS="$(valgrind_$(VALGRIND_TOOL)_flags)" \ + TEST_SUITE_LOG=test-suite-$(VALGRIND_TOOL).log +else + @echo "Need to reconfigure with --enable-valgrind" +endif + +check-valgrind-memcheck: +ifeq ($(VALGRIND_ENABLED),yes) + $(MAKE) check-TESTS \ + TESTS_ENVIRONMENT="$(VALGRIND_TESTS_ENVIRONMENT)" \ + LOG_COMPILER="$(VALGRIND_LOG_COMPILER)" \ + LOG_FLAGS="$(valgrind_memcheck_flags)" \ + TEST_SUITE_LOG=test-suite-memcheck.log +else + @echo "Need to reconfigure with --enable-valgrind" +endif + +check-valgrind-helgrind: +ifeq ($(VALGRIND_ENABLED),yes) + $(MAKE) check-TESTS \ + TESTS_ENVIRONMENT="$(VALGRIND_TESTS_ENVIRONMENT)" \ + LOG_COMPILER="$(VALGRIND_LOG_COMPILER)" \ + LOG_FLAGS="$(valgrind_helgrind_flags)" \ + TEST_SUITE_LOG=test-suite-helgrind.log +else + @echo "Need to reconfigure with --enable-valgrind" +endif + +check-valgrind-drd: +ifeq ($(VALGRIND_ENABLED),yes) + $(MAKE) check-TESTS \ + TESTS_ENVIRONMENT="$(VALGRIND_TESTS_ENVIRONMENT)" \ + LOG_COMPILER="$(VALGRIND_LOG_COMPILER)" \ + LOG_FLAGS="$(valgrind_drd_flags)" \ + TEST_SUITE_LOG=test-suite-drd.log +else + @echo "Need to reconfigure with --enable-valgrind" +endif + +check-valgrind-sgcheck: +ifeq ($(VALGRIND_ENABLED),yes) + $(MAKE) check-TESTS \ + TESTS_ENVIRONMENT="$(VALGRIND_TESTS_ENVIRONMENT)" \ + LOG_COMPILER="$(VALGRIND_LOG_COMPILER)" \ + LOG_FLAGS="$(valgrind_sgcheck_flags)" \ + TEST_SUITE_LOG=test-suite-sgcheck.log +else + @echo "Need to reconfigure with --enable-valgrind" +endif + +A''M_DISTCHECK_CONFIGURE_FLAGS ?= +A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-valgrind + +MOSTLYCLEANFILES ?= +MOSTLYCLEANFILES += $(valgrind_log_files) + +.PHONY: check-valgrind check-valgrind-tool +'] + + AC_SUBST([VALGRIND_CHECK_RULES]) + m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([VALGRIND_CHECK_RULES])]) +]) diff -r 99d80cbe2eb4 -r a29623b68ca2 plover-gtk/Makefile.am --- a/plover-gtk/Makefile.am Mon Apr 18 15:04:47 2016 +0100 +++ b/plover-gtk/Makefile.am Mon Jun 13 12:18:42 2016 +0100 @@ -1,7 +1,9 @@ -AM_CFLAGS=-g $(PLOVER_GTK_CFLAGS) -DPLOVER_DATADIR=\""$(pkgdatadir)"\" +AM_CFLAGS=-g $(PLOVER_GTK_CFLAGS) $(CODE_COVERAGE_CFLAGS) \ + -DPLOVER_DATADIR=\""$(pkgdatadir)"\" LIBS=../plover/libplover.la $(PLOVER_GTK_LIBS) INCLUDES=-I$(top_srcdir) -AM_LDFLAGS=-no-undefined -version-info $(PLOVER_GTK_LT_VERSION_INFO) +AM_LDFLAGS=-no-undefined -version-info $(PLOVER_GTK_LT_VERSION_INFO) \ + $(CODE_COVERAGE_LDFLAGS) uidir=$(pkgdatadir) ui_DATA=software-installation.ui diff -r 99d80cbe2eb4 -r a29623b68ca2 plover-gtk/packagefilestore.c --- a/plover-gtk/packagefilestore.c Mon Apr 18 15:04:47 2016 +0100 +++ b/plover-gtk/packagefilestore.c Mon Jun 13 12:18:42 2016 +0100 @@ -265,7 +265,7 @@ g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL); struct razor_file_iterator *iter; iter=plover_package_file_iterator_create(package,FALSE); - store=GTK_TREE_MODEL(plover_package_file_store_new(iter)); + store=plover_package_file_store_new(iter); razor_file_iterator_destroy(iter); return store; } diff -r 99d80cbe2eb4 -r a29623b68ca2 plover-gtk/software-installation.ui --- a/plover-gtk/software-installation.ui Mon Apr 18 15:04:47 2016 +0100 +++ b/plover-gtk/software-installation.ui Mon Jun 13 12:18:42 2016 +0100 @@ -21,8 +21,8 @@ 16 <b>Welcome to the Installation Assistant</b> -The Installation Assistant will install the software. -To continue, click Forward. +The Installation Assistant will make the changes to the +software you have requested. To continue, click Forward. True @@ -110,7 +110,7 @@ True vertical - + True 0 0 @@ -138,7 +138,7 @@ True True True - Unpacking files + Starting diff -r 99d80cbe2eb4 -r a29623b68ca2 plover-gtk/stockicons.c --- a/plover-gtk/stockicons.c Mon Apr 18 15:04:47 2016 +0100 +++ b/plover-gtk/stockicons.c Mon Jun 13 12:18:42 2016 +0100 @@ -34,6 +34,8 @@ GSList *tmp_list; static gint found_svg=-1; gchar **mime_types,**mime_type; + if (g_getenv("PLOVER_IGNORE_SVG_SUPPORT")) + return FALSE; if (found_svg!=-1) return found_svg; formats=gdk_pixbuf_get_formats(); @@ -55,10 +57,15 @@ { int w,h; GdkPixbuf *pixbuf; + GtkSettings *settings; GtkIconSource *source; - if (gtk_icon_size_lookup(size,&w,&h)) + GError *err=NULL; + settings=gtk_settings_get_default(); + if (!settings) + g_warning("plover: Can't add icons without a default screen"); + else if (gtk_icon_size_lookup_for_settings(settings,size,&w,&h)) { - pixbuf=gdk_pixbuf_new_from_file_at_size(filename,w,h,NULL); + pixbuf=gdk_pixbuf_new_from_file_at_size(filename,w,h,&err); if (pixbuf) { source=gtk_icon_source_new(); @@ -69,6 +76,11 @@ gtk_icon_source_free(source); g_object_unref(pixbuf); } + else + { + g_warning("%s: %s",filename,err->message); + g_error_free(err); + } } } @@ -87,23 +99,30 @@ */ void plover_icons_add_to_stock(const char *type,const char *name) { - gchar *prefix,*s,*filename; + gchar *datadir,*prefix,*s,*filename; GtkIconSource *source; GtkIconSet *icon_set; GtkIconFactory *factory; factory=gtk_icon_factory_new(); icon_set=gtk_icon_set_new(); + datadir=g_strdup(g_getenv("PLOVER_ICONS_DATADIR")); + if (!datadir) + { #ifdef WIN32 - prefix=g_win32_get_package_installation_directory_of_module(NULL); + prefix=g_win32_get_package_installation_directory_of_module(NULL); #else - prefix=NULL; + prefix=NULL; #endif + if (!prefix) + prefix=g_strdup("/usr"); + datadir=g_strconcat(prefix,"share",NULL); + g_free(prefix); + } if (plover_pixbuf_supports_svg()) { source=gtk_icon_source_new(); s=g_strconcat(name,".svg",NULL); - filename=g_build_filename(prefix?prefix:"/usr", - "share/icons/hicolor/scalable",type,s,NULL); + filename=g_build_filename(datadir,"icons/hicolor/scalable",type,s,NULL); g_free(s); gtk_icon_source_set_filename(source,filename); g_free(filename); @@ -113,8 +132,7 @@ else { s=g_strconcat(name,".png",NULL); - filename=g_build_filename(prefix?prefix:"/usr", - "share/icons/hicolor/24x24",type,s,NULL); + filename=g_build_filename(datadir,"icons/hicolor/24x24",type,s,NULL); plover_install_icon_at_size(name,icon_set,GTK_ICON_SIZE_MENU, filename); plover_install_icon_at_size(name,icon_set,GTK_ICON_SIZE_BUTTON, @@ -124,8 +142,7 @@ plover_install_icon_at_size(name,icon_set,GTK_ICON_SIZE_LARGE_TOOLBAR, filename); g_free(filename); - filename=g_build_filename(prefix?prefix:"/usr", - "share/icons/hicolor/48x48",type,s,NULL); + filename=g_build_filename(datadir,"icons/hicolor/48x48",type,s,NULL); plover_install_icon_at_size(name,icon_set,GTK_ICON_SIZE_DND, filename); plover_install_icon_at_size(name,icon_set,GTK_ICON_SIZE_DIALOG, @@ -133,6 +150,7 @@ g_free(filename); g_free(s); } + g_free(datadir); gtk_icon_factory_add(factory,name,icon_set); gtk_icon_set_unref(icon_set); //icon_set=gtk_icon_factory_lookup(factory,name); diff -r 99d80cbe2eb4 -r a29623b68ca2 plover-gtk/transactionhelper.c --- a/plover-gtk/transactionhelper.c Mon Apr 18 15:04:47 2016 +0100 +++ b/plover-gtk/transactionhelper.c Mon Jun 13 12:18:42 2016 +0100 @@ -31,6 +31,23 @@ G_DEFINE_TYPE(PloverTransactionHelper,plover_transaction_helper,G_TYPE_OBJECT) +enum plover_transaction_type { + TRANSACTION_TYPE_NULL=0, + TRANSACTION_TYPE_INSTALL=1UL<<0, + TRANSACTION_TYPE_REMOVE=1UL<<1, + TRANSACTION_TYPE_UPDATE=TRANSACTION_TYPE_INSTALL|TRANSACTION_TYPE_REMOVE +}; + +typedef struct _PloverTransactionHelperPrivate { + enum plover_transaction_type transaction_type; + gchar *default_prefix; +} PloverTransactionHelperPrivate; + +#define PLOVER_TRANSACTION_HELPER_GET_PRIVATE(obj)\ + G_TYPE_INSTANCE_GET_PRIVATE(obj,\ + PLOVER_TYPE_TRANSACTION_HELPER,\ + PloverTransactionHelperPrivate) + enum { CLOSE=0, N_SIGNALS @@ -40,6 +57,9 @@ static void plover_transaction_helper_finalize(PloverTransactionHelper *helper) { + PloverTransactionHelperPrivate *priv; + priv=PLOVER_TRANSACTION_HELPER_GET_PRIVATE(helper); + g_free(priv->default_prefix); g_free(helper->error_primary_text); g_free(helper->base); g_free(helper->unsatisfied); @@ -80,6 +100,7 @@ (void (*)(GObject *))plover_transaction_helper_finalize; gobject_class->dispose= (void (*)(GObject *))plover_transaction_helper_dispose; + g_type_class_add_private(klass,sizeof(PloverTransactionHelperPrivate)); signals[CLOSE]=g_signal_newv("close", G_TYPE_FROM_CLASS(klass),G_SIGNAL_RUN_LAST,NULL,NULL,NULL, g_cclosure_marshal_VOID__VOID,G_TYPE_NONE,0,NULL); @@ -185,6 +206,12 @@ } else plover_transaction_helper_run(helper); + /* + * There may be status updates queued by transaction as idle events. + * Process them now before we disconnect so that we don't lose them. + */ + while(g_main_context_pending(NULL)) + g_main_context_iteration(NULL,FALSE); g_signal_handlers_disconnect_by_data(transaction,helper); g_object_unref(transaction); } @@ -248,11 +275,35 @@ GError *error=NULL; GtkToggleButton *button; PloverTransaction *transaction; + GSList *save_transactions; + PloverTransactionHelperPrivate *priv; + enum plover_transaction_type save_transaction_type; + priv=PLOVER_TRANSACTION_HELPER_GET_PRIVATE(helper); button=GTK_TOGGLE_BUTTON(gtk_builder_get_object(helper->ui, "SIRemoveExisting")); if (gtk_toggle_button_get_active(button)) { transaction=plover_transaction_new_remove(NULL,&error); + if (transaction) + { + save_transactions=helper->transactions; + helper->transactions=NULL; + save_transaction_type=priv->transaction_type; + priv->transaction_type=0; + if (!plover_transaction_helper_add_transaction(helper,transaction, + NULL,PLOVER_TRANSACTION_HELPER_REPORT_REMOVE,&error)) + { + g_object_unref(transaction); + transaction=NULL; + helper->transactions=save_transactions; + priv->transaction_type=save_transaction_type; + } + else + { + g_slist_foreach(save_transactions,(GFunc)g_object_unref,NULL); + g_slist_free(save_transactions); + } + } if (!transaction) { if (g_error_matches(error,PLOVER_POSIX_ERROR,ENOENT)) @@ -260,14 +311,11 @@ if (error) { plover_transaction_helper_set_error(helper,error, - "Software installation failed"); + "Failed to remove existing packages"); g_error_free(error); return; } } - else - helper->transactions= - g_slist_prepend(helper->transactions,transaction); } /* * Note that PloverTransaction does support cancelling a transaction, but @@ -427,71 +475,15 @@ GError **error) { const char *base; -#if 0 - const char *prefix; - struct razor_relocations *relocations=NULL; -#endif g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL); if (!helper->upstream) { -#if 0 - prefix=plover_transaction_helper_get_prefix(helper,error); - if (!prefix) - return NULL; -#endif base=plover_transaction_helper_get_base(helper); -#if 0 - if (prefix) - { - relocations=razor_relocations_create(); - razor_relocations_add(relocations,"/usr",prefix); - } -#endif helper->upstream=plover_repository_new_from_yum(base,error); -#if 0 - if (relocations) - razor_relocations_destroy(relocations); -#endif } return helper->upstream; } -static PloverPackageSet *plover_transaction_helper_get_relocated_upstream( - PloverTransactionHelper *helper,GError **error) -{ - const char *prefix; - struct razor_relocations *relocations=NULL; - GError *tmp_error=NULL; - PloverRepository *upstream; - PloverPackageSet *set; - if (!helper->relocated_upstream) - { - upstream=plover_transaction_helper_get_upstream(helper,error); - if (!upstream) - return NULL; - prefix=plover_transaction_helper_get_prefix(helper,&tmp_error); - if (tmp_error) - { - g_propagate_error(error,tmp_error); - return NULL; - } - set=plover_repository_get_package_set(upstream); - if (prefix) - { - relocations=razor_relocations_create(); - razor_relocations_add(relocations,"/usr",prefix); - helper->relocated_upstream= - plover_package_set_new_from_repository(upstream,relocations, - error); - if (relocations) - razor_relocations_destroy(relocations); - } - else - helper->relocated_upstream=g_object_ref(set); - } - return helper->relocated_upstream; -} - void plover_transaction_helper_set_upstream(PloverTransactionHelper *helper, PloverRepository *upstream) { @@ -541,14 +533,18 @@ { const char *prefix; struct comps *comps; + PloverTransactionHelperPrivate *priv; g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL); g_return_val_if_fail(helper->base != NULL || helper->installed != NULL,NULL); + priv=PLOVER_TRANSACTION_HELPER_GET_PRIVATE(helper); if (helper->base) { comps=plover_transaction_helper_get_comps(helper,error); if (!comps) return NULL; - return plover_default_prefix_for_vendor(comps->vendor); + g_free(priv->default_prefix); + priv->default_prefix=plover_default_prefix_for_vendor(comps->vendor); + return priv->default_prefix; } prefix=plover_package_set_guess_prefix(helper->installed,error); return prefix; @@ -583,7 +579,7 @@ int i; gchar *prefix=NULL,*s; struct comps *comps=NULL; - GtkWidget *container,*page; + GtkWidget *container,*summary,*page; GtkButton *button; GtkLabel *label; g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE); @@ -598,6 +594,7 @@ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),FALSE); container=GTK_WIDGET(gtk_builder_get_object(helper->ui, "SIIncompatibleInstallation")); + summary=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SISummaryOfWork")); page=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SIConfirm")); if (helper->check_vendor && prefix && !plover_installed_files_match_prefix(prefix)) @@ -615,15 +612,18 @@ gtk_button_set_label(button,s); g_free(s); gtk_widget_show(container); + gtk_widget_hide(summary); if (helper->assistant) gtk_assistant_set_page_complete(helper->assistant,page,FALSE); } else { gtk_widget_hide(container); + gtk_widget_show(summary); if (helper->assistant) gtk_assistant_set_page_complete(helper->assistant,page,TRUE); } + g_free(prefix); return TRUE; } @@ -653,22 +653,31 @@ return helper->unsatisfied; } +#define PLOVER_TRANSACTION_HELPER_IS_VALID_REPORT_ACTION(action) \ + ((action)==PLOVER_TRANSACTION_HELPER_REPORT_INSTALL || \ + (action)==PLOVER_TRANSACTION_HELPER_REPORT_REMOVE || \ + (action)==PLOVER_TRANSACTION_HELPER_REPORT_UPDATE) + gboolean plover_transaction_helper_add_transaction(PloverTransactionHelper *helper, PloverTransaction *transaction,struct plover_vector *report_packages, - enum razor_install_action report_action,GError **error) + PloverTransactionHelperReportAction report_action,GError **error) { int i,count; gboolean other_packages; const char *s,*name; enum razor_install_action action; struct razor_install_iterator *ii; - struct razor_set *next; + struct razor_set *report_set; struct razor_package *package; struct plover_vector *tasked_packages; + PloverTransactionHelperPrivate *priv; + GtkWidget *w; g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE); g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),FALSE); - g_return_val_if_fail(report_action==RAZOR_INSTALL_ACTION_ADD || report_action==RAZOR_INSTALL_ACTION_REMOVE,FALSE); + g_return_val_if_fail(PLOVER_TRANSACTION_HELPER_IS_VALID_REPORT_ACTION(report_action),FALSE); + g_return_val_if_fail(plover_transaction_get_system_set(transaction)!=NULL,FALSE); + priv=PLOVER_TRANSACTION_HELPER_GET_PRIVATE(helper); g_free(helper->unsatisfied); helper->unsatisfied=NULL; if (!plover_transaction_resolve(transaction,error)) @@ -680,17 +689,21 @@ ii=plover_transaction_get_install_iterator(transaction,error); if (!ii) return FALSE; - next=plover_transaction_get_next_set(transaction,error); - if (!next) + if (report_action==PLOVER_TRANSACTION_HELPER_REPORT_REMOVE) + report_set=plover_transaction_get_system_set(transaction); + else + report_set=plover_transaction_get_next_set(transaction,error); + if (!report_set) return FALSE; tasked_packages=plover_vector_new(); other_packages=FALSE; while (razor_install_iterator_next(ii,&package,&action,&count)) { - if (action==report_action) + if (action==report_action || action==RAZOR_INSTALL_ACTION_ADD && + report_action==PLOVER_TRANSACTION_HELPER_REPORT_UPDATE) { - razor_package_get_details(next,package,RAZOR_DETAIL_NAME,&name, - RAZOR_DETAIL_LAST); + razor_package_get_details(report_set,package,RAZOR_DETAIL_NAME, + &name,RAZOR_DETAIL_LAST); if (!report_packages || plover_vector_contains(report_packages,name)) plover_vector_append(tasked_packages,name); @@ -710,8 +723,8 @@ { if (action==report_action) { - razor_package_get_details(next,package,RAZOR_DETAIL_NAME,&name, - RAZOR_DETAIL_LAST); + razor_package_get_details(report_set,package,RAZOR_DETAIL_NAME, + &name,RAZOR_DETAIL_LAST); plover_vector_append(tasked_packages,name); } } @@ -720,7 +733,8 @@ { g_set_error(error,PLOVER_GENERAL_ERROR, PLOVER_GENERAL_ERROR_NO_WORK,"Transaction includes no %s actions", - report_action==RAZOR_INSTALL_ACTION_ADD?"add":"remove"); + report_action==PLOVER_TRANSACTION_HELPER_REPORT_REMOVE? + "remove":"add"); plover_vector_free(tasked_packages); return FALSE; } @@ -728,8 +742,22 @@ plover_transaction_helper_check_vendor(helper,error); g_object_ref(transaction); helper->transactions=g_slist_append(helper->transactions,transaction); - if (report_action==RAZOR_INSTALL_ACTION_ADD) + if (report_action==PLOVER_TRANSACTION_HELPER_REPORT_REMOVE) { + priv->transaction_type|=TRANSACTION_TYPE_REMOVE; + for(i=0;ilen;i++) + { + s=tasked_packages->strings[i]; + if (!plover_vector_contains(helper->report_removing,s)) + plover_vector_append(helper->report_removing,s); + } + helper->report_removing_dependants|=other_packages; + } + else + { + if (report_action==PLOVER_TRANSACTION_HELPER_REPORT_UPDATE) + priv->transaction_type|=TRANSACTION_TYPE_REMOVE; + priv->transaction_type|=TRANSACTION_TYPE_INSTALL; for(i=0;ilen;i++) { s=tasked_packages->strings[i]; @@ -738,15 +766,31 @@ } helper->report_adding_dependencies|=other_packages; } - else + w=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SIProgressLabel")); + switch(priv->transaction_type) { - for(i=0;ilen;i++) - { - s=tasked_packages->strings[i]; - if (!plover_vector_contains(helper->report_removing,s)) - plover_vector_append(helper->report_removing,s); - } - helper->report_removing_dependants|=other_packages; + case TRANSACTION_TYPE_INSTALL: + gtk_label_set_markup(GTK_LABEL(w), + "Installing the Software\n\n" + "Please wait while the Installation Assistant " + "installs the software.\n" + "This may take several minutes."); + break; + case TRANSACTION_TYPE_REMOVE: + gtk_label_set_markup(GTK_LABEL(w), + "Removing Packages\n\n" + "Please wait while the Installation Assistant " + "removes packages.\n" + "This may take several minutes."); + break; + default: + case TRANSACTION_TYPE_UPDATE: + gtk_label_set_markup(GTK_LABEL(w), + "Updating the Software\n\n" + "Please wait while the Installation Assistant " + "updates the software.\n" + "This may take several minutes."); + break; } plover_vector_free(tasked_packages); return TRUE; @@ -761,6 +805,7 @@ GError *tmp_error=NULL; PloverTransaction *transaction; g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL); + g_return_val_if_fail(helper->installed != NULL,NULL); prefix=plover_transaction_helper_get_prefix(helper,&tmp_error); if (tmp_error) { @@ -814,7 +859,7 @@ continue; if (pkg->type==COMPS_REQUIREMENT_DEFAULT || pkg->type==COMPS_REQUIREMENT_MANDATORY || - pkg->type==COMPS_REQUIREMENT_CONDITIONAL && + pkg->type==COMPS_REQUIREMENT_CONDITIONAL && pkg->requires && plover_vector_contains(default_packages,pkg->requires)) { changed=TRUE; @@ -852,7 +897,7 @@ return FALSE; } retval=plover_transaction_helper_add_transaction(helper,transaction, - packages,RAZOR_INSTALL_ACTION_ADD,error); + packages,PLOVER_TRANSACTION_HELPER_REPORT_INSTALL,error); g_object_unref(transaction); return retval; } @@ -896,6 +941,7 @@ struct plover_vector *selected_packages; PloverTransaction *transaction; g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE); + g_return_val_if_fail(helper->installed != NULL,FALSE); selected_packages=plover_transaction_helper_group_get_default_packages( helper,group,error); if (!selected_packages) @@ -917,7 +963,7 @@ return FALSE; } retval=plover_transaction_helper_add_transaction(helper,transaction, - NULL,RAZOR_INSTALL_ACTION_REMOVE,error); + NULL,PLOVER_TRANSACTION_HELPER_REPORT_REMOVE,error); g_object_unref(transaction); plover_vector_free(selected_packages); return retval; @@ -942,7 +988,7 @@ return FALSE; } retval=plover_transaction_helper_add_transaction(helper,transaction, - NULL,RAZOR_INSTALL_ACTION_ADD,error); + NULL,PLOVER_TRANSACTION_HELPER_REPORT_UPDATE,error); g_object_unref(transaction); return retval; } diff -r 99d80cbe2eb4 -r a29623b68ca2 plover-gtk/transactionhelper.h --- a/plover-gtk/transactionhelper.h Mon Apr 18 15:04:47 2016 +0100 +++ b/plover-gtk/transactionhelper.h Mon Jun 13 12:18:42 2016 +0100 @@ -25,6 +25,12 @@ PLOVER_TYPE_TRANSACTION_HELPER,\ PloverTransactionHelperClass) +typedef enum { + PLOVER_TRANSACTION_HELPER_REPORT_INSTALL=RAZOR_INSTALL_ACTION_ADD, + PLOVER_TRANSACTION_HELPER_REPORT_REMOVE=RAZOR_INSTALL_ACTION_REMOVE, + PLOVER_TRANSACTION_HELPER_REPORT_UPDATE +} PloverTransactionHelperReportAction; + typedef struct _PloverTransactionHelper { GObject parent_instance; PloverPackageSet *installed; @@ -77,7 +83,7 @@ gboolean plover_transaction_helper_add_transaction(PloverTransactionHelper *helper, PloverTransaction *transaction,struct plover_vector *report_packages, - enum razor_install_action report_action,GError **error); + PloverTransactionHelperReportAction report_action,GError **error); struct plover_vector *plover_transaction_helper_group_get_default_packages( PloverTransactionHelper *helper,const char *group,GError **error); gboolean diff -r 99d80cbe2eb4 -r a29623b68ca2 plover-open/plover-open.c --- a/plover-open/plover-open.c Mon Apr 18 15:04:47 2016 +0100 +++ b/plover-open/plover-open.c Mon Jun 13 12:18:42 2016 +0100 @@ -165,8 +165,8 @@ } #endif plover_exception_handler_init(); - razor_set_lua_loader("posix",luaopen_posix); - razor_set_lua_loader("whelk",luaopen_whelk); + razor_set_lua_loader("posix",(void (*)())luaopen_posix); + razor_set_lua_loader("whelk",(void (*)())luaopen_whelk); if (!gtk_init_with_args(&argc,&argv,NULL,options,NULL,&err)) { g_printerr("%s\n",err->message); diff -r 99d80cbe2eb4 -r a29623b68ca2 plover/Makefile.am --- a/plover/Makefile.am Mon Apr 18 15:04:47 2016 +0100 +++ b/plover/Makefile.am Mon Jun 13 12:18:42 2016 +0100 @@ -1,8 +1,9 @@ -AM_CFLAGS=-g $(LIBPLOVER_CFLAGS) -AM_CXXFLAGS=-g $(LIBPLOVER_CFLAGS) +AM_CFLAGS=-g $(LIBPLOVER_CFLAGS) $(CODE_COVERAGE_CFLAGS) +AM_CXXFLAGS=-g $(LIBPLOVER_CFLAGS) $(CODE_COVERAGE_CFLAGS) LIBS=$(LIBPLOVER_LIBS) INCLUDES=-I$(top_srcdir) -AM_LDFLAGS=-no-undefined -version-info $(LIBPLOVER_LT_VERSION_INFO) +AM_LDFLAGS=-no-undefined -version-info $(LIBPLOVER_LT_VERSION_INFO) \ + $(CODE_COVERAGE_LDFLAGS) pkginclude_HEADERS=plover.h transaction.h package.h packageset.h repository.h diff -r 99d80cbe2eb4 -r a29623b68ca2 plover/comps.c --- a/plover/comps.c Mon Apr 18 15:04:47 2016 +0100 +++ b/plover/comps.c Mon Jun 13 12:18:42 2016 +0100 @@ -57,7 +57,7 @@ } } -struct comps_group *comps_group_new(void) +static struct comps_group *comps_group_new(void) { struct comps_group *group; group=calloc(sizeof(*group),1); @@ -78,6 +78,7 @@ free(group); } } + static void comps_group_free(struct comps_group *group) { struct comps_group *next; diff -r 99d80cbe2eb4 -r a29623b68ca2 plover/log.c --- a/plover/log.c Mon Apr 18 15:04:47 2016 +0100 +++ b/plover/log.c Mon Jun 13 12:18:42 2016 +0100 @@ -169,7 +169,7 @@ data->dir=opendir(s); free(s); } - data->base=strdup(path+1); + data->base=strdup(base+1); } else { @@ -194,6 +194,7 @@ closedir(data->dir); return FALSE; } + data->suffix=NULL; if (find_suffixed_next(data)) return TRUE; free(data->entry); @@ -203,6 +204,7 @@ static void find_suffixed_close(struct find_suffixed_data *data) { + free(data->base); free(data->suffix); free(data->entry); closedir(data->dir); @@ -248,28 +250,33 @@ static int rotate_logfile(const char *path,struct tm *modified) { + gboolean okay_to_replace; gchar *s; char serial; char suffix[11]; /* -yyyymmdd or -yyyymmdds */ sprintf(suffix,"-%04d%02d%02d",modified->tm_year+1900,modified->tm_mon+1, modified->tm_mday); s=g_strconcat(path,suffix,NULL); - if (rename(path,s)) + if (g_file_test(s,G_FILE_TEST_EXISTS) || g_rename(path,s)) { suffix[10]='\0'; for(serial='a';serial<='z';serial++) { - if (errno!=EACCES || serial=='z') + free(s); + suffix[9]=serial; + s=g_strconcat(path,suffix,NULL); + if (serial=='z') + okay_to_replace=TRUE; + else + okay_to_replace=!g_file_test(s,G_FILE_TEST_EXISTS); + if (okay_to_replace && !g_rename(path,s)) + break; + else if (serial=='z') { - perror(s); + fprintf(stderr,"%s%s: Failed to rotate logfile\n",path,suffix); free(s); return -1; } - free(s); - suffix[9]=serial; - s=g_strconcat(path,suffix,NULL); - if (!rename(path,s)) - break; } } g_free(s); @@ -299,7 +306,10 @@ razor_atomic_get_error_msg(atomic)); razor_atomic_destroy(atomic); if (retval) + { + g_free(filename); return retval; + } if (stat(filename,&sb)<0) { if (errno!=ENOENT) diff -r 99d80cbe2eb4 -r a29623b68ca2 plover/package.c --- a/plover/package.c Mon Apr 18 15:04:47 2016 +0100 +++ b/plover/package.c Mon Jun 13 12:18:42 2016 +0100 @@ -28,7 +28,6 @@ typedef struct _PloverPackagePrivate { struct razor_set *set; struct razor_package *pkg; - GObject *file_store; const char **prefixes; } PloverPackagePrivate; @@ -47,17 +46,13 @@ { PloverPackagePrivate *priv=PLOVER_PACKAGE_GET_PRIVATE(obj); g_free(priv->prefixes); + razor_set_unref(priv->set); G_OBJECT_CLASS(plover_package_parent_class)->finalize(obj); } static void plover_package_dispose(GObject *obj) { PloverPackagePrivate *priv=PLOVER_PACKAGE_GET_PRIVATE(obj); - if (priv->file_store) - { - g_object_unref(priv->file_store); - priv->file_store=NULL; - } G_OBJECT_CLASS(plover_package_parent_class)->dispose(obj); } @@ -83,7 +78,7 @@ PloverPackagePrivate *priv; package=g_object_new(PLOVER_TYPE_PACKAGE,NULL); priv=PLOVER_PACKAGE_GET_PRIVATE(package); - priv->set=set; + priv->set=razor_set_ref(set); priv->pkg=pkg; return package; } @@ -241,6 +236,8 @@ PloverPackagePrivate *priv; g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL); priv=PLOVER_PACKAGE_GET_PRIVATE(package); + g_return_val_if_fail(priv->set!=NULL,NULL); + g_return_val_if_fail(priv->pkg!=NULL,NULL); return razor_file_iterator_create(priv->set,priv->pkg,reverse); } @@ -265,10 +262,10 @@ prefixes=g_ptr_array_new(); si=razor_install_prefix_iterator_create(priv->set,priv->pkg); while (razor_string_iterator_next(si,&prefix)) - g_ptr_array_add(prefixes,prefix); + g_ptr_array_add(prefixes,(gpointer)prefix); razor_string_iterator_destroy(si); g_ptr_array_add(prefixes,NULL); - priv->prefixes=g_ptr_array_free(prefixes,FALSE); + priv->prefixes=(const char **)g_ptr_array_free(prefixes,FALSE); } return priv->prefixes; } diff -r 99d80cbe2eb4 -r a29623b68ca2 plover/packageset.c --- a/plover/packageset.c Mon Apr 18 15:04:47 2016 +0100 +++ b/plover/packageset.c Mon Jun 13 12:18:42 2016 +0100 @@ -55,12 +55,19 @@ { PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(obj); g_free(priv->guessed_prefix); + g_free(priv->install_root); G_OBJECT_CLASS(plover_package_set_parent_class)->finalize(obj); } static void plover_package_set_dispose(GObject *obj) { PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(obj); + if (priv->packages) + { + g_slist_foreach(priv->packages,(GFunc)g_object_unref,NULL); + g_slist_free(priv->packages); + priv->packages=NULL; + } if (priv->set) { razor_set_unref(priv->set); diff -r 99d80cbe2eb4 -r a29623b68ca2 plover/transaction.c --- a/plover/transaction.c Mon Apr 18 15:04:47 2016 +0100 +++ b/plover/transaction.c Mon Jun 13 12:18:42 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2011, 2012, 2014 J. Ali Harlow + * Copyright (C) 2009, 2011, 2012, 2014, 2016 J. Ali Harlow * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,10 +32,23 @@ N_SIGNALS }; +typedef struct _PloverTransactionPrivate { + GMutex mutex; + gchar *status; +} PloverTransactionPrivate; + +#define PLOVER_TRANSACTION_GET_PRIVATE(obj)\ + G_TYPE_INSTANCE_GET_PRIVATE(obj,\ + PLOVER_TYPE_TRANSACTION,\ + PloverTransactionPrivate) + static guint signals[N_SIGNALS]; static void plover_transaction_finalize(PloverTransaction *transaction) { + PloverTransactionPrivate *priv=PLOVER_TRANSACTION_GET_PRIVATE(transaction); + g_free(priv->status); + g_mutex_clear(&priv->mutex); g_free(transaction->base); g_free(transaction->prefix); g_free(transaction->unsatisfied); @@ -66,10 +79,13 @@ signals[STATUS_CHANGED]=g_signal_new("status-changed", G_TYPE_FROM_CLASS(klass),G_SIGNAL_RUN_LAST,0,NULL,NULL, g_cclosure_marshal_VOID__STRING,G_TYPE_NONE,1,G_TYPE_STRING); + g_type_class_add_private(klass,sizeof(PloverTransactionPrivate)); } static void plover_transaction_init(PloverTransaction *transaction) { + PloverTransactionPrivate *priv=PLOVER_TRANSACTION_GET_PRIVATE(transaction); + g_mutex_init(&priv->mutex); } gboolean plover_transaction_resolve(PloverTransaction *transaction, @@ -167,28 +183,73 @@ return transaction->install_iterator; } +static gboolean + plover_transaction_emit_status_changed(PloverTransaction *transaction) +{ + gchar *status; + PloverTransactionPrivate *priv=PLOVER_TRANSACTION_GET_PRIVATE(transaction); + g_mutex_lock(&priv->mutex); + status=g_strdup(priv->status); + g_mutex_unlock(&priv->mutex); + g_signal_emit(transaction,signals[STATUS_CHANGED],0,status); + g_free(status); + return FALSE; /* No more calls */ +} + +static void plover_transaction_set_status(PloverTransaction *transaction, + gboolean via_g_idle,const char *status) +{ + PloverTransactionPrivate *priv=PLOVER_TRANSACTION_GET_PRIVATE(transaction); + g_mutex_lock(&priv->mutex); + g_free(priv->status); + priv->status=g_strdup(status); + g_mutex_unlock(&priv->mutex); + if (via_g_idle) + g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, + (GSourceFunc)plover_transaction_emit_status_changed, + g_object_ref(transaction),g_object_unref); + else + plover_transaction_emit_status_changed(transaction); +} + gboolean plover_transaction_commit(PloverTransaction *transaction, GCancellable *cancellable,GError **error) { - int r; + int r,count; + unsigned files_action; gboolean retval; size_t pos; struct razor_set *set; + struct razor_package *pkg; + enum razor_install_action action; struct razor_install_iterator *ii; struct razor_atomic *atomic; PloverPackageSet *next; + gboolean via_g_idle; g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),FALSE); if (g_cancellable_set_error_if_cancelled(cancellable,error)) return FALSE; ii=plover_transaction_get_install_iterator(transaction,error); if (!ii) return FALSE; + /* + * If we are called from the default thread it is most useful to + * emit signals directly however this is not safe when running in + * a non-default thread and we want to use g_idle to emit signals + * in the default thread instead. + * + * Note that the documentation for g_main_context_get_thread_default() + * explicitly states that it may return a non-NULL value even when + * called from the default thread. This would cause us to use g_idle + * when not strictly necessary, but will still be safe. + */ + via_g_idle=!!g_main_context_get_thread_default(); do { if (g_cancellable_set_error_if_cancelled(cancellable,error)) return FALSE; pos=razor_install_iterator_tell(ii); - g_signal_emit(transaction,signals[STATUS_CHANGED],0, + plover_transaction_set_status(transaction,via_g_idle, "Running pre-transaction scripts"); atomic=razor_atomic_open("package transaction"); next=plover_package_set_new_from_razor(transaction->next); @@ -198,7 +259,7 @@ transaction->relocations,RAZOR_STAGE_SCRIPTS_PRE,cancellable); if (r<0) { - g_signal_emit(transaction,signals[STATUS_CHANGED],0, + plover_transaction_set_status(transaction,via_g_idle, "Failed in pre-transaction scripts"); plover_propagate_razor_error_dup(error, razor_atomic_get_error(atomic)); @@ -208,8 +269,17 @@ } else { - g_signal_emit(transaction,signals[STATUS_CHANGED],0, - "Unpacking files"); + razor_install_iterator_seek(ii,pos); + files_action=0; + while (razor_install_iterator_next(ii,&pkg,&action,&count)) + if (action==RAZOR_INSTALL_ACTION_REMOVE) + files_action|=1; + else if (action==RAZOR_INSTALL_ACTION_ADD) + files_action|=2; + else + break; + plover_transaction_set_status(transaction,via_g_idle, + files_action==1?"Removing files":"Unpacking files"); razor_install_iterator_seek(ii,pos); r=plover_run_transaction(transaction->trans,ii, plover_package_set_get_install_root(transaction->installed), @@ -232,14 +302,14 @@ retval=!razor_atomic_commit(atomic); if (!retval) { - g_signal_emit(transaction,signals[STATUS_CHANGED],0, + plover_transaction_set_status(transaction,via_g_idle, "Failed to unpack all files correctly"); plover_propagate_razor_error_dup(error, razor_atomic_get_error(atomic)); } else { - g_signal_emit(transaction,signals[STATUS_CHANGED],0, + plover_transaction_set_status(transaction,via_g_idle, "Running post-transaction scripts"); razor_install_iterator_seek(ii,pos); plover_run_transaction(transaction->trans,ii, @@ -252,7 +322,7 @@ razor_atomic_destroy(atomic); g_object_unref(next); } while(retval && r==1); - g_signal_emit(transaction,signals[STATUS_CHANGED],0,"Completed"); + plover_transaction_set_status(transaction,via_g_idle,"Completed"); return retval; } @@ -261,11 +331,17 @@ { PloverTransaction *transaction=source_object; GError *error=NULL; - if (!plover_transaction_commit(transaction,cancellable,&error)) + GMainContext *context; + gboolean retval; + context=g_main_context_new(); + g_main_context_push_thread_default(context); + retval=plover_transaction_commit(transaction,cancellable,&error); + g_main_context_pop_thread_default(context); + g_main_context_unref(context); + if (!retval) g_task_return_error(task,error); else g_task_return_boolean(task,TRUE); - g_object_unref(task); } void plover_transaction_commit_async(PloverTransaction *transaction, @@ -275,6 +351,7 @@ g_return_if_fail(PLOVER_IS_TRANSACTION(transaction)); task=g_task_new(transaction,cancellable,callback,user_data); g_task_run_in_thread(task,plover_transaction_commit_async_thread); + g_object_unref(task); } gboolean plover_transaction_commit_finish(PloverTransaction *transaction, @@ -337,6 +414,11 @@ { g_return_if_fail(PLOVER_IS_TRANSACTION(transaction)); g_return_if_fail(PLOVER_IS_PACKAGE_SET(installed)); + if (transaction->system) + { + razor_set_unref(transaction->system); + transaction->system=NULL; + } if (transaction->installed) g_object_unref(transaction->installed); transaction->installed=g_object_ref(installed); @@ -360,9 +442,7 @@ g_object_unref(installed); return FALSE; } - if (transaction->installed) - g_object_unref(transaction->installed); - transaction->installed=installed; + plover_transaction_set_installed(transaction,installed); return TRUE; } @@ -417,6 +497,7 @@ system=plover_transaction_get_system_set(transaction); if (!system) { + /* Impossible */ g_set_error(error,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_FAILED, "Internal error: No system set"); return FALSE; @@ -451,6 +532,7 @@ system=plover_transaction_get_system_set(transaction); if (!system) { + /* Impossible */ g_set_error(error,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_FAILED, "Internal error: No system set"); return FALSE; @@ -546,6 +628,7 @@ system=plover_transaction_get_system_set(transaction); if (!system) { + /* Impossible */ g_set_error(error,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_FAILED, "Internal error: No system set"); return FALSE; @@ -583,36 +666,44 @@ return transaction; } -static GList *plover_what_requires(struct razor_set *set,const char *ref_name) +static GList *plover_what_has_property(struct razor_set *set,uint32_t prop_type, + const char *ref_name) { const char *name,*version; uint32_t flags; GList *list=NULL; struct razor_property *property; struct razor_package *package; - struct razor_package_iterator *what_requires; + struct razor_package_iterator *what_has; struct razor_property_iterator *all_props; all_props=razor_property_iterator_create(set,NULL); while (razor_property_iterator_next(all_props,&property,&name,&flags, &version)) { - if ((flags&RAZOR_PROPERTY_TYPE_MASK)!=RAZOR_PROPERTY_REQUIRES) + if ((flags&RAZOR_PROPERTY_TYPE_MASK)!=prop_type) continue; if (strcmp(name,ref_name)) continue; - what_requires=razor_package_iterator_create_for_property(set,property); - while(razor_package_iterator_next(what_requires,&package, + what_has=razor_package_iterator_create_for_property(set,property); + while(razor_package_iterator_next(what_has,&package, RAZOR_DETAIL_LAST)) list=g_list_prepend(list,package); - razor_package_iterator_destroy(what_requires); + razor_package_iterator_destroy(what_has); } razor_property_iterator_destroy(all_props); return list; } -/* - * Warning: This code is untested and probably wrong. - */ +static GList *plover_what_provides(struct razor_set *set,const char *ref_name) +{ + return plover_what_has_property(set,RAZOR_PROPERTY_PROVIDES,ref_name); +} + +static GList *plover_what_requires(struct razor_set *set,const char *ref_name) +{ + return plover_what_has_property(set,RAZOR_PROPERTY_REQUIRES,ref_name); +} + PloverTransaction *plover_transaction_new_remove_with_leaves(char **pkgs, GError **error) { @@ -624,6 +715,13 @@ struct razor_transaction *trans; PloverPackageSet *installed; PloverTransaction *transaction; + struct plover_vector *package_names; + GList *to_remove,*lnk,*lnk2,*what_requires,*what_provides; + struct razor_package *package,*maybe_unused_package; + struct razor_property *property; + struct razor_package_query *query; + struct razor_package_iterator *all_packages,*removed; + struct razor_property_iterator *removed_props; if (!pkgs) return plover_transaction_new_remove(NULL,error); installed=plover_package_set_new(); @@ -636,13 +734,6 @@ return NULL; } system=plover_package_set_get_razor(installed); - struct plover_vector *package_names; - GList *to_remove,*lnk,*what_requires; - struct razor_package *package,*maybe_unused_package; - struct razor_property *property; - struct razor_package_query *query; - struct razor_package_iterator *all_packages,*removed,*maybe_unused; - struct razor_property_iterator *removed_props; package_names=plover_vector_new(); for(i=0;pkgs[i];i++) plover_vector_append(package_names,pkgs[i]); @@ -679,15 +770,15 @@ { if ((flags&RAZOR_PROPERTY_TYPE_MASK)!=RAZOR_PROPERTY_REQUIRES) continue; - maybe_unused=razor_package_iterator_create_for_property(system, - property); - while(razor_package_iterator_next(maybe_unused, - &maybe_unused_package,RAZOR_DETAIL_NAME,&maybe_unused_name, - RAZOR_DETAIL_LAST)) + what_provides=plover_what_provides(system,name); + for(lnk2=what_provides;lnk2;lnk2=lnk2->next) { + maybe_unused_package=lnk2->data; if (g_list_find(to_remove,maybe_unused_package)) continue; is_leaf=TRUE; + razor_package_get_details(system,maybe_unused_package, + RAZOR_DETAIL_NAME,&maybe_unused_name,RAZOR_DETAIL_LAST); what_requires=plover_what_requires(system, maybe_unused_name); for(lnk=what_requires;lnk;lnk=lnk->next) @@ -704,7 +795,6 @@ changed=TRUE; } } - razor_package_iterator_destroy(maybe_unused); } razor_property_iterator_destroy(removed_props); } diff -r 99d80cbe2eb4 -r a29623b68ca2 plover/transaction.h --- a/plover/transaction.h Mon Apr 18 15:04:47 2016 +0100 +++ b/plover/transaction.h Mon Jun 13 12:18:42 2016 +0100 @@ -40,10 +40,6 @@ } PloverTransactionClass; GType plover_transaction_get_type(void) G_GNUC_CONST; -void plover_transaction_commit_async(PloverTransaction *transaction, - GCancellable *cancellable,GAsyncReadyCallback callback,gpointer user_data); -gboolean plover_transaction_commit_finish(PloverTransaction *transaction, - GAsyncResult *result,GError **error); PloverTransaction *plover_transaction_new(); void plover_transaction_set_prefix(PloverTransaction *transaction, const char *prefix); @@ -52,7 +48,7 @@ gboolean plover_transaction_root_open(PloverTransaction *transaction, const char *install_root,GError **error); struct razor_set *plover_transaction_import_yum(PloverTransaction *transaction, - const char *base,GError **error); + const char *base,GError **error) G_GNUC_DEPRECATED; gboolean plover_transaction_set_upstream(PloverTransaction *transaction, PloverRepository *upstream,GError **error); gboolean @@ -70,6 +66,8 @@ char **pkgs,GError **error); PloverTransaction *plover_transaction_new_remove(char **pkgs, GError **error); +PloverTransaction *plover_transaction_new_remove_with_leaves(char **pkgs, + GError **error); gboolean plover_transaction_resolve(PloverTransaction *transaction, GError **error); const char *plover_transaction_get_unsatisfied(PloverTransaction *transaction); @@ -83,5 +81,7 @@ GCancellable *cancellable,GError **error); void plover_transaction_commit_async(PloverTransaction *transaction, GCancellable *cancellable,GAsyncReadyCallback callback,gpointer user_data); +gboolean plover_transaction_commit_finish(PloverTransaction *transaction, + GAsyncResult *result,GError **error); #endif /* __PLOVER_TRANSACTION_H__ */ diff -r 99d80cbe2eb4 -r a29623b68ca2 plover/util.c --- a/plover/util.c Mon Apr 18 15:04:47 2016 +0100 +++ b/plover/util.c Mon Jun 13 12:18:42 2016 +0100 @@ -57,7 +57,12 @@ } return g_strconcat(program_files,"\\",vendor?vendor:"Plover",NULL); #else - return NULL; + const char *vendor_prefix; + vendor_prefix=g_getenv("PLOVER_VENDOR_PREFIX"); + if (!vendor_prefix) + return NULL; + else + return g_build_filename(vendor_prefix,vendor?vendor:"Plover",NULL); #endif } diff -r 99d80cbe2eb4 -r a29623b68ca2 pre-inst/pre-inst.c --- a/pre-inst/pre-inst.c Mon Apr 18 15:04:47 2016 +0100 +++ b/pre-inst/pre-inst.c Mon Jun 13 12:18:42 2016 +0100 @@ -141,8 +141,8 @@ void *retval; #endif char *path; - razor_set_lua_loader("posix",luaopen_posix); - razor_set_lua_loader("whelk",luaopen_whelk); + razor_set_lua_loader("posix",(void (*)())luaopen_posix); + razor_set_lua_loader("whelk",(void (*)())luaopen_whelk); path=plover_get_program_directory(argv0); #ifdef WIN32 retval=(HANDLE)_beginthreadex(NULL,0,pre_install_thread,path,0,NULL); @@ -194,8 +194,8 @@ gboolean success; gchar *s; GError *error=NULL; - razor_set_lua_loader("posix",luaopen_posix); - razor_set_lua_loader("whelk",luaopen_whelk); + razor_set_lua_loader("posix",(void (*)())luaopen_posix); + razor_set_lua_loader("whelk",(void (*)())luaopen_whelk); prefix=plover_pre_install_prefix(); s=g_strconcat(prefix,"/var/lib/razor",NULL); razor_set_database_path(s); diff -r 99d80cbe2eb4 -r a29623b68ca2 setup/setup.c --- a/setup/setup.c Mon Apr 18 15:04:47 2016 +0100 +++ b/setup/setup.c Mon Jun 13 12:18:42 2016 +0100 @@ -113,8 +113,8 @@ { GError *error=NULL; plover_exception_handler_init(); - razor_set_lua_loader("posix",luaopen_posix); - razor_set_lua_loader("whelk",luaopen_whelk); + razor_set_lua_loader("posix",(void (*)())luaopen_posix); + razor_set_lua_loader("whelk",(void (*)())luaopen_whelk); if (argc>1 && !strcmp(argv[1],"-u")) { if (!plover_remove(NULL,&error)) diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/Makefile.am --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/Makefile.am Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,77 @@ +SUBDIRS = . plover plover-gtk + +EXTRA_DIST = zsh.spec zsh2.spec zip.spec zap.spec filesystem.spec zappy.spec \ + zappy2.spec unsatisfiable.spec uninstallable.spec badpostun.spec comps.xml \ + glib.supp.in README xvfb-run + +if HAVE_CHECK_TOOLS + +noinst_DATA = glib.supp yum-repo-test-dir/repodata/primary.xml.gz \ + primary.xml.gz razor-test-dir/var/lib/razor/system.rzdb + +if HAVE_VALGRIND_3_9 +%.supp: %.supp.in + cat $< > $@ +else +%.supp: %.supp.in + grep -v '^ *match-leak-kinds: ' $< > $@ +endif + +yum-repo-test-dir/repodata/primary.xml.gz: zsh.spec zsh2.spec zip.spec \ + zap.spec filesystem.spec zappy.spec zappy2.spec unsatisfiable.spec \ + uninstallable.spec badpostun.spec Makefile + rm -rf rpmbuild yum-repo-test-dir + mkdir -p rpmbuild/BUILD rpmbuild/RPMS + $(RPMBUILD) --define "_topdir `pwd`/rpmbuild" -bb $(srcdir)/zap.spec + $(RPMBUILD) --define "_topdir `pwd`/rpmbuild" --define "_version 1" \ + -bb $(srcdir)/zip.spec + $(RPMBUILD) --define "_topdir `pwd`/rpmbuild" -bb $(srcdir)/zsh.spec + $(RPMBUILD) --define "_topdir `pwd`/rpmbuild" -bb $(srcdir)/zsh2.spec + $(RPMBUILD) --define "_topdir `pwd`/rpmbuild" -bb \ + $(srcdir)/filesystem.spec + $(RPMBUILD) --define "_topdir `pwd`/rpmbuild" -bb $(srcdir)/zappy.spec + $(RPMBUILD) --define "_topdir `pwd`/rpmbuild" -bb $(srcdir)/zappy2.spec + $(RPMBUILD) --define "_topdir `pwd`/rpmbuild" -bb \ + $(srcdir)/unsatisfiable.spec + $(RPMBUILD) --define "_topdir `pwd`/rpmbuild" -bb \ + $(srcdir)/uninstallable.spec + $(RPMBUILD) --define "_topdir `pwd`/rpmbuild" -bb \ + $(srcdir)/badpostun.spec + mkdir -p yum-repo-test-dir/rpms + mv rpmbuild/RPMS/noarch/*.rpm yum-repo-test-dir/rpms + rm -rf rpmbuild + cp $(srcdir)/comps.xml yum-repo-test-dir/rpms + $(CREATEREPO) --simple-md-filenames -g comps.xml -o yum-repo-test-dir \ + yum-repo-test-dir/rpms + $(RM) yum-repo-test-dir/rpms/comps.xml + cp $(srcdir)/comps.xml yum-repo-test-dir/repodata + +primary.xml.gz: yum-repo-test-dir/repodata/primary.xml.gz + cp yum-repo-test-dir/repodata/primary.xml.gz \ + yum-repo-test-dir/repodata/filelists.xml.gz . + rm -rf rpms + ln -s yum-repo-test-dir/rpms . + +razor-test-dir/var/lib/razor/system.rzdb: primary.xml.gz + $(RM) -r razor-test-dir + $(RAZOR) --root=razor-test-dir init + $(RAZOR) --root=razor-test-dir \ + --url=file://localhost/`pwd`/yum-repo-test-dir import-yum + $(RAZOR) --root=razor-test-dir install zap zappy zappy2 zappy-tools + +endif + +check-valgrind: + $(RM) test-suite-*.log + -(cd plover && $(MAKE) $(AM_MAKEFLAGS) check-valgrind) + -(cd plover-gtk && $(MAKE) $(AM_MAKEFLAGS) check-valgrind) + @for infile in plover/test-suite-*.log plover-gtk/test-suite-*.log; do \ + outfile=`echo $$infile | sed -e 's:.*/::'`; \ + cat $$infile >> $$outfile; \ + done + +clean-local: + rm -rf yum-repo-test-dir razor-test-dir + rm -f primary.xml.gz filelists.xml.gz rpms rawhide.rzdb + +CLEANFILES = glib.supp diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/README Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,19 @@ +There are a number of good sources for valgrind suppression files: + +1) The cockpit project: http://cockpit-project.org + Suppression files are in the tools directory: + https://github.com/cockpit-project/cockpit/tree/master/tools + +2) Johan Dahlin's file for the Gtk stack: + https://people.gnome.org/~johan/gtk.suppression + +3) Daniel Trebbien's GNOME.supp project: + https://github.com/dtrebbien/GNOME.supp + +At the time of testing, the cockpit project produced far better results +against glib version 2.36.3 and so that is what is included. + + +xvfb-run comes from Debian: + +https://anonscm.debian.org/cgit/pkg-xorg/xserver/xorg-server.git/tree/debian/local/xvfb-run diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/badpostun.spec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/badpostun.spec Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,33 @@ +%define _source_payload w9.gzdio +%define _binary_payload w9.gzdio + +Name: badpostun +Summary: A package that fails in its postun script +Group: Test +License: GPL +URL: http://www.juiblex.co.uk/beach +Version: 1 +Release: 1 +Source: badpostun.tar +BuildArch: noarch +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +Prefix: /usr + +%description +A package that fails in its postun script, triggering a warning on removal. + +%prep + +%build + +%install +mkdir -p $RPM_BUILD_ROOT/usr/bin +echo %{name}-%{version}-%{release} > $RPM_BUILD_ROOT/usr/bin/badpostun + +%clean + +%postun -p +error("Failed after uninstall") + +%files +/usr/bin/badpostun diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/comps.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/comps.xml Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,34 @@ + + + + + base + Base + A set of base packages + true + true + + zsh + zsh2 + zip + zap + filesystem + zappy + zappy-tools + zappy2 + + + + zappy + Zappy + A set of zappy packages + true + + zap + zappy + zappy2 + zappy-tools + + + diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/filesystem.spec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/filesystem.spec Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,41 @@ +%define _source_payload w9.gzdio +%define _binary_payload w9.gzdio + +Name: filesystem +Summary: Test package +Group: Test +License: GPL +Version: 1 +Release: 1 +BuildArch: noarch +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + +%description +Test package + +%prep + +%build + +%install +mkdir -p %{buildroot} +mkdir -p %{buildroot}%{_sysconfdir} +mkdir -p %{buildroot}/{%{_bindir},%{_prefix}/lib,%{_includedir}} +mkdir -p %{buildroot}/media + +%clean +rm -rf %{buildroot} + +%post -p +function mkdir_missing(dir) + if posix.stat(dir) == nil then + posix.mkdir(dir) + end +end +mkdir_missing("/media/cdrom") + +%files +%defattr(0755,root,root) +/etc +%{_prefix} +%dir /media diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/glib.supp.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/glib.supp.in Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,521 @@ +# This GLib suppressions file is known to be used at least by: +# +# - rpm-software-management/libhif +# +# This file should be treated as canonical. +{ + gobject_init_1 + Memcheck:Leak + ... + fun:gobject_init +} +{ + g_type_register_static_1 + Memcheck:Leak + ... + fun:g_type_register_static +} +{ + g_type_register_fundamental + Memcheck:Leak + ... + fun:g_type_register_fundamental +} +{ + g_type_init_with_debug_flags + Memcheck:Leak + ... + fun:g_type_init_with_debug_flags +} +{ + g_type_class_ref_1 + Memcheck:Leak + ... + fun:type_iface_vtable_base_init_Wm + ... + fun:g_type_class_ref +} +{ + g_type_class_ref_2 + Memcheck:Leak + ... + fun:type_class_init_Wm + ... + fun:g_type_class_ref +} +{ + g_type_add_interface_static + Memcheck:Leak + ... + fun:g_type_add_interface_static +} +{ + g_param_spec_internal + Memcheck:Leak + ... + fun:g_type_class_ref + fun:g_type_create_instance + fun:g_param_spec_internal +} +{ + g_param_spec_enum + Memcheck:Leak + ... + fun:g_type_class_ref + fun:g_param_spec_enum +} +{ + g_param_spec_flags + Memcheck:Leak + ... + fun:g_type_class_ref + fun:g_param_spec_flags +} +{ + g_quark_from_static_string + Memcheck:Leak + ... + fun:g_quark_from_static_string +} +{ + g_quark_from_string + Memcheck:Leak + ... + fun:g_quark_from_string +} +{ + g_value_register_transform_func + Memcheck:Leak + ... + fun:g_value_register_transform_func +} +{ + test_run_seed + Memcheck:Leak + ... + fun:g_rand_new_with_seed_array + fun:test_run_seed + ... + fun:g_test_run_suite +} +{ + g_test_init + Memcheck:Leak + ... + fun:g_rand_new_with_seed_array + ... + fun:g_test_init +} +{ + g_intern_static_string + Memcheck:Leak + ... + fun:g_intern_static_string +} +{ + g_main_context_push_thread_default + Memcheck:Leak + ... + fun:g_queue_new + fun:g_main_context_push_thread_default +} +{ + g_dbus_error_register_error + Memcheck:Leak + ... + fun:g_dbus_error_register_error +} +{ + g_param_spec_pool_insert + Memcheck:Leak + ... + fun:g_param_spec_pool_insert +} +{ + g_main_context_default + Memcheck:Leak + ... + fun:g_main_context_default +} +{ + g_main_context_check + Memcheck:Leak + ... + fun:g_ptr_array_add + fun:g_main_context_check +} +{ + g_test_run_suite + Memcheck:Leak + ... + fun:g_slist_copy + fun:g_test_run_suite_internal + fun:g_test_run_suite +} +{ + g_dbus_interface_info_cache_build + Memcheck:Leak + ... + fun:g_dbus_interface_info_cache_build +} +{ + g_cancellable_push_current + Memcheck:Leak + ... + fun:thread_memory_from_self + ... + fun:g_cancellable_push_current +} +{ + _g_io_module_get_default + Memcheck:Leak + ... + fun:g_io_module_new + fun:g_io_modules_scan_all_in_directory_with_scope + fun:_g_io_modules_ensure_loaded + fun:_g_io_module_get_default +} +{ + g_io_scheduler_push_job + Memcheck:Leak + ... + fun:init_scheduler + fun:g_once_impl + fun:g_io_scheduler_push_job +} +{ + g_io_scheduler_push_job_2 + Memcheck:Leak + ... + fun:g_system_thread_new + ... + fun:g_io_scheduler_push_job +} +{ + g_bus_get_sync__available_connections + Memcheck:Leak + ... + fun:g_hash_table_new + fun:initable_init + fun:g_initable_init + fun:g_bus_get_sync +} +{ + g_socket_connection_factory_register_type + Memcheck:Leak + ... + fun:g_socket_connection_factory_register_type +} +{ + g_test_add_vtable + Memcheck:Leak + ... + fun:g_test_add_vtable +} +{ + g_mutex_lock + Memcheck:Leak + ... + fun:g_mutex_impl_new + fun:g_mutex_get_impl + fun:g_mutex_lock +} +{ + g_thread_self + Memcheck:Leak + ... + fun:g_thread_self +} +{ + g_rec_mutex_lock + Memcheck:Leak + ... + fun:g_rec_mutex_impl_new + fun:g_rec_mutex_get_impl + fun:g_rec_mutex_lock +} +{ + test_case_run + Memcheck:Leak + ... + fun:g_malloc0 + fun:test_case_run + ... + fun:g_test_run_suite +} +{ + g_get_charset + Memcheck:Leak + ... + fun:g_get_charset +} +{ + g_test_run_suite__timer_new + Memcheck:Leak + ... + fun:g_timer_new + fun:test_case_run + ... + fun:g_test_run_suite +} +{ + g_test_run_suite__timer_new2 + Memcheck:Leak + ... + fun:g_timer_new + fun:test_case_run_suite_internal + ... + fun:g_test_run_suite +} +{ + g_test_run_suite__strconcat + Memcheck:Leak + ... + fun:g_strconcat + fun:test_case_run + ... + fun:g_test_run_suite + fun:g_test_run +} +{ + g_type_interface_add_prerequisite + Memcheck:Leak + ... + fun:g_type_interface_add_prerequisite +} +{ + + Memcheck:Leak + ... + fun:g_slist_copy + fun:g_test_run_suite_internal + ... + fun:g_test_run_suite +} +{ + g_set_prgname + Memcheck:Leak + ... + fun:g_set_prgname +} +{ + g_test_run_suite__strconcat_2 + Memcheck:Leak + ... + fun:g_strconcat + fun:g_test_run_suite_internal +} +{ + g_test_run_suite__strdup + Memcheck:Leak + ... + fun:g_strdup + fun:g_test_run_suite_internal +} +{ + g_private_get + Memcheck:Leak + ... + fun:g_private_get +} +{ + g_private_set + Memcheck:Leak + ... + fun:g_private_set +} +{ + g_static_mutex_get_mutex_impl + Memcheck:Leak + ... + fun:g_static_mutex_get_mutex_impl +} +{ + g_variant_type_info_unref + Memcheck:Leak + ... + fun:g_hash_table_remove + fun:g_variant_type_info_unref +} +{ + g_rw_lock_reader_lock + Memcheck:Leak + ... + fun:g_rw_lock_impl_new + fun:g_rw_lock_get_impl + fun:g_rw_lock_reader_lock +} +{ + g_child_watch_finalize__rt_sigaction + Memcheck:Param + rt_sigaction(act->sa_flags) + fun:__libc_sigaction + ... + fun:g_child_watch_finalize +} +{ + gdbus_shared_thread_func + Memcheck:Leak + match-leak-kinds: definite + ... + fun:g_malloc + ... + fun:gdbus_shared_thread_func +} +{ + g_task_start_task_thread + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:g_malloc + fun:g_slice_alloc + fun:g_slice_alloc0 + ... + fun:g_thread_pool_push + fun:g_task_start_task_thread +} +{ + g_get_language_names + Memcheck:Leak + match-leak-kinds: definite + fun:calloc + fun:g_malloc0 + fun:g_get_language_names +} +{ + g_get_filename_charsets + Memcheck:Leak + match-leak-kinds: definite + ... + fun:g_get_filename_charsets + fun:g_filename_display_name +} +{ + g_main_current_source + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:g_malloc + ... + fun:g_main_current_source + fun:g_task_return + fun:g_task_thread_pool_thread +} +{ + g_once_init_enter + Memcheck:Leak + match-leak-kinds: definite + ... + fun:g_once_init_enter +} +{ + g_child_watch_source_new + Memcheck:Leak + match-leak-kinds: definite + ... + fun:g_thread_new + ... + fun:g_child_watch_source_new +} +{ + continue_writing_in_idle_cb + Memcheck:Leak + match-leak-kinds: definite + ... + fun:g_task_new + ... + fun:continue_writing_in_idle_cb + fun:g_main_context_dispatch +} +{ + g_main_current_source + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + ... + fun:g_main_current_source +} +{ + g_thread_pool_push + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + ... + fun:g_thread_pool_push +} +{ + leak_test_dbus_dispose + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + ... + fun:g_main_loop_run + fun:g_test_dbus_down +} +{ + leak_test_dbus_down + Memcheck:Leak + match-leak-kinds: definite + fun:calloc + fun:g_malloc0 + fun:g_main_loop_new + fun:g_test_dbus_down +} +{ + leak_socket_client_connect + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:g_malloc + fun:g_slice_alloc + fun:g_slice_alloc0 + fun:g_socket_client_connect_async + fun:g_socket_client_connect_to_uri_async +} +{ + leak_signal_handlers_disconnect_matched + Memcheck:Leak + match-leak-kinds: definite + fun:calloc + fun:g_malloc0 + ... + fun:g_slice_alloc + ... + fun:g_signal_handlers_disconnect_matched +} +{ + g_tls_connection_gnutls_init_priorities + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:g_malloc + fun:g_strdup + fun:g_tls_connection_gnutls_init_priorities +} +{ + g_tls_connection_gnutls_heisenbug_likely_same_as_above + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:g_malloc + fun:g_strdup + ... + fun:g_tls_client_connection_new +} +{ + g_unix_signal_add_full + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:g_malloc + ... + fun:g_thread_new + ... + fun:g_unix_signal_add_full +} +{ + glib_worker_1 + Memcheck:Leak + ... + fun:glib_worker_main +} diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/plover-gtk/Makefile.am --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/plover-gtk/Makefile.am Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,45 @@ +AM_CFLAGS=-g $(PLOVER_GTK_CFLAGS) +INCLUDES=-I$(top_srcdir) +LDADD=../../plover-gtk/libplover-gtk.la ../../plover/libplover.la \ + $(PLOVER_GTK_LIBS) + +if HAVE_CHECK_TOOLS + +TESTS = $(txt_tests) $(gui_tests:=.xvfb) +TESTS_ENVIRONMENT = gtk_srcdir="$(top_srcdir)/plover-gtk" +TEST_EXTENSIONS = .xvfb +XVFB_LOG_COMPILER = $(top_srcdir)/tests/xvfb-run +XVFB_LOG_FLAGS = --auto-servernum --auth-file .Xauthority + +check_PROGRAMS = $(txt_tests) $(gui_tests) + +txt_tests = test-packagefilestore test-packagestore test-stockicons +gui_tests = test-transactionhelper + +test_packagefilestore_SOURCES = test-packagefilestore.c treemodel.c treemodel.h +test_packagestore_SOURCES = test-packagestore.c treemodel.c treemodel.h +test_stockicons_DEPENDENCIES = \ + icons/hicolor/scalable/mimetypes/application-x-redhat-package-manager.svg + +.c.xvfb: + $(AM_V_GEN)echo '#!/bin/sh' > $@ + $(AM_V_GEN)echo '$(LOG_COMPILER) $(LOG_FLAGS) ./$*' >> $@ + $(AM_V_GEN)chmod +x $@ + +icons/hicolor/scalable/mimetypes/application-x-redhat-package-manager.svg: \ + $(top_srcdir)/plover-open/mimetypes-application-x-rpm.svg + $(PLOVER_V_SKIP)mkdir -p icons/hicolor/scalable/mimetypes \ + icons/hicolor/24x24/mimetypes icons/hicolor/48x48/mimetypes + $(AM_V_GEN)cp $< $@ + $(AM_V_GEN)rsvg -w 24 -h 24 -f png $< \ + icons/hicolor/24x24/mimetypes/application-x-redhat-package-manager.png + $(AM_V_GEN)rsvg -w 48 -h 48 -f png $< \ + icons/hicolor/48x48/mimetypes/application-x-redhat-package-manager.png + +endif + +@VALGRIND_CHECK_RULES@ +VALGRIND_SUPPRESSIONS_FILES = ../glib.supp + +clean-local: + rm -rf icons razor-test-dir-* $(gui_tests:=.xvfb) .Xauthority diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/plover-gtk/test-packagefilestore.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/plover-gtk/test-packagefilestore.c Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2016 J. Ali Harlow + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "treemodel.h" + +static PloverPackage *package_getref(const char *name) +{ + GSList *packages,*lnk; + GError *err=NULL; + PloverPackageSet *package_set; + PloverPackage *package; + package_set=plover_package_set_new_from_yum("../yum-repo-test-dir",NULL, + &err); + if (!package_set) + g_error("../yum-repo-test-dir: %s",err->message); + packages=plover_package_set_get_packages(package_set); + for(lnk=packages;lnk;lnk=lnk->next) + { + package=lnk->data; + if (!strcmp(plover_package_get_name(package),name)) + break; + } + if (!lnk) + package=NULL; + if (package) + g_object_ref(package); + g_object_unref(package_set); + return package; +} + +static void test_empty(void) +{ + PloverPackage *package; + PloverPackageFileStore *store; + package=package_getref("zappy-tools"); + store=plover_package_file_store_new_from_package(package); + g_object_unref(package); + test_tree_model(GTK_TREE_MODEL(store)); + g_object_unref(store); +} + +static void test_basic(void) +{ + int i; + const char *name; + GValue value={0,}; + GtkTreeModel *model; + GtkTreeIter iter; + PloverPackage *package; + PloverPackageFileStore *store; + GList *expected,*lnk; + package=package_getref("zsh"); + store=plover_package_file_store_new_from_package(package); + g_object_unref(package); + model=GTK_TREE_MODEL(store); + test_tree_model(model); + expected=g_list_prepend(NULL,(gpointer)g_intern_string("/etc/zsh.conf")); + expected=g_list_prepend(expected,(gpointer)g_intern_string("/usr/bin/zsh")); + g_assert_cmpint(gtk_tree_model_get_n_columns(model),==,1); + g_assert_cmpint(gtk_tree_model_get_column_type(model,0),==,G_TYPE_STRING); + for(i=0;;i++) + { + if (!gtk_tree_model_iter_nth_child(model,&iter,NULL,i)) + break; + gtk_tree_model_get_value(model,&iter,0,&value); + name=g_value_get_string(&value); + lnk=g_list_find(expected,g_intern_string(name)); + if (!lnk) + g_warning("Unexpected file in zsh package: %s",name); + else + expected=g_list_delete_link(expected,lnk); + g_value_unset(&value); + } + if (expected) + g_warning("%d missing file%s in set, including %s", + g_list_length(expected),g_list_length(expected)==1?"":"s", + expected->data); + g_object_unref(store); +} + +int main(int argc,char **argv) +{ + int retval; + gtk_test_init(&argc,&argv,NULL); + g_test_bug_base("mailto:ali@juiblex.co.uk"); + g_test_add_func("/packagefilestore/empty",test_empty); + g_test_add_func("/packagefilestore/basic",test_basic); + retval=g_test_run(); + return retval; +} diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/plover-gtk/test-packagestore.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/plover-gtk/test-packagestore.c Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2016 J. Ali Harlow + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "treemodel.h" + +static void verify_package_store(PloverPackageStore *store, + GSList *expected_packages) +{ + int i; + const char *s; + gchar *nosummary; + PloverPackage *package; + PloverPackageSet *package_set; + GtkTreeModel *model; + GtkTreeIter iter; + GValue value={0,}; + GSList *expected,*lnk; + GdkPixbuf *icon; + model=GTK_TREE_MODEL(store); + test_tree_model(model); + expected=g_slist_copy(expected_packages); + g_assert_cmpint(gtk_tree_model_get_n_columns(model),==,PLOVER_PACKAGE_STORE_NO_COLUMNS); + g_assert_cmpint(gtk_tree_model_get_column_type(model,PLOVER_PACKAGE_STORE_OBJ_COLUMN),==,PLOVER_TYPE_PACKAGE); + g_assert_cmpint(gtk_tree_model_get_column_type(model,PLOVER_PACKAGE_STORE_INSTALLED_COLUMN),==,G_TYPE_BOOLEAN); + g_assert_cmpint(gtk_tree_model_get_column_type(model,PLOVER_PACKAGE_STORE_ICON_COLUMN),==,GDK_TYPE_PIXBUF); + g_assert_cmpint(gtk_tree_model_get_column_type(model,PLOVER_PACKAGE_STORE_NAME_COLUMN),==,G_TYPE_STRING); + g_assert_cmpint(gtk_tree_model_get_column_type(model,PLOVER_PACKAGE_STORE_VERSION_COLUMN),==,G_TYPE_STRING); + g_assert_cmpint(gtk_tree_model_get_column_type(model,PLOVER_PACKAGE_STORE_SUMMARY_COLUMN),==,G_TYPE_STRING); + for(i=0;;i++) + { + if (!gtk_tree_model_iter_nth_child(model,&iter,NULL,i)) + break; + gtk_tree_model_get_value(model,&iter,PLOVER_PACKAGE_STORE_OBJ_COLUMN, + &value); + package=g_value_dup_object(&value); + lnk=g_slist_find(expected,package); + if (!lnk) + g_warning("Unexpected package in store: %s", + plover_package_get_name(package)); + else + { + g_object_unref(lnk->data); + expected=g_slist_delete_link(expected,lnk); + } + g_value_unset(&value); + gtk_tree_model_get_value(model,&iter, + PLOVER_PACKAGE_STORE_INSTALLED_COLUMN,&value); + g_assert_cmpint(G_VALUE_TYPE(&value),==,G_TYPE_BOOLEAN); + /* Can't check value of installed yet, it + * isn't set (or even properly defined). + */ + g_value_unset(&value); + gtk_tree_model_get_value(model,&iter, + PLOVER_PACKAGE_STORE_ICON_COLUMN,&value); + icon=g_value_get_object(&value); + if (icon) + g_assert(GDK_IS_PIXBUF(icon)); + g_value_unset(&value); + gtk_tree_model_get_value(model,&iter,PLOVER_PACKAGE_STORE_NAME_COLUMN, + &value); + s=g_value_get_string(&value); + g_assert_cmpstr(plover_package_get_name(package),==,s); + g_value_unset(&value); + gtk_tree_model_get_value(model,&iter, + PLOVER_PACKAGE_STORE_VERSION_COLUMN,&value); + s=g_value_get_string(&value); + g_assert_cmpstr(plover_package_get_version(package),==,s); + g_value_unset(&value); + gtk_tree_model_get_value(model,&iter, + PLOVER_PACKAGE_STORE_SUMMARY_COLUMN,&value); + s=g_value_get_string(&value); + if (*plover_package_get_summary(package)) + g_assert_cmpstr(plover_package_get_summary(package),==,s); + else + { + nosummary=g_strconcat("The ",plover_package_get_name(package), + " package",NULL); + g_assert_cmpstr(nosummary,==,s); + g_free(nosummary); + } + g_value_unset(&value); + } + if (expected) + { + package=PLOVER_PACKAGE(expected->data); + g_warning("%d missing package%s in store, including %s", + g_slist_length(expected),g_slist_length(expected)==1?"":"s", + plover_package_get_name(package)); + } +} + +static void test_empty(void) +{ + PloverPackageStore *store; + store=plover_package_store_new(); + g_assert(!plover_package_store_get_sets(store)); + verify_package_store(store,NULL); + g_object_unref(store); +} + +static void test_basic(void) +{ + PloverPackageSet *package_set; + PloverPackageStore *store; + GError *err=NULL; + GSList *expected; + package_set=plover_package_set_new_from_yum("../yum-repo-test-dir",NULL, + &err); + if (!package_set) + g_error("../yum-repo-test-dir: %s",err->message); + store=plover_package_store_new(); + plover_package_store_add_set(store,package_set); + expected=g_slist_copy(plover_package_set_get_packages(package_set)); + g_slist_foreach(expected,(GFunc)g_object_ref,NULL); + g_object_unref(package_set); + verify_package_store(store,expected); + g_slist_foreach(expected,(GFunc)g_object_unref,NULL); + g_slist_free(expected); + g_object_unref(store); +} + +static PloverPackageSet *no_details_new(void) +{ + struct razor_set *set; + struct razor_importer *importer; + PloverPackageSet *package_set; + importer=razor_importer_create(); + razor_importer_begin_package(importer,"no-details","1-1","noarch"); + razor_importer_add_details(importer,"","","",""); + razor_importer_add_property(importer,"no-details", + RAZOR_PROPERTY_PROVIDES|RAZOR_PROPERTY_EQUAL,"1-1"); + razor_importer_finish_package(importer); + set=razor_importer_finish(importer); + package_set=plover_package_set_new_from_razor(set); + razor_set_unref(set); + return package_set; +} + +static void test_no_details(void) +{ + PloverPackageSet *package_set; + PloverPackageStore *store; + GSList *expected; + package_set=no_details_new(); + store=plover_package_store_new(); + plover_package_store_add_set(store,package_set); + expected=g_slist_copy(plover_package_set_get_packages(package_set)); + g_slist_foreach(expected,(GFunc)g_object_ref,NULL); + g_object_unref(package_set); + verify_package_store(store,expected); + g_slist_foreach(expected,(GFunc)g_object_unref,NULL); + g_slist_free(expected); + g_object_unref(store); +} + +static void test_remove(void) +{ + PloverPackageSet *yum_set,*nodetails_set; + PloverPackageStore *store; + GSList *expected; + GError *err=NULL; + store=plover_package_store_new(); + yum_set=plover_package_set_new_from_yum("../yum-repo-test-dir",NULL,&err); + if (!yum_set) + g_error("../yum-repo-test-dir: %s",err->message); + plover_package_store_add_set(store,yum_set); + nodetails_set=no_details_new(); + expected=g_slist_copy(plover_package_set_get_packages(nodetails_set)); + g_slist_foreach(expected,(GFunc)g_object_ref,NULL); + plover_package_store_add_set(store,nodetails_set); + plover_package_store_remove_set(store,yum_set); + g_object_unref(nodetails_set); + g_object_unref(yum_set); + verify_package_store(store,expected); + g_slist_foreach(expected,(GFunc)g_object_unref,NULL); + g_slist_free(expected); + g_object_unref(store); +} + +int main(int argc,char **argv) +{ + int retval; + gtk_test_init(&argc,&argv,NULL); + g_test_bug_base("mailto:ali@juiblex.co.uk"); + g_test_add_func("/packagestore/empty",test_empty); + g_test_add_func("/packagestore/basic",test_basic); + g_test_add_func("/packagestore/no-details",test_no_details); + g_test_add_func("/packagestore/remove",test_remove); + retval=g_test_run(); + return retval; +} diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/plover-gtk/test-stockicons.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/plover-gtk/test-stockicons.c Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2016 J. Ali Harlow + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include + +static void test_basic(void) +{ + gchar *cwd; + cwd=g_get_current_dir(); + g_setenv("PLOVER_ICONS_DATADIR",cwd,TRUE); + g_free(cwd); + plover_icons_add_to_stock("mimetypes", + "application-x-redhat-package-manager"); + g_assert(gtk_icon_factory_lookup_default("application-x-redhat-package-manager")); + g_unsetenv("PLOVER_ICONS_DATADIR"); +} + +static void test_no_svg(void) +{ + gchar *cwd; + cwd=g_get_current_dir(); + g_setenv("PLOVER_ICONS_DATADIR",cwd,TRUE); + g_free(cwd); + g_setenv("PLOVER_IGNORE_SVG_SUPPORT","yes",TRUE); + plover_icons_add_to_stock("mimetypes", + "application-x-redhat-package-manager"); + g_assert(gtk_icon_factory_lookup_default("application-x-redhat-package-manager")); + g_unsetenv("PLOVER_IGNORE_SVG_SUPPORT"); + g_unsetenv("PLOVER_ICONS_DATADIR"); +} + +static void test_none_existant(void) +{ + plover_icons_add_to_stock("mimetypes", + "application-x-plover-test-stockicons"); +} + +int main(int argc,char **argv) +{ + int retval; + gtk_test_init(&argc,&argv,NULL); + g_test_bug_base("mailto:ali@juiblex.co.uk"); + g_test_add_func("/stockicons/basic",test_basic); + g_test_add_func("/stockicons/no-svg",test_no_svg); + g_test_add_func("/stockicons/non-existant",test_none_existant); + retval=g_test_run(); + return retval; +} diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/plover-gtk/test-transactionhelper.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/plover-gtk/test-transactionhelper.c Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,725 @@ +/* + * Copyright (C) 2016 J. Ali Harlow + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GtkBuilder *ui; +gboolean manual_mode=FALSE; + +PloverTransactionHelper *get_transaction_helper(void) +{ + const char *dir; + gchar *s; + GError *err=NULL; + PloverTransactionHelper *helper; + dir=g_getenv("gtk_srcdir"); + s=g_build_filename(dir,"software-installation.ui",NULL); + ui=gtk_builder_new(); + if (!gtk_builder_add_from_file(ui,s,&err)) + g_error("%s: %s",s,err->message); + g_free(s); + helper=plover_transaction_helper_new(ui); + g_object_unref(ui); + return helper; +} + +static void test_init(void) +{ + PloverTransactionHelper *helper; + helper=get_transaction_helper(); + g_object_unref(helper); +} + +static void test_basic_properties(void) +{ + const char *prefix; + GError *err=NULL; + struct comps *comps; + PloverTransactionHelper *helper; + PloverPackageSet *installed; + PloverRepository *upstream; + upstream=plover_repository_new_from_yum("../yum-repo-test-dir",&err); + if (!upstream) + g_error("../yum-repo-test-dir: %s",err->message); + installed=plover_package_set_new_from_installed("../razor-test-dir",&err); + if (!installed) + g_error("../razor-test-dir: %s",err->message); + helper=get_transaction_helper(); + g_assert(!plover_transaction_helper_get_visible(helper)); + plover_transaction_helper_set_installed(helper,installed); + g_assert(plover_transaction_helper_get_installed(helper)==installed); + plover_transaction_helper_set_upstream(helper,upstream); + g_assert(plover_transaction_helper_get_upstream(helper,&err)==upstream); + g_assert(!err); + plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); + g_assert_cmpstr(plover_transaction_helper_get_base(helper),==,"../yum-repo-test-dir"); + comps=plover_transaction_helper_get_comps(helper,&err); + g_assert(!err); + g_assert(plover_comps_lookup_group(comps,"base")); + prefix=plover_transaction_helper_get_prefix(helper,&err); + g_assert(!err); + g_assert_cmpstr(prefix,==,plover_default_prefix_for_vendor("Acme Corporation")); + g_assert(!plover_transaction_helper_get_visible(helper)); + g_assert(!plover_transaction_helper_get_error(helper,NULL)); + g_object_unref(upstream); + g_object_unref(installed); + g_object_unref(helper); +} + +static void test_install_group(void) +{ + gchar *root; + GError *err=NULL; + PloverPackageSet *installed; + PloverTransactionHelper *helper; + root=g_strdup("razor-test-dir-XXXXXX"); + g_assert(mkdtemp(root)); + g_setenv("RAZOR_ROOT",root,TRUE); + g_free(root); + helper=get_transaction_helper(); + installed=plover_package_set_new_from_installed("../razor-test-dir",&err); + if (!installed) + g_error("../razor-test-dir: %s",err->message); + plover_transaction_helper_set_installed(helper,installed); + g_object_unref(installed); + plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); + if (!plover_transaction_helper_install_group(helper,"base",&err)) + g_error("base: %s",err->message); + g_assert(!err); + g_object_unref(helper); + g_unsetenv("RAZOR_ROOT"); +} + +static void test_remove_group(void) +{ + gchar *root; + GError *err=NULL; + PloverPackageSet *installed; + PloverTransactionHelper *helper; + struct plover_vector *packages; + char *pkgs[]={"zip",NULL}; + root=g_strdup("razor-test-dir-XXXXXX"); + g_assert(mkdtemp(root)); + g_setenv("RAZOR_ROOT",root,TRUE); + helper=get_transaction_helper(); + plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); + packages=plover_transaction_helper_group_get_default_packages(helper, + "zappy",&err); + if (!packages) + g_error("zappy: %s",err->message); + if (!plover_install("../yum-repo-test-dir",NULL,packages->strings,&err)) + g_error("plover_install: %s",err->message); + plover_vector_free(packages); + installed=plover_package_set_new_from_installed(root,&err); + if (!installed) + g_error("%s: %s",root,err->message); + plover_transaction_helper_set_installed(helper,installed); + g_object_unref(installed); + if (!plover_transaction_helper_remove_group(helper,"zappy",&err)) + g_error("zappy: %s",err->message); + g_assert(!err); + g_object_unref(helper); + g_unsetenv("RAZOR_ROOT"); + g_free(root); +} + +static void test_update(void) +{ + gchar *root; + GError *err=NULL; + PloverPackageSet *installed; + PloverTransactionHelper *helper; + root=g_strdup("razor-test-dir-XXXXXX"); + g_assert(mkdtemp(root)); + g_setenv("RAZOR_ROOT",root,TRUE); + g_free(root); + helper=get_transaction_helper(); + installed=plover_package_set_new_from_installed("../razor-test-dir",&err); + if (!installed) + g_error("../razor-test-dir: %s",err->message); + plover_transaction_helper_set_installed(helper,installed); + g_object_unref(installed); + plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); + if (plover_transaction_helper_update(helper,&err)) + g_error("plover_transaction_helper_update reports work to be done"); + g_assert_error(err,PLOVER_GENERAL_ERROR,PLOVER_GENERAL_ERROR_NO_WORK); + g_object_unref(helper); + g_unsetenv("RAZOR_ROOT"); +} + +struct run_install_baton { + enum { + RI_STATE_INIT = 0, + RI_STATE_SUMMARY, + RI_STATE_PROGRESS, + RI_STATE_PROGRESS_DELAY, + RI_STATE_DONE, + RI_STATE_FINISH + } state; + guint eid; /* event ID (or 0) */ + PloverTransactionHelper *helper; +}; + +gboolean run_install_tick(gpointer data) +{ + gboolean retval=TRUE; + struct run_install_baton *baton=data; + GtkWidget *page; + GtkAssistant *assistant=baton->helper->assistant; + switch(baton->state) + { + case RI_STATE_INIT: + if (!assistant || !gtk_widget_get_visible(GTK_WIDGET(assistant))) + return TRUE; + if (!manual_mode) + gtk_button_clicked(GTK_BUTTON(assistant->forward)); + break; + case RI_STATE_SUMMARY: + if (gtk_assistant_get_current_page(assistant)<1) + return TRUE; + if (!manual_mode) + gtk_button_clicked(GTK_BUTTON(assistant->apply)); + break; + case RI_STATE_PROGRESS: + if (gtk_assistant_get_current_page(assistant)<2) + return TRUE; + page=gtk_assistant_get_nth_page(assistant,2); + baton->eid=g_timeout_add_seconds(1,run_install_tick,baton); + if (!gtk_assistant_get_page_complete(assistant,page)) + return FALSE; + else + retval=FALSE; + break; + case RI_STATE_PROGRESS_DELAY: + retval=FALSE; + baton->eid=g_idle_add_full(G_PRIORITY_LOW,run_install_tick,baton, + NULL); + if (!manual_mode) + gtk_button_clicked(GTK_BUTTON(assistant->forward)); + break; + case RI_STATE_DONE: + if (gtk_assistant_get_current_page(assistant)<3) + return TRUE; + if (!manual_mode) + gtk_button_clicked(GTK_BUTTON(assistant->close)); + break; + case RI_STATE_FINISH: + if (assistant && gtk_widget_get_visible(GTK_WIDGET(assistant))) + return TRUE; + gtk_main_quit(); + baton->eid=0; + return FALSE; + } + baton->state++; + return retval; +} + +static void test_run_install(void) +{ + gchar *root; + GError *err=NULL; + struct plover_vector *packages; + PloverPackageSet *installed; + PloverTransactionHelper *helper; + struct run_install_baton baton={0,}; + root=g_strdup("razor-test-dir-XXXXXX"); + g_assert(mkdtemp(root)); + g_setenv("RAZOR_ROOT",root,TRUE); + helper=get_transaction_helper(); + installed=plover_package_set_new(); + if (!plover_package_set_open(installed,root,TRUE,&err)) + g_error("%s: %s",root,err->message); + plover_transaction_helper_set_installed(helper,installed); + g_object_unref(installed); + plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); + packages=plover_vector_new(); + plover_vector_append(packages,"zappy-tools"); + if (!plover_transaction_helper_install_packages(helper,packages,&err)) + g_error("zappy-tools: %s",err->message); + g_assert(!err); + plover_vector_free(packages); + plover_transaction_helper_present(helper); + baton.helper=helper; + baton.eid=g_idle_add_full(G_PRIORITY_LOW,run_install_tick,&baton,NULL); + gtk_main(); + g_object_unref(helper); + g_unsetenv("RAZOR_ROOT"); + g_free(root); +} + +struct run_remove_baton { + enum { + RR_STATE_INIT = 0, + RR_STATE_SUMMARY, + RR_STATE_PROGRESS, + RR_STATE_PROGRESS_DELAY, + RR_STATE_DONE, + RR_STATE_FINISH + } state; + guint eid; /* event ID (or 0) */ + PloverTransactionHelper *helper; +}; + +gboolean run_remove_tick(gpointer data) +{ + gboolean retval=TRUE; + struct run_remove_baton *baton=data; + GtkWidget *page; + GtkAssistant *assistant=baton->helper->assistant; + switch(baton->state) + { + case RR_STATE_INIT: + if (!assistant || !gtk_widget_get_visible(GTK_WIDGET(assistant))) + return TRUE; + if (!manual_mode) + gtk_button_clicked(GTK_BUTTON(assistant->forward)); + break; + case RR_STATE_SUMMARY: + if (gtk_assistant_get_current_page(assistant)<1) + return TRUE; + if (!manual_mode) + gtk_button_clicked(GTK_BUTTON(assistant->apply)); + break; + case RR_STATE_PROGRESS: + if (gtk_assistant_get_current_page(assistant)<2) + return TRUE; + page=gtk_assistant_get_nth_page(assistant,2); + baton->eid=g_timeout_add_seconds(1,run_remove_tick,baton); + if (!gtk_assistant_get_page_complete(assistant,page)) + return FALSE; + else + retval=FALSE; + break; + case RR_STATE_PROGRESS_DELAY: + retval=FALSE; + baton->eid=g_idle_add_full(G_PRIORITY_LOW,run_remove_tick,baton, + NULL); + if (!manual_mode) + gtk_button_clicked(GTK_BUTTON(assistant->forward)); + break; + case RR_STATE_DONE: + if (gtk_assistant_get_current_page(assistant)<3) + return TRUE; + if (!manual_mode) + gtk_button_clicked(GTK_BUTTON(assistant->close)); + break; + case RR_STATE_FINISH: + if (assistant && gtk_widget_get_visible(GTK_WIDGET(assistant))) + return TRUE; + gtk_main_quit(); + baton->eid=0; + return FALSE; + } + baton->state++; + return retval; +} + +static void test_run_remove(void) +{ + gchar *root; + GError *err=NULL; + struct plover_vector *packages; + PloverPackageSet *installed; + PloverTransactionHelper *helper; + struct run_remove_baton baton={0,}; + root=g_strdup("razor-test-dir-XXXXXX"); + g_assert(mkdtemp(root)); + g_setenv("RAZOR_ROOT",root,TRUE); + helper=get_transaction_helper(); + plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); + packages= + plover_transaction_helper_group_get_default_packages(helper,"zappy",&err); + if (!packages) + g_error("zappy: %s",err->message); + if (!plover_install("../yum-repo-test-dir",NULL,packages->strings,&err)) + g_error("plover_install: %s",err->message); + plover_vector_free(packages); + installed=plover_package_set_new(); + if (!plover_package_set_open(installed,root,TRUE,&err)) + g_error("%s: %s",root,err->message); + plover_transaction_helper_set_installed(helper,installed); + g_object_unref(installed); + if (!plover_transaction_helper_remove_group(helper,"zappy",&err)) + g_error("zappy: %s",err->message); + g_assert(!err); + plover_transaction_helper_present(helper); + baton.helper=helper; + baton.eid=g_idle_add_full(G_PRIORITY_LOW,run_remove_tick,&baton,NULL); + gtk_main(); + g_object_unref(helper); + g_unsetenv("RAZOR_ROOT"); + g_free(root); +} + +struct run_update_baton { + enum { + RU_STATE_INIT = 0, + RU_STATE_SUMMARY, + RU_STATE_PROGRESS, + RU_STATE_PROGRESS_DELAY, + RU_STATE_DONE, + RU_STATE_FINISH + } state; + guint eid; /* event ID (or 0) */ + PloverTransactionHelper *helper; +}; + +gboolean run_update_tick(gpointer data) +{ + gboolean retval=TRUE; + struct run_update_baton *baton=data; + GtkWidget *page; + GtkAssistant *assistant=baton->helper->assistant; + switch(baton->state) + { + case RU_STATE_INIT: + if (!assistant || !gtk_widget_get_visible(GTK_WIDGET(assistant))) + return TRUE; + if (!manual_mode) + gtk_button_clicked(GTK_BUTTON(assistant->forward)); + break; + case RU_STATE_SUMMARY: + if (gtk_assistant_get_current_page(assistant)<1) + return TRUE; + if (!manual_mode) + gtk_button_clicked(GTK_BUTTON(assistant->apply)); + break; + case RU_STATE_PROGRESS: + if (gtk_assistant_get_current_page(assistant)<2) + return TRUE; + page=gtk_assistant_get_nth_page(assistant,2); + baton->eid=g_timeout_add_seconds(1,run_update_tick,baton); + if (!gtk_assistant_get_page_complete(assistant,page)) + return FALSE; + else + retval=FALSE; + break; + case RU_STATE_PROGRESS_DELAY: + retval=FALSE; + baton->eid=g_idle_add_full(G_PRIORITY_LOW,run_update_tick,baton, + NULL); + if (!manual_mode) + gtk_button_clicked(GTK_BUTTON(assistant->forward)); + break; + case RU_STATE_DONE: + if (gtk_assistant_get_current_page(assistant)<3) + return TRUE; + if (!manual_mode) + gtk_button_clicked(GTK_BUTTON(assistant->close)); + break; + case RU_STATE_FINISH: + if (assistant && gtk_widget_get_visible(GTK_WIDGET(assistant))) + return TRUE; + gtk_main_quit(); + baton->eid=0; + return FALSE; + } + baton->state++; + return retval; +} + +static void test_run_update(void) +{ + gchar *root; + GError *err=NULL; + struct razor_importer *importer; + struct razor_set *downgraded; + struct razor_atomic *atomic; + struct plover_vector *packages; + PloverPackageSet *installed; + PloverTransactionHelper *helper; + struct run_update_baton baton={0,}; + root=g_strdup("razor-test-dir-XXXXXX"); + g_assert(mkdtemp(root)); + g_setenv("RAZOR_ROOT",root,TRUE); + helper=get_transaction_helper(); + plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); + installed=plover_package_set_new(); + if (!plover_package_set_open(installed,root,TRUE,&err)) + g_error("%s: %s",root,err->message); + importer=razor_importer_create(); + razor_importer_begin_package(importer,"zappy","0-1","noarch"); + razor_importer_add_details(importer,"","","",""); + razor_importer_add_property(importer,"zappy",RAZOR_PROPERTY_PROVIDES,"0-1"); + razor_importer_finish_package(importer); + downgraded=razor_importer_finish(importer); + atomic=razor_atomic_open("Add downgraded packages"); + if (!plover_package_set_update(installed,downgraded,atomic) || + razor_atomic_commit(atomic)) + g_error("%s: %s",root,razor_atomic_get_error_msg(atomic)); + razor_atomic_destroy(atomic); + razor_set_unref(downgraded); + plover_transaction_helper_set_installed(helper,installed); + g_object_unref(installed); + if (!plover_transaction_helper_update(helper,&err)) + g_error("update: %s",err->message); + g_assert(!err); + plover_transaction_helper_present(helper); + baton.helper=helper; + baton.eid=g_idle_add_full(G_PRIORITY_LOW,run_update_tick,&baton,NULL); + gtk_main(); + g_object_unref(helper); + g_unsetenv("RAZOR_ROOT"); + g_free(root); +} + +struct check_vendor_baton { + enum { + CV_STATE_INIT = 0, + CV_STATE_SUMMARY, + CV_STATE_PROGRESS, + CV_STATE_PROGRESS_DELAY, + CV_STATE_DONE, + CV_STATE_FINISH + } state; + guint eid; /* event ID (or 0) */ + PloverTransactionHelper *helper; +}; + +gboolean check_vendor_tick(gpointer data) +{ + gboolean retval=TRUE; + struct check_vendor_baton *baton=data; + GtkWidget *page,*w; + GtkAssistant *assistant=baton->helper->assistant; + switch(baton->state) + { + case CV_STATE_INIT: + if (!assistant || !gtk_widget_get_visible(GTK_WIDGET(assistant))) + return TRUE; + if (!manual_mode) + gtk_button_clicked(GTK_BUTTON(assistant->forward)); + break; + case CV_STATE_SUMMARY: + if (gtk_assistant_get_current_page(assistant)<1) + return TRUE; + g_assert(!gtk_widget_is_sensitive(assistant->apply)); + w=GTK_WIDGET(gtk_builder_get_object(ui,"SIRemoveExisting")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),TRUE); + g_assert(gtk_widget_is_sensitive(assistant->apply)); + if (!manual_mode) + gtk_button_clicked(GTK_BUTTON(assistant->apply)); + break; + case CV_STATE_PROGRESS: + if (gtk_assistant_get_current_page(assistant)<2) + return TRUE; + page=gtk_assistant_get_nth_page(assistant,2); + baton->eid=g_timeout_add_seconds(1,check_vendor_tick,baton); + if (!gtk_assistant_get_page_complete(assistant,page)) + return FALSE; + else + retval=FALSE; + break; + case CV_STATE_PROGRESS_DELAY: + retval=FALSE; + baton->eid=g_idle_add_full(G_PRIORITY_LOW,check_vendor_tick,baton, + NULL); + if (!manual_mode) + gtk_button_clicked(GTK_BUTTON(assistant->forward)); + break; + case CV_STATE_DONE: + if (gtk_assistant_get_current_page(assistant)<3) + return TRUE; + if (!manual_mode) + gtk_button_clicked(GTK_BUTTON(assistant->close)); + break; + case CV_STATE_FINISH: + if (assistant && gtk_widget_get_visible(GTK_WIDGET(assistant))) + return TRUE; + gtk_main_quit(); + baton->eid=0; + return FALSE; + } + baton->state++; + return retval; +} + +static void test_check_vendor(void) +{ + int fh; + gchar *root,*s; + GError *err=NULL; + struct razor_importer *importer; + struct razor_set *downgraded; + struct razor_atomic *atomic; + struct plover_vector *packages; + PloverPackageSet *installed; + PloverTransactionHelper *helper; + struct run_update_baton baton={0,}; + g_setenv("PLOVER_VENDOR_PREFIX","/srv",TRUE); + root=g_strdup("razor-test-dir-XXXXXX"); + g_assert(mkdtemp(root)); + g_setenv("RAZOR_ROOT",root,TRUE); + helper=get_transaction_helper(); + plover_transaction_helper_set_check_vendor(helper,TRUE); + plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); + installed=plover_package_set_new(); + if (!plover_package_set_open(installed,root,TRUE,&err)) + g_error("%s: %s",root,err->message); + importer=razor_importer_create(); + razor_importer_begin_package(importer,"zappy","0-1","noarch"); + razor_importer_add_details(importer,"","","",""); + razor_importer_add_property(importer,"zappy",RAZOR_PROPERTY_PROVIDES,"0-1"); + razor_importer_add_install_prefix(importer,"/test"); + razor_importer_add_file(importer,"/test/bin/zappy"); + razor_importer_finish_package(importer); + downgraded=razor_importer_finish(importer); + atomic=razor_atomic_open("Add downgraded packages"); + razor_atomic_make_dirs(atomic,root,"/test/bin/zappy"); + s=g_build_filename(root,"test/bin/zappy",NULL); + fh=razor_atomic_create_file(atomic,s,S_IRWXU|S_IRWXG|S_IRWXO); + g_free(s); + razor_atomic_close(atomic,fh); + if (!plover_package_set_update(installed,downgraded,atomic) || + razor_atomic_commit(atomic)) + g_error("%s: %s",root,razor_atomic_get_error_msg(atomic)); + razor_atomic_destroy(atomic); + razor_set_unref(downgraded); + plover_transaction_helper_set_installed(helper,installed); + g_object_unref(installed); + if (!plover_transaction_helper_update(helper,&err)) + g_error("update: %s",err->message); + g_assert(!err); + plover_transaction_helper_present(helper); + baton.helper=helper; + baton.eid=g_idle_add_full(G_PRIORITY_LOW,check_vendor_tick,&baton,NULL); + gtk_main(); + g_object_unref(helper); + g_unsetenv("RAZOR_ROOT"); + g_free(root); + g_unsetenv("PLOVER_VENDOR_PREFIX"); +} + +struct set_error_baton { + enum { + SE_STATE_INIT = 0, + SE_STATE_FINISH + } state; + PloverTransactionHelper *helper; +}; + +/* + * This handler may be called as either an event (ie., idle or timeout) + * or as a (swapped) signal. In the latter case, the return is ignored. + */ +gboolean set_error_tick(gpointer data) +{ + struct set_error_baton *baton=data; + GtkDialog *dlg; + GtkWidget *button; + dlg=GTK_DIALOG(baton->helper->error_dialog); + switch(baton->state) + { + case SE_STATE_INIT: + if (!dlg || !gtk_widget_get_visible(GTK_WIDGET(dlg))) + return TRUE; + button=gtk_dialog_get_widget_for_response(dlg,GTK_RESPONSE_CLOSE); + if (!manual_mode) + gtk_button_clicked(GTK_BUTTON(button)); + break; + case SE_STATE_FINISH: + if (dlg && gtk_widget_get_visible(GTK_WIDGET(dlg))) + return TRUE; + gtk_main_quit(); + return FALSE; + } + baton->state++; + return TRUE; +} + +static void test_set_error(void) +{ + gchar *root; + const char *errmsg; + GError *err=NULL; + const GError *err2=NULL; + PloverPackageSet *installed; + PloverTransactionHelper *helper; + struct set_error_baton baton={0,}; + root=g_strdup("razor-test-dir-XXXXXX"); + g_assert(mkdtemp(root)); + g_setenv("RAZOR_ROOT",root,TRUE); + g_free(root); + helper=get_transaction_helper(); + installed=plover_package_set_new_from_installed("../razor-test-dir",&err); + if (!installed) + g_error("../razor-test-dir: %s",err->message); + plover_transaction_helper_set_installed(helper,installed); + g_object_unref(installed); + plover_transaction_helper_set_base(helper,"../yum-repo-test-dir"); + if (!plover_transaction_helper_update(helper,&err)) + plover_transaction_helper_set_error(helper,err,"Expected error"); + g_assert(plover_transaction_helper_get_visible(helper)); + errmsg=plover_transaction_helper_get_error(helper,&err2); + g_assert_cmpstr(errmsg,==,"Expected error"); + g_assert_error(err2,err->domain,err->code); + plover_transaction_helper_present(helper); + baton.helper=helper; + g_idle_add_full(G_PRIORITY_LOW,set_error_tick,&baton,NULL); + g_error_free(err); + gtk_main(); + g_object_unref(helper); + g_unsetenv("RAZOR_ROOT"); +} + +int main(int argc,char **argv) +{ + int retval; + GError *err=NULL; + /* + * Note that because g_test_init() handles --help, + * these options will not appear in the output. + */ + GOptionEntry options[]={ + {"manual",0,0,G_OPTION_ARG_NONE,&manual_mode, + "Disable automatic mode",NULL}, + {NULL} + }; + g_test_init(&argc,&argv,NULL); + g_setenv("GTK_MODULES","",TRUE); + g_setenv("GTK2_RC_FILES","/dev/null",TRUE); + gtk_disable_setlocale(); + setlocale(LC_ALL,"C"); + g_test_bug_base("mailto:ali@juiblex.co.uk"); + if (!gtk_init_with_args(&argc,&argv,NULL,options,NULL,&err)) + { + g_printf("%s\n",err->message); + exit(0); + } + g_test_add_func("/transactionhelper/init",test_init); + g_test_add_func("/transactionhelper/basic-properties", + test_basic_properties); + g_test_add_func("/transactionhelper/install-group",test_install_group); + g_test_add_func("/transactionhelper/remove-group",test_remove_group); + g_test_add_func("/transactionhelper/update",test_update); + g_test_add_func("/transactionhelper/run-install",test_run_install); + g_test_add_func("/transactionhelper/run-remove",test_run_remove); + g_test_add_func("/transactionhelper/run-update",test_run_update); + g_test_add_func("/transactionhelper/check-vendor",test_check_vendor); + g_test_add_func("/transactionhelper/set-error",test_set_error); + retval=g_test_run(); + return retval; +} diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/plover-gtk/treemodel.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/plover-gtk/treemodel.c Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2011, 2016 J. Ali Harlow + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include + +static void test_tree_model_iter(GtkTreeModel *model,GtkTreeIter *iter) +{ + GtkTreePath *path,*path2; + GtkTreeIter iter2,child; + gchar *string,*string2,*s; + int i,n; + if (iter) /* Not all tests make sense on the virtual root */ + { + /* Check we can convert to a path and back */ + path=gtk_tree_model_get_path(model,iter); + g_assert(path!=NULL); + g_assert(gtk_tree_model_get_iter(model,&iter2,path)); + path2=gtk_tree_model_get_path(model,&iter2); + g_assert(path2!=NULL); + g_assert(gtk_tree_path_compare(path,path2)==0); + gtk_tree_path_free(path2); + /* Check we can convert to a path string and back */ + string=gtk_tree_model_get_string_from_iter(model,iter); + g_assert(string!=NULL); + g_assert(gtk_tree_model_get_iter_from_string(model,&iter2,string)); + string2=gtk_tree_model_get_string_from_iter(model,&iter2); + g_assert(string2!=NULL); + g_assert(strcmp(string,string2)==0); + g_free(string2); + } + else + { + path=NULL; + string=NULL; + } + if (string) + g_debug("Checking iter %s",string); + else + g_debug("Checking virtual root iter"); + n=gtk_tree_model_iter_n_children(model,iter); + g_assert(n>=0); + if (n>0) + { + /* Check that GTK_TREE_MODEL_LIST_ONLY is not set inappropriately */ + if (iter) + { + gboolean list_only_with_grandchildren; + list_only_with_grandchildren= + gtk_tree_model_get_flags(model)>K_TREE_MODEL_LIST_ONLY; + g_assert(!list_only_with_grandchildren); + } + /* Check that gtk_tree_model_iter_has_child() agrees */ + if (iter) + g_assert(gtk_tree_model_iter_has_child(model,iter)); + /* Check that gtk_tree_model_iter_children() returns the first child */ + g_assert(gtk_tree_model_iter_children(model,&child,iter)); + string2=gtk_tree_model_get_string_from_iter(model,&child); + g_assert(string2!=NULL); + if (string) + { + g_assert(g_str_has_prefix(string2,string)); + g_assert(strlen(string2)==strlen(string)+2); + g_assert(g_str_has_suffix(string2,":0")); + } + else + g_assert(strcmp(string2,"0")==0); + g_free(string2); + for(i=0;i + +void test_tree_model(GtkTreeModel *model); diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/plover/Makefile.am --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/plover/Makefile.am Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,25 @@ +AM_CFLAGS=-g $(LIBPLOVER_CFLAGS) +INCLUDES=-I$(top_srcdir) +LDADD=../../plover/libplover.la $(LIBPLOVER_LIBS) + +if HAVE_CHECK_TOOLS + +TESTS = $(test_programs) +TESTS_ENVIRONMENT = tests_srcdir="$(top_srcdir)/tests" + +check_PROGRAMS = $(test_programs) + +test_programs = test-import-yum test-package test-repository test-packageset \ + test-transaction test-comps test-log test-util test-razor test-vector \ + test-exception-handler + +test_transaction_LDADD = $(LDADD) $(LUA_POSIX_LIBS) +test_razor_LDADD = $(LDADD) $(LUA_POSIX_LIBS) + +endif + +@VALGRIND_CHECK_RULES@ +VALGRIND_SUPPRESSIONS_FILES = ../glib.supp + +clean-local: + rm -rf test-log-rotate razor-test-dir-* diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/plover/test-comps.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/plover/test-comps.c Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2016 J. Ali Harlow + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include + +static void test_basic(void) +{ + struct comps *comps; + comps=plover_comps_new(); + g_assert(comps); + plover_comps_free(comps); +} + +static void test_from_file(void) +{ + struct comps *comps; + struct comps_group *group; + gchar *s; + s=g_build_filename(g_getenv("tests_srcdir"),"comps.xml",NULL); + comps=plover_comps_new_from_file(s); + if (!comps) + g_error("%s: Failed to read components",s); + g_free(s); + group=plover_comps_lookup_group(comps,"base"); + g_assert(group); + g_assert(!plover_comps_lookup_group(comps,"nonexistant")); + plover_comps_free(comps); +} + +int main(int argc,char **argv) +{ + int retval; + g_test_init(&argc,&argv,NULL); + g_test_bug_base("mailto:ali@juiblex.co.uk"); + g_test_add_func("/comps/basic",test_basic); + g_test_add_func("/comps/from-file",test_from_file); + retval=g_test_run(); + return retval; +} diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/plover/test-exception-handler.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/plover/test-exception-handler.c Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2016 J. Ali Harlow + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include + +static void test_init(void) +{ + plover_exception_handler_init(); +} + +int main(int argc,char **argv) +{ + int retval; + g_test_init(&argc,&argv,NULL); + g_test_bug_base("mailto:ali@juiblex.co.uk"); + g_test_add_func("/exception-handler/init",test_init); + retval=g_test_run(); + return retval; +} diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/plover/test-import-yum.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/plover/test-import-yum.c Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2016 J. Ali Harlow + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include + +const char *yum_packages[]={ + "zsh","zsh2","zip","zap","filesystem","zappy","zappy-tools","zappy2", + "unsatisfiable","uninstallable","badpostun" +}; + +static void test_basic_import(void) +{ + int i; + struct razor_set *set; + struct razor_package_iterator *iter; + struct razor_package *package; + const char *name; + GList *expected=NULL,*lnk; + GError *err=NULL; + set=plover_razor_set_create_from_yum("../yum-repo-test-dir",&err); + if (!set && err) + g_error("../yum-repo-test-dir: %s",err->message); + g_assert(set != NULL); + g_assert(err == NULL); + for(i=0;idata); + razor_set_unref(set); +} + +int main(int argc,char **argv) +{ + g_test_init(&argc,&argv,NULL); + g_test_bug_base("mailto:ali@juiblex.co.uk"); + g_test_add_func("/import-yum/basic",test_basic_import); + return g_test_run(); +} diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/plover/test-log.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/plover/test-log.c Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2016 J. Ali Harlow + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include + +static gchar *log_file_path(const char *directory,const char *name, + const char *stamp) +{ + gchar *s,*path; + if (name) + s=g_strdup(name); + else + s=g_strconcat("test-",stamp,NULL); + if (directory) + path=g_build_filename(directory,s,NULL); + else + path=g_strdup(s); + g_free(s); + return path; +} + +static GDateTime *date_days_ago(int age) +{ + GDateTime *now,*then; + now=g_date_time_new_now_utc(); + then=g_date_time_add_days(now,-age); + g_date_time_unref(now); + return then; +} + +static gchar *date_stamp(int age) +{ + gchar *stamp; + GDateTime *then; + then=date_days_ago(age); + stamp=g_date_time_format(then,"%Y%m%d"); + g_date_time_unref(then); + return stamp; +} + +static void simulate_log_file(const char *directory,const char *name,int age) +{ + gchar *path,*contents,*stamp; + GDateTime *then; + GError *err=NULL; + struct timeval times[2]={{0,},{0,}}; + stamp=date_stamp(age); + path=log_file_path(directory,name,stamp); + contents=g_strdup_printf("Log for %s\n",stamp); + if (!g_file_set_contents(path,contents,-1,&err)) + g_error("%s: %s",path,err->message); + g_free(contents); + then=date_days_ago(age); + times[0].tv_sec=times[1].tv_sec=g_date_time_to_unix(then); + utimes(path,times); + g_date_time_unref(then); + g_free(path); + g_free(stamp); +} + +static void verify_log_file(const char *directory,const char *name,int age, + gboolean should_exist) +{ + gchar *path,*contents,*stamp,*s; + GError *err=NULL; + stamp=date_stamp(age); + path=log_file_path(directory,name,stamp); + if (!should_exist) + g_assert(!g_file_test(path,G_FILE_TEST_EXISTS)); + else + { + if (!g_file_get_contents(path,&contents,NULL,&err)) + g_error("%s: %s",path,err->message); + s=g_strdup_printf("Log for %s\n",stamp); + g_assert_cmpstr(contents,==,s); + g_free(s); + g_free(contents); + } + g_free(path); + g_free(stamp); +} + +static int safe_log_open(const char *s) +{ + int fd1,fd2,result; + fflush(stdout); + fflush(stderr); + fd1=dup(1); + fd2=dup(2); + result=plover_log_open(s); + fflush(stdout); + fflush(stderr); + dup2(fd1,1); + dup2(fd2,2); + close(fd1); + close(fd2); + return result; +} + +static void verify_log_open(const char *directory) +{ + int result; + gchar *stamp,*s; + simulate_log_file(directory,"test",1); + simulate_log_file(directory,NULL,1); + simulate_log_file(directory,NULL,2); + simulate_log_file(directory,NULL,3); + simulate_log_file(directory,NULL,4); + if (directory) + s=g_build_filename(directory,"test",NULL); + else + s=g_strdup("test"); + result=safe_log_open(s); + g_free(s); + g_assert_cmpint(result,==,0); + stamp=date_stamp(1); + s=g_strconcat("test-",stamp,"a",NULL); + g_free(stamp); + verify_log_file(directory,s,1,TRUE); + g_free(s); + verify_log_file(directory,NULL,1,TRUE); + verify_log_file(directory,NULL,2,TRUE); + verify_log_file(directory,NULL,3,TRUE); + verify_log_file(directory,NULL,4,FALSE); +} + +static void test_rotate(void) +{ + system("rm -rf test-log-rotate"); + g_assert(mkdir("test-log-rotate",0777)==0); + verify_log_open("test-log-rotate"); +} + +static void test_rotate_cwd(void) +{ + system("rm -rf test-log-rotate"); + g_assert(mkdir("test-log-rotate",0777)==0); + g_assert(chdir("test-log-rotate")==0); + verify_log_open(NULL); + g_assert(chdir("..")==0); +} + +static void test_rotate_root(void) +{ + gchar *cwd,*s; + system("rm -rf test-log-rotate"); + g_assert(mkdir("test-log-rotate",0777)==0); + cwd=g_get_current_dir(); + s=g_strconcat(cwd,"/",NULL); + g_free(cwd); + g_setenv("RAZOR_ROOT",s,TRUE); + g_free(s); + verify_log_open("test-log-rotate"); + g_unsetenv("RAZOR_ROOT"); +} + +static void test_readonly_dir(void) +{ + system("rm -rf test-log-rotate"); + g_assert(mkdir("test-log-rotate",0)==0); + g_assert(safe_log_open("test-log-rotate/test")!=0); +} + +static void test_directory(void) +{ + system("rm -rf test-log-rotate"); + g_assert(mkdir("test-log-rotate",0777)==0); + g_assert(mkdir("test-log-rotate/test",0777)==0); + g_assert(safe_log_open("test-log-rotate/test")!=0); +} + +static void test_readonly_file(void) +{ + GError *err=NULL; + system("rm -rf test-log-rotate"); + g_assert(mkdir("test-log-rotate",0777)==0); + if (!g_file_set_contents("test-log-rotate/test","",0,&err)) + g_error("test-log-rotate/test: %s",err->message); + g_assert(chmod("test-log-rotate/test",0)==0); + g_assert(safe_log_open("test-log-rotate/test")!=0); +} + +int main(int argc,char **argv) +{ + int retval; + g_test_init(&argc,&argv,NULL); + g_test_bug_base("mailto:ali@juiblex.co.uk"); + g_test_add_func("/log/rotate",test_rotate); + g_test_add_func("/log/rotate-cwd",test_rotate_cwd); + g_test_add_func("/log/rotate-root",test_rotate_root); + g_test_add_func("/log/readonly-dir",test_readonly_dir); + g_test_add_func("/log/directory",test_directory); + g_test_add_func("/log/readonly-file",test_readonly_file); + retval=g_test_run(); + return retval; +} diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/plover/test-package.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/plover/test-package.c Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,324 @@ +/* + * Copyright (C) 2016 J. Ali Harlow + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include + +struct razor_set *test_set=NULL; +struct razor_package *test_pkg=NULL; + +static void finalize(void) +{ + if (test_set) + razor_set_unref(test_set); +} + +void import_properties(struct razor_importer *importer, + struct razor_set *set,struct razor_package *pkg) +{ + struct razor_property_iterator *iter; + struct razor_property *prop; + uint32_t flags; + const char *name,*version; + iter=razor_property_iterator_create(set,pkg); + while(razor_property_iterator_next(iter,&prop,&name,&flags,&version)) + razor_importer_add_property(importer,name,flags,version); + razor_property_iterator_destroy(iter); +} + +void import_files(struct razor_importer *importer, + struct razor_set *set,struct razor_package *pkg) +{ + struct razor_file_iterator *iter; + const char *name; + iter=razor_file_iterator_create(set,pkg,FALSE); + while(razor_file_iterator_next(iter,&name)) + razor_importer_add_file(importer,name); + razor_file_iterator_destroy(iter); +} + +gboolean import_rpm(struct razor_rpm *rpm) +{ + int i; + struct razor_importer *importer; + struct razor_package_iterator *iter; + struct razor_set *set; + struct razor_package *pkg=NULL; + const char *name,*version,*arch,*summary,*description,*url,*license; + const char *s,*pkg_name; + const char *const *prefixes; + /* + * First pass: get a razor_set and razor_package with everything + * except the prefixes. + */ + importer=razor_importer_create(); + if (razor_importer_add_rpm(importer,rpm)) + g_error("../yum-repo-test-dir: Failed to add rpm"); + set=razor_importer_finish(importer); + if (!set) + g_error("../yum-repo-test-dir: Failed to import"); + iter=razor_package_iterator_create(set); + pkg=NULL; + razor_rpm_get_details(rpm,RAZOR_DETAIL_NAME,&pkg_name,RAZOR_DETAIL_LAST); + while(razor_package_iterator_next(iter,&pkg,RAZOR_DETAIL_NAME,&s, + RAZOR_DETAIL_LAST)) + if (!strcmp(s,pkg_name)) + break; + razor_package_iterator_destroy(iter); + if (!pkg) + { + razor_set_unref(set); + return FALSE; + } + /* + * Second pass: use the information from the first pass plus the + * prefixes to create a final razor_set and razor_package. + */ + importer=razor_importer_create(); + razor_package_get_details(set,pkg,RAZOR_DETAIL_NAME,&name, + RAZOR_DETAIL_VERSION,&version,RAZOR_DETAIL_ARCH,&arch, + RAZOR_DETAIL_SUMMARY,&summary,RAZOR_DETAIL_DESCRIPTION,&description, + RAZOR_DETAIL_URL,&url,RAZOR_DETAIL_LICENSE,&license,RAZOR_DETAIL_LAST); + razor_importer_begin_package(importer,name,version,arch); + razor_importer_add_details(importer,summary,description,url,license); + import_properties(importer,set,pkg); + import_files(importer,set,pkg); + razor_rpm_get_details(rpm,RAZOR_DETAIL_PREFIXES,&prefixes, + RAZOR_DETAIL_LAST); + for(i=0;prefixes && prefixes[i];i++) + razor_importer_add_install_prefix(importer,prefixes[i]); + razor_importer_finish_package(importer); + razor_set_unref(set); + test_set=razor_importer_finish(importer); + g_assert(test_set != NULL); + iter=razor_package_iterator_create(test_set); + test_pkg=NULL; + while(razor_package_iterator_next(iter,&test_pkg,RAZOR_DETAIL_NAME,&s, + RAZOR_DETAIL_LAST)) + if (!strcmp(s,pkg_name)) + break; + razor_package_iterator_destroy(iter); + return !!test_pkg; +} + +static PloverPackage *package_getref(const char *name,const char *version) +{ + struct razor_rpm *rpm; + PloverPackage *package=NULL; + struct razor_error *err=NULL; + gchar *filename; + if (test_set) + { + razor_set_unref(test_set); + test_set=NULL; + } + /* + * yum metadata doesn't include all the information included in + * a rpm file, so do this the hard way. Unfortunately, + * razor_importer_add_rpm() doesn't support prefixes so we have + * to do it the really hard way. + */ + filename=g_strconcat("../yum-repo-test-dir/rpms/",name,"-",version, + ".noarch.rpm",NULL); + rpm=razor_rpm_open(filename,&err); + if (!rpm) + g_error("%s: %s",filename,razor_error_get_msg(err)); + g_free(filename); + if (import_rpm(rpm)) + package=plover_package_new(test_set,test_pkg); + else + package=NULL; + razor_rpm_close(rpm); + return package; +} + +static void test_basic_properties(void) +{ + PloverPackage *package; + package=package_getref("zsh","1-1"); + g_assert(package != NULL); + g_assert(plover_package_get_razor_set(package) == test_set); + g_assert(plover_package_get_razor_package(package) == test_pkg); + g_assert_cmpstr(plover_package_get_name(package),==,"zsh"); + g_assert_cmpstr(plover_package_get_summary(package),==,"Test package"); + g_assert_cmpstr(plover_package_get_version(package),==,"1-1"); + g_assert_cmpstr(plover_package_get_license(package),==,"GPL"); + g_assert_cmpstr(plover_package_get_arch(package),==,"noarch"); + g_assert_cmpstr(plover_package_get_description(package),==,"Test package"); + g_assert_cmpstr(plover_package_get_URL(package),==, + "http://www.juiblex.co.uk/beach"); + g_object_unref(package); +} + +static void test_package_properties(void) +{ + PloverPackage *package; + struct razor_property_iterator *iter; + struct razor_property *prop; + uint32_t flags; + const char *s,*name,*version; + GString *str; + GList *expected,*lnk; + package=package_getref("zsh","1-1"); + g_assert(package != NULL); + expected=g_list_prepend(NULL, + (gpointer)g_intern_string("requires(pre,postun): zip")); + expected=g_list_prepend(expected, + (gpointer)g_intern_string("requires: zip")); + expected=g_list_prepend(expected, + (gpointer)g_intern_string("provides: zsh = 1-1")); + iter=plover_package_property_iterator_create(package); + g_assert(iter != NULL); + while(razor_property_iterator_next(iter,&prop,&name,&flags,&version)) + { + if (g_str_has_prefix(name,"rpmlib(")) + continue; + s=razor_property_type_to_string(prop); + g_assert(s != NULL); + str=g_string_new(s); + if (flags&RAZOR_PROPERTY_SCRIPT_MASK) + { + g_string_append_c(str,'('); + if (flags&RAZOR_PROPERTY_PRE) + g_string_append(str,"pre"); + if (flags&RAZOR_PROPERTY_POST) + { + if (str->str[str->len-1]!='(' && str->str[str->len-1]!=',') + g_string_append_c(str,','); + g_string_append(str,"post"); + } + if (flags&RAZOR_PROPERTY_PREUN) + { + if (str->str[str->len-1]!='(' && str->str[str->len-1]!=',') + g_string_append_c(str,','); + g_string_append(str,"preun"); + } + if (flags&RAZOR_PROPERTY_POSTUN) + { + if (str->str[str->len-1]!='(' && str->str[str->len-1]!=',') + g_string_append_c(str,','); + g_string_append(str,"postun"); + } + g_string_append_c(str,')'); + } + g_string_append(str,": "); + g_string_append(str,name); + if (*version) + { + g_string_append_c(str,' '); + g_string_append(str,razor_property_relation_to_string(prop)); + g_string_append_c(str,' '); + g_string_append(str,version); + } + lnk=g_list_find(expected,g_intern_string(str->str)); + if (!lnk) + g_warning("Unexpected property in zsh package: %s",str->str); + else + expected=g_list_delete_link(expected,lnk); + g_string_free(str,TRUE); + } + razor_property_iterator_destroy(iter); + if (expected) + g_warning("%d missing propert%s in set, including %s", + g_list_length(expected),g_list_length(expected)==1?"y":"ies", + expected->data); + g_object_unref(package); +} + +static void test_package_files(void) +{ + PloverPackage *package; + struct razor_file_iterator *iter; + const char *name; + GList *expected,*lnk; + package=package_getref("zsh","1-1"); + g_assert(package != NULL); + expected=g_list_prepend(NULL,(gpointer)g_intern_string("/etc/zsh.conf")); + expected=g_list_prepend(expected,(gpointer)g_intern_string("/usr/bin/zsh")); + iter=plover_package_file_iterator_create(package,FALSE); + g_assert(iter != NULL); + while(razor_file_iterator_next(iter,&name)) + { + lnk=g_list_find(expected,g_intern_string(name)); + if (!lnk) + g_warning("Unexpected file in zsh package: %s",name); + else + expected=g_list_delete_link(expected,lnk); + } + razor_file_iterator_destroy(iter); + if (expected) + g_warning("%d missing file%s in set, including %s", + g_list_length(expected),g_list_length(expected)==1?"":"s", + expected->data); + g_object_unref(package); +} + +static void test_package_icon(void) +{ + /* + * icons aren't supported yet. + */ + PloverPackage *package; + GInputStream *stream; + GError *err=NULL; + package=package_getref("zsh","1-1"); + g_assert(package != NULL); + stream=plover_package_read_icon(package,&err); + if (stream) + { + /* Unexpected, but hardly an error */ + g_object_unref(stream); + } + else + { + g_assert(err != NULL); + g_assert(err->message != NULL); + g_error_free(err); + } + g_object_unref(package); +} + +static void test_package_prefixes(void) +{ + PloverPackage *package; + const char *const *prefixes; + package=package_getref("zsh","1-1"); + g_assert(package != NULL); + prefixes=plover_package_get_prefixes(package); + g_assert_cmpstr(prefixes[0], ==, "/usr"); + g_assert(prefixes[1] == NULL); + g_object_unref(package); +} + +int main(int argc,char **argv) +{ + int retval; + g_test_init(&argc,&argv,NULL); + g_test_bug_base("mailto:ali@juiblex.co.uk"); + g_test_add_func("/package/basic",test_basic_properties); + g_test_add_func("/package/icons",test_package_icon); + g_test_add_func("/package/properties",test_package_properties); + g_test_add_func("/package/files",test_package_files); + g_test_add_func("/package/prefixes",test_package_prefixes); + g_test_message("PloverPackage::changed signal unused and thus untestable"); + retval=g_test_run(); + finalize(); + return retval; +} diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/plover/test-packageset.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/plover/test-packageset.c Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,369 @@ +/* + * Copyright (C) 2016 J. Ali Harlow + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include + +const char *yum_packages[]={ + "zsh","zsh2","zip","zap","filesystem","zappy","zappy-tools","zappy2", + "unsatisfiable","uninstallable","badpostun" +}; + +const char *zappy_packages[]={ + "zap","zappy","zappy-tools","zappy2" +}; + +static struct razor_set *get_dummy_set(void) +{ + struct razor_importer *importer; + importer=razor_importer_create(); + g_assert(importer != NULL); + razor_importer_begin_package(importer,"dummy","1-1","noarch"); + razor_importer_add_details(importer,"Dummy package", + "A dummy package for testing","http://www.juiblex.co.uk/beach","GPL"); + razor_importer_add_property(importer,"dummy", + RAZOR_PROPERTY_PROVIDES|RAZOR_PROPERTY_EQUAL,"1-1"); + razor_importer_finish_package(importer); + return razor_importer_finish(importer); +} + +static int verify_empty_set_compar(gconstpointer a,gconstpointer b) +{ + return 0; +} + +static void verify_empty_set(PloverPackageSet *package_set) +{ + struct razor_set *set; + struct razor_package *pkg; + struct razor_package_iterator *iter; + PloverPackage *package; + GError *err=NULL; + const char *prefix; + gchar *default_prefix; + g_assert(!plover_package_set_get_packages(package_set)); + set=get_dummy_set(); + g_assert(set != NULL); + iter=razor_package_iterator_create(set); + g_assert(iter != NULL); + g_assert(razor_package_iterator_next(iter,&pkg,RAZOR_DETAIL_LAST)); + g_assert(!plover_package_set_lookup(package_set,pkg)); + razor_package_iterator_destroy(iter); + g_assert(!plover_package_set_find_custom(package_set,NULL, + verify_empty_set_compar)); + package=plover_package_new(set,pkg); + g_assert(package != NULL); + g_assert(!plover_package_set_find_matching(package_set,package)); + g_object_unref(package); + razor_set_unref(set); + g_assert(!plover_package_set_get_no_details(package_set)); + prefix=plover_package_set_guess_prefix(package_set,&err); + if (!prefix && err) + g_error("plover_package_set_guess_prefix: %s",err->message); + g_assert(err == NULL); + default_prefix=plover_default_prefix_for_vendor("Acme Corporation"); + g_assert_cmpstr(prefix,==,default_prefix); + g_free(default_prefix); +} + +static void test_unopened(void) +{ + PloverPackageSet *package_set; + package_set=plover_package_set_new(); + g_assert(PLOVER_IS_PACKAGE_SET(package_set)); + g_assert(!plover_package_set_get_header_version(package_set)); + g_assert(!plover_package_set_set_header_version(package_set,1)); + g_assert(!plover_package_set_get_install_root(package_set)); + g_assert(!plover_package_set_get_exclusive(package_set)); + g_assert(!plover_package_set_get_razor(package_set)); + verify_empty_set(package_set); + plover_package_set_close(package_set); + g_object_unref(package_set); +} + +static int package_name_compar(gconstpointer a,gconstpointer b) +{ + PloverPackage *package=PLOVER_PACKAGE(a); + const char *name=b; + return strcmp(plover_package_get_name(package),name); +} + +static void verify_package_set(PloverPackageSet *package_set,int n_packages, + const char **package_names,const char *prefix) +{ + int i,ver; + struct razor_importer *importer; + struct razor_set *set; + struct razor_package *pkg; + struct razor_package_iterator *iter; + PloverPackage *package,*package0; + GError *err=NULL; + const char *guessed_prefix; + GSList *packages,*lnk2; + GList *expected=NULL,*lnk; + ver=plover_package_set_get_header_version(package_set); + g_assert_cmpint(ver,==,RAZOR_HEADER_VERSION); + g_assert(plover_package_set_set_header_version(package_set, + RAZOR_HEADER_VERSION_MIN)); + g_assert(plover_package_set_set_header_version(package_set,ver)); + g_assert(!plover_package_set_get_exclusive(package_set)); + set=plover_package_set_get_razor(package_set); + g_assert(set != NULL); + for(i=0;inext) + { + package=PLOVER_PACKAGE(lnk2->data); + if (!strcmp(plover_package_get_name(package),package_names[0])) + package0=package; + lnk=g_list_find(expected, + g_intern_string(plover_package_get_name(package))); + if (!lnk) + g_warning("Unexpected package in set: %s", + plover_package_get_name(package)); + else + expected=g_list_delete_link(expected,lnk); + } + if (expected) + g_warning("%d missing package%s in set, including %s", + g_list_length(expected),g_list_length(expected)==1?"":"s", + expected->data); + pkg=plover_package_get_razor_package(package0); + g_assert(plover_package_set_lookup(package_set,pkg)==package0); + g_assert(plover_package_set_find_custom(package_set,package_names[0], + package_name_compar)==package0); + g_assert(plover_package_set_find_matching(package_set,package0)==package0); + g_assert(!plover_package_set_get_no_details(package_set)); + guessed_prefix=plover_package_set_guess_prefix(package_set,&err); + if (!guessed_prefix && err) + g_error("plover_package_set_guess_prefix: %s",err->message); + g_assert(err == NULL); + g_assert_cmpstr(guessed_prefix,==,prefix); +} + +static void verify_zappy_set(PloverPackageSet *package_set) +{ + verify_package_set(package_set,G_N_ELEMENTS(zappy_packages),zappy_packages, + NULL); + g_assert_cmpstr(plover_package_set_get_install_root(package_set),==, + "../razor-test-dir"); +} + +static void test_open(void) +{ + PloverPackageSet *package_set; + GError *err=NULL; + package_set=plover_package_set_new(); + g_assert(PLOVER_IS_PACKAGE_SET(package_set)); + if (!plover_package_set_open(package_set,"../razor-test-dir",FALSE,&err)) + { + g_assert(err && err->message); + g_error("../razor-test-dir: %s",err->message); + } + g_assert(!err); + verify_zappy_set(package_set); + plover_package_set_close(package_set); + g_object_unref(package_set); +} + +static void test_update(void) +{ + int ver; + struct razor_importer *importer; + struct razor_set *set,*dummy_set; + struct razor_package *pkg; + struct razor_package_iterator *iter; + struct razor_atomic *atomic; + PloverPackageSet *package_set; + PloverPackage *package; + GError *err=NULL; + const char *prefix; + gchar *root; + GSList *packages; + package_set=plover_package_set_new(); + g_assert(PLOVER_IS_PACKAGE_SET(package_set)); + root=g_strdup("razor-test-dir-XXXXXX"); + g_assert(mkdtemp(root)); + if (!plover_package_set_open(package_set,root,TRUE,&err)) + { + g_assert(err && err->message); + g_error("%s: %s",root,err->message); + } + g_assert(!err); + ver=plover_package_set_get_header_version(package_set); + g_assert_cmpint(ver,==,RAZOR_HEADER_VERSION); + g_assert(plover_package_set_set_header_version(package_set, + RAZOR_HEADER_VERSION_MIN)); + g_assert(plover_package_set_set_header_version(package_set,ver)); + g_assert_cmpstr(plover_package_set_get_install_root(package_set),==,root); + g_free(root); + g_assert(plover_package_set_get_exclusive(package_set)); + set=plover_package_set_get_razor(package_set); + g_assert(set != NULL); + verify_empty_set(package_set); + dummy_set=get_dummy_set(); + atomic=razor_atomic_open("packageset-update"); + if (!plover_package_set_update(package_set,dummy_set,atomic)) + g_error("plover_package_set_update: %s", + razor_atomic_get_error_msg(atomic)); + if (razor_atomic_commit(atomic)) + g_error("plover_package_set_update: commit: %s", + razor_atomic_get_error_msg(atomic)); + razor_atomic_destroy(atomic); + razor_set_unref(dummy_set); + packages=plover_package_set_get_packages(package_set); + g_assert_cmpint(g_slist_length(packages),==,1); + package=PLOVER_PACKAGE(packages->data); + g_assert_cmpstr(plover_package_get_name(package),==,"dummy"); + pkg=plover_package_get_razor_package(package); + g_assert(plover_package_set_lookup(package_set,pkg)==package); + g_assert(plover_package_set_find_custom(package_set,"dummy", + package_name_compar)==package); + g_assert(plover_package_set_find_matching(package_set,package)==package); + g_assert(!plover_package_set_get_no_details(package_set)); + prefix=plover_package_set_guess_prefix(package_set,&err); + if (!prefix && err) + g_error("plover_package_set_guess_prefix: %s",err->message); + g_assert(err == NULL); + g_assert_cmpstr(prefix,==, + plover_default_prefix_for_vendor("Acme Corporation")); + plover_package_set_close(package_set); + g_object_unref(package_set); +} + +static void test_from_installed(void) +{ + PloverPackageSet *package_set; + PloverPackage *package; + GError *err=NULL; + package_set=plover_package_set_new_from_installed("../razor-test-dir",&err); + if (!package_set && err) + g_error("../razor-test-dir: %s",err->message); + g_assert(PLOVER_IS_PACKAGE_SET(package_set)); + g_assert(!err); + verify_zappy_set(package_set); + plover_package_set_close(package_set); + g_object_unref(package_set); +} + +static void test_from_razor(void) +{ + struct razor_set *set; + PloverPackageSet *package_set; + PloverPackage *package; + set=razor_set_create_without_root(); + package_set=plover_package_set_new_from_razor(set); + g_assert(PLOVER_IS_PACKAGE_SET(package_set)); + verify_empty_set(package_set); + plover_package_set_close(package_set); + g_object_unref(package_set); + razor_set_unref(set); +} + +static void verify_yum_set(PloverPackageSet *package_set,const char *prefix) +{ + verify_package_set(package_set,G_N_ELEMENTS(yum_packages),yum_packages, + prefix); + g_assert(!plover_package_set_get_install_root(package_set)); +} + +static void test_from_repository(void) +{ + PloverRepository *repository; + PloverPackageSet *package_set; + PloverPackage *package; + GError *err=NULL; + repository=plover_repository_new_from_yum("../yum-repo-test-dir",&err); + if (!repository && err) + g_error("../yum-repo-test-dir: %s",err->message); + g_assert(PLOVER_IS_REPOSITORY(repository)); + g_assert(!err); + package_set=plover_package_set_new_from_repository(repository,NULL,&err); + if (!package_set && err) + g_error("../yum-repo-test-dir: %s",err->message); + g_assert(PLOVER_IS_PACKAGE_SET(package_set)); + g_assert(!err); + g_object_unref(repository); + verify_yum_set(package_set,NULL); + plover_package_set_close(package_set); + g_object_unref(package_set); +} + +static void test_from_yum(void) +{ + struct razor_relocations *relocations; + PloverPackageSet *package_set; + PloverPackage *package; + GError *err=NULL; + relocations=razor_relocations_create(); + razor_relocations_add(relocations,"/usr","/test"); + package_set=plover_package_set_new_from_yum("../yum-repo-test-dir", + relocations,&err); + if (!package_set && err) + g_error("../yum-repo-test-dir: %s",err->message); + g_assert(PLOVER_IS_PACKAGE_SET(package_set)); + g_assert(!err); + razor_relocations_destroy(relocations); + verify_yum_set(package_set,"/test"); + plover_package_set_close(package_set); + g_object_unref(package_set); +} + +static void test_from_rpms(void) +{ + int i; + PloverPackageSet *package_set; + PloverPackage *package; + GError *err=NULL; + gchar **filenames; + filenames=g_new(char *,G_N_ELEMENTS(yum_packages)+1); + for(i=0;imessage); + g_assert(PLOVER_IS_PACKAGE_SET(package_set)); + g_assert(!err); + g_strfreev(filenames); + verify_yum_set(package_set,NULL); + plover_package_set_close(package_set); + g_object_unref(package_set); +} + +int main(int argc,char **argv) +{ + g_test_init(&argc,&argv,NULL); + g_test_bug_base("mailto:ali@juiblex.co.uk"); + g_test_add_func("/packageset/unopened",test_unopened); + g_test_add_func("/packageset/open",test_open); + g_test_add_func("/packageset/update",test_update); + g_test_add_func("/packageset/from-installed",test_from_installed); + g_test_add_func("/packageset/from-razor",test_from_razor); + g_test_add_func("/packageset/from-repository",test_from_repository); + g_test_add_func("/packageset/from-yum",test_from_yum); + g_test_add_func("/packageset/from-rpms",test_from_rpms); + return g_test_run(); +} diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/plover/test-razor.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/plover/test-razor.c Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2016 J. Ali Harlow + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include + +LUALIB_API int luaopen_posix(lua_State *L); + +static void test_install(void) +{ + char *pkgs[]={"zip",NULL}; + gchar *root; + GError *err=NULL; + root=g_strdup("razor-test-dir-XXXXXX"); + g_assert(mkdtemp(root)); + g_setenv("RAZOR_ROOT",root,TRUE); + if (!plover_install("../yum-repo-test-dir","/test",pkgs,&err)) + { + g_assert(err && err->message); + g_error("test-install: %s",err->message); + } + g_assert(!err); + g_unsetenv("RAZOR_ROOT"); + g_free(root); +} + +static void test_install_bad_rpm(void) +{ + gboolean installed_bad_rpm; + char *pkgs[]={"zip",NULL}; + gchar *root; + GError *err=NULL; + root=g_strdup("razor-test-dir-XXXXXX"); + g_assert(mkdtemp(root)); + g_setenv("RAZOR_ROOT",root,TRUE); + chmod("../yum-repo-test-dir/rpms/zip-1-1.noarch.rpm",0); + installed_bad_rpm=plover_install("../yum-repo-test-dir","/test",pkgs,&err); + chmod("../yum-repo-test-dir/rpms/zip-1-1.noarch.rpm",0666); + g_assert(!installed_bad_rpm); + g_assert(err && err->message); + g_unsetenv("RAZOR_ROOT"); + g_free(root); +} + +static void test_update_noop(void) +{ + gchar *root; + GError *err=NULL; + root=g_strdup("razor-test-dir-XXXXXX"); + g_assert(mkdtemp(root)); + g_setenv("RAZOR_ROOT",root,TRUE); + if (!plover_update("../yum-repo-test-dir","/test",NULL,&err)) + { + g_assert(err && err->message); + g_error("test-update-noop: %s",err->message); + } + g_assert(!err); + g_unsetenv("RAZOR_ROOT"); + g_free(root); +} + +static void test_update_nonexistant(void) +{ + char *pkgs[]={"nonexistant",NULL}; + gchar *root; + GError *err=NULL; + root=g_strdup("razor-test-dir-XXXXXX"); + g_assert(mkdtemp(root)); + g_setenv("RAZOR_ROOT",root,TRUE); + g_assert(!plover_update("../yum-repo-test-dir","/test",pkgs,&err)); + g_assert(g_error_matches(err,PLOVER_GENERAL_ERROR, + PLOVER_GENERAL_ERROR_NO_SUCH_PACKAGE)); + g_clear_error(&err); + g_unsetenv("RAZOR_ROOT"); + g_free(root); +} + +static void test_remove(void) +{ + char *pkgs[]={"zip",NULL}; + gchar *root; + GError *err=NULL; + root=g_strdup("razor-test-dir-XXXXXX"); + g_assert(mkdtemp(root)); + g_setenv("RAZOR_ROOT",root,TRUE); + if (!plover_install("../yum-repo-test-dir","/test",pkgs,&err)) + g_error("test-remove: %s",err->message); + if (!plover_remove(pkgs,&err)) + { + g_assert(err && err->message); + g_error("test-remove: %s",err->message); + } + g_assert(!err); + g_unsetenv("RAZOR_ROOT"); + g_free(root); +} + +static void test_remove_noop(void) +{ + gchar *root; + GError *err=NULL; + root=g_strdup("razor-test-dir-XXXXXX"); + g_assert(mkdtemp(root)); + g_setenv("RAZOR_ROOT",root,TRUE); + if (!plover_remove(NULL,&err)) + { + g_assert(err && err->message); + g_error("test-remove-noop: %s",err->message); + } + g_assert(!err); + g_unsetenv("RAZOR_ROOT"); + g_free(root); +} + +static void test_remove_nonexistant(void) +{ + char *pkgs[]={"nonexistant",NULL}; + gchar *root; + GError *err=NULL; + root=g_strdup("razor-test-dir-XXXXXX"); + g_assert(mkdtemp(root)); + g_setenv("RAZOR_ROOT",root,TRUE); + g_assert(!plover_remove(pkgs,&err)); + g_assert(g_error_matches(err,PLOVER_GENERAL_ERROR, + PLOVER_GENERAL_ERROR_NO_SUCH_PACKAGE)); + g_clear_error(&err); + g_unsetenv("RAZOR_ROOT"); + g_free(root); +} + +static void test_remove_warning(void) +{ + char *pkgs[]={"badpostun",NULL}; + gchar *root; + GError *err=NULL; + root=g_strdup("razor-test-dir-XXXXXX"); + g_assert(mkdtemp(root)); + g_setenv("RAZOR_ROOT",root,TRUE); + if (!plover_install("../yum-repo-test-dir","/test",pkgs,&err)) + g_error("test-remove-warning: %s",err->message); + if (!plover_remove(pkgs,&err)) + { + g_assert(err && err->message); + g_error("test-remove-warning: %s",err->message); + } + g_assert(!err); + g_unsetenv("RAZOR_ROOT"); + g_free(root); +} + +static void test_prefix(void) +{ + g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE); + g_assert(plover_installed_files_match_prefix("/usr//")); + g_assert(!plover_installed_files_match_prefix("/tmp")); + g_unsetenv("RAZOR_ROOT"); +} + +static void test_prefix_none(void) +{ + gchar *root; + root=g_strdup("razor-test-dir-XXXXXX"); + g_assert(mkdtemp(root)); + g_setenv("RAZOR_ROOT",root,TRUE); + g_assert(plover_installed_files_match_prefix("/any-prefix")); + g_unsetenv("RAZOR_ROOT"); + g_free(root); +} + +int main(int argc,char **argv) +{ + int retval; + g_test_init(&argc,&argv,NULL); + razor_set_lua_loader("posix",(void (*)())luaopen_posix); + g_test_bug_base("mailto:ali@juiblex.co.uk"); + g_test_add_func("/razor/install",test_install); + g_test_add_func("/razor/install-bad-rpm",test_install_bad_rpm); + g_test_add_func("/razor/update-noop",test_update_noop); + g_test_add_func("/razor/update-nonexistant",test_update_nonexistant); + g_test_add_func("/razor/remove",test_remove); + g_test_add_func("/razor/remove-noop",test_remove_noop); + g_test_add_func("/razor/remove-nonexistant",test_remove_nonexistant); + g_test_add_func("/razor/remove-warning",test_remove_warning); + g_test_add_func("/razor/prefix",test_prefix); + g_test_add_func("/razor/prefix-none",test_prefix_none); + retval=g_test_run(); + return retval; +} diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/plover/test-repository.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/plover/test-repository.c Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2016 J. Ali Harlow + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include + +const char *test_repo_packages[]={ + "zsh","zsh2","zip","zap","filesystem","zappy","zappy-tools","zappy2", + "unsatisfiable","uninstallable","badpostun" +}; + +static void test_from_files(void) +{ + int i; + struct razor_set *set; + struct razor_package_iterator *iter; + struct razor_package *package; + PloverRepository *repository; + PloverPackageSet *package_set; + char **filenames; + const char *name; + GList *expected=NULL,*lnk; + GError *err=NULL; + filenames=g_new(char *,G_N_ELEMENTS(test_repo_packages)+1); + for(i=0;imessage); + g_assert(repository != NULL); + g_assert(err == NULL); + package_set=plover_repository_get_package_set(repository); + g_assert(package_set != NULL); + set=plover_package_set_get_razor(package_set); + g_assert(set != NULL); + for(i=0;idata); + g_object_unref(repository); +} + +static void test_from_yum(void) +{ + int i; + struct razor_set *set; + struct razor_package_iterator *iter; + struct razor_package *package; + PloverRepository *repository; + PloverPackageSet *package_set; + const char *name; + GList *expected=NULL,*lnk; + GError *err=NULL; + repository=plover_repository_new_from_yum("../yum-repo-test-dir",&err); + if (!repository && err) + g_error("../yum-repo-test-dir: %s",err->message); + g_assert(repository != NULL); + g_assert(err == NULL); + package_set=plover_repository_get_package_set(repository); + g_assert(package_set != NULL); + set=plover_package_set_get_razor(package_set); + g_assert(set != NULL); + for(i=0;idata); + g_object_unref(repository); +} + +static void test_open_rpm(void) +{ + struct razor_rpm *rpm; + PloverRepository *repository; + PloverPackageSet *package_set; + PloverPackage *package; + const char *name; + GSList *packages,*lnk; + GError *err=NULL; + repository=plover_repository_new_from_yum("../yum-repo-test-dir",&err); + if (!repository) + g_error("../yum-repo-test-dir: %s",err->message); + package_set=plover_repository_get_package_set(repository); + packages=plover_package_set_get_packages(package_set); + for(lnk=packages;lnk;lnk=lnk->next) + { + package=PLOVER_PACKAGE(lnk->data); + rpm=plover_repository_open_rpm(repository,package,&err); + if (!rpm && err) + g_error("%s: %s",plover_package_get_name(package),err->message); + g_assert(rpm != NULL); + g_assert(err == NULL); + razor_rpm_get_details(rpm,RAZOR_DETAIL_NAME,&name,RAZOR_DETAIL_LAST); + g_assert_cmpstr(plover_package_get_name(package),==,name); + razor_rpm_close(rpm); + } + g_object_unref(repository); +} + +int main(int argc,char **argv) +{ + g_test_init(&argc,&argv,NULL); + g_test_bug_base("mailto:ali@juiblex.co.uk"); + g_test_add_func("/repository/from-files",test_from_files); + g_test_add_func("/repository/from-yum",test_from_yum); + g_test_add_func("/repository/open-rpm",test_open_rpm); + return g_test_run(); +} diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/plover/test-transaction.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/plover/test-transaction.c Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,441 @@ +/* + * Copyright (C) 2016 J. Ali Harlow + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +LUALIB_API int luaopen_posix(lua_State *L); + +const char *zappy_packages[]={ + "zap","zappy","zappy-tools","zappy2" +}; + +static void test_installed_system_set(void) +{ + PloverTransaction *transaction; + PloverPackageSet *package_set; + struct razor_set *set; + GError *err=NULL; + transaction=plover_transaction_new(); + g_assert(PLOVER_IS_TRANSACTION(transaction)); + package_set=plover_package_set_new_from_yum("../yum-repo-test-dir",NULL, + &err); + if (!package_set) + g_error("../yum-repo-test-dir: %s",err->message); + plover_transaction_set_installed(transaction,package_set); + set=plover_transaction_get_system_set(transaction); + g_assert(set == plover_package_set_get_razor(package_set)); + g_object_unref(package_set); + g_object_unref(transaction); +} + +static PloverTransaction *update_noop(void) +{ + PloverTransaction *transaction; + struct razor_install_iterator *iter; + struct razor_package *pkg; + enum razor_install_action action; + int count; + GError *err=NULL; + g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE); + transaction=plover_transaction_new_update("../yum-repo-test-dir","/test", + NULL,&err); + if (!transaction && err) + g_error("../yum-repo-test-dir: %s",err->message); + g_assert(PLOVER_IS_TRANSACTION(transaction)); + g_assert(!err); + g_assert(!plover_transaction_get_unsatisfied(transaction)); + iter=plover_transaction_get_install_iterator(transaction,&err); + if (!iter && err) + g_error("plover_transaction_get_install_iterator: %s",err->message); + g_assert(iter); + g_assert(!err); + g_assert(!razor_install_iterator_next(iter,&pkg,&action,&count)); + return transaction; +} + +static void test_update_noop(void) +{ + PloverTransaction *transaction; + transaction=update_noop(); + g_object_unref(transaction); +} + +static void test_update_nonexistant(void) +{ + PloverTransaction *transaction; + char *pkgs[]={"nonexistant",NULL}; + GError *err=NULL; + g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE); + transaction=plover_transaction_new_update("../yum-repo-test-dir","/test", + pkgs,&err); + g_assert(!transaction); + g_assert(g_error_matches(err,PLOVER_GENERAL_ERROR, + PLOVER_GENERAL_ERROR_NO_SUCH_PACKAGE)); + g_clear_error(&err); +} + +static void test_install(void) +{ + PloverTransaction *transaction; + struct razor_set *next; + struct razor_install_iterator *iter; + struct razor_package *pkg; + enum razor_install_action action; + int count; + char *name; + char *pkgs[]={"zip",NULL}; + GError *err=NULL; + g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE); + transaction=plover_transaction_new_install("../yum-repo-test-dir","/test", + pkgs,&err); + if (!transaction && err) + g_error("../yum-repo-test-dir: %s",err->message); + g_assert(PLOVER_IS_TRANSACTION(transaction)); + g_assert(!err); + g_assert(!plover_transaction_get_unsatisfied(transaction)); + next=plover_transaction_get_next_set(transaction,&err); + if (!next && err) + g_error("plover_transaction_get_next_set: %s",err->message); + g_assert(next); + g_assert(!err); + iter=plover_transaction_get_install_iterator(transaction,&err); + if (!iter && err) + g_error("plover_transaction_get_install_iterator: %s",err->message); + g_assert(iter); + g_assert(!err); + g_assert(razor_install_iterator_next(iter,&pkg,&action,&count)); + g_assert_cmpint(action,==,RAZOR_INSTALL_ACTION_ADD); + g_assert_cmpint(count,==,1); + razor_package_get_details(next,pkg,RAZOR_DETAIL_NAME,&name, + RAZOR_DETAIL_LAST); + g_assert_cmpstr(name,==,"zip"); + g_assert(!razor_install_iterator_next(iter,&pkg,&action,&count)); + g_object_unref(transaction); +} + +static void test_install_nonexistant(void) +{ + PloverTransaction *transaction; + char *pkgs[]={"nonexistant",NULL}; + GError *err=NULL; + g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE); + transaction=plover_transaction_new_install("../yum-repo-test-dir","/test", + pkgs,&err); + g_assert(!transaction); + g_assert(g_error_matches(err,PLOVER_GENERAL_ERROR, + PLOVER_GENERAL_ERROR_NO_SUCH_PACKAGE)); + g_clear_error(&err); +} + +static void test_install_uninstallable(void) +{ + PloverTransaction *transaction; + struct razor_set *next; + struct razor_install_iterator *iter; + struct razor_package *pkg; + enum razor_install_action action; + int count; + char *name; + char *pkgs[]={"uninstallable",NULL}; + GError *err=NULL; + g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE); + transaction=plover_transaction_new_install("../yum-repo-test-dir","/test", + pkgs,&err); + if (!transaction && err) + g_error("../yum-repo-test-dir: %s",err->message); + g_assert(PLOVER_IS_TRANSACTION(transaction)); + g_assert(!err); + g_assert_cmpstr(plover_transaction_get_unsatisfied(transaction),==,NULL); + next=plover_transaction_get_next_set(transaction,&err); + if (!next && err) + g_error("plover_transaction_get_next_set: %s",err->message); + g_assert(next); + g_assert(!err); + iter=plover_transaction_get_install_iterator(transaction,&err); + if (!iter && err) + g_error("plover_transaction_get_install_iterator: %s",err->message); + g_assert(iter); + g_assert(!err); + g_assert(razor_install_iterator_next(iter,&pkg,&action,&count)); + g_assert_cmpint(action,==,RAZOR_INSTALL_ACTION_ADD); + g_assert_cmpint(count,==,1); + razor_package_get_details(next,pkg,RAZOR_DETAIL_NAME,&name, + RAZOR_DETAIL_LAST); + g_assert_cmpstr(name,==,"uninstallable"); + g_assert(!razor_install_iterator_next(iter,&pkg,&action,&count)); + g_assert(!plover_transaction_commit(transaction,NULL,&err)); + g_assert_cmpint(err->domain,==,PLOVER_RAZOR_ERROR); + g_assert_cmpint(err->code,==,RAZOR_GENERAL_ERROR_FAILED); + g_clear_error(&err); + g_object_unref(transaction); +} + +static void test_unsatisfied(void) +{ + PloverTransaction *transaction; + struct razor_install_iterator *iter; + char *pkgs[]={"unsatisfiable",NULL}; + const char *s; + GError *err=NULL; + g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE); + transaction=plover_transaction_new_install("../yum-repo-test-dir","/test", + pkgs,&err); + if (!transaction && err) + g_error("../yum-repo-test-dir: %s",err->message); + g_assert(PLOVER_IS_TRANSACTION(transaction)); + g_assert(!err); + iter=plover_transaction_get_install_iterator(transaction,&err); + g_assert(!iter); + g_assert(g_error_matches(err,PLOVER_GENERAL_ERROR, + PLOVER_GENERAL_ERROR_REQUIREMENTS_NOT_MET)); + g_clear_error(&err); + s=plover_transaction_get_unsatisfied(transaction); + g_assert_cmpstr(s,!=,NULL); + g_assert_cmpstr(s,!=,""); + g_object_unref(transaction); +} + +static void test_remove(void) +{ + PloverTransaction *transaction; + struct razor_set *system; + struct razor_install_iterator *iter; + struct razor_package *pkg; + enum razor_install_action action; + int count; + char *name; + char *pkgs[]={"zappy-tools",NULL}; + GError *err=NULL; + g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE); + transaction=plover_transaction_new_remove(pkgs,&err); + if (!transaction && err) + g_error("zappy-tools: %s",err->message); + g_assert(PLOVER_IS_TRANSACTION(transaction)); + g_assert(!err); + system=plover_transaction_get_system_set(transaction); + g_assert(system); + iter=plover_transaction_get_install_iterator(transaction,&err); + if (!iter && err) + g_error("plover_transaction_get_install_iterator: %s",err->message); + g_assert(iter); + g_assert(!err); + g_assert(razor_install_iterator_next(iter,&pkg,&action,&count)); + g_assert_cmpint(action,==,RAZOR_INSTALL_ACTION_REMOVE); + g_assert_cmpint(count,==,0); + razor_package_get_details(system,pkg,RAZOR_DETAIL_NAME,&name, + RAZOR_DETAIL_LAST); + g_assert_cmpstr(name,==,"zappy-tools"); + g_assert(!razor_install_iterator_next(iter,&pkg,&action,&count)); + g_object_unref(transaction); +} + +static void test_remove_nonexistant(void) +{ + PloverTransaction *transaction; + char *pkgs[]={"nonexistant",NULL}; + GError *err=NULL; + g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE); + transaction=plover_transaction_new_remove(pkgs,&err); + g_assert(!transaction); + g_assert(g_error_matches(err,PLOVER_GENERAL_ERROR, + PLOVER_GENERAL_ERROR_NO_SUCH_PACKAGE)); + g_clear_error(&err); +} + +GMainLoop *test_commit_mainloop; + +static void test_commit_callback(GObject *source,GAsyncResult *result, + gpointer user_data) +{ + PloverTransaction *transaction=user_data; + GError *err=NULL; + if (!plover_transaction_commit_finish(transaction,result,&err)) + { + g_assert(err && err->message); + g_error("test-commit: %s",err->message); + } + g_assert(!err); + g_main_loop_quit(test_commit_mainloop); +} + +static void test_commit(void) +{ + PloverTransaction *transaction; + test_commit_mainloop=g_main_loop_new(NULL,FALSE); + transaction=update_noop(); + plover_transaction_commit_async(transaction,NULL,test_commit_callback, + transaction); + g_main_loop_run(test_commit_mainloop); + g_main_loop_unref(test_commit_mainloop); + g_object_unref(transaction); +} + +static void test_remove_with_leaves(void) +{ + PloverTransaction *transaction; + struct razor_set *system; + struct razor_install_iterator *iter; + struct razor_package *pkg; + enum razor_install_action action; + int count; + char *name; + char *pkgs[]={"zappy-tools",NULL}; + GError *err=NULL; + g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE); + transaction=plover_transaction_new_remove_with_leaves(pkgs,&err); + if (!transaction && err) + g_error("zappy-tools: %s",err->message); + g_assert(PLOVER_IS_TRANSACTION(transaction)); + g_assert(!err); + system=plover_transaction_get_system_set(transaction); + g_assert(system); + iter=plover_transaction_get_install_iterator(transaction,&err); + if (!iter && err) + g_error("plover_transaction_get_install_iterator: %s",err->message); + g_assert(iter); + g_assert(!err); + g_assert(razor_install_iterator_next(iter,&pkg,&action,&count)); + g_assert_cmpint(action,==,RAZOR_INSTALL_ACTION_REMOVE); + g_assert_cmpint(count,==,0); + razor_package_get_details(system,pkg,RAZOR_DETAIL_NAME,&name, + RAZOR_DETAIL_LAST); + g_assert(!strcmp(name,"zappy-tools") || !strcmp(name,"zappy")); + g_assert(razor_install_iterator_next(iter,&pkg,&action,&count)); + g_assert_cmpint(action,==,RAZOR_INSTALL_ACTION_REMOVE); + g_assert_cmpint(count,==,0); + razor_package_get_details(system,pkg,RAZOR_DETAIL_NAME,&name, + RAZOR_DETAIL_LAST); + g_assert(!strcmp(name,"zappy-tools") || !strcmp(name,"zappy")); + g_assert(!razor_install_iterator_next(iter,&pkg,&action,&count)); + g_object_unref(transaction); +} + +static void test_remove_nonexistant_with_leaves(void) +{ + PloverTransaction *transaction; + char *pkgs[]={"nonexistant",NULL}; + GError *err=NULL; + g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE); + transaction=plover_transaction_new_remove_with_leaves(pkgs,&err); + g_assert(!transaction); + g_assert(g_error_matches(err,PLOVER_GENERAL_ERROR, + PLOVER_GENERAL_ERROR_NO_SUCH_PACKAGE)); + g_clear_error(&err); +} + +static void test_remove_all(void) +{ + int i; + PloverTransaction *transaction; + struct razor_set *system; + struct razor_install_iterator *iter; + struct razor_package *pkg; + enum razor_install_action action; + int count; + char *name; + GError *err=NULL; + GList *expected=NULL,*lnk; + g_setenv("RAZOR_ROOT","../razor-test-dir",TRUE); + transaction=plover_transaction_new_remove_with_leaves(NULL,&err); + if (!transaction && err) + g_error("remove-all: %s",err->message); + g_assert(PLOVER_IS_TRANSACTION(transaction)); + g_assert(!err); + system=plover_transaction_get_system_set(transaction); + g_assert(system); + for(i=0;imessage); + g_assert(iter); + g_assert(!err); + while(razor_install_iterator_next(iter,&pkg,&action,&count)) + { + g_assert_cmpint(action,==,RAZOR_INSTALL_ACTION_REMOVE); + g_assert_cmpint(count,==,0); + razor_package_get_details(system,pkg,RAZOR_DETAIL_NAME,&name, + RAZOR_DETAIL_LAST); + lnk=g_list_find(expected,g_intern_string(name)); + if (!lnk) + g_warning("Unexpected package to be removed: %s",name); + else + expected=g_list_delete_link(expected,lnk); + } + if (expected) + g_warning("%d package%s not removed, including %s", + g_list_length(expected),g_list_length(expected)==1?"":"s", + expected->data); + g_object_unref(transaction); +} + +static void test_change_installed(void) +{ + PloverTransaction *transaction; + PloverPackageSet *package_set; + GError *err=NULL; + transaction=plover_transaction_new(); + g_assert(PLOVER_IS_TRANSACTION(transaction)); + if (!plover_transaction_root_open(transaction,"../razor-test-dir",&err)) + { + g_assert(err && err->message); + g_error("../razor-test-dir: %s",err->message); + } + g_assert(!err); + g_assert(plover_transaction_get_system_set(transaction)); + package_set=plover_package_set_new_from_yum("../yum-repo-test-dir",NULL, + &err); + if (!package_set) + g_error("../yum-repo-test-dir: %s",err->message); + plover_transaction_set_installed(transaction,package_set); + g_object_unref(package_set); + g_object_unref(transaction); +} + +int main(int argc,char **argv) +{ + g_test_init(&argc,&argv,NULL); + razor_set_lua_loader("posix",(void (*)())luaopen_posix); + g_test_bug_base("mailto:ali@juiblex.co.uk"); + g_test_add_func("/transaction/installed-system-set", + test_installed_system_set); + g_test_add_func("/transaction/update-noop",test_update_noop); + g_test_add_func("/transaction/update-nonexistant",test_update_nonexistant); + g_test_add_func("/transaction/install",test_install); + g_test_add_func("/transaction/install-nonexistant", + test_install_nonexistant); + g_test_add_func("/transaction/install-uninstallable", + test_install_uninstallable); + g_test_add_func("/transaction/unsatisfied",test_unsatisfied); + g_test_add_func("/transaction/remove",test_remove); + g_test_add_func("/transaction/remove-nonexistant",test_remove_nonexistant); + g_test_add_func("/transaction/commit",test_commit); + g_test_add_func("/transaction/remove-with-leaves",test_remove_with_leaves); + g_test_add_func("/transaction/remove-nonexistant-with-leaves", + test_remove_nonexistant_with_leaves); + g_test_add_func("/transaction/remove-all",test_remove_all); + g_test_add_func("/transaction/change-installed",test_change_installed); + return g_test_run(); +} diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/plover/test-util.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/plover/test-util.c Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2016 J. Ali Harlow + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#ifdef WIN32 +#include +#endif +#include +#include +#include +#include +#include +#include + +static void test_pre_install_prefix(void) +{ + gchar *pre_install_prefix; + pre_install_prefix=plover_pre_install_prefix(); + g_assert_cmpstr(pre_install_prefix,!=,NULL); + g_assert_cmpstr(pre_install_prefix,!=,""); + g_free(pre_install_prefix); +} + +static void test_reports_directory(void) +{ + gchar *reports_directory; + reports_directory=plover_get_reports_directory(); + g_assert_cmpstr(reports_directory,!=,NULL); + g_assert_cmpstr(reports_directory,!=,""); + g_free(reports_directory); +} + +static void test_program_directory(void) +{ + gchar *program_directory; + program_directory=plover_get_program_directory("test-util"); + g_assert_cmpstr(program_directory,!=,NULL); + g_assert_cmpstr(program_directory,!=,""); + free(program_directory); + program_directory=plover_get_program_directory("./test-util"); + g_assert_cmpstr(program_directory,!=,NULL); + g_assert_cmpstr(program_directory,!=,""); + free(program_directory); +} + +static void verify_error_propagation(int domain,int code) +{ + GError *src,*dest=NULL; + struct razor_error *tmp=NULL; + src=g_error_new_literal(domain,code,"test error"); + plover_propagate_g_error(&tmp,src); + g_assert(tmp!=NULL); + plover_propagate_razor_error(&dest,tmp); + g_assert(dest!=NULL); + g_assert_cmpint(dest->domain,==,domain); + g_assert_cmpint(dest->code,==,code); + g_assert_cmpstr(dest->message,==,"test error"); + g_error_free(dest); +} + +static void test_propagate_razor_error(void) +{ + verify_error_propagation(PLOVER_RAZOR_ERROR,RAZOR_GENERAL_ERROR_FAILED); +} + +static void test_propagate_posix_error(void) +{ + verify_error_propagation(PLOVER_POSIX_ERROR,ENOENT); +} + +static void test_propagate_mswin_error(void) +{ +#ifdef WIN32 + verify_error_propagation(PLOVER_MSWIN_ERROR,ERROR_NOT_SUPPORTED); +#else + verify_error_propagation(PLOVER_MSWIN_ERROR,0); +#endif +} + +static void test_propagate_zlib_error(void) +{ + verify_error_propagation(PLOVER_ZLIB_ERROR,Z_VERSION_ERROR); +} + +static void test_propagate_cancelled(void) +{ + verify_error_propagation(G_IO_ERROR,G_IO_ERROR_CANCELLED); +} + +static void test_propagate_other_error(void) +{ + GError *src,*dest=NULL; + struct razor_error *tmp=NULL; + src=g_error_new_literal(G_SHELL_ERROR,G_SHELL_ERROR_FAILED,"test error"); + plover_propagate_g_error(&tmp,src); + g_assert(tmp!=NULL); + plover_propagate_razor_error(&dest,tmp); + g_assert(dest!=NULL); + g_assert_cmpint(dest->domain,==,PLOVER_RAZOR_ERROR); + g_assert_cmpint(dest->code,==,RAZOR_GENERAL_ERROR_FAILED); + g_assert_cmpstr(dest->message,==,"test error"); + g_error_free(dest); +} + +int main(int argc,char **argv) +{ + int retval; + g_test_init(&argc,&argv,NULL); + g_test_bug_base("mailto:ali@juiblex.co.uk"); + g_test_add_func("/util/pre-install-prefix",test_pre_install_prefix); + g_test_add_func("/util/reports-directory",test_reports_directory); + g_test_add_func("/util/program-directory",test_program_directory); + g_test_add_func("/util/propagate-razor-error",test_propagate_razor_error); + g_test_add_func("/util/propagate-posix-error",test_propagate_posix_error); + g_test_add_func("/util/propagate-mswin-error",test_propagate_mswin_error); + g_test_add_func("/util/propagate-zlib-error",test_propagate_zlib_error); + g_test_add_func("/util/propagate-cancelled",test_propagate_cancelled); + g_test_add_func("/util/propagate-other-error",test_propagate_other_error); + retval=g_test_run(); + return retval; +} diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/plover/test-vector.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/plover/test-vector.c Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2016 J. Ali Harlow + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include + +static void test_empty(void) +{ + struct plover_vector *vector; + char *display; + vector=plover_vector_new(); + g_assert(vector); + display=plover_vector_format_for_display(vector); + g_assert_cmpstr(display,==,"none"); + free(display); + plover_vector_free(vector); +} + +static void test_single(void) +{ + struct plover_vector *vector; + char *display; + vector=plover_vector_new(); + g_assert(vector); + plover_vector_append(vector,"single"); + display=plover_vector_format_for_display(vector); + g_assert_cmpstr(display,==,"single"); + free(display); + plover_vector_free(vector); +} + +static void test_pair(void) +{ + struct plover_vector *vector; + char *display; + vector=plover_vector_new(); + g_assert(vector); + plover_vector_append(vector,"one"); + plover_vector_append(vector,"two"); + display=plover_vector_format_for_display(vector); + g_assert_cmpstr(display,==,"one and two"); + free(display); + plover_vector_free(vector); +} + +static void test_triple(void) +{ + struct plover_vector *vector; + char *display; + vector=plover_vector_new(); + g_assert(vector); + plover_vector_append(vector,"one"); + plover_vector_append(vector,"two"); + plover_vector_append(vector,"three"); + display=plover_vector_format_for_display(vector); + g_assert_cmpstr(display,==,"one, two and three"); + free(display); + plover_vector_free(vector); +} + +static void test_sort(void) +{ + struct plover_vector *vector; + char *display; + vector=plover_vector_new(); + g_assert(vector); + plover_vector_append(vector,"one"); + plover_vector_append(vector,"two"); + plover_vector_append(vector,"three"); + plover_vector_sort(vector); + display=plover_vector_format_for_display(vector); + g_assert_cmpstr(display,==,"one, three and two"); + free(display); + plover_vector_free(vector); +} + +static void test_dup(void) +{ + struct plover_vector *vector,*vector2; + char *display; + vector=plover_vector_new(); + g_assert(vector); + plover_vector_append(vector,"one"); + plover_vector_append(vector,"two"); + plover_vector_append(vector,"three"); + vector2=plover_vector_dup(vector); + plover_vector_sort(vector2); + display=plover_vector_format_for_display(vector); + g_assert_cmpstr(display,==,"one, two and three"); + free(display); + display=plover_vector_format_for_display(vector2); + g_assert_cmpstr(display,==,"one, three and two"); + free(display); + plover_vector_free(vector); + plover_vector_free(vector2); +} + +static void test_contains(void) +{ + struct plover_vector *vector; + vector=plover_vector_new(); + g_assert(vector); + plover_vector_append(vector,"one"); + plover_vector_append(vector,"two"); + plover_vector_append(vector,"three"); + g_assert(plover_vector_contains(vector,"one")); + g_assert(plover_vector_contains(vector,"two")); + g_assert(plover_vector_contains(vector,"three")); + g_assert(!plover_vector_contains(vector,"four")); + plover_vector_free(vector); +} + +static void test_long(void) +{ + int i; + struct plover_vector *vector; + char letter[2],*display; + vector=plover_vector_new(); + g_assert(vector); + letter[1]=0; + for(i=0;i<26;i++) + { + letter[0]='a'+i; + plover_vector_append(vector,letter); + } + display=plover_vector_format_for_display(vector); + g_assert_cmpstr(display,==,"a, b, c, d, e, f, g, h, i, j, k, l, " + "m, n, o, p, q, r, s, t, u, v, w, x, y and z"); + free(display); + plover_vector_free(vector); +} + +int main(int argc,char **argv) +{ + int retval; + g_test_init(&argc,&argv,NULL); + g_test_bug_base("mailto:ali@juiblex.co.uk"); + g_test_add_func("/vector/empty",test_empty); + g_test_add_func("/vector/single",test_single); + g_test_add_func("/vector/pair",test_pair); + g_test_add_func("/vector/triple",test_triple); + g_test_add_func("/vector/sort",test_sort); + g_test_add_func("/vector/dup",test_dup); + g_test_add_func("/vector/contains",test_contains); + g_test_add_func("/vector/long",test_long); + retval=g_test_run(); + return retval; +} diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/uninstallable.spec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/uninstallable.spec Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,30 @@ +%define _source_payload w9.gzdio +%define _binary_payload w9.gzdio + +Name: uninstallable +Summary: A package that cannot be installed +Group: Test +License: GPL +URL: http://www.juiblex.co.uk/beach +Version: 1 +Release: 1 +Source: uninstallable.tar +BuildArch: noarch +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +Prefix: /usr + +%description +A package that cannot be installed because its pre script always fails. + +%prep + +%build + +%install + +%clean + +%pre -p +error("Package is uninstallable") + +%files diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/unsatisfiable.spec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/unsatisfiable.spec Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,31 @@ +%define _source_payload w9.gzdio +%define _binary_payload w9.gzdio + +Name: unsatisfiable +Summary: A package that cannot be installed +Group: Test +License: GPL +URL: http://www.juiblex.co.uk/beach +Version: 1 +Release: 1 +Source: unsatisfiable.tar +BuildArch: noarch +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +Prefix: /usr +Requires: pony > 0, pony-tail >= 1, pony-feet <= 4, pony-lame < 1 +Conflicts: money +Obsoletes: life + +%description +A package that cannot be installed because it requires a property (pony) +that is not provided by any package. + +%prep + +%build + +%install + +%clean + +%files diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/xvfb-run --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/xvfb-run Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,190 @@ +#!/bin/sh + +# This script starts an instance of Xvfb, the "fake" X server, runs a command +# with that server available, and kills the X server when done. The return +# value of the command becomes the return value of this script. +# +# If anyone is using this to build a Debian package, make sure the package +# Build-Depends on xvfb and xauth. + +set -e + +PROGNAME=xvfb-run +SERVERNUM=99 +AUTHFILE= +ERRORFILE=/dev/null +XVFBARGS="-screen 0 640x480x8" +LISTENTCP="-nolisten tcp" +XAUTHPROTO=. + +# Query the terminal to establish a default number of columns to use for +# displaying messages to the user. This is used only as a fallback in the event +# the COLUMNS variable is not set. ($COLUMNS can react to SIGWINCH while the +# script is running, and this cannot, only being calculated once.) +DEFCOLUMNS=$(stty size 2>/dev/null | awk '{print $2}') || true +if ! expr "$DEFCOLUMNS" : "[[:digit:]]\+$" >/dev/null 2>&1; then + DEFCOLUMNS=80 +fi + +# Display a message, wrapping lines at the terminal width. +message () { + echo "$PROGNAME: $*" | fmt -t -w ${COLUMNS:-$DEFCOLUMNS} +} + +# Display an error message. +error () { + message "error: $*" >&2 +} + +# Display a usage message. +usage () { + if [ -n "$*" ]; then + message "usage error: $*" + fi + cat <>"$ERRORFILE" 2>&1 + fi + if [ -n "$XVFB_RUN_TMPDIR" ]; then + if ! rm -r "$XVFB_RUN_TMPDIR"; then + error "problem while cleaning up temporary directory" + exit 5 + fi + fi + if [ -n "$XVFBPID" ]; then + kill "$XVFBPID" >>"$ERRORFILE" 2>&1 + fi +} + +# Parse the command line. +ARGS=$(getopt --options +ae:f:hn:lp:s:w: \ + --long auto-servernum,error-file:,auth-file:,help,server-num:,listen-tcp,xauth-protocol:,server-args:,wait: \ + --name "$PROGNAME" -- "$@") +GETOPT_STATUS=$? + +if [ $GETOPT_STATUS -ne 0 ]; then + error "internal error; getopt exited with status $GETOPT_STATUS" + exit 6 +fi + +eval set -- "$ARGS" + +while :; do + case "$1" in + -a|--auto-servernum) SERVERNUM=$(find_free_servernum); AUTONUM="yes" ;; + -e|--error-file) ERRORFILE="$2"; shift ;; + -f|--auth-file) AUTHFILE="$2"; shift ;; + -h|--help) SHOWHELP="yes" ;; + -n|--server-num) SERVERNUM="$2"; shift ;; + -l|--listen-tcp) LISTENTCP="" ;; + -p|--xauth-protocol) XAUTHPROTO="$2"; shift ;; + -s|--server-args) XVFBARGS="$2"; shift ;; + -w|--wait) shift ;; + --) shift; break ;; + *) error "internal error; getopt permitted \"$1\" unexpectedly" + exit 6 + ;; + esac + shift +done + +if [ "$SHOWHELP" ]; then + usage + exit 0 +fi + +if [ -z "$*" ]; then + usage "need a command to run" >&2 + exit 2 +fi + +if ! which xauth >/dev/null; then + error "xauth command not found" + exit 3 +fi + +# tidy up after ourselves +trap clean_up EXIT + +# If the user did not specify an X authorization file to use, set up a temporary +# directory to house one. +if [ -z "$AUTHFILE" ]; then + XVFB_RUN_TMPDIR="$(mktemp -d -t $PROGNAME.XXXXXX)" + # Create empty file to avoid xauth warning + AUTHFILE=$(tempfile -n "$XVFB_RUN_TMPDIR/Xauthority") +fi + +# Start Xvfb. +MCOOKIE=$(mcookie) +tries=10 +while [ $tries -gt 0 ]; do + tries=$(( $tries - 1 )) + XAUTHORITY=$AUTHFILE xauth source - << EOF >>"$ERRORFILE" 2>&1 +add :$SERVERNUM $XAUTHPROTO $MCOOKIE +EOF + # handle SIGUSR1 so Xvfb knows to send a signal when it's ready to accept + # connections + trap : USR1 + (trap '' USR1; exec Xvfb ":$SERVERNUM" $XVFBARGS $LISTENTCP -auth $AUTHFILE >>"$ERRORFILE" 2>&1) & + XVFBPID=$! + + wait || : + if kill -0 $XVFBPID 2>/dev/null; then + break + elif [ -n "$AUTONUM" ]; then + # The display is in use so try another one (if '-a' was specified). + SERVERNUM=$((SERVERNUM + 1)) + SERVERNUM=$(find_free_servernum) + continue + fi + error "Xvfb failed to start" >&2 + XVFBPID= + exit 1 +done + +# Start the command and save its exit status. +set +e +DISPLAY=:$SERVERNUM XAUTHORITY=$AUTHFILE "$@" 2>&1 +RETVAL=$? +set -e + +# Return the executed command's exit status. +exit $RETVAL + +# vim:set ai et sts=4 sw=4 tw=80: diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/zap.spec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/zap.spec Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,29 @@ +%define _source_payload w9.gzdio +%define _binary_payload w9.gzdio + +Name: zap +Summary: Test package +Group: Test +License: GPL +Version: 1 +Release: 1 +Source: zap.tar +BuildArch: noarch +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +Prefix: /usr + +%description +Test package + +%prep + +%build + +%install +mkdir -p $RPM_BUILD_ROOT/usr/bin +touch $RPM_BUILD_ROOT/usr/bin/zap + +%clean + +%files +/usr/bin/zap diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/zappy.spec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/zappy.spec Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,40 @@ +%define _source_payload w9.gzdio +%define _binary_payload w9.gzdio + +Name: zappy +Summary: Test package +Group: Test +License: GPL +Version: 1 +Release: 1 +Source: zappy.tar +BuildArch: noarch +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +Prefix: /usr +Requires: zap + +%description +Test package + +%package tools +Summary: Tools for using zappy +Group: Test +Requires: zappy + +%description tools +Test package + +%prep + +%build + +%install +mkdir -p $RPM_BUILD_ROOT/usr/bin +echo %{name}-%{version}-%{release} > $RPM_BUILD_ROOT/usr/bin/zappy + +%clean + +%files +/usr/bin/zappy + +%files tools diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/zappy2.spec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/zappy2.spec Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,30 @@ +%define _source_payload w9.gzdio +%define _binary_payload w9.gzdio + +Name: zappy2 +Summary: Test package +Group: Test +License: GPL +Version: 1 +Release: 1 +Source: zappy2.tar +BuildArch: noarch +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +Prefix: /usr +Requires: zap + +%description +Test package + +%prep + +%build + +%install +mkdir -p $RPM_BUILD_ROOT/usr/bin +echo %{name}-%{version}-%{release} > $RPM_BUILD_ROOT/usr/bin/zappy2 + +%clean + +%files +/usr/bin/zappy2 diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/zip.spec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/zip.spec Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,60 @@ +%define _source_payload w9.gzdio +%define _binary_payload w9.gzdio + +Name: zip +Summary: Test package +Group: Test +License: GPL +Version: %{_version} +Release: 1 +Source: zip.tar +BuildArch: noarch +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +Prefix: /usr +Requires: zap +Requires(pre,postun): zap + +%description +Test package + +%prep + +%build + +%install +mkdir -p $RPM_BUILD_ROOT/usr/bin +echo %{name}-%{version}-%{release} > $RPM_BUILD_ROOT/usr/bin/zip + +%clean + +%pre -p +function mkdir_missing(dir) + if posix.stat(dir)==nil then + posix.mkdir(dir) + end +end +prefix=posix.getenv("RPM_INSTALL_PREFIX0") +if prefix==nil then + prefix="/usr" +end +if arg[2]==1 and posix.stat(prefix.."/bin/zap")~=nil then + mkdir_missing(prefix.."/var") + mkdir_missing(prefix.."/var/lib") + posix.mkdir(prefix.."/var/lib/zip") + io.output(prefix.."/var/lib/zip/data.zap") + io.write("Important data\n"); + io.close() +end + +%postun -p +prefix=posix.getenv("RPM_INSTALL_PREFIX0") +if prefix==nil then + prefix="/usr" +end +if arg[2]==0 and posix.stat(prefix.."/bin/zap")~=nil then + os.remove(prefix.."/var/lib/zip/data.zap") + os.remove(prefix.."/var/lib/zip") +end + +%files +/usr/bin/zip diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/zsh.spec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/zsh.spec Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,64 @@ +%define _source_payload w9.gzdio +%define _binary_payload w9.gzdio + +Name: zsh +Summary: Test package +Group: Test +License: GPL +URL: http://www.juiblex.co.uk/beach +Version: 1 +Release: 1 +Source: zsh.tar +BuildArch: noarch +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +Prefix: /usr +Requires: zip +Requires(pre,postun): zip + +%description +Test package + +%prep + +%build + +%install +mkdir -p $RPM_BUILD_ROOT/usr/bin +mkdir -p $RPM_BUILD_ROOT/etc +touch $RPM_BUILD_ROOT/usr/bin/zsh +echo "DEVICE /dev/tty" > $RPM_BUILD_ROOT/etc/zsh.conf + +%clean + +%pre -p +function mkdir_missing(dir) + if posix.stat(dir)==nil then + posix.mkdir(dir) + end +end +prefix=posix.getenv("RPM_INSTALL_PREFIX0") +if prefix==nil then + prefix="/usr" +end +if arg[2]==1 and posix.stat(prefix.."/bin/zip")~=nil then + mkdir_missing(prefix.."/var") + mkdir_missing(prefix.."/var/lib") + posix.mkdir(prefix.."/var/lib/zsh") + io.output(prefix.."/var/lib/zsh/data.zip") + io.write("Important data\n"); + io.close() +end + +%postun -p +prefix=posix.getenv("RPM_INSTALL_PREFIX0") +if prefix==nil then + prefix="/usr" +end +if arg[2]==0 and posix.stat(prefix.."/bin/zip")~=nil then + os.remove(prefix.."/var/lib/zsh/data.zip") + os.remove(prefix.."/var/lib/zsh") +end + +%files +/usr/bin/zsh +/etc/zsh.conf diff -r 99d80cbe2eb4 -r a29623b68ca2 tests/zsh2.spec --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/zsh2.spec Mon Jun 13 12:18:42 2016 +0100 @@ -0,0 +1,33 @@ +%define _source_payload w9.gzdio +%define _binary_payload w9.gzdio + +Name: zsh2 +Summary: Test package +Group: Test +License: GPL +Version: 1 +Release: 1 +Source: zsh2.tar +BuildArch: noarch +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +Prefix: /usr +Requires: zip + +%description +New and improved test package + +%prep + +%build + +%install +mkdir -p $RPM_BUILD_ROOT/usr/bin +mkdir -p $RPM_BUILD_ROOT/etc +touch $RPM_BUILD_ROOT/usr/bin/zsh2 +echo "DEVICE /dev/tty" > $RPM_BUILD_ROOT/etc/zsh.conf + +%clean + +%files +/usr/bin/zsh2 +/etc/zsh.conf diff -r 99d80cbe2eb4 -r a29623b68ca2 update/update.c --- a/update/update.c Mon Apr 18 15:04:47 2016 +0100 +++ b/update/update.c Mon Jun 13 12:18:42 2016 +0100 @@ -73,8 +73,8 @@ int main(int argc,char **argv) { plover_exception_handler_init(); - razor_set_lua_loader("posix",luaopen_posix); - razor_set_lua_loader("whelk",luaopen_whelk); + razor_set_lua_loader("posix",(void (*)())luaopen_posix); + razor_set_lua_loader("whelk",(void (*)())luaopen_whelk); update(argv[0]); exit(0); }