[gdm-list] automated unit testing in GDM
- From: Andrew Ziem <ahz001 gmail com>
- To: gdm-list <gdm-list gnome org>
- Subject: [gdm-list] automated unit testing in GDM
- Date: Mon, 26 Nov 2007 08:52:48 -0700
Hi,
Attached is a proposed patch (against the SVN trunk) to bring unit
testing and its benefits to GDM. Even though I otherwise prefer
CppUnit, I chose check against CppUnit simply because the CppUnit
requires a C++ compiler and check does not. Another attached patch
allow the initial tests to pass.
Accepting unit testing into GDM implies writing more tests, maintaining
the tests, fixing code to pass the tests, refactoring code into testable
pieces, documenting code, etc. At a glance, it appears GDM may be
already undergoing some of these changes.
In the future, it would be helpful to conditionally include check into
configure.ac, so that it is possible to run "./configure; make" without
check.
Andrew
Index: tests/checkgdm.c
===================================================================
--- tests/checkgdm.c (revision 0)
+++ tests/checkgdm.c (revision 0)
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Andrew Ziem
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors: Andrew Ziem
+ *
+ */
+
+
+#include <check.h>
+#include <glib-object.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "checkgdm.h"
+
+int
+main (int argc, char *argv[])
+{
+ SRunner *sr;
+ int i;
+ enum print_output print_mode = CK_NORMAL;
+
+
+ g_type_init();
+
+ int number_failed;
+ Suite *suite_gdm_address = gdm_address_suite ();
+ Suite *suite_gdm_common = gdm_common_suite ();
+ sr = srunner_create (suite_gdm_address);
+ srunner_add_suite (sr, suite_gdm_common);
+ for (i = 0; i < argc; i++)
+ {
+ if (0 == strncmp(argv[i], "--nofork", 9))
+ srunner_set_fork_status (sr, CK_NOFORK);
+ else if (0 == strncmp(argv[i], "--verbose", 10))
+ print_mode = CK_VERBOSE;
+ }
+ srunner_run_all (sr, print_mode);
+ number_failed = srunner_ntests_failed (sr);
+ srunner_free (sr);
+ return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
Index: tests/gdm-address-check.c
===================================================================
--- tests/gdm-address-check.c (revision 0)
+++ tests/gdm-address-check.c (revision 0)
@@ -0,0 +1,245 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Andrew Ziem
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors: Andrew Ziem
+ *
+ */
+
+#include "config.h"
+
+#include <check.h>
+#include <glib.h>
+#include <netinet/in.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "checkgdm.h"
+#include "gdm-address.h"
+
+
+GdmAddress *ga;
+GdmAddress *ga192;
+struct sockaddr sa;
+struct sockaddr_in *s_in;
+
+#ifdef ENABLE_IPV6
+GdmAddress *ga6;
+struct sockaddr_storage sa6;
+struct sockaddr_in6 *s_in6;
+#endif
+
+
+void setup (void);
+void teardown (void);
+
+
+void
+setup (void)
+{
+ s_in = (struct sockaddr_in *) &sa;
+ s_in->sin_family = AF_INET;
+ s_in->sin_port = htons(25);
+ s_in->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ fail_unless ( NULL != (ga = gdm_address_new_from_sockaddr(&sa, sizeof(sa))));
+
+ s_in->sin_addr.s_addr = htonl(0xc0a80001); /* 192.168.0.1 */
+ fail_unless ( NULL != (ga192 = gdm_address_new_from_sockaddr(&sa, sizeof(sa))));
+
+#ifdef ENABLE_IPV6
+ s_in6 = (struct sockaddr_in6 *) &sa6;
+ s_in6->sin6_family = AF_INET6;
+ s_in6->sin6_port = htons(25);
+ s_in6->sin6_addr = in6addr_loopback;
+ fail_unless ( NULL != (ga6 = gdm_address_new_from_sockaddr((struct sockaddr*)&sa6, sizeof(sa6))));
+#endif
+}
+
+void
+teardown (void)
+{
+ gdm_address_free (ga);
+ gdm_address_free (ga192);
+#ifdef ENABLE_IPV6
+ gdm_address_free (ga6);
+#endif
+}
+
+
+/*
+ * GType gdm_address_get_type (void);
+ */
+START_TEST (test_gdm_address_get_type)
+{
+ GType g;
+ g = gdm_address_get_type();
+ /* it did not crash! :) */
+
+}
+END_TEST
+
+
+/*
+GdmAddress * gdm_address_new_from_sockaddr (struct sockaddr *sa,
+ size_t size);
+*/
+START_TEST (test_gdm_address_new_from_sockaddr)
+{
+
+ GdmAddress *_ga;
+#ifdef ENABLE_IPV6
+ GdmAddress *_ga6;
+#endif
+
+ fail_unless ( NULL != (_ga = gdm_address_new_from_sockaddr((struct sockaddr *)&sa, sizeof(sa))) );
+ gdm_address_free (_ga);
+
+#ifdef ENABLE_IPV6
+ fail_unless ( NULL != (_ga6 = gdm_address_new_from_sockaddr((struct sockaddr *)&sa6, sizeof(sa6))) );
+ gdm_address_free (_ga6);
+#endif
+
+#ifndef NO_INVALID_INPUT
+ /* invalid input */
+ fail_unless ( NULL == gdm_address_new_from_sockaddr((struct sockaddr*)&sa, 1), NULL );
+ fail_unless ( NULL == gdm_address_new_from_sockaddr(NULL, 0), NULL);
+#endif
+}
+END_TEST
+
+/*
+int gdm_address_get_family_type (GdmAddress *address); */
+
+START_TEST (test_gdm_address_get_family_type)
+{
+ fail_unless ( AF_INET == gdm_address_get_family_type(ga), NULL);
+
+#ifdef ENABLE_IPV6
+ fail_unless ( AF_INET6 == gdm_address_get_family_type(ga6), NULL);
+#endif
+
+#ifndef NO_INVALID_INPUT
+ /* invalid input */
+ fail_unless ( -1 == gdm_address_get_family_type(NULL), NULL);
+#endif
+
+}
+END_TEST
+
+/*
+struct sockaddr_storage *gdm_address_get_sockaddr_storage (GdmAddress *address);
+struct sockaddr_storage *gdm_address_peek_sockaddr_storage (GdmAddress *address);
+
+gboolean gdm_address_get_hostname (GdmAddress *address,
+ char **hostname);
+gboolean gdm_address_get_numeric_info (GdmAddress *address,
+ char **numeric_hostname,
+ char **service);
+gboolean gdm_address_is_local (GdmAddress *address);
+*/
+
+/*
+ * gboolean gdm_address_is_loopback (GdmAddress *address);
+ */
+START_TEST (test_gdm_address_is_loopback)
+{
+ fail_unless( TRUE == gdm_address_is_loopback(ga));
+ fail_unless( FALSE == gdm_address_is_loopback(ga192));
+
+#ifdef ENABLE_IPV6
+ fail_unless( TRUE == gdm_address_is_loopback(ga6));
+ /* FIXME: add more addresses */
+#endif
+
+#ifndef NO_INVALID_INPUT
+ /* invalid input */
+ fail_unless( FALSE == gdm_address_is_loopback(NULL));
+#endif
+}
+END_TEST
+
+/*
+ * gboolean gdm_address_equal (GdmAddress *a,
+ * GdmAddress *b);
+ */
+START_TEST (test_gdm_address_equal)
+{
+ GdmAddress *gdm1;
+ struct sockaddr sa1;
+ struct sockaddr_in *sin1;
+
+ /* should be inequal */
+ sin1 = (struct sockaddr_in *) &sa1;
+ sin1->sin_family = AF_INET;
+ sin1->sin_addr.s_addr = htonl(0xc0a80001); /* 192.168.0.1 */
+ gdm1 = gdm_address_new_from_sockaddr(&sa1, sizeof(sa1));
+ fail_unless (gdm_address_equal (ga, ga192) == FALSE, NULL);
+
+ /* should be equal */
+ fail_unless (TRUE == gdm_address_equal (ga192, gdm1), NULL);
+
+ gdm_address_free(gdm1);
+
+#ifdef ENABLE_IPV6
+ /* should be inequal */
+ fail_unless (FALSE == gdm_address_equal (ga6, ga), NULL);
+ fail_unless (FALSE == gdm_address_equal (ga6, ga192), NULL);
+ fail_unless (FALSE == gdm_address_equal (ga6, gdm1), NULL);
+
+ /* should be equal */
+ /* FIXME: ipv6 version too */
+#endif
+
+#ifndef NO_INVALID_INPUT
+ /* invalid input */
+ fail_unless (FALSE == gdm_address_equal(NULL, NULL), NULL);
+ fail_unless (FALSE == gdm_address_equal(ga, NULL), NULL);
+ fail_unless (FALSE == gdm_address_equal(NULL, ga), NULL);
+#endif
+}
+
+
+END_TEST
+
+/*
+GdmAddress * gdm_address_copy (GdmAddress *address);
+void gdm_address_free (GdmAddress *address);
+
+
+void gdm_address_debug (GdmAddress *address);
+
+const GList * gdm_address_peek_local_list (void);
+*/
+
+
+Suite *
+gdm_address_suite (void)
+{
+ Suite *s = suite_create ("gdm-address");
+ TCase *tc_core = tcase_create ("core");
+ tcase_add_checked_fixture (tc_core, setup, teardown);
+ tcase_add_test (tc_core, test_gdm_address_get_type);
+ tcase_add_test (tc_core, test_gdm_address_new_from_sockaddr);
+ tcase_add_test (tc_core, test_gdm_address_get_family_type);
+ tcase_add_test (tc_core, test_gdm_address_is_loopback);
+ tcase_add_test (tc_core, test_gdm_address_equal);
+ suite_add_tcase(s, tc_core);
+
+ return s;
+}
+
Index: tests/Makefile.am
===================================================================
--- tests/Makefile.am (revision 0)
+++ tests/Makefile.am (revision 0)
@@ -0,0 +1,30 @@
+INCLUDES = \
+ -I. \
+ -I.. \
+ -I$(top_srcdir)/common \
+ $(COMMON_CFLAGS)
+
+noinst_PROGRAMS = \
+ checkgdm \
+ $(NULL)
+
+checkgdm_SOURCES = \
+ checkgdm.c \
+ gdm-address-check.c \
+ gdm-common-check.c \
+ $(NULL)
+
+checkgdm_CFLAGS = \
+ @CHECK_CFLAGS@ \
+ $(COMMON_CFLAGS) \
+ $(NULL)
+
+checkgdm_LDADD = \
+ @CHECK_LIBS@ \
+ $(COMMON_LIBS) \
+ gdm-address-check.o \
+ gdm-common-check.o \
+ $(NULL)
+
+TESTS = checkgdm
+
Index: tests/gdm-common-check.c
===================================================================
--- tests/gdm-common-check.c (revision 0)
+++ tests/gdm-common-check.c (revision 0)
@@ -0,0 +1,91 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Andrew Ziem
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors: Andrew Ziem
+ *
+ */
+
+
+#include <check.h>
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "checkgdm.h"
+#include "gdm-common.h"
+
+/*
+ * void gdm_set_fatal_warnings_if_unstable (void);
+ */
+
+/*
+int gdm_signal_pid (int pid,
+ int signal);
+*/
+
+/*
+gboolean gdm_string_hex_encode (const GString *source,
+ int start,
+ GString *dest,
+ int insert_at);
+*/
+START_TEST (test_gdm_string_hex_encode)
+{
+ GString *a, *b;
+
+ a = g_string_new("foo");
+ b = g_string_sized_new(100);
+ fail_unless ( TRUE == gdm_string_hex_encode(a, 0, b, 0), NULL);
+ fail_unless ( 0 == strncmp(b->str, "666f6f", 7), NULL);
+
+#ifndef NO_INVALID_INPUT
+ /* invalid input */
+ fail_unless ( FALSE == gdm_string_hex_encode(a, -1, b, -1), NULL);
+ fail_unless ( FALSE == gdm_string_hex_encode(NULL, 0, NULL, 0), NULL);
+ fail_unless ( FALSE == gdm_string_hex_encode(a, 0, a, 0), NULL);
+#endif
+
+ g_string_free(a, TRUE);
+ g_string_free(b, TRUE);
+}
+END_TEST
+
+/*
+gboolean gdm_string_hex_decode (const GString *source,
+ int start,
+ int *end_return,
+ GString *dest,
+ int insert_at);
+*/
+
+
+
+Suite *
+gdm_common_suite (void)
+{
+ Suite *s = suite_create ("gdm-common");
+ TCase *tc_core = tcase_create ("core");
+
+ tcase_add_test (tc_core, test_gdm_string_hex_encode);
+
+ suite_add_tcase(s, tc_core);
+
+ return s;
+}
+
+
Index: tests/checkgdm.h
===================================================================
--- tests/checkgdm.h (revision 0)
+++ tests/checkgdm.h (revision 0)
@@ -0,0 +1,33 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Andrew Ziem
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors: Andrew Ziem
+ *
+ */
+
+#ifndef __CHECKGDM_H
+#define __CHECKGDM_H
+
+#include <check.h>
+
+Suite * gdm_address_suite (void);
+Suite * gdm_common_suite (void);
+
+
+#endif
+
Index: configure.ac
===================================================================
--- configure.ac (revision 5522)
+++ configure.ac (working copy)
@@ -956,6 +956,11 @@
AC_MSG_RESULT(no)
fi
+# Unit testing framework called check
+#
+PKG_CHECK_MODULES([CHECK], [check >= 0.9.4])
+
+
# Check for Solaris logindevperm support
#
AC_MSG_CHECKING(for Solaris di_devperm_login)
@@ -1322,6 +1327,7 @@
data/pixmaps/48x48/Makefile
common/Makefile
po/Makefile.in
+tests/Makefile
])
dnl ---------------------------------------------------------------------------
Index: Makefile.am
===================================================================
--- Makefile.am (revision 5522)
+++ Makefile.am (working copy)
@@ -7,6 +7,7 @@
gui \
utils \
po \
+ tests \
$(NULL)
# add these when help gets added back
Index: common/gdm-address.c
===================================================================
--- common/gdm-address.c (revision 5522)
+++ common/gdm-address.c (working copy)
@@ -166,8 +166,10 @@
guint8 fam_a;
guint8 fam_b;
- g_return_val_if_fail (a != NULL || a->ss != NULL, FALSE);
- g_return_val_if_fail (b != NULL || b->ss != NULL, FALSE);
+ g_return_val_if_fail (a != NULL, FALSE);
+ g_return_val_if_fail (a->ss != NULL, FALSE);
+ g_return_val_if_fail (b != NULL, FALSE);
+ g_return_val_if_fail (b->ss != NULL, FALSE);
fam_a = a->ss->ss_family;
fam_b = b->ss->ss_family;
@@ -259,7 +261,8 @@
gboolean
gdm_address_is_loopback (GdmAddress *address)
{
- g_return_val_if_fail (address != NULL || address->ss != NULL, FALSE);
+ g_return_val_if_fail (address != NULL, FALSE);
+ g_return_val_if_fail (address->ss != NULL, FALSE);
switch (address->ss->ss_family){
#ifdef AF_INET6
Index: common/gdm-common.c
===================================================================
--- common/gdm-common.c (revision 5522)
+++ common/gdm-common.c (working copy)
@@ -119,6 +119,11 @@
const unsigned char *end;
gboolean retval;
+ g_return_val_if_fail (source != NULL, FALSE);
+ g_return_val_if_fail (dest != NULL, FALSE);
+ g_return_val_if_fail (source != dest, FALSE);
+ g_return_val_if_fail (start >= 0, FALSE);
+ g_return_val_if_fail (dest >= 0, FALSE);
g_assert (start <= source->len);
result = g_string_new (NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]