diff --git a/tests/xrdp/Makefile.am b/tests/xrdp/Makefile.am index ac654079..014cf36d 100644 --- a/tests/xrdp/Makefile.am +++ b/tests/xrdp/Makefile.am @@ -27,11 +27,16 @@ test_xrdp_SOURCES = \ test_xrdp.h \ test_xrdp_main.c \ test_xrdp_egfx.c \ + test_xrdp_region.c \ test_bitmap_load.c test_xrdp_CFLAGS = \ -D IMAGEDIR=\"$(srcdir)\" \ - @CHECK_CFLAGS@ + @CHECK_CFLAGS@ \ + @CMOCKA_CFLAGS@ + +test_xrdp_LDFLAGS = -Wl,--wrap=pixman_region_extents, \ + -Wl,--wrap=pixman_region_not_empty test_xrdp_LDADD = \ $(top_builddir)/xrdp/xrdp_bitmap_load.o \ @@ -58,4 +63,5 @@ test_xrdp_LDADD = \ $(top_builddir)/xrdp/xrdp_main_utils.o \ $(PIXMAN_LIBS) \ $(IMLIB2_LIBS) \ - @CHECK_LIBS@ + @CHECK_LIBS@ \ + @CMOCKA_LIBS@ diff --git a/tests/xrdp/test_xrdp.h b/tests/xrdp/test_xrdp.h index ed062c9b..58d33578 100644 --- a/tests/xrdp/test_xrdp.h +++ b/tests/xrdp/test_xrdp.h @@ -5,5 +5,6 @@ Suite *make_suite_test_bitmap_load(void); Suite *make_suite_egfx_base_functions(void); +Suite *make_suite_region(void); #endif /* TEST_XRDP_H */ diff --git a/tests/xrdp/test_xrdp_main.c b/tests/xrdp/test_xrdp_main.c index b0aaa12f..017ef102 100644 --- a/tests/xrdp/test_xrdp_main.c +++ b/tests/xrdp/test_xrdp_main.c @@ -56,6 +56,7 @@ int main (void) sr = srunner_create (make_suite_test_bitmap_load()); srunner_add_suite(sr, make_suite_egfx_base_functions()); + srunner_add_suite(sr, make_suite_region()); srunner_set_tap(sr, "-"); srunner_run_all (sr, CK_ENV); diff --git a/tests/xrdp/test_xrdp_region.c b/tests/xrdp/test_xrdp_region.c new file mode 100644 index 00000000..12418932 --- /dev/null +++ b/tests/xrdp/test_xrdp_region.c @@ -0,0 +1,164 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg, Christopher Pitstick 2004-2023 + * + * Licensed 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. + * + * Test driver for XRDP routines + * + * If you want to run this driver under valgrind to check for memory leaks, + * use the following command line:- + * + * CK_FORK=no valgrind --leak-check=full --show-leak-kinds=all \ + * .libs/test_xrdp + * + * without the 'CK_FORK=no', memory still allocated by the test driver will + * be logged + */ + +#if defined(HAVE_CONFIG_H) +#include "config_ac.h" +#endif + +#include "log.h" +#include "os_calls.h" +#include + +#if defined(XRDP_PIXMAN) +#include +#else +#include "pixman-region.h" +#endif + +#include "test_xrdp.h" +#include "xrdp.h" +#include +#include +#include +#include +#ifdef __cplusplus +#error "cmocka is not supported with C++" +#else +#include +#endif + +#define UNUSED(x) (void)(x) + +// Mock functions +static pixman_box16_t test_box = +{ + 0, 0, 100, 100 +}; + +pixman_box16_t *__wrap_pixman_region_extents(pixman_region16_t *region) +{ + check_expected_ptr(region); + return mock_ptr_type(pixman_box16_t *); +} + +static void test_xrdp_region_get_bounds__negligent_path(void **state) +{ + struct xrdp_region *region = g_new0(struct xrdp_region, 1); + struct xrdp_rect *rect = g_new0(struct xrdp_rect, 1); + + // Cmocka boilerplate + UNUSED(state); + expect_any(__wrap_pixman_region_extents, region); + will_return(__wrap_pixman_region_extents, NULL); + + const int ret = xrdp_region_get_bounds(region, rect); + + assert_int_equal(1, ret); + + g_free(region); + g_free(rect); +} + +static void test_xrdp_region_get_bounds__happy_path(void **state) +{ + struct xrdp_region *region = g_new0(struct xrdp_region, 1); + struct xrdp_rect *rect = g_new0(struct xrdp_rect, 1); + + // Cmocka boilerplate + UNUSED(state); + expect_any(__wrap_pixman_region_extents, region); + will_return(__wrap_pixman_region_extents, &test_box); + + const int ret = xrdp_region_get_bounds(region, rect); + + assert_int_equal(0, ret); + assert_int_equal(0, rect->top); + assert_int_equal(0, rect->left); + assert_int_equal(100, rect->bottom); + assert_int_equal(100, rect->right); + + g_free(region); + g_free(rect); +} + +pixman_bool_t __wrap_pixman_region_not_empty(pixman_region16_t *region) +{ + check_expected_ptr(region); + return mock_type(pixman_bool_t); +} + +static void test_xrdp_region_not_empty__happy_path(void **state) +{ + struct xrdp_region *region = g_new0(struct xrdp_region, 1); + + // Cmocka boilerplate + UNUSED(state); + expect_any(__wrap_pixman_region_not_empty, region); + will_return(__wrap_pixman_region_not_empty, (pixman_bool_t)0); + + const int ret = xrdp_region_not_empty(region); + + assert_int_equal(0, ret); + + g_free(region); +} + +START_TEST(execute_suite) +{ + const struct CMUnitTest tests[] = + { + cmocka_unit_test(test_xrdp_region_get_bounds__negligent_path), + cmocka_unit_test(test_xrdp_region_get_bounds__happy_path), + cmocka_unit_test(test_xrdp_region_not_empty__happy_path) + }; + + ck_assert_int_eq(cmocka_run_group_tests(tests, NULL, NULL), 0); +} +END_TEST + +/******************************************************************************/ +/* +For an example of how to use cmocka, see the following: +https://gitlab.com/cmocka/cmocka/-/blob/master/example/mock/uptime/test_uptime.c +*/ +Suite * +make_suite_region(void) +{ + Suite *s; + TCase *tc_region; + + s = suite_create("test_xrdp_region"); + + tc_region = tcase_create("test_xrdp_region"); + tcase_add_test(tc_region, execute_suite); + + suite_add_tcase(s, tc_region); + + return s; +} diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h index 29181a45..77b2bce1 100644 --- a/xrdp/xrdp.h +++ b/xrdp/xrdp.h @@ -209,6 +209,10 @@ xrdp_region_intersect_rect(struct xrdp_region *self, struct xrdp_rect *rect); int xrdp_region_get_rect(struct xrdp_region *self, int index, struct xrdp_rect *rect); +int +xrdp_region_get_bounds(struct xrdp_region *self, struct xrdp_rect *rect); +int +xrdp_region_not_empty(struct xrdp_region *self); /* xrdp_bitmap_common.c */ struct xrdp_bitmap * diff --git a/xrdp/xrdp_region.c b/xrdp/xrdp_region.c index b6dd2ffb..dae79d4e 100644 --- a/xrdp/xrdp_region.c +++ b/xrdp/xrdp_region.c @@ -135,3 +135,33 @@ xrdp_region_get_rect(struct xrdp_region *self, int index, } return 1; } + +/*****************************************************************************/ +/* returns error */ +int +xrdp_region_get_bounds(struct xrdp_region *self, struct xrdp_rect *rect) +{ + struct pixman_box16 *box; + + box = pixman_region_extents(self->reg); + if (box != 0) + { + rect->left = box->x1; + rect->top = box->y1; + rect->right = box->x2; + rect->bottom = box->y2; + return 0; + } + return 1; +} + +/*****************************************************************************/ +/* returns boolean */ +int +xrdp_region_not_empty(struct xrdp_region *self) +{ + pixman_bool_t not_empty; + + not_empty = pixman_region_not_empty(self->reg); + return not_empty; +}