Commit 1d037a7b authored by David Zeuthen's avatar David Zeuthen

add unit test framework with gcov coverage support (make check-coverage)

This is what it looks like

==============================================================================
Test coverage for module polkit:
==============================================================================
polkit-sysdeps.c                                        :   0% (0 of 38)
polkit-error.c                                          :   0% (0 of 44)
polkit-result.c                                         :   0% (0 of 16)
polkit-context.c                                        :   0% (0 of 213)
polkit-action.c                                         :  34% (20 of 58)
polkit-seat.c                                           :   0% (0 of 34)
polkit-session.c                                        :   0% (0 of 97)
polkit-caller.c                                         :   0% (0 of 81)
polkit-policy-file-entry.c                              :   0% (0 of 72)
polkit-policy-file.c                                    :   0% (0 of 220)
polkit-policy-cache.c                                   :   0% (0 of 98)
polkit-policy-default.c                                 :   0% (0 of 67)
polkit-debug.c                                          :   0% (0 of 15)
polkit-utils.c                                          :   0% (0 of 42)
polkit-config.c                                         :   0% (0 of 263)
polkit-authorization.c                                  :   0% (0 of 162)
polkit-authorization-constraint.c                       :   0% (0 of 107)
polkit-authorization-db.c                               :   0% (0 of 222)

Source lines          : 6919
Actual statements     : 1849
Executed statements   : 20
Test coverage         : 1%
parent 7d149b62
## Process this file with automake to produce Makefile.in
SUBDIRS = data polkit polkit-dbus polkit-grant polkitd doc tools policy po
SUBDIRS = data polkit polkit-dbus polkit-grant polkitd doc tools policy po test
# Creating ChangeLog from git log (taken from cairo/Makefile.am):
ChangeLog: $(srcdir)/ChangeLog
......@@ -19,8 +19,24 @@ $(srcdir)/ChangeLog:
echo A git checkout and git-log is required to generate this file >> $@); \
fi
if POLKIT_GCOV_ENABLED
.PHONY: ChangeLog $(srcdir)/ChangeLog coverage-report.txt
coverage-report.txt :
make -C polkit check-coverage
cat polkit/coverage-report.txt > coverage-report.txt
check-coverage: coverage-report.txt
cat coverage-report.txt
else
.PHONY: ChangeLog $(srcdir)/ChangeLog
coverage-report.txt:
@echo "Need to reconfigure with --enable-gcov"
check-coverage:
@echo "Need to reconfigure with --enable-gcov"
endif
EXTRA_DIST = \
HACKING \
mkinstalldirs \
......@@ -35,7 +51,7 @@ DISTCLEANFILES = \
intltool-update
# xsltproc barfs on 'make distcheck'; disable for now
DISTCHECK_CONFIGURE_FLAGS=--disable-man-pages
DISTCHECK_CONFIGURE_FLAGS=--disable-man-pages --disable-gtk-doc
clean-local :
rm -f *~
......@@ -30,8 +30,31 @@ AM_PROG_CC_C_O
# Taken from dbus
AC_ARG_ENABLE(ansi, [ --enable-ansi enable -ansi -pedantic gcc flags],enable_ansi=$enableval,enable_ansi=no)
AC_ARG_ENABLE(verbose-mode, [ --enable-verbose-mode support verbose debug mode],enable_verbose_mode=$enableval,enable_verbose_mode=$USE_MAINTAINER_MODE)
AC_ARG_ENABLE(tests, AS_HELP_STRING([--enable-tests],[enable unit test code]),enable_tests=$enableval,enable_tests=$USE_MAINTAINER_MODE)
AC_ARG_ENABLE(gcov, AS_HELP_STRING([--enable-gcov],[compile with coverage profiling instrumentation (gcc only)]),enable_gcov=$enableval,enable_gcov=no)
AC_ARG_ENABLE(man-pages, [ --enable-man-pages build manual pages],enable_man_pages=$enableval,enable_man_pages=yes)
AM_CONDITIONAL(POLKIT_BUILD_TESTS, test x$enable_tests = xyes)
if test x$enable_tests = xyes; then
AC_DEFINE(POLKIT_BUILD_TESTS,1,[Build test code])
fi
if test x$enable_gcov = xyes; then
## so that config.h changes when you toggle gcov support
AC_DEFINE_UNQUOTED(POLKIT_GCOV_ENABLED, 1, [Defined if gcov is enabled to force a rebuild due to config.h changing])
AC_MSG_CHECKING([for gcc 3.3 version of gcov file format])
have_gcc33_gcov=no
AC_RUN_IFELSE( [AC_LANG_PROGRAM( , [[ if (__GNUC__ >=3 && __GNUC_MINOR__ >= 3) exit (0); else exit (1); ]])],
have_gcc33_gcov=yes)
if test x$have_gcc33_gcov = xyes ; then
AC_DEFINE_UNQUOTED(POLKIT_HAVE_GCC33_GCOV, 1, [Defined if we have gcc 3.3 and thus the new gcov format])
fi
AC_MSG_RESULT($have_gcc33_gcov)
fi
AM_CONDITIONAL(POLKIT_GCOV_ENABLED, test x$enable_gcov = xyes)
if test "${enable_man_page}" != no; then
dnl
dnl Check for xsltproc
......@@ -440,6 +463,7 @@ doc/version.xml
doc/man/Makefile
policy/Makefile
po/Makefile.in
test/Makefile
])
dnl ==========================================================================
......@@ -481,41 +505,45 @@ fi
echo "
Maintainer mode: ${USE_MAINTAINER_MODE}
Building unit tests: ${enable_tests}
GCC coverage profiling: ${enable_gcov}
Building verbose mode: ${enable_verbose_mode}
Building api docs: ${enable_gtk_doc}
Building man pages: ${enable_man_pages}
"
if test "${POLKIT_AUTHDB}" = default ; then
echo "NOTE: Remember to create user '${POLKIT_USER}' and group '${POLKIT_GROUP}'"
echo " before 'make install'"
echo
echo "NOTE: The directories ${localstatedir}/run/PolicyKit and ${localstatedir}/lib/PolicyKit will be"
echo " owned by group '${POLKIT_GROUP}' and will be of mode 770."
echo
echo "NOTE: ${libexecdir}/polkit-read-auth-helper will be owned by group"
echo " '${POLKIT_GROUP}', and installed with mode 2755 (setgid binary)."
echo
echo "NOTE: ${libexecdir}/polkit-revoke-helper will be owned by group"
echo " '${POLKIT_GROUP}', and installed with mode 2755 (setgid binary)."
echo
echo "NOTE: ${libexecdir}/polkit-grant-helper will be owned by group"
echo " '${POLKIT_GROUP}', and installed with mode 2755 (setgid binary)."
echo
echo "NOTE: ${libexecdir}/polkit-explicit-grant-helper will be owned by group"
echo " '${POLKIT_GROUP}', and installed with mode 2755 (setgid binary)."
echo
echo "NOTE: ${libexecdir}/polkit-grant-helper-pam will be setuid root."
echo
if test x$enable_tests = xyes; then
echo "NOTE: Building with unit tests increases the size of the installed "
echo " library and may render it insecure."
echo
fi
echo "NOTE: For packaging, remember to retain the modes and ownership."
echo
if test x$enable_gcov = xyes; then
echo "NOTE: Building with coverage profiling is definitely for developers only."
echo
fi
if test "${POLKIT_AUTHDB}" = default ; then
echo "NOTE: Remember to create user ${POLKIT_USER} and group ${POLKIT_GROUP}"
echo " before 'make install'"
echo
echo "NOTE: The directories ${localstatedir}/run/PolicyKit and ${localstatedir}/lib/PolicyKit will be"
echo " owned by group ${POLKIT_GROUP} and will be mode 770."
echo
echo "NOTE: ${libexecdir}/polkit-read-auth-helper will be owned by"
echo " group ${POLKIT_GROUP} and installed with mode 2755 (setgid binary)."
echo
echo "NOTE: ${libexecdir}/polkit-revoke-helper will be owned by"
echo " group '${POLKIT_GROUP} and installed with mode 2755 (setgid binary)."
echo
echo "NOTE: ${libexecdir}/polkit-grant-helper will be owned by"
echo " group ${POLKIT_GROUP} and installed with mode 2755 (setgid binary)."
echo
echo "NOTE: ${libexecdir}/polkit-explicit-grant-helper will be owned by"
echo " group ${POLKIT_GROUP} and installed with mode 2755 (setgid binary)."
echo
echo "NOTE: ${libexecdir}/polkit-grant-helper-pam will be setuid root."
echo
echo "NOTE: For packaging, remember to retain the modes and ownership."
echo
fi
......@@ -29,12 +29,14 @@ IGNORE_HFILES= \
# CFLAGS and LDFLAGS for compiling scan program. Only needed
# if $(DOC_MODULE).types is non-empty.
INCLUDES = \
$(DBUS_GLIB_CFLAGS) \
$(GLIB_CFLAGS) \
-I$(top_srcdir) \
-I$(top_builddir) \
$(NULL)
GTKDOC_LIBS = \
$(DBUS_GLIB_LIBS) \
$(GLIB_LIBS) \
$(top_builddir)/polkit/libpolkit.la \
$(NULL)
......@@ -74,7 +76,11 @@ MAINTAINERCLEANFILES = \
polkit-*.txt \
$(NULL)
if ENABLE_GTK_DOC
include $(top_srcdir)/gtk-doc.make
else
EXTRA_DIST =
endif
# Version information for marking the documentation
EXTRA_DIST += version.xml.in
......@@ -74,8 +74,49 @@ libpolkit_la_LIBADD = @GLIB_LIBS@ @EXPAT_LIBS@
libpolkit_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
## note that TESTS has special meaning (stuff to use in make check)
## so if adding tests not to be run in make check, don't add them to
## TESTS
if POLKIT_BUILD_TESTS
TESTS_ENVIRONMENT=
TESTS=polkit-test
if POLKIT_GCOV_ENABLED
clean-gcov:
rm -f *.gcov .libs/*.gcda
.PHONY: coverage-report.txt
coverage-report.txt :
$(top_srcdir)/test/create-coverage-report.sh polkit $(filter %.c,$(libpolkit_la_SOURCES)) > coverage-report.txt
check-coverage : clean-gcov all check coverage-report.txt
cat coverage-report.txt
else
coverage-report.txt:
@echo "Need to reconfigure with --enable-gcov"
check-coverage:
@echo "Need to reconfigure with --enable-gcov"
endif
else
TESTS=
endif
## we use noinst_PROGRAMS not check_PROGRAMS so that we build
## even when not doing "make check"
noinst_PROGRAMS=$(TESTS)
polkit_test_SOURCES= \
polkit-test.h polkit-test.c
polkit_test_LDADD=$(top_builddir)/polkit/libpolkit.la
polkit_test_LDFLAGS=
#@R_DYNAMIC_LDFLAG@
clean-local :
rm -f *~ $(BUILT_SOURCES)
rm -f *~ $(BUILT_SOURCES) *.bb *.bbg *.da *.gcov .libs/*.da .libs/*.bbg
if POLKIT_AUTHDB_DEFAULT
# The directories /var/lib/PolicyKit and /var/run/PolicyKit is where
......
......@@ -40,6 +40,7 @@
#include "polkit-debug.h"
#include "polkit-action.h"
#include "polkit-utils.h"
#include <polkit/polkit-test.h>
/**
* SECTION:polkit-action
......@@ -130,7 +131,7 @@ polkit_bool_t
polkit_action_set_action_id (PolKitAction *action, const char *action_id)
{
g_return_val_if_fail (action != NULL, FALSE);
g_return_val_if_fail (_pk_validate_identifier (action_id), FALSE);
g_return_val_if_fail (polkit_action_validate_id (action_id), FALSE);
if (action->id != NULL)
g_free (action->id);
action->id = g_strdup (action_id);
......@@ -176,7 +177,9 @@ polkit_action_debug (PolKitAction *action)
*
* Validate whether an action identifier is well formed. To be well
* formed, an action identifier needs to start with a lower case ASCII
* character and can only contain the characters "[a-z][0-9].-".
* character and can only contain the characters "[a-z][0-9].-". It
* must be less than or equal 256 bytes in length including the
* terminating NUL character.
*
* Returns: #TRUE iff the action identifier is well formed
**/
......@@ -192,6 +195,9 @@ polkit_action_validate_id (const char *action_id)
goto malformed;
for (n = 1; action_id[n] != '\0'; n++) {
if (n >= 255)
goto malformed;
if (! (g_ascii_islower (action_id[n]) ||
g_ascii_isdigit (action_id[n]) ||
action_id[n] == '.' ||
......@@ -224,3 +230,34 @@ polkit_action_validate (PolKitAction *action)
#ifdef POLKIT_BUILD_TESTS
polkit_bool_t
_test_polkit_action (void)
{
int n;
char *valid_action_ids[] = {"org.example.action",
"org.example.action-foo",
"org.example.action-foo.42",
"org.example.42-.foo",
"t0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd",
NULL};
char *invalid_action_ids[] = {"1org.example.action",
".org.example.action",
"-org.example.action",
"org.example.action_foo",
"org.example.something.that.is.too.long.0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
NULL};
for (n = 0; valid_action_ids[n] != NULL; n++) {
g_assert (polkit_action_validate_id (valid_action_ids[n]));
}
for (n = 0; invalid_action_ids[n] != NULL; n++) {
g_assert (! polkit_action_validate_id (invalid_action_ids[n]));
}
return TRUE;
}
#endif /* POLKIT_BUILD_TESTS */
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
/***************************************************************************
*
* polkit-test.c : PolicyKit test
*
* Copyright (C) 2007 David Zeuthen, <david@fubar.dk>
*
* Licensed under the Academic Free License version 2.1
*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
**************************************************************************/
#include <polkit/polkit-test.h>
int
main (int argc, char *argv[])
{
int ret;
ret = 1;
printf ("Running unit tests for libpolkit\n");
if (!_test_polkit_action ())
goto out;
ret = 0;
out:
return ret;
}
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
/***************************************************************************
*
* polkit-test.h : PolicyKit test
*
* Copyright (C) 2007 David Zeuthen, <david@fubar.dk>
*
* Licensed under the Academic Free License version 2.1
*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
**************************************************************************/
#if !defined (POLKIT_COMPILATION)
#error "polkit-test.h is a private file"
#endif
#ifndef POLKIT_TEST_H
#define POLKIT_TEST_H
#include <polkit/polkit-types.h>
POLKIT_BEGIN_DECLS
#endif /* POLKIT_BUILD_TESTS */
#ifdef POLKIT_BUILD_TESTS
polkit_bool_t _test_polkit_action (void);
POLKIT_END_DECLS
#endif /* POLKIT_TEST_H */
EXTRA_DIST = create-coverage-report.sh
clean-local :
rm -f *~
#!/bin/sh
TOTAL_ACTUAL=0
TOTAL_COVERED=0
TOTAL_SOURCE=0
MODULE=$1
shift
echo "=============================================================================="
echo "Test coverage for module $MODULE:"
echo "=============================================================================="
while [ $# -gt 0 ] ; do
gcov $1 -o .libs/ > /dev/null
SOURCE=`cat $1 |wc -l`
ACTUAL=`grep -v " -:" $1.gcov |wc -l`
NOT_COVERED=`grep " #####:" $1.gcov |wc -l`
COVERED=$(($ACTUAL - $NOT_COVERED))
PERCENT=$((100 * $COVERED / $ACTUAL))
TOTAL_SOURCE=$(($TOTAL_SOURCE + $SOURCE))
TOTAL_ACTUAL=$(($TOTAL_ACTUAL + $ACTUAL))
TOTAL_COVERED=$(($TOTAL_COVERED + $COVERED))
echo -n "$1"
n=${#1}
while [ $n -lt 55 ] ; do
echo -n " "
n=$(($n + 1))
done
echo -n " : "
if [ $PERCENT -lt 10 ] ; then
echo -n " $PERCENT%"
elif [ $PERCENT -lt 100 ] ; then
echo -n " $PERCENT%"
else
echo -n "100%"
fi
echo " ($COVERED of $ACTUAL)"
shift
done
TOTAL_PERCENT=$((100 * $TOTAL_COVERED / $TOTAL_ACTUAL))
echo
echo "Source lines : $TOTAL_SOURCE"
echo "Actual statements : $TOTAL_ACTUAL"
echo "Executed statements : $TOTAL_COVERED"
echo "Test coverage : $TOTAL_PERCENT%"
echo
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment