From 476b43104103fb61363f0e451e6553ebac45d157 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 13 Nov 2018 13:26:43 -0800 Subject: [PATCH] GUACAMOLE-662: Migrate tests to test runners generated by new convenience script. Remove unnecessary test runners. --- .gitignore | 15 +- Makefile.am | 6 +- README-unit-testing.md | 89 ++++++ configure.ac | 7 +- src/common/.gitignore | 9 + src/common/Makefile.am | 1 + src/common/tests/Makefile.am | 72 +++++ .../common/tests/iconv/convert.c | 175 +++++++---- src/common/tests/rect/clip_and_split.c | 156 ++++++++++ .../common/tests/rect/constrain.c | 36 +-- src/common/tests/rect/expand_to_grid.c | 71 +++++ .../common/tests/rect/extend.c | 43 +-- .../common/tests/rect/init.c | 21 +- src/common/tests/rect/intersects.c | 91 ++++++ .../common/tests/string/count_occurrences.c | 32 +- .../common/tests/string/split.c | 23 +- src/libguac/.gitignore | 44 +-- src/libguac/Makefile.am | 1 + {tests => src/libguac/tests}/Makefile.am | 62 ++-- .../libguac/tests}/client/buffer_pool.c | 19 +- .../libguac/tests}/client/layer_pool.c | 19 +- .../libguac/tests/parser/append.c | 15 +- src/libguac/tests/parser/read.c | 145 +++++++++ .../libguac/tests/pool/next_free.c | 31 +- .../libguac/tests}/protocol/base64_decode.c | 16 +- .../tests/socket/fd_send_instruction.c | 136 +++++++++ .../tests/socket/nested_send_instruction.c | 149 +++++++++ src/libguac/tests/unicode/charsize.c | 33 ++ src/libguac/tests/unicode/read.c | 52 ++++ .../libguac/tests/unicode/strlen.c | 48 +-- .../libguac/tests/unicode/write.c | 48 +-- tests/client/client_suite.c | 56 ---- tests/common/common_suite.c | 57 ---- tests/common/guac_rect.c | 289 ------------------ tests/protocol/instruction_read.c | 108 ------- tests/protocol/instruction_write.c | 101 ------ tests/protocol/nest_write.c | 109 ------- tests/protocol/suite.c | 59 ---- tests/util/util_suite.c | 56 ---- 39 files changed, 1311 insertions(+), 1189 deletions(-) create mode 100644 README-unit-testing.md create mode 100644 src/common/.gitignore create mode 100644 src/common/tests/Makefile.am rename tests/common/guac_iconv.c => src/common/tests/iconv/convert.c (52%) create mode 100644 src/common/tests/rect/clip_and_split.c rename tests/test_libguac.c => src/common/tests/rect/constrain.c (60%) create mode 100644 src/common/tests/rect/expand_to_grid.c rename tests/common/common_suite.h => src/common/tests/rect/extend.c (56%) rename tests/client/client_suite.h => src/common/tests/rect/init.c (68%) create mode 100644 src/common/tests/rect/intersects.c rename tests/protocol/suite.h => src/common/tests/string/count_occurrences.c (56%) rename tests/common/guac_string.c => src/common/tests/string/split.c (79%) rename {tests => src/libguac/tests}/Makefile.am (59%) rename {tests => src/libguac/tests}/client/buffer_pool.c (84%) rename {tests => src/libguac/tests}/client/layer_pool.c (84%) rename tests/protocol/instruction_parse.c => src/libguac/tests/parser/append.c (89%) create mode 100644 src/libguac/tests/parser/read.c rename tests/util/guac_pool.c => src/libguac/tests/pool/next_free.c (78%) rename {tests => src/libguac/tests}/protocol/base64_decode.c (90%) create mode 100644 src/libguac/tests/socket/fd_send_instruction.c create mode 100644 src/libguac/tests/socket/nested_send_instruction.c create mode 100644 src/libguac/tests/unicode/charsize.c create mode 100644 src/libguac/tests/unicode/read.c rename tests/util/util_suite.h => src/libguac/tests/unicode/strlen.c (55%) rename tests/util/guac_unicode.c => src/libguac/tests/unicode/write.c (50%) delete mode 100644 tests/client/client_suite.c delete mode 100644 tests/common/common_suite.c delete mode 100644 tests/common/guac_rect.c delete mode 100644 tests/protocol/instruction_read.c delete mode 100644 tests/protocol/instruction_write.c delete mode 100644 tests/protocol/nest_write.c delete mode 100644 tests/protocol/suite.c delete mode 100644 tests/util/util_suite.c diff --git a/.gitignore b/.gitignore index dec0cd10..e0a6d53e 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/Makefile.am b/Makefile.am index cbfea857..c75735c1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/README-unit-testing.md b/README-unit-testing.md new file mode 100644 index 00000000..5bed8721 --- /dev/null +++ b/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. + diff --git a/configure.ac b/configure.ac index 672d19eb..b63ed690 100644 --- a/configure.ac +++ b/configure.ac @@ -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]) @@ -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 @@ -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 diff --git a/src/common/.gitignore b/src/common/.gitignore new file mode 100644 index 00000000..f7efbda8 --- /dev/null +++ b/src/common/.gitignore @@ -0,0 +1,9 @@ + +# Auto-generated test runner and binary +_generated_runner.c +test_common + +# Test suite output +*.log +*.trs + diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 06190103..f98054be 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -27,6 +27,7 @@ AUTOMAKE_OPTIONS = foreign ACLOCAL_AMFLAGS = -I m4 noinst_LTLIBRARIES = libguac_common.la +SUBDIRS = . tests noinst_HEADERS = \ common/io.h \ diff --git a/src/common/tests/Makefile.am b/src/common/tests/Makefile.am new file mode 100644 index 00000000..8169d7d7 --- /dev/null +++ b/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 + diff --git a/tests/common/guac_iconv.c b/src/common/tests/iconv/convert.c similarity index 52% rename from tests/common/guac_iconv.c rename to src/common/tests/iconv/convert.c index 6af706f9..1a00994f 100644 --- a/tests/common/guac_iconv.c +++ b/src/common/tests/iconv/convert.c @@ -17,15 +17,75 @@ * under the License. */ -#include "config.h" - -#include "common_suite.h" #include "common/iconv.h" -#include -#include +#include -static void test_conversion( +/** + * UTF8 for "papà è bello". + */ +unsigned char test_string_utf8[] = { + 'p', 'a', 'p', 0xC3, 0xA0, ' ', + 0xC3, 0xA8, ' ', + 'b', 'e', 'l', 'l', 'o', + 0x00 +}; + +/** + * UTF16 for "papà è bello". + */ +unsigned char test_string_utf16[] = { + 'p', 0x00, 'a', 0x00, 'p', 0x00, 0xE0, 0x00, ' ', 0x00, + 0xE8, 0x00, ' ', 0x00, + 'b', 0x00, 'e', 0x00, 'l', 0x00, 'l', 0x00, 'o', 0x00, + 0x00, 0x00 +}; + +/** + * ISO-8859-1 for "papà è bello". + */ +unsigned char test_string_iso8859_1[] = { + 'p', 'a', 'p', 0xE0, ' ', + 0xE8, ' ', + 'b', 'e', 'l', 'l', 'o', + 0x00 +}; + +/** + * CP1252 for "papà è bello". + */ +unsigned char test_string_cp1252[] = { + 'p', 'a', 'p', 0xE0, ' ', + 0xE8, ' ', + 'b', 'e', 'l', 'l', 'o', + 0x00 +}; + +/** + * Tests that conversion between character sets using the given guac_iconv_read + * and guac_iconv_write implementations matches expectations. + * + * @param reader + * The guac_iconv_read implementation to use to read the input string. + * + * @param in_string + * A pointer to the beginning of the input string. + * + * @param in_length + * The size of the input string in bytes. + * + * @param writer + * The guac_iconv_write implementation to use to write the output string + * (the converted input string). + * + * @param out_string + * A pointer to the beginning of a string which contains the expected + * result of the conversion. + * + * @param out_length + * The size of the expected result in bytes. + */ +static void verify_conversion( guac_iconv_read* reader, unsigned char* in_string, int in_length, guac_iconv_write* writer, unsigned char* out_string, int out_length) { @@ -50,77 +110,74 @@ static void test_conversion( } -void test_guac_iconv() { - - /* UTF8 for "papà è bello" */ - unsigned char test_string_utf8[] = { - 'p', 'a', 'p', 0xC3, 0xA0, ' ', - 0xC3, 0xA8, ' ', - 'b', 'e', 'l', 'l', 'o', - 0x00 - }; - - /* UTF16 for "papà è bello" */ - unsigned char test_string_utf16[] = { - 'p', 0x00, 'a', 0x00, 'p', 0x00, 0xE0, 0x00, ' ', 0x00, - 0xE8, 0x00, ' ', 0x00, - 'b', 0x00, 'e', 0x00, 'l', 0x00, 'l', 0x00, 'o', 0x00, - 0x00, 0x00 - }; - - /* ISO-8859-1 for "papà è bello" */ - unsigned char test_string_iso8859_1[] = { - 'p', 'a', 'p', 0xE0, ' ', - 0xE8, ' ', - 'b', 'e', 'l', 'l', 'o', - 0x00 - }; - - /* CP1252 for "papà è bello" */ - unsigned char test_string_cp1252[] = { - 'p', 'a', 'p', 0xE0, ' ', - 0xE8, ' ', - 'b', 'e', 'l', 'l', 'o', - 0x00 - }; - - /* UTF8 identity */ - test_conversion( +/** + * Tests which verifies conversion of UTF-8 to itself. + */ +void test_iconv__utf8_to_utf8() { + verify_conversion( GUAC_READ_UTF8, test_string_utf8, sizeof(test_string_utf8), GUAC_WRITE_UTF8, test_string_utf8, sizeof(test_string_utf8)); +} - /* UTF16 identity */ - test_conversion( - GUAC_READ_UTF16, test_string_utf16, sizeof(test_string_utf16), - GUAC_WRITE_UTF16, test_string_utf16, sizeof(test_string_utf16)); - - /* UTF8 to UTF16 */ - test_conversion( +/** + * Tests which verifies conversion of UTF-16 to UTF-8. + */ +void test_iconv__utf8_to_utf16() { + verify_conversion( GUAC_READ_UTF8, test_string_utf8, sizeof(test_string_utf8), GUAC_WRITE_UTF16, test_string_utf16, sizeof(test_string_utf16)); +} - /* UTF16 to UTF8 */ - test_conversion( +/** + * Tests which verifies conversion of UTF-16 to itself. + */ +void test_iconv__utf16_to_utf16() { + verify_conversion( + GUAC_READ_UTF16, test_string_utf16, sizeof(test_string_utf16), + GUAC_WRITE_UTF16, test_string_utf16, sizeof(test_string_utf16)); +} + +/** + * Tests which verifies conversion of UTF-8 to UTF-16. + */ +void test_iconv__utf16_to_utf8() { + verify_conversion( GUAC_READ_UTF16, test_string_utf16, sizeof(test_string_utf16), GUAC_WRITE_UTF8, test_string_utf8, sizeof(test_string_utf8)); +} - /* UTF16 to ISO-8859-1 */ - test_conversion( +/** + * Tests which verifies conversion of UTF-16 to ISO 8859-1. + */ +void test_iconv__utf16_to_iso8859_1() { + verify_conversion( GUAC_READ_UTF16, test_string_utf16, sizeof(test_string_utf16), GUAC_WRITE_ISO8859_1, test_string_iso8859_1, sizeof(test_string_iso8859_1)); +} - /* UTF16 to CP1252 */ - test_conversion( +/** + * Tests which verifies conversion of UTF-16 to CP1252. + */ +void test_iconv__utf16_to_cp1252() { + verify_conversion( GUAC_READ_UTF16, test_string_utf16, sizeof(test_string_utf16), GUAC_WRITE_CP1252, test_string_cp1252, sizeof(test_string_cp1252)); +} - /* CP1252 to UTF8 */ - test_conversion( +/** + * Tests which verifies conversion of CP1252 to UTF-8. + */ +void test_iconv__cp1252_to_utf8() { + verify_conversion( GUAC_READ_CP1252, test_string_cp1252, sizeof(test_string_cp1252), GUAC_WRITE_UTF8, test_string_utf8, sizeof(test_string_utf8)); +} - /* ISO-8859-1 to UTF8 */ - test_conversion( +/** + * Tests which verifies conversion of ISO 8859-1 to UTF-8. + */ +void test_iconv__iso8859_1_to_utf8() { + verify_conversion( GUAC_READ_ISO8859_1, test_string_iso8859_1, sizeof(test_string_iso8859_1), GUAC_WRITE_UTF8, test_string_utf8, sizeof(test_string_utf8)); diff --git a/src/common/tests/rect/clip_and_split.c b/src/common/tests/rect/clip_and_split.c new file mode 100644 index 00000000..e286bce9 --- /dev/null +++ b/src/common/tests/rect/clip_and_split.c @@ -0,0 +1,156 @@ +/* + * 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. + */ + +#include "common/rect.h" + +#include + +/** + * Test which verifies that guac_common_rect_clip_and_split() divides a + * rectangle into subrectangles after removing a "hole" rectangle. + */ +void test_rect__clip_and_split() { + + int res; + + guac_common_rect cut; + guac_common_rect min; + guac_common_rect rect; + + guac_common_rect_init(&min, 10, 10, 10, 10); + + /* Clip top */ + guac_common_rect_init(&rect, 10, 5, 10, 10); + res = guac_common_rect_clip_and_split(&rect, &min, &cut); + CU_ASSERT_EQUAL(1, res); + CU_ASSERT_EQUAL(10, cut.x); + CU_ASSERT_EQUAL(5, cut.y); + CU_ASSERT_EQUAL(10, cut.width); + CU_ASSERT_EQUAL(5, cut.height); + + CU_ASSERT_EQUAL(10, rect.x); + CU_ASSERT_EQUAL(10, rect.y); + CU_ASSERT_EQUAL(10, rect.width); + CU_ASSERT_EQUAL(5, rect.height); + + /* Clip bottom */ + guac_common_rect_init(&rect, 10, 15, 10, 10); + res = guac_common_rect_clip_and_split(&rect, &min, &cut); + CU_ASSERT_EQUAL(1, res); + CU_ASSERT_EQUAL(10, cut.x); + CU_ASSERT_EQUAL(20, cut.y); + CU_ASSERT_EQUAL(10, cut.width); + CU_ASSERT_EQUAL(5, cut.height); + + CU_ASSERT_EQUAL(10, rect.x); + CU_ASSERT_EQUAL(15, rect.y); + CU_ASSERT_EQUAL(10, rect.width); + CU_ASSERT_EQUAL(5, rect.height); + + /* Clip left */ + guac_common_rect_init(&rect, 5, 10, 10, 10); + res = guac_common_rect_clip_and_split(&rect, &min, &cut); + CU_ASSERT_EQUAL(1, res); + CU_ASSERT_EQUAL(5, cut.x); + CU_ASSERT_EQUAL(10, cut.y); + CU_ASSERT_EQUAL(5, cut.width); + CU_ASSERT_EQUAL(10, cut.height); + + CU_ASSERT_EQUAL(10, rect.x); + CU_ASSERT_EQUAL(10, rect.y); + CU_ASSERT_EQUAL(5, rect.width); + CU_ASSERT_EQUAL(10, rect.height); + + /* Clip right */ + guac_common_rect_init(&rect, 15, 10, 10, 10); + res = guac_common_rect_clip_and_split(&rect, &min, &cut); + CU_ASSERT_EQUAL(1, res); + CU_ASSERT_EQUAL(20, cut.x); + CU_ASSERT_EQUAL(10, cut.y); + CU_ASSERT_EQUAL(5, cut.width); + CU_ASSERT_EQUAL(10, cut.height); + + CU_ASSERT_EQUAL(15, rect.x); + CU_ASSERT_EQUAL(10, rect.y); + CU_ASSERT_EQUAL(5, rect.width); + CU_ASSERT_EQUAL(10, rect.height); + + /* + * Test a rectangle which completely covers the hole. + * Clip and split until done. + */ + guac_common_rect_init(&rect, 5, 5, 20, 20); + + /* Clip top */ + res = guac_common_rect_clip_and_split(&rect, &min, &cut); + CU_ASSERT_EQUAL(1, res); + CU_ASSERT_EQUAL(5, cut.x); + CU_ASSERT_EQUAL(5, cut.y); + CU_ASSERT_EQUAL(20, cut.width); + CU_ASSERT_EQUAL(5, cut.height); + + CU_ASSERT_EQUAL(5, rect.x); + CU_ASSERT_EQUAL(10, rect.y); + CU_ASSERT_EQUAL(20, rect.width); + CU_ASSERT_EQUAL(15, rect.height); + + /* Clip left */ + res = guac_common_rect_clip_and_split(&rect, &min, &cut); + CU_ASSERT_EQUAL(1, res); + CU_ASSERT_EQUAL(5, cut.x); + CU_ASSERT_EQUAL(10, cut.y); + CU_ASSERT_EQUAL(5, cut.width); + CU_ASSERT_EQUAL(15, cut.height); + + CU_ASSERT_EQUAL(10, rect.x); + CU_ASSERT_EQUAL(10, rect.y); + CU_ASSERT_EQUAL(15, rect.width); + CU_ASSERT_EQUAL(15, rect.height); + + /* Clip bottom */ + res = guac_common_rect_clip_and_split(&rect, &min, &cut); + CU_ASSERT_EQUAL(1, res); + CU_ASSERT_EQUAL(10, cut.x); + CU_ASSERT_EQUAL(20, cut.y); + CU_ASSERT_EQUAL(15, cut.width); + CU_ASSERT_EQUAL(5, cut.height); + + CU_ASSERT_EQUAL(10, rect.x); + CU_ASSERT_EQUAL(10, rect.y); + CU_ASSERT_EQUAL(15, rect.width); + CU_ASSERT_EQUAL(10, rect.height); + + /* Clip right */ + res = guac_common_rect_clip_and_split(&rect, &min, &cut); + CU_ASSERT_EQUAL(20, cut.x); + CU_ASSERT_EQUAL(10, cut.y); + CU_ASSERT_EQUAL(5, cut.width); + CU_ASSERT_EQUAL(10, cut.height); + + CU_ASSERT_EQUAL(10, rect.x); + CU_ASSERT_EQUAL(10, rect.y); + CU_ASSERT_EQUAL(10, rect.width); + CU_ASSERT_EQUAL(10, rect.height); + + /* Make sure nothing is left to do */ + res = guac_common_rect_clip_and_split(&rect, &min, &cut); + CU_ASSERT_EQUAL(0, res); + +} + diff --git a/tests/test_libguac.c b/src/common/tests/rect/constrain.c similarity index 60% rename from tests/test_libguac.c rename to src/common/tests/rect/constrain.c index 06223ce9..793aac22 100644 --- a/tests/test_libguac.c +++ b/src/common/tests/rect/constrain.c @@ -17,31 +17,27 @@ * under the License. */ -#include "config.h" +#include "common/rect.h" -#include "client/client_suite.h" -#include "common/common_suite.h" -#include "protocol/suite.h" -#include "util/util_suite.h" +#include -#include +/** + * Test which verifies that guac_common_rect_constrain() restricts a given + * rectangle to arbitrary bounds. + */ +void test_rect__constrain() { -int main() { + guac_common_rect max; + guac_common_rect rect; - /* Init registry */ - if (CU_initialize_registry() != CUE_SUCCESS) - return CU_get_error(); + guac_common_rect_init(&rect, -10, -10, 110, 110); + guac_common_rect_init(&max, 0, 0, 100, 100); + guac_common_rect_constrain(&rect, &max); - /* Register suites */ - register_protocol_suite(); - register_client_suite(); - register_util_suite(); - - /* Run tests */ - CU_basic_set_mode(CU_BRM_VERBOSE); - CU_basic_run_tests(); - CU_cleanup_registry(); - return CU_get_error(); + CU_ASSERT_EQUAL(0, rect.x); + CU_ASSERT_EQUAL(0, rect.y); + CU_ASSERT_EQUAL(100, rect.width); + CU_ASSERT_EQUAL(100, rect.height); } diff --git a/src/common/tests/rect/expand_to_grid.c b/src/common/tests/rect/expand_to_grid.c new file mode 100644 index 00000000..beef87d8 --- /dev/null +++ b/src/common/tests/rect/expand_to_grid.c @@ -0,0 +1,71 @@ +/* + * 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. + */ + +#include "common/rect.h" + +#include + +/** + * Test which verifies guac_common_rect_expand_to_grid() properly shifts and + * resizes rectangles to fit an NxN grid. + */ +void test_rect__expand_to_grid() { + + int cell_size = 16; + + guac_common_rect max; + guac_common_rect rect; + + /* Simple adjustment */ + guac_common_rect_init(&rect, 0, 0, 25, 25); + guac_common_rect_init(&max, 0, 0, 100, 100); + guac_common_rect_expand_to_grid(cell_size, &rect, &max); + CU_ASSERT_EQUAL(0, rect.x); + CU_ASSERT_EQUAL(0, rect.y); + CU_ASSERT_EQUAL(32, rect.width); + CU_ASSERT_EQUAL(32, rect.height); + + /* Adjustment with moving of rect */ + guac_common_rect_init(&rect, 75, 75, 25, 25); + guac_common_rect_init(&max, 0, 0, 100, 100); + guac_common_rect_expand_to_grid(cell_size, &rect, &max); + CU_ASSERT_EQUAL(max.width - 32, rect.x); + CU_ASSERT_EQUAL(max.height - 32, rect.y); + CU_ASSERT_EQUAL(32, rect.width); + CU_ASSERT_EQUAL(32, rect.height); + + guac_common_rect_init(&rect, -5, -5, 25, 25); + guac_common_rect_init(&max, 0, 0, 100, 100); + guac_common_rect_expand_to_grid(cell_size, &rect, &max); + CU_ASSERT_EQUAL(0, rect.x); + CU_ASSERT_EQUAL(0, rect.y); + CU_ASSERT_EQUAL(32, rect.width); + CU_ASSERT_EQUAL(32, rect.height); + + /* Adjustment with moving and clamping of rect */ + guac_common_rect_init(&rect, 0, 0, 25, 15); + guac_common_rect_init(&max, 0, 5, 32, 15); + guac_common_rect_expand_to_grid(cell_size, &rect, &max); + CU_ASSERT_EQUAL(max.x, rect.x); + CU_ASSERT_EQUAL(max.y, rect.y); + CU_ASSERT_EQUAL(max.width, rect.width); + CU_ASSERT_EQUAL(max.height, rect.height); + +} + diff --git a/tests/common/common_suite.h b/src/common/tests/rect/extend.c similarity index 56% rename from tests/common/common_suite.h rename to src/common/tests/rect/extend.c index 60dbe9ae..dc2a0e30 100644 --- a/tests/common/common_suite.h +++ b/src/common/tests/rect/extend.c @@ -17,39 +17,26 @@ * under the License. */ +#include "common/rect.h" -#ifndef _GUAC_TEST_COMMON_SUITE_H -#define _GUAC_TEST_COMMON_SUITE_H +#include /** - * Test suite containing unit tests for the "common" utility library included - * for the sake of simplifying guacamole-server development, but not included - * as part of libguac. - * - * @file common_suite.h + * Test which verifies that guac_common_rect_extend() expands the given + * rectangle as necessary to contain at least the given bounds. */ +void test_rect__extend() { -#include "config.h" + guac_common_rect max; + guac_common_rect rect; -/** - * Registers the common test suite with CUnit. - */ -int register_common_suite(); + guac_common_rect_init(&rect, 10, 10, 90, 90); + guac_common_rect_init(&max, 0, 0, 100, 100); + guac_common_rect_extend(&rect, &max); + CU_ASSERT_EQUAL(0, rect.x); + CU_ASSERT_EQUAL(0, rect.y); + CU_ASSERT_EQUAL(100, rect.width); + CU_ASSERT_EQUAL(100, rect.height); -/** - * Unit test for string utility functions. - */ -void test_guac_string(); - -/** - * Unit test for character conversion functions. - */ -void test_guac_iconv(); - -/** - * Unit test for rectangle calculation functions. - */ -void test_guac_rect(); - -#endif +} diff --git a/tests/client/client_suite.h b/src/common/tests/rect/init.c similarity index 68% rename from tests/client/client_suite.h rename to src/common/tests/rect/init.c index da1bc22b..288cd751 100644 --- a/tests/client/client_suite.h +++ b/src/common/tests/rect/init.c @@ -17,16 +17,23 @@ * under the License. */ +#include "common/rect.h" -#ifndef _GUAC_TEST_CLIENT_SUITE_H -#define _GUAC_TEST_CLIENT_SUITE_H +#include -#include "config.h" +/** + * Test which verifies rectangle initialization via guac_common_rect_init(). + */ +void test_rect__init() { -int register_client_suite(); + guac_common_rect max; -void test_layer_pool(); -void test_buffer_pool(); + guac_common_rect_init(&max, 0, 0, 100, 100); -#endif + CU_ASSERT_EQUAL(0, max.x); + CU_ASSERT_EQUAL(0, max.y); + CU_ASSERT_EQUAL(100, max.width); + CU_ASSERT_EQUAL(100, max.height); + +} diff --git a/src/common/tests/rect/intersects.c b/src/common/tests/rect/intersects.c new file mode 100644 index 00000000..c4802684 --- /dev/null +++ b/src/common/tests/rect/intersects.c @@ -0,0 +1,91 @@ +/* + * 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. + */ + +#include "common/rect.h" + +#include + +/** + * Test which verifies intersection testing via guac_common_rect_intersects(). + */ +void test_rect__intersects() { + + int res; + + guac_common_rect min; + guac_common_rect rect; + + guac_common_rect_init(&min, 10, 10, 10, 10); + + /* Rectangle intersection - empty + * rectangle is outside */ + guac_common_rect_init(&rect, 25, 25, 5, 5); + res = guac_common_rect_intersects(&rect, &min); + CU_ASSERT_EQUAL(0, res); + + /* Rectangle intersection - complete + * rectangle is completely inside */ + guac_common_rect_init(&rect, 11, 11, 5, 5); + res = guac_common_rect_intersects(&rect, &min); + CU_ASSERT_EQUAL(2, res); + + /* Rectangle intersection - partial + * rectangle intersects UL */ + guac_common_rect_init(&rect, 8, 8, 5, 5); + res = guac_common_rect_intersects(&rect, &min); + CU_ASSERT_EQUAL(1, res); + + /* Rectangle intersection - partial + * rectangle intersects LR */ + guac_common_rect_init(&rect, 18, 18, 5, 5); + res = guac_common_rect_intersects(&rect, &min); + CU_ASSERT_EQUAL(1, res); + + /* Rectangle intersection - complete + * rect intersects along UL but inside */ + guac_common_rect_init(&rect, 10, 10, 5, 5); + res = guac_common_rect_intersects(&rect, &min); + CU_ASSERT_EQUAL(2, res); + + /* Rectangle intersection - partial + * rectangle intersects along L but outside */ + guac_common_rect_init(&rect, 5, 10, 5, 5); + res = guac_common_rect_intersects(&rect, &min); + CU_ASSERT_EQUAL(1, res); + + /* Rectangle intersection - complete + * rectangle intersects along LR but rest is inside */ + guac_common_rect_init(&rect, 15, 15, 5, 5); + res = guac_common_rect_intersects(&rect, &min); + CU_ASSERT_EQUAL(2, res); + + /* Rectangle intersection - partial + * rectangle intersects along R but rest is outside */ + guac_common_rect_init(&rect, 20, 10, 5, 5); + res = guac_common_rect_intersects(&rect, &min); + CU_ASSERT_EQUAL(1, res); + + /* Rectangle intersection - partial + * rectangle encloses min; which is a partial intersection */ + guac_common_rect_init(&rect, 5, 5, 20, 20); + res = guac_common_rect_intersects(&rect, &min); + CU_ASSERT_EQUAL(1, res); + +} + diff --git a/tests/protocol/suite.h b/src/common/tests/string/count_occurrences.c similarity index 56% rename from tests/protocol/suite.h rename to src/common/tests/string/count_occurrences.c index 01345fac..0c7d01de 100644 --- a/tests/protocol/suite.h +++ b/src/common/tests/string/count_occurrences.c @@ -17,27 +17,17 @@ * under the License. */ +#include "common/string.h" -#ifndef _GUAC_TEST_PROTOCOL_SUITE_H -#define _GUAC_TEST_PROTOCOL_SUITE_H +#include -#include "config.h" - -/* Unicode (UTF-8) strings */ - -#define UTF8_1 "\xe7\x8a\xac" /* One character */ -#define UTF8_2 UTF8_1 "\xf0\x90\xac\x80" /* Two characters */ -#define UTF8_3 UTF8_2 "z" /* Three characters */ -#define UTF8_4 UTF8_3 "\xc3\xa1" /* Four characters */ -#define UTF8_8 UTF8_4 UTF8_4 /* Eight characters */ - -int register_protocol_suite(); - -void test_base64_decode(); -void test_instruction_parse(); -void test_instruction_read(); -void test_instruction_write(); -void test_nest_write(); - -#endif +/** + * Test which verifies that guac_count_occurrences() counts the number of + * occurrences of an arbitrary character within a given string. + */ +void test_string__guac_count_occurrences() { + CU_ASSERT_EQUAL(4, guac_count_occurrences("this is a test string", 's')); + CU_ASSERT_EQUAL(3, guac_count_occurrences("this is a test string", 'i')); + CU_ASSERT_EQUAL(0, guac_count_occurrences("", 's')); +} diff --git a/tests/common/guac_string.c b/src/common/tests/string/split.c similarity index 79% rename from tests/common/guac_string.c rename to src/common/tests/string/split.c index 543a41b8..36f8f191 100644 --- a/tests/common/guac_string.c +++ b/src/common/tests/string/split.c @@ -17,26 +17,20 @@ * under the License. */ -#include "config.h" - -#include "common_suite.h" #include "common/string.h" +#include + #include -#include -void test_guac_string() { - - char** tokens; - - /* Test occurrence counting */ - CU_ASSERT_EQUAL(4, guac_count_occurrences("this is a test string", 's')); - CU_ASSERT_EQUAL(3, guac_count_occurrences("this is a test string", 'i')); - CU_ASSERT_EQUAL(0, guac_count_occurrences("", 's')); +/** + * Test which verifies that guac_split() splits a string on occurrences of a + * given character. + */ +void test_string__split() { /* Split test string */ - tokens = guac_split("this is a test string", ' '); - + char** tokens = guac_split("this is a test string", ' '); CU_ASSERT_PTR_NOT_NULL(tokens); /* Check resulting tokens */ @@ -57,7 +51,6 @@ void test_guac_string() { CU_ASSERT_PTR_NULL(tokens[5]); - /* Clean up */ free(tokens[0]); free(tokens[1]); diff --git a/src/libguac/.gitignore b/src/libguac/.gitignore index 95b69b0d..ab580797 100644 --- a/src/libguac/.gitignore +++ b/src/libguac/.gitignore @@ -1,41 +1,9 @@ -# Object code -*.o -*.so -*.lo -*.la +# Auto-generated test runner and binary +_generated_runner.c +test_libguac -# gcov files -*.gcda -*.gcov -*.gcno - -# Backup files -*~ - -# Release files -*.tar.gz - -# Files currently being edited by vim or vi -*.swp - -# automake/autoconf -.deps/ -.libs/ -Makefile -Makefile.in -aclocal.m4 -autom4te.cache/ -m4/* -!README -config.guess -config.log -config.status -config.sub -configure -depcomp -install-sh -libtool -ltmain.sh -missing +# Test suite output +*.log +*.trs diff --git a/src/libguac/Makefile.am b/src/libguac/Makefile.am index d541df58..2757f706 100644 --- a/src/libguac/Makefile.am +++ b/src/libguac/Makefile.am @@ -27,6 +27,7 @@ AUTOMAKE_OPTIONS = foreign ACLOCAL_AMFLAGS = -I m4 lib_LTLIBRARIES = libguac.la +SUBDIRS = . tests libguacincdir = $(includedir)/guacamole diff --git a/tests/Makefile.am b/src/libguac/tests/Makefile.am similarity index 59% rename from tests/Makefile.am rename to src/libguac/tests/Makefile.am index fc1302e5..414a2f45 100644 --- a/tests/Makefile.am +++ b/src/libguac/tests/Makefile.am @@ -26,41 +26,51 @@ AUTOMAKE_OPTIONS = foreign ACLOCAL_AMFLAGS = -I m4 -TESTS = test_libguac +# +# Unit tests for libguac +# + check_PROGRAMS = test_libguac +TESTS = $(check_PROGRAMS) -noinst_HEADERS = \ - client/client_suite.h \ - common/common_suite.h \ - protocol/suite.h \ - util/util_suite.h +test_libguac_SOURCES = \ + client/buffer_pool.c \ + client/layer_pool.c \ + parser/append.c \ + parser/read.c \ + pool/next_free.c \ + protocol/base64_decode.c \ + socket/fd_send_instruction.c \ + socket/nested_send_instruction.c \ + unicode/charsize.c \ + unicode/read.c \ + unicode/strlen.c \ + unicode/write.c -test_libguac_SOURCES = \ - test_libguac.c \ - client/client_suite.c \ - client/buffer_pool.c \ - client/layer_pool.c \ - common/common_suite.c \ - common/guac_iconv.c \ - common/guac_string.c \ - common/guac_rect.c \ - protocol/suite.c \ - protocol/base64_decode.c \ - protocol/instruction_parse.c \ - protocol/instruction_read.c \ - protocol/instruction_write.c \ - protocol/nest_write.c \ - util/util_suite.c \ - util/guac_pool.c \ - util/guac_unicode.c test_libguac_CFLAGS = \ -Werror -Wall -pedantic \ - @COMMON_INCLUDE@ \ @LIBGUAC_INCLUDE@ test_libguac_LDADD = \ - @COMMON_LTLIB@ \ @CUNIT_LIBS@ \ @LIBGUAC_LTLIB@ +# +# Autogenerate test runner +# + +GEN_RUNNER = $(top_srcdir)/util/generate-test-runner.pl +CLEANFILES = _generated_runner.c + +_generated_runner.c: $(test_libguac_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 + diff --git a/tests/client/buffer_pool.c b/src/libguac/tests/client/buffer_pool.c similarity index 84% rename from tests/client/buffer_pool.c rename to src/libguac/tests/client/buffer_pool.c index df27f6ef..4f3b3c12 100644 --- a/tests/client/buffer_pool.c +++ b/src/libguac/tests/client/buffer_pool.c @@ -17,20 +17,23 @@ * under the License. */ -#include "config.h" - -#include "client_suite.h" - -#include +#include #include #include -void test_buffer_pool() { +#include + +/** + * Test which verifies that buffers can be allocated and freed using the pool + * of buffers available to each guac_client, and that doing so does not disturb + * the similar pool of layers. + */ +void test_client__buffer_pool() { guac_client* client; int i; - int seen[GUAC_BUFFER_POOL_INITIAL_SIZE] = {0}; + bool seen[GUAC_BUFFER_POOL_INITIAL_SIZE] = { 0 }; guac_layer* layer; @@ -53,7 +56,7 @@ void test_buffer_pool() { /* This should be a layer we have not seen yet */ CU_ASSERT_FALSE(seen[-layer->index - 1]); - seen[-layer->index - 1] = 1; + seen[-layer->index - 1] = true; guac_client_free_buffer(client, layer); diff --git a/tests/client/layer_pool.c b/src/libguac/tests/client/layer_pool.c similarity index 84% rename from tests/client/layer_pool.c rename to src/libguac/tests/client/layer_pool.c index 8b61c866..f82e84fb 100644 --- a/tests/client/layer_pool.c +++ b/src/libguac/tests/client/layer_pool.c @@ -17,20 +17,23 @@ * under the License. */ -#include "config.h" - -#include "client_suite.h" - -#include +#include #include #include -void test_layer_pool() { +#include + +/** + * Test which verifies that layers can be allocated and freed using the pool + * of layers available to each guac_client, and that doing so does not disturb + * the similar pool of buffers. + */ +void test_client__layer_pool() { guac_client* client; int i; - int seen[GUAC_BUFFER_POOL_INITIAL_SIZE] = {0}; + bool seen[GUAC_BUFFER_POOL_INITIAL_SIZE] = {0}; guac_layer* layer; @@ -53,7 +56,7 @@ void test_layer_pool() { /* This should be a layer we have not seen yet */ CU_ASSERT_FALSE(seen[layer->index - 1]); - seen[layer->index - 1] = 1; + seen[layer->index - 1] = true; guac_client_free_layer(client, layer); diff --git a/tests/protocol/instruction_parse.c b/src/libguac/tests/parser/append.c similarity index 89% rename from tests/protocol/instruction_parse.c rename to src/libguac/tests/parser/append.c index ec679854..88515c15 100644 --- a/tests/protocol/instruction_parse.c +++ b/src/libguac/tests/parser/append.c @@ -17,18 +17,18 @@ * under the License. */ -#include "config.h" - -#include "suite.h" +#include +#include #include #include #include -#include -#include - -void test_instruction_parse() { +/** + * Test which verifies that guac_parser correctly parses Guacamole instructions + * from arbitrary blocks of data passed to guac_parser_append(). + */ +void test_parser__append() { /* Allocate parser */ guac_parser* parser = guac_parser_alloc(); @@ -52,6 +52,7 @@ void test_instruction_parse() { } + /* Parse of instruction should be complete */ CU_ASSERT_EQUAL(remaining, 18); CU_ASSERT_EQUAL(parser->state, GUAC_PARSE_COMPLETE); diff --git a/src/libguac/tests/parser/read.c b/src/libguac/tests/parser/read.c new file mode 100644 index 00000000..e3b254c3 --- /dev/null +++ b/src/libguac/tests/parser/read.c @@ -0,0 +1,145 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include + +#include +#include + +/** + * Test string which contains exactly four Unicode characters encoded in UTF-8. + * This particular test string uses several characters which encode to multiple + * bytes in UTF-8. + */ +#define UTF8_4 "\xe7\x8a\xac\xf0\x90\xac\x80z\xc3\xa1" + +/** + * Writes a series of Guacamole instructions as raw bytes to the given file + * descriptor. The instructions written correspond to the instructions verified + * by read_expected_instructions(). The given file descriptor is automatically + * closed as a result of calling this function. + * + * @param fd + * The file descriptor to write instructions to. + */ +static void write_instructions(int fd) { + + char test_string[] = "4.test,6.a" UTF8_4 "b," + "5.12345,10.a" UTF8_4 UTF8_4 "c;" + "5.test2,10.hellohello,15.worldworldworld;"; + + char* current = test_string; + int remaining = sizeof(test_string) - 1; + + /* Write all bytes in test string */ + while (remaining > 0) { + + /* Bail out immediately if write fails (test will fail in parent + * process due to failure to read) */ + int written = write(fd, current, remaining); + if (written <= 0) + break; + + current += written; + remaining -= written; + + } + + /* Done writing */ + close(fd); + +} + +/** + * Reads and parses instructions from the given file descriptor using a + * guac_socket and guac_parser, verfying that those instructions match the + * series of Guacamole instructions expected to be written by + * write_instructions(). The given file descriptor is automatically closed as a + * result of calling this function. + * + * @param fd + * The file descriptor to read data from. + */ +static void read_expected_instructions(int fd) { + + /* Open guac socket */ + guac_socket* socket = guac_socket_open(fd); + CU_ASSERT_PTR_NOT_NULL_FATAL(socket); + + /* Allocate parser */ + guac_parser* parser = guac_parser_alloc(); + CU_ASSERT_PTR_NOT_NULL_FATAL(parser); + + /* Read and validate first instruction */ + CU_ASSERT_EQUAL_FATAL(guac_parser_read(parser, socket, 1000000), 0); + CU_ASSERT_STRING_EQUAL(parser->opcode, "test"); + CU_ASSERT_EQUAL_FATAL(parser->argc, 3); + CU_ASSERT_STRING_EQUAL(parser->argv[0], "a" UTF8_4 "b"); + CU_ASSERT_STRING_EQUAL(parser->argv[1], "12345"); + CU_ASSERT_STRING_EQUAL(parser->argv[2], "a" UTF8_4 UTF8_4 "c"); + + /* Read and validate second instruction */ + CU_ASSERT_EQUAL_FATAL(guac_parser_read(parser, socket, 1000000), 0); + CU_ASSERT_STRING_EQUAL(parser->opcode, "test2"); + CU_ASSERT_EQUAL_FATAL(parser->argc, 2); + CU_ASSERT_STRING_EQUAL(parser->argv[0], "hellohello"); + CU_ASSERT_STRING_EQUAL(parser->argv[1], "worldworldworld"); + + /* Done */ + guac_parser_free(parser); + guac_socket_free(socket); + +} + +/** + * Tests that guac_parser_read() correctly reads and parses instructions + * received over a guac_socket. A child process is forked to write a series of + * instructions which are read and verified by the parent process. + */ +void test_parser__read() { + + int fd[2]; + + /* Create pipe */ + CU_ASSERT_EQUAL_FATAL(pipe(fd), 0); + + int read_fd = fd[0]; + int write_fd = fd[1]; + + /* Fork into writer process (child) and reader process (parent) */ + int childpid; + CU_ASSERT_NOT_EQUAL_FATAL((childpid = fork()), -1); + + /* Attempt to write a series of instructions within the child process */ + if (childpid == 0) { + close(read_fd); + write_instructions(write_fd); + exit(0); + } + + /* Read and verify the expected instructions within the parent process */ + close(write_fd); + read_expected_instructions(read_fd); + +} + diff --git a/tests/util/guac_pool.c b/src/libguac/tests/pool/next_free.c similarity index 78% rename from tests/util/guac_pool.c rename to src/libguac/tests/pool/next_free.c index e24d8fc3..e8bd945e 100644 --- a/tests/util/guac_pool.c +++ b/src/libguac/tests/pool/next_free.c @@ -17,20 +17,21 @@ * under the License. */ -#include "config.h" - -#include "util_suite.h" - -#include +#include #include -#define UNSEEN 0 -#define SEEN_PHASE_1 1 -#define SEEN_PHASE_2 2 - +/** + * The number of unique integers to provide through the guac_pool instance + * being tested. + */ #define POOL_SIZE 128 -void test_guac_pool() { +/** + * Test which verifies that guac_pool provides access to a given number of + * unique integers, never repeating a retrieved integer until that integer + * is returned to the pool. + */ +void test_pool__next_free() { guac_pool* pool; @@ -53,8 +54,8 @@ void test_guac_pool() { CU_ASSERT_FATAL(value < POOL_SIZE); /* This should be an integer we have not seen yet */ - CU_ASSERT_EQUAL(UNSEEN, seen[value]); - seen[value] = SEEN_PHASE_1; + CU_ASSERT_EQUAL(0, seen[value]); + seen[value]++; /* Return value to pool */ guac_pool_free_int(pool, value); @@ -71,9 +72,9 @@ void test_guac_pool() { CU_ASSERT_FATAL(value >= 0); CU_ASSERT_FATAL(value < POOL_SIZE); - /* This should be an integer we have seen already */ - CU_ASSERT_EQUAL(SEEN_PHASE_1, seen[value]); - seen[value] = SEEN_PHASE_2; + /* This should be an integer we have seen only once */ + CU_ASSERT_EQUAL(1, seen[value]); + seen[value]++; } diff --git a/tests/protocol/base64_decode.c b/src/libguac/tests/protocol/base64_decode.c similarity index 90% rename from tests/protocol/base64_decode.c rename to src/libguac/tests/protocol/base64_decode.c index 9f8b7b7c..60c8a032 100644 --- a/tests/protocol/base64_decode.c +++ b/src/libguac/tests/protocol/base64_decode.c @@ -17,18 +17,14 @@ * under the License. */ -#include "config.h" - -#include "suite.h" - -#include -#include -#include - -#include +#include #include -void test_base64_decode() { +/** + * Tests that libguac's in-place base64 decoding function properly decodes + * valid base64 and fails for invalid base64. + */ +void test_protocol__decode_base64() { /* Test strings */ char test_HELLO[] = "SEVMTE8="; diff --git a/src/libguac/tests/socket/fd_send_instruction.c b/src/libguac/tests/socket/fd_send_instruction.c new file mode 100644 index 00000000..5a162d61 --- /dev/null +++ b/src/libguac/tests/socket/fd_send_instruction.c @@ -0,0 +1,136 @@ +/* + * 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. + */ + +#include +#include +#include + +#include +#include + +/** + * Test string which contains exactly four Unicode characters encoded in UTF-8. + * This particular test string uses several characters which encode to multiple + * bytes in UTF-8. + */ +#define UTF8_4 "\xe7\x8a\xac\xf0\x90\xac\x80z\xc3\xa1" + +/** + * Writes a series of Guacamole instructions using a normal guac_socket + * wrapping the given file descriptor. The instructions written correspond to + * the instructions verified by read_expected_instructions(). The given file + * descriptor is automatically closed as a result of calling this function. + * + * @param fd + * The file descriptor to write instructions to. + */ +static void write_instructions(int fd) { + + /* Open guac socket */ + guac_socket* socket = guac_socket_open(fd); + + /* Write nothing if socket cannot be allocated (test will fail in parent + * process due to failure to read) */ + if (socket == NULL) { + close(fd); + return; + } + + /* Write instructions */ + guac_protocol_send_name(socket, "a" UTF8_4 "b" UTF8_4 "c"); + guac_protocol_send_sync(socket, 12345); + guac_socket_flush(socket); + + /* Close and free socket */ + guac_socket_free(socket); + +} + +/** + * Reads raw bytes from the given file descriptor until no further bytes + * remain, verfying that those bytes represent the series of Guacamole + * instructions expected to be written by write_instructions(). The given + * file descriptor is automatically closed as a result of calling this + * function. + * + * @param fd + * The file descriptor to read data from. + */ +static void read_expected_instructions(int fd) { + + char expected[] = + "4.name,11.a" UTF8_4 "b" UTF8_4 "c;" + "4.sync,5.12345;"; + + int numread; + char buffer[1024]; + int offset = 0; + + /* Read everything available into buffer */ + while ((numread = read(fd, &(buffer[offset]), + sizeof(buffer) - offset)) > 0) { + offset += numread; + } + + /* Verify length of read data */ + CU_ASSERT_EQUAL(offset, strlen(expected)); + + /* Add NULL terminator */ + buffer[offset] = '\0'; + + /* Read value should be equal to expected value */ + CU_ASSERT_STRING_EQUAL(buffer, expected); + + /* File descriptor is no longer needed */ + close(fd); + +} + +/** + * Tests that the file descriptor implementation of guac_socket properly + * implements writing of instructions. A child process is forked to write a + * series of instructions which are read and verified by the parent process. + */ +void test_socket__fd_send_instruction() { + + int fd[2]; + + /* Create pipe */ + CU_ASSERT_EQUAL_FATAL(pipe(fd), 0); + + int read_fd = fd[0]; + int write_fd = fd[1]; + + /* Fork into writer process (child) and reader process (parent) */ + int childpid; + CU_ASSERT_NOT_EQUAL_FATAL((childpid = fork()), -1); + + /* Attempt to write a series of instructions within the child process */ + if (childpid == 0) { + close(read_fd); + write_instructions(write_fd); + exit(0); + } + + /* Read and verify the expected instructions within the parent process */ + close(write_fd); + read_expected_instructions(read_fd); + +} + diff --git a/src/libguac/tests/socket/nested_send_instruction.c b/src/libguac/tests/socket/nested_send_instruction.c new file mode 100644 index 00000000..db29e2b2 --- /dev/null +++ b/src/libguac/tests/socket/nested_send_instruction.c @@ -0,0 +1,149 @@ +/* + * 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. + */ + +#include +#include +#include + +#include +#include + +/** + * Test string which contains exactly four Unicode characters encoded in UTF-8. + * This particular test string uses several characters which encode to multiple + * bytes in UTF-8. + */ +#define UTF8_4 "\xe7\x8a\xac\xf0\x90\xac\x80z\xc3\xa1" + +/** + * Writes a series of Guacamole instructions using a nested guac_socket + * wrapping another guac_socket which writes to the given file descriptor. The + * instructions written correspond to the instructions verified by + * read_expected_instructions(). The given file descriptor is automatically + * closed as a result of calling this function. + * + * @param fd + * The file descriptor to write instructions to. + */ +static void write_instructions(int fd) { + + /* Open guac socket */ + guac_socket* socket = guac_socket_open(fd); + + /* Write nothing if socket cannot be allocated (test will fail in parent + * process due to failure to read) */ + if (socket == NULL) { + close(fd); + return; + } + + /* Nest socket */ + guac_socket* nested_socket = guac_socket_nest(socket, 123); + + /* Write nothing if nested socket cannot be allocated (test will fail in + * parent process due to failure to read) */ + if (socket == NULL) { + guac_socket_free(socket); + return; + } + + /* Write instructions */ + guac_protocol_send_name(nested_socket, "a" UTF8_4 "b" UTF8_4 "c"); + guac_protocol_send_sync(nested_socket, 12345); + + /* Close and free sockets */ + guac_socket_free(nested_socket); + guac_socket_free(socket); + +} + +/** + * Reads raw bytes from the given file descriptor until no further bytes + * remain, verfying that those bytes represent the series of Guacamole + * instructions expected to be written by write_instructions(). The given + * file descriptor is automatically closed as a result of calling this + * function. + * + * @param fd + * The file descriptor to read data from. + */ +static void read_expected_instructions(int fd) { + + char expected[] = + "4.nest,3.123,37." + "4.name,11.a" UTF8_4 "b" UTF8_4 "c;" + "4.sync,5.12345;" + ";"; + + int numread; + char buffer[1024]; + int offset = 0; + + /* Read everything available into buffer */ + while ((numread = read(fd, &(buffer[offset]), + sizeof(buffer) - offset)) > 0) { + offset += numread; + } + + /* Verify length of read data */ + CU_ASSERT_EQUAL(offset, strlen(expected)); + + /* Add NULL terminator */ + buffer[offset] = '\0'; + + /* Read value should be equal to expected value */ + CU_ASSERT_STRING_EQUAL(buffer, expected); + + /* File descriptor is no longer needed */ + close(fd); + +} + +/** + * Tests that the nested socket implementation of guac_socket properly + * implements writing of instructions. A child process is forked to write a + * series of instructions which are read and verified by the parent process. + */ +void test_socket__nested_send_instruction() { + + int fd[2]; + + /* Create pipe */ + CU_ASSERT_EQUAL_FATAL(pipe(fd), 0); + + int read_fd = fd[0]; + int write_fd = fd[1]; + + /* Fork into writer process (child) and reader process (parent) */ + int childpid; + CU_ASSERT_NOT_EQUAL_FATAL((childpid = fork()), -1); + + /* Attempt to write a series of instructions within the child process */ + if (childpid == 0) { + close(read_fd); + write_instructions(write_fd); + exit(0); + } + + /* Read and verify the expected instructions within the parent process */ + close(write_fd); + read_expected_instructions(read_fd); + +} + diff --git a/src/libguac/tests/unicode/charsize.c b/src/libguac/tests/unicode/charsize.c new file mode 100644 index 00000000..e636155f --- /dev/null +++ b/src/libguac/tests/unicode/charsize.c @@ -0,0 +1,33 @@ +/* + * 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. + */ + +#include +#include + +/** + * Test which verifies that guac_utf8_charsize() correctly determines the + * length of UTF-8 characters from the leading byte of that character. + */ +void test_unicode__utf8_charsize() { + CU_ASSERT_EQUAL(1, guac_utf8_charsize('g')); + CU_ASSERT_EQUAL(2, guac_utf8_charsize('\xC4')); + CU_ASSERT_EQUAL(3, guac_utf8_charsize('\xE7')); + CU_ASSERT_EQUAL(4, guac_utf8_charsize('\xF0')); +} + diff --git a/src/libguac/tests/unicode/read.c b/src/libguac/tests/unicode/read.c new file mode 100644 index 00000000..230a721c --- /dev/null +++ b/src/libguac/tests/unicode/read.c @@ -0,0 +1,52 @@ +/* + * 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. + */ + +#include +#include + +/** + * Test which verifies that guac_utf8_read() properly parses UTF-8. + */ +void test_unicode__utf8_read() { + + int codepoint; + + char buffer[16] = + /* U+0065 */ "\x65" + /* U+0654 */ "\xD9\x94" + /* U+0876 */ "\xE0\xA1\xB6" + /* U+12345 */ "\xF0\x92\x8D\x85"; + + CU_ASSERT_EQUAL(1, guac_utf8_read(&(buffer[0]), 10, &codepoint)); + CU_ASSERT_EQUAL(0x0065, codepoint); + + CU_ASSERT_EQUAL(2, guac_utf8_read(&(buffer[1]), 9, &codepoint)); + CU_ASSERT_EQUAL(0x0654, codepoint); + + CU_ASSERT_EQUAL(3, guac_utf8_read(&(buffer[3]), 7, &codepoint)); + CU_ASSERT_EQUAL(0x0876, codepoint); + + CU_ASSERT_EQUAL(4, guac_utf8_read(&(buffer[6]), 4, &codepoint)); + CU_ASSERT_EQUAL(0x12345, codepoint); + + CU_ASSERT_EQUAL(0, guac_utf8_read(&(buffer[10]), 0, &codepoint)); + CU_ASSERT_EQUAL(0x12345, codepoint); + +} + diff --git a/tests/util/util_suite.h b/src/libguac/tests/unicode/strlen.c similarity index 55% rename from tests/util/util_suite.h rename to src/libguac/tests/unicode/strlen.c index 3e3253b0..995a5038 100644 --- a/tests/util/util_suite.h +++ b/src/libguac/tests/unicode/strlen.c @@ -17,19 +17,8 @@ * under the License. */ - -#ifndef _GUAC_TEST_UTIL_SUITE_H -#define _GUAC_TEST_UTIL_SUITE_H - -/** - * Test suite containing unit tests for utility functions built into libguac. - * These utility functions are included for convenience rather as integral - * requirements of the core. - * - * @file util_suite.h - */ - -#include "config.h" +#include +#include /** * A single Unicode character encoded as one byte with UTF-8. @@ -52,24 +41,19 @@ #define UTF8_4b "\xf0\x90\x84\xa3" /** - * Registers the utility test suite with CUnit. + * Test which verifies that guac_utf8_strlen() properly calculates the length + * of UTF-8 strings. */ -int register_util_suite(); - -/** - * Unit test for the guac_pool structure and related functions. The guac_pool - * structure provides a consistent source of pooled integers. This unit test - * checks that the associated functions behave as documented (returning - * integers in the proper order, allocating new integers as necessary, etc.). - */ -void test_guac_pool(); - -/** - * Unit test for libguac's Unicode convenience functions. This test checks that - * the functions provided for determining string length, character length, and - * for reading and writing UTF-8 behave as specified in the documentation. - */ -void test_guac_unicode(); - -#endif +void test_unicode__utf8_strlen() { + CU_ASSERT_EQUAL(0, guac_utf8_strlen("")); + CU_ASSERT_EQUAL(1, guac_utf8_strlen(UTF8_4b)); + CU_ASSERT_EQUAL(2, guac_utf8_strlen(UTF8_4b UTF8_1b)); + CU_ASSERT_EQUAL(2, guac_utf8_strlen(UTF8_2b UTF8_3b)); + CU_ASSERT_EQUAL(3, guac_utf8_strlen(UTF8_1b UTF8_3b UTF8_4b)); + CU_ASSERT_EQUAL(3, guac_utf8_strlen(UTF8_2b UTF8_1b UTF8_3b)); + CU_ASSERT_EQUAL(3, guac_utf8_strlen(UTF8_4b UTF8_2b UTF8_1b)); + CU_ASSERT_EQUAL(3, guac_utf8_strlen(UTF8_3b UTF8_4b UTF8_2b)); + CU_ASSERT_EQUAL(5, guac_utf8_strlen("hello")); + CU_ASSERT_EQUAL(9, guac_utf8_strlen("guacamole")); +} diff --git a/tests/util/guac_unicode.c b/src/libguac/tests/unicode/write.c similarity index 50% rename from tests/util/guac_unicode.c rename to src/libguac/tests/unicode/write.c index 62f58876..8480086d 100644 --- a/tests/util/guac_unicode.c +++ b/src/libguac/tests/unicode/write.c @@ -17,36 +17,17 @@ * under the License. */ -#include "config.h" - -#include "util_suite.h" - -#include +#include #include -void test_guac_unicode() { +/** + * Test which verifies that guac_utf8_write() properly encodes Unicode + * codepoints as UTF-8. + */ +void test_unicode__utf8_write() { - int codepoint; char buffer[16]; - /* Test character length */ - CU_ASSERT_EQUAL(1, guac_utf8_charsize(UTF8_1b[0])); - CU_ASSERT_EQUAL(2, guac_utf8_charsize(UTF8_2b[0])); - CU_ASSERT_EQUAL(3, guac_utf8_charsize(UTF8_3b[0])); - CU_ASSERT_EQUAL(4, guac_utf8_charsize(UTF8_4b[0])); - - /* Test string length */ - CU_ASSERT_EQUAL(0, guac_utf8_strlen("")); - CU_ASSERT_EQUAL(1, guac_utf8_strlen(UTF8_4b)); - CU_ASSERT_EQUAL(2, guac_utf8_strlen(UTF8_4b UTF8_1b)); - CU_ASSERT_EQUAL(2, guac_utf8_strlen(UTF8_2b UTF8_3b)); - CU_ASSERT_EQUAL(3, guac_utf8_strlen(UTF8_1b UTF8_3b UTF8_4b)); - CU_ASSERT_EQUAL(3, guac_utf8_strlen(UTF8_2b UTF8_1b UTF8_3b)); - CU_ASSERT_EQUAL(3, guac_utf8_strlen(UTF8_4b UTF8_2b UTF8_1b)); - CU_ASSERT_EQUAL(3, guac_utf8_strlen(UTF8_3b UTF8_4b UTF8_2b)); - CU_ASSERT_EQUAL(5, guac_utf8_strlen("hello")); - CU_ASSERT_EQUAL(9, guac_utf8_strlen("guacamole")); - /* Test writes */ CU_ASSERT_EQUAL(1, guac_utf8_write(0x00065, &(buffer[0]), 10)); CU_ASSERT_EQUAL(2, guac_utf8_write(0x00654, &(buffer[1]), 9)); @@ -60,22 +41,5 @@ void test_guac_unicode() { CU_ASSERT(memcmp("\xE0\xA1\xB6", &(buffer[3]), 3) == 0); /* U+0876 */ CU_ASSERT(memcmp("\xF0\x92\x8D\x85", &(buffer[6]), 4) == 0); /* U+12345 */ - /* Test reads */ - - CU_ASSERT_EQUAL(1, guac_utf8_read(&(buffer[0]), 10, &codepoint)); - CU_ASSERT_EQUAL(0x0065, codepoint); - - CU_ASSERT_EQUAL(2, guac_utf8_read(&(buffer[1]), 9, &codepoint)); - CU_ASSERT_EQUAL(0x0654, codepoint); - - CU_ASSERT_EQUAL(3, guac_utf8_read(&(buffer[3]), 7, &codepoint)); - CU_ASSERT_EQUAL(0x0876, codepoint); - - CU_ASSERT_EQUAL(4, guac_utf8_read(&(buffer[6]), 4, &codepoint)); - CU_ASSERT_EQUAL(0x12345, codepoint); - - CU_ASSERT_EQUAL(0, guac_utf8_read(&(buffer[10]), 0, &codepoint)); - CU_ASSERT_EQUAL(0x12345, codepoint); - } diff --git a/tests/client/client_suite.c b/tests/client/client_suite.c deleted file mode 100644 index 18bba6bb..00000000 --- a/tests/client/client_suite.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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. - */ - -#include "config.h" - -#include "client_suite.h" - -#include - -int client_suite_init() { - return 0; -} - -int client_suite_cleanup() { - return 0; -} - -int register_client_suite() { - - /* Add client test suite */ - CU_pSuite suite = CU_add_suite("client", - client_suite_init, client_suite_cleanup); - if (suite == NULL) { - CU_cleanup_registry(); - return CU_get_error(); - } - - /* Add tests */ - if ( - CU_add_test(suite, "layer-pool", test_layer_pool) == NULL - || CU_add_test(suite, "buffer-pool", test_buffer_pool) == NULL - ) { - CU_cleanup_registry(); - return CU_get_error(); - } - - return 0; - -} - diff --git a/tests/common/common_suite.c b/tests/common/common_suite.c deleted file mode 100644 index 58ca7993..00000000 --- a/tests/common/common_suite.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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. - */ - -#include "config.h" - -#include "common_suite.h" - -#include - -int common_suite_init() { - return 0; -} - -int common_suite_cleanup() { - return 0; -} - -int register_common_suite() { - - /* Add common test suite */ - CU_pSuite suite = CU_add_suite("common", - common_suite_init, common_suite_cleanup); - if (suite == NULL) { - CU_cleanup_registry(); - return CU_get_error(); - } - - /* Add tests */ - if ( - CU_add_test(suite, "guac-iconv", test_guac_iconv) == NULL - || CU_add_test(suite, "guac-string", test_guac_string) == NULL - || CU_add_test(suite, "guac-rect", test_guac_rect) == NULL - ) { - CU_cleanup_registry(); - return CU_get_error(); - } - - return 0; - -} - diff --git a/tests/common/guac_rect.c b/tests/common/guac_rect.c deleted file mode 100644 index a45ee385..00000000 --- a/tests/common/guac_rect.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * 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. - */ - -#include "config.h" - -#include "common_suite.h" -#include "common/rect.h" - -#include -#include -#include - -void test_guac_rect() { - - guac_common_rect max; - - /* - * Test init method - */ - guac_common_rect_init(&max, 0, 0, 100, 100); - CU_ASSERT_EQUAL(0, max.x); - CU_ASSERT_EQUAL(0, max.y); - CU_ASSERT_EQUAL(100, max.width); - CU_ASSERT_EQUAL(100, max.height); - - /* - * Test constrain method - */ - guac_common_rect rect; - guac_common_rect_init(&rect, -10, -10, 110, 110); - guac_common_rect_init(&max, 0, 0, 100, 100); - guac_common_rect_constrain(&rect, &max); - CU_ASSERT_EQUAL(0, rect.x); - CU_ASSERT_EQUAL(0, rect.y); - CU_ASSERT_EQUAL(100, rect.width); - CU_ASSERT_EQUAL(100, rect.height); - - /* - * Test extend method - */ - guac_common_rect_init(&rect, 10, 10, 90, 90); - guac_common_rect_init(&max, 0, 0, 100, 100); - guac_common_rect_extend(&rect, &max); - CU_ASSERT_EQUAL(0, rect.x); - CU_ASSERT_EQUAL(0, rect.y); - CU_ASSERT_EQUAL(100, rect.width); - CU_ASSERT_EQUAL(100, rect.height); - - /* - * Test adjust method - */ - int cell_size = 16; - - /* Simple adjustment */ - guac_common_rect_init(&rect, 0, 0, 25, 25); - guac_common_rect_init(&max, 0, 0, 100, 100); - guac_common_rect_expand_to_grid(cell_size, &rect, &max); - CU_ASSERT_EQUAL(0, rect.x); - CU_ASSERT_EQUAL(0, rect.y); - CU_ASSERT_EQUAL(32, rect.width); - CU_ASSERT_EQUAL(32, rect.height); - - /* Adjustment with moving of rect */ - guac_common_rect_init(&rect, 75, 75, 25, 25); - guac_common_rect_init(&max, 0, 0, 100, 100); - guac_common_rect_expand_to_grid(cell_size, &rect, &max); - CU_ASSERT_EQUAL(max.width - 32, rect.x); - CU_ASSERT_EQUAL(max.height - 32, rect.y); - CU_ASSERT_EQUAL(32, rect.width); - CU_ASSERT_EQUAL(32, rect.height); - - guac_common_rect_init(&rect, -5, -5, 25, 25); - guac_common_rect_init(&max, 0, 0, 100, 100); - guac_common_rect_expand_to_grid(cell_size, &rect, &max); - CU_ASSERT_EQUAL(0, rect.x); - CU_ASSERT_EQUAL(0, rect.y); - CU_ASSERT_EQUAL(32, rect.width); - CU_ASSERT_EQUAL(32, rect.height); - - /* Adjustment with moving and clamping of rect */ - guac_common_rect_init(&rect, 0, 0, 25, 15); - guac_common_rect_init(&max, 0, 5, 32, 15); - guac_common_rect_expand_to_grid(cell_size, &rect, &max); - CU_ASSERT_EQUAL(max.x, rect.x); - CU_ASSERT_EQUAL(max.y, rect.y); - CU_ASSERT_EQUAL(max.width, rect.width); - CU_ASSERT_EQUAL(max.height, rect.height); - - /* - * Rectangle intersection tests - */ - guac_common_rect min; - guac_common_rect_init(&min, 10, 10, 10, 10); - - /* Rectangle intersection - empty - * rectangle is outside */ - guac_common_rect_init(&rect, 25, 25, 5, 5); - int res = guac_common_rect_intersects(&rect, &min); - CU_ASSERT_EQUAL(0, res); - - /* Rectangle intersection - complete - * rectangle is completely inside */ - guac_common_rect_init(&rect, 11, 11, 5, 5); - res = guac_common_rect_intersects(&rect, &min); - CU_ASSERT_EQUAL(2, res); - - /* Rectangle intersection - partial - * rectangle intersects UL */ - guac_common_rect_init(&rect, 8, 8, 5, 5); - res = guac_common_rect_intersects(&rect, &min); - CU_ASSERT_EQUAL(1, res); - - /* Rectangle intersection - partial - * rectangle intersects LR */ - guac_common_rect_init(&rect, 18, 18, 5, 5); - res = guac_common_rect_intersects(&rect, &min); - CU_ASSERT_EQUAL(1, res); - - /* Rectangle intersection - complete - * rect intersects along UL but inside */ - guac_common_rect_init(&rect, 10, 10, 5, 5); - res = guac_common_rect_intersects(&rect, &min); - CU_ASSERT_EQUAL(2, res); - - /* Rectangle intersection - partial - * rectangle intersects along L but outside */ - guac_common_rect_init(&rect, 5, 10, 5, 5); - res = guac_common_rect_intersects(&rect, &min); - CU_ASSERT_EQUAL(1, res); - - /* Rectangle intersection - complete - * rectangle intersects along LR but rest is inside */ - guac_common_rect_init(&rect, 15, 15, 5, 5); - res = guac_common_rect_intersects(&rect, &min); - CU_ASSERT_EQUAL(2, res); - - /* Rectangle intersection - partial - * rectangle intersects along R but rest is outside */ - guac_common_rect_init(&rect, 20, 10, 5, 5); - res = guac_common_rect_intersects(&rect, &min); - CU_ASSERT_EQUAL(1, res); - - /* Rectangle intersection - partial - * rectangle encloses min; which is a partial intersection */ - guac_common_rect_init(&rect, 5, 5, 20, 20); - res = guac_common_rect_intersects(&rect, &min); - CU_ASSERT_EQUAL(1, res); - - /* - * Basic test of clip and split method - */ - guac_common_rect_init(&min, 10, 10, 10, 10); - guac_common_rect cut; - - /* Clip top */ - guac_common_rect_init(&rect, 10, 5, 10, 10); - res = guac_common_rect_clip_and_split(&rect, &min, &cut); - CU_ASSERT_EQUAL(1, res); - CU_ASSERT_EQUAL(10, cut.x); - CU_ASSERT_EQUAL(5, cut.y); - CU_ASSERT_EQUAL(10, cut.width); - CU_ASSERT_EQUAL(5, cut.height); - - CU_ASSERT_EQUAL(10, rect.x); - CU_ASSERT_EQUAL(10, rect.y); - CU_ASSERT_EQUAL(10, rect.width); - CU_ASSERT_EQUAL(5, rect.height); - - /* Clip bottom */ - guac_common_rect_init(&rect, 10, 15, 10, 10); - res = guac_common_rect_clip_and_split(&rect, &min, &cut); - CU_ASSERT_EQUAL(1, res); - CU_ASSERT_EQUAL(10, cut.x); - CU_ASSERT_EQUAL(20, cut.y); - CU_ASSERT_EQUAL(10, cut.width); - CU_ASSERT_EQUAL(5, cut.height); - - CU_ASSERT_EQUAL(10, rect.x); - CU_ASSERT_EQUAL(15, rect.y); - CU_ASSERT_EQUAL(10, rect.width); - CU_ASSERT_EQUAL(5, rect.height); - - /* Clip left */ - guac_common_rect_init(&rect, 5, 10, 10, 10); - res = guac_common_rect_clip_and_split(&rect, &min, &cut); - CU_ASSERT_EQUAL(1, res); - CU_ASSERT_EQUAL(5, cut.x); - CU_ASSERT_EQUAL(10, cut.y); - CU_ASSERT_EQUAL(5, cut.width); - CU_ASSERT_EQUAL(10, cut.height); - - CU_ASSERT_EQUAL(10, rect.x); - CU_ASSERT_EQUAL(10, rect.y); - CU_ASSERT_EQUAL(5, rect.width); - CU_ASSERT_EQUAL(10, rect.height); - - /* Clip right */ - guac_common_rect_init(&rect, 15, 10, 10, 10); - res = guac_common_rect_clip_and_split(&rect, &min, &cut); - CU_ASSERT_EQUAL(1, res); - CU_ASSERT_EQUAL(20, cut.x); - CU_ASSERT_EQUAL(10, cut.y); - CU_ASSERT_EQUAL(5, cut.width); - CU_ASSERT_EQUAL(10, cut.height); - - CU_ASSERT_EQUAL(15, rect.x); - CU_ASSERT_EQUAL(10, rect.y); - CU_ASSERT_EQUAL(5, rect.width); - CU_ASSERT_EQUAL(10, rect.height); - - /* - * Test a rectangle which completely covers the hole. - * Clip and split until done. - */ - guac_common_rect_init(&rect, 5, 5, 20, 20); - - /* Clip top */ - res = guac_common_rect_clip_and_split(&rect, &min, &cut); - CU_ASSERT_EQUAL(1, res); - CU_ASSERT_EQUAL(5, cut.x); - CU_ASSERT_EQUAL(5, cut.y); - CU_ASSERT_EQUAL(20, cut.width); - CU_ASSERT_EQUAL(5, cut.height); - - CU_ASSERT_EQUAL(5, rect.x); - CU_ASSERT_EQUAL(10, rect.y); - CU_ASSERT_EQUAL(20, rect.width); - CU_ASSERT_EQUAL(15, rect.height); - - /* Clip left */ - res = guac_common_rect_clip_and_split(&rect, &min, &cut); - CU_ASSERT_EQUAL(1, res); - CU_ASSERT_EQUAL(5, cut.x); - CU_ASSERT_EQUAL(10, cut.y); - CU_ASSERT_EQUAL(5, cut.width); - CU_ASSERT_EQUAL(15, cut.height); - - CU_ASSERT_EQUAL(10, rect.x); - CU_ASSERT_EQUAL(10, rect.y); - CU_ASSERT_EQUAL(15, rect.width); - CU_ASSERT_EQUAL(15, rect.height); - - /* Clip bottom */ - res = guac_common_rect_clip_and_split(&rect, &min, &cut); - CU_ASSERT_EQUAL(1, res); - CU_ASSERT_EQUAL(10, cut.x); - CU_ASSERT_EQUAL(20, cut.y); - CU_ASSERT_EQUAL(15, cut.width); - CU_ASSERT_EQUAL(5, cut.height); - - CU_ASSERT_EQUAL(10, rect.x); - CU_ASSERT_EQUAL(10, rect.y); - CU_ASSERT_EQUAL(15, rect.width); - CU_ASSERT_EQUAL(10, rect.height); - - /* Clip right */ - res = guac_common_rect_clip_and_split(&rect, &min, &cut); - CU_ASSERT_EQUAL(20, cut.x); - CU_ASSERT_EQUAL(10, cut.y); - CU_ASSERT_EQUAL(5, cut.width); - CU_ASSERT_EQUAL(10, cut.height); - - CU_ASSERT_EQUAL(10, rect.x); - CU_ASSERT_EQUAL(10, rect.y); - CU_ASSERT_EQUAL(10, rect.width); - CU_ASSERT_EQUAL(10, rect.height); - - /* Make sure nothing is left to do */ - res = guac_common_rect_clip_and_split(&rect, &min, &cut); - CU_ASSERT_EQUAL(0, res); - -} - diff --git a/tests/protocol/instruction_read.c b/tests/protocol/instruction_read.c deleted file mode 100644 index 930b5b5e..00000000 --- a/tests/protocol/instruction_read.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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. - */ - -#include "config.h" - -#include "suite.h" - -#include -#include -#include - -#include -#include -#include -#include -#include - -void test_instruction_read() { - - int rfd, wfd; - int fd[2], childpid; - - char test_string[] = "4.test,6.a" UTF8_4 "b," - "5.12345,10.a" UTF8_8 "c;" - "5.test2,10.hellohello,15.worldworldworld;"; - - /* Create pipe */ - CU_ASSERT_EQUAL_FATAL(pipe(fd), 0); - - /* File descriptors */ - rfd = fd[0]; - wfd = fd[1]; - - /* Fork */ - if ((childpid = fork()) == -1) { - /* ERROR */ - perror("fork"); - return; - } - - /* Child (pipe writer) */ - if (childpid == 0) { - close(rfd); - CU_ASSERT_EQUAL( - write(wfd, test_string, sizeof(test_string)), - sizeof(test_string) - ); - exit(0); - } - - /* Parent (unit test) */ - else { - - guac_socket* socket; - guac_parser* parser; - - close(wfd); - - /* Open guac socket */ - socket = guac_socket_open(rfd); - CU_ASSERT_PTR_NOT_NULL_FATAL(socket); - - /* Allocate parser */ - parser = guac_parser_alloc(); - CU_ASSERT_PTR_NOT_NULL_FATAL(parser); - - /* Read instruction */ - CU_ASSERT_EQUAL_FATAL(guac_parser_read(parser, socket, 1000000), 0); - - /* Validate contents */ - CU_ASSERT_STRING_EQUAL(parser->opcode, "test"); - CU_ASSERT_EQUAL_FATAL(parser->argc, 3); - CU_ASSERT_STRING_EQUAL(parser->argv[0], "a" UTF8_4 "b"); - CU_ASSERT_STRING_EQUAL(parser->argv[1], "12345"); - CU_ASSERT_STRING_EQUAL(parser->argv[2], "a" UTF8_8 "c"); - - /* Read another instruction */ - CU_ASSERT_EQUAL_FATAL(guac_parser_read(parser, socket, 1000000), 0); - - /* Validate contents */ - CU_ASSERT_STRING_EQUAL(parser->opcode, "test2"); - CU_ASSERT_EQUAL_FATAL(parser->argc, 2); - CU_ASSERT_STRING_EQUAL(parser->argv[0], "hellohello"); - CU_ASSERT_STRING_EQUAL(parser->argv[1], "worldworldworld"); - - guac_parser_free(parser); - guac_socket_free(socket); - - } - -} - diff --git a/tests/protocol/instruction_write.c b/tests/protocol/instruction_write.c deleted file mode 100644 index 8e12dfc1..00000000 --- a/tests/protocol/instruction_write.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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. - */ - -#include "config.h" - -#include "suite.h" - -#include -#include -#include - -#include -#include -#include -#include - -void test_instruction_write() { - - int rfd, wfd; - int fd[2], childpid; - - /* Create pipe */ - CU_ASSERT_EQUAL_FATAL(pipe(fd), 0); - - /* File descriptors */ - rfd = fd[0]; - wfd = fd[1]; - - /* Fork */ - if ((childpid = fork()) == -1) { - /* ERROR */ - perror("fork"); - return; - } - - /* Child (pipe writer) */ - if (childpid == 0) { - - guac_socket* socket; - - close(rfd); - - /* Open guac socket */ - socket = guac_socket_open(wfd); - - /* Write instruction */ - guac_protocol_send_name(socket, "a" UTF8_4 "b" UTF8_4 "c"); - guac_protocol_send_sync(socket, 12345); - guac_socket_flush(socket); - - guac_socket_free(socket); - exit(0); - } - - /* Parent (unit test) */ - else { - - char expected[] = - "4.name,11.a" UTF8_4 "b" UTF8_4 "c;" - "4.sync,5.12345;"; - - int numread; - char buffer[1024]; - int offset = 0; - - close(wfd); - - /* Read everything available into buffer */ - while ((numread = - read(rfd, - &(buffer[offset]), - sizeof(buffer)-offset)) != 0) { - offset += numread; - } - - /* Add NULL terminator */ - buffer[offset] = '\0'; - - /* Read value should be equal to expected value */ - CU_ASSERT_STRING_EQUAL(buffer, expected); - - } - -} - diff --git a/tests/protocol/nest_write.c b/tests/protocol/nest_write.c deleted file mode 100644 index e1b885b2..00000000 --- a/tests/protocol/nest_write.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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. - */ - -#include "config.h" - -#include "suite.h" - -#include -#include -#include - -#include -#include -#include -#include - -void test_nest_write() { - - int rfd, wfd; - int fd[2], childpid; - - /* Create pipe */ - CU_ASSERT_EQUAL_FATAL(pipe(fd), 0); - - /* File descriptors */ - rfd = fd[0]; - wfd = fd[1]; - - /* Fork */ - if ((childpid = fork()) == -1) { - /* ERROR */ - perror("fork"); - return; - } - - /* Child (pipe writer) */ - if (childpid == 0) { - - guac_socket* nested_socket; - guac_socket* socket; - - close(rfd); - - /* Open guac socket */ - socket = guac_socket_open(wfd); - - /* Nest socket */ - nested_socket = guac_socket_nest(socket, 0); - - /* Write instruction */ - guac_protocol_send_name(nested_socket, "a" UTF8_4 "b" UTF8_4 "c"); - guac_protocol_send_sync(nested_socket, 12345); - guac_socket_flush(nested_socket); - guac_socket_flush(socket); - - guac_socket_free(nested_socket); - guac_socket_free(socket); - exit(0); - } - - /* Parent (unit test) */ - else { - - char expected[] = - "4.nest,1.0,37." - "4.name,11.a" UTF8_4 "b" UTF8_4 "c;" - "4.sync,5.12345;" - ";"; - - int numread; - char buffer[1024]; - int offset = 0; - - close(wfd); - - /* Read everything available into buffer */ - while ((numread = - read(rfd, - &(buffer[offset]), - sizeof(buffer)-offset)) != 0) { - offset += numread; - } - - /* Add NULL terminator */ - buffer[offset] = '\0'; - - /* Read value should be equal to expected value */ - CU_ASSERT_STRING_EQUAL(buffer, expected); - - } - -} - diff --git a/tests/protocol/suite.c b/tests/protocol/suite.c deleted file mode 100644 index 14cfc406..00000000 --- a/tests/protocol/suite.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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. - */ - -#include "config.h" - -#include "suite.h" - -#include - -int protocol_suite_init() { - return 0; -} - -int protocol_suite_cleanup() { - return 0; -} - -int register_protocol_suite() { - - /* Add protocol test suite */ - CU_pSuite suite = CU_add_suite("protocol", - protocol_suite_init, protocol_suite_cleanup); - if (suite == NULL) { - CU_cleanup_registry(); - return CU_get_error(); - } - - /* Add tests */ - if ( - CU_add_test(suite, "base64-decode", test_base64_decode) == NULL - || CU_add_test(suite, "instruction-parse", test_instruction_parse) == NULL - || CU_add_test(suite, "instruction-read", test_instruction_read) == NULL - || CU_add_test(suite, "instruction-write", test_instruction_write) == NULL - || CU_add_test(suite, "nest-write", test_nest_write) == NULL - ) { - CU_cleanup_registry(); - return CU_get_error(); - } - - return 0; - -} - diff --git a/tests/util/util_suite.c b/tests/util/util_suite.c deleted file mode 100644 index 7213a0f2..00000000 --- a/tests/util/util_suite.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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. - */ - -#include "config.h" - -#include "util_suite.h" - -#include - -int util_suite_init() { - return 0; -} - -int util_suite_cleanup() { - return 0; -} - -int register_util_suite() { - - /* Add util test suite */ - CU_pSuite suite = CU_add_suite("util", - util_suite_init, util_suite_cleanup); - if (suite == NULL) { - CU_cleanup_registry(); - return CU_get_error(); - } - - /* Add tests */ - if ( - CU_add_test(suite, "guac-pool", test_guac_pool) == NULL - || CU_add_test(suite, "guac-unicode", test_guac_unicode) == NULL - ) { - CU_cleanup_registry(); - return CU_get_error(); - } - - return 0; - -} -