You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by vn...@apache.org on 2019/01/07 00:43:37 UTC
[6/7] guacamole-server git commit: GUACAMOLE-662: Migrate tests to
test runners generated by new convenience script. Remove unnecessary test
runners.
GUACAMOLE-662: Migrate tests to test runners generated by new convenience script. Remove unnecessary test runners.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/476b4310
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/476b4310
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/476b4310
Branch: refs/heads/master
Commit: 476b43104103fb61363f0e451e6553ebac45d157
Parents: 877bf59
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Nov 13 13:26:43 2018 -0800
Committer: Michael Jumper <mj...@apache.org>
Committed: Sat Nov 17 18:06:40 2018 -0800
----------------------------------------------------------------------
.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 +++++
src/common/tests/iconv/convert.c | 185 ++++++++++++
src/common/tests/rect/clip_and_split.c | 156 ++++++++++
src/common/tests/rect/constrain.c | 43 +++
src/common/tests/rect/expand_to_grid.c | 71 +++++
src/common/tests/rect/extend.c | 42 +++
src/common/tests/rect/init.c | 39 +++
src/common/tests/rect/intersects.c | 91 ++++++
src/common/tests/string/count_occurrences.c | 33 +++
src/common/tests/string/split.c | 63 ++++
src/libguac/.gitignore | 44 +--
src/libguac/Makefile.am | 1 +
src/libguac/tests/Makefile.am | 76 +++++
src/libguac/tests/client/buffer_pool.c | 76 +++++
src/libguac/tests/client/layer_pool.c | 76 +++++
src/libguac/tests/parser/append.c | 77 +++++
src/libguac/tests/parser/read.c | 145 ++++++++++
src/libguac/tests/pool/next_free.c | 90 ++++++
src/libguac/tests/protocol/base64_decode.c | 55 ++++
src/libguac/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 ++++
src/libguac/tests/unicode/strlen.c | 59 ++++
src/libguac/tests/unicode/write.c | 45 +++
tests/Makefile.am | 66 -----
tests/client/buffer_pool.c | 73 -----
tests/client/client_suite.c | 56 ----
tests/client/client_suite.h | 32 --
tests/client/layer_pool.c | 73 -----
tests/common/common_suite.c | 57 ----
tests/common/common_suite.h | 55 ----
tests/common/guac_iconv.c | 128 --------
tests/common/guac_rect.c | 289 -------------------
tests/common/guac_string.c | 70 -----
tests/protocol/base64_decode.c | 59 ----
tests/protocol/instruction_parse.c | 76 -----
tests/protocol/instruction_read.c | 108 -------
tests/protocol/instruction_write.c | 101 -------
tests/protocol/nest_write.c | 109 -------
tests/protocol/suite.c | 59 ----
tests/protocol/suite.h | 43 ---
tests/test_libguac.c | 47 ---
tests/util/guac_pool.c | 89 ------
tests/util/guac_unicode.c | 81 ------
tests/util/util_suite.c | 56 ----
tests/util/util_suite.h | 75 -----
53 files changed, 1980 insertions(+), 1858 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index dec0cd1..e0a6d53 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
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/Makefile.am
----------------------------------------------------------------------
diff --git a/Makefile.am b/Makefile.am
index cbfea85..c75735c 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
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/README-unit-testing.md
----------------------------------------------------------------------
diff --git a/README-unit-testing.md b/README-unit-testing.md
new file mode 100644
index 0000000..5bed872
--- /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.
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 672d19e..b63ed69 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
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/common/.gitignore
----------------------------------------------------------------------
diff --git a/src/common/.gitignore b/src/common/.gitignore
new file mode 100644
index 0000000..f7efbda
--- /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
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/common/Makefile.am
----------------------------------------------------------------------
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 0619010..f98054b 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 \
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/common/tests/Makefile.am
----------------------------------------------------------------------
diff --git a/src/common/tests/Makefile.am b/src/common/tests/Makefile.am
new file mode 100644
index 0000000..8169d7d
--- /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
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/common/tests/iconv/convert.c
----------------------------------------------------------------------
diff --git a/src/common/tests/iconv/convert.c b/src/common/tests/iconv/convert.c
new file mode 100644
index 0000000..1a00994
--- /dev/null
+++ b/src/common/tests/iconv/convert.c
@@ -0,0 +1,185 @@
+/*
+ * 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/iconv.h"
+
+#include <CUnit/CUnit.h>
+
+/**
+ * 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) {
+
+ char output[4096];
+ char input[4096];
+
+ const char* current_input = input;
+ char* current_output = output;
+
+ memcpy(input, in_string, in_length);
+ guac_iconv(reader, ¤t_input, sizeof(input),
+ writer, ¤t_output, sizeof(output));
+
+ /* Verify output length */
+ CU_ASSERT_EQUAL(out_length, current_output - output);
+
+ /* Verify entire input read */
+ CU_ASSERT_EQUAL(in_length, current_input - input);
+
+ /* Verify output content */
+ CU_ASSERT_EQUAL(0, memcmp(output, out_string, out_length));
+
+}
+
+/**
+ * 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));
+}
+
+/**
+ * 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));
+}
+
+/**
+ * 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));
+}
+
+/**
+ * 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));
+}
+
+/**
+ * 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));
+}
+
+/**
+ * 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));
+}
+
+/**
+ * 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));
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/common/tests/rect/clip_and_split.c
----------------------------------------------------------------------
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 0000000..e286bce
--- /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 <CUnit/CUnit.h>
+
+/**
+ * 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);
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/common/tests/rect/constrain.c
----------------------------------------------------------------------
diff --git a/src/common/tests/rect/constrain.c b/src/common/tests/rect/constrain.c
new file mode 100644
index 0000000..793aac2
--- /dev/null
+++ b/src/common/tests/rect/constrain.c
@@ -0,0 +1,43 @@
+/*
+ * 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 <CUnit/CUnit.h>
+
+/**
+ * Test which verifies that guac_common_rect_constrain() restricts a given
+ * rectangle to arbitrary bounds.
+ */
+void test_rect__constrain() {
+
+ guac_common_rect max;
+ 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);
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/common/tests/rect/expand_to_grid.c
----------------------------------------------------------------------
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 0000000..beef87d
--- /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 <CUnit/CUnit.h>
+
+/**
+ * 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);
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/common/tests/rect/extend.c
----------------------------------------------------------------------
diff --git a/src/common/tests/rect/extend.c b/src/common/tests/rect/extend.c
new file mode 100644
index 0000000..dc2a0e3
--- /dev/null
+++ b/src/common/tests/rect/extend.c
@@ -0,0 +1,42 @@
+/*
+ * 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 <CUnit/CUnit.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() {
+
+ guac_common_rect max;
+ guac_common_rect rect;
+
+ 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);
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/common/tests/rect/init.c
----------------------------------------------------------------------
diff --git a/src/common/tests/rect/init.c b/src/common/tests/rect/init.c
new file mode 100644
index 0000000..288cd75
--- /dev/null
+++ b/src/common/tests/rect/init.c
@@ -0,0 +1,39 @@
+/*
+ * 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 <CUnit/CUnit.h>
+
+/**
+ * Test which verifies rectangle initialization via guac_common_rect_init().
+ */
+void test_rect__init() {
+
+ guac_common_rect max;
+
+ 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);
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/common/tests/rect/intersects.c
----------------------------------------------------------------------
diff --git a/src/common/tests/rect/intersects.c b/src/common/tests/rect/intersects.c
new file mode 100644
index 0000000..c480268
--- /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 <CUnit/CUnit.h>
+
+/**
+ * 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);
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/common/tests/string/count_occurrences.c
----------------------------------------------------------------------
diff --git a/src/common/tests/string/count_occurrences.c b/src/common/tests/string/count_occurrences.c
new file mode 100644
index 0000000..0c7d01d
--- /dev/null
+++ b/src/common/tests/string/count_occurrences.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 "common/string.h"
+
+#include <CUnit/CUnit.h>
+
+/**
+ * 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'));
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/common/tests/string/split.c
----------------------------------------------------------------------
diff --git a/src/common/tests/string/split.c b/src/common/tests/string/split.c
new file mode 100644
index 0000000..36f8f19
--- /dev/null
+++ b/src/common/tests/string/split.c
@@ -0,0 +1,63 @@
+/*
+ * 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/string.h"
+
+#include <CUnit/CUnit.h>
+
+#include <stdlib.h>
+
+/**
+ * Test which verifies that guac_split() splits a string on occurrences of a
+ * given character.
+ */
+void test_string__split() {
+
+ /* Split test string */
+ char** tokens = guac_split("this is a test string", ' ');
+ CU_ASSERT_PTR_NOT_NULL(tokens);
+
+ /* Check resulting tokens */
+ CU_ASSERT_PTR_NOT_NULL_FATAL(tokens[0]);
+ CU_ASSERT_STRING_EQUAL("this", tokens[0]);
+
+ CU_ASSERT_PTR_NOT_NULL_FATAL(tokens[1]);
+ CU_ASSERT_STRING_EQUAL("is", tokens[1]);
+
+ CU_ASSERT_PTR_NOT_NULL_FATAL(tokens[2]);
+ CU_ASSERT_STRING_EQUAL("a", tokens[2]);
+
+ CU_ASSERT_PTR_NOT_NULL_FATAL(tokens[3]);
+ CU_ASSERT_STRING_EQUAL("test", tokens[3]);
+
+ CU_ASSERT_PTR_NOT_NULL_FATAL(tokens[4]);
+ CU_ASSERT_STRING_EQUAL("string", tokens[4]);
+
+ CU_ASSERT_PTR_NULL(tokens[5]);
+
+ /* Clean up */
+ free(tokens[0]);
+ free(tokens[1]);
+ free(tokens[2]);
+ free(tokens[3]);
+ free(tokens[4]);
+ free(tokens);
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/libguac/.gitignore
----------------------------------------------------------------------
diff --git a/src/libguac/.gitignore b/src/libguac/.gitignore
index 95b69b0..ab58079 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
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/libguac/Makefile.am
----------------------------------------------------------------------
diff --git a/src/libguac/Makefile.am b/src/libguac/Makefile.am
index d541df5..2757f70 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
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/libguac/tests/Makefile.am
----------------------------------------------------------------------
diff --git a/src/libguac/tests/Makefile.am b/src/libguac/tests/Makefile.am
new file mode 100644
index 0000000..414a2f4
--- /dev/null
+++ b/src/libguac/tests/Makefile.am
@@ -0,0 +1,76 @@
+#
+# 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
+#
+
+check_PROGRAMS = test_libguac
+TESTS = $(check_PROGRAMS)
+
+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_CFLAGS = \
+ -Werror -Wall -pedantic \
+ @LIBGUAC_INCLUDE@
+
+test_libguac_LDADD = \
+ @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
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/libguac/tests/client/buffer_pool.c
----------------------------------------------------------------------
diff --git a/src/libguac/tests/client/buffer_pool.c b/src/libguac/tests/client/buffer_pool.c
new file mode 100644
index 0000000..4f3b3c1
--- /dev/null
+++ b/src/libguac/tests/client/buffer_pool.c
@@ -0,0 +1,76 @@
+/*
+ * 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 <CUnit/CUnit.h>
+#include <guacamole/client.h>
+#include <guacamole/layer.h>
+
+#include <stdbool.h>
+
+/**
+ * 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;
+ bool seen[GUAC_BUFFER_POOL_INITIAL_SIZE] = { 0 };
+
+ guac_layer* layer;
+
+ /* Get client */
+ client = guac_client_alloc();
+ CU_ASSERT_PTR_NOT_NULL_FATAL(client);
+
+ /* Fill pool */
+ for (i=0; i<GUAC_BUFFER_POOL_INITIAL_SIZE; i++) {
+
+ /* Allocate and throw away a layer (should not disturb buffer alloc) */
+ CU_ASSERT_PTR_NOT_NULL_FATAL(guac_client_alloc_layer(client));
+
+ layer = guac_client_alloc_buffer(client);
+
+ /* Index should be within pool size */
+ CU_ASSERT_PTR_NOT_NULL_FATAL(layer);
+ CU_ASSERT_FATAL(layer->index < 0);
+ CU_ASSERT_FATAL(layer->index >= -GUAC_BUFFER_POOL_INITIAL_SIZE);
+
+ /* This should be a layer we have not seen yet */
+ CU_ASSERT_FALSE(seen[-layer->index - 1]);
+ seen[-layer->index - 1] = true;
+
+ guac_client_free_buffer(client, layer);
+
+ }
+
+ /* Now that pool is filled, we should get a previously seen layer */
+ layer = guac_client_alloc_buffer(client);
+
+ CU_ASSERT_FATAL(layer->index < 0);
+ CU_ASSERT_FATAL(layer->index >= -GUAC_BUFFER_POOL_INITIAL_SIZE);
+ CU_ASSERT_TRUE(seen[-layer->index - 1]);
+
+ /* Free client */
+ guac_client_free(client);
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/libguac/tests/client/layer_pool.c
----------------------------------------------------------------------
diff --git a/src/libguac/tests/client/layer_pool.c b/src/libguac/tests/client/layer_pool.c
new file mode 100644
index 0000000..f82e84f
--- /dev/null
+++ b/src/libguac/tests/client/layer_pool.c
@@ -0,0 +1,76 @@
+/*
+ * 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 <CUnit/CUnit.h>
+#include <guacamole/client.h>
+#include <guacamole/layer.h>
+
+#include <stdbool.h>
+
+/**
+ * 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;
+ bool seen[GUAC_BUFFER_POOL_INITIAL_SIZE] = {0};
+
+ guac_layer* layer;
+
+ /* Get client */
+ client = guac_client_alloc();
+ CU_ASSERT_PTR_NOT_NULL_FATAL(client);
+
+ /* Fill pool */
+ for (i=0; i<GUAC_BUFFER_POOL_INITIAL_SIZE; i++) {
+
+ /* Allocate and throw away a buffer (should not disturb layer alloc) */
+ CU_ASSERT_PTR_NOT_NULL_FATAL(guac_client_alloc_buffer(client));
+
+ layer = guac_client_alloc_layer(client);
+
+ /* Index should be within pool size */
+ CU_ASSERT_PTR_NOT_NULL_FATAL(layer);
+ CU_ASSERT_FATAL(layer->index > 0);
+ CU_ASSERT_FATAL(layer->index <= GUAC_BUFFER_POOL_INITIAL_SIZE);
+
+ /* This should be a layer we have not seen yet */
+ CU_ASSERT_FALSE(seen[layer->index - 1]);
+ seen[layer->index - 1] = true;
+
+ guac_client_free_layer(client, layer);
+
+ }
+
+ /* Now that pool is filled, we should get a previously seen layer */
+ layer = guac_client_alloc_layer(client);
+
+ CU_ASSERT_FATAL(layer->index > 0);
+ CU_ASSERT_FATAL(layer->index <= GUAC_BUFFER_POOL_INITIAL_SIZE);
+ CU_ASSERT_TRUE(seen[layer->index - 1]);
+
+ /* Free client */
+ guac_client_free(client);
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/libguac/tests/parser/append.c
----------------------------------------------------------------------
diff --git a/src/libguac/tests/parser/append.c b/src/libguac/tests/parser/append.c
new file mode 100644
index 0000000..88515c1
--- /dev/null
+++ b/src/libguac/tests/parser/append.c
@@ -0,0 +1,77 @@
+/*
+ * 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 <CUnit/CUnit.h>
+#include <guacamole/parser.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/**
+ * 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();
+ CU_ASSERT_PTR_NOT_NULL_FATAL(parser);
+
+ /* Instruction input */
+ char buffer[] = "4.test,8.testdata,5.zxcvb,13.guacamoletest;XXXXXXXXXXXXXXXXXX";
+ char* current = buffer;
+
+ /* While data remains */
+ int remaining = sizeof(buffer)-1;
+ while (remaining > 18) {
+
+ /* Parse more data */
+ int parsed = guac_parser_append(parser, current, remaining);
+ if (parsed == 0)
+ break;
+
+ current += parsed;
+ remaining -= parsed;
+
+ }
+
+ /* Parse of instruction should be complete */
+ CU_ASSERT_EQUAL(remaining, 18);
+ CU_ASSERT_EQUAL(parser->state, GUAC_PARSE_COMPLETE);
+
+ /* Parse is complete - no more data should be read */
+ CU_ASSERT_EQUAL(guac_parser_append(parser, current, 18), 0);
+ CU_ASSERT_EQUAL(parser->state, GUAC_PARSE_COMPLETE);
+
+ /* Validate resulting structure */
+ CU_ASSERT_EQUAL(parser->argc, 3);
+ CU_ASSERT_PTR_NOT_NULL_FATAL(parser->opcode);
+ CU_ASSERT_PTR_NOT_NULL_FATAL(parser->argv[0]);
+ CU_ASSERT_PTR_NOT_NULL_FATAL(parser->argv[1]);
+ CU_ASSERT_PTR_NOT_NULL_FATAL(parser->argv[2]);
+
+ /* Validate resulting content */
+ CU_ASSERT_STRING_EQUAL(parser->opcode, "test");
+ CU_ASSERT_STRING_EQUAL(parser->argv[0], "testdata");
+ CU_ASSERT_STRING_EQUAL(parser->argv[1], "zxcvb");
+ CU_ASSERT_STRING_EQUAL(parser->argv[2], "guacamoletest");
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/libguac/tests/parser/read.c
----------------------------------------------------------------------
diff --git a/src/libguac/tests/parser/read.c b/src/libguac/tests/parser/read.c
new file mode 100644
index 0000000..e3b254c
--- /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 <CUnit/CUnit.h>
+#include <guacamole/error.h>
+#include <guacamole/parser.h>
+#include <guacamole/protocol.h>
+#include <guacamole/socket.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/**
+ * 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);
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/libguac/tests/pool/next_free.c
----------------------------------------------------------------------
diff --git a/src/libguac/tests/pool/next_free.c b/src/libguac/tests/pool/next_free.c
new file mode 100644
index 0000000..e8bd945
--- /dev/null
+++ b/src/libguac/tests/pool/next_free.c
@@ -0,0 +1,90 @@
+/*
+ * 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 <CUnit/CUnit.h>
+#include <guacamole/pool.h>
+
+/**
+ * The number of unique integers to provide through the guac_pool instance
+ * being tested.
+ */
+#define POOL_SIZE 128
+
+/**
+ * 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;
+
+ int i;
+ int seen[POOL_SIZE] = {0};
+ int value;
+
+ /* Get pool */
+ pool = guac_pool_alloc(POOL_SIZE);
+ CU_ASSERT_PTR_NOT_NULL_FATAL(pool);
+
+ /* Fill pool */
+ for (i=0; i<POOL_SIZE; i++) {
+
+ /* Get value from pool */
+ value = guac_pool_next_int(pool);
+
+ /* Value should be within pool size */
+ CU_ASSERT_FATAL(value >= 0);
+ CU_ASSERT_FATAL(value < POOL_SIZE);
+
+ /* This should be an integer we have not seen yet */
+ CU_ASSERT_EQUAL(0, seen[value]);
+ seen[value]++;
+
+ /* Return value to pool */
+ guac_pool_free_int(pool, value);
+
+ }
+
+ /* Now that pool is filled, we should get ONLY previously seen integers */
+ for (i=0; i<POOL_SIZE; i++) {
+
+ /* Get value from pool */
+ value = guac_pool_next_int(pool);
+
+ /* Value should be within pool size */
+ CU_ASSERT_FATAL(value >= 0);
+ CU_ASSERT_FATAL(value < POOL_SIZE);
+
+ /* This should be an integer we have seen only once */
+ CU_ASSERT_EQUAL(1, seen[value]);
+ seen[value]++;
+
+ }
+
+ /* Pool is filled to minimum now. Next value should be equal to size. */
+ value = guac_pool_next_int(pool);
+
+ CU_ASSERT_EQUAL(POOL_SIZE, value);
+
+ /* Free pool */
+ guac_pool_free(pool);
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/libguac/tests/protocol/base64_decode.c
----------------------------------------------------------------------
diff --git a/src/libguac/tests/protocol/base64_decode.c b/src/libguac/tests/protocol/base64_decode.c
new file mode 100644
index 0000000..60c8a03
--- /dev/null
+++ b/src/libguac/tests/protocol/base64_decode.c
@@ -0,0 +1,55 @@
+/*
+ * 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 <CUnit/CUnit.h>
+#include <guacamole/protocol.h>
+
+/**
+ * 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=";
+ char test_AVOCADO[] = "QVZPQ0FETw==";
+ char test_GUACAMOLE[] = "R1VBQ0FNT0xF";
+
+ /* Invalid strings */
+ char invalid1[] = "====";
+ char invalid2[] = "";
+
+ /* Test one character of padding */
+ CU_ASSERT_EQUAL(guac_protocol_decode_base64(test_HELLO), 5);
+ CU_ASSERT_NSTRING_EQUAL(test_HELLO, "HELLO", 5);
+
+ /* Test two characters of padding */
+ CU_ASSERT_EQUAL(guac_protocol_decode_base64(test_AVOCADO), 7);
+ CU_ASSERT_NSTRING_EQUAL(test_AVOCADO, "AVOCADO", 7);
+
+ /* Test three characters of padding */
+ CU_ASSERT_EQUAL(guac_protocol_decode_base64(test_GUACAMOLE), 9);
+ CU_ASSERT_NSTRING_EQUAL(test_GUACAMOLE, "GUACAMOLE", 9);
+
+ /* Verify invalid strings stop early as expected */
+ CU_ASSERT_EQUAL(guac_protocol_decode_base64(invalid1), 0);
+ CU_ASSERT_EQUAL(guac_protocol_decode_base64(invalid2), 0);
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/libguac/tests/socket/fd_send_instruction.c
----------------------------------------------------------------------
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 0000000..5a162d6
--- /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 <CUnit/CUnit.h>
+#include <guacamole/protocol.h>
+#include <guacamole/socket.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/**
+ * 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);
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/libguac/tests/socket/nested_send_instruction.c
----------------------------------------------------------------------
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 0000000..db29e2b
--- /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 <CUnit/CUnit.h>
+#include <guacamole/protocol.h>
+#include <guacamole/socket.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/**
+ * 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);
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/libguac/tests/unicode/charsize.c
----------------------------------------------------------------------
diff --git a/src/libguac/tests/unicode/charsize.c b/src/libguac/tests/unicode/charsize.c
new file mode 100644
index 0000000..e636155
--- /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 <CUnit/CUnit.h>
+#include <guacamole/unicode.h>
+
+/**
+ * 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'));
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/libguac/tests/unicode/read.c
----------------------------------------------------------------------
diff --git a/src/libguac/tests/unicode/read.c b/src/libguac/tests/unicode/read.c
new file mode 100644
index 0000000..230a721
--- /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 <CUnit/CUnit.h>
+#include <guacamole/unicode.h>
+
+/**
+ * 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);
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/libguac/tests/unicode/strlen.c
----------------------------------------------------------------------
diff --git a/src/libguac/tests/unicode/strlen.c b/src/libguac/tests/unicode/strlen.c
new file mode 100644
index 0000000..995a503
--- /dev/null
+++ b/src/libguac/tests/unicode/strlen.c
@@ -0,0 +1,59 @@
+/*
+ * 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 <CUnit/CUnit.h>
+#include <guacamole/unicode.h>
+
+/**
+ * A single Unicode character encoded as one byte with UTF-8.
+ */
+#define UTF8_1b "g"
+
+/**
+ * A single Unicode character encoded as two bytes with UTF-8.
+ */
+#define UTF8_2b "\xc4\xa3"
+
+/**
+ * A single Unicode character encoded as three bytes with UTF-8.
+ */
+#define UTF8_3b "\xe7\x8a\xac"
+
+/**
+ * A single Unicode character encoded as four bytes with UTF-8.
+ */
+#define UTF8_4b "\xf0\x90\x84\xa3"
+
+/**
+ * Test which verifies that guac_utf8_strlen() properly calculates the length
+ * of UTF-8 strings.
+ */
+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"));
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/src/libguac/tests/unicode/write.c
----------------------------------------------------------------------
diff --git a/src/libguac/tests/unicode/write.c b/src/libguac/tests/unicode/write.c
new file mode 100644
index 0000000..8480086
--- /dev/null
+++ b/src/libguac/tests/unicode/write.c
@@ -0,0 +1,45 @@
+/*
+ * 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 <CUnit/CUnit.h>
+#include <guacamole/unicode.h>
+
+/**
+ * Test which verifies that guac_utf8_write() properly encodes Unicode
+ * codepoints as UTF-8.
+ */
+void test_unicode__utf8_write() {
+
+ char buffer[16];
+
+ /* Test writes */
+ CU_ASSERT_EQUAL(1, guac_utf8_write(0x00065, &(buffer[0]), 10));
+ CU_ASSERT_EQUAL(2, guac_utf8_write(0x00654, &(buffer[1]), 9));
+ CU_ASSERT_EQUAL(3, guac_utf8_write(0x00876, &(buffer[3]), 7));
+ CU_ASSERT_EQUAL(4, guac_utf8_write(0x12345, &(buffer[6]), 4));
+ CU_ASSERT_EQUAL(0, guac_utf8_write(0x00066, &(buffer[10]), 0));
+
+ /* Test result of write */
+ CU_ASSERT(memcmp("\x65", &(buffer[0]), 1) == 0); /* U+0065 */
+ CU_ASSERT(memcmp("\xD9\x94", &(buffer[1]), 2) == 0); /* U+0654 */
+ 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 */
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/tests/Makefile.am
----------------------------------------------------------------------
diff --git a/tests/Makefile.am b/tests/Makefile.am
deleted file mode 100644
index fc1302e..0000000
--- a/tests/Makefile.am
+++ /dev/null
@@ -1,66 +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.
-#
-# 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
-
-TESTS = test_libguac
-check_PROGRAMS = test_libguac
-
-noinst_HEADERS = \
- client/client_suite.h \
- common/common_suite.h \
- protocol/suite.h \
- util/util_suite.h
-
-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@
-
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/tests/client/buffer_pool.c
----------------------------------------------------------------------
diff --git a/tests/client/buffer_pool.c b/tests/client/buffer_pool.c
deleted file mode 100644
index df27f6e..0000000
--- a/tests/client/buffer_pool.c
+++ /dev/null
@@ -1,73 +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 <CUnit/Basic.h>
-#include <guacamole/client.h>
-#include <guacamole/layer.h>
-
-void test_buffer_pool() {
-
- guac_client* client;
-
- int i;
- int seen[GUAC_BUFFER_POOL_INITIAL_SIZE] = {0};
-
- guac_layer* layer;
-
- /* Get client */
- client = guac_client_alloc();
- CU_ASSERT_PTR_NOT_NULL_FATAL(client);
-
- /* Fill pool */
- for (i=0; i<GUAC_BUFFER_POOL_INITIAL_SIZE; i++) {
-
- /* Allocate and throw away a layer (should not disturb buffer alloc) */
- CU_ASSERT_PTR_NOT_NULL_FATAL(guac_client_alloc_layer(client));
-
- layer = guac_client_alloc_buffer(client);
-
- /* Index should be within pool size */
- CU_ASSERT_PTR_NOT_NULL_FATAL(layer);
- CU_ASSERT_FATAL(layer->index < 0);
- CU_ASSERT_FATAL(layer->index >= -GUAC_BUFFER_POOL_INITIAL_SIZE);
-
- /* This should be a layer we have not seen yet */
- CU_ASSERT_FALSE(seen[-layer->index - 1]);
- seen[-layer->index - 1] = 1;
-
- guac_client_free_buffer(client, layer);
-
- }
-
- /* Now that pool is filled, we should get a previously seen layer */
- layer = guac_client_alloc_buffer(client);
-
- CU_ASSERT_FATAL(layer->index < 0);
- CU_ASSERT_FATAL(layer->index >= -GUAC_BUFFER_POOL_INITIAL_SIZE);
- CU_ASSERT_TRUE(seen[-layer->index - 1]);
-
- /* Free client */
- guac_client_free(client);
-
-}
-
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/476b4310/tests/client/client_suite.c
----------------------------------------------------------------------
diff --git a/tests/client/client_suite.c b/tests/client/client_suite.c
deleted file mode 100644
index 18bba6b..0000000
--- 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 <CUnit/Basic.h>
-
-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;
-
-}
-