From a4dd0ad63c00f4dee3b86dfd3075d1d61b2b3180 Mon Sep 17 00:00:00 2001 From: sanine Date: Sat, 27 Aug 2022 23:52:56 -0500 Subject: add plibsys --- 3rdparty/plibsys/tests/CMakeLists.txt | 96 ++ 3rdparty/plibsys/tests/patomic_test.cpp | 118 +++ 3rdparty/plibsys/tests/pcondvariable_test.cpp | 230 +++++ 3rdparty/plibsys/tests/pcryptohash_test.cpp | 662 ++++++++++++++ 3rdparty/plibsys/tests/pdir_test.cpp | 248 ++++++ 3rdparty/plibsys/tests/perror_test.cpp | 236 +++++ 3rdparty/plibsys/tests/pfile_test.cpp | 61 ++ 3rdparty/plibsys/tests/phashtable_test.cpp | 320 +++++++ 3rdparty/plibsys/tests/pinifile_test.cpp | 357 ++++++++ 3rdparty/plibsys/tests/plibraryloader_test.cpp | 179 ++++ 3rdparty/plibsys/tests/plist_test.cpp | 200 +++++ 3rdparty/plibsys/tests/pmacros_test.cpp | 646 ++++++++++++++ 3rdparty/plibsys/tests/pmain_test.cpp | 111 +++ 3rdparty/plibsys/tests/pmem_test.cpp | 171 ++++ 3rdparty/plibsys/tests/pmutex_test.cpp | 146 +++ 3rdparty/plibsys/tests/pprocess_test.cpp | 49 + 3rdparty/plibsys/tests/prwlock_test.cpp | 224 +++++ 3rdparty/plibsys/tests/psemaphore_test.cpp | 226 +++++ 3rdparty/plibsys/tests/pshm_test.cpp | 313 +++++++ 3rdparty/plibsys/tests/pshmbuffer_test.cpp | 352 ++++++++ 3rdparty/plibsys/tests/psocket_test.cpp | 1131 ++++++++++++++++++++++++ 3rdparty/plibsys/tests/psocketaddress_test.cpp | 338 +++++++ 3rdparty/plibsys/tests/pspinlock_test.cpp | 148 ++++ 3rdparty/plibsys/tests/pstdarg_test.cpp | 205 +++++ 3rdparty/plibsys/tests/pstring_test.cpp | 289 ++++++ 3rdparty/plibsys/tests/ptestmacros.h | 131 +++ 3rdparty/plibsys/tests/ptimeprofiler_test.cpp | 126 +++ 3rdparty/plibsys/tests/ptree_test.cpp | 633 +++++++++++++ 3rdparty/plibsys/tests/ptypes_test.cpp | 456 ++++++++++ 3rdparty/plibsys/tests/puthread_test.cpp | 481 ++++++++++ 30 files changed, 8883 insertions(+) create mode 100644 3rdparty/plibsys/tests/CMakeLists.txt create mode 100644 3rdparty/plibsys/tests/patomic_test.cpp create mode 100644 3rdparty/plibsys/tests/pcondvariable_test.cpp create mode 100644 3rdparty/plibsys/tests/pcryptohash_test.cpp create mode 100644 3rdparty/plibsys/tests/pdir_test.cpp create mode 100644 3rdparty/plibsys/tests/perror_test.cpp create mode 100644 3rdparty/plibsys/tests/pfile_test.cpp create mode 100644 3rdparty/plibsys/tests/phashtable_test.cpp create mode 100644 3rdparty/plibsys/tests/pinifile_test.cpp create mode 100644 3rdparty/plibsys/tests/plibraryloader_test.cpp create mode 100644 3rdparty/plibsys/tests/plist_test.cpp create mode 100644 3rdparty/plibsys/tests/pmacros_test.cpp create mode 100644 3rdparty/plibsys/tests/pmain_test.cpp create mode 100644 3rdparty/plibsys/tests/pmem_test.cpp create mode 100644 3rdparty/plibsys/tests/pmutex_test.cpp create mode 100644 3rdparty/plibsys/tests/pprocess_test.cpp create mode 100644 3rdparty/plibsys/tests/prwlock_test.cpp create mode 100644 3rdparty/plibsys/tests/psemaphore_test.cpp create mode 100644 3rdparty/plibsys/tests/pshm_test.cpp create mode 100644 3rdparty/plibsys/tests/pshmbuffer_test.cpp create mode 100644 3rdparty/plibsys/tests/psocket_test.cpp create mode 100644 3rdparty/plibsys/tests/psocketaddress_test.cpp create mode 100644 3rdparty/plibsys/tests/pspinlock_test.cpp create mode 100644 3rdparty/plibsys/tests/pstdarg_test.cpp create mode 100644 3rdparty/plibsys/tests/pstring_test.cpp create mode 100644 3rdparty/plibsys/tests/ptestmacros.h create mode 100644 3rdparty/plibsys/tests/ptimeprofiler_test.cpp create mode 100644 3rdparty/plibsys/tests/ptree_test.cpp create mode 100644 3rdparty/plibsys/tests/ptypes_test.cpp create mode 100644 3rdparty/plibsys/tests/puthread_test.cpp (limited to '3rdparty/plibsys/tests') diff --git a/3rdparty/plibsys/tests/CMakeLists.txt b/3rdparty/plibsys/tests/CMakeLists.txt new file mode 100644 index 0000000..54f747b --- /dev/null +++ b/3rdparty/plibsys/tests/CMakeLists.txt @@ -0,0 +1,96 @@ +# The MIT License +# +# Copyright (C) 2018 Alexander Saprykin +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# 'Software'), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +project (tests CXX) +set (OUTPUT_DIR ${CMAKE_BINARY_DIR}) + +include (${PROJECT_SOURCE_DIR}/../cmake/PlatformDetect.cmake) +plibsys_detect_target_os (PLIBSYS_TESTS_TARGET_OS) + +list (APPEND PLIBSYS_TEST_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/../src ${CMAKE_BINARY_DIR}) + +if (MSVC) + list (APPEND PLIBSYS_TEST_COMPILE_DEFS -D_CRT_SECURE_NO_WARNINGS) +endif() + +macro (plibsys_add_test_executable TEST_NAME SRC_FILE) + add_executable (${TEST_NAME} ${SRC_FILE}) + target_link_libraries (${TEST_NAME} plibsys) + set_target_properties (${TEST_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_DIR}) + + # QNX requires libm for sqrt() and friends + if (PLIBSYS_TESTS_TARGET_OS STREQUAL qnx) + target_link_libraries (${TEST_NAME} m) + endif() + + # Add include directories + if (COMMAND target_include_directories) + target_include_directories (${TEST_NAME} PUBLIC ${PLIBSYS_TEST_INCLUDE_DIRS}) + else() + include_directories (${PLIBSYS_TEST_INCLUDE_DIRS}) + endif() + + # Add compile definitions + if (PLIBSYS_TEST_COMPILE_DEFS) + if (COMMAND target_compile_definitions) + target_compile_definitions (${TEST_NAME} PRIVATE ${PLIBSYS_TEST_COMPILE_DEFS}) + else() + add_definitions (${PLIBSYS_TEST_COMPILE_DEFS}) + endif() + endif() + + if (${TEST_NAME} STREQUAL "plibraryloader_test") + add_test (NAME ${TEST_NAME} COMMAND ${TEST_NAME} -- "$") + else() + add_test (NAME ${TEST_NAME} COMMAND ${TEST_NAME}) + endif() +endmacro() + +plibsys_add_test_executable (patomic_test patomic_test.cpp) +plibsys_add_test_executable (pcondvariable_test pcondvariable_test.cpp) +plibsys_add_test_executable (pcryptohash_test pcryptohash_test.cpp) +plibsys_add_test_executable (perror_test perror_test.cpp) +plibsys_add_test_executable (pdir_test pdir_test.cpp) +plibsys_add_test_executable (pfile_test pfile_test.cpp) +plibsys_add_test_executable (phashtable_test phashtable_test.cpp) +plibsys_add_test_executable (pinifile_test pinifile_test.cpp) +plibsys_add_test_executable (plibraryloader_test plibraryloader_test.cpp) +plibsys_add_test_executable (plist_test plist_test.cpp) +plibsys_add_test_executable (pmacros_test pmacros_test.cpp) +plibsys_add_test_executable (pmain_test pmain_test.cpp) +plibsys_add_test_executable (pmem_test pmem_test.cpp) +plibsys_add_test_executable (pmutex_test pmutex_test.cpp) +plibsys_add_test_executable (pprocess_test pprocess_test.cpp) +plibsys_add_test_executable (prwlock_test prwlock_test.cpp) +plibsys_add_test_executable (psemaphore_test psemaphore_test.cpp) +plibsys_add_test_executable (pshmbuffer_test pshmbuffer_test.cpp) +plibsys_add_test_executable (pshm_test pshm_test.cpp) +plibsys_add_test_executable (psocket_test psocket_test.cpp) +plibsys_add_test_executable (psocketaddress_test psocketaddress_test.cpp) +plibsys_add_test_executable (pspinlock_test pspinlock_test.cpp) +plibsys_add_test_executable (pstdarg_test pstdarg_test.cpp) +plibsys_add_test_executable (pstring_test pstring_test.cpp) +plibsys_add_test_executable (ptimeprofiler_test ptimeprofiler_test.cpp) +plibsys_add_test_executable (ptree_test ptree_test.cpp) +plibsys_add_test_executable (ptypes_test ptypes_test.cpp) +plibsys_add_test_executable (puthread_test puthread_test.cpp) diff --git a/3rdparty/plibsys/tests/patomic_test.cpp b/3rdparty/plibsys/tests/patomic_test.cpp new file mode 100644 index 0000000..6efb2d4 --- /dev/null +++ b/3rdparty/plibsys/tests/patomic_test.cpp @@ -0,0 +1,118 @@ +/* + * The MIT License + * + * Copyright (C) 2013-2017 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +/* Actually we couldn't test the work of the atomic operations across the + * threads, but at least we can test the sanity of operations */ + +P_TEST_MODULE_INIT (); + +P_TEST_CASE_BEGIN (patomic_general_test) +{ + p_libsys_init (); + + (void) p_atomic_is_lock_free (); + + pint atomic_int = 0; + p_atomic_int_set (&atomic_int, 10); + + P_TEST_CHECK (p_atomic_int_add (&atomic_int, 5) == 10); + P_TEST_CHECK (p_atomic_int_get (&atomic_int) == 15); + + p_atomic_int_add (&atomic_int, -5); + P_TEST_CHECK (p_atomic_int_get (&atomic_int) == 10); + + p_atomic_int_inc (&atomic_int); + P_TEST_CHECK (p_atomic_int_get (&atomic_int) == 11); + + P_TEST_CHECK (p_atomic_int_dec_and_test (&atomic_int) == FALSE); + P_TEST_CHECK (p_atomic_int_get (&atomic_int) == 10); + + P_TEST_CHECK (p_atomic_int_compare_and_exchange (&atomic_int, 10, -10) == TRUE); + P_TEST_CHECK (p_atomic_int_get (&atomic_int) == -10); + P_TEST_CHECK (p_atomic_int_compare_and_exchange (&atomic_int, 10, 20) == FALSE); + P_TEST_CHECK (p_atomic_int_get (&atomic_int) == -10); + + p_atomic_int_inc (&atomic_int); + P_TEST_CHECK (p_atomic_int_get (&atomic_int) == -9); + + p_atomic_int_set (&atomic_int, 4); + P_TEST_CHECK (p_atomic_int_get (&atomic_int) == 4); + + P_TEST_CHECK (p_atomic_int_xor ((puint *) &atomic_int, (puint) 1) == 4); + P_TEST_CHECK (p_atomic_int_get (&atomic_int) == 5); + + P_TEST_CHECK (p_atomic_int_or ((puint *) &atomic_int, (puint) 2) == 5); + P_TEST_CHECK (p_atomic_int_get (&atomic_int) == 7); + + P_TEST_CHECK (p_atomic_int_and ((puint *) &atomic_int, (puint) 1) == 7); + P_TEST_CHECK (p_atomic_int_get (&atomic_int) == 1); + + p_atomic_int_set (&atomic_int, 51); + P_TEST_CHECK (p_atomic_int_get (&atomic_int) == 51); + + for (pint i = 51; i > 1; --i) { + P_TEST_CHECK (p_atomic_int_dec_and_test (&atomic_int) == FALSE); + P_TEST_CHECK (p_atomic_int_get (&atomic_int) == (i - 1)); + } + + P_TEST_CHECK (p_atomic_int_dec_and_test (&atomic_int) == TRUE); + P_TEST_CHECK (p_atomic_int_get (&atomic_int) == 0); + + ppointer atomic_pointer = NULL; + p_atomic_pointer_set (&atomic_pointer, PUINT_TO_POINTER (P_MAXSIZE)); + P_TEST_CHECK (p_atomic_pointer_get (&atomic_pointer) == PUINT_TO_POINTER (P_MAXSIZE)); + + p_atomic_pointer_set (&atomic_pointer, PUINT_TO_POINTER (100)); + P_TEST_CHECK (p_atomic_pointer_get (&atomic_pointer) == PUINT_TO_POINTER (100)); + P_TEST_CHECK (p_atomic_pointer_add (&atomic_pointer, (pssize) 100) == 100); + P_TEST_CHECK (p_atomic_pointer_get (&atomic_pointer) == PUINT_TO_POINTER (200)); + + p_atomic_pointer_set (&atomic_pointer, PINT_TO_POINTER (4)); + P_TEST_CHECK (p_atomic_pointer_get (&atomic_pointer) == PINT_TO_POINTER (4)); + + P_TEST_CHECK (p_atomic_pointer_xor (&atomic_pointer, (psize) 1) == 4); + P_TEST_CHECK (p_atomic_pointer_get (&atomic_pointer) == PINT_TO_POINTER (5)); + + P_TEST_CHECK (p_atomic_pointer_or (&atomic_pointer, (psize) 2) == 5); + P_TEST_CHECK (p_atomic_pointer_get (&atomic_pointer) == PINT_TO_POINTER (7)); + + P_TEST_CHECK (p_atomic_pointer_and (&atomic_pointer, (psize) 1) == 7); + P_TEST_CHECK (p_atomic_pointer_get (&atomic_pointer) == PINT_TO_POINTER (1)); + + P_TEST_CHECK (p_atomic_pointer_compare_and_exchange (&atomic_pointer, PUINT_TO_POINTER (1), NULL) == TRUE); + P_TEST_CHECK (p_atomic_pointer_get (&atomic_pointer) == NULL); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (patomic_general_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/pcondvariable_test.cpp b/3rdparty/plibsys/tests/pcondvariable_test.cpp new file mode 100644 index 0000000..887b77f --- /dev/null +++ b/3rdparty/plibsys/tests/pcondvariable_test.cpp @@ -0,0 +1,230 @@ +/* + * The MIT License + * + * Copyright (C) 2013-2019 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +P_TEST_MODULE_INIT (); + +#define PCONDTEST_MAX_QUEUE 10 + +static pint thread_wakeups = 0; +static pint thread_queue = 0; +static PCondVariable * queue_empty_cond = NULL; +static PCondVariable * queue_full_cond = NULL; +static PMutex * cond_mutex = NULL; +volatile static pboolean is_working = TRUE; + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + P_UNUSED (block); + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" void pmem_free (ppointer block) +{ + P_UNUSED (block); +} + +static void * producer_test_thread (void *) +{ + while (is_working == TRUE) { + if (!p_mutex_lock (cond_mutex)) { + is_working = FALSE; + p_cond_variable_broadcast (queue_full_cond); + p_uthread_exit (1); + } + + while (thread_queue >= PCONDTEST_MAX_QUEUE && is_working == TRUE) { + if (!p_cond_variable_wait (queue_empty_cond, cond_mutex)) { + is_working = FALSE; + p_cond_variable_broadcast (queue_full_cond); + p_mutex_unlock (cond_mutex); + p_uthread_exit (1); + } + } + + if (is_working) { + ++thread_queue; + ++thread_wakeups; + } + + if (!p_cond_variable_broadcast (queue_full_cond)) { + is_working = FALSE; + p_mutex_unlock (cond_mutex); + p_uthread_exit (1); + } + + if (!p_mutex_unlock (cond_mutex)) { + is_working = FALSE; + p_cond_variable_broadcast (queue_full_cond); + p_uthread_exit (1); + } + } + + p_cond_variable_broadcast (queue_full_cond); + p_uthread_exit (0); + + return NULL; +} + +static void * consumer_test_thread (void *) +{ + while (is_working == TRUE) { + if (!p_mutex_lock (cond_mutex)) { + is_working = FALSE; + p_cond_variable_signal (queue_empty_cond); + p_uthread_exit (1); + } + + while (thread_queue <= 0 && is_working == TRUE) { + if (!p_cond_variable_wait (queue_full_cond, cond_mutex)) { + is_working = FALSE; + p_cond_variable_signal (queue_empty_cond); + p_mutex_unlock (cond_mutex); + p_uthread_exit (1); + } + } + + if (is_working) { + --thread_queue; + ++thread_wakeups; + } + + if (!p_cond_variable_signal (queue_empty_cond)) { + is_working = FALSE; + p_mutex_unlock (cond_mutex); + p_uthread_exit (1); + } + + if (!p_mutex_unlock (cond_mutex)) { + is_working = FALSE; + p_cond_variable_signal (queue_empty_cond); + p_uthread_exit (1); + } + } + + p_cond_variable_signal (queue_empty_cond); + p_uthread_exit (0); + + return NULL; +} + +P_TEST_CASE_BEGIN (pcondvariable_nomem_test) +{ + p_libsys_init (); + + PMemVTable vtable; + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + P_TEST_CHECK (p_cond_variable_new () == NULL); + + p_mem_restore_vtable (); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pcondvariable_bad_input_test) +{ + p_libsys_init (); + + P_TEST_REQUIRE (p_cond_variable_broadcast (NULL) == FALSE); + P_TEST_REQUIRE (p_cond_variable_signal (NULL) == FALSE); + P_TEST_REQUIRE (p_cond_variable_wait (NULL, NULL) == FALSE); + p_cond_variable_free (NULL); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pcondvariable_general_test) +{ + PUThread *thr1, *thr2, *thr3; + + p_libsys_init (); + + queue_empty_cond = p_cond_variable_new (); + P_TEST_REQUIRE (queue_empty_cond != NULL); + queue_full_cond = p_cond_variable_new (); + P_TEST_REQUIRE (queue_full_cond != NULL); + cond_mutex = p_mutex_new (); + P_TEST_REQUIRE (cond_mutex != NULL); + + is_working = TRUE; + thread_wakeups = 0; + thread_queue = 0; + + thr1 = p_uthread_create ((PUThreadFunc) producer_test_thread, NULL, TRUE, NULL); + P_TEST_REQUIRE (thr1 != NULL); + + thr2 = p_uthread_create ((PUThreadFunc) consumer_test_thread, NULL, TRUE, NULL); + P_TEST_REQUIRE (thr2 != NULL); + + thr3 = p_uthread_create ((PUThreadFunc) consumer_test_thread, NULL, TRUE, NULL); + P_TEST_REQUIRE (thr3 != NULL); + + P_TEST_REQUIRE (p_cond_variable_broadcast (queue_empty_cond) == TRUE); + P_TEST_REQUIRE (p_cond_variable_broadcast (queue_full_cond) == TRUE); + + p_uthread_sleep (4000); + + is_working = FALSE; + + P_TEST_CHECK (p_uthread_join (thr1) == 0); + P_TEST_CHECK (p_uthread_join (thr2) == 0); + P_TEST_CHECK (p_uthread_join (thr3) == 0); + + P_TEST_REQUIRE (thread_wakeups > 0 && thread_queue >= 0 && thread_queue <= 10); + + p_uthread_unref (thr1); + p_uthread_unref (thr2); + p_uthread_unref (thr3); + p_cond_variable_free (queue_empty_cond); + p_cond_variable_free (queue_full_cond); + p_mutex_free (cond_mutex); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (pcondvariable_nomem_test); + P_TEST_SUITE_RUN_CASE (pcondvariable_bad_input_test); + P_TEST_SUITE_RUN_CASE (pcondvariable_general_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/pcryptohash_test.cpp b/3rdparty/plibsys/tests/pcryptohash_test.cpp new file mode 100644 index 0000000..30c1f91 --- /dev/null +++ b/3rdparty/plibsys/tests/pcryptohash_test.cpp @@ -0,0 +1,662 @@ +/* + * The MIT License + * + * Copyright (C) 2013-2017 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +#include + +P_TEST_MODULE_INIT (); + +#define PCRYPTO_STRESS_LENGTH 10000 +#define PCRYPTO_MAX_UPDATES 1000000 + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + P_UNUSED (block); + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" void pmem_free (ppointer block) +{ + P_UNUSED (block); +} + +static void +general_hash_test (PCryptoHashType type, + psize hash_len, + const pchar *msg1, + const pchar *msg2, + const puchar *etalon1, + const puchar *etalon2, + const puchar *etalon3, + const pchar *hash1, + const pchar *hash2, + const pchar *hash3, + const pchar *hash_stress) +{ + PCryptoHash *crypto_hash; + psize dig_len; + pchar *hash_str; + pchar *long_str; + puchar *hash_dig; + + crypto_hash = p_crypto_hash_new (type); + + P_TEST_REQUIRE ((psize) p_crypto_hash_get_length (crypto_hash) == hash_len); + P_TEST_REQUIRE (p_crypto_hash_get_type (crypto_hash) == type); + + hash_str = p_crypto_hash_get_string (crypto_hash); + P_TEST_REQUIRE (hash_str != NULL); + p_crypto_hash_reset (crypto_hash); + p_free (hash_str); + + hash_dig = (puchar *) p_malloc0 (hash_len); + P_TEST_REQUIRE (hash_dig != NULL); + + long_str = (pchar *) p_malloc0 (PCRYPTO_STRESS_LENGTH); + P_TEST_REQUIRE (long_str != NULL); + + for (int i = 0; i < PCRYPTO_STRESS_LENGTH; ++i) + long_str[i] = (pchar) (97 + i % 20); + + /* Case 1 */ + + /* Check string */ + p_crypto_hash_update (crypto_hash, (const puchar *) msg1, strlen (msg1)); + hash_str = p_crypto_hash_get_string (crypto_hash); + P_TEST_CHECK (strcmp (hash_str, hash1) == 0); + p_free (hash_str); + + p_crypto_hash_reset (crypto_hash); + + /* Check digest */ + dig_len = hash_len; + p_crypto_hash_update (crypto_hash, (const puchar *) msg1, strlen (msg1)); + p_crypto_hash_get_digest (crypto_hash, hash_dig, &dig_len); + + P_TEST_CHECK (dig_len == hash_len); + + for (unsigned int i = 0; i < hash_len; ++i) + P_TEST_CHECK (hash_dig[i] == etalon1[i]); + + p_crypto_hash_reset (crypto_hash); + + /* Case 2 */ + + /* Check string */ + p_crypto_hash_update (crypto_hash, (const puchar *) msg2, strlen (msg2)); + hash_str = p_crypto_hash_get_string (crypto_hash); + P_TEST_CHECK (strcmp (hash_str, hash2) == 0); + p_free (hash_str); + + p_crypto_hash_reset (crypto_hash); + + /* Check digest */ + dig_len = hash_len; + p_crypto_hash_update (crypto_hash, (const puchar *) msg2, strlen (msg2)); + p_crypto_hash_get_digest (crypto_hash, hash_dig, &dig_len); + + P_TEST_CHECK (dig_len == hash_len); + + for (unsigned int i = 0; i < hash_len; ++i) + P_TEST_CHECK (hash_dig[i] == etalon2[i]); + + p_crypto_hash_reset (crypto_hash); + + /* Case 3 */ + + /* Check string */ + for (int i = 0; i < PCRYPTO_MAX_UPDATES; ++i) + p_crypto_hash_update (crypto_hash, (const puchar *) "a", 1); + + hash_str = p_crypto_hash_get_string (crypto_hash); + + P_TEST_CHECK (strcmp (hash_str, hash3) == 0); + p_free (hash_str); + + p_crypto_hash_reset (crypto_hash); + + /* Check digest */ + dig_len = hash_len; + for (int i = 0; i < PCRYPTO_MAX_UPDATES; ++i) + p_crypto_hash_update (crypto_hash, (const puchar *) "a", 1); + + p_crypto_hash_get_digest (crypto_hash, hash_dig, &dig_len); + P_TEST_CHECK (dig_len == hash_len); + + for (unsigned int i = 0; i < hash_len; ++i) + P_TEST_CHECK (hash_dig[i] == etalon3[i]); + + p_crypto_hash_reset (crypto_hash); + + /* Stress test */ + p_crypto_hash_update (crypto_hash, (const puchar *) long_str, PCRYPTO_STRESS_LENGTH); + hash_str = p_crypto_hash_get_string (crypto_hash); + + P_TEST_CHECK (strcmp (hash_str, hash_stress) == 0); + p_free (hash_str); + + p_crypto_hash_reset (crypto_hash); + + p_free (long_str); + p_free (hash_dig); + p_crypto_hash_free (crypto_hash); +} + +P_TEST_CASE_BEGIN (pcryptohash_nomem_test) +{ + p_libsys_init (); + + PMemVTable vtable; + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + + P_TEST_CHECK (p_crypto_hash_new (P_CRYPTO_HASH_TYPE_MD5) == NULL); + P_TEST_CHECK (p_crypto_hash_new (P_CRYPTO_HASH_TYPE_SHA1) == NULL); + P_TEST_CHECK (p_crypto_hash_new (P_CRYPTO_HASH_TYPE_GOST) == NULL); + + p_mem_restore_vtable (); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pcryptohash_invalid_test) +{ + PCryptoHash *hash; + psize len; + pssize md5_len; + pchar *hash_str; + puchar *buf; + + p_libsys_init (); + + P_TEST_CHECK (p_crypto_hash_new ((PCryptoHashType) -1) == NULL); + P_TEST_CHECK (p_crypto_hash_get_length (NULL) == 0); + P_TEST_CHECK (p_crypto_hash_get_string (NULL) == NULL); + P_TEST_CHECK ((pint) p_crypto_hash_get_type (NULL) == -1); + p_crypto_hash_free (NULL); + + p_crypto_hash_update (NULL, NULL, 0); + p_crypto_hash_get_digest (NULL, NULL, NULL); + + p_crypto_hash_get_digest (NULL, NULL, &len); + P_TEST_CHECK (len == 0); + + p_crypto_hash_reset (NULL); + + hash = p_crypto_hash_new (P_CRYPTO_HASH_TYPE_MD5); + P_TEST_CHECK (hash != NULL); + + md5_len = p_crypto_hash_get_length (hash); + P_TEST_CHECK (md5_len > 0); + + buf = (puchar *) p_malloc0 (md5_len); + P_TEST_CHECK (buf != NULL); + + p_crypto_hash_get_digest (hash, buf, &len); + P_TEST_CHECK (len == 0); + + p_crypto_hash_update (hash, (const puchar *) ("abc"), 3); + len = ((psize) md5_len) - 1; + p_crypto_hash_get_digest (hash, buf, &len); + P_TEST_CHECK (len == 0); + + hash_str = p_crypto_hash_get_string (hash); + P_TEST_CHECK (strcmp (hash_str, "900150983cd24fb0d6963f7d28e17f72") == 0); + p_free (hash_str); + + p_crypto_hash_update (hash, (const puchar *) ("abc"), 3); + hash_str = p_crypto_hash_get_string (hash); + P_TEST_CHECK (strcmp (hash_str, "900150983cd24fb0d6963f7d28e17f72") == 0); + p_free (hash_str); + + p_crypto_hash_free (hash); + p_free (buf); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (md5_test) +{ + const puchar hash_etalon_1[] = {144, 1, 80, 152, 60, 210, 79, 176, + 214, 150, 63, 125, 40, 225, 127, 114}; + const puchar hash_etalon_2[] = {130, 21, 239, 7, 150, 162, 11, 202, + 170, 225, 22, 211, 135, 108, 102, 74}; + const puchar hash_etalon_3[] = {119, 7, 214, 174, 78, 2, 124, 112, + 238, 162, 169, 53, 194, 41, 111, 33}; + + p_libsys_init (); + + general_hash_test (P_CRYPTO_HASH_TYPE_MD5, + 16, + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + hash_etalon_1, + hash_etalon_2, + hash_etalon_3, + "900150983cd24fb0d6963f7d28e17f72", + "8215ef0796a20bcaaae116d3876c664a", + "7707d6ae4e027c70eea2a935c2296f21", + "e19ea4a77c97fa6c2521ae1ca66982b9"); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (sha1_test) +{ + const puchar hash_etalon_1[] = {169, 153, 62, 54, 71, 6, 129, 106, + 186, 62, 37, 113, 120, 80, 194, 108, + 156, 208, 216, 157}; + const puchar hash_etalon_2[] = {132, 152, 62, 68, 28, 59, 210, 110, + 186, 174, 74, 161, 249, 81, 41, 229, + 229, 70, 112, 241}; + const puchar hash_etalon_3[] = { 52, 170, 151, 60, 212, 196, 218, 164, + 246, 30, 235, 43, 219, 173, 39, 49, + 101, 52, 1, 111}; + + p_libsys_init (); + + general_hash_test (P_CRYPTO_HASH_TYPE_SHA1, + 20, + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + hash_etalon_1, + hash_etalon_2, + hash_etalon_3, + "a9993e364706816aba3e25717850c26c9cd0d89d", + "84983e441c3bd26ebaae4aa1f95129e5e54670f1", + "34aa973cd4c4daa4f61eeb2bdbad27316534016f", + "56309c2dbe04a348ec801ca5f40b035bad01f907"); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (sha2_224_test) +{ + const puchar hash_etalon_1[] = { 35, 9, 125, 34, 52, 5, 216, 34, 134, 66, + 164, 119, 189, 162, 85, 179, 42, 173, 188, 228, + 189, 160, 179, 247, 227, 108, 157, 167}; + const puchar hash_etalon_2[] = {117, 56, 139, 22, 81, 39, 118, 204, 93, 186, + 93, 161, 253, 137, 1, 80, 176, 198, 69, 92, + 180, 245, 139, 25, 82, 82, 37, 37}; + const puchar hash_etalon_3[] = { 32, 121, 70, 85, 152, 12, 145, 216, 187, 180, + 193, 234, 151, 97, 138, 75, 240, 63, 66, 88, + 25, 72, 178, 238, 78, 231, 173, 103, }; + + p_libsys_init (); + + general_hash_test (P_CRYPTO_HASH_TYPE_SHA2_224, + 28, + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + hash_etalon_1, + hash_etalon_2, + hash_etalon_3, + "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", + "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525", + "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67", + "4cf3d45b57e0d54981c4d86954e8378168d5a9f6ceab9e0aae5dd2f6"); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (sha2_256_test) +{ + const puchar hash_etalon_1[] = {186, 120, 22, 191, 143, 1, 207, 234, + 65, 65, 64, 222, 93, 174, 34, 35, + 176, 3, 97, 163, 150, 23, 122, 156, + 180, 16, 255, 97, 242, 0, 21, 173}; + const puchar hash_etalon_2[] = { 36, 141, 106, 97, 210, 6, 56, 184, + 229, 192, 38, 147, 12, 62, 96, 57, + 163, 60, 228, 89, 100, 255, 33, 103, + 246, 236, 237, 212, 25, 219, 6, 193}; + const puchar hash_etalon_3[] = {205, 199, 110, 92, 153, 20, 251, 146, + 129, 161, 199, 226, 132, 215, 62, 103, + 241, 128, 154, 72, 164, 151, 32, 14, + 4, 109, 57, 204, 199, 17, 44, 208}; + + p_libsys_init (); + + general_hash_test (P_CRYPTO_HASH_TYPE_SHA2_256, + 32, + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + hash_etalon_1, + hash_etalon_2, + hash_etalon_3, + "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", + "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1", + "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0", + "4c2d7749e1b711ca652fda20dd29fe378fd9988f19eadadfa570682e2c55349f"); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (sha2_384_test) +{ + const puchar hash_etalon_1[] = {203, 0, 117, 63, 69, 163, 94, 139, 181, 160, 61, 105, + 154, 198, 80, 7, 39, 44, 50, 171, 14, 222, 209, 99, + 26, 139, 96, 90, 67, 255, 91, 237, 128, 134, 7, 43, + 161, 231, 204, 35, 88, 186, 236, 161, 52, 200, 37, 167}; + const puchar hash_etalon_2[] = { 51, 145, 253, 221, 252, 141, 199, 57, 55, 7, 166, 91, + 27, 71, 9, 57, 124, 248, 177, 209, 98, 175, 5, 171, + 254, 143, 69, 13, 229, 243, 107, 198, 176, 69, 90, 133, + 32, 188, 78, 111, 95, 233, 91, 31, 227, 200, 69, 43}; + const puchar hash_etalon_3[] = {157, 14, 24, 9, 113, 100, 116, 203, 8, 110, 131, 78, + 49, 10, 74, 28, 237, 20, 158, 156, 0, 242, 72, 82, + 121, 114, 206, 197, 112, 76, 42, 91, 7, 184, 179, 220, + 56, 236, 196, 235, 174, 151, 221, 216, 127, 61, 137, 133}; + + p_libsys_init (); + + general_hash_test (P_CRYPTO_HASH_TYPE_SHA2_384, + 48, + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + hash_etalon_1, + hash_etalon_2, + hash_etalon_3, + "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7", + "3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b", + "9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985", + "533e016fd92dd8a8c339328bb5401c3e700e27cd72d8230059e1d4583a506fe8187607bf899a86961af2bf5521b359eb"); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (sha2_512_test) +{ + const puchar hash_etalon_1[] = {221, 175, 53, 161, 147, 97, 122, 186, + 204, 65, 115, 73, 174, 32, 65, 49, + 18, 230, 250, 78, 137, 169, 126, 162, + 10, 158, 238, 230, 75, 85, 211, 154, + 33, 146, 153, 42, 39, 79, 193, 168, + 54, 186, 60, 35, 163, 254, 235, 189, + 69, 77, 68, 35, 100, 60, 232, 14, + 42, 154, 201, 79, 165, 76, 164, 159}; + const puchar hash_etalon_2[] = { 32, 74, 143, 198, 221, 168, 47, 10, + 12, 237, 123, 235, 142, 8, 164, 22, + 87, 193, 110, 244, 104, 178, 40, 168, + 39, 155, 227, 49, 167, 3, 195, 53, + 150, 253, 21, 193, 59, 27, 7, 249, + 170, 29, 59, 234, 87, 120, 156, 160, + 49, 173, 133, 199, 167, 29, 215, 3, + 84, 236, 99, 18, 56, 202, 52, 69}; + const puchar hash_etalon_3[] = {231, 24, 72, 61, 12, 231, 105, 100, + 78, 46, 66, 199, 188, 21, 180, 99, + 142, 31, 152, 177, 59, 32, 68, 40, + 86, 50, 168, 3, 175, 169, 115, 235, + 222, 15, 242, 68, 135, 126, 166, 10, + 76, 176, 67, 44, 229, 119, 195, 27, + 235, 0, 156, 92, 44, 73, 170, 46, + 78, 173, 178, 23, 173, 140, 192, 155}; + + p_libsys_init (); + + general_hash_test (P_CRYPTO_HASH_TYPE_SHA2_512, + 64, + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + hash_etalon_1, + hash_etalon_2, + hash_etalon_3, + "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f", + "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445", + "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b", + "411525772d02eef0e2ce1107d89b79b8cf6d704e88d4509f726c963d411df6df178c1c9473718f70b0e06c2fda6a9c25f6c91a925849f372634d5f63e6047a20"); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (sha3_224_test) +{ + const puchar hash_etalon_1[] = {230, 66, 130, 76, 63, 140, 242, 74, 208, 146, + 52, 238, 125, 60, 118, 111, 201, 163, 165, 22, + 141, 12, 148, 173, 115, 180, 111, 223}; + const puchar hash_etalon_2[] = {138, 36, 16, 139, 21, 74, 218, 33, 201, 253, + 85, 116, 73, 68, 121, 186, 92, 126, 122, 183, + 110, 242, 100, 234, 208, 252, 206, 51}; + const puchar hash_etalon_3[] = {214, 147, 53, 185, 51, 37, 25, 46, 81, 106, + 145, 46, 109, 25, 161, 92, 181, 28, 110, 213, + 193, 82, 67, 231, 167, 253, 101, 60}; + + p_libsys_init (); + + general_hash_test (P_CRYPTO_HASH_TYPE_SHA3_224, + 28, + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + hash_etalon_1, + hash_etalon_2, + hash_etalon_3, + "e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf", + "8a24108b154ada21c9fd5574494479ba5c7e7ab76ef264ead0fcce33", + "d69335b93325192e516a912e6d19a15cb51c6ed5c15243e7a7fd653c", + "425fbad801bf675651dcf61af1138831480b562e714c70a2a0050ad3"); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (sha3_256_test) +{ + const puchar hash_etalon_1[] = { 58, 152, 93, 167, 79, 226, 37, 178, + 4, 92, 23, 45, 107, 211, 144, 189, + 133, 95, 8, 110, 62, 157, 82, 91, + 70, 191, 226, 69, 17, 67, 21, 50}; + const puchar hash_etalon_2[] = { 65, 192, 219, 162, 169, 214, 36, 8, + 73, 16, 3, 118, 168, 35, 94, 44, + 130, 225, 185, 153, 138, 153, 158, 33, + 219, 50, 221, 151, 73, 109, 51, 118}; + const puchar hash_etalon_3[] = { 92, 136, 117, 174, 71, 74, 54, 52, + 186, 79, 213, 94, 200, 91, 255, 214, + 97, 243, 42, 202, 117, 198, 214, 153, + 208, 205, 203, 108, 17, 88, 145, 193}; + + p_libsys_init (); + + general_hash_test (P_CRYPTO_HASH_TYPE_SHA3_256, + 32, + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + hash_etalon_1, + hash_etalon_2, + hash_etalon_3, + "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532", + "41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376", + "5c8875ae474a3634ba4fd55ec85bffd661f32aca75c6d699d0cdcb6c115891c1", + "e37ed9f31da3d61740e04c3124a2da5dbe8be0a2ef5c8b5932d45eb1958219e2"); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (sha3_384_test) +{ + const puchar hash_etalon_1[] = {236, 1, 73, 130, 136, 81, 111, 201, 38, 69, 159, 88, + 226, 198, 173, 141, 249, 180, 115, 203, 15, 192, 140, 37, + 150, 218, 124, 240, 228, 155, 228, 178, 152, 216, 140, 234, + 146, 122, 199, 245, 57, 241, 237, 242, 40, 55, 109, 37}; + const puchar hash_etalon_2[] = {153, 28, 102, 87, 85, 235, 58, 75, 107, 189, 251, 117, + 199, 138, 73, 46, 140, 86, 162, 44, 92, 77, 126, 66, + 155, 253, 188, 50, 185, 212, 173, 90, 160, 74, 31, 7, + 110, 98, 254, 161, 158, 239, 81, 172, 208, 101, 124, 34}; + const puchar hash_etalon_3[] = {238, 233, 226, 77, 120, 193, 133, 83, 55, 152, 52, 81, + 223, 151, 200, 173, 158, 237, 242, 86, 198, 51, 79, 142, + 148, 141, 37, 45, 94, 14, 118, 132, 122, 160, 119, 77, + 219, 144, 168, 66, 25, 13, 44, 85, 139, 75, 131, 64}; + + p_libsys_init (); + + general_hash_test (P_CRYPTO_HASH_TYPE_SHA3_384, + 48, + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + hash_etalon_1, + hash_etalon_2, + hash_etalon_3, + "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25", + "991c665755eb3a4b6bbdfb75c78a492e8c56a22c5c4d7e429bfdbc32b9d4ad5aa04a1f076e62fea19eef51acd0657c22", + "eee9e24d78c1855337983451df97c8ad9eedf256c6334f8e948d252d5e0e76847aa0774ddb90a842190d2c558b4b8340", + "3836508de3aa893ad8bd18df238a79e534bc55a6fae84a557bde0820ccfc3ad58e3eaab29a7d0d3bfc071c6d69b2e9d3"); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (sha3_512_test) +{ + const puchar hash_etalon_1[] = {183, 81, 133, 11, 26, 87, 22, 138, + 86, 147, 205, 146, 75, 107, 9, 110, + 8, 246, 33, 130, 116, 68, 247, 13, + 136, 79, 93, 2, 64, 210, 113, 46, + 16, 225, 22, 233, 25, 42, 243, 201, + 26, 126, 197, 118, 71, 227, 147, 64, + 87, 52, 11, 76, 244, 8, 213, 165, + 101, 146, 248, 39, 78, 236, 83, 240}; + const puchar hash_etalon_2[] = { 4, 163, 113, 232, 78, 207, 181, 184, + 183, 124, 180, 134, 16, 252, 168, 24, + 45, 212, 87, 206, 111, 50, 106, 15, + 211, 215, 236, 47, 30, 145, 99, 109, + 238, 105, 31, 190, 12, 152, 83, 2, + 186, 27, 13, 141, 199, 140, 8, 99, + 70, 181, 51, 180, 156, 3, 13, 153, + 162, 125, 175, 17, 57, 214, 231, 94}; + const puchar hash_etalon_3[] = { 60, 58, 135, 109, 161, 64, 52, 171, + 96, 98, 124, 7, 123, 185, 143, 126, + 18, 10, 42, 83, 112, 33, 45, 255, + 179, 56, 90, 24, 212, 243, 136, 89, + 237, 49, 29, 10, 157, 81, 65, 206, + 156, 197, 198, 110, 230, 137, 178, 102, + 168, 170, 24, 172, 232, 40, 42, 14, + 13, 181, 150, 201, 11, 10, 123, 135}; + + p_libsys_init (); + + general_hash_test (P_CRYPTO_HASH_TYPE_SHA3_512, + 64, + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + hash_etalon_1, + hash_etalon_2, + hash_etalon_3, + "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0", + "04a371e84ecfb5b8b77cb48610fca8182dd457ce6f326a0fd3d7ec2f1e91636dee691fbe0c985302ba1b0d8dc78c086346b533b49c030d99a27daf1139d6e75e", + "3c3a876da14034ab60627c077bb98f7e120a2a5370212dffb3385a18d4f38859ed311d0a9d5141ce9cc5c66ee689b266a8aa18ace8282a0e0db596c90b0a7b87", + "16f59fe0b4344af86b37eb145afe41e9dadb45279d074c5bf5c649dd3d2952e47c0ac3a59ea19dc8395d04e8a72fddd9307b839c35fc4bc44a0463003b80dcf1"); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (gost3411_94_test) +{ + PCryptoHash *gost3411_94_hash; + pchar *hash_str; + const puchar hash_etalon_1[] = { 44, 239, 194, 247, 183, 189, 197, 20, + 225, 142, 165, 127, 167, 79, 243, 87, + 231, 250, 23, 214, 82, 199, 95, 105, + 203, 27, 231, 137, 62, 222, 72, 235}; + const puchar hash_etalon_2[] = {195, 115, 12, 92, 188, 202, 207, 145, + 90, 194, 146, 103, 111, 33, 232, 189, + 78, 247, 83, 49, 217, 64, 94, 95, + 26, 97, 220, 49, 48, 166, 80, 17}; + const puchar hash_etalon_3[] = {134, 147, 40, 122, 166, 47, 148, 120, + 247, 203, 49, 46, 192, 134, 107, 108, + 78, 74, 15, 17, 22, 4, 65, 232, + 244, 255, 205, 39, 21, 221, 85, 79}; + + p_libsys_init (); + + general_hash_test (P_CRYPTO_HASH_TYPE_GOST, + 32, + "This is message, length=32 bytes", + "Suppose the original message has length = 50 bytes", + hash_etalon_1, + hash_etalon_2, + hash_etalon_3, + "2cefc2f7b7bdc514e18ea57fa74ff357e7fa17d652c75f69cb1be7893ede48eb", + "c3730c5cbccacf915ac292676f21e8bd4ef75331d9405e5f1a61dc3130a65011", + "8693287aa62f9478f7cb312ec0866b6c4e4a0f11160441e8f4ffcd2715dd554f", + "3738fb45a7f0de6a5447163c0b441ead7a23e48e7af553829dc4300a99f86343"); + + gost3411_94_hash = p_crypto_hash_new (P_CRYPTO_HASH_TYPE_GOST); + + P_TEST_REQUIRE (gost3411_94_hash != NULL); + + /* Repeat test */ + p_crypto_hash_update (gost3411_94_hash, (const puchar *) "message digest", 14); + p_crypto_hash_update (gost3411_94_hash, (const puchar *) "message digest", 14); + p_crypto_hash_update (gost3411_94_hash, (const puchar *) "message digest", 14); + p_crypto_hash_update (gost3411_94_hash, (const puchar *) "message digest", 14); + + hash_str = p_crypto_hash_get_string (gost3411_94_hash); + P_TEST_CHECK (strcmp (hash_str, "9c7b5288c8b3343b29e8ee4a5579593bd90131db7f6fed9b13af4399698b5d29") == 0); + p_free (hash_str); + + p_crypto_hash_reset (gost3411_94_hash); + p_crypto_hash_free (gost3411_94_hash); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (pcryptohash_nomem_test); + P_TEST_SUITE_RUN_CASE (pcryptohash_invalid_test); + P_TEST_SUITE_RUN_CASE (md5_test); + P_TEST_SUITE_RUN_CASE (sha1_test); + P_TEST_SUITE_RUN_CASE (sha2_224_test); + P_TEST_SUITE_RUN_CASE (sha2_256_test); + P_TEST_SUITE_RUN_CASE (sha2_384_test); + P_TEST_SUITE_RUN_CASE (sha2_512_test); + P_TEST_SUITE_RUN_CASE (sha3_224_test); + P_TEST_SUITE_RUN_CASE (sha3_256_test); + P_TEST_SUITE_RUN_CASE (sha3_384_test); + P_TEST_SUITE_RUN_CASE (sha3_512_test); + P_TEST_SUITE_RUN_CASE (gost3411_94_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/pdir_test.cpp b/3rdparty/plibsys/tests/pdir_test.cpp new file mode 100644 index 0000000..7b1689d --- /dev/null +++ b/3rdparty/plibsys/tests/pdir_test.cpp @@ -0,0 +1,248 @@ +/* + * The MIT License + * + * Copyright (C) 2015-2017 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +#include + +P_TEST_MODULE_INIT (); + +#define PDIR_ENTRY_DIR "test_2" +#define PDIR_ENTRY_FILE "test_file.txt" +#define PDIR_TEST_DIR "." P_DIR_SEPARATOR "pdir_test_dir" +#define PDIR_TEST_DIR_IN "." P_DIR_SEPARATOR "pdir_test_dir" P_DIR_SEPARATOR "test_2" +#define PDIR_TEST_FILE "." P_DIR_SEPARATOR "pdir_test_dir" P_DIR_SEPARATOR "test_file.txt" + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + P_UNUSED (block); + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" void pmem_free (ppointer block) +{ + P_UNUSED (block); +} + +P_TEST_CASE_BEGIN (pdir_nomem_test) +{ + p_libsys_init (); + + PMemVTable vtable; + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + + /* Cleanup previous run */ + p_dir_remove (PDIR_TEST_DIR_IN, NULL); + p_dir_remove (PDIR_TEST_DIR, NULL); + + P_TEST_REQUIRE (p_dir_create (PDIR_TEST_DIR, 0777, NULL) == TRUE); + P_TEST_REQUIRE (p_dir_create (PDIR_TEST_DIR_IN, 0777, NULL) == TRUE); + + P_TEST_CHECK (p_dir_new (PDIR_TEST_DIR"/", NULL) == NULL); + + /* Revert memory management back */ + p_mem_restore_vtable (); + + /* Try out of memory when iterating */ + PDir *dir = p_dir_new (PDIR_TEST_DIR"/", NULL); + P_TEST_CHECK (dir != NULL); + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + + P_TEST_CHECK (p_dir_get_next_entry (dir, NULL) == NULL); + + /* Cleanup */ + p_mem_restore_vtable (); + + p_dir_free (dir); + + P_TEST_CHECK (p_dir_remove (PDIR_TEST_DIR_IN, NULL) == TRUE); + P_TEST_CHECK (p_dir_remove (PDIR_TEST_DIR, NULL) == TRUE); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pdir_general_test) +{ + p_libsys_init (); + + P_TEST_CHECK (p_dir_new (NULL, NULL) == NULL); + P_TEST_CHECK (p_dir_new ("." P_DIR_SEPARATOR "pdir_test_dir_new", NULL) == NULL); + P_TEST_CHECK (p_dir_create (NULL, -1, NULL) == FALSE); +#ifndef P_OS_VMS + P_TEST_CHECK (p_dir_create ("." P_DIR_SEPARATOR "pdir_test_dir_new" P_DIR_SEPARATOR "test_dir", -1, NULL) == FALSE); +#endif + P_TEST_CHECK (p_dir_remove (NULL, NULL) == FALSE); + P_TEST_CHECK (p_dir_remove ("." P_DIR_SEPARATOR "pdir_test_dir_new", NULL) == FALSE); + P_TEST_CHECK (p_dir_is_exists (NULL) == FALSE); + P_TEST_CHECK (p_dir_is_exists ("." P_DIR_SEPARATOR "pdir_test_dir_new") == FALSE); + P_TEST_CHECK (p_dir_get_path (NULL) == NULL); + P_TEST_CHECK (p_dir_get_next_entry (NULL, NULL) == NULL); + P_TEST_CHECK (p_dir_rewind (NULL, NULL) == FALSE); + + p_dir_entry_free (NULL); + p_dir_free (NULL); + + /* Cleanup previous run */ + p_dir_remove (PDIR_TEST_DIR_IN, NULL); + p_dir_remove (PDIR_TEST_DIR, NULL); + + P_TEST_REQUIRE (p_dir_create (PDIR_TEST_DIR, 0777, NULL) == TRUE); + P_TEST_REQUIRE (p_dir_create (PDIR_TEST_DIR, 0777, NULL) == TRUE); + P_TEST_REQUIRE (p_dir_create (PDIR_TEST_DIR_IN, 0777, NULL) == TRUE); + P_TEST_REQUIRE (p_dir_create (PDIR_TEST_DIR_IN, 0777, NULL) == TRUE); + + FILE *file = fopen (PDIR_TEST_FILE, "w"); + P_TEST_REQUIRE (file != NULL); + P_TEST_REQUIRE (p_file_is_exists (PDIR_TEST_FILE) == TRUE); + + fprintf (file, "This is a test file string\n"); + + P_TEST_CHECK (fclose (file) == 0); + + P_TEST_CHECK (p_dir_is_exists (PDIR_TEST_DIR) == TRUE); + P_TEST_CHECK (p_dir_is_exists (PDIR_TEST_DIR_IN) == TRUE); + + PDir *dir = p_dir_new (PDIR_TEST_DIR"/", NULL); + + P_TEST_CHECK (dir != NULL); + + pint dir_count = 0; + pint file_count = 0; + pboolean has_entry_dir = FALSE; + pboolean has_entry_file = FALSE; + + PDirEntry *entry; + + while ((entry = p_dir_get_next_entry (dir, NULL)) != NULL) { + P_TEST_CHECK (entry->name != NULL); + + switch (entry->type) { + case P_DIR_ENTRY_TYPE_DIR: + ++dir_count; + break; + case P_DIR_ENTRY_TYPE_FILE: + ++file_count; + break; + case P_DIR_ENTRY_TYPE_OTHER: + default: + break; + } + + if (strcmp (entry->name, PDIR_ENTRY_DIR) == 0) + has_entry_dir = TRUE; + else if (strcmp (entry->name, PDIR_ENTRY_FILE) == 0) + has_entry_file = TRUE; + + p_dir_entry_free (entry); + } + + P_TEST_CHECK (dir_count > 0 && dir_count < 4); + P_TEST_CHECK (file_count == 1); + P_TEST_CHECK (has_entry_dir == TRUE); + P_TEST_CHECK (has_entry_file == TRUE); + + P_TEST_CHECK (p_dir_rewind (dir, NULL) == TRUE); + + pint dir_count_2 = 0; + pint file_count_2 = 0; + has_entry_dir = FALSE; + has_entry_file = FALSE; + + while ((entry = p_dir_get_next_entry (dir, NULL)) != NULL) { + P_TEST_CHECK (entry->name != NULL); + + switch (entry->type) { + case P_DIR_ENTRY_TYPE_DIR: + ++dir_count_2; + break; + case P_DIR_ENTRY_TYPE_FILE: + ++file_count_2; + break; + case P_DIR_ENTRY_TYPE_OTHER: + default: + break; + } + + if (strcmp (entry->name, PDIR_ENTRY_DIR) == 0) + has_entry_dir = TRUE; + else if (strcmp (entry->name, PDIR_ENTRY_FILE) == 0) + has_entry_file = TRUE; + + p_dir_entry_free (entry); + } + + P_TEST_CHECK (dir_count_2 > 0 && dir_count_2 < 4); + P_TEST_CHECK (file_count_2 == 1); + P_TEST_CHECK (has_entry_dir == TRUE); + P_TEST_CHECK (has_entry_file == TRUE); + + /* Compare two previous attempts */ + P_TEST_CHECK (dir_count == dir_count_2); + P_TEST_CHECK (file_count == file_count_2); + + /* Remove all stuff */ + P_TEST_CHECK (p_file_remove (PDIR_TEST_FILE, NULL) == TRUE); + P_TEST_CHECK (p_dir_remove (PDIR_TEST_DIR, NULL) == FALSE); + P_TEST_CHECK (p_dir_remove (PDIR_TEST_DIR_IN, NULL) == TRUE); + P_TEST_CHECK (p_dir_remove (PDIR_TEST_DIR, NULL) == TRUE); + + P_TEST_CHECK (p_dir_is_exists (PDIR_TEST_DIR_IN) == FALSE); + P_TEST_CHECK (p_dir_is_exists (PDIR_TEST_DIR) == FALSE); + + pchar *orig_path = p_dir_get_path (dir); + P_TEST_CHECK (strcmp (orig_path, PDIR_TEST_DIR"/") == 0); + p_free (orig_path); + + p_dir_free (dir); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (pdir_nomem_test); + P_TEST_SUITE_RUN_CASE (pdir_general_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/perror_test.cpp b/3rdparty/plibsys/tests/perror_test.cpp new file mode 100644 index 0000000..1db2f4d --- /dev/null +++ b/3rdparty/plibsys/tests/perror_test.cpp @@ -0,0 +1,236 @@ +/* + * The MIT License + * + * Copyright (C) 2016-2017 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +#include + +P_TEST_MODULE_INIT (); + +#define PERROR_TEST_MESSAGE "PError test error message" +#define PERROR_TEST_MESSAGE_2 "Another PError test error message" + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + P_UNUSED (block); + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" void pmem_free (ppointer block) +{ + P_UNUSED (block); +} + +P_TEST_CASE_BEGIN (perror_nomem_test) +{ + p_libsys_init (); + + PError *error = p_error_new_literal (0, 0, NULL); + P_TEST_CHECK (error != NULL); + + PMemVTable vtable; + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + + P_TEST_CHECK (p_error_new () == NULL); + P_TEST_CHECK (p_error_new_literal (0, 0, NULL) == NULL); + P_TEST_CHECK (p_error_copy (error) == NULL); + + p_mem_restore_vtable (); + + p_error_free (error); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (perror_invalid_test) +{ + p_libsys_init (); + + P_TEST_CHECK (p_error_get_message (NULL) == NULL); + P_TEST_CHECK (p_error_get_code (NULL) == 0); + P_TEST_CHECK (p_error_get_native_code (NULL) == 0); + P_TEST_CHECK (p_error_get_domain (NULL) == P_ERROR_DOMAIN_NONE); + P_TEST_CHECK (p_error_copy (NULL) == NULL); + + PError *error = (PError *) 0x1; + + p_error_set_code (NULL, 0); + p_error_set_native_code (NULL, 0); + p_error_set_message (NULL, NULL); + + p_error_set_error (NULL, 0, 0, NULL); + p_error_set_error_p (NULL, 0, 0, NULL); + + p_error_set_error_p (&error, 0, 0, NULL); + P_TEST_CHECK (error == (PError *) 0x1); + + p_error_clear (NULL); + p_error_free (NULL); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (perror_general_test) +{ + p_libsys_init (); + + /* Empty initialization test */ + PError *error = p_error_new (); + + P_TEST_CHECK (error != NULL); + P_TEST_CHECK (p_error_get_code (error) == 0); + P_TEST_CHECK (p_error_get_domain (error) == P_ERROR_DOMAIN_NONE); + P_TEST_CHECK (p_error_get_message (error) == NULL); + + PError *copy_error = p_error_copy (error); + + P_TEST_CHECK (copy_error != NULL); + P_TEST_CHECK (p_error_get_code (copy_error) == 0); + P_TEST_CHECK (p_error_get_domain (error) == P_ERROR_DOMAIN_NONE); + P_TEST_CHECK (p_error_get_message (copy_error) == NULL); + + p_error_free (copy_error); + copy_error = NULL; + + p_error_set_error (error, (pint) P_ERROR_DOMAIN_IO, -10, PERROR_TEST_MESSAGE); + + P_TEST_CHECK (p_error_get_code (error) == (pint) P_ERROR_DOMAIN_IO); + P_TEST_CHECK (p_error_get_native_code (error) == -10); + P_TEST_CHECK (p_error_get_domain (error) == P_ERROR_DOMAIN_IO); + P_TEST_CHECK (strcmp (p_error_get_message (error), PERROR_TEST_MESSAGE) == 0); + + /* Change internal data */ + p_error_set_code (error, (pint) P_ERROR_DOMAIN_IPC); + p_error_set_native_code (error, -20); + p_error_set_message (error, PERROR_TEST_MESSAGE_2); + + P_TEST_CHECK (p_error_get_code (error) == (pint) P_ERROR_DOMAIN_IPC); + P_TEST_CHECK (p_error_get_native_code (error) == -20); + P_TEST_CHECK (p_error_get_domain (error) == P_ERROR_DOMAIN_IPC); + P_TEST_CHECK (strcmp (p_error_get_message (error), PERROR_TEST_MESSAGE_2) == 0); + + /* Revert data back */ + p_error_set_code (error, 10); + p_error_set_native_code (error, -10); + p_error_set_message (error, PERROR_TEST_MESSAGE); + + copy_error = p_error_copy (error); + + P_TEST_CHECK (copy_error != NULL); + P_TEST_CHECK (p_error_get_code (copy_error) == 10); + P_TEST_CHECK (p_error_get_domain (error) == P_ERROR_DOMAIN_NONE); + P_TEST_CHECK (p_error_get_native_code (copy_error) == -10); + + P_TEST_CHECK (strcmp (p_error_get_message (copy_error), PERROR_TEST_MESSAGE) == 0); + + p_error_free (copy_error); + copy_error = NULL; + + p_error_set_error (error, 20, -20, PERROR_TEST_MESSAGE_2); + + P_TEST_CHECK (p_error_get_code (error) == 20); + P_TEST_CHECK (p_error_get_native_code (error) == -20); + P_TEST_CHECK (p_error_get_domain (error) == P_ERROR_DOMAIN_NONE); + P_TEST_CHECK (strcmp (p_error_get_message (error), PERROR_TEST_MESSAGE_2) == 0); + + p_error_clear (error); + + P_TEST_CHECK (p_error_get_code (error) == 0); + P_TEST_CHECK (p_error_get_native_code (error) == 0); + P_TEST_CHECK (p_error_get_domain (error) == P_ERROR_DOMAIN_NONE); + P_TEST_CHECK (p_error_get_message (error) == NULL); + + p_error_free (error); + error = NULL; + + /* Literal initialization test */ + error = p_error_new_literal (30, -30, PERROR_TEST_MESSAGE); + + P_TEST_CHECK (p_error_get_code (error) == 30); + P_TEST_CHECK (p_error_get_native_code (error) == -30); + P_TEST_CHECK (p_error_get_domain (error) == P_ERROR_DOMAIN_NONE); + P_TEST_CHECK (strcmp (p_error_get_message (error), PERROR_TEST_MESSAGE) == 0); + + copy_error = p_error_copy (error); + + P_TEST_CHECK (copy_error != NULL); + P_TEST_CHECK (p_error_get_code (copy_error) == 30); + P_TEST_CHECK (p_error_get_native_code (copy_error) == -30); + P_TEST_CHECK (p_error_get_domain (error) == P_ERROR_DOMAIN_NONE); + P_TEST_CHECK (strcmp (p_error_get_message (copy_error), PERROR_TEST_MESSAGE) == 0); + + p_error_free (copy_error); + p_error_free (error); + + /* Through the double pointer */ + error = NULL; + p_error_set_error_p (&error, 10, -10, PERROR_TEST_MESSAGE); + + P_TEST_CHECK (p_error_get_code (error) == 10); + P_TEST_CHECK (p_error_get_native_code (error) == -10); + P_TEST_CHECK (p_error_get_domain (error) == P_ERROR_DOMAIN_NONE); + P_TEST_CHECK (strcmp (p_error_get_message (error), PERROR_TEST_MESSAGE) == 0); + + p_error_free (error); + + /* System codes */ + p_error_set_last_system (10); + P_TEST_CHECK (p_error_get_last_system () == 10); + p_error_set_last_system (0); + P_TEST_CHECK (p_error_get_last_system () == 0); + +#ifndef P_OS_OS2 + p_error_set_last_net (20); + P_TEST_CHECK (p_error_get_last_net () == 20); + p_error_set_last_net (0); + P_TEST_CHECK (p_error_get_last_net () == 0); +#endif + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (perror_nomem_test); + P_TEST_SUITE_RUN_CASE (perror_invalid_test); + P_TEST_SUITE_RUN_CASE (perror_general_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/pfile_test.cpp b/3rdparty/plibsys/tests/pfile_test.cpp new file mode 100644 index 0000000..7f3c643 --- /dev/null +++ b/3rdparty/plibsys/tests/pfile_test.cpp @@ -0,0 +1,61 @@ +/* + * The MIT License + * + * Copyright (C) 2013-2017 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +#include + +P_TEST_MODULE_INIT (); + +#define PFILE_TEST_FILE "." P_DIR_SEPARATOR "pfile_test_file.txt" + +P_TEST_CASE_BEGIN (pfile_general_test) +{ + p_libsys_init (); + + P_TEST_CHECK (p_file_remove (NULL, NULL) == FALSE); + + P_TEST_CHECK (p_file_is_exists (PFILE_TEST_FILE) == FALSE); + P_TEST_CHECK (p_file_remove ("." P_DIR_SEPARATOR" pfile_test_file_remove.txt", NULL) == FALSE); + + FILE *file = fopen (PFILE_TEST_FILE, "w"); + P_TEST_REQUIRE (file != NULL); + P_TEST_CHECK (p_file_is_exists (PFILE_TEST_FILE) == TRUE); + + fprintf (file, "This is a test file string\n"); + + P_TEST_CHECK (fclose (file) == 0); + P_TEST_CHECK (p_file_remove (PFILE_TEST_FILE, NULL) == TRUE); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (pfile_general_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/phashtable_test.cpp b/3rdparty/plibsys/tests/phashtable_test.cpp new file mode 100644 index 0000000..2975fde --- /dev/null +++ b/3rdparty/plibsys/tests/phashtable_test.cpp @@ -0,0 +1,320 @@ +/* + * The MIT License + * + * Copyright (C) 2013-2017 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +#include +#include + +P_TEST_MODULE_INIT (); + +#define PHASHTABLE_STRESS_COUNT 10000 + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + P_UNUSED (block); + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" void pmem_free (ppointer block) +{ + P_UNUSED (block); +} + +static int test_hash_table_values (pconstpointer a, pconstpointer b) +{ + return a > b ? 0 : (a < b ? -1 : 1); +} + +P_TEST_CASE_BEGIN (phashtable_nomem_test) +{ + p_libsys_init (); + + PHashTable *table = p_hash_table_new (); + P_TEST_CHECK (table != NULL); + + PMemVTable vtable; + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + + P_TEST_CHECK (p_hash_table_new () == NULL); + p_hash_table_insert (table, PINT_TO_POINTER (1), PINT_TO_POINTER (10)); + P_TEST_CHECK (p_hash_table_keys (table) == NULL); + P_TEST_CHECK (p_hash_table_values (table) == NULL); + + p_mem_restore_vtable (); + + p_hash_table_free (table); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (phashtable_invalid_test) +{ + p_libsys_init (); + + P_TEST_CHECK (p_hash_table_keys (NULL) == NULL); + P_TEST_CHECK (p_hash_table_values (NULL) == NULL); + P_TEST_CHECK (p_hash_table_lookup (NULL, NULL) == NULL); + P_TEST_CHECK (p_hash_table_lookup_by_value (NULL, NULL, NULL) == NULL); + p_hash_table_insert (NULL, NULL, NULL); + p_hash_table_remove (NULL, NULL); + p_hash_table_free (NULL); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (phashtable_general_test) +{ + PHashTable *table = NULL; + PList *list = NULL; + + p_libsys_init (); + + table = p_hash_table_new (); + P_TEST_REQUIRE (table != NULL); + + /* Test for NULL key */ + p_hash_table_insert (table, NULL, PINT_TO_POINTER (1)); + list = p_hash_table_keys (table); + P_TEST_REQUIRE (p_list_length (list) == 1); + P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) == 0); + p_list_free (list); + list = p_hash_table_values (table); + P_TEST_REQUIRE (p_list_length (list) == 1); + P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) == 1); + p_list_free (list); + p_hash_table_remove (table, NULL); + + /* Test for insertion */ + p_hash_table_insert (table, PINT_TO_POINTER (1), PINT_TO_POINTER (10)); + list = p_hash_table_values (table); + P_TEST_REQUIRE (list != NULL); + P_TEST_REQUIRE (p_list_length (list) == 1); + P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) == 10); + p_list_free (list); + list = p_hash_table_keys (table); + P_TEST_REQUIRE (list != NULL); + P_TEST_REQUIRE (p_list_length (list) == 1); + P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) == 1); + p_list_free (list); + + /* False remove */ + p_hash_table_remove (table, PINT_TO_POINTER (2)); + list = p_hash_table_values (table); + P_TEST_REQUIRE (list != NULL); + P_TEST_REQUIRE (p_list_length (list) == 1); + P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) == 10); + p_list_free (list); + list = p_hash_table_keys (table); + P_TEST_REQUIRE (list != NULL); + P_TEST_REQUIRE (p_list_length (list) == 1); + P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) == 1); + p_list_free (list); + + /* Replace existing value */ + p_hash_table_insert (table, PINT_TO_POINTER (1), PINT_TO_POINTER (15)); + list = p_hash_table_values (table); + P_TEST_REQUIRE (list != NULL); + P_TEST_REQUIRE (p_list_length (list) == 1); + P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) == 15); + p_list_free (list); + list = p_hash_table_keys (table); + P_TEST_REQUIRE (list != NULL); + P_TEST_REQUIRE (p_list_length (list) == 1); + P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) == 1); + p_list_free (list); + + /* More insertion */ + p_hash_table_insert (table, PINT_TO_POINTER (2), PINT_TO_POINTER (20)); + p_hash_table_insert (table, PINT_TO_POINTER (3), PINT_TO_POINTER (30)); + + list = p_hash_table_values (table); + P_TEST_REQUIRE (list != NULL); + P_TEST_REQUIRE (p_list_length (list) == 3); + P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) + + PPOINTER_TO_INT (list->next->data) + + PPOINTER_TO_INT (list->next->next->data) == 65); + p_list_free (list); + list = p_hash_table_keys (table); + P_TEST_REQUIRE (list != NULL); + P_TEST_REQUIRE (p_list_length (list) == 3); + P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) + + PPOINTER_TO_INT (list->next->data) + + PPOINTER_TO_INT (list->next->next->data) == 6); + p_list_free (list); + + P_TEST_CHECK (PPOINTER_TO_INT (p_hash_table_lookup (table, PINT_TO_POINTER (1))) == 15); + P_TEST_CHECK (PPOINTER_TO_INT (p_hash_table_lookup (table, PINT_TO_POINTER (2))) == 20); + P_TEST_CHECK (PPOINTER_TO_INT (p_hash_table_lookup (table, PINT_TO_POINTER (3))) == 30); + P_TEST_CHECK (p_hash_table_lookup (table, PINT_TO_POINTER (4)) == (ppointer) -1); + p_hash_table_insert (table, PINT_TO_POINTER (22), PINT_TO_POINTER (20)); + + list = p_hash_table_lookup_by_value (table, + PINT_TO_POINTER (19), + (PCompareFunc) test_hash_table_values); + P_TEST_REQUIRE (list != NULL); + P_TEST_REQUIRE (p_list_length (list) == 3); + P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) + + PPOINTER_TO_INT (list->next->data) + + PPOINTER_TO_INT (list->next->next->data) == 27); + p_list_free (list); + + list = p_hash_table_lookup_by_value (table, + PINT_TO_POINTER (20), + NULL); + P_TEST_REQUIRE (list != NULL); + P_TEST_REQUIRE (p_list_length (list) == 2); + P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) + + PPOINTER_TO_INT (list->next->data) == 24); + p_list_free (list); + + P_TEST_REQUIRE (PPOINTER_TO_INT (p_hash_table_lookup (table, PINT_TO_POINTER (22))) == 20); + + p_hash_table_remove (table, PINT_TO_POINTER (1)); + p_hash_table_remove (table, PINT_TO_POINTER (2)); + + list = p_hash_table_keys (table); + P_TEST_REQUIRE (p_list_length (list) == 2); + p_list_free (list); + list = p_hash_table_values (table); + P_TEST_REQUIRE (p_list_length (list) == 2); + p_list_free (list); + + p_hash_table_remove (table, PINT_TO_POINTER (3)); + + list = p_hash_table_keys (table); + P_TEST_REQUIRE (p_list_length (list) == 1); + P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) == 22); + p_list_free (list); + list = p_hash_table_values (table); + P_TEST_REQUIRE (p_list_length (list) == 1); + P_TEST_REQUIRE (PPOINTER_TO_INT (list->data) == 20); + p_list_free (list); + + p_hash_table_remove (table, PINT_TO_POINTER (22)); + + P_TEST_REQUIRE (p_hash_table_keys (table) == NULL); + P_TEST_REQUIRE (p_hash_table_values (table) == NULL); + + p_hash_table_free (table); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (phashtable_stress_test) +{ + p_libsys_init (); + + PHashTable *table = p_hash_table_new (); + P_TEST_REQUIRE (table != NULL); + + srand ((unsigned int) time (NULL)); + + int counter = 0; + + pint *keys = (pint *) p_malloc0 (PHASHTABLE_STRESS_COUNT * sizeof (pint)); + pint *values = (pint *) p_malloc0 (PHASHTABLE_STRESS_COUNT * sizeof (pint)); + + P_TEST_REQUIRE (keys != NULL); + P_TEST_REQUIRE (values != NULL); + + while (counter != PHASHTABLE_STRESS_COUNT) { + pint rand_number = rand (); + + if (p_hash_table_lookup (table, PINT_TO_POINTER (rand_number)) != (ppointer) (-1)) + continue; + + keys[counter] = rand_number; + values[counter] = rand () + 1; + + p_hash_table_remove (table, PINT_TO_POINTER (keys[counter])); + p_hash_table_insert (table, PINT_TO_POINTER (keys[counter]), PINT_TO_POINTER (values[counter])); + + ++counter; + } + + for (int i = 0; i < PHASHTABLE_STRESS_COUNT; ++i) { + P_TEST_CHECK (p_hash_table_lookup (table, PINT_TO_POINTER (keys[i])) == + PINT_TO_POINTER (values[i])); + + p_hash_table_remove (table, PINT_TO_POINTER (keys[i])); + P_TEST_CHECK (p_hash_table_lookup (table, PINT_TO_POINTER (keys[i])) == (ppointer) (-1)); + } + + P_TEST_CHECK (p_hash_table_keys (table) == NULL); + P_TEST_CHECK (p_hash_table_values (table) == NULL); + + p_free (keys); + p_free (values); + + p_hash_table_free (table); + + /* Try to free at once */ + table = p_hash_table_new (); + P_TEST_REQUIRE (table != NULL); + + counter = 0; + + while (counter != PHASHTABLE_STRESS_COUNT) { + pint rand_number = rand (); + + if (p_hash_table_lookup (table, PINT_TO_POINTER (rand_number)) != (ppointer) (-1)) + continue; + + p_hash_table_insert (table, PINT_TO_POINTER (rand_number), PINT_TO_POINTER (rand () + 1)); + + ++counter; + } + + p_hash_table_free (table); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (phashtable_nomem_test); + P_TEST_SUITE_RUN_CASE (phashtable_invalid_test); + P_TEST_SUITE_RUN_CASE (phashtable_general_test); + P_TEST_SUITE_RUN_CASE (phashtable_stress_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/pinifile_test.cpp b/3rdparty/plibsys/tests/pinifile_test.cpp new file mode 100644 index 0000000..3d4d4c8 --- /dev/null +++ b/3rdparty/plibsys/tests/pinifile_test.cpp @@ -0,0 +1,357 @@ +/* + * The MIT License + * + * Copyright (C) 2013-2017 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +#include +#include +#include +#include + +P_TEST_MODULE_INIT (); + +#define PINIFILE_STRESS_LINE 2048 +#define PINIFILE_MAX_LINE 1024 + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + P_UNUSED (block); + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" void pmem_free (ppointer block) +{ + P_UNUSED (block); +} + +static bool create_test_ini_file (bool last_empty_section) +{ + FILE *file = fopen ("." P_DIR_SEPARATOR "p_ini_test_file.ini", "w"); + + if (file == NULL) + return false; + + pchar *buf = (pchar *) p_malloc0 (PINIFILE_STRESS_LINE + 1); + + for (int i = 0; i < PINIFILE_STRESS_LINE; ++i) + buf[i] = (pchar) (97 + i % 20); + + /* Empty section */ + fprintf (file, "[empty_section]\n"); + + /* Numeric section */ + fprintf (file, "[numeric_section]\n"); + fprintf (file, "int_parameter_1 = 4\n"); + fprintf (file, "int_parameter_2 = 5 ;This is a comment\n"); + fprintf (file, "int_parameter_3 = 6 #This is another type of a comment\n"); + fprintf (file, "# Whole line is a comment\n"); + fprintf (file, "; Yet another comment line\n"); + fprintf (file, "float_parameter_1 = 3.24\n"); + fprintf (file, "float_parameter_2 = 0.15\n"); + + /* String section */ + fprintf (file, "[string_section]\n"); + fprintf (file, "string_parameter_1 = Test string\n"); + fprintf (file, "string_parameter_2 = \"Test string with #'\"\n"); + fprintf (file, "string_parameter_3 = \n"); + fprintf (file, "string_parameter_4 = 12345 ;Comment\n"); + fprintf (file, "string_parameter_4 = 54321\n"); + fprintf (file, "string_parameter_5 = 'Test string'\n"); + fprintf (file, "string_parameter_6 = %s\n", buf); + fprintf (file, "string_parameter_7 = ''\n"); + fprintf (file, "string_parameter_8 = \"\"\n"); + fprintf (file, "%s = stress line\n", buf); + + /* Boolean section */ + fprintf (file, "[boolean_section]\n"); + fprintf (file, "boolean_parameter_1 = TRUE ;True value\n"); + fprintf (file, "boolean_parameter_2 = 0 ;False value\n"); + fprintf (file, "boolean_parameter_3 = false ;False value\n"); + fprintf (file, "boolean_parameter_4 = 1 ;True value\n"); + + /* List section */ + fprintf (file, "[list_section]\n"); + fprintf (file, "list_parameter_1 = {1\t2\t5\t10} ;First list\n"); + fprintf (file, "list_parameter_2 = {2.0 3.0 5.0} #Second list\n"); + fprintf (file, "list_parameter_3 = {true FALSE 1} #Last list\n"); + + /* Empty section */ + if (last_empty_section) + fprintf (file, "[empty_section_2]\n"); + + p_free (buf); + + return fclose (file) == 0; +} + +P_TEST_CASE_BEGIN (pinifile_nomem_test) +{ + p_libsys_init (); + + P_TEST_REQUIRE (create_test_ini_file (false)); + + PIniFile *ini = p_ini_file_new ("." P_DIR_SEPARATOR "p_ini_test_file.ini"); + P_TEST_CHECK (ini != NULL); + + PMemVTable vtable; + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + + P_TEST_CHECK (p_ini_file_new ("." P_DIR_SEPARATOR "p_ini_test_file.ini") == NULL); + P_TEST_CHECK (p_ini_file_parse (ini, NULL) == TRUE); + P_TEST_CHECK (p_ini_file_sections (ini) == NULL); + + p_mem_restore_vtable (); + + p_ini_file_free (ini); + + ini = p_ini_file_new ("." P_DIR_SEPARATOR "p_ini_test_file.ini"); + P_TEST_CHECK (ini != NULL); + + P_TEST_CHECK (p_ini_file_parse (ini, NULL) == TRUE); + PList *section_list = p_ini_file_sections (ini); + P_TEST_CHECK (section_list != NULL); + P_TEST_CHECK (p_list_length (section_list) == 4); + + p_list_foreach (section_list, (PFunc) p_free, NULL); + p_list_free (section_list); + p_ini_file_free (ini); + + P_TEST_CHECK (p_file_remove ("." P_DIR_SEPARATOR "p_ini_test_file.ini", NULL) == TRUE); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pinifile_bad_input_test) +{ + PIniFile *ini = NULL; + + p_libsys_init (); + + p_ini_file_free (ini); + P_TEST_CHECK (p_ini_file_new (NULL) == NULL); + P_TEST_CHECK (p_ini_file_parse (ini, NULL) == FALSE); + P_TEST_CHECK (p_ini_file_is_parsed (ini) == FALSE); + P_TEST_CHECK (p_ini_file_is_key_exists (ini, "string_section", "string_paramter_1") == FALSE); + P_TEST_CHECK (p_ini_file_sections (ini) == NULL); + P_TEST_CHECK (p_ini_file_keys (ini, "string_section") == NULL); + P_TEST_CHECK (p_ini_file_parameter_boolean (ini, "boolean_section", "boolean_parameter_1", FALSE) == FALSE); + P_TEST_CHECK_CLOSE (p_ini_file_parameter_double (ini, "numeric_section", "float_parameter_1", 1.0), 1.0, 0.0001); + P_TEST_CHECK (p_ini_file_parameter_int (ini, "numeric_section", "int_parameter_1", 0) == 0); + P_TEST_CHECK (p_ini_file_parameter_list (ini, "list_section", "list_parameter_1") == NULL); + P_TEST_CHECK (p_ini_file_parameter_string (ini, "string_section", "string_parameter_1", NULL) == NULL); + + ini = p_ini_file_new ("./bad_file_path/fake.ini"); + P_TEST_CHECK (ini != NULL); + P_TEST_CHECK (p_ini_file_parse (ini, NULL) == FALSE); + p_ini_file_free (ini); + + P_TEST_REQUIRE (create_test_ini_file (true)); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pinifile_read_test) +{ + p_libsys_init (); + + PIniFile *ini = p_ini_file_new ("." P_DIR_SEPARATOR "p_ini_test_file.ini"); + P_TEST_REQUIRE (ini != NULL); + P_TEST_CHECK (p_ini_file_is_parsed (ini) == FALSE); + + P_TEST_REQUIRE (p_ini_file_parse (ini, NULL) == TRUE); + P_TEST_CHECK (p_ini_file_is_parsed (ini) == TRUE); + P_TEST_REQUIRE (p_ini_file_parse (ini, NULL) == TRUE); + P_TEST_CHECK (p_ini_file_is_parsed (ini) == TRUE); + + /* Test list of sections */ + PList *list = p_ini_file_sections (ini); + P_TEST_CHECK (list != NULL); + P_TEST_CHECK (p_list_length (list) == 4); + + p_list_foreach (list, (PFunc) p_free, NULL); + p_list_free (list); + + /* Test empty section */ + list = p_ini_file_keys (ini, "empty_section"); + P_TEST_CHECK (list == NULL); + + /* Test numeric section */ + list = p_ini_file_keys (ini, "numeric_section"); + P_TEST_CHECK (p_list_length (list) == 5); + p_list_foreach (list, (PFunc) p_free, NULL); + p_list_free (list); + + P_TEST_CHECK (p_ini_file_parameter_list (ini, "numeric_section", "int_parameter_1") == NULL); + P_TEST_CHECK (p_ini_file_parameter_int (ini, "numeric_section", "int_parameter_1", -1) == 4); + P_TEST_CHECK (p_ini_file_parameter_int (ini, "numeric_section", "int_parameter_2", -1) == 5); + P_TEST_CHECK (p_ini_file_parameter_int (ini, "numeric_section", "int_parameter_3", -1) == 6); + P_TEST_CHECK (p_ini_file_parameter_int (ini, "numeric_section", "int_parameter_def", 10) == 10); + P_TEST_CHECK_CLOSE (p_ini_file_parameter_double (ini, "numeric_section", "float_parameter_1", -1.0), 3.24, 0.0001); + P_TEST_CHECK_CLOSE (p_ini_file_parameter_double (ini, "numeric_section", "float_parameter_2", -1.0), 0.15, 0.0001); + P_TEST_CHECK_CLOSE (p_ini_file_parameter_double (ini, "numeric_section_no", "float_parameter_def", 10.0), 10.0, 0.0001); + P_TEST_CHECK (p_ini_file_is_key_exists (ini, "numeric_section", "int_parameter_1") == TRUE); + P_TEST_CHECK (p_ini_file_is_key_exists (ini, "numeric_section", "float_parameter_1") == TRUE); + P_TEST_CHECK (p_ini_file_is_key_exists (ini, "numeric_section_false", "float_parameter_1") == FALSE); + + /* Test string section */ + list = p_ini_file_keys (ini, "string_section"); + P_TEST_CHECK (p_list_length (list) == 8); + p_list_foreach (list, (PFunc) p_free, NULL); + p_list_free (list); + + pchar *str = p_ini_file_parameter_string (ini, "string_section", "string_parameter_1", NULL); + P_TEST_REQUIRE (str != NULL); + P_TEST_CHECK (strcmp (str, "Test string") == 0); + p_free (str); + + str = p_ini_file_parameter_string (ini, "string_section", "string_parameter_2", NULL); + P_TEST_REQUIRE (str != NULL); + P_TEST_CHECK (strcmp (str, "Test string with #'") == 0); + p_free (str); + + str = p_ini_file_parameter_string (ini, "string_section", "string_parameter_3", NULL); + P_TEST_REQUIRE (str == NULL); + P_TEST_CHECK (p_ini_file_is_key_exists (ini, "string_section", "string_parameter_3") == FALSE); + + str = p_ini_file_parameter_string (ini, "string_section", "string_parameter_4", NULL); + P_TEST_REQUIRE (str != NULL); + P_TEST_CHECK (strcmp (str, "54321") == 0); + p_free (str); + + str = p_ini_file_parameter_string (ini, "string_section", "string_parameter_5", NULL); + P_TEST_REQUIRE (str != NULL); + P_TEST_CHECK (strcmp (str, "Test string") == 0); + p_free (str); + + str = p_ini_file_parameter_string (ini, "string_section", "string_parameter_6", NULL); + P_TEST_REQUIRE (str != NULL); + P_TEST_CHECK (strlen (str) > 0 && strlen (str) < PINIFILE_MAX_LINE); + p_free (str); + + str = p_ini_file_parameter_string (ini, "string_section", "string_parameter_7", NULL); + P_TEST_REQUIRE (str != NULL); + P_TEST_CHECK (strcmp (str, "") == 0); + p_free (str); + + str = p_ini_file_parameter_string (ini, "string_section", "string_parameter_8", NULL); + P_TEST_REQUIRE (str != NULL); + P_TEST_CHECK (strcmp (str, "") == 0); + p_free (str); + + str = p_ini_file_parameter_string (ini, "string_section", "string_parameter_def", "default_value"); + P_TEST_REQUIRE (str != NULL); + P_TEST_CHECK (strcmp (str, "default_value") == 0); + p_free (str); + + /* Test boolean section */ + list = p_ini_file_keys (ini, "boolean_section"); + P_TEST_CHECK (p_list_length (list) == 4); + p_list_foreach (list, (PFunc) p_free, NULL); + p_list_free (list); + + P_TEST_CHECK (p_ini_file_parameter_boolean (ini, "boolean_section", "boolean_parameter_1", FALSE) == TRUE); + P_TEST_CHECK (p_ini_file_parameter_boolean (ini, "boolean_section", "boolean_parameter_2", TRUE) == FALSE); + P_TEST_CHECK (p_ini_file_parameter_boolean (ini, "boolean_section", "boolean_parameter_3", TRUE) == FALSE); + P_TEST_CHECK (p_ini_file_parameter_boolean (ini, "boolean_section", "boolean_parameter_4", FALSE) == TRUE); + P_TEST_CHECK (p_ini_file_parameter_boolean (ini, "boolean_section", "boolean_section_def", TRUE) == TRUE); + + /* Test list section */ + list = p_ini_file_keys (ini, "list_section"); + P_TEST_CHECK (p_list_length (list) == 3); + p_list_foreach (list, (PFunc) p_free, NULL); + p_list_free (list); + + /* -- First list parameter */ + PList *list_val = p_ini_file_parameter_list (ini, "list_section", "list_parameter_1"); + P_TEST_CHECK (list_val != NULL); + P_TEST_CHECK (p_list_length (list_val) == 4); + + pint int_sum = 0; + for (PList *iter = list_val; iter != NULL; iter = iter->next) + int_sum += atoi ((const pchar *) (iter->data)); + + P_TEST_CHECK (int_sum == 18); + p_list_foreach (list_val, (PFunc) p_free, NULL); + p_list_free (list_val); + + /* -- Second list parameter */ + list_val = p_ini_file_parameter_list (ini, "list_section", "list_parameter_2"); + P_TEST_CHECK (list_val != NULL); + P_TEST_CHECK (p_list_length (list_val) == 3); + + double flt_sum = 0; + for (PList *iter = list_val; iter != NULL; iter = iter->next) + flt_sum += atof ((const pchar *) (iter->data)); + + P_TEST_CHECK_CLOSE (flt_sum, 10.0, 0.0001); + p_list_foreach (list_val, (PFunc) p_free, NULL); + p_list_free (list_val); + + /* -- Third list parameter */ + list_val = p_ini_file_parameter_list (ini, "list_section", "list_parameter_3"); + P_TEST_CHECK (list_val != NULL); + P_TEST_CHECK (p_list_length (list_val) == 3); + + pboolean bool_sum = TRUE; + for (PList *iter = list_val; iter != NULL; iter = iter->next) + bool_sum = bool_sum && atoi ((const pchar *) (iter->data)); + + P_TEST_CHECK (bool_sum == FALSE); + p_list_foreach (list_val, (PFunc) p_free, NULL); + p_list_free (list_val); + + /* -- False list parameter */ + P_TEST_CHECK (p_ini_file_parameter_list (ini, "list_section_no", "list_parameter_def") == NULL); + + p_ini_file_free (ini); + + P_TEST_CHECK (p_file_remove ("." P_DIR_SEPARATOR "p_ini_test_file.ini", NULL) == TRUE); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (pinifile_nomem_test); + P_TEST_SUITE_RUN_CASE (pinifile_bad_input_test); + P_TEST_SUITE_RUN_CASE (pinifile_read_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/plibraryloader_test.cpp b/3rdparty/plibsys/tests/plibraryloader_test.cpp new file mode 100644 index 0000000..52ce1b0 --- /dev/null +++ b/3rdparty/plibsys/tests/plibraryloader_test.cpp @@ -0,0 +1,179 @@ +/* + * The MIT License + * + * Copyright (C) 2015-2017 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +#include + +P_TEST_MODULE_INIT (); + +static int g_argc = 0; +static char **g_argv = NULL; + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + P_UNUSED (block); + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" void pmem_free (ppointer block) +{ + P_UNUSED (block); +} + +P_TEST_CASE_BEGIN (plibraryloader_nomem_test) +{ + p_libsys_init (); + + if (P_UNLIKELY (p_library_loader_is_ref_counted () == FALSE)) { + p_libsys_shutdown (); + P_TEST_CASE_RETURN (); + } + + /* We assume that 3rd argument is ourself library path */ + P_TEST_REQUIRE (g_argc > 1); + + /* Cleanup from previous run */ + p_file_remove ("." P_DIR_SEPARATOR "p_empty_file.txt", NULL); + + FILE *file = fopen ("." P_DIR_SEPARATOR "p_empty_file.txt", "w"); + P_TEST_CHECK (file != NULL); + P_TEST_CHECK (fclose (file) == 0); + + PMemVTable vtable; + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + +#ifdef P_OS_WIN + SetErrorMode (SEM_FAILCRITICALERRORS); +#endif + + P_TEST_CHECK (p_library_loader_new ("." P_DIR_SEPARATOR "p_empty_file.txt") == NULL); + P_TEST_CHECK (p_library_loader_new (g_argv[g_argc - 1]) == NULL); + +#ifdef P_OS_WIN + SetErrorMode (0); +#endif + + p_mem_restore_vtable (); + + P_TEST_CHECK (p_file_remove ("." P_DIR_SEPARATOR "p_empty_file.txt", NULL) == TRUE); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (plibraryloader_general_test) +{ + PLibraryLoader *loader; + pchar *err_msg; + void (*shutdown_func) (void); + + p_libsys_init (); + + /* We assume that 3rd argument is ourself library path */ + P_TEST_REQUIRE (g_argc > 1); + + /* Invalid usage */ + P_TEST_CHECK (p_library_loader_new (NULL) == NULL); + P_TEST_CHECK (p_library_loader_new ("./unexistent_file.nofile") == NULL); + P_TEST_CHECK (p_library_loader_get_symbol (NULL, NULL) == NULL); + P_TEST_CHECK (p_library_loader_get_symbol (NULL, "unexistent_symbol") == NULL); + + p_library_loader_free (NULL); + + /* General tests */ + + /* At least not on HP-UX it should be true */ +#if !defined (P_OS_HPUX) + P_TEST_CHECK (p_library_loader_is_ref_counted () == TRUE); +#else + p_library_loader_is_ref_counted (); +#endif + + err_msg = p_library_loader_get_last_error (NULL); + p_free (err_msg); + + if (P_UNLIKELY (p_library_loader_is_ref_counted () == FALSE)) { + p_libsys_shutdown (); + P_TEST_CASE_RETURN (); + } + + loader = p_library_loader_new (g_argv[g_argc - 1]); + P_TEST_REQUIRE (loader != NULL); + + P_TEST_CHECK (p_library_loader_get_symbol (loader, "there_is_no_such_a_symbol") == (PFuncAddr) NULL); + + err_msg = p_library_loader_get_last_error (loader); + P_TEST_CHECK (err_msg != NULL); + p_free (err_msg); + + shutdown_func = (void (*) (void)) p_library_loader_get_symbol (loader, "p_libsys_shutdown"); + + if (shutdown_func == NULL) + shutdown_func = (void (*) (void)) p_library_loader_get_symbol (loader, "_p_libsys_shutdown"); + + /* For Watcom C */ + + if (shutdown_func == NULL) + shutdown_func = (void (*) (void)) p_library_loader_get_symbol (loader, "p_libsys_shutdown_"); + + P_TEST_REQUIRE (shutdown_func != NULL); + + err_msg = p_library_loader_get_last_error (loader); + p_free (err_msg); + + p_library_loader_free (loader); + +#ifdef P_OS_BEOS + p_libsys_shutdown (); +#else + /* We have already loaded reference to ourself library, it's OK */ + shutdown_func (); +#endif +} +P_TEST_CASE_END () + +P_TEST_SUITE_ARGS_BEGIN() +{ + g_argc = argc; + g_argv = argv; + + P_TEST_SUITE_RUN_CASE (plibraryloader_nomem_test); + P_TEST_SUITE_RUN_CASE (plibraryloader_general_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/plist_test.cpp b/3rdparty/plibsys/tests/plist_test.cpp new file mode 100644 index 0000000..87933ae --- /dev/null +++ b/3rdparty/plibsys/tests/plist_test.cpp @@ -0,0 +1,200 @@ +/* + * The MIT License + * + * Copyright (C) 2013-2017 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +#include + +P_TEST_MODULE_INIT (); + +typedef struct _TestData { + pint test_array[3]; + pint index; +} TestData; + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + P_UNUSED (block); + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" void pmem_free (ppointer block) +{ + P_UNUSED (block); +} + +static void foreach_test_func (ppointer data, ppointer user_data) +{ + if (user_data == NULL) + return; + + TestData *test_data = (TestData *) user_data; + + if (test_data->index < 0 || test_data->index > 2) + return; + + test_data->test_array[test_data->index] = P_POINTER_TO_INT (data); + ++test_data->index; +} + +P_TEST_CASE_BEGIN (plist_nomem_test) +{ + p_libsys_init (); + + PMemVTable vtable; + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + + P_TEST_CHECK (p_list_append (NULL, PINT_TO_POINTER (10)) == NULL); + P_TEST_CHECK (p_list_prepend (NULL, PINT_TO_POINTER (10)) == NULL); + + p_mem_restore_vtable (); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (plist_invalid_test) +{ + p_libsys_init (); + + P_TEST_CHECK (p_list_remove (NULL, NULL) == NULL); + P_TEST_CHECK (p_list_last (NULL) == NULL); + P_TEST_CHECK (p_list_length (NULL) == 0); + P_TEST_CHECK (p_list_reverse (NULL) == NULL); + + p_list_free (NULL); + p_list_foreach (NULL, NULL, NULL); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (plist_general_test) +{ + PList *list = NULL; + TestData test_data; + + p_libsys_init (); + + /* Testing append */ + list = p_list_append (list, P_INT_TO_POINTER (32)); + list = p_list_append (list, P_INT_TO_POINTER (64)); + + P_TEST_REQUIRE (list != NULL); + P_TEST_CHECK (p_list_length (list) == 2); + + /* Testing data access */ + P_TEST_CHECK (P_POINTER_TO_INT (list->data) == 32); + P_TEST_CHECK (P_POINTER_TO_INT (p_list_last(list)->data) == 64); + + /* Testing prepend */ + list = p_list_prepend (list, P_INT_TO_POINTER (128)); + P_TEST_REQUIRE (list != NULL); + P_TEST_CHECK (p_list_length (list) == 3); + P_TEST_CHECK (P_POINTER_TO_INT (list->data) == 128); + P_TEST_CHECK (P_POINTER_TO_INT (p_list_last(list)->data) == 64); + + /* Testing for each loop */ + memset (&test_data, 0, sizeof (test_data)); + + P_TEST_REQUIRE (test_data.test_array[0] == 0); + P_TEST_REQUIRE (test_data.test_array[1] == 0); + P_TEST_REQUIRE (test_data.test_array[2] == 0); + P_TEST_REQUIRE (test_data.index == 0); + + p_list_foreach (list, (PFunc) foreach_test_func, (ppointer) &test_data); + + P_TEST_CHECK (test_data.index == 3); + P_TEST_CHECK (test_data.test_array[0] == 128); + P_TEST_CHECK (test_data.test_array[1] == 32); + P_TEST_CHECK (test_data.test_array[2] == 64); + + /* Testing reverse */ + + list = p_list_reverse (list); + + P_TEST_CHECK (list != NULL); + P_TEST_CHECK (p_list_length (list) == 3); + P_TEST_CHECK (P_POINTER_TO_INT (list->data) == 64); + P_TEST_CHECK (P_POINTER_TO_INT (p_list_last(list)->data) == 128); + + /* Testing for each loop */ + memset (&test_data, 0, sizeof (test_data)); + + P_TEST_REQUIRE (test_data.test_array[0] == 0); + P_TEST_REQUIRE (test_data.test_array[1] == 0); + P_TEST_REQUIRE (test_data.test_array[2] == 0); + P_TEST_REQUIRE (test_data.index == 0); + + p_list_foreach (list, (PFunc) foreach_test_func, (ppointer) &test_data); + + P_TEST_CHECK (test_data.index == 3); + P_TEST_CHECK (test_data.test_array[0] == 64); + P_TEST_CHECK (test_data.test_array[1] == 32); + P_TEST_CHECK (test_data.test_array[2] == 128); + + /* Testing remove */ + list = p_list_remove (list, P_INT_TO_POINTER (32)); + P_TEST_REQUIRE (list != NULL); + P_TEST_CHECK (p_list_length (list) == 2); + + list = p_list_remove (list, P_INT_TO_POINTER (128)); + P_TEST_REQUIRE (list != NULL); + P_TEST_CHECK (p_list_length (list) == 1); + + list = p_list_remove (list, P_INT_TO_POINTER (256)); + P_TEST_REQUIRE (list != NULL); + P_TEST_CHECK (p_list_length (list) == 1); + + list = p_list_remove (list, P_INT_TO_POINTER (64)); + P_TEST_REQUIRE (list == NULL); + P_TEST_CHECK (p_list_length (list) == 0); + + p_list_free (list); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (plist_nomem_test); + P_TEST_SUITE_RUN_CASE (plist_invalid_test); + P_TEST_SUITE_RUN_CASE (plist_general_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/pmacros_test.cpp b/3rdparty/plibsys/tests/pmacros_test.cpp new file mode 100644 index 0000000..fed35a2 --- /dev/null +++ b/3rdparty/plibsys/tests/pmacros_test.cpp @@ -0,0 +1,646 @@ +/* + * The MIT License + * + * Copyright (C) 2014-2018 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +#include +#include + +P_TEST_MODULE_INIT (); + +static P_GNUC_WARN_UNUSED_RESULT pint unused_result_test_func () +{ + return 0; +} + +P_LIB_INTERNAL_API int internal_api_test () +{ + return 0; +} + +P_LIB_GLOBAL_API int global_api_test () +{ + return 0; +} + +P_TEST_CASE_BEGIN (pmacros_general_test) +{ + p_libsys_init (); + + /* Test OS detection macros */ +#if !defined (P_OS_DARWIN) && !defined (P_OS_MAC9) && !defined (P_OS_BSD4) && \ + !defined (P_OS_AIX) && !defined (P_OS_HPUX) && !defined (P_OS_SOLARIS) && \ + !defined (P_OS_QNX) && !defined (P_OS_QNX6) && !defined (P_OS_UNIX) && \ + !defined (P_OS_LINUX) && !defined (P_OS_WIN) && !defined (P_OS_CYGWIN) && \ + !defined (P_OS_SCO) && !defined (P_OS_UNIXWARE) && !defined (P_OS_VMS) && \ + !defined (P_OS_IRIX) && !defined (P_OS_MSYS) && !defined (P_OS_DRAGONFLY) && \ + !defined (P_OS_HAIKU) && !defined (P_OS_TRU64) && !defined (P_OS_SYLLABLE) && \ + !defined (P_OS_BEOS) && !defined (P_OS_OS2) && !defined (P_OS_AMIGA) + P_TEST_CHECK (false); +#endif + + /* Test for Mac OS */ +#if defined (P_OS_MAC9) && defined (P_OS_UNIX) + P_TEST_CHECK (false); +#endif + +#if defined (P_OS_MAC9) && defined (P_OS_MAC) + P_TEST_CHECK (false); +#endif + +#if defined (P_OS_MAC) && !defined (P_OS_MAC32) && !defined (P_OS_MAC64) + P_TEST_CHECK (false); +#endif + +#if defined (P_OS_MAC) && (!defined (P_OS_DARWIN) || !defined (P_OS_BSD4)) + P_TEST_CHECK (false); +#endif + +#if defined (P_OS_MAC32) && !defined (P_OS_DARWIN32) + P_TEST_CHECK (false); +#endif + +#if defined (P_OS_MAC64) && !defined (P_OS_DARWIN64) + P_TEST_CHECK (false); +#endif + +#if defined (P_OS_MAC32) && defined (P_OS_MAC64) + P_TEST_CHECK (false); +#endif + + /* Test for Windows */ +#if defined (P_OS_WIN64) && !defined (P_OS_WIN) + P_TEST_CHECK (false); +#endif + +#if defined (P_OS_WIN) && defined (P_OS_UNIX) + P_TEST_CHECK (false); +#endif + + /* Test for FreeBSD */ +#if defined (P_OS_FREEBSD) && !defined (P_OS_BSD4) + P_TEST_CHECK (false); +#endif + + /* Test for DragonFlyBSD */ +#if defined (P_OS_DRAGONFLY) && !defined (P_OS_BSD4) + P_TEST_CHECK (false); +#endif + + /* Test for NetBSD */ +#if defined (P_OS_NETBSD) && !defined (P_OS_BSD4) + P_TEST_CHECK (false); +#endif + + /* Test for OpenBSD */ +#if defined (P_OS_OPENBSD) && !defined (P_OS_BSD4) + P_TEST_CHECK (false); +#endif + + /* Test for Android */ +#if defined (P_OS_ANDROID) && !defined (P_OS_LINUX) + P_TEST_CHECK (false); +#endif + + /* Test for others */ +#if defined (P_OS_HAIKU) || defined (P_OS_BEOS) || defined (P_OS_OS2) || defined (P_OS_VMS) || \ + defined (P_OS_AMIGA) +# if defined (P_OS_UNIX) + P_TEST_CHECK (false); +# endif +#endif + + /* Test for compiler detection macros */ +#if !defined (P_CC_MSVC) && !defined (P_CC_GNU) && !defined (P_CC_MINGW) && \ + !defined (P_CC_INTEL) && !defined (P_CC_CLANG) && !defined (P_CC_SUN) && \ + !defined (P_CC_XLC) && !defined (P_CC_HP) && !defined (P_CC_WATCOM) && \ + !defined (P_CC_BORLAND) && !defined (P_CC_MIPS) && !defined (P_CC_USLC) && \ + !defined (P_CC_DEC) && !defined (P_CC_PGI) && !defined (P_CC_CRAY) + P_TEST_CHECK (false); +#endif + +#if defined (P_CC_MSVC) +# if !defined (P_OS_WIN) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CC_INTEL) +# if !defined (P_OS_WIN) && !defined (P_OS_MAC) && \ + !defined (P_OS_LINUX) && !defined (P_OS_FREEBSD) && \ + !defined (P_OS_QNX6) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CC_SUN) +# if !defined (P_OS_SOLARIS) && !defined (P_OS_LINUX) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CC_XLC) +# if !defined (P_OS_AIX) && !defined (P_OS_LINUX) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CC_HP) +# if !defined (P_OS_HPUX) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CC_WATCOM) +# if !defined (P_OS_WIN) && !defined (P_OS_LINUX) && \ + !defined (P_OS_OS2) && !defined (P_OS_QNX) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CC_BORLAND) +# if !defined (P_OS_WIN) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CC_MIPS) +# if !defined (P_OS_IRIX) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CC_USLC) +# if !defined (P_OS_SCO) && !defined (P_OS_UNIXWARE) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CC_DEC) +# if !defined (P_OS_VMS) && !defined (P_OS_TRU64) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CC_PGI) +# if !defined (P_OS_WIN) && !defined (P_OS_MAC) && !defined (P_OS_LINUX) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CC_CRAY) +# if !defined (P_OS_LINUX) + P_TEST_CHECK (false); +# endif +#endif + + /* Test for CPU architecture detection macros */ +#if defined (P_OS_VMS) +# if !defined (P_CPU_ALPHA) && !defined (P_CPU_IA64) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_OS_AMIGA) +# if !defined (P_CPU_POWER) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_OS_TRU64) +# if !defined (P_CPU_ALPHA) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_OS_AIX) +# if !defined (P_CPU_POWER) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_OS_HPUX) +# if !defined (P_CPU_HPPA) && !defined (P_CPU_IA64) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_OS_SOLARIS) +# if !defined (P_CPU_X86) && !defined (P_CPU_SPARC) && !defined (P_CPU_POWER) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_OS_QNX) +# if !defined (P_CPU_X86) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_OS_QNX6) +# if !defined (P_CPU_X86) && !defined (P_CPU_ARM) && \ + !defined (P_CPU_MIPS) && !defined (P_CPU_POWER) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_OS_BB10) +# if !defined(P_CPU_X86) && !defined (P_CPU_ARM) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_OS_SCO) +# if !defined (P_CPU_X86) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_OS_UNIXWARE) +# if !defined (P_CPU_X86) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_OS_IRIX) +# if !defined (P_CPU_MIPS) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_OS_HAIKU) +# if !defined (P_CPU_X86) && !defined (P_CPU_ARM) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_OS_SYLLABLE) +# if !defined (P_CPU_X86) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_OS_BEOS) +# if !defined (P_CPU_X86) && !defined (P_CPU_POWER) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_OS_OS2) +# if !defined (P_CPU_X86) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_OS_MAC9) +# if !defined (P_CPU_POWER) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_OS_MAC) +# if !defined (P_CPU_X86) && !defined (P_CPU_POWER) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_OS_WIN) +# if !defined (P_CPU_X86) && !defined (P_CPU_ARM) && !defined (P_CPU_IA64) && \ + !defined (P_CPU_MIPS) && !defined (P_CPU_POWER) && !defined (P_CPU_ALPHA) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_OS_ANDROID) +# if !defined (P_CPU_X86) && !defined (P_CPU_ARM) && !defined (P_CPU_MIPS) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CC_MSVC) +# if !defined (P_CPU_X86) && !defined (P_CPU_ARM) && !defined (P_CPU_IA64) && \ + !defined (P_CPU_MIPS) && !defined (P_CPU_POWER) && !defined (P_CPU_ALPHA) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CC_SUN) +# if !defined (P_CPU_X86) && !defined (P_CPU_SPARC) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CC_XLC) +# if !defined (P_CPU_POWER) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CC_HP) +# if !defined (P_CPU_HPPA) && !defined (P_CPU_IA64) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CC_DEC) +# if !defined (P_CPU_ALPHA) && !defined (P_CPU_IA64) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CC_MIPS) +# if !defined (P_CPU_MIPS) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CC_USLC) +# if !defined (P_CPU_X86) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CC_WATCOM) +# if !defined (P_CPU_X86) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CC_BORLAND) +# if !defined (P_CPU_X86) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CC_PGI) +# if !defined (P_CPU_X86) && !defined (P_CPU_POWER) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_ARM) +# if !defined (P_CPU_ARM_V2) && !defined (P_CPU_ARM_V3) && !defined (P_CPU_ARM_V4) && \ + !defined (P_CPU_ARM_V5) && !defined (P_CPU_ARM_V6) && !defined (P_CPU_ARM_V7) && \ + !defined (P_CPU_ARM_V8) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_ARM_V2) +# if !defined (P_CPU_ARM) || !(P_CPU_ARM - 0 == 2) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_ARM_V3) +# if !defined (P_CPU_ARM) || !(P_CPU_ARM - 0 == 3) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_ARM_V4) +# if !defined (P_CPU_ARM) || !(P_CPU_ARM - 0 == 4) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_ARM_V5) +# if !defined (P_CPU_ARM) || !(P_CPU_ARM - 0 == 5) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_ARM_V6) +# if !defined (P_CPU_ARM) || !(P_CPU_ARM - 0 == 6) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_ARM_V7) +# if !defined (P_CPU_ARM) || !(P_CPU_ARM - 0 == 7) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_ARM_V8) +# if !defined (P_CPU_ARM) || !(P_CPU_ARM - 0 == 8) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_ARM) && !(P_CPU_ARM - 0 > 0) + P_TEST_CHECK (false); +#endif + +#if defined (P_CPU_ARM) +# if !defined (P_CPU_ARM_32) && !defined (P_CPU_ARM_64) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_ARM_32) || defined (P_CPU_ARM_64) +# if !defined (P_CPU_ARM) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_ARM_32) +# ifdef P_CPU_ARM_64 + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_ARM_64) +# ifdef P_CPU_ARM_32 + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_X86) +# if !((P_CPU_X86 >= 3) && (P_CPU_X86 <= 6)) + P_TEST_CHECK (false); +# endif +# if !defined (P_CPU_X86_32) && !defined (P_CPU_X86_64) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_X86_32) || defined (P_CPU_X86_64) +# if !defined (P_CPU_X86) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_X86_32) && defined (P_CPU_X86_64) + P_TEST_CHECK (false); +#endif + +#if defined (P_CPU_X86_64) +# if !defined (P_CPU_X86) || !(P_CPU_X86 - 0 == 6) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_MIPS) +# if !defined (P_CPU_MIPS_I) && !defined (P_CPU_MIPS_II) && !defined (P_CPU_MIPS_III) && \ + !defined (P_CPU_MIPS_IV) && !defined (P_CPU_MIPS_V) && !defined (P_CPU_MIPS_32) && \ + !defined (P_CPU_MIPS_64) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_MIPS_I) || defined (P_CPU_MIPS_II) || defined (P_CPU_MIPS_III) || \ + defined (P_CPU_MIPS_IV) || defined (P_CPU_MIPS_V) || defined (P_CPU_MIPS_32) || \ + defined (P_CPU_MIPS_64) +# if !defined (P_CPU_MIPS) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_MIPS_II) +# if !defined (P_CPU_MIPS_I) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_MIPS_III) +# if !defined (P_CPU_MIPS_II) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_MIPS_IV) +# if !defined (P_CPU_MIPS_III) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_MIPS_V) +# if !defined (P_CPU_MIPS_IV) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_MIPS_32) +# if !defined (P_CPU_MIPS_II) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_MIPS_64) +# if !defined (P_CPU_MIPS_V) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_POWER) +# if !defined (P_CPU_POWER_32) && !defined (P_CPU_POWER_64) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_POWER_32) || defined (P_CPU_POWER_64) +# if !defined (P_CPU_POWER) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_POWER_32) && defined (P_CPU_POWER_64) + P_TEST_CHECK (false); +#endif + +#if defined (P_CPU_SPARC_V8) || defined (P_CPU_SPARC_V9) +# if !defined (P_CPU_SPARC) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_SPARC_V8) && defined (P_CPU_SPARC_V9) + P_TEST_CHECK (false); +#endif + +#if defined (P_CPU_HPPA) +# if !defined (P_CPU_HPPA_32) && !defined (P_CPU_HPPA_64) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_HPPA_32) || defined (P_CPU_HPPA_64) +# if !defined (P_CPU_HPPA) + P_TEST_CHECK (false); +# endif +#endif + +#if defined (P_CPU_HPPA_32) && defined (P_CPU_HPPA_64) + P_TEST_CHECK (false); +#endif + + /* Test other macros */ + pint unused; + P_UNUSED (unused); + + pint result = unused_result_test_func (); + + P_UNUSED (result); + + P_TEST_CHECK (internal_api_test () == 0); + P_TEST_CHECK (global_api_test () == 0); + + P_WARNING ("Test warning output"); + P_ERROR ("Test error output"); + P_DEBUG ("Test debug output"); + + srand ((unsigned int) time (NULL)); + + pint rand_number = rand (); + + if (P_LIKELY (rand_number > 0)) + P_DEBUG ("Likely condition triggered"); + + if (P_UNLIKELY (rand_number == 0)) + P_DEBUG ("Unlikely condition triggered"); + + /* Test version macros */ + P_TEST_CHECK (PLIBSYS_VERSION_MAJOR >= 0); + P_TEST_CHECK (PLIBSYS_VERSION_MINOR >= 0); + P_TEST_CHECK (PLIBSYS_VERSION_PATCH >= 0); + P_TEST_CHECK (PLIBSYS_VERSION >= 0); + +#if !defined (PLIBSYS_VERSION_STR) + P_TEST_CHECK (false); +#endif + + P_TEST_CHECK (PLIBSYS_VERSION >= PLIBSYS_VERSION_CHECK (0, 0, 1)); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (pmacros_general_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/pmain_test.cpp b/3rdparty/plibsys/tests/pmain_test.cpp new file mode 100644 index 0000000..ec1b553 --- /dev/null +++ b/3rdparty/plibsys/tests/pmain_test.cpp @@ -0,0 +1,111 @@ +/* + * The MIT License + * + * Copyright (C) 2013-2017 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +#include +#include + +P_TEST_MODULE_INIT (); + +static pint alloc_counter = 0; +static pint realloc_counter = 0; +static pint free_counter = 0; + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + ++alloc_counter; + return (ppointer) malloc (nbytes); +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + ++realloc_counter; + return (ppointer) realloc (block, nbytes); +} + +extern "C" void pmem_free (ppointer block) +{ + ++free_counter; + free (block); +} + +P_TEST_CASE_BEGIN (pmain_general_test) +{ + p_libsys_init (); + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pmain_double_test) +{ + p_libsys_init_full (NULL); + p_libsys_init (); + p_libsys_shutdown (); + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pmain_vtable_test) +{ + PMemVTable vtable; + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + p_libsys_init_full (&vtable); + + alloc_counter = 0; + realloc_counter = 0; + free_counter = 0; + + pchar *buf = (pchar *) p_malloc0 (10); + pchar *new_buf = (pchar *) p_realloc ((ppointer) buf, 20); + + P_TEST_REQUIRE (new_buf != NULL); + + buf = new_buf; + + p_free (buf); + + P_TEST_CHECK (alloc_counter > 0); + P_TEST_CHECK (realloc_counter > 0); + P_TEST_CHECK (free_counter > 0); + + P_TEST_CHECK (strcmp (p_libsys_version (), PLIBSYS_VERSION_STR) == 0); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (pmain_general_test); + P_TEST_SUITE_RUN_CASE (pmain_double_test); + P_TEST_SUITE_RUN_CASE (pmain_vtable_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/pmem_test.cpp b/3rdparty/plibsys/tests/pmem_test.cpp new file mode 100644 index 0000000..c9504b6 --- /dev/null +++ b/3rdparty/plibsys/tests/pmem_test.cpp @@ -0,0 +1,171 @@ +/* + * The MIT License + * + * Copyright (C) 2013-2017 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +#include +#include + +P_TEST_MODULE_INIT (); + +static pint alloc_counter = 0; +static pint realloc_counter = 0; +static pint free_counter = 0; + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + ++alloc_counter; + return (ppointer) malloc (nbytes); +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + ++realloc_counter; + return (ppointer) realloc (block, nbytes); +} + +extern "C" void pmem_free (ppointer block) +{ + ++free_counter; + free (block); +} + +P_TEST_CASE_BEGIN (pmem_bad_input_test) +{ + PMemVTable vtable; + + p_libsys_init (); + + vtable.free = NULL; + vtable.malloc = NULL; + vtable.realloc = NULL; + + P_TEST_CHECK (p_malloc (0) == NULL); + P_TEST_CHECK (p_malloc0 (0) == NULL); + P_TEST_CHECK (p_realloc (NULL, 0) == NULL); + P_TEST_CHECK (p_mem_set_vtable (NULL) == FALSE); + P_TEST_CHECK (p_mem_set_vtable (&vtable) == FALSE); + p_free (NULL); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pmem_general_test) +{ + PMemVTable vtable; + ppointer ptr = NULL; + pint i; + + p_libsys_init (); + + alloc_counter = 0; + realloc_counter = 0; + free_counter = 0; + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + + /* Test memory allocation using system functions */ + ptr = p_malloc (1024); + P_TEST_REQUIRE (ptr != NULL); + + for (int i = 0; i < 1024; ++i) + *(((pchar *) ptr) + i) = (pchar) (i % 127); + + for (int i = 0; i < 1024; ++i) + P_TEST_CHECK (*(((pchar *) ptr) + i) == (pchar) (i % 127)); + + p_free (ptr); + + ptr = p_malloc0 (2048); + P_TEST_REQUIRE (ptr != NULL); + + for (int i = 0; i < 2048; ++i) + P_TEST_CHECK (*(((pchar *) ptr) + i) == 0); + + for (int i = 0; i < 2048; ++i) + *(((pchar *) ptr) + i) = (pchar) (i % 127); + + for (int i = 0; i < 2048; ++i) + P_TEST_CHECK (*(((pchar *) ptr) + i) == (pchar) (i % 127)); + + p_free (ptr); + + ptr = p_realloc (NULL, 1024); + P_TEST_REQUIRE (ptr != NULL); + + for (int i = 0; i < 1024; ++i) + *(((pchar *) ptr) + i) = (pchar) (i % 127); + + ptr = p_realloc (ptr, 2048); + + for (int i = 1024; i < 2048; ++i) + *(((pchar *) ptr) + i) = (pchar) ((i - 1) % 127); + + for (int i = 0; i < 1024; ++i) + P_TEST_CHECK (*(((pchar *) ptr) + i) == (pchar) (i % 127)); + + for (int i = 1024; i < 2048; ++i) + P_TEST_CHECK (*(((pchar *) ptr) + i) == (pchar) ((i - 1) % 127)); + + p_free (ptr); + + P_TEST_CHECK (alloc_counter > 0); + P_TEST_CHECK (realloc_counter > 0); + P_TEST_CHECK (free_counter > 0); + + p_mem_restore_vtable (); + + /* Test memory mapping */ + ptr = p_mem_mmap (0, NULL); + P_TEST_CHECK (ptr == NULL); + + ptr = p_mem_mmap (1024, NULL); + P_TEST_REQUIRE (ptr != NULL); + + for (i = 0; i < 1024; ++i) + *(((pchar *) ptr) + i) = i % 127; + + for (i = 0; i < 1024; ++i) + P_TEST_CHECK (*(((pchar *) ptr) + i) == i % 127); + + P_TEST_CHECK (p_mem_munmap (NULL, 1024, NULL) == FALSE); + P_TEST_CHECK (p_mem_munmap (ptr, 1024, NULL) == TRUE); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (pmem_bad_input_test); + P_TEST_SUITE_RUN_CASE (pmem_general_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/pmutex_test.cpp b/3rdparty/plibsys/tests/pmutex_test.cpp new file mode 100644 index 0000000..4d16909 --- /dev/null +++ b/3rdparty/plibsys/tests/pmutex_test.cpp @@ -0,0 +1,146 @@ +/* + * The MIT License + * + * Copyright (C) 2013-2019 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +P_TEST_MODULE_INIT (); + +static pint mutex_test_val = 0; +static PMutex *global_mutex = NULL; + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + P_UNUSED (block); + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" void pmem_free (ppointer block) +{ + P_UNUSED (block); +} + +static void * mutex_test_thread (void *) +{ + pint i; + + for (i = 0; i < 1000; ++i) { + if (!p_mutex_trylock (global_mutex)) { + if (!p_mutex_lock (global_mutex)) + p_uthread_exit (1); + } + + if (mutex_test_val == 10) + --mutex_test_val; + else { + p_uthread_sleep (1); + ++mutex_test_val; + } + + if (!p_mutex_unlock (global_mutex)) + p_uthread_exit (1); + } + + p_uthread_exit (0); + + return NULL; +} + +P_TEST_CASE_BEGIN (pmutex_nomem_test) +{ + p_libsys_init (); + + PMemVTable vtable; + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + P_TEST_CHECK (p_mutex_new () == NULL); + + p_mem_restore_vtable (); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pmutex_bad_input_test) +{ + p_libsys_init (); + + P_TEST_REQUIRE (p_mutex_lock (NULL) == FALSE); + P_TEST_REQUIRE (p_mutex_unlock (NULL) == FALSE); + P_TEST_REQUIRE (p_mutex_trylock (NULL) == FALSE); + p_mutex_free (NULL); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pmutex_general_test) +{ + PUThread *thr1, *thr2; + + p_libsys_init (); + + global_mutex = p_mutex_new (); + P_TEST_REQUIRE (global_mutex != NULL); + + mutex_test_val = 10; + + thr1 = p_uthread_create ((PUThreadFunc) mutex_test_thread, NULL, TRUE, NULL); + P_TEST_REQUIRE (thr1 != NULL); + + thr2 = p_uthread_create ((PUThreadFunc) mutex_test_thread, NULL, TRUE, NULL); + P_TEST_REQUIRE (thr2 != NULL); + + P_TEST_CHECK (p_uthread_join (thr1) == 0); + P_TEST_CHECK (p_uthread_join (thr2) == 0); + + P_TEST_REQUIRE (mutex_test_val == 10); + + p_uthread_unref (thr1); + p_uthread_unref (thr2); + p_mutex_free (global_mutex); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (pmutex_nomem_test); + P_TEST_SUITE_RUN_CASE (pmutex_bad_input_test); + P_TEST_SUITE_RUN_CASE (pmutex_general_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/pprocess_test.cpp b/3rdparty/plibsys/tests/pprocess_test.cpp new file mode 100644 index 0000000..c58cf13 --- /dev/null +++ b/3rdparty/plibsys/tests/pprocess_test.cpp @@ -0,0 +1,49 @@ +/* + * The MIT License + * + * Copyright (C) 2013-2017 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +P_TEST_MODULE_INIT (); + +P_TEST_CASE_BEGIN (pprocess_general_test) +{ + puint32 pid; + + p_libsys_init (); + + pid = p_process_get_current_pid (); + P_TEST_CHECK (pid > 0); + P_TEST_REQUIRE (p_process_is_running (pid) == TRUE); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (pprocess_general_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/prwlock_test.cpp b/3rdparty/plibsys/tests/prwlock_test.cpp new file mode 100644 index 0000000..c8bce38 --- /dev/null +++ b/3rdparty/plibsys/tests/prwlock_test.cpp @@ -0,0 +1,224 @@ +/* + * The MIT License + * + * Copyright (C) 2016-2019 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +#include + +P_TEST_MODULE_INIT (); + +#define PRWLOCK_TEST_STRING_1 "This is a test string." +#define PRWLOCK_TEST_STRING_2 "Ouh, yet another string to check!" + +static PRWLock * test_rwlock = NULL; +static volatile pboolean is_threads_working = FALSE; +static volatile pint writers_counter = 0; +static pchar string_buf[50]; + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + P_UNUSED (block); + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" void pmem_free (ppointer block) +{ + P_UNUSED (block); +} + +static void * reader_thread_func (void *data) +{ + P_UNUSED (data); + + pint counter = 0; + + while (p_atomic_int_get (&writers_counter) == 0) + p_uthread_sleep (10); + + while (is_threads_working == TRUE) { + p_uthread_sleep (10); + + if (p_rwlock_reader_trylock (test_rwlock) == FALSE) { + if (p_rwlock_reader_lock (test_rwlock) == FALSE) + p_uthread_exit (-1); + } + + if (strcmp (string_buf, PRWLOCK_TEST_STRING_1) != 0 && + strcmp (string_buf, PRWLOCK_TEST_STRING_2) != 0) { + p_rwlock_reader_unlock (test_rwlock); + p_uthread_exit (-1); + } + + if (p_rwlock_reader_unlock (test_rwlock) == FALSE) + p_uthread_exit (-1); + + ++counter; + } + + p_uthread_exit (counter); + + return NULL; +} + +static void * writer_thread_func (void *data) +{ + pint string_num = PPOINTER_TO_INT (data); + pint counter = 0; + + while (is_threads_working == TRUE) { + p_uthread_sleep (10); + + if (p_rwlock_writer_trylock (test_rwlock) == FALSE) { + if (p_rwlock_writer_lock (test_rwlock) == FALSE) + p_uthread_exit (-1); + } + + memset (string_buf, 0, sizeof (string_buf)); + + if (string_num == 1) + strcpy (string_buf, PRWLOCK_TEST_STRING_1); + else + strcpy (string_buf, PRWLOCK_TEST_STRING_1); + + if (p_rwlock_writer_unlock (test_rwlock) == FALSE) + p_uthread_exit (-1); + + ++counter; + + p_atomic_int_inc ((&writers_counter)); + } + + p_uthread_exit (counter); + + return NULL; +} + +P_TEST_CASE_BEGIN (prwlock_nomem_test) +{ + p_libsys_init (); + + PMemVTable vtable; + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + + P_TEST_CHECK (p_rwlock_new () == NULL); + + p_mem_restore_vtable (); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (prwlock_bad_input_test) +{ + p_libsys_init (); + + P_TEST_CHECK (p_rwlock_reader_lock (NULL) == FALSE); + P_TEST_CHECK (p_rwlock_reader_trylock (NULL) == FALSE); + P_TEST_CHECK (p_rwlock_reader_unlock (NULL) == FALSE); + P_TEST_CHECK (p_rwlock_writer_lock (NULL) == FALSE); + P_TEST_CHECK (p_rwlock_writer_trylock (NULL) == FALSE); + P_TEST_CHECK (p_rwlock_writer_unlock (NULL) == FALSE); + p_rwlock_free (NULL); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (prwlock_general_test) +{ + p_libsys_init (); + + test_rwlock = p_rwlock_new (); + + P_TEST_REQUIRE (test_rwlock != NULL); + + is_threads_working = TRUE; + writers_counter = 0; + + PUThread *reader_thr1 = p_uthread_create ((PUThreadFunc) reader_thread_func, + NULL, + TRUE, + NULL); + + PUThread *reader_thr2 = p_uthread_create ((PUThreadFunc) reader_thread_func, + NULL, + TRUE, + NULL); + + PUThread *writer_thr1 = p_uthread_create ((PUThreadFunc) writer_thread_func, + NULL, + TRUE, + NULL); + + PUThread *writer_thr2 = p_uthread_create ((PUThreadFunc) writer_thread_func, + NULL, + TRUE, + NULL); + + P_TEST_REQUIRE (reader_thr1 != NULL); + P_TEST_REQUIRE (reader_thr2 != NULL); + P_TEST_REQUIRE (writer_thr1 != NULL); + P_TEST_REQUIRE (writer_thr2 != NULL); + + p_uthread_sleep (10000); + + is_threads_working = FALSE; + + P_TEST_CHECK (p_uthread_join (reader_thr1) > 0); + P_TEST_CHECK (p_uthread_join (reader_thr2) > 0); + P_TEST_CHECK (p_uthread_join (writer_thr1) > 0); + P_TEST_CHECK (p_uthread_join (writer_thr2) > 0); + + p_uthread_unref (reader_thr1); + p_uthread_unref (reader_thr2); + p_uthread_unref (writer_thr1); + p_uthread_unref (writer_thr2); + + p_rwlock_free (test_rwlock); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (prwlock_nomem_test); + P_TEST_SUITE_RUN_CASE (prwlock_bad_input_test); + P_TEST_SUITE_RUN_CASE (prwlock_general_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/psemaphore_test.cpp b/3rdparty/plibsys/tests/psemaphore_test.cpp new file mode 100644 index 0000000..0b445bd --- /dev/null +++ b/3rdparty/plibsys/tests/psemaphore_test.cpp @@ -0,0 +1,226 @@ +/* + * The MIT License + * + * Copyright (C) 2013-2019 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +P_TEST_MODULE_INIT (); + +#define PSEMAPHORE_MAX_VAL 10 + +static pint semaphore_test_val = 0; +static pint is_thread_exit = 0; + +static void clean_error (PError **error) +{ + if (error == NULL || *error == NULL) + return; + + p_error_free (*error); + *error = NULL; +} + +static void * semaphore_test_thread (void *) +{ + PSemaphore *sem; + pint i; + + sem = p_semaphore_new ("p_semaphore_test_object", 1, P_SEM_ACCESS_OPEN, NULL); + + if (sem == NULL) + p_uthread_exit (1); + + for (i = 0; i < 1000; ++i) { + if (!p_semaphore_acquire (sem, NULL)) { + if (is_thread_exit > 0) { + semaphore_test_val = PSEMAPHORE_MAX_VAL; + break; + } + + p_uthread_exit (1); + } + + if (semaphore_test_val == PSEMAPHORE_MAX_VAL) + --semaphore_test_val; + else { + p_uthread_sleep (1); + ++semaphore_test_val; + } + + if (!p_semaphore_release (sem, NULL)) { + if (is_thread_exit > 0) { + semaphore_test_val = PSEMAPHORE_MAX_VAL; + break; + } + + p_uthread_exit (1); + } + } + + ++is_thread_exit; + + p_semaphore_free (sem); + p_uthread_exit (0); + + return NULL; +} + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + P_UNUSED (block); + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" void pmem_free (ppointer block) +{ + P_UNUSED (block); +} + +P_TEST_CASE_BEGIN (psemaphore_nomem_test) +{ + p_libsys_init (); + + PMemVTable vtable; + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + + P_TEST_CHECK (p_semaphore_new ("p_semaphore_test_object", 1, P_SEM_ACCESS_CREATE, NULL) == NULL); + + p_mem_restore_vtable (); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (psemaphore_general_test) +{ + PSemaphore *sem = NULL; + PError *error = NULL; + pint i; + + p_libsys_init (); + + P_TEST_CHECK (p_semaphore_new (NULL, 0, P_SEM_ACCESS_CREATE, &error) == NULL); + P_TEST_CHECK (error != NULL); + clean_error (&error); + + P_TEST_REQUIRE (p_semaphore_acquire (sem, &error) == FALSE); + P_TEST_CHECK (error != NULL); + clean_error (&error); + + P_TEST_REQUIRE (p_semaphore_release (sem, &error) == FALSE); + P_TEST_CHECK (error != NULL); + clean_error (&error); + + p_semaphore_take_ownership (sem); + p_semaphore_free (NULL); + + sem = p_semaphore_new ("p_semaphore_test_object", 10, P_SEM_ACCESS_CREATE, NULL); + P_TEST_REQUIRE (sem != NULL); + p_semaphore_take_ownership (sem); + p_semaphore_free (sem); + + sem = p_semaphore_new ("p_semaphore_test_object", 10, P_SEM_ACCESS_CREATE, NULL); + P_TEST_REQUIRE (sem != NULL); + + for (i = 0; i < 10; ++i) + P_TEST_CHECK (p_semaphore_acquire (sem, NULL)); + + for (i = 0; i < 10; ++i) + P_TEST_CHECK (p_semaphore_release (sem, NULL)); + + for (i = 0; i < 1000; ++i) { + P_TEST_CHECK (p_semaphore_acquire (sem, NULL)); + P_TEST_CHECK (p_semaphore_release (sem, NULL)); + } + + p_semaphore_free (sem); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (psemaphore_thread_test) +{ + PUThread *thr1, *thr2; + PSemaphore *sem = NULL; + + p_libsys_init (); + + sem = p_semaphore_new ("p_semaphore_test_object", 10, P_SEM_ACCESS_CREATE, NULL); + P_TEST_REQUIRE (sem != NULL); + p_semaphore_take_ownership (sem); + p_semaphore_free (sem); + + sem = NULL; + is_thread_exit = 0; + semaphore_test_val = PSEMAPHORE_MAX_VAL; + + thr1 = p_uthread_create ((PUThreadFunc) semaphore_test_thread, NULL, TRUE, NULL); + P_TEST_REQUIRE (thr1 != NULL); + + thr2 = p_uthread_create ((PUThreadFunc) semaphore_test_thread, NULL, TRUE, NULL); + P_TEST_REQUIRE (thr2 != NULL); + + P_TEST_CHECK (p_uthread_join (thr1) == 0); + P_TEST_CHECK (p_uthread_join (thr2) == 0); + + P_TEST_REQUIRE (semaphore_test_val == PSEMAPHORE_MAX_VAL); + + P_TEST_REQUIRE (p_semaphore_acquire (sem, NULL) == FALSE); + P_TEST_REQUIRE (p_semaphore_release (sem, NULL) == FALSE); + p_semaphore_free (sem); + p_semaphore_take_ownership (sem); + + sem = p_semaphore_new ("p_semaphore_test_object", 1, P_SEM_ACCESS_OPEN, NULL); + P_TEST_REQUIRE (sem != NULL); + p_semaphore_take_ownership (sem); + p_semaphore_free (sem); + + p_uthread_unref (thr1); + p_uthread_unref (thr2); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (psemaphore_nomem_test); + P_TEST_SUITE_RUN_CASE (psemaphore_general_test); + P_TEST_SUITE_RUN_CASE (psemaphore_thread_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/pshm_test.cpp b/3rdparty/plibsys/tests/pshm_test.cpp new file mode 100644 index 0000000..bc89692 --- /dev/null +++ b/3rdparty/plibsys/tests/pshm_test.cpp @@ -0,0 +1,313 @@ +/* + * The MIT License + * + * Copyright (C) 2013-2019 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +#include +#include + +P_TEST_MODULE_INIT (); + +static void * shm_test_thread (void *arg) +{ + pint rand_num; + psize shm_size; + ppointer addr; + PShm *shm; + + if (arg == NULL) + p_uthread_exit (1); + + shm = (PShm *) arg; + rand_num = rand () % 127; + shm_size = p_shm_get_size (shm); + addr = p_shm_get_address (shm); + + if (shm_size == 0 || addr == NULL) + p_uthread_exit (1); + + if (!p_shm_lock (shm, NULL)) + p_uthread_exit (1); + + for (puint i = 0; i < shm_size; ++i) + *(((pchar *) addr) + i) = (pchar) rand_num; + + if (!p_shm_unlock (shm, NULL)) + p_uthread_exit (1); + + p_uthread_exit (0); + + return NULL; +} + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + P_UNUSED (block); + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" void pmem_free (ppointer block) +{ + P_UNUSED (block); +} + +P_TEST_CASE_BEGIN (pshm_nomem_test) +{ + p_libsys_init (); + + PMemVTable vtable; + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + + P_TEST_CHECK (p_shm_new ("p_shm_test_memory_block", 1024, P_SHM_ACCESS_READWRITE, NULL) == NULL); + + p_mem_restore_vtable (); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pshm_invalid_test) +{ + p_libsys_init (); + + P_TEST_CHECK (p_shm_new (NULL, 0, P_SHM_ACCESS_READWRITE, NULL) == NULL); + P_TEST_CHECK (p_shm_lock (NULL, NULL) == FALSE); + P_TEST_CHECK (p_shm_unlock (NULL, NULL) == FALSE); + P_TEST_CHECK (p_shm_get_address (NULL) == NULL); + P_TEST_CHECK (p_shm_get_size (NULL) == 0); + p_shm_take_ownership (NULL); + + PShm *shm = p_shm_new ("p_shm_invalid_test", 0, P_SHM_ACCESS_READWRITE, NULL); + p_shm_take_ownership (shm); + p_shm_free (shm); + + shm = p_shm_new ("p_shm_invalid_test", 10, (PShmAccessPerms) -1, NULL); + p_shm_take_ownership (shm); + p_shm_free (shm); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pshm_general_test) +{ + PShm *shm = NULL; +#ifndef P_OS_HPUX + PShm *shm2 = NULL; +#endif + ppointer addr, addr2; + pint i; + + p_libsys_init (); + + shm = p_shm_new ("p_shm_test_memory_block", 1024, P_SHM_ACCESS_READWRITE, NULL); + P_TEST_REQUIRE (shm != NULL); + p_shm_take_ownership (shm); + p_shm_free (shm); + + shm = p_shm_new ("p_shm_test_memory_block", 1024, P_SHM_ACCESS_READWRITE, NULL); + P_TEST_REQUIRE (shm != NULL); + P_TEST_REQUIRE (p_shm_get_size (shm) == 1024); + + addr = p_shm_get_address (shm); + P_TEST_REQUIRE (addr != NULL); + +#ifndef P_OS_HPUX + shm2 = p_shm_new ("p_shm_test_memory_block", 1024, P_SHM_ACCESS_READONLY, NULL); + + if (shm2 == NULL) { + /* OK, some systems may want exactly the same permissions */ + shm2 = p_shm_new ("p_shm_test_memory_block", 1024, P_SHM_ACCESS_READWRITE, NULL); + } + + P_TEST_REQUIRE (shm2 != NULL); + P_TEST_REQUIRE (p_shm_get_size (shm2) == 1024); + + addr2 = p_shm_get_address (shm2); + P_TEST_REQUIRE (addr2 != NULL); +#endif + + for (i = 0; i < 512; ++i) { + P_TEST_CHECK (p_shm_lock (shm, NULL)); + *(((pchar *) addr) + i) = 'a'; + P_TEST_CHECK (p_shm_unlock (shm, NULL)); + } + +#ifndef P_OS_HPUX + for (i = 0; i < 512; ++i) { + P_TEST_CHECK (p_shm_lock (shm2, NULL)); + P_TEST_CHECK (*(((pchar *) addr) + i) == 'a'); + P_TEST_CHECK (p_shm_unlock (shm2, NULL)); + } +#else + for (i = 0; i < 512; ++i) { + P_TEST_CHECK (p_shm_lock (shm, NULL)); + P_TEST_CHECK (*(((pchar *) addr) + i) == 'a'); + P_TEST_CHECK (p_shm_unlock (shm, NULL)); + } +#endif + + for (i = 0; i < 1024; ++i) { + P_TEST_CHECK (p_shm_lock (shm, NULL)); + *(((pchar *) addr) + i) = 'b'; + P_TEST_CHECK (p_shm_unlock (shm, NULL)); + } + +#ifndef P_OS_HPUX + for (i = 0; i < 1024; ++i) { + P_TEST_CHECK (p_shm_lock (shm2, NULL)); + P_TEST_CHECK (*(((pchar *) addr) + i) != 'c'); + P_TEST_CHECK (p_shm_unlock (shm2, NULL)); + } + + for (i = 0; i < 1024; ++i) { + P_TEST_CHECK (p_shm_lock (shm2, NULL)); + P_TEST_CHECK (*(((pchar *) addr) + i) == 'b'); + P_TEST_CHECK (p_shm_unlock (shm2, NULL)); + } +#else + for (i = 0; i < 1024; ++i) { + P_TEST_CHECK (p_shm_lock (shm, NULL)); + P_TEST_CHECK (*(((pchar *) addr) + i) != 'c'); + P_TEST_CHECK (p_shm_unlock (shm, NULL)); + } + + for (i = 0; i < 1024; ++i) { + P_TEST_CHECK (p_shm_lock (shm, NULL)); + P_TEST_CHECK (*(((pchar *) addr) + i) == 'b'); + P_TEST_CHECK (p_shm_unlock (shm, NULL)); + } +#endif + + p_shm_free (shm); + + shm = p_shm_new ("p_shm_test_memory_block_2", 1024, P_SHM_ACCESS_READWRITE, NULL); + P_TEST_REQUIRE (shm != NULL); + P_TEST_REQUIRE (p_shm_get_size (shm) == 1024); + + addr = p_shm_get_address (shm); + P_TEST_REQUIRE (addr != NULL); + + for (i = 0; i < 1024; ++i) { + P_TEST_CHECK (p_shm_lock (shm, NULL)); + P_TEST_CHECK (*(((pchar *) addr) + i) != 'b'); + P_TEST_CHECK (p_shm_unlock (shm, NULL)); + } + + p_shm_free (shm); + +#ifndef P_OS_HPUX + p_shm_free (shm2); +#endif + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pshm_thread_test) +{ + PShm *shm; + PUThread *thr1, *thr2, *thr3; + ppointer addr; + pint i, val; + pboolean test_ok; + + p_libsys_init (); + + srand ((puint) time (NULL)); + + shm = p_shm_new ("p_shm_test_memory_block", 1024 * 1024, P_SHM_ACCESS_READWRITE, NULL); + P_TEST_REQUIRE (shm != NULL); + p_shm_take_ownership (shm); + p_shm_free (shm); + + shm = p_shm_new ("p_shm_test_memory_block", 1024 * 1024, P_SHM_ACCESS_READWRITE, NULL); + P_TEST_REQUIRE (shm != NULL); + + if (p_shm_get_size (shm) != 1024 * 1024) { + p_shm_free (shm); + shm = p_shm_new ("p_shm_test_memory_block", 1024 * 1024, P_SHM_ACCESS_READWRITE, NULL); + P_TEST_REQUIRE (shm != NULL); + } + + P_TEST_REQUIRE (p_shm_get_size (shm) == 1024 * 1024); + + addr = p_shm_get_address (shm); + P_TEST_REQUIRE (addr != NULL); + + thr1 = p_uthread_create ((PUThreadFunc) shm_test_thread, (ppointer) shm, TRUE, NULL); + P_TEST_REQUIRE (thr1 != NULL); + + thr2 = p_uthread_create ((PUThreadFunc) shm_test_thread, (ppointer) shm, TRUE, NULL); + P_TEST_REQUIRE (thr2 != NULL); + + thr3 = p_uthread_create ((PUThreadFunc) shm_test_thread, (ppointer) shm, TRUE, NULL); + P_TEST_REQUIRE (thr3 != NULL); + + P_TEST_CHECK (p_uthread_join (thr1) == 0); + P_TEST_CHECK (p_uthread_join (thr2) == 0); + P_TEST_CHECK (p_uthread_join (thr3) == 0); + + test_ok = TRUE; + val = *((pchar *) addr); + + for (i = 1; i < 1024 * 1024; ++i) + if (*(((pchar *) addr) + i) != val) { + test_ok = FALSE; + break; + } + + P_TEST_REQUIRE (test_ok == TRUE); + + p_uthread_unref (thr1); + p_uthread_unref (thr2); + p_uthread_unref (thr3); + p_shm_free (shm); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (pshm_nomem_test); + P_TEST_SUITE_RUN_CASE (pshm_invalid_test); + P_TEST_SUITE_RUN_CASE (pshm_general_test); + P_TEST_SUITE_RUN_CASE (pshm_thread_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/pshmbuffer_test.cpp b/3rdparty/plibsys/tests/pshmbuffer_test.cpp new file mode 100644 index 0000000..7e48f56 --- /dev/null +++ b/3rdparty/plibsys/tests/pshmbuffer_test.cpp @@ -0,0 +1,352 @@ +/* + * The MIT License + * + * Copyright (C) 2013-2020 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +#include + +P_TEST_MODULE_INIT (); + +static pchar test_str[] = "This is a test string!"; +static pchar test_str_sm[] = "Small"; +static pint is_thread_exit = 0; +static pint read_count = 0; +static pint write_count = 0; + +#ifndef P_OS_HPUX +volatile static pboolean is_working = FALSE; + +static void * shm_buffer_test_write_thread (void *) +{ + PShmBuffer *buffer = p_shm_buffer_new ("pshm_test_buffer", 1024, NULL); + + if (buffer == NULL) + p_uthread_exit (1); + + while (is_working == TRUE) { + p_uthread_sleep (3); + + pssize op_result = p_shm_buffer_get_free_space (buffer, NULL); + + if (op_result < 0) { + if (is_thread_exit > 0) + break; + else { + ++is_thread_exit; + p_shm_buffer_free (buffer); + p_uthread_exit (1); + } + } + + if ((psize) op_result < sizeof (test_str)) + continue; + + op_result = p_shm_buffer_write (buffer, (ppointer) test_str, sizeof (test_str), NULL); + + if (op_result < 0) { + if (is_thread_exit > 0) + break; + else { + ++is_thread_exit; + p_shm_buffer_free (buffer); + p_uthread_exit (1); + } + } + + if (op_result != sizeof (test_str)) { + ++is_thread_exit; + p_shm_buffer_free (buffer); + p_uthread_exit (1); + } + + ++read_count; + } + + ++is_thread_exit; + + p_shm_buffer_free (buffer); + p_uthread_exit (0); + + return NULL; +} + +static void * shm_buffer_test_read_thread (void *) +{ + PShmBuffer *buffer = p_shm_buffer_new ("pshm_test_buffer", 1024, NULL); + pchar test_buf[sizeof (test_str)]; + + if (buffer == NULL) + p_uthread_exit (1); + + while (is_working == TRUE) { + p_uthread_sleep (3); + + pssize op_result = p_shm_buffer_get_used_space (buffer, NULL); + + if (op_result < 0) { + if (is_thread_exit > 0) + break; + else { + ++is_thread_exit; + p_shm_buffer_free (buffer); + p_uthread_exit (1); + } + } + + if ((psize) op_result < sizeof (test_str)) + continue; + + op_result = p_shm_buffer_read (buffer, (ppointer) test_buf, sizeof (test_buf), NULL); + + if (op_result < 0) { + if (is_thread_exit > 0) + break; + else { + ++is_thread_exit; + p_shm_buffer_free (buffer); + p_uthread_exit (1); + } + } + + if (op_result != sizeof (test_buf)) { + ++is_thread_exit; + p_shm_buffer_free (buffer); + p_uthread_exit (1); + } + + if (strncmp (test_buf, test_str, sizeof (test_buf)) != 0) { + ++is_thread_exit; + p_shm_buffer_free (buffer); + p_uthread_exit (1); + } + + ++write_count; + } + + ++is_thread_exit; + + p_shm_buffer_free (buffer); + p_uthread_exit (0); + + return NULL; +} +#endif /* !P_OS_HPUX */ + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + P_UNUSED (block); + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" void pmem_free (ppointer block) +{ + P_UNUSED (block); +} + +P_TEST_CASE_BEGIN (pshmbuffer_nomem_test) +{ + p_libsys_init (); + + PMemVTable vtable; + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + + P_TEST_CHECK (p_shm_buffer_new ("pshm_test_buffer", 1024, NULL) == NULL); + + p_mem_restore_vtable (); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pshmbuffer_bad_input_test) +{ + p_libsys_init (); + + P_TEST_CHECK (p_shm_buffer_new (NULL, 0, NULL) == NULL); + P_TEST_CHECK (p_shm_buffer_read (NULL, NULL, 0, NULL) == -1); + P_TEST_CHECK (p_shm_buffer_write (NULL, NULL, 0, NULL) == -1); + P_TEST_CHECK (p_shm_buffer_get_free_space (NULL, NULL) == -1); + P_TEST_CHECK (p_shm_buffer_get_used_space (NULL, NULL) == -1); + + PShmBuffer *buf = p_shm_buffer_new ("pshm_invalid_buffer", 0, NULL); + p_shm_buffer_take_ownership (buf); + p_shm_buffer_free (buf); + + p_shm_buffer_clear (NULL); + p_shm_buffer_free (NULL); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pshmbuffer_general_test) +{ + p_libsys_init (); + + pchar test_buf[sizeof (test_str)]; + pchar *large_buf; + PShmBuffer *buffer = NULL; + + /* Buffer may be from the previous test on UNIX systems */ + buffer = p_shm_buffer_new ("pshm_test_buffer", 1024, NULL); + P_TEST_REQUIRE (buffer != NULL); + p_shm_buffer_take_ownership (buffer); + p_shm_buffer_free (buffer); + buffer = p_shm_buffer_new ("pshm_test_buffer", 1024, NULL); + P_TEST_REQUIRE (buffer != NULL); + + P_TEST_CHECK (p_shm_buffer_get_free_space (buffer, NULL) == 1024); + P_TEST_CHECK (p_shm_buffer_get_used_space (buffer, NULL) == 0); + p_shm_buffer_clear (buffer); + P_TEST_CHECK (p_shm_buffer_get_free_space (buffer, NULL) == 1024); + P_TEST_CHECK (p_shm_buffer_get_used_space (buffer, NULL) == 0); + + memset (test_buf, 0, sizeof (test_buf)); + + P_TEST_CHECK (p_shm_buffer_write (buffer, (ppointer) test_str, sizeof (test_str), NULL) == sizeof (test_str)); + P_TEST_CHECK (p_shm_buffer_get_free_space (buffer, NULL) == (1024 - sizeof (test_str))); + P_TEST_CHECK (p_shm_buffer_get_used_space (buffer, NULL) == sizeof (test_str)); + P_TEST_CHECK (p_shm_buffer_read (buffer, (ppointer) test_buf, sizeof (test_buf), NULL) == sizeof (test_str)); + P_TEST_CHECK (p_shm_buffer_read (buffer, (ppointer) test_buf, sizeof (test_buf), NULL) == 0); + + P_TEST_CHECK (strncmp (test_buf, test_str, sizeof (test_str)) == 0); + P_TEST_CHECK (p_shm_buffer_get_free_space (buffer, NULL) == 1024); + P_TEST_CHECK (p_shm_buffer_get_used_space (buffer, NULL) == 0); + + p_shm_buffer_clear (buffer); + + large_buf = (pchar *) p_malloc0 (2048); + P_TEST_REQUIRE (large_buf != NULL); + P_TEST_CHECK (p_shm_buffer_write (buffer, (ppointer) large_buf, 2048, NULL) == 0); + + p_free (large_buf); + p_shm_buffer_free (buffer); + + /* Test read-write positions */ + + buffer = p_shm_buffer_new ("pshm_test_buffer_small", 10, NULL); + P_TEST_REQUIRE (buffer != NULL); + p_shm_buffer_take_ownership (buffer); + p_shm_buffer_free (buffer); + buffer = p_shm_buffer_new ("pshm_test_buffer_small", 10, NULL); + P_TEST_REQUIRE (buffer != NULL); + + P_TEST_CHECK (p_shm_buffer_get_free_space (buffer, NULL) == 10); + P_TEST_CHECK (p_shm_buffer_get_used_space (buffer, NULL) == 0); + + /* Case 1: write position > read position */ + P_TEST_CHECK (p_shm_buffer_write (buffer, (ppointer) test_str_sm, sizeof (test_str_sm), NULL) == sizeof (test_str_sm)); + P_TEST_CHECK (p_shm_buffer_get_free_space (buffer, NULL) == (10 - sizeof (test_str_sm))); + P_TEST_CHECK (p_shm_buffer_get_used_space (buffer, NULL) == sizeof (test_str_sm)); + + /* Case 2: write position == read position */ + memset (test_buf, 0, sizeof (test_buf)); + P_TEST_CHECK (p_shm_buffer_read (buffer, (ppointer) test_buf, sizeof (test_buf), NULL) == sizeof (test_str_sm)); + P_TEST_CHECK (strncmp (test_buf, test_str_sm, sizeof (test_str_sm)) == 0); + P_TEST_CHECK (p_shm_buffer_get_free_space (buffer, NULL) == 10); + P_TEST_CHECK (p_shm_buffer_get_used_space (buffer, NULL) == 0); + + /* Case 3: write position < read position */ + P_TEST_CHECK (p_shm_buffer_write (buffer, (ppointer) test_str_sm, sizeof (test_str_sm), NULL) == sizeof (test_str_sm)); + P_TEST_CHECK (p_shm_buffer_get_free_space (buffer, NULL) == (10 - sizeof (test_str_sm))); + P_TEST_CHECK (p_shm_buffer_get_used_space (buffer, NULL) == sizeof (test_str_sm)); + + p_shm_buffer_free (buffer); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +#ifndef P_OS_HPUX +P_TEST_CASE_BEGIN (pshmbuffer_thread_test) +{ + p_libsys_init (); + + PShmBuffer *buffer = NULL; + PUThread *thr1, *thr2; + + /* Buffer may be from the previous test on UNIX systems */ + buffer = p_shm_buffer_new ("pshm_test_buffer", 1024, NULL); + P_TEST_REQUIRE (buffer != NULL); + p_shm_buffer_take_ownership (buffer); + p_shm_buffer_free (buffer); + + is_thread_exit = 0; + read_count = 0; + write_count = 0; + is_working = TRUE; + + buffer = p_shm_buffer_new ("pshm_test_buffer", 1024, NULL); + P_TEST_REQUIRE (buffer != NULL); + + thr1 = p_uthread_create ((PUThreadFunc) shm_buffer_test_write_thread, NULL, TRUE, NULL); + P_TEST_REQUIRE (thr1 != NULL); + + thr2 = p_uthread_create ((PUThreadFunc) shm_buffer_test_read_thread, NULL, TRUE, NULL); + P_TEST_REQUIRE (thr1 != NULL); + + p_uthread_sleep (5000); + + is_working = FALSE; + + P_TEST_CHECK (p_uthread_join (thr1) == 0); + P_TEST_CHECK (p_uthread_join (thr2) == 0); + + P_TEST_CHECK (read_count > 0); + P_TEST_CHECK (write_count > 0); + + p_shm_buffer_free (buffer); + p_uthread_unref (thr1); + p_uthread_unref (thr2); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () +#endif /* !P_OS_HPUX */ + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (pshmbuffer_nomem_test); + P_TEST_SUITE_RUN_CASE (pshmbuffer_bad_input_test); + P_TEST_SUITE_RUN_CASE (pshmbuffer_general_test); + +#ifndef P_OS_HPUX + P_TEST_SUITE_RUN_CASE (pshmbuffer_thread_test); +#endif +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/psocket_test.cpp b/3rdparty/plibsys/tests/psocket_test.cpp new file mode 100644 index 0000000..c1a44a4 --- /dev/null +++ b/3rdparty/plibsys/tests/psocket_test.cpp @@ -0,0 +1,1131 @@ +/* + * The MIT License + * + * Copyright (C) 2013-2019 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +#include + +P_TEST_MODULE_INIT (); + +static pchar socket_data[] = "This is a socket test data!"; +volatile static pboolean is_sender_working = FALSE; +volatile static pboolean is_receiver_working = FALSE; + +typedef struct _SocketTestData { + puint16 sender_port; + puint16 receiver_port; + pboolean shutdown_channel; +} SocketTestData; + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + P_UNUSED (block); + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" void pmem_free (ppointer block) +{ + P_UNUSED (block); +} + +static void clean_error (PError **error) +{ + if (error == NULL || *error == NULL) + return; + + p_error_free (*error); + *error = NULL; +} + +static pboolean test_socket_address_directly (const PSocketAddress *addr, puint16 port) +{ + if (addr == NULL) + return FALSE; + + pchar *addr_str = p_socket_address_get_address (addr); + PSocketFamily remote_family = p_socket_address_get_family (addr); + puint16 remote_port = p_socket_address_get_port (addr); + psize remote_size = p_socket_address_get_native_size (addr); + + pboolean ret = (strcmp (addr_str, "127.0.0.1") == 0 && remote_family == P_SOCKET_FAMILY_INET && + remote_port == port && remote_size > 0) ? TRUE : FALSE; + + p_free (addr_str); + + return ret; +} + +static pboolean test_socket_address (PSocket *socket, puint16 port) +{ + /* Test remote address */ + PSocketAddress *remote_addr = p_socket_get_remote_address (socket, NULL); + + if (remote_addr == NULL) + return FALSE; + + pboolean ret = test_socket_address_directly (remote_addr, port); + + p_socket_address_free (remote_addr); + + return ret; +} + +static pboolean compare_socket_addresses (const PSocketAddress *addr1, const PSocketAddress *addr2) +{ + if (addr1 == NULL || addr2 == NULL) + return FALSE; + + pchar *addr_str1 = p_socket_address_get_address (addr1); + pchar *addr_str2 = p_socket_address_get_address (addr2); + + if (addr_str1 == NULL || addr_str2 == NULL) { + p_free (addr_str1); + p_free (addr_str2); + + return FALSE; + } + + pboolean addr_cmp = (strcmp (addr_str1, addr_str2) == 0 ? TRUE : FALSE); + + p_free (addr_str1); + p_free (addr_str2); + + if (addr_cmp == FALSE) + return FALSE; + + if (p_socket_address_get_family (addr1) != p_socket_address_get_family (addr2)) + return FALSE; + + if (p_socket_address_get_native_size (addr1) != p_socket_address_get_native_size (addr2)) + return FALSE; + + return TRUE; +} + +static void * udp_socket_sender_thread (void *arg) +{ + pint send_counter = 0; + + if (arg == NULL) + p_uthread_exit (-1); + + SocketTestData *data = (SocketTestData *) (arg); + + /* Create sender socket */ + PSocket *skt_sender = p_socket_new (P_SOCKET_FAMILY_INET, + P_SOCKET_TYPE_DATAGRAM, + P_SOCKET_PROTOCOL_UDP, + NULL); + + if (skt_sender == NULL) + p_uthread_exit (-1); + + PSocketAddress *addr_sender = p_socket_address_new ("127.0.0.1", data->sender_port); + + if (addr_sender == NULL) { + p_socket_free (skt_sender); + p_uthread_exit (-1); + } + + if (p_socket_bind (skt_sender, addr_sender, FALSE, NULL) == FALSE) { + p_socket_free (skt_sender); + p_socket_address_free (addr_sender); + p_uthread_exit (-1); + } else { + p_socket_address_free (addr_sender); + + PSocketAddress *local_addr = p_socket_get_local_address (skt_sender, NULL); + + if (local_addr == NULL) { + p_socket_free (skt_sender); + p_uthread_exit (-1); + } + + data->sender_port = p_socket_address_get_port (local_addr); + + p_socket_address_free (local_addr); + } + + p_socket_set_timeout (skt_sender, 50); + + /* Test that remote address is NULL */ + PSocketAddress *remote_addr = p_socket_get_remote_address (skt_sender, NULL); + + if (remote_addr != NULL) { + if (p_socket_address_is_any (remote_addr) == FALSE) { + p_socket_address_free (remote_addr); + p_socket_free (skt_sender); + p_uthread_exit (-1); + } else { + p_socket_address_free (remote_addr); + remote_addr = NULL; + } + } + + /* Test that we are not connected */ + if (p_socket_is_connected (skt_sender) == TRUE) { + p_socket_free (skt_sender); + p_uthread_exit (-1); + } + + while (is_sender_working == TRUE && data->receiver_port == 0) { + p_uthread_sleep (1); + continue; + } + + PSocketAddress *addr_receiver = NULL; + + if (data->receiver_port != 0) + addr_receiver = p_socket_address_new ("127.0.0.1", data->receiver_port); + + while (is_sender_working == TRUE) { + if (data->receiver_port == 0) + break; + + if (p_socket_send_to (skt_sender, + addr_receiver, + socket_data, + sizeof (socket_data), + NULL) == sizeof (socket_data)) + ++send_counter; + + p_uthread_sleep (1); + } + + p_socket_address_free (addr_receiver); + p_socket_free (skt_sender); + p_uthread_exit (send_counter); + + return NULL; +} + +static void * udp_socket_receiver_thread (void *arg) +{ + pchar recv_buffer[sizeof (socket_data) * 3]; + pint recv_counter = 0; + + if (arg == NULL) + p_uthread_exit (-1); + + SocketTestData *data = (SocketTestData *) (arg); + + /* Create receiving socket */ + PSocket *skt_receiver = p_socket_new (P_SOCKET_FAMILY_INET, + P_SOCKET_TYPE_DATAGRAM, + P_SOCKET_PROTOCOL_UDP, + NULL); + + if (skt_receiver == NULL) + p_uthread_exit (-1); + + p_socket_set_blocking (skt_receiver, FALSE); + + PSocketAddress *addr_receiver = p_socket_address_new ("127.0.0.1", data->receiver_port); + + if (addr_receiver == NULL) { + p_socket_free (skt_receiver); + p_uthread_exit (-1); + } + + if (p_socket_bind (skt_receiver, addr_receiver, TRUE, NULL) == FALSE) { + p_socket_free (skt_receiver); + p_socket_address_free (addr_receiver); + p_uthread_exit (-1); + } else { + p_socket_address_free (addr_receiver); + + PSocketAddress *local_addr = p_socket_get_local_address (skt_receiver, NULL); + + if (local_addr == NULL) { + p_socket_free (skt_receiver); + p_uthread_exit (-1); + } + + data->receiver_port = p_socket_address_get_port (local_addr); + + p_socket_address_free (local_addr); + } + + p_socket_set_timeout (skt_receiver, 50); + + /* Test that remote address is NULL */ + PSocketAddress *remote_addr = p_socket_get_remote_address (skt_receiver, NULL); + + if (remote_addr != NULL) { + if (p_socket_address_is_any (remote_addr) == FALSE) { + p_socket_address_free (remote_addr); + p_socket_free (skt_receiver); + p_uthread_exit (-1); + } else { + p_socket_address_free (remote_addr); + remote_addr = NULL; + } + } + + /* Test that we are not connected */ + if (p_socket_is_connected (skt_receiver) == TRUE) { + p_socket_free (skt_receiver); + p_uthread_exit (-1); + } + + while (is_receiver_working == TRUE) { + PSocketAddress *remote_addr = NULL; + + pssize received = p_socket_receive_from (skt_receiver, + &remote_addr, + recv_buffer, + sizeof (recv_buffer), + NULL); + + if (remote_addr != NULL && test_socket_address_directly (remote_addr, data->sender_port) == FALSE) { + p_socket_address_free (remote_addr); + break; + } + + p_socket_address_free (remote_addr); + + if (received == sizeof (socket_data)) + ++recv_counter; + else if (received > 0) { + p_socket_free (skt_receiver); + p_uthread_exit (-1); + } + + p_uthread_sleep (1); + } + + p_socket_free (skt_receiver); + p_uthread_exit (recv_counter); + + return NULL; +} + +static void * tcp_socket_sender_thread (void *arg) +{ + pint send_counter = 0; + psize send_total; + pssize send_now; + pboolean is_connected = FALSE; + + if (arg == NULL) + p_uthread_exit (-1); + + SocketTestData *data = (SocketTestData *) (arg); + + /* Create sender socket */ + PSocket *skt_sender = p_socket_new (P_SOCKET_FAMILY_INET, + P_SOCKET_TYPE_STREAM, + P_SOCKET_PROTOCOL_DEFAULT, + NULL); + + if (skt_sender == NULL) + p_uthread_exit (-1); + + p_socket_set_timeout (skt_sender, 2000); + + if (p_socket_get_fd (skt_sender) < 0) { + p_socket_free (skt_sender); + p_uthread_exit (-1); + } + + while (is_sender_working == TRUE && data->receiver_port == 0) { + p_uthread_sleep (1); + continue; + } + + PSocketAddress *addr_sender = p_socket_address_new ("127.0.0.1", data->sender_port); + + if (addr_sender == NULL) { + p_socket_free (skt_sender); + p_uthread_exit (-1); + } + + if (p_socket_bind (skt_sender, addr_sender, FALSE, NULL) == FALSE) { + p_socket_free (skt_sender); + p_socket_address_free (addr_sender); + p_uthread_exit (-1); + } else { + p_socket_address_free (addr_sender); + + PSocketAddress *local_addr = p_socket_get_local_address (skt_sender, NULL); + + if (local_addr == NULL) { + p_socket_free (skt_sender); + p_uthread_exit (-1); + } + + data->sender_port = p_socket_address_get_port (local_addr); + + p_socket_address_free (local_addr); + } + + send_total = 0; + send_now = 0; + + while (is_sender_working == TRUE && data->receiver_port == 0) { + p_uthread_sleep (1); + continue; + } + + PSocketAddress *addr_receiver = NULL; + + /* Try to connect in non-blocking mode */ + p_socket_set_blocking (skt_sender, FALSE); + + if (data->receiver_port != 0) { + addr_receiver = p_socket_address_new ("127.0.0.1", data->receiver_port); + is_connected = p_socket_connect (skt_sender, addr_receiver, NULL); + + if (is_connected == FALSE) { + if (p_socket_io_condition_wait (skt_sender, P_SOCKET_IO_CONDITION_POLLOUT, NULL) == TRUE && + p_socket_check_connect_result (skt_sender, NULL) == FALSE) { + p_socket_address_free (addr_receiver); + p_socket_free (skt_sender); + p_uthread_exit (-1); + } + } + + is_connected = p_socket_is_connected (skt_sender); + + if (is_connected == TRUE && p_socket_shutdown (skt_sender, + FALSE, + data->shutdown_channel, + NULL) == FALSE) + is_connected = FALSE; + } + + if (data->shutdown_channel == TRUE && p_socket_is_closed (skt_sender) == TRUE) { + p_socket_address_free (addr_receiver); + p_socket_free (skt_sender); + p_uthread_exit (-1); + } + + p_socket_set_blocking (skt_sender, TRUE); + + while (is_sender_working == TRUE) { + if (data->receiver_port == 0 || is_connected == FALSE) + break; + + if (test_socket_address (skt_sender, data->receiver_port) == FALSE) + break; + + if (data->shutdown_channel == FALSE && p_socket_is_connected (skt_sender) == FALSE) { + p_socket_address_free (addr_receiver); + p_socket_free (skt_sender); + p_uthread_exit (-1); + } + + send_now = p_socket_send (skt_sender, + socket_data + send_total, + sizeof (socket_data) - send_total, + NULL); + + if (send_now > 0) + send_total += (psize) send_now; + + if (send_total == sizeof (socket_data)) { + send_total = 0; + ++send_counter; + } + + p_uthread_sleep (1); + } + + if (p_socket_close (skt_sender, NULL) == FALSE) + send_counter = -1; + + p_socket_address_free (addr_receiver); + p_socket_free (skt_sender); + p_uthread_exit (send_counter); + + return NULL; +} + +static void * tcp_socket_receiver_thread (void *arg) +{ + pchar recv_buffer[sizeof (socket_data)]; + pint recv_counter = 0; + psize recv_total; + pssize recv_now; + + if (arg == NULL) + p_uthread_exit (-1); + + SocketTestData *data = (SocketTestData *) (arg); + + /* Create receiving socket */ + PSocket *skt_receiver = p_socket_new (P_SOCKET_FAMILY_INET, + P_SOCKET_TYPE_STREAM, + P_SOCKET_PROTOCOL_TCP, + NULL); + + if (skt_receiver == NULL) + p_uthread_exit (-1); + + PSocketAddress *addr_receiver = p_socket_address_new ("127.0.0.1", data->receiver_port); + + if (addr_receiver == NULL) { + p_socket_free (skt_receiver); + p_uthread_exit (-1); + } + + p_socket_set_timeout (skt_receiver, 2000); + + if (p_socket_bind (skt_receiver, addr_receiver, TRUE, NULL) == FALSE || + p_socket_listen (skt_receiver, NULL) == FALSE) { + p_socket_free (skt_receiver); + p_socket_address_free (addr_receiver); + p_uthread_exit (-1); + } else { + p_socket_address_free (addr_receiver); + + PSocketAddress *local_addr = p_socket_get_local_address (skt_receiver, NULL); + + if (local_addr == NULL) { + p_socket_free (skt_receiver); + p_uthread_exit (-1); + } + + data->receiver_port = p_socket_address_get_port (local_addr); + + p_socket_address_free (local_addr); + } + + PSocket *conn_socket = NULL; + recv_total = 0; + recv_now = 0; + + while (is_receiver_working == TRUE) { + if (conn_socket == NULL) { + conn_socket = p_socket_accept (skt_receiver, NULL); + + if (conn_socket == NULL) { + p_uthread_sleep (1); + continue; + } else { + /* On Syllable there is a bug in TCP which changes a local port + * of the client socket which connects to a server */ +#ifndef P_OS_SYLLABLE + if (test_socket_address (conn_socket, data->sender_port) == FALSE) + break; +#endif + + if (p_socket_shutdown (conn_socket, data->shutdown_channel, FALSE, NULL) == FALSE) + break; + + p_socket_set_timeout (conn_socket, 2000); + } + } + + if ((data->shutdown_channel == FALSE && p_socket_is_connected (conn_socket) == FALSE) || + (data->shutdown_channel == TRUE && p_socket_is_closed (conn_socket) == TRUE)) { + p_socket_free (conn_socket); + p_socket_free (skt_receiver); + p_uthread_exit (-1); + } + + recv_now = p_socket_receive (conn_socket, + recv_buffer + recv_total, + sizeof (recv_buffer) - recv_total, + NULL); + + if (recv_now > 0) + recv_total += (psize) recv_now; + + if (recv_total == sizeof (recv_buffer)) { + recv_total = 0; + + if (strncmp (recv_buffer, socket_data, sizeof (recv_buffer)) == 0) + ++recv_counter; + + memset (recv_buffer, 0, sizeof (recv_buffer)); + } + + p_uthread_sleep (1); + } + + if (p_socket_close (skt_receiver, NULL) == FALSE) + recv_counter = -1; + + p_socket_free (conn_socket); + p_socket_free (skt_receiver); + + p_uthread_exit (recv_counter); + + return NULL; +} + +P_TEST_CASE_BEGIN (psocket_nomem_test) +{ + p_libsys_init (); + + PSocket *socket = p_socket_new (P_SOCKET_FAMILY_INET, + P_SOCKET_TYPE_DATAGRAM, + P_SOCKET_PROTOCOL_UDP, + NULL); + P_TEST_CHECK (socket != NULL); + + PSocketAddress *sock_addr = p_socket_address_new ("127.0.0.1", 32211); + + P_TEST_CHECK (sock_addr != NULL); + P_TEST_CHECK (p_socket_bind (socket, sock_addr, TRUE, NULL) == TRUE); + + p_socket_address_free (sock_addr); + + p_socket_set_timeout (socket, 1000); + sock_addr = p_socket_address_new ("127.0.0.1", 32215); + P_TEST_CHECK (sock_addr != NULL); + P_TEST_CHECK (p_socket_connect (socket, sock_addr, NULL) == TRUE); + + p_socket_address_free (sock_addr); + + PMemVTable vtable; + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + + P_TEST_CHECK (p_socket_new (P_SOCKET_FAMILY_INET, + P_SOCKET_TYPE_DATAGRAM, + P_SOCKET_PROTOCOL_UDP, + NULL) == NULL); + P_TEST_CHECK (p_socket_new_from_fd (p_socket_get_fd (socket), NULL) == NULL); + P_TEST_CHECK (p_socket_get_local_address (socket, NULL) == NULL); + P_TEST_CHECK (p_socket_get_remote_address (socket, NULL) == NULL); + + p_mem_restore_vtable (); + + p_socket_close (socket, NULL); + p_socket_free (socket); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (psocket_bad_input_test) +{ + p_libsys_init (); + + PError *error = NULL; + + P_TEST_CHECK (p_socket_new_from_fd (-1, &error) == NULL); + P_TEST_CHECK (error != NULL); + clean_error (&error); + + P_TEST_CHECK (p_socket_new (P_SOCKET_FAMILY_INET, + (PSocketType) -1, + P_SOCKET_PROTOCOL_TCP, + NULL) == NULL); + /* Syllable doesn't validate socket family */ +#ifndef P_OS_SYLLABLE + P_TEST_CHECK (p_socket_new ((PSocketFamily) -1, + P_SOCKET_TYPE_SEQPACKET, + P_SOCKET_PROTOCOL_TCP, + NULL) == NULL); +#endif + P_TEST_CHECK (p_socket_new (P_SOCKET_FAMILY_UNKNOWN, + P_SOCKET_TYPE_UNKNOWN, + P_SOCKET_PROTOCOL_UNKNOWN, + &error) == NULL); + P_TEST_CHECK (p_socket_new_from_fd (1, NULL) == NULL); + P_TEST_CHECK (error != NULL); + clean_error (&error); + + P_TEST_CHECK (p_socket_get_fd (NULL) == -1); + P_TEST_CHECK (p_socket_get_family (NULL) == P_SOCKET_FAMILY_UNKNOWN); + P_TEST_CHECK (p_socket_get_type (NULL) == P_SOCKET_TYPE_UNKNOWN); + P_TEST_CHECK (p_socket_get_protocol (NULL) == P_SOCKET_PROTOCOL_UNKNOWN); + P_TEST_CHECK (p_socket_get_keepalive (NULL) == FALSE); + P_TEST_CHECK (p_socket_get_blocking (NULL) == FALSE); + P_TEST_CHECK (p_socket_get_timeout (NULL) == -1); + P_TEST_CHECK (p_socket_get_listen_backlog (NULL) == -1); + P_TEST_CHECK (p_socket_io_condition_wait (NULL, P_SOCKET_IO_CONDITION_POLLIN, NULL) == FALSE); + P_TEST_CHECK (p_socket_io_condition_wait (NULL, P_SOCKET_IO_CONDITION_POLLOUT, NULL) == FALSE); + + P_TEST_CHECK (p_socket_get_local_address (NULL, &error) == NULL); + P_TEST_CHECK (error != NULL); + clean_error (&error); + + P_TEST_CHECK (p_socket_get_remote_address (NULL, &error) == NULL); + P_TEST_CHECK (error != NULL); + clean_error (&error); + + P_TEST_CHECK (p_socket_is_connected (NULL) == FALSE); + P_TEST_CHECK (p_socket_is_closed (NULL) == TRUE); + + P_TEST_CHECK (p_socket_check_connect_result (NULL, &error) == FALSE); + P_TEST_CHECK (error != NULL); + clean_error (&error); + + p_socket_set_keepalive (NULL, FALSE); + p_socket_set_blocking (NULL, FALSE); + p_socket_set_timeout (NULL, 0); + p_socket_set_listen_backlog (NULL, 0); + + P_TEST_CHECK (p_socket_bind (NULL, NULL, FALSE, &error) == FALSE); + P_TEST_CHECK (error != NULL); + clean_error (&error); + + P_TEST_CHECK (p_socket_connect (NULL, NULL, &error) == FALSE); + P_TEST_CHECK (error != NULL); + clean_error (&error); + + P_TEST_CHECK (p_socket_listen (NULL, &error) == FALSE); + P_TEST_CHECK (error != NULL); + clean_error (&error); + + P_TEST_CHECK (p_socket_accept (NULL, &error) == NULL); + P_TEST_CHECK (error != NULL); + clean_error (&error); + + P_TEST_CHECK (p_socket_receive (NULL, NULL, 0, &error) == -1); + P_TEST_CHECK (error != NULL); + clean_error (&error); + + P_TEST_CHECK (p_socket_receive_from (NULL, NULL, NULL, 0, &error) == -1); + P_TEST_CHECK (error != NULL); + clean_error (&error); + + P_TEST_CHECK (p_socket_send (NULL, NULL, 0, &error) == -1); + P_TEST_CHECK (error != NULL); + clean_error (&error); + + P_TEST_CHECK (p_socket_send_to (NULL, NULL, NULL, 0, &error) == -1); + P_TEST_CHECK (error != NULL); + clean_error (&error); + + P_TEST_CHECK (p_socket_close (NULL, &error) == FALSE); + P_TEST_CHECK (error != NULL); + clean_error (&error); + + P_TEST_CHECK (p_socket_shutdown (NULL, FALSE, FALSE, &error) == FALSE); + P_TEST_CHECK (error != NULL); + clean_error (&error); + + P_TEST_CHECK (p_socket_set_buffer_size (NULL, P_SOCKET_DIRECTION_RCV, 0, &error) == FALSE); + P_TEST_CHECK (error != NULL); + clean_error (&error); + + P_TEST_CHECK (p_socket_set_buffer_size (NULL, P_SOCKET_DIRECTION_SND, 0, &error) == FALSE); + P_TEST_CHECK (error != NULL); + clean_error (&error); + + p_socket_free (NULL); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (psocket_general_udp_test) +{ + p_libsys_init (); + + /* Test UDP socket */ + PSocket *socket = p_socket_new (P_SOCKET_FAMILY_INET, + P_SOCKET_TYPE_DATAGRAM, + P_SOCKET_PROTOCOL_UDP, + NULL); + + P_TEST_CHECK (socket != NULL); + P_TEST_CHECK (p_socket_get_family (socket) == P_SOCKET_FAMILY_INET); + P_TEST_CHECK (p_socket_get_fd (socket) >= 0); + P_TEST_CHECK (p_socket_get_listen_backlog (socket) == 5); + P_TEST_CHECK (p_socket_get_timeout (socket) == 0); + + /* On some operating systems (i.e. OpenVMS) remote address is not NULL */ + PSocketAddress *remote_addr = p_socket_get_remote_address (socket, NULL); + + if (remote_addr != NULL) { + P_TEST_CHECK (p_socket_address_is_any (remote_addr) == TRUE); + p_socket_address_free (remote_addr); + remote_addr = NULL; + } + + P_TEST_CHECK (p_socket_get_protocol (socket) == P_SOCKET_PROTOCOL_UDP); + P_TEST_CHECK (p_socket_get_blocking (socket) == TRUE); + P_TEST_CHECK (p_socket_get_type (socket) == P_SOCKET_TYPE_DATAGRAM); + P_TEST_CHECK (p_socket_get_keepalive (socket) == FALSE); + P_TEST_CHECK (p_socket_is_closed (socket) == FALSE); + + p_socket_set_listen_backlog (socket, 12); + p_socket_set_timeout (socket, -10); + P_TEST_CHECK (p_socket_get_timeout (socket) == 0); + p_socket_set_timeout (socket, 10); + + P_TEST_CHECK (p_socket_get_listen_backlog (socket) == 12); + P_TEST_CHECK (p_socket_get_timeout (socket) == 10); + + PSocketAddress *sock_addr = p_socket_address_new ("127.0.0.1", 32111); + P_TEST_CHECK (sock_addr != NULL); + + P_TEST_CHECK (p_socket_bind (socket, sock_addr, TRUE, NULL) == TRUE); + + /* Test creating socket from descriptor */ + PSocket *fd_socket = p_socket_new_from_fd (p_socket_get_fd (socket), NULL); + P_TEST_CHECK (fd_socket != NULL); + P_TEST_CHECK (p_socket_get_family (fd_socket) == P_SOCKET_FAMILY_INET); + P_TEST_CHECK (p_socket_get_fd (fd_socket) >= 0); + P_TEST_CHECK (p_socket_get_listen_backlog (fd_socket) == 5); + P_TEST_CHECK (p_socket_get_timeout (fd_socket) == 0); + + remote_addr = p_socket_get_remote_address (fd_socket, NULL); + + if (remote_addr != NULL) { + P_TEST_CHECK (p_socket_address_is_any (remote_addr) == TRUE); + p_socket_address_free (remote_addr); + remote_addr = NULL; + } + + P_TEST_CHECK (p_socket_get_protocol (fd_socket) == P_SOCKET_PROTOCOL_UDP); + P_TEST_CHECK (p_socket_get_blocking (fd_socket) == TRUE); + P_TEST_CHECK (p_socket_get_type (fd_socket) == P_SOCKET_TYPE_DATAGRAM); + P_TEST_CHECK (p_socket_get_keepalive (fd_socket) == FALSE); + P_TEST_CHECK (p_socket_is_closed (fd_socket) == FALSE); + + p_socket_set_keepalive (fd_socket, FALSE); + P_TEST_CHECK (p_socket_get_keepalive (fd_socket) == FALSE); + + p_socket_set_keepalive (fd_socket, TRUE); + p_socket_set_keepalive (fd_socket, FALSE); + P_TEST_CHECK (p_socket_get_keepalive (fd_socket) == FALSE); + + /* Test UDP local address */ + PSocketAddress *addr = p_socket_get_local_address (socket, NULL); + P_TEST_CHECK (addr != NULL); + + P_TEST_CHECK (compare_socket_addresses (sock_addr, addr) == TRUE); + + p_socket_address_free (sock_addr); + p_socket_address_free (addr); + + /* Test UDP connecting to remote address */ + p_socket_set_timeout (socket, 1000); + addr = p_socket_address_new ("127.0.0.1", 32115); + P_TEST_CHECK (addr != NULL); + P_TEST_CHECK (p_socket_connect (socket, addr, NULL) == TRUE); + + P_TEST_CHECK (p_socket_io_condition_wait (socket, P_SOCKET_IO_CONDITION_POLLIN, NULL) == FALSE); + P_TEST_CHECK (p_socket_io_condition_wait (socket, P_SOCKET_IO_CONDITION_POLLOUT, NULL) == TRUE); + + sock_addr = p_socket_get_remote_address (socket, NULL); + + /* Syllable doesn't support getpeername() for UDP sockets */ +#ifdef P_OS_SYLLABLE + P_TEST_CHECK (sock_addr == NULL); + sock_addr = p_socket_address_new ("127.0.0.1", 32115); + P_TEST_CHECK (addr != NULL); +#else + P_TEST_CHECK (sock_addr != NULL); + P_TEST_CHECK (compare_socket_addresses (sock_addr, addr) == TRUE); +#endif + + /* Not supported on Syllable */ +#ifndef P_OS_SYLLABLE + P_TEST_CHECK (p_socket_set_buffer_size (socket, P_SOCKET_DIRECTION_RCV, 72 * 1024, NULL) == TRUE); + P_TEST_CHECK (p_socket_set_buffer_size (socket, P_SOCKET_DIRECTION_SND, 72 * 1024, NULL) == TRUE); + P_TEST_CHECK (p_socket_check_connect_result (socket, NULL) == TRUE); +#endif + + P_TEST_CHECK (p_socket_is_connected (socket) == TRUE); + P_TEST_CHECK (p_socket_close (socket, NULL) == TRUE); + + pchar sock_buf[10]; + + P_TEST_CHECK (p_socket_bind (socket, sock_addr, TRUE, NULL) == FALSE); + P_TEST_CHECK (p_socket_connect (socket, addr, NULL) == FALSE); + P_TEST_CHECK (p_socket_listen (socket, NULL) == FALSE); + P_TEST_CHECK (p_socket_accept (socket, NULL) == FALSE); + P_TEST_CHECK (p_socket_receive (socket, sock_buf, sizeof (sock_buf), NULL) == -1); + P_TEST_CHECK (p_socket_receive_from (socket, NULL, sock_buf, sizeof (sock_buf), NULL) == -1); + P_TEST_CHECK (p_socket_send (socket, sock_buf, sizeof (sock_buf), NULL) == -1); + P_TEST_CHECK (p_socket_send_to (socket, addr, sock_buf, sizeof (sock_buf), NULL) == -1); + P_TEST_CHECK (p_socket_shutdown (socket, TRUE, TRUE, NULL) == FALSE); + P_TEST_CHECK (p_socket_get_local_address (socket, NULL) == NULL); + P_TEST_CHECK (p_socket_check_connect_result (socket, NULL) == FALSE); + P_TEST_CHECK (p_socket_get_fd (socket) == -1); + P_TEST_CHECK (p_socket_is_connected (socket) == FALSE); + P_TEST_CHECK (p_socket_is_closed (socket) == TRUE); + + p_socket_set_keepalive (socket, TRUE); + P_TEST_CHECK (p_socket_get_keepalive (socket) == FALSE); + + P_TEST_CHECK (p_socket_io_condition_wait (socket, P_SOCKET_IO_CONDITION_POLLIN, NULL) == FALSE); + P_TEST_CHECK (p_socket_io_condition_wait (socket, P_SOCKET_IO_CONDITION_POLLOUT, NULL) == FALSE); + + P_TEST_CHECK (p_socket_set_buffer_size (socket, P_SOCKET_DIRECTION_RCV, 72 * 1024, NULL) == FALSE); + P_TEST_CHECK (p_socket_set_buffer_size (socket, P_SOCKET_DIRECTION_SND, 72 * 1024, NULL) == FALSE); + + p_socket_address_free (sock_addr); + p_socket_address_free (addr); + p_socket_free (socket); + p_socket_free (fd_socket); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (psocket_general_tcp_test) +{ + p_libsys_init (); + + /* Test TCP socket */ + PSocket *socket = p_socket_new (P_SOCKET_FAMILY_INET, + P_SOCKET_TYPE_STREAM, + P_SOCKET_PROTOCOL_TCP, + NULL); + p_socket_set_blocking (socket, FALSE); + p_socket_set_listen_backlog (socket, 11); + + p_socket_set_timeout (socket, -12); + P_TEST_CHECK (p_socket_get_timeout (socket) == 0); + p_socket_set_timeout (socket, 12); + + P_TEST_CHECK (socket != NULL); + P_TEST_CHECK (p_socket_get_family (socket) == P_SOCKET_FAMILY_INET); + P_TEST_CHECK (p_socket_get_fd (socket) >= 0); + P_TEST_CHECK (p_socket_get_listen_backlog (socket) == 11); + P_TEST_CHECK (p_socket_get_timeout (socket) == 12); + P_TEST_CHECK (p_socket_get_remote_address (socket, NULL) == NULL); + P_TEST_CHECK (p_socket_get_protocol (socket) == P_SOCKET_PROTOCOL_TCP); + P_TEST_CHECK (p_socket_get_blocking (socket) == FALSE); + P_TEST_CHECK (p_socket_get_type (socket) == P_SOCKET_TYPE_STREAM); + P_TEST_CHECK (p_socket_get_keepalive (socket) == FALSE); + P_TEST_CHECK (p_socket_is_closed (socket) == FALSE); + + p_socket_set_keepalive (socket, FALSE); + P_TEST_CHECK (p_socket_get_keepalive (socket) == FALSE); + + p_socket_set_keepalive (socket, TRUE); + p_socket_set_keepalive (socket, FALSE); + P_TEST_CHECK (p_socket_get_keepalive (socket) == FALSE); + + PSocketAddress *sock_addr = p_socket_address_new ("127.0.0.1", 0); + P_TEST_CHECK (sock_addr != NULL); + + P_TEST_CHECK (p_socket_bind (socket, sock_addr, TRUE, NULL) == TRUE); + + PSocketAddress *addr = p_socket_get_local_address (socket, NULL); + P_TEST_CHECK (addr != NULL); + + P_TEST_CHECK (compare_socket_addresses (sock_addr, addr) == TRUE); + + P_TEST_CHECK (p_socket_set_buffer_size (socket, P_SOCKET_DIRECTION_RCV, 72 * 1024, NULL) == TRUE); + P_TEST_CHECK (p_socket_set_buffer_size (socket, P_SOCKET_DIRECTION_SND, 72 * 1024, NULL) == TRUE); + + /* In case of success p_socket_check_connect_result() marks socket as connected */ + P_TEST_CHECK (p_socket_is_connected (socket) == FALSE); + P_TEST_CHECK (p_socket_check_connect_result (socket, NULL) == TRUE); + P_TEST_CHECK (p_socket_close (socket, NULL) == TRUE); + + pchar sock_buf[10]; + + P_TEST_CHECK (p_socket_bind (socket, sock_addr, TRUE, NULL) == FALSE); + P_TEST_CHECK (p_socket_connect (socket, addr, NULL) == FALSE); + P_TEST_CHECK (p_socket_listen (socket, NULL) == FALSE); + P_TEST_CHECK (p_socket_accept (socket, NULL) == FALSE); + P_TEST_CHECK (p_socket_receive (socket, sock_buf, sizeof (sock_buf), NULL) == -1); + P_TEST_CHECK (p_socket_receive_from (socket, NULL, sock_buf, sizeof (sock_buf), NULL) == -1); + P_TEST_CHECK (p_socket_send (socket, sock_buf, sizeof (sock_buf), NULL) == -1); + P_TEST_CHECK (p_socket_send_to (socket, addr, sock_buf, sizeof (sock_buf), NULL) == -1); + P_TEST_CHECK (p_socket_shutdown (socket, TRUE, TRUE, NULL) == FALSE); + P_TEST_CHECK (p_socket_get_local_address (socket, NULL) == NULL); + P_TEST_CHECK (p_socket_check_connect_result (socket, NULL) == FALSE); + P_TEST_CHECK (p_socket_is_closed (socket) == TRUE); + P_TEST_CHECK (p_socket_get_fd (socket) == -1); + + p_socket_set_keepalive (socket, TRUE); + P_TEST_CHECK (p_socket_get_keepalive (socket) == FALSE); + + P_TEST_CHECK (p_socket_io_condition_wait (socket, P_SOCKET_IO_CONDITION_POLLIN, NULL) == FALSE); + P_TEST_CHECK (p_socket_io_condition_wait (socket, P_SOCKET_IO_CONDITION_POLLOUT, NULL) == FALSE); + + P_TEST_CHECK (p_socket_set_buffer_size (socket, P_SOCKET_DIRECTION_RCV, 72 * 1024, NULL) == FALSE); + P_TEST_CHECK (p_socket_set_buffer_size (socket, P_SOCKET_DIRECTION_SND, 72 * 1024, NULL) == FALSE); + + p_socket_address_free (sock_addr); + p_socket_address_free (addr); + + p_socket_free (socket); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (psocket_udp_test) +{ + p_libsys_init (); + + is_sender_working = TRUE; + is_receiver_working = TRUE; + + SocketTestData data; + data.receiver_port = 0; + data.sender_port = 0; + data.shutdown_channel = FALSE; + + PUThread *receiver_thr = p_uthread_create ((PUThreadFunc) udp_socket_receiver_thread, + (ppointer) &data, + TRUE, + NULL); + + PUThread *sender_thr = p_uthread_create ((PUThreadFunc) udp_socket_sender_thread, + (ppointer) &data, + TRUE, + NULL); + + P_TEST_CHECK (sender_thr != NULL); + P_TEST_CHECK (receiver_thr != NULL); + + p_uthread_sleep (8000); + + is_sender_working = FALSE; + pint send_counter = p_uthread_join (sender_thr); + + p_uthread_sleep (2000); + + is_receiver_working = FALSE; + pint recv_counter = p_uthread_join (receiver_thr); + + P_TEST_CHECK (send_counter > 0); + P_TEST_CHECK (recv_counter > 0); + + p_uthread_unref (sender_thr); + p_uthread_unref (receiver_thr); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (psocket_tcp_test) +{ + p_libsys_init (); + + is_sender_working = TRUE; + is_receiver_working = TRUE; + + SocketTestData data; + data.receiver_port = 0; + data.sender_port = 0; + data.shutdown_channel = FALSE; + + PUThread *receiver_thr = p_uthread_create ((PUThreadFunc) tcp_socket_receiver_thread, + (ppointer) &data, + TRUE, + NULL); + + PUThread *sender_thr = p_uthread_create ((PUThreadFunc) tcp_socket_sender_thread, + (ppointer) &data, + TRUE, + NULL); + + P_TEST_CHECK (receiver_thr != NULL); + P_TEST_CHECK (sender_thr != NULL); + + p_uthread_sleep (8000); + + is_sender_working = FALSE; + pint send_counter = p_uthread_join (sender_thr); + + p_uthread_sleep (2000); + + is_receiver_working = FALSE; + pint recv_counter = p_uthread_join (receiver_thr); + + P_TEST_CHECK (send_counter > 0); + P_TEST_CHECK (recv_counter > 0); + + p_uthread_unref (sender_thr); + p_uthread_unref (receiver_thr); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (psocket_shutdown_test) +{ + p_libsys_init (); + + is_sender_working = TRUE; + is_receiver_working = TRUE; + + SocketTestData data; + data.receiver_port = 0; + data.sender_port = 0; + data.shutdown_channel = TRUE; + + PUThread *receiver_thr = p_uthread_create ((PUThreadFunc) tcp_socket_receiver_thread, + (ppointer) &data, + TRUE, + NULL); + + PUThread *sender_thr = p_uthread_create ((PUThreadFunc) tcp_socket_sender_thread, + (ppointer) &data, + TRUE, + NULL); + + P_TEST_CHECK (receiver_thr != NULL); + P_TEST_CHECK (sender_thr != NULL); + + p_uthread_sleep (8000); + + is_sender_working = FALSE; + pint send_counter = p_uthread_join (sender_thr); + + p_uthread_sleep (2000); + + is_receiver_working = FALSE; + pint recv_counter = p_uthread_join (receiver_thr); + + P_TEST_CHECK (send_counter == 0); + P_TEST_CHECK (recv_counter == 0); + + p_uthread_unref (sender_thr); + p_uthread_unref (receiver_thr); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (psocket_nomem_test); + P_TEST_SUITE_RUN_CASE (psocket_bad_input_test); + P_TEST_SUITE_RUN_CASE (psocket_general_udp_test); + P_TEST_SUITE_RUN_CASE (psocket_general_tcp_test); + P_TEST_SUITE_RUN_CASE (psocket_udp_test); + P_TEST_SUITE_RUN_CASE (psocket_tcp_test); + P_TEST_SUITE_RUN_CASE (psocket_shutdown_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/psocketaddress_test.cpp b/3rdparty/plibsys/tests/psocketaddress_test.cpp new file mode 100644 index 0000000..2085725 --- /dev/null +++ b/3rdparty/plibsys/tests/psocketaddress_test.cpp @@ -0,0 +1,338 @@ +/* + * The MIT License + * + * Copyright (C) 2013-2017 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +#include + +P_TEST_MODULE_INIT (); + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + P_UNUSED (block); + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" void pmem_free (ppointer block) +{ + P_UNUSED (block); +} + +P_TEST_CASE_BEGIN (psocketaddress_nomem_test) +{ + p_libsys_init (); + + PSocketAddress *sock_addr = p_socket_address_new ("192.168.0.1", 1058); + P_TEST_CHECK (sock_addr != NULL); + + psize native_size = p_socket_address_get_native_size (sock_addr); + P_TEST_CHECK (native_size > 0); + + ppointer addr_buf = p_malloc0 (native_size); + P_TEST_CHECK (addr_buf != NULL); + + P_TEST_CHECK (p_socket_address_to_native (sock_addr, addr_buf, native_size - 1) == FALSE); + P_TEST_CHECK (p_socket_address_to_native (sock_addr, addr_buf, native_size) == TRUE); + p_socket_address_free (sock_addr); + + PSocketAddress *sock_addr6; + psize native_size6; + ppointer addr_buf6; + + if (p_socket_address_is_ipv6_supported ()) { + sock_addr6 = p_socket_address_new ("2001:cdba:345f:24ab:fe45:5423:3257:9652", 1058); + P_TEST_CHECK (sock_addr6 != NULL); + + native_size6 = p_socket_address_get_native_size (sock_addr6); + P_TEST_CHECK (native_size6 > 0); + + addr_buf6 = p_malloc0 (native_size6); + P_TEST_CHECK (addr_buf6 != NULL); + + P_TEST_CHECK (p_socket_address_to_native (sock_addr6, addr_buf6, native_size6 - 1) == FALSE); + P_TEST_CHECK (p_socket_address_to_native (sock_addr6, addr_buf6, native_size6) == TRUE); + p_socket_address_free (sock_addr6); + } + + PMemVTable vtable; + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + + P_TEST_CHECK (p_socket_address_new ("192.168.0.1", 1058) == NULL); + P_TEST_CHECK (p_socket_address_new_any (P_SOCKET_FAMILY_INET, 1058) == NULL); + P_TEST_CHECK (p_socket_address_new_loopback (P_SOCKET_FAMILY_INET, 1058) == NULL); + P_TEST_CHECK (p_socket_address_new_from_native (addr_buf, native_size) == NULL); + + if (p_socket_address_is_ipv6_supported ()) + P_TEST_CHECK (p_socket_address_new_from_native (addr_buf6, native_size6) == NULL); + + p_mem_restore_vtable (); + + P_TEST_CHECK (p_socket_address_new_from_native (addr_buf, native_size - 1) == NULL); + + if (p_socket_address_is_ipv6_supported ()) { + P_TEST_CHECK (p_socket_address_new_from_native (addr_buf6, native_size6 - 1) == NULL); + p_free (addr_buf6); + } + + p_free (addr_buf); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (psocketaddress_bad_input_test) +{ + p_libsys_init (); + + P_TEST_CHECK (p_socket_address_new_from_native (NULL, 0) == NULL); + P_TEST_CHECK (p_socket_address_new (NULL, 0) == NULL); + P_TEST_CHECK (p_socket_address_new ("bad_address", 0) == NULL); + P_TEST_CHECK (p_socket_address_new_any (P_SOCKET_FAMILY_UNKNOWN, 0) == NULL); + P_TEST_CHECK (p_socket_address_new_loopback (P_SOCKET_FAMILY_UNKNOWN, 0) == NULL); + P_TEST_CHECK (p_socket_address_to_native (NULL, NULL, 0) == FALSE); + P_TEST_CHECK (p_socket_address_get_native_size (NULL) == 0); + P_TEST_CHECK (p_socket_address_get_family (NULL) == P_SOCKET_FAMILY_UNKNOWN); + P_TEST_CHECK (p_socket_address_get_address (NULL) == NULL); + P_TEST_CHECK (p_socket_address_get_port (NULL) == 0); + P_TEST_CHECK (p_socket_address_get_flow_info (NULL) == 0); + P_TEST_CHECK (p_socket_address_get_scope_id (NULL) == 0); + P_TEST_CHECK (p_socket_address_is_any (NULL) == FALSE); + P_TEST_CHECK (p_socket_address_is_loopback (NULL) == FALSE); + + p_socket_address_set_flow_info (NULL, 0); + p_socket_address_set_scope_id (NULL, 0); + p_socket_address_free (NULL); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (psocketaddress_general_test) +{ + p_libsys_init (); + + /* Test IPv4 LAN address */ + PSocketAddress *addr = p_socket_address_new ("192.168.0.1", 2345); + + P_TEST_REQUIRE (addr != NULL); + P_TEST_CHECK (p_socket_address_is_loopback (addr) == FALSE); + P_TEST_CHECK (p_socket_address_is_any (addr) == FALSE); + P_TEST_CHECK (p_socket_address_get_family (addr) == P_SOCKET_FAMILY_INET); + P_TEST_CHECK (p_socket_address_get_port (addr) == 2345); + P_TEST_CHECK (p_socket_address_get_native_size (addr) > 0); + P_TEST_CHECK (p_socket_address_get_flow_info (addr) == 0); + P_TEST_CHECK (p_socket_address_get_scope_id (addr) == 0); + + pchar *addr_str = p_socket_address_get_address (addr); + + P_TEST_REQUIRE (addr_str != NULL); + P_TEST_CHECK (strcmp (addr_str, "192.168.0.1") == 0); + + p_free (addr_str); + p_socket_address_free (addr); + + if (p_socket_address_is_ipv6_supported ()) { + /* Test IPv6 LAN address */ + addr = p_socket_address_new ("2001:cdba:345f:24ab:fe45:5423:3257:9652", 2345); + + P_TEST_REQUIRE (addr != NULL); + P_TEST_CHECK (p_socket_address_is_loopback (addr) == FALSE); + P_TEST_CHECK (p_socket_address_is_any (addr) == FALSE); + P_TEST_CHECK (p_socket_address_get_family (addr) == P_SOCKET_FAMILY_INET6); + P_TEST_CHECK (p_socket_address_get_port (addr) == 2345); + P_TEST_CHECK (p_socket_address_get_native_size (addr) > 0); + P_TEST_CHECK (p_socket_address_get_flow_info (addr) == 0); + P_TEST_CHECK (p_socket_address_get_scope_id (addr) == 0); + + addr_str = p_socket_address_get_address (addr); + + P_TEST_REQUIRE (addr_str != NULL); + P_TEST_CHECK (strcmp (addr_str, "2001:cdba:345f:24ab:fe45:5423:3257:9652") == 0); + + p_free (addr_str); + p_socket_address_free (addr); + } + + /* Test IPv4 loopback address */ + addr = p_socket_address_new_loopback (P_SOCKET_FAMILY_INET, 2345); + + P_TEST_REQUIRE (addr != NULL); + P_TEST_CHECK (p_socket_address_is_loopback (addr) == TRUE); + P_TEST_CHECK (p_socket_address_is_any (addr) == FALSE); + P_TEST_CHECK (p_socket_address_get_family (addr) == P_SOCKET_FAMILY_INET); + P_TEST_CHECK (p_socket_address_get_port (addr) == 2345); + P_TEST_CHECK (p_socket_address_get_native_size (addr) > 0); + P_TEST_CHECK (p_socket_address_get_flow_info (addr) == 0); + P_TEST_CHECK (p_socket_address_get_scope_id (addr) == 0); + + p_socket_address_free (addr); + + if (p_socket_address_is_ipv6_supported ()) { + /* Test IPv6 loopback address */ + addr = p_socket_address_new_loopback (P_SOCKET_FAMILY_INET6, 2345); + + P_TEST_REQUIRE (addr != NULL); + P_TEST_CHECK (p_socket_address_is_loopback (addr) == TRUE); + P_TEST_CHECK (p_socket_address_is_any (addr) == FALSE); + P_TEST_CHECK (p_socket_address_get_family (addr) == P_SOCKET_FAMILY_INET6); + P_TEST_CHECK (p_socket_address_get_port (addr) == 2345); + P_TEST_CHECK (p_socket_address_get_native_size (addr) > 0); + P_TEST_CHECK (p_socket_address_get_flow_info (addr) == 0); + P_TEST_CHECK (p_socket_address_get_scope_id (addr) == 0); + + p_socket_address_free (addr); + } + + /* Test IPv4 any interface */ + addr = p_socket_address_new_any (P_SOCKET_FAMILY_INET, 2345); + + P_TEST_REQUIRE (addr != NULL); + P_TEST_CHECK (p_socket_address_is_loopback (addr) == FALSE); + P_TEST_CHECK (p_socket_address_is_any (addr) == TRUE); + P_TEST_CHECK (p_socket_address_get_family (addr) == P_SOCKET_FAMILY_INET); + P_TEST_CHECK (p_socket_address_get_port (addr) == 2345); + P_TEST_CHECK (p_socket_address_get_native_size (addr) > 0); + P_TEST_CHECK (p_socket_address_get_flow_info (addr) == 0); + P_TEST_CHECK (p_socket_address_get_scope_id (addr) == 0); + + psize native_size = p_socket_address_get_native_size (addr); + + p_socket_address_free (addr); + + /* Test IPv4 native raw data */ + ppointer native_buf = p_malloc0 (native_size); + P_TEST_CHECK (native_buf != NULL); + P_TEST_CHECK (p_socket_address_new_from_native (native_buf, native_size) == NULL); + addr = p_socket_address_new ("192.168.0.2", 2345); + P_TEST_REQUIRE (addr != NULL); + + p_socket_address_set_flow_info (addr, 1); + p_socket_address_set_scope_id (addr, 1); + + P_TEST_CHECK (p_socket_address_to_native (addr, native_buf, native_size) == TRUE); + p_socket_address_free (addr); + + addr = p_socket_address_new_from_native (native_buf, native_size); + + P_TEST_CHECK (addr != NULL); + P_TEST_CHECK (p_socket_address_is_loopback (addr) == FALSE); + P_TEST_CHECK (p_socket_address_is_any (addr) == FALSE); + P_TEST_CHECK (p_socket_address_get_family (addr) == P_SOCKET_FAMILY_INET); + P_TEST_CHECK (p_socket_address_get_port (addr) == 2345); + P_TEST_CHECK (p_socket_address_get_native_size (addr) == native_size); + P_TEST_CHECK (p_socket_address_get_flow_info (addr) == 0); + P_TEST_CHECK (p_socket_address_get_scope_id (addr) == 0); + + addr_str = p_socket_address_get_address (addr); + + P_TEST_REQUIRE (addr_str != NULL); + P_TEST_CHECK (strcmp (addr_str, "192.168.0.2") == 0); + + p_free (native_buf); + p_free (addr_str); + p_socket_address_free (addr); + + if (p_socket_address_is_ipv6_supported ()) { + /* Test IPv6 any interface */ + addr = p_socket_address_new_any (P_SOCKET_FAMILY_INET6, 2345); + + P_TEST_REQUIRE (addr != NULL); + P_TEST_CHECK (p_socket_address_is_loopback (addr) == FALSE); + P_TEST_CHECK (p_socket_address_is_any (addr) == TRUE); + P_TEST_CHECK (p_socket_address_get_family (addr) == P_SOCKET_FAMILY_INET6); + P_TEST_CHECK (p_socket_address_get_port (addr) == 2345); + P_TEST_CHECK (p_socket_address_get_native_size (addr) > 0); + P_TEST_CHECK (p_socket_address_get_flow_info (addr) == 0); + P_TEST_CHECK (p_socket_address_get_scope_id (addr) == 0); + + native_size = p_socket_address_get_native_size (addr); + + p_socket_address_free (addr); + + /* Test IPv6 native raw data */ + native_buf = p_malloc0 (native_size); + P_TEST_CHECK (native_buf != NULL); + P_TEST_CHECK (p_socket_address_new_from_native (native_buf, native_size) == NULL); + addr = p_socket_address_new ("2001:cdba:345f:24ab:fe45:5423:3257:9652", 2345); + P_TEST_REQUIRE (addr != NULL); + + p_socket_address_set_flow_info (addr, 1); + p_socket_address_set_scope_id (addr, 1); + + P_TEST_CHECK (p_socket_address_to_native (addr, native_buf, native_size) == TRUE); + p_socket_address_free (addr); + + addr = p_socket_address_new_from_native (native_buf, native_size); + + P_TEST_CHECK (addr != NULL); + P_TEST_CHECK (p_socket_address_is_loopback (addr) == FALSE); + P_TEST_CHECK (p_socket_address_is_any (addr) == FALSE); + P_TEST_CHECK (p_socket_address_get_family (addr) == P_SOCKET_FAMILY_INET6); + P_TEST_CHECK (p_socket_address_get_port (addr) == 2345); + P_TEST_CHECK (p_socket_address_get_native_size (addr) == native_size); + + if (p_socket_address_is_flow_info_supported ()) + P_TEST_CHECK (p_socket_address_get_flow_info (addr) == 1); + + if (p_socket_address_is_scope_id_supported ()) + P_TEST_CHECK (p_socket_address_get_scope_id (addr) == 1); + + addr_str = p_socket_address_get_address (addr); + + P_TEST_REQUIRE (addr_str != NULL); + P_TEST_CHECK (strcmp (addr_str, "2001:cdba:345f:24ab:fe45:5423:3257:9652") == 0); + + p_free (native_buf); + p_free (addr_str); + p_socket_address_free (addr); + } + + if (p_socket_address_is_flow_info_supported () || p_socket_address_is_scope_id_supported ()) + P_TEST_CHECK (p_socket_address_is_ipv6_supported () == TRUE); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (psocketaddress_nomem_test); + P_TEST_SUITE_RUN_CASE (psocketaddress_bad_input_test); + P_TEST_SUITE_RUN_CASE (psocketaddress_general_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/pspinlock_test.cpp b/3rdparty/plibsys/tests/pspinlock_test.cpp new file mode 100644 index 0000000..1f23dab --- /dev/null +++ b/3rdparty/plibsys/tests/pspinlock_test.cpp @@ -0,0 +1,148 @@ +/* + * The MIT License + * + * Copyright (C) 2016-2019 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +P_TEST_MODULE_INIT (); + +#define PSPINLOCK_MAX_VAL 10 + +static pint spinlock_test_val = 0; +static PSpinLock * global_spinlock = NULL; + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + P_UNUSED (block); + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" void pmem_free (ppointer block) +{ + P_UNUSED (block); +} + +static void * spinlock_test_thread (void *) +{ + pint i; + + for (i = 0; i < 1000; ++i) { + if (!p_spinlock_trylock (global_spinlock)) { + if (!p_spinlock_lock (global_spinlock)) + p_uthread_exit (1); + } + + if (spinlock_test_val == PSPINLOCK_MAX_VAL) + --spinlock_test_val; + else { + p_uthread_sleep (1); + ++spinlock_test_val; + } + + if (!p_spinlock_unlock (global_spinlock)) + p_uthread_exit (1); + } + + p_uthread_exit (0); + + return NULL; +} + +P_TEST_CASE_BEGIN (pspinlock_nomem_test) +{ + p_libsys_init (); + + PMemVTable vtable; + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + P_TEST_CHECK (p_spinlock_new () == NULL); + + p_mem_restore_vtable (); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pspinlock_bad_input_test) +{ + p_libsys_init (); + + P_TEST_REQUIRE (p_spinlock_lock (NULL) == FALSE); + P_TEST_REQUIRE (p_spinlock_unlock (NULL) == FALSE); + P_TEST_REQUIRE (p_spinlock_trylock (NULL) == FALSE); + p_spinlock_free (NULL); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pspinlock_general_test) +{ + PUThread *thr1, *thr2; + + p_libsys_init (); + + spinlock_test_val = PSPINLOCK_MAX_VAL; + global_spinlock = p_spinlock_new (); + + P_TEST_REQUIRE (global_spinlock != NULL); + + thr1 = p_uthread_create ((PUThreadFunc) spinlock_test_thread, NULL, TRUE, NULL); + P_TEST_REQUIRE (thr1 != NULL); + + thr2 = p_uthread_create ((PUThreadFunc) spinlock_test_thread, NULL, TRUE, NULL); + P_TEST_REQUIRE (thr2 != NULL); + + P_TEST_CHECK (p_uthread_join (thr1) == 0); + P_TEST_CHECK (p_uthread_join (thr2) == 0); + + P_TEST_REQUIRE (spinlock_test_val == PSPINLOCK_MAX_VAL); + + p_uthread_unref (thr1); + p_uthread_unref (thr2); + p_spinlock_free (global_spinlock); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (pspinlock_nomem_test); + P_TEST_SUITE_RUN_CASE (pspinlock_bad_input_test); + P_TEST_SUITE_RUN_CASE (pspinlock_general_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/pstdarg_test.cpp b/3rdparty/plibsys/tests/pstdarg_test.cpp new file mode 100644 index 0000000..7df041f --- /dev/null +++ b/3rdparty/plibsys/tests/pstdarg_test.cpp @@ -0,0 +1,205 @@ +/* + * The MIT License + * + * Copyright (C) 2017 Jean-Damien Durand + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +#if defined(P_CC_WATCOM) +# pragma disable_message (7) +#endif + +P_TEST_MODULE_INIT (); + +static void variadic_function (pint unused, ...); +static void variadic_function_copy_all (pint unused, p_va_list ap); +static void variadic_function_copy_trail (pint unused, p_va_list ap); + +/* The "runtime" thingies here are just to avoid compiler warnings */ +/* In head, In trail */ +static const pint8 pint8_var[2] = { P_MININT8, P_MAXINT8 }; +static const puint8 puint8_var[2] = { 0, P_MAXUINT8 }; +static const pint16 pint16_var[2] = { P_MININT16, P_MAXINT16 }; +static const puint16 puint16_var[2] = { 0, P_MAXUINT16 }; +static pint32 pint32_var[2] = { 0 /* runtime */, 0 /* runtime */ }; +static puint32 puint32_var[2] = { 0, 0 /* runtime */ }; +static pint64 pint64_var[2] = { 0 /* runtime */, 0 /* runtime */ }; +static puint64 puint64_var[2] = { 0, 0 /* runtime */ }; +static const pint pint_var[2] = { P_MININT, P_MAXINT }; +static const puint puint_var[2] = { 0, P_MAXUINT }; +static const pshort pshort_var[2] = { P_MINSHORT, P_MAXSHORT }; +static const plong plong_var[2] = { P_MINLONG, P_MAXLONG }; +static const pchar pchar_var[2] = { '\0', 'z' }; +static const ppointer ppointer_var[2] = { NULL, (ppointer) p_libsys_init }; +static const pfloat pfloat_var[2] = { -1.234f, 1.234f }; +static const pdouble pdouble_var[2] = { -1.567, 1.567 }; + +/* Macros are used for testing because these tests MUST play with the CURRENT stack. */ + +#define P_TEST_VA_ARG(ap, type, wantedvalue) do { \ + P_DEBUG ("Unstacking a " #type); \ + P_TEST_CHECK (type##_va_arg(ap) == wantedvalue); \ + } while (0) + +#define P_TEST_VA_ARG_HEAD(ap) do { \ + P_TEST_VA_ARG(ap, pint8, pint8_var[0]); \ + P_TEST_VA_ARG(ap, puint8, puint8_var[0]); \ + P_TEST_VA_ARG(ap, pint16, pint16_var[0]); \ + P_TEST_VA_ARG(ap, puint16, puint16_var[0]); \ + P_TEST_VA_ARG(ap, pint32, pint32_var[0]); \ + P_TEST_VA_ARG(ap, puint32, puint32_var[0]); \ + P_TEST_VA_ARG(ap, pint64, pint64_var[0]); \ + P_TEST_VA_ARG(ap, puint64, puint64_var[0]); \ + P_TEST_VA_ARG(ap, pint, pint_var[0]); \ + P_TEST_VA_ARG(ap, puint, puint_var[0]); \ + P_TEST_VA_ARG(ap, pshort, pshort_var[0]); \ + P_TEST_VA_ARG(ap, plong, plong_var[0]); \ + P_TEST_VA_ARG(ap, pchar, pchar_var[0]); \ + P_TEST_VA_ARG(ap, ppointer, ppointer_var[0]); \ + P_TEST_VA_ARG(ap, pfloat, pfloat_var[0]); \ + P_TEST_VA_ARG(ap, pdouble, pdouble_var[0]); \ + } while (0) + +#define P_TEST_VA_ARG_TRAIL(ap) do { \ + P_TEST_VA_ARG(ap, pdouble, pdouble_var[1]); \ + P_TEST_VA_ARG(ap, pfloat, pfloat_var[1]); \ + P_TEST_VA_ARG(ap, ppointer, ppointer_var[1]); \ + P_TEST_VA_ARG(ap, pchar, pchar_var[1]); \ + P_TEST_VA_ARG(ap, plong, plong_var[1]); \ + P_TEST_VA_ARG(ap, pshort, pshort_var[1]); \ + P_TEST_VA_ARG(ap, puint, puint_var[1]); \ + P_TEST_VA_ARG(ap, pint, pint_var[1]); \ + P_TEST_VA_ARG(ap, puint64, puint64_var[1]); \ + P_TEST_VA_ARG(ap, pint64, pint64_var[1]); \ + P_TEST_VA_ARG(ap, puint32, puint32_var[1]); \ + P_TEST_VA_ARG(ap, pint32, pint32_var[1]); \ + P_TEST_VA_ARG(ap, puint16, puint16_var[1]); \ + P_TEST_VA_ARG(ap, pint16, pint16_var[1]); \ + P_TEST_VA_ARG(ap, puint8, puint8_var[1]); \ + P_TEST_VA_ARG(ap, pint8, pint8_var[1]); \ + } while (0) + +static void variadic_function_copy_all (pint unused, p_va_list ap) +{ + P_UNUSED (unused); + P_DEBUG ("Unstacking a copy of all the arguments"); + P_TEST_VA_ARG_HEAD (ap); + P_TEST_VA_ARG_TRAIL (ap); +} + +static void variadic_function_copy_trail (pint unused, p_va_list ap) +{ + P_UNUSED (unused); + P_DEBUG ("Unstacking second part of the arguments"); + P_TEST_VA_ARG_TRAIL (ap); +} + +static void variadic_function (pint unused, ...) +{ + p_va_list ap; + p_va_list ap2; + + p_va_start (ap, unused); + + P_DEBUG ("Copy of arguments"); + p_va_copy (ap2, ap); + variadic_function_copy_all (unused, ap2); + p_va_end (ap2); + + P_DEBUG ("Unstacking first part of arguments"); + P_TEST_VA_ARG_HEAD (ap); + + P_DEBUG ("Copy of arguments at current unstack state, i.e. in the middle"); + p_va_copy (ap2, ap); + variadic_function_copy_trail (unused, ap2); + p_va_end (ap2); + + P_DEBUG ("Unstacking second part of arguments"); + P_TEST_VA_ARG_TRAIL (ap); + + p_va_end (ap); +} + +P_TEST_CASE_BEGIN (pstdarg_general_test) +{ + p_libsys_init (); + + pint32_var[0] = P_MININT16; + pint32_var[0] <<= 16; + pint32_var[1] = P_MAXINT16; + pint32_var[1] <<= 16; + puint32_var[1] = P_MAXUINT16; + puint32_var[1] <<= 16; + + pint64_var[0] = pint32_var[0]; + pint64_var[0] <<= 32; + pint64_var[1] = pint32_var[1]; + pint64_var[1] <<= 32; + puint64_var[1] = puint32_var[1]; + puint64_var[1] <<= 32; + + variadic_function (0, + pint8_var[0], + puint8_var[0], + pint16_var[0], + puint16_var[0], + pint32_var[0], + puint32_var[0], + pint64_var[0], + puint64_var[0], + pint_var[0], + puint_var[0], + pshort_var[0], + plong_var[0], + pchar_var[0], + ppointer_var[0], + pfloat_var[0], + pdouble_var[0], + /* Cut is here when testing p_va_copy, we stack in reverse order */ + pdouble_var[1], + pfloat_var[1], + ppointer_var[1], + pchar_var[1], + plong_var[1], + pshort_var[1], + puint_var[1], + pint_var[1], + puint64_var[1], + pint64_var[1], + puint32_var[1], + pint32_var[1], + puint16_var[1], + pint16_var[1], + puint8_var[1], + pint8_var[1]); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (pstdarg_general_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/pstring_test.cpp b/3rdparty/plibsys/tests/pstring_test.cpp new file mode 100644 index 0000000..73e5805 --- /dev/null +++ b/3rdparty/plibsys/tests/pstring_test.cpp @@ -0,0 +1,289 @@ +/* + * The MIT License + * + * Copyright (C) 2013-2017 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +#include +#include +#include + +P_TEST_MODULE_INIT (); + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + P_UNUSED (block); + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" void pmem_free (ppointer block) +{ + P_UNUSED (block); +} + +P_TEST_CASE_BEGIN (pstring_nomem_test) +{ + p_libsys_init (); + + PMemVTable vtable; + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + + P_TEST_CHECK (p_strdup ("test string") == NULL); + + p_mem_restore_vtable (); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pstring_strdup_test) +{ + p_libsys_init (); + + const pchar *test_str_1 = "Test string"; + + pchar *new_string = p_strdup (test_str_1); + P_TEST_CHECK (new_string != NULL); + p_free (new_string); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pstring_strchomp_test) +{ + p_libsys_init (); + + const pchar *test_chomp_str_orig = "Test chomp string"; + const pchar *test_chomp_str_1 = "Test chomp string "; + const pchar *test_chomp_str_2 = "\n\nTest chomp string "; + const pchar *test_chomp_str_3 = "\n\rTest chomp string \n"; + const pchar *test_chomp_str_4 = "Test chomp string\n\n"; + const pchar *test_chomp_str_5 = " \rTest chomp string \n\n "; + const pchar *test_chomp_str_6 = " \rI\n\n "; + const pchar *test_chomp_str_7 = "\n"; + const pchar *test_chomp_str_8 = "I"; + const pchar *test_chomp_str_9 = ""; + const pchar *test_chomp_str_10 = " "; + const pchar *test_chomp_str_11 = NULL; + + pchar *new_string = p_strchomp (test_chomp_str_1); + P_TEST_REQUIRE (new_string != NULL); + P_TEST_CHECK (strcmp (test_chomp_str_orig, new_string) == 0); + p_free (new_string); + + new_string = p_strchomp (test_chomp_str_2); + P_TEST_REQUIRE (new_string != NULL); + P_TEST_CHECK (strcmp (test_chomp_str_orig, new_string) == 0); + p_free (new_string); + + new_string = p_strchomp (test_chomp_str_3); + P_TEST_REQUIRE (new_string != NULL); + P_TEST_CHECK (strcmp (test_chomp_str_orig, new_string) == 0); + p_free (new_string); + + new_string = p_strchomp (test_chomp_str_4); + P_TEST_REQUIRE (new_string != NULL); + P_TEST_CHECK (strcmp (test_chomp_str_orig, new_string) == 0); + p_free (new_string); + + new_string = p_strchomp (test_chomp_str_5); + P_TEST_REQUIRE (new_string != NULL); + P_TEST_CHECK (strcmp (test_chomp_str_orig, new_string) == 0); + p_free (new_string); + + new_string = p_strchomp (test_chomp_str_6); + P_TEST_REQUIRE (new_string != NULL); + P_TEST_CHECK (strcmp ("I", new_string) == 0); + p_free (new_string); + + new_string = p_strchomp (test_chomp_str_7); + P_TEST_REQUIRE (new_string != NULL); + P_TEST_CHECK (*new_string == '\0'); + p_free (new_string); + + new_string = p_strchomp (test_chomp_str_8); + P_TEST_REQUIRE (new_string != NULL); + P_TEST_CHECK (strcmp ("I", new_string) == 0); + p_free (new_string); + + new_string = p_strchomp (test_chomp_str_9); + P_TEST_REQUIRE (new_string != NULL); + P_TEST_CHECK (*new_string == '\0'); + p_free (new_string); + + new_string = p_strchomp (test_chomp_str_10); + P_TEST_REQUIRE (new_string != NULL); + P_TEST_CHECK (*new_string == '\0'); + p_free (new_string); + + new_string = p_strchomp (test_chomp_str_11); + P_TEST_CHECK (new_string == NULL); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pstring_strtok_test) +{ + p_libsys_init (); + + P_TEST_CHECK (p_strtok (NULL, NULL, NULL) == NULL); + + /* First string */ + pchar test_string[] = "1,2,3"; + pchar *token, *next_token; + + /* Check third parameter for possible NULL */ + token = p_strtok (test_string, ",", NULL); + + if (strcmp (token, "1") != 0) { + token = p_strtok (test_string, ",", &next_token); + P_TEST_CHECK (token != NULL); + P_TEST_CHECK (strcmp (token, "1") == 0); + } + + token = p_strtok (NULL, ",", &next_token); + P_TEST_CHECK (token != NULL); + P_TEST_CHECK (strcmp (token, "2") == 0); + + token = p_strtok (NULL, ",", &next_token); + P_TEST_CHECK (token != NULL); + P_TEST_CHECK (strcmp (token, "3") == 0); + + token = p_strtok (NULL, ",", &next_token); + P_TEST_CHECK (token == NULL); + + /* Second string */ + pchar test_string_2[] = "Test string, to test"; + + token = p_strtok (test_string_2, " ", &next_token); + P_TEST_CHECK (token != NULL); + P_TEST_CHECK (strcmp (token, "Test") == 0); + + token = p_strtok (NULL, ", ", &next_token); + P_TEST_CHECK (token != NULL); + P_TEST_CHECK (strcmp (token, "string") == 0); + + token = p_strtok (NULL, ", ", &next_token); + P_TEST_CHECK (token != NULL); + P_TEST_CHECK (strcmp (token, "to") == 0); + + token = p_strtok (NULL, ", \t\n", &next_token); + P_TEST_CHECK (token != NULL); + P_TEST_CHECK (strcmp (token, "test") == 0); + + token = p_strtok (NULL, ", \t\n", &next_token); + P_TEST_CHECK (token == NULL); + + /* Third string */ + pchar test_string_3[] = "compile\ttest\ndeploy"; + + token = p_strtok (test_string_3, "\t\n", &next_token); + P_TEST_CHECK (token != NULL); + P_TEST_CHECK (strcmp (token, "compile") == 0); + + token = p_strtok (NULL, "\t\n", &next_token); + P_TEST_CHECK (token != NULL); + P_TEST_CHECK (strcmp (token, "test") == 0); + + token = p_strtok (NULL, "\t\n", &next_token); + P_TEST_CHECK (token != NULL); + P_TEST_CHECK (strcmp (token, "deploy") == 0); + + token = p_strtok (NULL, ", \t\n", &next_token); + P_TEST_CHECK (token == NULL); + + /* Fourth string */ + pchar test_string_4[] = "\t \t\n \t"; + + token = p_strtok (test_string_4, "\t\n ", &next_token); + P_TEST_CHECK (token == NULL); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (pstring_strtod_test) +{ + p_libsys_init (); + + /* Incorrect input */ + P_TEST_CHECK_CLOSE (p_strtod (NULL), 0.0, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("e2"), 0.0, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("e-2"), 0.0, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("-e2"), 0.0, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("-e-2"), 0.0, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("0,3"), 0.0, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("12,3"), 12.0, 0.0001); + + /* Correct input */ + P_TEST_CHECK_CLOSE (p_strtod ("0"), 0.0, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("0.0"), 0.0, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("-0"), 0.0, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("-0.0"), 0.0, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("3.14"), 3.14, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("+3.14"), 3.14, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("-12.256"), -12.256, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("0.056"), 0.056, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("-0.057"), -0.057, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("1.5423e2"), 154.23, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("1e3"), 1000.0, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("1e+3"), 1000.0, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("-2.56e1"), -25.6, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("-2.56e+1"), -25.6, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("123e-2"), 1.23, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("3.14e-1"), 0.314, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("3.14e60"), 3.14e60, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("3.14e-60"), 3.14e-60, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("2.14e10"), 2.14e10, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("2.14e-10"), 2.14e-10, 0.0001); + P_TEST_CHECK_CLOSE (p_strtod ("1.10e310"), 1.10e308, 0.0001); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (pstring_nomem_test); + P_TEST_SUITE_RUN_CASE (pstring_strdup_test); + P_TEST_SUITE_RUN_CASE (pstring_strchomp_test); + P_TEST_SUITE_RUN_CASE (pstring_strtok_test); + P_TEST_SUITE_RUN_CASE (pstring_strtod_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/ptestmacros.h b/3rdparty/plibsys/tests/ptestmacros.h new file mode 100644 index 0000000..206a8a6 --- /dev/null +++ b/3rdparty/plibsys/tests/ptestmacros.h @@ -0,0 +1,131 @@ +/* + * The MIT License + * + * Copyright (C) 2017 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file ptestmacros.h + * @brief Macros for unit-tests + * @author Alexander Saprykin + */ + +#ifndef PLIBSYS_HEADER_PTESTMACROS_H +#define PLIBSYS_HEADER_PTESTMACROS_H + +#include + +#include + +#if defined (P_CC_MSVC) +# pragma warning (push) +# pragma warning (disable : 4723) +#elif defined (P_CC_BORLAND) +# pragma option -w-8008 +# pragma option -w-8066 +#elif defined (P_CC_WATCOM) +# pragma disable_message (13) +# pragma disable_message (367) +# pragma disable_message (368) +#endif + +inline double p_test_safe_division (double f1, double f2) +{ + return (f2 < 1.0 && f1 > f2 * P_MAXDOUBLE) ? P_MAXDOUBLE : + (((f2 > 1.0 && f1 < f2 * P_MINDOUBLE) || f1 == 0) ? 0 : f1 / f2); +} + +#ifdef P_CC_MSVC +# pragma warning (pop) +#endif + +#define P_TEST_MODULE_FAIL_COUNTER p_test_module_fail_counter +#define P_TEST_SUITE_FAIL_COUNTER p_test_suite_fail_counter + +#define P_TEST_MODULE_INIT() static pint P_TEST_MODULE_FAIL_COUNTER = 0 + +#define P_TEST_CASE_BEGIN(test_case_name) \ + pint p_test_case_##test_case_name (void) \ + { \ + P_TEST_MODULE_FAIL_COUNTER = 0; + +#define P_TEST_CASE_END() \ + return (P_TEST_MODULE_FAIL_COUNTER == 0) ? 0 : -1; \ + } + +#define P_TEST_CASE_RETURN() return 0 + +#define P_TEST_SUITE_BEGIN() \ + int main (void) \ + { \ + pint P_TEST_SUITE_FAIL_COUNTER = 0; + +#define P_TEST_SUITE_ARGS_BEGIN() \ + int main (int argc, char *argv[]) \ + { \ + pint P_TEST_SUITE_FAIL_COUNTER = 0; + +#define P_TEST_SUITE_END() \ + if (P_TEST_SUITE_FAIL_COUNTER == 0) \ + printf ("Test passed\n"); \ + else \ + printf ("Test failed\n"); \ + \ + return P_TEST_SUITE_FAIL_COUNTER == 0 ? 0 : -1; \ + } + +#define P_TEST_SUITE_RUN_CASE(a) \ + printf ("Running test case: %s\n", #a); \ + P_TEST_SUITE_FAIL_COUNTER += (p_test_case_##a)() + +#define P_TEST_CHECK(a) \ + do { \ + if (!(a)) { \ + printf ("%s:%d: check failed\n", __FILE__, __LINE__); \ + p_atomic_int_inc (&P_TEST_MODULE_FAIL_COUNTER); \ + } \ + } while (0) + +#define P_TEST_CHECK_CLOSE(a, b, eps) \ + do { \ + double p_test_eps_diff = (a) > (b) ? (a) - (b) : (b) - (a); \ + double p_test_d1 = p_test_safe_division (p_test_eps_diff, \ + ((a) < 0.0 ? (-(a)) : (a))); \ + double p_test_d2 = p_test_safe_division (p_test_eps_diff, \ + ((b) < 0.0 ? (-(b)) : (b))); \ + double p_test_tol = (eps) * 0.01; \ + \ + if (!(p_test_d1 <= p_test_tol && p_test_d2 <= p_test_tol)) { \ + printf ("%s:%d: check failed\n", __FILE__, __LINE__); \ + p_atomic_int_inc (&P_TEST_MODULE_FAIL_COUNTER); \ + } \ + } while (0) + +#define P_TEST_REQUIRE(a) \ + do { \ + if (!(a)) { \ + printf ("%s:%d: required check failed\n", __FILE__, __LINE__); \ + exit (-1); \ + } \ + } while (0) + +#endif /* PLIBSYS_HEADER_PTESTMACROS_H */ diff --git a/3rdparty/plibsys/tests/ptimeprofiler_test.cpp b/3rdparty/plibsys/tests/ptimeprofiler_test.cpp new file mode 100644 index 0000000..dd9e2b7 --- /dev/null +++ b/3rdparty/plibsys/tests/ptimeprofiler_test.cpp @@ -0,0 +1,126 @@ +/* + * The MIT License + * + * Copyright (C) 2013-2017 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +P_TEST_MODULE_INIT (); + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + P_UNUSED (block); + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" void pmem_free (ppointer block) +{ + P_UNUSED (block); +} + +P_TEST_CASE_BEGIN (ptimeprofiler_nomem_test) +{ + p_libsys_init (); + + PMemVTable vtable; + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + + P_TEST_CHECK (p_time_profiler_new () == NULL); + + p_mem_restore_vtable (); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (ptimeprofiler_bad_input_test) +{ + p_libsys_init (); + + P_TEST_CHECK (p_time_profiler_elapsed_usecs (NULL) == 0); + p_time_profiler_reset (NULL); + p_time_profiler_free (NULL); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (ptimeprofiler_general_test) +{ + PTimeProfiler *profiler = NULL; + puint64 prev_val, val; + + p_libsys_init (); + + profiler = p_time_profiler_new (); + P_TEST_REQUIRE (profiler != NULL); + + p_uthread_sleep (50); + prev_val = p_time_profiler_elapsed_usecs (profiler); + P_TEST_CHECK (prev_val > 0); + + p_uthread_sleep (100); + val = p_time_profiler_elapsed_usecs (profiler); + P_TEST_CHECK (val > prev_val); + prev_val = val; + + p_uthread_sleep (1000); + val = p_time_profiler_elapsed_usecs (profiler); + P_TEST_CHECK (val > prev_val); + + p_time_profiler_reset (profiler); + + p_uthread_sleep (15); + prev_val = p_time_profiler_elapsed_usecs (profiler); + P_TEST_CHECK (prev_val > 0); + + p_uthread_sleep (178); + val = p_time_profiler_elapsed_usecs (profiler); + P_TEST_CHECK (val > prev_val); + + p_time_profiler_free (profiler); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (ptimeprofiler_nomem_test); + P_TEST_SUITE_RUN_CASE (ptimeprofiler_bad_input_test); + P_TEST_SUITE_RUN_CASE (ptimeprofiler_general_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/ptree_test.cpp b/3rdparty/plibsys/tests/ptree_test.cpp new file mode 100644 index 0000000..e038ebb --- /dev/null +++ b/3rdparty/plibsys/tests/ptree_test.cpp @@ -0,0 +1,633 @@ +/* + * The MIT License + * + * Copyright (C) 2015-2017 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +#include +#include +#include +#include + +P_TEST_MODULE_INIT (); + +#define PTREE_STRESS_ITERATIONS 20 +#define PTREE_STRESS_NODES 10000 +#define PTREE_STRESS_ROOT_MIN 10000 +#define PTREE_STRESS_TRAVS 30 + +typedef struct _TreeData { + pint cmp_counter; + pint key_destroy_counter; + pint value_destroy_counter; + pint traverse_counter; + pint traverse_thres; + pint key_sum; + pint value_sum; + pint last_key; + pint key_order_errors; +} TreeData; + +static TreeData tree_data = {0, 0, 0, 0, 0, 0, 0, 0, 0}; + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + P_UNUSED (block); + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" void pmem_free (ppointer block) +{ + P_UNUSED (block); +} + +static pint +tree_complexity (PTree *tree) +{ + if (tree == NULL || p_tree_get_nnodes (tree) == 0) + return 0; + + switch (p_tree_get_type (tree)) { + case P_TREE_TYPE_BINARY: + return p_tree_get_nnodes (tree); + case P_TREE_TYPE_RB: + return 2 * ((pint) (log ((double) p_tree_get_nnodes (tree) + 1) / log (2.0))); + case P_TREE_TYPE_AVL: + { + double phi = (1 + sqrt (5.0)) / 2.0; + return (pint) (log (sqrt (5.0) * (p_tree_get_nnodes (tree) + 2)) / log (phi) - 2); + } + default: + return p_tree_get_nnodes (tree); + } +} + +static pint +compare_keys (pconstpointer a, pconstpointer b) +{ + int p1 = PPOINTER_TO_INT (a); + int p2 = PPOINTER_TO_INT (b); + + if (p1 < p2) + return -1; + else if (p1 > p2) + return 1; + else + return 0; +} + +static pint +compare_keys_data (pconstpointer a, pconstpointer b, ppointer data) +{ + int p1 = PPOINTER_TO_INT (a); + int p2 = PPOINTER_TO_INT (b); + + if (data != NULL) + ((TreeData *) data)->cmp_counter++; + + if (p1 < p2) + return -1; + else if (p1 > p2) + return 1; + else + return 0; +} + +static void +key_destroy_notify (ppointer data) +{ + tree_data.key_destroy_counter++; + tree_data.key_sum += PPOINTER_TO_INT (data); +} + +static void +value_destroy_notify (ppointer data) +{ + tree_data.value_destroy_counter++; + tree_data.value_sum += PPOINTER_TO_INT (data); +} + +static pboolean +tree_traverse (ppointer key, ppointer value, ppointer data) +{ + TreeData* tdata = ((TreeData *) data); + + tdata->key_sum += PPOINTER_TO_INT (key); + tdata->value_sum += PPOINTER_TO_INT (value); + tdata->traverse_counter++; + + if (tdata->last_key >= PPOINTER_TO_INT (key)) + tdata->key_order_errors++; + + tdata->last_key = PPOINTER_TO_INT (key); + + return FALSE; +} + +static pboolean +tree_traverse_thres (ppointer key, ppointer value, ppointer data) +{ + TreeData* tdata = ((TreeData *) data); + + tree_traverse (key, value, data); + + return tdata->traverse_counter >= tdata->traverse_thres ? TRUE : FALSE; +} + +static bool +check_tree_data_is_zero () +{ + return tree_data.cmp_counter == 0 && + tree_data.key_destroy_counter == 0 && + tree_data.value_destroy_counter == 0 && + tree_data.traverse_counter == 0 && + tree_data.traverse_thres == 0 && + tree_data.key_sum == 0 && + tree_data.value_sum == 0 && + tree_data.last_key == 0 && + tree_data.key_order_errors == 0; +} + +static bool +general_tree_test (PTree *tree, PTreeType type, bool check_cmp, bool check_notify) +{ + memset (&tree_data, 0, sizeof (tree_data)); + + P_TEST_REQUIRE (tree != NULL); + P_TEST_CHECK (p_tree_get_nnodes (tree) == 0); + P_TEST_CHECK (p_tree_get_type (tree) == type); + P_TEST_CHECK (p_tree_lookup (tree, NULL) == NULL); + P_TEST_CHECK (p_tree_remove (tree, NULL) == FALSE); + + p_tree_insert (tree, NULL, PINT_TO_POINTER (10)); + P_TEST_CHECK (p_tree_get_nnodes (tree) == 1); + P_TEST_CHECK (p_tree_lookup (tree, NULL) == PINT_TO_POINTER (10)); + P_TEST_CHECK (p_tree_lookup (tree, PINT_TO_POINTER (2)) == NULL); + P_TEST_CHECK (p_tree_remove (tree, NULL) == TRUE); + P_TEST_CHECK (p_tree_get_nnodes (tree) == 0); + + p_tree_foreach (tree, (PTraverseFunc) tree_traverse, &tree_data); + P_TEST_CHECK (tree_data.traverse_counter == 0); + P_TEST_CHECK (tree_data.key_order_errors == 0); + + /* Because we have NULL-key node */ + P_TEST_CHECK (tree_data.key_sum == 0); + + if (check_notify) + P_TEST_CHECK (tree_data.value_sum == 10); + else + P_TEST_CHECK (tree_data.value_sum == 0); + + memset (&tree_data, 0, sizeof (tree_data)); + + p_tree_insert (tree, PINT_TO_POINTER (4), PINT_TO_POINTER (40)); + p_tree_insert (tree, PINT_TO_POINTER (1), PINT_TO_POINTER (10)); + p_tree_insert (tree, PINT_TO_POINTER (5), PINT_TO_POINTER (50)); + p_tree_insert (tree, PINT_TO_POINTER (2), PINT_TO_POINTER (20)); + p_tree_insert (tree, PINT_TO_POINTER (6), PINT_TO_POINTER (60)); + p_tree_insert (tree, PINT_TO_POINTER (3), PINT_TO_POINTER (30)); + + P_TEST_CHECK (p_tree_get_nnodes (tree) == 6); + + p_tree_insert (tree, PINT_TO_POINTER (1), PINT_TO_POINTER (100)); + p_tree_insert (tree, PINT_TO_POINTER (5), PINT_TO_POINTER (500)); + + P_TEST_CHECK (p_tree_get_nnodes (tree) == 6); + + p_tree_insert (tree, PINT_TO_POINTER (1), PINT_TO_POINTER (10)); + p_tree_insert (tree, PINT_TO_POINTER (5), PINT_TO_POINTER (50)); + + P_TEST_CHECK (p_tree_get_nnodes (tree) == 6); + + if (check_cmp) + P_TEST_CHECK (tree_data.cmp_counter > 0); + else + P_TEST_CHECK (tree_data.cmp_counter == 0); + + if (check_notify) { + P_TEST_CHECK (tree_data.key_sum == 12); + P_TEST_CHECK (tree_data.value_sum == 660); + } else { + P_TEST_CHECK (tree_data.key_sum == 0); + P_TEST_CHECK (tree_data.value_sum == 0); + } + + P_TEST_CHECK (tree_data.traverse_counter == 0); + P_TEST_CHECK (tree_data.key_order_errors == 0); + + memset (&tree_data, 0, sizeof (tree_data)); + + p_tree_foreach (tree, (PTraverseFunc) tree_traverse, &tree_data); + P_TEST_CHECK (p_tree_get_nnodes (tree) == 6); + + P_TEST_CHECK (tree_data.cmp_counter == 0); + P_TEST_CHECK (tree_data.key_sum == 21); + P_TEST_CHECK (tree_data.value_sum == 210); + P_TEST_CHECK (tree_data.traverse_counter == 6); + P_TEST_CHECK (tree_data.key_order_errors == 0); + + memset (&tree_data, 0, sizeof (tree_data)); + + for (int i = 0; i < 7; ++i) + P_TEST_CHECK (p_tree_lookup (tree, PINT_TO_POINTER (i)) == PINT_TO_POINTER (i * 10)); + + if (check_cmp) + P_TEST_CHECK (tree_data.cmp_counter > 0); + else + P_TEST_CHECK (tree_data.cmp_counter == 0); + + P_TEST_CHECK (tree_data.key_sum == 0); + P_TEST_CHECK (tree_data.value_sum == 0); + P_TEST_CHECK (tree_data.key_order_errors == 0); + + tree_data.cmp_counter = 0; + + P_TEST_CHECK (p_tree_remove (tree, PINT_TO_POINTER (7)) == FALSE); + + if (check_cmp) + P_TEST_CHECK (tree_data.cmp_counter > 0 && + tree_data.cmp_counter <= tree_complexity (tree)); + else + P_TEST_CHECK (tree_data.cmp_counter == 0); + + if (check_notify) { + P_TEST_CHECK (tree_data.key_sum == 0); + P_TEST_CHECK (tree_data.value_sum == 0); + } + + tree_data.cmp_counter = 0; + + for (int i = 0; i < 7; ++i) + P_TEST_CHECK (p_tree_lookup (tree, PINT_TO_POINTER (i)) == PINT_TO_POINTER (i * 10)); + + if (check_cmp) + P_TEST_CHECK (tree_data.cmp_counter > 0); + else + P_TEST_CHECK (tree_data.cmp_counter == 0); + + P_TEST_CHECK (tree_data.key_sum == 0); + P_TEST_CHECK (tree_data.value_sum == 0); + P_TEST_CHECK (tree_data.key_order_errors == 0); + + memset (&tree_data, 0, sizeof (tree_data)); + + tree_data.traverse_thres = 5; + + p_tree_foreach (tree, (PTraverseFunc) tree_traverse_thres, &tree_data); + P_TEST_CHECK (p_tree_get_nnodes (tree) == 6); + + P_TEST_CHECK (tree_data.cmp_counter == 0); + P_TEST_CHECK (tree_data.key_sum == 15); + P_TEST_CHECK (tree_data.value_sum == 150); + P_TEST_CHECK (tree_data.traverse_counter == 5); + P_TEST_CHECK (tree_data.key_order_errors == 0); + + memset (&tree_data, 0, sizeof (tree_data)); + + tree_data.traverse_thres = 3; + + p_tree_foreach (tree, (PTraverseFunc) tree_traverse_thres, &tree_data); + P_TEST_CHECK (p_tree_get_nnodes (tree) == 6); + + P_TEST_CHECK (tree_data.cmp_counter == 0); + P_TEST_CHECK (tree_data.key_sum == 6); + P_TEST_CHECK (tree_data.value_sum == 60); + P_TEST_CHECK (tree_data.traverse_counter == 3); + P_TEST_CHECK (tree_data.key_order_errors == 0); + + memset (&tree_data, 0, sizeof (tree_data)); + + P_TEST_CHECK (p_tree_remove (tree, PINT_TO_POINTER (1)) == TRUE); + P_TEST_CHECK (p_tree_remove (tree, PINT_TO_POINTER (6)) == TRUE); + P_TEST_CHECK (p_tree_lookup (tree, PINT_TO_POINTER (1)) == NULL); + P_TEST_CHECK (p_tree_lookup (tree, PINT_TO_POINTER (6)) == NULL); + + if (check_cmp) + P_TEST_CHECK (tree_data.cmp_counter > 0); + else + P_TEST_CHECK (tree_data.cmp_counter == 0); + + if (check_notify) { + P_TEST_CHECK (tree_data.key_sum == 7); + P_TEST_CHECK (tree_data.value_sum == 70); + } else { + P_TEST_CHECK (tree_data.key_sum == 0); + P_TEST_CHECK (tree_data.value_sum == 0); + } + + tree_data.cmp_counter = 0; + + for (int i = 2; i < 6; ++i) + P_TEST_CHECK (p_tree_lookup (tree, PINT_TO_POINTER (i)) == PINT_TO_POINTER (i * 10)); + + if (check_cmp) + P_TEST_CHECK (tree_data.cmp_counter > 0); + else + P_TEST_CHECK (tree_data.cmp_counter == 0); + + if (check_notify) { + P_TEST_CHECK (tree_data.key_sum == 7); + P_TEST_CHECK (tree_data.value_sum == 70); + } else { + P_TEST_CHECK (tree_data.key_sum == 0); + P_TEST_CHECK (tree_data.value_sum == 0); + } + + P_TEST_CHECK (tree_data.key_order_errors == 0); + + tree_data.cmp_counter = 0; + + p_tree_foreach (tree, NULL, NULL); + + P_TEST_CHECK (tree_data.cmp_counter == 0); + P_TEST_CHECK (tree_data.key_order_errors == 0); + + p_tree_clear (tree); + + P_TEST_CHECK (tree_data.cmp_counter == 0); + P_TEST_CHECK (tree_data.key_order_errors == 0); + + if (check_notify) { + P_TEST_CHECK (tree_data.key_sum == 21); + P_TEST_CHECK (tree_data.value_sum == 210); + } else { + P_TEST_CHECK (tree_data.key_sum == 0); + P_TEST_CHECK (tree_data.value_sum == 0); + } + + P_TEST_CHECK (p_tree_get_nnodes (tree) == 0); + + return true; +} + +static bool +stress_tree_test (PTree *tree, int node_count) +{ + P_TEST_REQUIRE (tree != NULL); + P_TEST_REQUIRE (node_count > 0); + P_TEST_CHECK (p_tree_get_nnodes (tree) == 0); + + srand ((unsigned int) time (NULL)); + + int counter = 0; + + memset (&tree_data, 0, sizeof (tree_data)); + + pint *keys = (pint *) p_malloc0 ((psize) node_count * sizeof (pint)); + pint *values = (pint *) p_malloc0 ((psize) node_count * sizeof (pint)); + + P_TEST_REQUIRE (keys != NULL); + P_TEST_REQUIRE (values != NULL); + + while (counter != node_count) { + pint rand_number = rand (); + + if (counter == 0 && rand_number < PTREE_STRESS_ROOT_MIN) + continue; + + memset (&tree_data, 0, sizeof (tree_data)); + + if (p_tree_lookup (tree, PINT_TO_POINTER (rand_number)) != NULL) + continue; + + if (counter > 0) + P_TEST_CHECK (tree_data.cmp_counter > 0 && + tree_data.cmp_counter <= tree_complexity (tree)); + + memset (&tree_data, 0, sizeof (tree_data)); + + keys[counter] = rand_number; + values[counter] = rand () + 1; + + p_tree_insert (tree, PINT_TO_POINTER (keys[counter]), PINT_TO_POINTER (values[counter])); + + if (counter > 0) + P_TEST_CHECK (tree_data.cmp_counter > 0 && + tree_data.cmp_counter <= tree_complexity (tree)); + + ++counter; + } + + for (int i = 0; i < PTREE_STRESS_TRAVS; ++i) { + memset (&tree_data, 0, sizeof (tree_data)); + + tree_data.traverse_thres = i + 1; + tree_data.last_key = -1; + + p_tree_foreach (tree, (PTraverseFunc) tree_traverse_thres, &tree_data); + + P_TEST_CHECK (tree_data.traverse_counter == i + 1); + P_TEST_CHECK (tree_data.key_order_errors == 0); + } + + for (int i = 0; i < node_count; ++i) { + memset (&tree_data, 0, sizeof (tree_data)); + + P_TEST_CHECK (p_tree_lookup (tree, PINT_TO_POINTER (keys[i])) == + PINT_TO_POINTER (values[i])); + + P_TEST_CHECK (tree_data.cmp_counter > 0 && + tree_data.cmp_counter <= tree_complexity (tree)); + + P_TEST_CHECK (p_tree_remove (tree, PINT_TO_POINTER (keys[i])) == TRUE); + P_TEST_CHECK (p_tree_lookup (tree, PINT_TO_POINTER (keys[i])) == NULL); + } + + P_TEST_CHECK (p_tree_get_nnodes (tree) == 0); + + for (int i = 0; i < node_count; ++i) + p_tree_insert (tree, PINT_TO_POINTER (keys[i]), PINT_TO_POINTER (values[i])); + + P_TEST_CHECK (p_tree_get_nnodes (tree) == node_count); + + p_tree_clear (tree); + + P_TEST_CHECK (p_tree_get_nnodes (tree) == 0); + + p_free (keys); + p_free (values); + + return true; +} + +P_TEST_CASE_BEGIN (ptree_nomem_test) +{ + p_libsys_init (); + + PMemVTable vtable; + + for (int i = (int) P_TREE_TYPE_BINARY; i <= (int) P_TREE_TYPE_AVL; ++i) { + PTree *tree = p_tree_new ((PTreeType) i, (PCompareFunc) compare_keys); + P_TEST_CHECK (tree != NULL); + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + + P_TEST_CHECK (p_tree_new ((PTreeType) i, (PCompareFunc) compare_keys) == NULL); + p_tree_insert (tree, PINT_TO_POINTER (1), PINT_TO_POINTER (10)); + P_TEST_CHECK (p_tree_get_nnodes (tree) == 0); + + p_mem_restore_vtable (); + + p_tree_free (tree); + } + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (ptree_invalid_test) +{ + p_libsys_init (); + + for (int i = (int) P_TREE_TYPE_BINARY; i <= (int) P_TREE_TYPE_AVL; ++i) { + /* Invalid usage */ + P_TEST_CHECK (p_tree_new ((PTreeType) i, NULL) == NULL); + P_TEST_CHECK (p_tree_new ((PTreeType) -1, (PCompareFunc) compare_keys) == NULL); + P_TEST_CHECK (p_tree_new ((PTreeType) -1, NULL) == NULL); + + P_TEST_CHECK (p_tree_new_with_data ((PTreeType) i, NULL, NULL) == NULL); + P_TEST_CHECK (p_tree_new_with_data ((PTreeType) -1, (PCompareDataFunc) compare_keys, NULL) == NULL); + P_TEST_CHECK (p_tree_new_with_data ((PTreeType) -1, NULL, NULL) == NULL); + + P_TEST_CHECK (p_tree_new_full ((PTreeType) i, + NULL, + NULL, + NULL, + NULL) == NULL); + P_TEST_CHECK (p_tree_new_full ((PTreeType) -1, + (PCompareDataFunc) compare_keys, + NULL, + NULL, + NULL) == NULL); + P_TEST_CHECK (p_tree_new_full ((PTreeType) -1, + NULL, + NULL, + NULL, + NULL) == NULL); + + P_TEST_CHECK (p_tree_remove (NULL, NULL) == FALSE); + P_TEST_CHECK (p_tree_lookup (NULL, NULL) == NULL); + P_TEST_CHECK (p_tree_get_type (NULL) == (PTreeType) -1); + P_TEST_CHECK (p_tree_get_nnodes (NULL) == 0); + + p_tree_insert (NULL, NULL, NULL); + p_tree_foreach (NULL, NULL, NULL); + p_tree_clear (NULL); + p_tree_free (NULL); + } + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (ptree_general_test) +{ + PTree *tree; + + p_libsys_init (); + + for (int i = (int) P_TREE_TYPE_BINARY; i <= (int) P_TREE_TYPE_AVL; ++i) { + /* Test 1 */ + tree = p_tree_new ((PTreeType) i, (PCompareFunc) compare_keys); + + P_TEST_CHECK (general_tree_test (tree, (PTreeType) i, false, false) == true); + + memset (&tree_data, 0, sizeof (tree_data)); + p_tree_free (tree); + + P_TEST_CHECK (check_tree_data_is_zero () == true); + + /* Test 2 */ + tree = p_tree_new_with_data ((PTreeType) i, + (PCompareDataFunc) compare_keys_data, + &tree_data); + + P_TEST_CHECK (general_tree_test (tree, (PTreeType) i, true, false) == true); + + memset (&tree_data, 0, sizeof (tree_data)); + p_tree_free (tree); + + P_TEST_CHECK (check_tree_data_is_zero () == true); + + /* Test 3 */ + tree = p_tree_new_full ((PTreeType) i, + (PCompareDataFunc) compare_keys_data, + &tree_data, + (PDestroyFunc) key_destroy_notify, + (PDestroyFunc) value_destroy_notify); + P_TEST_CHECK (general_tree_test (tree, (PTreeType) i, true, true) == true); + + memset (&tree_data, 0, sizeof (tree_data)); + p_tree_free (tree); + + P_TEST_CHECK (check_tree_data_is_zero () == true); + } + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (ptree_stress_test) +{ + PTree *tree; + + p_libsys_init (); + + for (int i = (int) P_TREE_TYPE_BINARY; i <= (int) P_TREE_TYPE_AVL; ++i) { + tree = p_tree_new_full ((PTreeType) i, + (PCompareDataFunc) compare_keys_data, + &tree_data, + (PDestroyFunc) key_destroy_notify, + (PDestroyFunc) value_destroy_notify); + + for (int j = 0; j < PTREE_STRESS_ITERATIONS; ++j) + P_TEST_CHECK (stress_tree_test (tree, PTREE_STRESS_NODES) == true); + + p_tree_free (tree); + } + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (ptree_nomem_test); + P_TEST_SUITE_RUN_CASE (ptree_invalid_test); + P_TEST_SUITE_RUN_CASE (ptree_general_test); + P_TEST_SUITE_RUN_CASE (ptree_stress_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/ptypes_test.cpp b/3rdparty/plibsys/tests/ptypes_test.cpp new file mode 100644 index 0000000..1e9c0e9 --- /dev/null +++ b/3rdparty/plibsys/tests/ptypes_test.cpp @@ -0,0 +1,456 @@ +/* + * The MIT License + * + * Copyright (C) 2014-2017 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +P_TEST_MODULE_INIT (); + +P_TEST_CASE_BEGIN (ptypes_general_test) +{ + p_libsys_init (); + + P_TEST_CHECK (P_BYTE_ORDER == P_LITTLE_ENDIAN || + P_BYTE_ORDER == P_BIG_ENDIAN); + + P_TEST_CHECK (sizeof (pint8) == 1); + P_TEST_CHECK (sizeof (puint8) == 1); + P_TEST_CHECK (sizeof (pint16) == 2); + P_TEST_CHECK (sizeof (puint16) == 2); + P_TEST_CHECK (sizeof (pint32) == 4); + P_TEST_CHECK (sizeof (puint32) == 4); + P_TEST_CHECK (sizeof (pint64) == 8); + P_TEST_CHECK (sizeof (puint64) == 8); + P_TEST_CHECK (sizeof (void *) == sizeof (ppointer)); + P_TEST_CHECK (sizeof (const void *) == sizeof (pconstpointer)); + P_TEST_CHECK (sizeof (int) == sizeof (pboolean)); + P_TEST_CHECK (sizeof (char) == sizeof (pchar)); + P_TEST_CHECK (sizeof (short) == sizeof (pshort)); + P_TEST_CHECK (sizeof (int) == sizeof (pint)); + P_TEST_CHECK (sizeof (long) == sizeof (plong)); + P_TEST_CHECK (sizeof (unsigned char) == sizeof (puchar)); + P_TEST_CHECK (sizeof (unsigned short) == sizeof (pushort)); + P_TEST_CHECK (sizeof (unsigned int) == sizeof (puint)); + P_TEST_CHECK (sizeof (unsigned long) == sizeof (pulong)); + P_TEST_CHECK (sizeof (float) == sizeof (pfloat)); + P_TEST_CHECK (sizeof (double) == sizeof (pdouble)); + P_TEST_CHECK (sizeof (pintptr) == PLIBSYS_SIZEOF_VOID_P); + P_TEST_CHECK (sizeof (puintptr) == PLIBSYS_SIZEOF_VOID_P); + P_TEST_CHECK (sizeof (psize) == PLIBSYS_SIZEOF_SIZE_T); + P_TEST_CHECK (sizeof (pssize) == PLIBSYS_SIZEOF_SIZE_T); + P_TEST_CHECK (sizeof (plong) == PLIBSYS_SIZEOF_LONG); + P_TEST_CHECK (sizeof (pulong) == PLIBSYS_SIZEOF_LONG); + P_TEST_CHECK (sizeof (poffset) == 8); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (ptypes_pointers_convert_test) +{ + p_libsys_init (); + + ppointer pointer = P_INT_TO_POINTER (128); + P_TEST_CHECK (P_POINTER_TO_INT (pointer) == 128); + + pint pint_val = -64; + pointer = PINT_TO_POINTER (pint_val); + P_TEST_CHECK (PPOINTER_TO_INT (pointer) == -64); + + puint puint_val = 64; + pointer = PUINT_TO_POINTER (puint_val); + P_TEST_CHECK (PPOINTER_TO_UINT (pointer) == 64); + + psize psize_val = 1024; + pointer = PSIZE_TO_POINTER (psize_val); + P_TEST_CHECK (PPOINTER_TO_PSIZE (psize_val) == 1024); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (ptypes_min_max_test) +{ + p_libsys_init (); + + P_TEST_CHECK (P_MININT8 == (pint8) 0x80); + P_TEST_CHECK (P_MAXINT8 == (pint8) 0x7F); + P_TEST_CHECK (P_MAXUINT8 == (puint8) 0xFF); + P_TEST_CHECK (P_MININT16 == (pint16) 0x8000); + P_TEST_CHECK (P_MAXINT16 == (pint16) 0x7FFF); + P_TEST_CHECK (P_MAXUINT16 == (puint16) 0xFFFF); + P_TEST_CHECK (P_MININT32 == (pint32) 0x80000000); + P_TEST_CHECK (P_MAXINT32 == (pint32) 0x7FFFFFFF); + P_TEST_CHECK (P_MAXUINT32 == (puint32) 0xFFFFFFFF); + P_TEST_CHECK (P_MININT64 == (pint64) 0x8000000000000000LL); + P_TEST_CHECK (P_MAXINT64 == (pint64) 0x7FFFFFFFFFFFFFFFLL); + P_TEST_CHECK (P_MAXUINT64 == (puint64) 0xFFFFFFFFFFFFFFFFULL); + + if (PLIBSYS_SIZEOF_SIZE_T == 8) { + P_TEST_CHECK (P_MINSSIZE == P_MININT64); + P_TEST_CHECK (P_MAXSSIZE == P_MAXINT64); + P_TEST_CHECK (P_MAXSIZE == P_MAXUINT64); + + if (PLIBSYS_SIZEOF_LONG == 8) { + P_TEST_CHECK (P_MINSSIZE == P_MINLONG); + P_TEST_CHECK (P_MAXSSIZE == P_MAXLONG); + P_TEST_CHECK (P_MAXSIZE == P_MAXULONG); + } + } else { + P_TEST_CHECK (P_MINSSIZE == P_MININT32); + P_TEST_CHECK (P_MAXSSIZE == P_MAXINT32); + P_TEST_CHECK (P_MAXSIZE == P_MAXUINT32); + + if (PLIBSYS_SIZEOF_LONG == 4) { + P_TEST_CHECK (P_MINSSIZE == P_MINLONG); + P_TEST_CHECK (P_MAXSSIZE == P_MAXLONG); + P_TEST_CHECK (P_MAXSIZE == P_MAXULONG); + } + } + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (ptypes_modifiers_test) +{ + p_libsys_init (); + + psize size_val = 256; + printf ("%#" PSIZE_MODIFIER "x\n", size_val); + pssize ssize_val = -256; + printf ("%#" PSIZE_MODIFIER "x\n", ssize_val); + + puintptr puintptr_val = 512; + printf ("%#" PINTPTR_MODIFIER "x\n", puintptr_val); + pintptr pintptr_val = -512; + printf ("%#" PINTPTR_MODIFIER "x\n", pintptr_val); + + puint16 puint16_val = 1024; + printf ("%#" PINT16_MODIFIER "x\n", puint16_val); + pint16 pint16_val = -1024; + printf ("%#" PINT16_MODIFIER "x\n", pint16_val); + + puint32 puint32_val = 2048; + printf ("%#" PINT32_MODIFIER "x\n", puint32_val); + pint32 pint32_val = -2048; + printf ("%#" PINT32_MODIFIER "x\n", pint32_val); + + puint64 puint64_val = 4096; + printf ("%#" PINT64_MODIFIER "x\n", puint64_val); + pint64 pint64_val = -4096; + printf ("%#" PINT64_MODIFIER "x\n", pint64_val); + + poffset poffset_val = 8192; + printf ("%#" POFFSET_MODIFIER "x\n", poffset_val); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (ptypes_formats_test) +{ + p_libsys_init (); + + pssize ssize_val = -256; + printf ("%" PSSIZE_FORMAT "\n", ssize_val); + psize size_val = 256; + printf ("%" PSIZE_FORMAT "\n", size_val); + + puintptr puintptr_val = 512; + printf ("%" PUINTPTR_FORMAT "\n", puintptr_val); + pintptr pintptr_val = -512; + printf ("%" PINTPTR_FORMAT "\n", pintptr_val); + + puint16 puint16_val = 1024; + printf ("%" PUINT16_FORMAT "\n", puint16_val); + pint16 pint16_val = -1024; + printf ("%" PINT16_FORMAT "\n", pint16_val); + + puint32 puint32_val = 2048; + printf ("%" PUINT32_FORMAT "\n", puint32_val); + pint32 pint32_val = -2048; + printf ("%" PINT32_FORMAT "\n", pint32_val); + + puint64 puint64_val = 4096; + printf ("%" PUINT64_FORMAT "\n", puint64_val); + pint64 pint64_val = -4096; + printf ("%" PINT64_FORMAT "\n", pint64_val); + + poffset poffset_val = 8192; + printf ("%" POFFSET_FORMAT "\n", poffset_val); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (ptypes_host_network_test) +{ + p_libsys_init (); + + if (P_BYTE_ORDER == P_LITTLE_ENDIAN) { + pint16 pint16_val = PINT16_TO_BE (0xFFE0); + P_TEST_CHECK (pint16_val == (pint16) 0xE0FF); + P_TEST_CHECK (PINT16_FROM_BE (pint16_val) == (pint16) 0xFFE0); + P_TEST_CHECK (PINT16_TO_LE (pint16_val) == (pint16) 0xE0FF); + P_TEST_CHECK (PINT16_FROM_LE (pint16_val) == (pint16) 0xE0FF); + + puint16 puint16_val = PUINT16_TO_BE (0x0020); + P_TEST_CHECK (puint16_val == (puint16) 0x2000); + P_TEST_CHECK (PUINT16_FROM_BE (puint16_val) == (puint16) 0x0020); + P_TEST_CHECK (PUINT16_TO_LE (puint16_val) == (puint16) 0x2000); + P_TEST_CHECK (PUINT16_FROM_LE (puint16_val) == (puint16) 0x2000); + + pint32 pint32_val = PINT32_TO_BE (0xFFFFFFC0); + P_TEST_CHECK (pint32_val == (pint32) 0xC0FFFFFF); + P_TEST_CHECK (PINT32_FROM_BE (pint32_val) == (pint32) 0xFFFFFFC0); + P_TEST_CHECK (PINT32_TO_LE (pint32_val) == (pint32) 0xC0FFFFFF); + P_TEST_CHECK (PINT32_FROM_LE (pint32_val) == (pint32) 0xC0FFFFFF); + + puint32 puint32_val = PUINT32_TO_BE (0x00000040); + P_TEST_CHECK (puint32_val == (puint32) 0x40000000); + P_TEST_CHECK (PUINT32_FROM_BE (puint32_val) == (puint32) 0x00000040); + P_TEST_CHECK (PUINT32_TO_LE (puint32_val) == (puint32) 0x40000000); + P_TEST_CHECK (PUINT32_FROM_LE (puint32_val) == (puint32) 0x40000000); + + pint64 pint64_val = PINT64_TO_BE (0xFFFFFFFFFFFFFF80LL); + P_TEST_CHECK (pint64_val == (pint64) 0x80FFFFFFFFFFFFFFLL); + P_TEST_CHECK (PINT64_FROM_BE (pint64_val) == (pint64) 0xFFFFFFFFFFFFFF80LL); + P_TEST_CHECK (PINT64_TO_LE (pint64_val) == (pint64) 0x80FFFFFFFFFFFFFFLL); + P_TEST_CHECK (PINT64_FROM_LE (pint64_val) == (pint64) 0x80FFFFFFFFFFFFFFLL); + + puint64 puint64_val = PUINT64_TO_BE (0x0000000000000080ULL); + P_TEST_CHECK (puint64_val == (puint64) 0x8000000000000000ULL); + P_TEST_CHECK (PUINT64_FROM_BE (puint64_val) == (puint64) 0x0000000000000080ULL); + P_TEST_CHECK (PUINT64_TO_LE (puint64_val) == (puint64) 0x8000000000000000ULL); + P_TEST_CHECK (PUINT64_FROM_LE (puint64_val) == (puint64) 0x8000000000000000ULL); + + pint pint_val = PINT_TO_BE (0xFFFFFC00); + P_TEST_CHECK (pint_val == (pint) 0x00FCFFFF); + P_TEST_CHECK (PINT_FROM_BE (pint_val) == (pint) 0xFFFFFC00); + P_TEST_CHECK (PINT_TO_LE (pint_val) == (pint) 0x00FCFFFF); + P_TEST_CHECK (PINT_FROM_LE (pint_val) == (pint) 0x00FCFFFF); + + puint puint_val = PUINT_TO_BE (0x00000400); + P_TEST_CHECK (puint_val == (puint) 0x00040000); + P_TEST_CHECK (PUINT_FROM_BE (puint_val) == (puint) 0x00000400); + P_TEST_CHECK (PUINT_TO_LE (puint_val) == (puint) 0x00040000); + P_TEST_CHECK (PUINT_FROM_LE (puint_val) == (puint) 0x00040000); + + if (PLIBSYS_SIZEOF_LONG == 8) { + plong plong_val = PLONG_TO_BE (0xFFFFFFFFFFFFF800LL); + P_TEST_CHECK (plong_val == (plong) 0x00F8FFFFFFFFFFFFLL); + P_TEST_CHECK (PLONG_FROM_BE (plong_val) == (plong) 0xFFFFFFFFFFFFF800LL); + P_TEST_CHECK (PLONG_TO_LE (plong_val) == (plong) 0x00F8FFFFFFFFFFFFLL); + P_TEST_CHECK (PLONG_FROM_LE (plong_val) == (plong) 0x00F8FFFFFFFFFFFFLL); + + pulong pulong_val = PULONG_TO_BE (0x0000000000000800ULL); + P_TEST_CHECK (pulong_val == (pulong) 0x0008000000000000ULL); + P_TEST_CHECK (PULONG_FROM_BE (pulong_val) == (pulong) 0x0000000000000800ULL); + P_TEST_CHECK (PULONG_TO_LE (pulong_val) == (pulong) 0x0008000000000000ULL); + P_TEST_CHECK (PULONG_FROM_LE (pulong_val) == (pulong) 0x0008000000000000ULL); + } else { + plong plong_val = PLONG_TO_BE (0xFFFFF800); + P_TEST_CHECK (plong_val == (plong) 0x00F8FFFF); + P_TEST_CHECK (PLONG_FROM_BE (plong_val) == (plong) 0xFFFFF800); + P_TEST_CHECK (PLONG_TO_LE (plong_val) == (plong) 0x00F8FFFF); + P_TEST_CHECK (PLONG_FROM_LE (plong_val) == (plong) 0x00F8FFFF); + + pulong pulong_val = PULONG_TO_BE (0x00000800); + P_TEST_CHECK (pulong_val == (pulong) 0x00080000); + P_TEST_CHECK (PULONG_FROM_BE (pulong_val) == (pulong) 0x00000800); + P_TEST_CHECK (PULONG_TO_LE (pulong_val) == (pulong) 0x00080000); + P_TEST_CHECK (PULONG_FROM_LE (pulong_val) == (pulong) 0x00080000); + } + + if (PLIBSYS_SIZEOF_SIZE_T == 8) { + psize psize_val = PSIZE_TO_BE (0x0000000000001000ULL); + P_TEST_CHECK (psize_val == (psize) 0x0010000000000000ULL); + P_TEST_CHECK (PSIZE_FROM_BE (psize_val) == (psize) 0x0000000000001000ULL); + P_TEST_CHECK (PSIZE_TO_LE (psize_val) == (psize) 0x0010000000000000ULL); + P_TEST_CHECK (PSIZE_FROM_LE (psize_val) == (psize) 0x0010000000000000ULL); + + pssize pssize_val = PSSIZE_TO_BE (0x000000000000F000LL); + P_TEST_CHECK (pssize_val == (pssize) 0x00F0000000000000LL); + P_TEST_CHECK (PSSIZE_FROM_BE (pssize_val) == (pssize) 0x000000000000F000LL); + P_TEST_CHECK (PSSIZE_TO_LE (pssize_val) == (pssize) 0x00F0000000000000LL); + P_TEST_CHECK (PSSIZE_FROM_LE (pssize_val) == (pssize) 0x00F0000000000000LL); + } else { + psize psize_val = PSIZE_TO_BE (0x00001000); + P_TEST_CHECK (psize_val == (psize) 0x00100000); + P_TEST_CHECK (PSIZE_FROM_BE (psize_val) == (psize) 0x00001000); + P_TEST_CHECK (PSIZE_TO_LE (psize_val) == (psize) 0x00100000); + P_TEST_CHECK (PSIZE_FROM_LE (psize_val) == (psize) 0x00100000); + + pssize pssize_val = PSSIZE_TO_BE (0x0000F000); + P_TEST_CHECK (pssize_val == (pssize) 0x00F00000); + P_TEST_CHECK (PSSIZE_FROM_BE (pssize_val) == (pssize) 0x0000F000); + P_TEST_CHECK (PSSIZE_TO_LE (pssize_val) == (pssize) 0x00F00000); + P_TEST_CHECK (PSSIZE_FROM_LE (pssize_val) == (pssize) 0x00F00000); + } + + puint16_val = p_htons (0x0020); + P_TEST_CHECK (puint16_val == (puint16) 0x2000); + P_TEST_CHECK (p_ntohs (puint16_val) == (puint16) 0x0020); + + puint32_val = p_htonl (0x00000040); + P_TEST_CHECK (puint32_val == (puint32) 0x40000000); + P_TEST_CHECK (p_ntohl (puint32_val) == (puint32) 0x00000040); + } else { + pint16 pint16_val = PINT16_TO_LE (0xFFE0); + P_TEST_CHECK (pint16_val == (pint16) 0xE0FF); + P_TEST_CHECK (PINT16_FROM_LE (pint16_val) == (pint16) 0xFFE0); + P_TEST_CHECK (PINT16_TO_BE (pint16_val) == (pint16) 0xE0FF); + P_TEST_CHECK (PINT16_FROM_BE (pint16_val) == (pint16) 0xE0FF); + + puint16 puint16_val = PUINT16_TO_LE (0x0020); + P_TEST_CHECK (puint16_val == (puint16) 0x2000); + P_TEST_CHECK (PUINT16_FROM_LE (puint16_val) == (puint16) 0x0020); + P_TEST_CHECK (PUINT16_TO_BE (puint16_val) == (puint16) 0x2000); + P_TEST_CHECK (PUINT16_FROM_BE (puint16_val) == (puint16) 0x2000); + + pint32 pint32_val = PINT32_TO_LE (0xFFFFFFC0); + P_TEST_CHECK (pint32_val == (pint32) 0xC0FFFFFF); + P_TEST_CHECK (PINT32_FROM_LE (pint32_val) == (pint32) 0xFFFFFFC0); + P_TEST_CHECK (PINT32_TO_BE (pint32_val) == (pint32) 0xC0FFFFFF); + P_TEST_CHECK (PINT32_FROM_BE (pint32_val) == (pint32) 0xC0FFFFFF); + + puint32 puint32_val = PUINT32_TO_LE (0x00000040); + P_TEST_CHECK (puint32_val == (puint32) 0x40000000); + P_TEST_CHECK (PUINT32_FROM_LE (puint32_val) == (puint32) 0x00000040); + P_TEST_CHECK (PUINT32_TO_BE (puint32_val) == (puint32) 0x40000000); + P_TEST_CHECK (PUINT32_FROM_BE (puint32_val) == (puint32) 0x40000000); + + pint64 pint64_val = PINT64_TO_LE (0xFFFFFFFFFFFFFF80LL); + P_TEST_CHECK (pint64_val == (pint64) 0x80FFFFFFFFFFFFFFLL); + P_TEST_CHECK (PINT64_FROM_LE (pint64_val) == (pint64) 0xFFFFFFFFFFFFFF80LL); + P_TEST_CHECK (PINT64_TO_BE (pint64_val) == (pint64) 0x80FFFFFFFFFFFFFFLL); + P_TEST_CHECK (PINT64_FROM_BE (pint64_val) == (pint64) 0x80FFFFFFFFFFFFFFLL); + + puint64 puint64_val = PUINT64_TO_LE (0x0000000000000080ULL); + P_TEST_CHECK (puint64_val == (puint64) 0x8000000000000000ULL); + P_TEST_CHECK (PUINT64_FROM_LE (puint64_val) == (puint64) 0x0000000000000080ULL); + P_TEST_CHECK (PUINT64_TO_BE (puint64_val) == (puint64) 0x8000000000000000ULL); + P_TEST_CHECK (PUINT64_FROM_BE (puint64_val) == (puint64) 0x8000000000000000ULL); + + pint pint_val = PINT_TO_LE (0xFFFFFC00); + P_TEST_CHECK (pint_val == (pint) 0x00FCFFFF); + P_TEST_CHECK (PINT_FROM_LE (pint_val) == (pint) 0xFFFFFC00); + P_TEST_CHECK (PINT_TO_BE (pint_val) == (pint) 0x00FCFFFF); + P_TEST_CHECK (PINT_FROM_BE (pint_val) == (pint) 0x00FCFFFF); + + puint puint_val = PUINT_TO_LE (0x00000400); + P_TEST_CHECK (puint_val == (puint) 0x00040000); + P_TEST_CHECK (PUINT_FROM_LE (puint_val) == (puint) 0x00000400); + P_TEST_CHECK (PUINT_TO_BE (puint_val) == (puint) 0x00040000); + P_TEST_CHECK (PUINT_FROM_BE (puint_val) == (puint) 0x00040000); + + if (PLIBSYS_SIZEOF_LONG == 8) { + plong plong_val = PLONG_TO_LE (0xFFFFFFFFFFFFF800LL); + P_TEST_CHECK (plong_val == (plong) 0x00F8FFFFFFFFFFFFLL); + P_TEST_CHECK (PLONG_FROM_LE (plong_val) == (plong) 0xFFFFFFFFFFFFF800LL); + P_TEST_CHECK (PLONG_TO_BE (plong_val) == (plong) 0x00F8FFFFFFFFFFFFLL); + P_TEST_CHECK (PLONG_FROM_BE (plong_val) == (plong) 0x00F8FFFFFFFFFFFFLL); + + pulong pulong_val = PULONG_TO_LE (0x0000000000000800ULL); + P_TEST_CHECK (pulong_val == (pulong) 0x0008000000000000ULL); + P_TEST_CHECK (PULONG_FROM_LE (pulong_val) == (pulong) 0x0000000000000800ULL); + P_TEST_CHECK (PULONG_TO_BE (pulong_val) == (pulong) 0x0008000000000000ULL); + P_TEST_CHECK (PULONG_FROM_BE (pulong_val) == (pulong) 0x0008000000000000ULL); + } else { + plong plong_val = PLONG_TO_LE (0xFFFFF800); + P_TEST_CHECK (plong_val == (plong) 0x00F8FFFF); + P_TEST_CHECK (PLONG_FROM_LE (plong_val) == (plong) 0xFFFFF800); + P_TEST_CHECK (PLONG_TO_BE (plong_val) == (plong) 0x00F8FFFF); + P_TEST_CHECK (PLONG_FROM_BE (plong_val) == (plong) 0x00F8FFFF); + + pulong pulong_val = PULONG_TO_LE (0x00000800); + P_TEST_CHECK (pulong_val == (pulong) 0x00080000); + P_TEST_CHECK (PULONG_FROM_LE (pulong_val) == (pulong) 0x00000800); + P_TEST_CHECK (PULONG_TO_BE (pulong_val) == (pulong) 0x00080000); + P_TEST_CHECK (PULONG_FROM_BE (pulong_val) == (pulong) 0x00080000); + } + + if (PLIBSYS_SIZEOF_SIZE_T == 8) { + psize psize_val = PSIZE_TO_LE (0x0000000000001000ULL); + P_TEST_CHECK (psize_val == (psize) 0x0010000000000000ULL); + P_TEST_CHECK (PSIZE_FROM_LE (psize_val) == (psize) 0x0000000000001000ULL); + P_TEST_CHECK (PSIZE_TO_BE (psize_val) == (psize) 0x0010000000000000ULL); + P_TEST_CHECK (PSIZE_FROM_BE (psize_val) == (psize) 0x0010000000000000ULL); + + pssize pssize_val = PSSIZE_TO_LE (0x000000000000F000LL); + P_TEST_CHECK (pssize_val == (pssize) 0x00F0000000000000LL); + P_TEST_CHECK (PSSIZE_FROM_LE (pssize_val) == (pssize) 0x000000000000F000LL); + P_TEST_CHECK (PSSIZE_TO_BE (pssize_val) == (pssize) 0x00F0000000000000LL); + P_TEST_CHECK (PSSIZE_FROM_BE (pssize_val) == (pssize) 0x00F0000000000000LL); + } else { + psize psize_val = PSIZE_TO_LE (0x00001000); + P_TEST_CHECK (psize_val == (psize) 0x00100000); + P_TEST_CHECK (PSIZE_FROM_LE (psize_val) == (psize) 0x00001000); + P_TEST_CHECK (PSIZE_TO_BE (psize_val) == (psize) 0x00100000); + P_TEST_CHECK (PSIZE_FROM_BE (psize_val) == (psize) 0x00100000); + + pssize pssize_val = PSSIZE_TO_LE (0x0000F000); + P_TEST_CHECK (pssize_val == (pssize) 0x00F00000); + P_TEST_CHECK (PSSIZE_FROM_LE (pssize_val) == (pssize) 0x0000F000); + P_TEST_CHECK (PSSIZE_TO_BE (pssize_val) == (pssize) 0x00F00000); + P_TEST_CHECK (PSSIZE_FROM_BE (pssize_val) == (pssize) 0x00F00000); + } + + puint16_val = p_htons (0x0020); + P_TEST_CHECK (puint16_val == (puint16) 0x0020); + P_TEST_CHECK (p_ntohs (puint16_val) == (puint16) 0x0020); + + puint32_val = p_htonl (0x00000040); + P_TEST_CHECK (puint32_val == (puint32) 0x00000040); + P_TEST_CHECK (p_ntohl (puint32_val) == (puint32) 0x00000040); + } + + puint16 puint16_val = PUINT16_SWAP_BYTES (0x0020); + P_TEST_CHECK (puint16_val == (puint16) 0x2000); + P_TEST_CHECK (PUINT16_SWAP_BYTES (puint16_val) == (puint16) 0x0020); + + puint32 puint32_val = PUINT32_SWAP_BYTES (0x00000040); + P_TEST_CHECK (puint32_val == (puint32) 0x40000000); + P_TEST_CHECK (PUINT32_SWAP_BYTES (puint32_val) == (puint32) 0x00000040); + + puint64 puint64_val = PUINT64_SWAP_BYTES (0x0000000000000080ULL); + P_TEST_CHECK (puint64_val == (puint64) 0x8000000000000000ULL); + P_TEST_CHECK (PUINT64_SWAP_BYTES (puint64_val) == (puint64) 0x0000000000000080ULL); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (ptypes_general_test); + P_TEST_SUITE_RUN_CASE (ptypes_pointers_convert_test); + P_TEST_SUITE_RUN_CASE (ptypes_min_max_test); + P_TEST_SUITE_RUN_CASE (ptypes_modifiers_test); + P_TEST_SUITE_RUN_CASE (ptypes_formats_test); + P_TEST_SUITE_RUN_CASE (ptypes_host_network_test); +} +P_TEST_SUITE_END() diff --git a/3rdparty/plibsys/tests/puthread_test.cpp b/3rdparty/plibsys/tests/puthread_test.cpp new file mode 100644 index 0000000..5c31cd1 --- /dev/null +++ b/3rdparty/plibsys/tests/puthread_test.cpp @@ -0,0 +1,481 @@ +/* + * The MIT License + * + * Copyright (C) 2013-2019 Alexander Saprykin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "plibsys.h" +#include "ptestmacros.h" + +P_TEST_MODULE_INIT (); + +static pint thread_wakes_1 = 0; +static pint thread_wakes_2 = 0; +static pint thread_to_wakes = 0; +static volatile pboolean is_threads_working = FALSE; + +static P_HANDLE thread1_id = (P_HANDLE) NULL; +static P_HANDLE thread2_id = (P_HANDLE) NULL; +static PUThread * thread1_obj = NULL; +static PUThread * thread2_obj = NULL; + +static PUThreadKey * tls_key = NULL; +static PUThreadKey * tls_key_2 = NULL; +static volatile pint free_counter = 0; + +extern "C" ppointer pmem_alloc (psize nbytes) +{ + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" ppointer pmem_realloc (ppointer block, psize nbytes) +{ + P_UNUSED (block); + P_UNUSED (nbytes); + return (ppointer) NULL; +} + +extern "C" void pmem_free (ppointer block) +{ + P_UNUSED (block); +} + +extern "C" void free_with_check (ppointer mem) +{ + p_free (mem); + p_atomic_int_inc (&free_counter); +} + +static void * test_thread_func (void *data) +{ + pint *counter = static_cast < pint * > (data); + + if ((*counter) == 1) { + thread1_id = p_uthread_current_id (); + thread1_obj = p_uthread_current (); + } else { + thread2_id = p_uthread_current_id (); + thread2_obj = p_uthread_current (); + } + + p_uthread_set_local (tls_key, (ppointer) p_uthread_current_id ()); + + *counter = 0; + + while (is_threads_working == TRUE) { + p_uthread_sleep (10); + ++(*counter); + p_uthread_yield (); + + if (p_uthread_get_local (tls_key) != (ppointer) p_uthread_current_id ()) + p_uthread_exit (-1); + } + + p_uthread_exit (*counter); + + return NULL; +} + +static void * test_thread_nonjoinable_func (void *data) +{ + pint *counter = static_cast < pint * > (data); + + is_threads_working = TRUE; + + for (int i = thread_to_wakes; i > 0; --i) { + p_uthread_sleep (10); + ++(*counter); + p_uthread_yield (); + } + + is_threads_working = FALSE; + + p_uthread_exit (0); + + return NULL; +} + +static void * test_thread_tls_func (void *data) +{ + pint self_thread_free = *((pint *) data); + + pint *tls_value = (pint *) p_malloc0 (sizeof (pint)); + *tls_value = 0; + p_uthread_set_local (tls_key, (ppointer) tls_value); + + pint prev_tls = 0; + pint counter = 0; + + while (is_threads_working == TRUE) { + p_uthread_sleep (10); + + pint *last_tls = (pint *) p_uthread_get_local (tls_key); + + if ((*last_tls) != prev_tls) + p_uthread_exit (-1); + + pint *tls_new_value = (pint *) p_malloc0 (sizeof (pint)); + + *tls_new_value = (*last_tls) + 1; + prev_tls = (*last_tls) + 1; + + p_uthread_replace_local (tls_key, (ppointer) tls_new_value); + + if (self_thread_free) + p_free (last_tls); + + ++counter; + + p_uthread_yield (); + } + + if (self_thread_free) { + pint *last_tls = (pint *) p_uthread_get_local (tls_key); + + if ((*last_tls) != prev_tls) + p_uthread_exit (-1); + + p_free (last_tls); + + p_uthread_replace_local (tls_key, (ppointer) NULL); + } + + p_uthread_exit (counter); + + return NULL; +} + +static void * test_thread_tls_create_func (void *data) +{ + P_UNUSED (data); + + pint *tls_value = (pint *) p_malloc0 (sizeof (pint)); + *tls_value = 0; + p_uthread_set_local (tls_key, (ppointer) tls_value); + + pint *tls_value_2 = (pint *) p_malloc0 (sizeof (pint)); + *tls_value_2 = 0; + p_uthread_set_local (tls_key_2, (ppointer) tls_value_2); + + return NULL; +} + +P_TEST_CASE_BEGIN (puthread_nomem_test) +{ + p_libsys_init (); + + PUThreadKey *thread_key = p_uthread_local_new (p_free); + P_TEST_CHECK (thread_key != NULL); + + PMemVTable vtable; + + vtable.free = pmem_free; + vtable.malloc = pmem_alloc; + vtable.realloc = pmem_realloc; + + P_TEST_CHECK (p_mem_set_vtable (&vtable) == TRUE); + + thread_wakes_1 = 0; + thread_wakes_2 = 0; + + P_TEST_CHECK (p_uthread_create ((PUThreadFunc) test_thread_func, + (ppointer) &thread_wakes_1, + TRUE, + NULL) == NULL); + + P_TEST_CHECK (p_uthread_create_full ((PUThreadFunc) test_thread_func, + (ppointer) &thread_wakes_2, + TRUE, + P_UTHREAD_PRIORITY_NORMAL, + 0, + NULL) == NULL); + + P_TEST_CHECK (p_uthread_current () == NULL); + P_TEST_CHECK (p_uthread_local_new (NULL) == NULL); + + p_uthread_exit (0); + + p_uthread_set_local (thread_key, PINT_TO_POINTER (10)); + + ppointer tls_value = p_uthread_get_local (thread_key); + + if (tls_value != NULL) { + P_TEST_CHECK (tls_value == PINT_TO_POINTER (10)); + p_uthread_set_local (thread_key, NULL); + } + + p_uthread_replace_local (thread_key, PINT_TO_POINTER (12)); + + tls_value = p_uthread_get_local (thread_key); + + if (tls_value != NULL) { + P_TEST_CHECK (tls_value == PINT_TO_POINTER (12)); + p_uthread_set_local (thread_key, NULL); + } + + p_mem_restore_vtable (); + + p_uthread_local_free (thread_key); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (puthread_bad_input_test) +{ + p_libsys_init (); + + P_TEST_CHECK (p_uthread_create (NULL, NULL, FALSE, NULL) == NULL); + P_TEST_CHECK (p_uthread_create_full (NULL, NULL, FALSE, P_UTHREAD_PRIORITY_NORMAL, 0, NULL) == NULL); + P_TEST_CHECK (p_uthread_join (NULL) == -1); + P_TEST_CHECK (p_uthread_set_priority (NULL, P_UTHREAD_PRIORITY_NORMAL) == FALSE); + P_TEST_CHECK (p_uthread_get_local (NULL) == NULL); + p_uthread_set_local (NULL, NULL); + p_uthread_replace_local (NULL, NULL); + p_uthread_ref (NULL); + p_uthread_unref (NULL); + p_uthread_local_free (NULL); + p_uthread_exit (0); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (puthread_general_test) +{ + p_libsys_init (); + + thread_wakes_1 = 1; + thread_wakes_2 = 2; + thread1_id = (P_HANDLE) NULL; + thread2_id = (P_HANDLE) NULL; + thread1_obj = NULL; + thread2_obj = NULL; + + tls_key = p_uthread_local_new (NULL); + P_TEST_CHECK (tls_key != NULL); + + /* Threre is no guarantee that we wouldn't get one of the IDs + * of the finished test threads */ + + P_HANDLE main_id = p_uthread_current_id (); + + is_threads_working = TRUE; + + PUThread *thr1 = p_uthread_create_full ((PUThreadFunc) test_thread_func, + (ppointer) &thread_wakes_1, + TRUE, + P_UTHREAD_PRIORITY_NORMAL, + 64 * 1024, + "thread_name"); + + PUThread *thr2 = p_uthread_create_full ((PUThreadFunc) test_thread_func, + (ppointer) &thread_wakes_2, + TRUE, + P_UTHREAD_PRIORITY_NORMAL, + 64 * 1024, + "very_long_name_for_thread_testing"); + + p_uthread_ref (thr1); + + p_uthread_set_priority (thr1, P_UTHREAD_PRIORITY_NORMAL); + + P_TEST_REQUIRE (thr1 != NULL); + P_TEST_REQUIRE (thr2 != NULL); + + p_uthread_sleep (5000); + + is_threads_working = FALSE; + + P_TEST_CHECK (p_uthread_join (thr1) == thread_wakes_1); + P_TEST_CHECK (p_uthread_join (thr2) == thread_wakes_2); + + P_TEST_REQUIRE (thread1_id != thread2_id); + P_TEST_CHECK (thread1_id != main_id && thread2_id != main_id); + + P_TEST_CHECK (thread1_obj == thr1); + P_TEST_CHECK (thread2_obj == thr2); + + p_uthread_local_free (tls_key); + p_uthread_unref (thr1); + p_uthread_unref (thr2); + + p_uthread_unref (thr1); + + PUThread *cur_thr = p_uthread_current (); + P_TEST_CHECK (cur_thr != NULL); + + P_TEST_CHECK (p_uthread_ideal_count () > 0); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (puthread_nonjoinable_test) +{ + p_libsys_init (); + + thread_wakes_1 = 0; + thread_to_wakes = 100; + is_threads_working = TRUE; + + PUThread *thr1 = p_uthread_create ((PUThreadFunc) test_thread_nonjoinable_func, + (ppointer) &thread_wakes_1, + FALSE, + NULL); + + P_TEST_REQUIRE (thr1 != NULL); + + p_uthread_sleep (3000); + + P_TEST_CHECK (p_uthread_join (thr1) == -1); + + while (is_threads_working == TRUE) + p_uthread_sleep (10); + + P_TEST_CHECK (thread_wakes_1 == thread_to_wakes); + + p_uthread_unref (thr1); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_CASE_BEGIN (puthread_tls_test) +{ + p_libsys_init (); + + /* With destroy notification */ + tls_key = p_uthread_local_new (free_with_check); + + is_threads_working = TRUE; + free_counter = 0; + + pint self_thread_free = 0; + + PUThread *thr1 = p_uthread_create ((PUThreadFunc) test_thread_tls_func, + (ppointer) &self_thread_free, + TRUE, + NULL); + + PUThread *thr2 = p_uthread_create ((PUThreadFunc) test_thread_tls_func, + (ppointer) &self_thread_free, + TRUE, + NULL); + + P_TEST_REQUIRE (thr1 != NULL); + P_TEST_REQUIRE (thr2 != NULL); + + p_uthread_sleep (5000); + + is_threads_working = FALSE; + + pint total_counter = 0; + + total_counter += (p_uthread_join (thr1) + 1); + total_counter += (p_uthread_join (thr2) + 1); + + P_TEST_CHECK (total_counter == free_counter); + + p_uthread_local_free (tls_key); + p_uthread_unref (thr1); + p_uthread_unref (thr2); + + /* Without destroy notification */ + tls_key = p_uthread_local_new (NULL); + + free_counter = 0; + is_threads_working = TRUE; + self_thread_free = 1; + + thr1 = p_uthread_create ((PUThreadFunc) test_thread_tls_func, + (ppointer) &self_thread_free, + TRUE, + NULL); + + thr2 = p_uthread_create ((PUThreadFunc) test_thread_tls_func, + (ppointer) &self_thread_free, + TRUE, + NULL); + + P_TEST_REQUIRE (thr1 != NULL); + P_TEST_REQUIRE (thr2 != NULL); + + p_uthread_sleep (5000); + + is_threads_working = FALSE; + + total_counter = 0; + + total_counter += (p_uthread_join (thr1) + 1); + total_counter += (p_uthread_join (thr2) + 1); + + P_TEST_CHECK (total_counter > 0); + P_TEST_CHECK (free_counter == 0); + + p_uthread_local_free (tls_key); + p_uthread_unref (thr1); + p_uthread_unref (thr2); + + /* With implicit thread exit */ + tls_key = p_uthread_local_new (free_with_check); + tls_key_2 = p_uthread_local_new (free_with_check); + + free_counter = 0; + + thr1 = p_uthread_create ((PUThreadFunc) test_thread_tls_create_func, + NULL, + TRUE, + NULL); + + thr2 = p_uthread_create ((PUThreadFunc) test_thread_tls_create_func, + NULL, + TRUE, + NULL); + + P_TEST_REQUIRE (thr1 != NULL); + P_TEST_REQUIRE (thr2 != NULL); + + p_uthread_join (thr1); + p_uthread_join (thr2); + + P_TEST_CHECK (free_counter == 4); + + p_uthread_local_free (tls_key); + p_uthread_local_free (tls_key_2); + p_uthread_unref (thr1); + p_uthread_unref (thr2); + + p_libsys_shutdown (); +} +P_TEST_CASE_END () + +P_TEST_SUITE_BEGIN() +{ + P_TEST_SUITE_RUN_CASE (puthread_nomem_test); + P_TEST_SUITE_RUN_CASE (puthread_bad_input_test); + P_TEST_SUITE_RUN_CASE (puthread_general_test); + P_TEST_SUITE_RUN_CASE (puthread_nonjoinable_test); + P_TEST_SUITE_RUN_CASE (puthread_tls_test); +} +P_TEST_SUITE_END() -- cgit v1.2.1