Skip to content

Commit

Permalink
GUACAMOLE-662: Migrate tests to test runners generated by new conveni…
Browse files Browse the repository at this point in the history
…ence script. Remove unnecessary test runners.
  • Loading branch information
mike-jumper committed Nov 18, 2018
1 parent 877bf59 commit 476b431
Show file tree
Hide file tree
Showing 39 changed files with 1,311 additions and 1,189 deletions.
15 changes: 2 additions & 13 deletions .gitignore
Expand Up @@ -28,27 +28,16 @@ Makefile
Makefile.in
aclocal.m4
autom4te.cache/
build-aux/
libtool
m4/*
!README
compile
config.guess
config.h
config.h.in
config.log
config.status
config.sub
configure
depcomp
install-sh
libtool
ltmain.sh
missing
stamp-h1
test-driver

# Test binaries
tests/test_*
!tests/test_*.[ch]

# Generated docs
doc/doxygen-output
Expand Down
6 changes: 2 additions & 4 deletions Makefile.am
Expand Up @@ -39,13 +39,11 @@ DIST_SUBDIRS = \
src/protocols/rdp \
src/protocols/ssh \
src/protocols/telnet \
src/protocols/vnc \
tests
src/protocols/vnc

SUBDIRS = \
src/libguac \
src/common \
tests
src/common

if ENABLE_COMMON_SSH
SUBDIRS += src/common-ssh
Expand Down
89 changes: 89 additions & 0 deletions README-unit-testing.md
@@ -0,0 +1,89 @@

Unit testing and guacamole-server
=================================

Unit tests within guacamole-server are implemented using the following:

* automake, which allows arbitrary tests to be declared within `Makefile.am`
and uses `make check` to run those tests.
* CUnit (libcunit), a unit testing framework.
* `util/generate-test-runner.pl`, a Perl script which generates a test runner
written in C which leverages CUnit, running the unit tests declared in each
of the given `.c` files. The generated test runner produces output in [TAP
format](https://testanything.org/) which is consumed by the TAP test driver
provided by automake.

Writing unit tests
------------------

All unit tests should be within reasonably-isolated C source files, with each
logical test having its own function of the form:

void test_SUITENAME__TESTNAME() {
...
}

where `TESTNAME` is the arbitrary name of the test and `SUITENAME` is the
arbitrary name of the test suite that this test belongs to.

**This naming convention is required by `generate-test-runner.pl`.** Absolutely
all tests MUST follow the above convention if they are to be picked up and
organized by the test runner generation script. Functions which are not tests
MUST NOT follow the above convention so that they are _not_ picked up mistakenly
by the test runner generator as if they were tests.

The `Makefile.am` for a subproject which contains such tests is typically
modified to contain a sections like the following:

#
# Unit tests for myproj
#

check_PROGRAMS = test_myproj
TESTS = $(check_PROGRAMS)

test_myproj_SOURCES = \
...all source files...

test_myproj_CFLAGS = \
-Werror -Wall -pedantic \
...other flags...

test_myproj_LDADD = \
...libraries...

#
# Autogenerate test runner
#

GEN_RUNNER = $(top_srcdir)/util/generate-test-runner.pl
CLEANFILES = _generated_runner.c

_generated_runner.c: $(test_myproj_SOURCES)
$(AM_V_GEN) $(GEN_RUNNER) $^ > $@

nodist_test_libguac_SOURCES = \
_generated_runner.c

# Use automake's TAP test driver for running any tests
LOG_DRIVER = \
env AM_TAP_AWK='$(AWK)' \
$(SHELL) $(top_srcdir)/build-aux/tap-driver.sh

The above declares ...

* ... that a binary, `test_myproj` should be built from the given sources.
Note that `test_myproj_SOURCES` contains only the source which was actually
written by hand while `nodist_test_myproj_SOURCES` contains only the source
which was generated by `generate-test-runner.pl`.
* ... that this `test_myproj` binary should be run to test this project when
`make check` is run, and that automake's TAP driver should be used to
consume its output.
* ... that the `_generated_runner.c` source file is generated dynamically
(through running `generate-test-runner.pl` on all non-generated test source)
and should not be distributed as part of the source archive.

With tests following the above naming convention in place, and with the
necessary changes made to the applicable `Makefile.am`, all tests will be
run automatically when `make check` is run.

7 changes: 6 additions & 1 deletion configure.ac
Expand Up @@ -19,6 +19,7 @@

AC_PREREQ([2.61])
AC_INIT([guacamole-server], [1.0.0])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
AM_SILENT_RULES([yes])

Expand All @@ -28,6 +29,9 @@ LT_INIT([dlopen])
AC_CONFIG_HEADER([config.h])
AC_CONFIG_MACRO_DIR([m4])

# Use TAP test driver for tests (part of automake)
AC_REQUIRE_AUX_FILE([tap-driver.sh])

# Programs
AC_PROG_CC
AC_PROG_CC_C99
Expand Down Expand Up @@ -1299,11 +1303,12 @@ AM_CONDITIONAL([ENABLE_GUACLOG], [test "x${enable_guaclog}" = "xyes"])

AC_CONFIG_FILES([Makefile
doc/Doxyfile
tests/Makefile
src/common/Makefile
src/common/tests/Makefile
src/common-ssh/Makefile
src/terminal/Makefile
src/libguac/Makefile
src/libguac/tests/Makefile
src/guacd/Makefile
src/guacd/man/guacd.8
src/guacd/man/guacd.conf.5
Expand Down
9 changes: 9 additions & 0 deletions src/common/.gitignore
@@ -0,0 +1,9 @@

# Auto-generated test runner and binary
_generated_runner.c
test_common

# Test suite output
*.log
*.trs

1 change: 1 addition & 0 deletions src/common/Makefile.am
Expand Up @@ -27,6 +27,7 @@ AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4

noinst_LTLIBRARIES = libguac_common.la
SUBDIRS = . tests

noinst_HEADERS = \
common/io.h \
Expand Down
72 changes: 72 additions & 0 deletions src/common/tests/Makefile.am
@@ -0,0 +1,72 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# NOTE: Parts of this file (Makefile.am) are automatically transcluded verbatim
# into Makefile.in. Though the build system (GNU Autotools) automatically adds
# its own license boilerplate to the generated Makefile.in, that boilerplate
# does not apply to the transcluded portions of Makefile.am which are licensed
# to you by the ASF under the Apache License, Version 2.0, as described above.
#

AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4

#
# Unit tests for libguac_common
#

check_PROGRAMS = test_common
TESTS = $(check_PROGRAMS)

test_common_SOURCES = \
iconv/convert.c \
rect/clip_and_split.c \
rect/constrain.c \
rect/expand_to_grid.c \
rect/extend.c \
rect/init.c \
rect/intersects.c \
string/count_occurrences.c \
string/split.c

test_common_CFLAGS = \
-Werror -Wall -pedantic \
@COMMON_INCLUDE@

test_common_LDADD = \
@COMMON_LTLIB@ \
@CUNIT_LIBS@

#
# Autogenerate test runner
#

GEN_RUNNER = $(top_srcdir)/util/generate-test-runner.pl
CLEANFILES = _generated_runner.c

_generated_runner.c: $(test_common_SOURCES)
$(AM_V_GEN) $(GEN_RUNNER) $^ > $@

nodist_test_common_SOURCES = \
_generated_runner.c

# Use automake's TAP test driver for running any tests
LOG_DRIVER = \
env AM_TAP_AWK='$(AWK)' \
$(SHELL) $(top_srcdir)/build-aux/tap-driver.sh

0 comments on commit 476b431

Please sign in to comment.