From c12348ad384d0ba4896c32a03f121682969d7741 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 28 Mar 2017 07:31:49 -0600 Subject: [PATCH 1/5] examples/mm: Fix Makefile. Built-in was not being registered. --- examples/mm/Makefile | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/examples/mm/Makefile b/examples/mm/Makefile index 1a832863b..8bd21dad5 100644 --- a/examples/mm/Makefile +++ b/examples/mm/Makefile @@ -1,7 +1,7 @@ ############################################################################ # apps/examples/mm/Makefile # -# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. +# Copyright (C) 2011-2012, 2017 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -37,13 +37,20 @@ # Memory Management Test +CONFIG_EXAMPLES_MM_PRIORITY ?= SCHED_PRIORITY_DEFAULT +CONFIG_EXAMPLES_MM_STACKSIZE ?= 2048 + APPNAME = mm +PRIORITY = $(CONFIG_EXAMPLES_MM_PRIORITY) +STACKSIZE = $(CONFIG_EXAMPLES_MM_STACKSIZE) + +# Hello, World! Example ASRCS = CSRCS = MAINSRC = mm_main.c -CONFIG_XYZ_PROGNAME ?= mm$(EXEEXT) -PROGNAME = $(CONFIG_XYZ_PROGNAME) +CONFIG_EXAMPLES_MM_PROGNAME ?= mm$(EXEEXT) +PROGNAME = $(CONFIG_EXAMPLES_MM_PROGNAME) include $(APPDIR)/Application.mk From 2168119b73034d31586afd73b1a12afb540a629a Mon Sep 17 00:00:00 2001 From: David Sidrane Date: Tue, 28 Mar 2017 14:36:03 +0000 Subject: [PATCH 2/5] apps/mm removed extraneous comment from Makefile --- examples/mm/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/mm/Makefile b/examples/mm/Makefile index 8bd21dad5..a74edc7a2 100644 --- a/examples/mm/Makefile +++ b/examples/mm/Makefile @@ -44,8 +44,6 @@ APPNAME = mm PRIORITY = $(CONFIG_EXAMPLES_MM_PRIORITY) STACKSIZE = $(CONFIG_EXAMPLES_MM_STACKSIZE) -# Hello, World! Example - ASRCS = CSRCS = MAINSRC = mm_main.c From 3e2743e826b9680840400457857c8c6d5938069c Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Fri, 31 Mar 2017 09:01:49 -0600 Subject: [PATCH 3/5] nshlib: fix building when CONFIG_NET_USRSOCK enabled with other link-layer --- nshlib/nsh_netinit.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nshlib/nsh_netinit.c b/nshlib/nsh_netinit.c index f49a45120..407802f5f 100644 --- a/nshlib/nsh_netinit.c +++ b/nshlib/nsh_netinit.c @@ -120,6 +120,8 @@ #elif defined(CONFIG_NET_LOCAL) # define NET_DEVNAME "lo" # define NSH_HAVE_NETDEV +#elif defined(CONFIG_NET_USRSOCK) +# undef NSH_HAVE_NETDEV #elif !defined(CONFIG_NET_LOOPBACK) # error ERROR: No link layer protocol defined #endif From 87fe31f87a381761243dcf58e038b058d6c2c604 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Fri, 31 Mar 2017 09:10:28 -0600 Subject: [PATCH 4/5] Add Unity test framework with usrsock test-cases --- include/testing/license.txt | 21 + include/testing/unity.h | 272 +++ include/testing/unity_fixture.h | 98 + include/testing/unity_fixture_internals.h | 46 + .../testing/unity_fixture_malloc_overrides.h | 27 + include/testing/unity_internals.h | 693 ++++++ tests/Kconfig | 11 + tests/Make.defs | 37 + tests/Makefile | 114 + tests/README.txt | 34 + tests/docs/Unity_Summary.txt | 216 ++ tests/docs/license.txt | 21 + tests/testing/.built | 0 tests/testing/Kconfig | 4 + tests/testing/Make.defs | 37 + tests/testing/Makefile | 95 + tests/testing/unity.c | 1268 +++++++++++ tests/testing/unity_fixture.c | 466 ++++ tests/tools/auto/colour_prompt.rb | 115 + tests/tools/auto/colour_reporter.rb | 39 + tests/tools/auto/generate_config.yml | 36 + tests/tools/auto/generate_module.rb | 202 ++ tests/tools/auto/generate_test_runner.rb | 349 +++ tests/tools/auto/parseOutput.rb | 189 ++ tests/tools/auto/test_file_filter.rb | 23 + tests/tools/auto/type_sanitizer.rb | 8 + tests/tools/auto/unity_test_summary.py | 135 ++ tests/tools/auto/unity_test_summary.rb | 139 ++ tests/tools/build_fixture_runner.pl | 45 + tests/tools/license.txt | 21 + tests/tools/rename_symbols | 21 + tests/tools/unity_test_summary.rb | 139 ++ tests/unity/.gitignore | 11 + tests/unity/Kconfig | 22 + tests/unity/Make.defs | 39 + tests/unity/Makefile | 137 ++ tests/unity/main/AllTests.c | 30 + tests/unity/testunity_fixture.c | 39 + tests/unity/unity_fixture_Test.c | 454 ++++ tests/unity/unity_fixture_TestRunner.c | 64 + tests/unity/unity_output_Spy.c | 56 + tests/unity/unity_output_Spy.h | 17 + tests/unity_ramtest/.gitignore | 11 + tests/unity_ramtest/Kconfig | 11 + tests/unity_ramtest/Make.defs | 39 + tests/unity_ramtest/Makefile | 146 ++ tests/unity_ramtest/addr_in_addr.c | 185 ++ tests/unity_ramtest/library.h | 196 ++ tests/unity_ramtest/marching_ones.c | 191 ++ tests/unity_ramtest/marching_zeroes.c | 193 ++ tests/unity_ramtest/pattern.c | 311 +++ tests/unity_ramtest/unity_ramtest_main.c | 503 +++++ tests/unity_usrsock/.gitignore | 11 + tests/unity_usrsock/Kconfig | 15 + tests/unity_usrsock/Make.defs | 39 + tests/unity_usrsock/Makefile | 152 ++ tests/unity_usrsock/basic_connect.c | 465 ++++ tests/unity_usrsock/basic_daemon.c | 653 ++++++ tests/unity_usrsock/basic_getsockname.c | 279 +++ tests/unity_usrsock/basic_getsockopt.c | 258 +++ tests/unity_usrsock/basic_send.c | 345 +++ tests/unity_usrsock/basic_setsockopt.c | 226 ++ tests/unity_usrsock/block_recv.c | 497 +++++ tests/unity_usrsock/block_send.c | 428 ++++ tests/unity_usrsock/chardev.c | 222 ++ tests/unity_usrsock/defines.h | 124 ++ tests/unity_usrsock/multi_thread.c | 256 +++ tests/unity_usrsock/noblock_connect.c | 806 +++++++ tests/unity_usrsock/noblock_recv.c | 503 +++++ tests/unity_usrsock/noblock_send.c | 400 ++++ tests/unity_usrsock/nodaemon.c | 148 ++ tests/unity_usrsock/poll.c | 632 ++++++ tests/unity_usrsock/remote_disconnect.c | 1055 +++++++++ tests/unity_usrsock/unity_usrsock_main.c | 161 ++ tests/unity_usrsock/usrsocktest_daemon.c | 1930 +++++++++++++++++ tests/unity_usrsock/wake_with_signal.c | 1563 +++++++++++++ 76 files changed, 18744 insertions(+) create mode 100644 include/testing/license.txt create mode 100644 include/testing/unity.h create mode 100644 include/testing/unity_fixture.h create mode 100644 include/testing/unity_fixture_internals.h create mode 100644 include/testing/unity_fixture_malloc_overrides.h create mode 100644 include/testing/unity_internals.h create mode 100644 tests/Kconfig create mode 100644 tests/Make.defs create mode 100644 tests/Makefile create mode 100644 tests/README.txt create mode 100644 tests/docs/Unity_Summary.txt create mode 100644 tests/docs/license.txt create mode 100644 tests/testing/.built create mode 100644 tests/testing/Kconfig create mode 100644 tests/testing/Make.defs create mode 100644 tests/testing/Makefile create mode 100644 tests/testing/unity.c create mode 100644 tests/testing/unity_fixture.c create mode 100644 tests/tools/auto/colour_prompt.rb create mode 100644 tests/tools/auto/colour_reporter.rb create mode 100644 tests/tools/auto/generate_config.yml create mode 100644 tests/tools/auto/generate_module.rb create mode 100644 tests/tools/auto/generate_test_runner.rb create mode 100644 tests/tools/auto/parseOutput.rb create mode 100644 tests/tools/auto/test_file_filter.rb create mode 100644 tests/tools/auto/type_sanitizer.rb create mode 100644 tests/tools/auto/unity_test_summary.py create mode 100644 tests/tools/auto/unity_test_summary.rb create mode 100644 tests/tools/build_fixture_runner.pl create mode 100644 tests/tools/license.txt create mode 100644 tests/tools/rename_symbols create mode 100644 tests/tools/unity_test_summary.rb create mode 100644 tests/unity/.gitignore create mode 100644 tests/unity/Kconfig create mode 100644 tests/unity/Make.defs create mode 100644 tests/unity/Makefile create mode 100644 tests/unity/main/AllTests.c create mode 100644 tests/unity/testunity_fixture.c create mode 100644 tests/unity/unity_fixture_Test.c create mode 100644 tests/unity/unity_fixture_TestRunner.c create mode 100644 tests/unity/unity_output_Spy.c create mode 100644 tests/unity/unity_output_Spy.h create mode 100644 tests/unity_ramtest/.gitignore create mode 100644 tests/unity_ramtest/Kconfig create mode 100644 tests/unity_ramtest/Make.defs create mode 100644 tests/unity_ramtest/Makefile create mode 100644 tests/unity_ramtest/addr_in_addr.c create mode 100644 tests/unity_ramtest/library.h create mode 100644 tests/unity_ramtest/marching_ones.c create mode 100644 tests/unity_ramtest/marching_zeroes.c create mode 100644 tests/unity_ramtest/pattern.c create mode 100644 tests/unity_ramtest/unity_ramtest_main.c create mode 100644 tests/unity_usrsock/.gitignore create mode 100644 tests/unity_usrsock/Kconfig create mode 100644 tests/unity_usrsock/Make.defs create mode 100644 tests/unity_usrsock/Makefile create mode 100644 tests/unity_usrsock/basic_connect.c create mode 100644 tests/unity_usrsock/basic_daemon.c create mode 100644 tests/unity_usrsock/basic_getsockname.c create mode 100644 tests/unity_usrsock/basic_getsockopt.c create mode 100644 tests/unity_usrsock/basic_send.c create mode 100644 tests/unity_usrsock/basic_setsockopt.c create mode 100644 tests/unity_usrsock/block_recv.c create mode 100644 tests/unity_usrsock/block_send.c create mode 100644 tests/unity_usrsock/chardev.c create mode 100644 tests/unity_usrsock/defines.h create mode 100644 tests/unity_usrsock/multi_thread.c create mode 100644 tests/unity_usrsock/noblock_connect.c create mode 100644 tests/unity_usrsock/noblock_recv.c create mode 100644 tests/unity_usrsock/noblock_send.c create mode 100644 tests/unity_usrsock/nodaemon.c create mode 100644 tests/unity_usrsock/poll.c create mode 100644 tests/unity_usrsock/remote_disconnect.c create mode 100644 tests/unity_usrsock/unity_usrsock_main.c create mode 100644 tests/unity_usrsock/usrsocktest_daemon.c create mode 100644 tests/unity_usrsock/wake_with_signal.c diff --git a/include/testing/license.txt b/include/testing/license.txt new file mode 100644 index 000000000..d66fba53e --- /dev/null +++ b/include/testing/license.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams + +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. diff --git a/include/testing/unity.h b/include/testing/unity.h new file mode 100644 index 000000000..d1decd042 --- /dev/null +++ b/include/testing/unity.h @@ -0,0 +1,272 @@ +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef UNITY_FRAMEWORK_H +#define UNITY_FRAMEWORK_H +#define UNITY + +#include "unity_internals.h" + +//------------------------------------------------------- +// Configuration Options +//------------------------------------------------------- +// All options described below should be passed as a compiler flag to all files using Unity. If you must add #defines, place them BEFORE the #include above. + +// Integers/longs/pointers +// - Unity attempts to automatically discover your integer sizes +// - define UNITY_EXCLUDE_STDINT_H to stop attempting to look in +// - define UNITY_EXCLUDE_LIMITS_H to stop attempting to look in +// - define UNITY_EXCLUDE_SIZEOF to stop attempting to use sizeof in macros +// - If you cannot use the automatic methods above, you can force Unity by using these options: +// - define UNITY_SUPPORT_64 +// - define UNITY_INT_WIDTH +// - UNITY_LONG_WIDTH +// - UNITY_POINTER_WIDTH + +// Floats +// - define UNITY_EXCLUDE_FLOAT to disallow floating point comparisons +// - define UNITY_FLOAT_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_FLOAT +// - define UNITY_FLOAT_TYPE to specify doubles instead of single precision floats +// - define UNITY_FLOAT_VERBOSE to print floating point values in errors (uses sprintf) +// - define UNITY_INCLUDE_DOUBLE to allow double floating point comparisons +// - define UNITY_EXCLUDE_DOUBLE to disallow double floating point comparisons (default) +// - define UNITY_DOUBLE_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_DOUBLE +// - define UNITY_DOUBLE_TYPE to specify something other than double +// - define UNITY_DOUBLE_VERBOSE to print floating point values in errors (uses sprintf) + +// Output +// - by default, Unity prints to standard out with putchar. define UNITY_OUTPUT_CHAR(a) with a different function if desired + +// Optimization +// - by default, line numbers are stored in unsigned shorts. Define UNITY_LINE_TYPE with a different type if your files are huge +// - by default, test and failure counters are unsigned shorts. Define UNITY_COUNTER_TYPE with a different type if you want to save space or have more than 65535 Tests. + +// Test Cases +// - define UNITY_SUPPORT_TEST_CASES to include the TEST_CASE macro, though really it's mostly about the runner generator script + +// Parameterized Tests +// - you'll want to create a define of TEST_CASE(...) which basically evaluates to nothing + +//------------------------------------------------------- +// Basic Fail and Ignore +//------------------------------------------------------- + +#define TEST_FAIL_MESSAGE(message) UNITY_TEST_FAIL(__LINE__, message) +#define TEST_FAIL() UNITY_TEST_FAIL(__LINE__, NULL) +#define TEST_IGNORE_MESSAGE(message) UNITY_TEST_IGNORE(__LINE__, message) +#define TEST_IGNORE() UNITY_TEST_IGNORE(__LINE__, NULL) +#define TEST_ONLY() + +//------------------------------------------------------- +// Test Asserts (simple) +//------------------------------------------------------- + +//Boolean +#define TEST_ASSERT(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expression Evaluated To FALSE") +#define TEST_ASSERT_TRUE(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expected TRUE Was FALSE") +#define TEST_ASSERT_UNLESS(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expression Evaluated To TRUE") +#define TEST_ASSERT_FALSE(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expected FALSE Was TRUE") +#define TEST_ASSERT_NULL(pointer) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, " Expected NULL") +#define TEST_ASSERT_NOT_NULL(pointer) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, " Expected Non-NULL") + +//Integers (of all sizes) +#define TEST_ASSERT_EQUAL_INT(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal") +#define TEST_ASSERT_EQUAL_UINT(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX8(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX16(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX32(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX64(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_BITS(mask, expected, actual) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_BITS_HIGH(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(-1), (actual), __LINE__, NULL) +#define TEST_ASSERT_BITS_LOW(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(0), (actual), __LINE__, NULL) +#define TEST_ASSERT_BIT_HIGH(bit, actual) UNITY_TEST_ASSERT_BITS(((_UU32)1 << bit), (_UU32)(-1), (actual), __LINE__, NULL) +#define TEST_ASSERT_BIT_LOW(bit, actual) UNITY_TEST_ASSERT_BITS(((_UU32)1 << bit), (_UU32)(0), (actual), __LINE__, NULL) + +//Integer Ranges (of all sizes) +#define TEST_ASSERT_INT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, __LINE__, NULL) +#define TEST_ASSERT_INT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT8_WITHIN(delta, expected, actual, __LINE__, NULL) +#define TEST_ASSERT_INT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT16_WITHIN(delta, expected, actual, __LINE__, NULL) +#define TEST_ASSERT_INT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT32_WITHIN(delta, expected, actual, __LINE__, NULL) +#define TEST_ASSERT_INT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, __LINE__, NULL) +#define TEST_ASSERT_UINT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT_WITHIN(delta, expected, actual, __LINE__, NULL) +#define TEST_ASSERT_UINT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT8_WITHIN(delta, expected, actual, __LINE__, NULL) +#define TEST_ASSERT_UINT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT16_WITHIN(delta, expected, actual, __LINE__, NULL) +#define TEST_ASSERT_UINT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT32_WITHIN(delta, expected, actual, __LINE__, NULL) +#define TEST_ASSERT_UINT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, __LINE__, NULL) +#define TEST_ASSERT_HEX_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, __LINE__, NULL) +#define TEST_ASSERT_HEX8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX8_WITHIN(delta, expected, actual, __LINE__, NULL) +#define TEST_ASSERT_HEX16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX16_WITHIN(delta, expected, actual, __LINE__, NULL) +#define TEST_ASSERT_HEX32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, __LINE__, NULL) +#define TEST_ASSERT_HEX64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, __LINE__, NULL) + +//Structs and Strings +#define TEST_ASSERT_EQUAL_PTR(expected, actual) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_STRING(expected, actual) UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_MEMORY(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, __LINE__, NULL) + +//Arrays +#define TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, __LINE__, NULL) + +//Floating Point (If Enabled) +#define TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_FLOAT(expected, actual) UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, __LINE__, NULL) + +//Double (If Enabled) +#define TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_DOUBLE(expected, actual) UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, __LINE__, NULL) +#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, __LINE__, NULL) + +//------------------------------------------------------- +// Test Asserts (with additional messages) +//------------------------------------------------------- + +//Boolean +#define TEST_ASSERT_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, message) +#define TEST_ASSERT_TRUE_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, message) +#define TEST_ASSERT_UNLESS_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, message) +#define TEST_ASSERT_FALSE_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, message) +#define TEST_ASSERT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, message) +#define TEST_ASSERT_NOT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, message) + +//Integers (of all sizes) +#define TEST_ASSERT_EQUAL_INT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, message) +#define TEST_ASSERT_EQUAL_INT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, message) +#define TEST_ASSERT_EQUAL_INT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, message) +#define TEST_ASSERT_EQUAL_INT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, message) +#define TEST_ASSERT_EQUAL_INT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, message) +#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, message) +#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, message) +#define TEST_ASSERT_EQUAL_UINT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, message) +#define TEST_ASSERT_EQUAL_UINT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, message) +#define TEST_ASSERT_EQUAL_UINT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, message) +#define TEST_ASSERT_EQUAL_UINT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, message) +#define TEST_ASSERT_EQUAL_UINT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, message) +#define TEST_ASSERT_EQUAL_HEX_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, message) +#define TEST_ASSERT_EQUAL_HEX8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, message) +#define TEST_ASSERT_EQUAL_HEX16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, message) +#define TEST_ASSERT_EQUAL_HEX32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, message) +#define TEST_ASSERT_EQUAL_HEX64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, message) +#define TEST_ASSERT_BITS_MESSAGE(mask, expected, actual, message) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, message) +#define TEST_ASSERT_BITS_HIGH_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(-1), (actual), __LINE__, message) +#define TEST_ASSERT_BITS_LOW_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(0), (actual), __LINE__, message) +#define TEST_ASSERT_BIT_HIGH_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((_UU32)1 << bit), (_UU32)(-1), (actual), __LINE__, message) +#define TEST_ASSERT_BIT_LOW_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((_UU32)1 << bit), (_UU32)(0), (actual), __LINE__, message) + +//Integer Ranges (of all sizes) +#define TEST_ASSERT_INT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, __LINE__, message) +#define TEST_ASSERT_INT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT8_WITHIN(delta, expected, actual, __LINE__, message) +#define TEST_ASSERT_INT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT16_WITHIN(delta, expected, actual, __LINE__, message) +#define TEST_ASSERT_INT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT32_WITHIN(delta, expected, actual, __LINE__, message) +#define TEST_ASSERT_INT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, __LINE__, message) +#define TEST_ASSERT_UINT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT_WITHIN(delta, expected, actual, __LINE__, message) +#define TEST_ASSERT_UINT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT8_WITHIN(delta, expected, actual, __LINE__, message) +#define TEST_ASSERT_UINT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT16_WITHIN(delta, expected, actual, __LINE__, message) +#define TEST_ASSERT_UINT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT32_WITHIN(delta, expected, actual, __LINE__, message) +#define TEST_ASSERT_UINT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, __LINE__, message) +#define TEST_ASSERT_HEX_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, __LINE__, message) +#define TEST_ASSERT_HEX8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX8_WITHIN(delta, expected, actual, __LINE__, message) +#define TEST_ASSERT_HEX16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX16_WITHIN(delta, expected, actual, __LINE__, message) +#define TEST_ASSERT_HEX32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, __LINE__, message) +#define TEST_ASSERT_HEX64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, __LINE__, message) + +//Structs and Strings +#define TEST_ASSERT_EQUAL_PTR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, __LINE__, message) +#define TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, __LINE__, message) +#define TEST_ASSERT_EQUAL_MEMORY_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, __LINE__, message) + +//Arrays +#define TEST_ASSERT_EQUAL_INT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements, __LINE__, message) +#define TEST_ASSERT_EQUAL_INT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements, __LINE__, message) +#define TEST_ASSERT_EQUAL_INT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements, __LINE__, message) +#define TEST_ASSERT_EQUAL_INT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements, __LINE__, message) +#define TEST_ASSERT_EQUAL_INT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, __LINE__, message) +#define TEST_ASSERT_EQUAL_UINT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements, __LINE__, message) +#define TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements, __LINE__, message) +#define TEST_ASSERT_EQUAL_UINT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements, __LINE__, message) +#define TEST_ASSERT_EQUAL_UINT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements, __LINE__, message) +#define TEST_ASSERT_EQUAL_UINT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, __LINE__, message) +#define TEST_ASSERT_EQUAL_HEX_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, __LINE__, message) +#define TEST_ASSERT_EQUAL_HEX8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements, __LINE__, message) +#define TEST_ASSERT_EQUAL_HEX16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements, __LINE__, message) +#define TEST_ASSERT_EQUAL_HEX32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, __LINE__, message) +#define TEST_ASSERT_EQUAL_HEX64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, __LINE__, message) +#define TEST_ASSERT_EQUAL_PTR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, __LINE__, message) +#define TEST_ASSERT_EQUAL_STRING_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, __LINE__, message) +#define TEST_ASSERT_EQUAL_MEMORY_ARRAY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, __LINE__, message) + +//Floating Point (If Enabled) +#define TEST_ASSERT_FLOAT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, __LINE__, message) +#define TEST_ASSERT_EQUAL_FLOAT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, __LINE__, message) +#define TEST_ASSERT_EQUAL_FLOAT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, __LINE__, message) +#define TEST_ASSERT_FLOAT_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, __LINE__, message) +#define TEST_ASSERT_FLOAT_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, __LINE__, message) +#define TEST_ASSERT_FLOAT_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, __LINE__, message) +#define TEST_ASSERT_FLOAT_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, __LINE__, message) +#define TEST_ASSERT_FLOAT_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, __LINE__, message) +#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, __LINE__, message) +#define TEST_ASSERT_FLOAT_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, __LINE__, message) +#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, __LINE__, message) + +//Double (If Enabled) +#define TEST_ASSERT_DOUBLE_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, __LINE__, message) +#define TEST_ASSERT_EQUAL_DOUBLE_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, __LINE__, message) +#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, __LINE__, message) +#define TEST_ASSERT_DOUBLE_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, __LINE__, message) +#define TEST_ASSERT_DOUBLE_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, __LINE__, message) +#define TEST_ASSERT_DOUBLE_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, __LINE__, message) +#define TEST_ASSERT_DOUBLE_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, __LINE__, message) +#define TEST_ASSERT_DOUBLE_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, __LINE__, message) +#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, __LINE__, message) +#define TEST_ASSERT_DOUBLE_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, __LINE__, message) +#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, __LINE__, message) + +//end of UNITY_FRAMEWORK_H +#endif diff --git a/include/testing/unity_fixture.h b/include/testing/unity_fixture.h new file mode 100644 index 000000000..304c2f7b7 --- /dev/null +++ b/include/testing/unity_fixture.h @@ -0,0 +1,98 @@ +//- Copyright (c) 2010 James Grenning and Contributed to Unity Project +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef UNITY_FIXTURE_H_ +#define UNITY_FIXTURE_H_ + +#include "unity.h" +#include "unity_internals.h" +#include "unity_fixture_malloc_overrides.h" +#include "unity_fixture_internals.h" + +int UnityMain(int argc, const char* argv[], void (*runAllTests)(void)); + + +#define TEST_GROUP(group)\ + static const char* TEST_GROUP_##group = #group + +#define TEST_SETUP(group) TEST_SETUP_WITH_TIMEOUT(group, UNITY_DEFAULT_TIMEOUT_MSEC) + +#define TEST_SETUP_WITH_TIMEOUT(group, timeout)\ + static const _U_UINT TEST_##group##_SETUP_TIMEOUT = (timeout);\ + void TEST_##group##_SETUP(void);\ + void TEST_##group##_SETUP(void) + +#define TEST_TEAR_DOWN(group) TEST_TEAR_DOWN_WITH_TIMEOUT(group, UNITY_DEFAULT_TIMEOUT_MSEC) + +#define TEST_TEAR_DOWN_WITH_TIMEOUT(group, timeout)\ + static const _U_UINT TEST_##group##_TEAR_DOWN_TIMEOUT = (timeout);\ + void TEST_##group##_TEAR_DOWN(void);\ + void TEST_##group##_TEAR_DOWN(void) + + +#define TEST(group, name) TEST_WITH_TIMEOUT(group, name, UNITY_DEFAULT_TIMEOUT_MSEC) + +#define TEST_WITH_TIMEOUT(group, name, timeout)\ + void TEST_##group##_##name##_(void);\ + void TEST_##group##_##name##_run(void);\ + void TEST_##group##_##name##_run(void)\ + {\ + UnityTestRunner(TEST_##group##_SETUP, TEST_##group##_SETUP_TIMEOUT,\ + TEST_##group##_##name##_, (timeout),\ + TEST_##group##_TEAR_DOWN, TEST_##group##_TEAR_DOWN_TIMEOUT,\ + #group "/" #name,\ + TEST_GROUP_##group, #name,\ + __FILE__, __LINE__);\ + }\ + void TEST_##group##_##name##_(void) + +#define IGNORE_TEST(group, name) IGNORE_TEST_WITH_TIMEOUT(group, name, UNITY_DEFAULT_TIMEOUT_MSEC) + +#define IGNORE_TEST_WITH_TIMEOUT(group, name, timeout) \ + void TEST_##group##_##name##_(void);\ + void TEST_##group##_##name##_run(void);\ + void TEST_##group##_##name##_run(void)\ + {\ + UnityIgnoreTest("IGNORE_TEST(" #group ", " #name ")");\ + }\ + void TEST_##group##_##name##_(void) + +#define DECLARE_TEST_CASE(group, name) \ + void TEST_##group##_##name##_run(void) + +#define RUN_TEST_CASE(group, name) \ + { DECLARE_TEST_CASE(group, name);\ + TEST_##group##_##name##_run(); } + +//This goes at the bottom of each test file or in a separate c file +#define TEST_GROUP_RUNNER(group)\ + void TEST_##group##_GROUP_RUNNER_runAll(void);\ + void TEST_##group##_GROUP_RUNNER(void);\ + void TEST_##group##_GROUP_RUNNER(void)\ + {\ + TEST_##group##_GROUP_RUNNER_runAll();\ + }\ + void TEST_##group##_GROUP_RUNNER_runAll(void) + +//Call this from main +#define RUN_TEST_GROUP(group)\ + { void TEST_##group##_GROUP_RUNNER(void);\ + TEST_##group##_GROUP_RUNNER(); } + +//CppUTest Compatibility Macros +#define UT_PTR_SET(ptr, newPointerValue) UnityPointer_Set((void**)&ptr, (void*)newPointerValue) +#define TEST_ASSERT_POINTERS_EQUAL(expected, actual) TEST_ASSERT_EQUAL_PTR(expected, actual) +#define TEST_ASSERT_BYTES_EQUAL(expected, actual) TEST_ASSERT_EQUAL_HEX8(0xff & (expected), 0xff & (actual)) +#define FAIL(message) TEST_FAIL((message)) +#define CHECK(condition) TEST_ASSERT_TRUE((condition)) +#define LONGS_EQUAL(expected, actual) TEST_ASSERT_EQUAL_INT((expected), (actual)) +#define STRCMP_EQUAL(expected, actual) TEST_ASSERT_EQUAL_STRING((expected), (actual)) +#define DOUBLES_EQUAL(expected, actual, delta) TEST_ASSERT_FLOAT_WITHIN(((expected), (actual), (delta)) + +void UnityMalloc_MakeMallocFailAfterCount(int count); + +#endif /* UNITY_FIXTURE_H_ */ diff --git a/include/testing/unity_fixture_internals.h b/include/testing/unity_fixture_internals.h new file mode 100644 index 000000000..dd5ceee8b --- /dev/null +++ b/include/testing/unity_fixture_internals.h @@ -0,0 +1,46 @@ +//- Copyright (c) 2010 James Grenning and Contributed to Unity Project +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef UNITY_FIXTURE_INTERNALS_H_ +#define UNITY_FIXTURE_INTERNALS_H_ + +typedef struct _UNITY_FIXTURE_T +{ + int Verbose; + int ListOnly; + unsigned int RepeatCount; + const char* NameFilter; + const char* GroupFilter; + const char** PlainListOfTests; +} UNITY_FIXTURE_T; + +typedef void unityfunction(void); +void UnityTestRunner(unityfunction * setup, _U_UINT setupTimeoutMsec, + unityfunction * body, _U_UINT bodyTimeoutMsec, + unityfunction * teardown, _U_UINT teardownTimeoutMsec, + const char * printableName, + const char * group, + const char * name, + const char * file, int line); + +void UnityIgnoreTest(const char * printableName); +void UnityMalloc_StartTest(void); +void UnityMalloc_EndTest(void); +int UnityFailureCount(void); +int UnityGetCommandLineOptions(int argc, const char* argv[]); +void UnityConcludeFixtureTest(void); + +void UnityPointer_Set(void ** ptr, void * newValue); +void UnityPointer_UndoAllSets(void); +void UnityPointer_Init(void); + +void UnityAssertEqualPointer(const void * expected, + const void * actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +#endif /* UNITY_FIXTURE_INTERNALS_H_ */ diff --git a/include/testing/unity_fixture_malloc_overrides.h b/include/testing/unity_fixture_malloc_overrides.h new file mode 100644 index 000000000..25385f4d7 --- /dev/null +++ b/include/testing/unity_fixture_malloc_overrides.h @@ -0,0 +1,27 @@ +//- Copyright (c) 2010 James Grenning and Contributed to Unity Project +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef UNITY_FIXTURE_MALLOC_OVERRIDES_H_ +#define UNITY_FIXTURE_MALLOC_OVERRIDES_H_ + +#ifndef UNITY_DISABLE_MEMORY_LEAK_TRACKING + +#include + +#define malloc unity_malloc +#define calloc unity_calloc +#define realloc unity_realloc +#define free unity_free + +void* unity_malloc(size_t size); +void* unity_calloc(size_t num, size_t size); +void* unity_realloc(void * oldMem, size_t size); +void unity_free(void * mem); + +#endif /* UNITY_DISABLE_MEMORY_LEAK_TRACKING */ + +#endif /* UNITY_FIXTURE_MALLOC_OVERRIDES_H_ */ diff --git a/include/testing/unity_internals.h b/include/testing/unity_internals.h new file mode 100644 index 000000000..b73729f13 --- /dev/null +++ b/include/testing/unity_internals.h @@ -0,0 +1,693 @@ +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef UNITY_INTERNALS_H +#define UNITY_INTERNALS_H + +#ifdef UNITY_INCLUDE_CONFIG_H +#include "unity_config.h" +#endif + +// Unity Attempts to Auto-Detect Integer Types +// Attempt 1: UINT_MAX, ULONG_MAX, etc in +// Attempt 2: UINT_MAX, ULONG_MAX, etc in +// Attempt 3: Deduced from sizeof() macros +#ifndef UNITY_EXCLUDE_STDINT_H +#include +#endif + +#ifndef UNITY_EXCLUDE_LIMITS_H +#include +#endif + +#ifndef UNITY_EXCLUDE_SIZEOF +#ifndef UINT_MAX +#define UINT_MAX (sizeof(unsigned int) * 256 - 1) +#endif +#ifndef ULONG_MAX +#define ULONG_MAX (sizeof(unsigned long) * 256 - 1) +#endif +#ifndef UINTPTR_MAX +//apparently this is not a constant expression: (sizeof(unsigned int *) * 256 - 1) so we have to just let this fall through +#endif +#endif +//------------------------------------------------------- +// Guess Widths If Not Specified +//------------------------------------------------------- + +// Determine the size of an int, if not already specificied. +// We cannot use sizeof(int), because it is not yet defined +// at this stage in the trnslation of the C program. +// Therefore, infer it from UINT_MAX if possible. +#ifndef UNITY_INT_WIDTH + #ifdef UINT_MAX + #if (UINT_MAX == 0xFFFF) + #define UNITY_INT_WIDTH (16) + #elif (UINT_MAX == 0xFFFFFFFF) + #define UNITY_INT_WIDTH (32) + #elif (UINT_MAX == 0xFFFFFFFFFFFFFFFF) + #define UNITY_INT_WIDTH (64) + #endif + #endif +#endif +#ifndef UNITY_INT_WIDTH + #define UNITY_INT_WIDTH (32) +#endif + +// Determine the size of a long, if not already specified, +// by following the process used above to define +// UNITY_INT_WIDTH. +#ifndef UNITY_LONG_WIDTH + #ifdef ULONG_MAX + #if (ULONG_MAX == 0xFFFF) + #define UNITY_LONG_WIDTH (16) + #elif (ULONG_MAX == 0xFFFFFFFF) + #define UNITY_LONG_WIDTH (32) + #elif (ULONG_MAX == 0xFFFFFFFFFFFFFFFF) + #define UNITY_LONG_WIDTH (64) + #endif + #endif +#endif +#ifndef UNITY_LONG_WIDTH + #define UNITY_LONG_WIDTH (32) +#endif + +// Determine the size of a pointer, if not already specified, +// by following the process used above to define +// UNITY_INT_WIDTH. +#ifndef UNITY_POINTER_WIDTH + #ifdef UINTPTR_MAX + #if (UINTPTR_MAX <= 0xFFFF) + #define UNITY_POINTER_WIDTH (16) + #elif (UINTPTR_MAX <= 0xFFFFFFFF) + #define UNITY_POINTER_WIDTH (32) + #elif (UINTPTR_MAX <= 0xFFFFFFFFFFFFFFFF) + #define UNITY_POINTER_WIDTH (64) + #endif + #endif +#endif +#ifndef UNITY_POINTER_WIDTH + #ifdef INTPTR_MAX + #if (INTPTR_MAX <= 0x7FFF) + #define UNITY_POINTER_WIDTH (16) + #elif (INTPTR_MAX <= 0x7FFFFFFF) + #define UNITY_POINTER_WIDTH (32) + #elif (INTPTR_MAX <= 0x7FFFFFFFFFFFFFFF) + #define UNITY_POINTER_WIDTH (64) + #endif + #endif +#endif +#ifndef UNITY_POINTER_WIDTH + #define UNITY_POINTER_WIDTH UNITY_LONG_WIDTH +#endif + +//------------------------------------------------------- +// Int Support (Define types based on detected sizes) +//------------------------------------------------------- + +#if (UNITY_INT_WIDTH == 32) + typedef unsigned char _UU8; + typedef unsigned short _UU16; + typedef unsigned int _UU32; + typedef signed char _US8; + typedef signed short _US16; + typedef signed int _US32; +#elif (UNITY_INT_WIDTH == 16) + typedef unsigned char _UU8; + typedef unsigned int _UU16; + typedef unsigned long _UU32; + typedef signed char _US8; + typedef signed int _US16; + typedef signed long _US32; +#else + #error Invalid UNITY_INT_WIDTH specified! (16 or 32 are supported) +#endif + +//------------------------------------------------------- +// 64-bit Support +//------------------------------------------------------- + +#ifndef UNITY_SUPPORT_64 +#if UNITY_LONG_WIDTH > 32 +#define UNITY_SUPPORT_64 +#endif +#endif +#ifndef UNITY_SUPPORT_64 +#if UNITY_POINTER_WIDTH > 32 +#define UNITY_SUPPORT_64 +#endif +#endif + +#ifndef UNITY_SUPPORT_64 + +//No 64-bit Support +typedef _UU32 _U_UINT; +typedef _US32 _U_SINT; + +#else + +//64-bit Support +#if (UNITY_LONG_WIDTH == 32) + typedef unsigned long long _UU64; + typedef signed long long _US64; +#elif (UNITY_LONG_WIDTH == 64) + typedef unsigned long _UU64; + typedef signed long _US64; +#else + #error Invalid UNITY_LONG_WIDTH specified! (32 or 64 are supported) +#endif +typedef _UU64 _U_UINT; +typedef _US64 _U_SINT; + +#endif + +//------------------------------------------------------- +// Pointer Support +//------------------------------------------------------- + +#if (UNITY_POINTER_WIDTH == 32) + typedef _UU32 _UP; +#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX32 +#elif (UNITY_POINTER_WIDTH == 64) + typedef _UU64 _UP; +#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX64 +#elif (UNITY_POINTER_WIDTH == 16) + typedef _UU16 _UP; +#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX16 +#else + #error Invalid UNITY_POINTER_WIDTH specified! (16, 32 or 64 are supported) +#endif + +#ifndef UNITY_PTR_ATTRIBUTE + #define UNITY_PTR_ATTRIBUTE +#endif + +//------------------------------------------------------- +// Float Support +//------------------------------------------------------- + +#ifdef UNITY_EXCLUDE_FLOAT + +//No Floating Point Support +#undef UNITY_INCLUDE_FLOAT +#undef UNITY_FLOAT_PRECISION +#undef UNITY_FLOAT_TYPE +#undef UNITY_FLOAT_VERBOSE + +#else + +#ifndef UNITY_INCLUDE_FLOAT +#define UNITY_INCLUDE_FLOAT +#endif + +//Floating Point Support +#ifndef UNITY_FLOAT_PRECISION +#define UNITY_FLOAT_PRECISION (0.00001f) +#endif +#ifndef UNITY_FLOAT_TYPE +#define UNITY_FLOAT_TYPE float +#endif +typedef UNITY_FLOAT_TYPE _UF; + +#endif + +//------------------------------------------------------- +// Double Float Support +//------------------------------------------------------- + +//unlike FLOAT, we DON'T include by default +#ifndef UNITY_EXCLUDE_DOUBLE +#ifndef UNITY_INCLUDE_DOUBLE +#define UNITY_EXCLUDE_DOUBLE +#endif +#endif + +#ifdef UNITY_EXCLUDE_DOUBLE + +//No Floating Point Support +#undef UNITY_DOUBLE_PRECISION +#undef UNITY_DOUBLE_TYPE +#undef UNITY_DOUBLE_VERBOSE + +#ifdef UNITY_INCLUDE_DOUBLE +#undef UNITY_INCLUDE_DOUBLE +#endif + +#else + +//Double Floating Point Support +#ifndef UNITY_DOUBLE_PRECISION +#define UNITY_DOUBLE_PRECISION (1e-12f) +#endif +#ifndef UNITY_DOUBLE_TYPE +#define UNITY_DOUBLE_TYPE double +#endif +typedef UNITY_DOUBLE_TYPE _UD; + +#endif + +#ifdef UNITY_DOUBLE_VERBOSE +#ifndef UNITY_FLOAT_VERBOSE +#define UNITY_FLOAT_VERBOSE +#endif +#endif + +//------------------------------------------------------- +// Output Method: stdout (DEFAULT) +//------------------------------------------------------- +#ifndef UNITY_OUTPUT_CHAR +//Default to using putchar, which is defined in stdio.h +#include +#define UNITY_OUTPUT_CHAR(a) putchar(a) +#else +//If defined as something else, make sure we declare it here so it's ready for use +extern int UNITY_OUTPUT_CHAR(int); +#endif + +#ifndef UNITY_OUTPUT_START +#define UNITY_OUTPUT_START() +#endif + +#ifndef UNITY_OUTPUT_COMPLETE +#define UNITY_OUTPUT_COMPLETE() +#endif + +//------------------------------------------------------- +// Footprint +//------------------------------------------------------- + +#ifndef UNITY_LINE_TYPE +#define UNITY_LINE_TYPE _U_UINT +#endif + +#ifndef UNITY_COUNTER_TYPE +#define UNITY_COUNTER_TYPE _U_UINT +#endif + +//------------------------------------------------------- +// Language Features Available +//------------------------------------------------------- +#if !defined(UNITY_WEAK_ATTRIBUTE) && !defined(UNITY_WEAK_PRAGMA) +# ifdef __GNUC__ // includes clang +# if !(defined(__WIN32__) && defined(__clang__)) +# define UNITY_WEAK_ATTRIBUTE __attribute__((weak)) +# endif +# endif +#endif + +#ifdef UNITY_NO_WEAK +# undef UNITY_WEAK_ATTRIBUTE +# undef UNITY_WEAK_PRAGMA +#endif + + +//------------------------------------------------------- +// Internal Structs Needed +//------------------------------------------------------- + +typedef void (*UnityTestFunction)(void); + +#define UNITY_DISPLAY_RANGE_INT (0x10) +#define UNITY_DISPLAY_RANGE_UINT (0x20) +#define UNITY_DISPLAY_RANGE_HEX (0x40) +#define UNITY_DISPLAY_RANGE_AUTO (0x80) + +typedef enum +{ +#if (UNITY_INT_WIDTH == 16) + UNITY_DISPLAY_STYLE_INT = 2 + UNITY_DISPLAY_RANGE_INT + UNITY_DISPLAY_RANGE_AUTO, +#elif (UNITY_INT_WIDTH == 32) + UNITY_DISPLAY_STYLE_INT = 4 + UNITY_DISPLAY_RANGE_INT + UNITY_DISPLAY_RANGE_AUTO, +#elif (UNITY_INT_WIDTH == 64) + UNITY_DISPLAY_STYLE_INT = 8 + UNITY_DISPLAY_RANGE_INT + UNITY_DISPLAY_RANGE_AUTO, +#endif + UNITY_DISPLAY_STYLE_INT8 = 1 + UNITY_DISPLAY_RANGE_INT, + UNITY_DISPLAY_STYLE_INT16 = 2 + UNITY_DISPLAY_RANGE_INT, + UNITY_DISPLAY_STYLE_INT32 = 4 + UNITY_DISPLAY_RANGE_INT, +#ifdef UNITY_SUPPORT_64 + UNITY_DISPLAY_STYLE_INT64 = 8 + UNITY_DISPLAY_RANGE_INT, +#endif + +#if (UNITY_INT_WIDTH == 16) + UNITY_DISPLAY_STYLE_UINT = 2 + UNITY_DISPLAY_RANGE_UINT + UNITY_DISPLAY_RANGE_AUTO, +#elif (UNITY_INT_WIDTH == 32) + UNITY_DISPLAY_STYLE_UINT = 4 + UNITY_DISPLAY_RANGE_UINT + UNITY_DISPLAY_RANGE_AUTO, +#elif (UNITY_INT_WIDTH == 64) + UNITY_DISPLAY_STYLE_UINT = 8 + UNITY_DISPLAY_RANGE_UINT + UNITY_DISPLAY_RANGE_AUTO, +#endif + UNITY_DISPLAY_STYLE_UINT8 = 1 + UNITY_DISPLAY_RANGE_UINT, + UNITY_DISPLAY_STYLE_UINT16 = 2 + UNITY_DISPLAY_RANGE_UINT, + UNITY_DISPLAY_STYLE_UINT32 = 4 + UNITY_DISPLAY_RANGE_UINT, +#ifdef UNITY_SUPPORT_64 + UNITY_DISPLAY_STYLE_UINT64 = 8 + UNITY_DISPLAY_RANGE_UINT, +#endif + UNITY_DISPLAY_STYLE_HEX8 = 1 + UNITY_DISPLAY_RANGE_HEX, + UNITY_DISPLAY_STYLE_HEX16 = 2 + UNITY_DISPLAY_RANGE_HEX, + UNITY_DISPLAY_STYLE_HEX32 = 4 + UNITY_DISPLAY_RANGE_HEX, +#ifdef UNITY_SUPPORT_64 + UNITY_DISPLAY_STYLE_HEX64 = 8 + UNITY_DISPLAY_RANGE_HEX, +#endif + UNITY_DISPLAY_STYLE_UNKNOWN +} UNITY_DISPLAY_STYLE_T; + +#ifndef UNITY_EXCLUDE_FLOAT +typedef enum _UNITY_FLOAT_TRAIT_T +{ + UNITY_FLOAT_IS_NOT_INF = 0, + UNITY_FLOAT_IS_INF, + UNITY_FLOAT_IS_NOT_NEG_INF, + UNITY_FLOAT_IS_NEG_INF, + UNITY_FLOAT_IS_NOT_NAN, + UNITY_FLOAT_IS_NAN, + UNITY_FLOAT_IS_NOT_DET, + UNITY_FLOAT_IS_DET, +} UNITY_FLOAT_TRAIT_T; +#endif + +struct _Unity +{ + const char* TestFile; + const char* CurrentTestName; + UNITY_LINE_TYPE CurrentTestLineNumber; + UNITY_COUNTER_TYPE NumberOfTests; + UNITY_COUNTER_TYPE TestFailures; + UNITY_COUNTER_TYPE TestIgnores; + UNITY_COUNTER_TYPE CurrentTestFailed; + UNITY_COUNTER_TYPE CurrentTestIgnored; + UNITY_COUNTER_TYPE CurrentTestTimeout; +}; + +extern struct _Unity Unity; + +//------------------------------------------------------- +// Test Suite Management +//------------------------------------------------------- + +void UnityBegin(const char* filename); +int UnityEnd(void); +void UnityConcludeTest(void); +void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum); + +//------------------------------------------------------- +// Test Output +//------------------------------------------------------- + +void UnityPrint(const char* string); +void UnityPrintMask(const _U_UINT mask, const _U_UINT number); +void UnityPrintNumberByStyle(const _U_SINT number, const UNITY_DISPLAY_STYLE_T style); +void UnityPrintNumber(const _U_SINT number); +void UnityPrintNumberUnsigned(const _U_UINT number); +void UnityPrintNumberHex(const _U_UINT number, const char nibbles); + +#ifdef UNITY_FLOAT_VERBOSE +void UnityPrintFloat(const _UF number); +#endif + +//------------------------------------------------------- +// Test Assertion Fuctions +//------------------------------------------------------- +// Use the macros below this section instead of calling +// these directly. The macros have a consistent naming +// convention and will pull in file and line information +// for you. + +void UnityAssertEqualNumber(const _U_SINT expected, + const _U_SINT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style); + +void UnityAssertEqualIntArray(UNITY_PTR_ATTRIBUTE const void* expected, + UNITY_PTR_ATTRIBUTE const void* actual, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style); + +void UnityAssertBits(const _U_SINT mask, + const _U_SINT expected, + const _U_SINT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualString(const char* expected, + const char* actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualStringArray( const char** expected, + const char** actual, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualMemory( UNITY_PTR_ATTRIBUTE const void* expected, + UNITY_PTR_ATTRIBUTE const void* actual, + const _UU32 length, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertNumbersWithin(const _U_SINT delta, + const _U_SINT expected, + const _U_SINT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style); + +void UnityFail(const char* message, const UNITY_LINE_TYPE line); + +void UnityIgnore(const char* message, const UNITY_LINE_TYPE line); + +#ifndef UNITY_EXCLUDE_FLOAT +void UnityAssertFloatsWithin(const _UF delta, + const _UF expected, + const _UF actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const _UF* expected, + UNITY_PTR_ATTRIBUTE const _UF* actual, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertFloatSpecial(const _UF actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style); +#endif + +#ifndef UNITY_EXCLUDE_DOUBLE +void UnityAssertDoublesWithin(const _UD delta, + const _UD expected, + const _UD actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const _UD* expected, + UNITY_PTR_ATTRIBUTE const _UD* actual, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertDoubleSpecial(const _UD actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style); +#endif + +int UnityProtect(UnityTestFunction function, _U_UINT timeout_msec); + +//------------------------------------------------------- +// Error Strings We Might Need +//------------------------------------------------------- + +extern const char UnityStrErrFloat[]; +extern const char UnityStrErrDouble[]; +extern const char UnityStrErr64[]; + +//------------------------------------------------------- +// Test Running Macros +//------------------------------------------------------- + +#define UNITY_DEFAULT_TIMEOUT_MSEC 120000 + +#define TEST_PROTECTED_WITH_TIMEOUT(function, timeout) UnityProtect(function, timeout) +#define TEST_PROTECTED(function) TEST_PROTECTED_WITH_TIMEOUT(function, UNITY_DEFAULT_TIMEOUT_MSEC) + +//This tricky series of macros gives us an optional line argument to treat it as RUN_TEST(func, num=__LINE__) +#ifndef RUN_TEST +#ifdef __STDC_VERSION__ +#if __STDC_VERSION__ >= 199901L +#define RUN_TEST(...) UnityDefaultTestRun(RUN_TEST_FIRST(__VA_ARGS__), RUN_TEST_SECOND(__VA_ARGS__)) +#define RUN_TEST_FIRST(...) RUN_TEST_FIRST_HELPER(__VA_ARGS__, throwaway) +#define RUN_TEST_FIRST_HELPER(first,...) first, #first +#define RUN_TEST_SECOND(...) RUN_TEST_SECOND_HELPER(__VA_ARGS__, __LINE__, throwaway) +#define RUN_TEST_SECOND_HELPER(first,second,...) second +#endif +#endif +#endif + +//If we can't do the tricky version, we'll just have to require them to always include the line number +#ifndef RUN_TEST +#ifdef CMOCK +#define RUN_TEST(func, num) UnityDefaultTestRun(func, #func, num) +#else +#define RUN_TEST(func) UnityDefaultTestRun(func, #func, __LINE__) +#endif +#endif + +#define TEST_LINE_NUM (Unity.CurrentTestLineNumber) +#define TEST_IS_IGNORED (Unity.CurrentTestIgnored) +#define UNITY_NEW_TEST(a) \ + Unity.CurrentTestName = a; \ + Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)(__LINE__); \ + Unity.NumberOfTests++; + +#ifndef UNITY_BEGIN +#define UNITY_BEGIN() UnityBegin(__FILE__) +#endif + +#ifndef UNITY_END +#define UNITY_END() UnityEnd() +#endif + +//------------------------------------------------------- +// Basic Fail and Ignore +//------------------------------------------------------- + +#define UNITY_TEST_FAIL(line, message) UnityFail( (message), (UNITY_LINE_TYPE)line); +#define UNITY_TEST_IGNORE(line, message) UnityIgnore( (message), (UNITY_LINE_TYPE)line); + +//------------------------------------------------------- +// Test Asserts +//------------------------------------------------------- + +#define UNITY_TEST_ASSERT(condition, line, message) if (condition) {} else {UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, message);} +#define UNITY_TEST_ASSERT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) == NULL), (UNITY_LINE_TYPE)line, message) +#define UNITY_TEST_ASSERT_NOT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) != NULL), (UNITY_LINE_TYPE)line, message) + +#define UNITY_TEST_ASSERT_EQUAL_INT(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_EQUAL_INT8(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US8 )(expected), (_U_SINT)(_US8 )(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_EQUAL_INT16(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US16)(expected), (_U_SINT)(_US16)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_EQUAL_INT32(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US32)(expected), (_U_SINT)(_US32)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_EQUAL_UINT(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_EQUAL_UINT8(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UU8 )(expected), (_U_SINT)(_UU8 )(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_EQUAL_UINT16(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UU16)(expected), (_U_SINT)(_UU16)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_EQUAL_UINT32(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UU32)(expected), (_U_SINT)(_UU32)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_EQUAL_HEX8(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US8 )(expected), (_U_SINT)(_US8 )(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_EQUAL_HEX16(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US16)(expected), (_U_SINT)(_US16)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_EQUAL_HEX32(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US32)(expected), (_U_SINT)(_US32)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_BITS(mask, expected, actual, line, message) UnityAssertBits((_U_SINT)(mask), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line) + +#define UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_INT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_US8 )(delta), (_U_SINT)(_US8 )(expected), (_U_SINT)(_US8 )(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_INT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_US16)(delta), (_U_SINT)(_US16)(expected), (_U_SINT)(_US16)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_INT32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_US32)(delta), (_U_SINT)(_US32)(expected), (_U_SINT)(_US32)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_UINT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_UINT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_U_UINT)(_UU8 )(delta), (_U_SINT)(_U_UINT)(_UU8 )(expected), (_U_SINT)(_U_UINT)(_UU8 )(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_UINT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_U_UINT)(_UU16)(delta), (_U_SINT)(_U_UINT)(_UU16)(expected), (_U_SINT)(_U_UINT)(_UU16)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_UINT32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_U_UINT)(_UU32)(delta), (_U_SINT)(_U_UINT)(_UU32)(expected), (_U_SINT)(_U_UINT)(_UU32)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_HEX8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_U_UINT)(_UU8 )(delta), (_U_SINT)(_U_UINT)(_UU8 )(expected), (_U_SINT)(_U_UINT)(_UU8 )(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_HEX16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_U_UINT)(_UU16)(delta), (_U_SINT)(_U_UINT)(_UU16)(expected), (_U_SINT)(_U_UINT)(_UU16)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_U_UINT)(_UU32)(delta), (_U_SINT)(_U_UINT)(_UU32)(expected), (_U_SINT)(_U_UINT)(_UU32)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX32) + +#define UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UP)(expected), (_U_SINT)(_UP)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_POINTER) +#define UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, line, message) UnityAssertEqualString((const char*)(expected), (const char*)(actual), (message), (UNITY_LINE_TYPE)line) +#define UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, line, message) UnityAssertEqualMemory((UNITY_PTR_ATTRIBUTE void*)(expected), (UNITY_PTR_ATTRIBUTE void*)(actual), (_UU32)(len), 1, (message), (UNITY_LINE_TYPE)line) + +#define UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(_UP*)(expected), (const void*)(_UP*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_POINTER) +#define UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualStringArray((const char**)(expected), (const char**)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line) +#define UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, line, message) UnityAssertEqualMemory((UNITY_PTR_ATTRIBUTE void*)(expected), (UNITY_PTR_ATTRIBUTE void*)(actual), (_UU32)(len), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line) + +#ifdef UNITY_SUPPORT_64 +#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const _U_SINT*)(expected), (UNITY_PTR_ATTRIBUTE const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const _U_SINT*)(expected), (UNITY_PTR_ATTRIBUTE const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const _U_SINT*)(expected), (UNITY_PTR_ATTRIBUTE const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(delta), (_U_SINT)(expected), (_U_SINT)(actual), NULL, (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(delta), (_U_SINT)(expected), (_U_SINT)(actual), NULL, (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(delta), (_U_SINT)(expected), (_U_SINT)(actual), NULL, (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX64) +#else +#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErr64) +#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErr64) +#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErr64) +#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErr64) +#endif + +#ifdef UNITY_EXCLUDE_FLOAT +#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) +#else +#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UnityAssertFloatsWithin((_UF)(delta), (_UF)(expected), (_UF)(actual), (message), (UNITY_LINE_TYPE)line) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((_UF)(expected) * (_UF)UNITY_FLOAT_PRECISION, (_UF)expected, (_UF)actual, (UNITY_LINE_TYPE)line, message) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualFloatArray((_UF*)(expected), (_UF*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line) +#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NEG_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NAN) +#define UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_DET) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NOT_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NOT_NEG_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NOT_NAN) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NOT_DET) +#endif + +#ifdef UNITY_EXCLUDE_DOUBLE +#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) +#else +#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UnityAssertDoublesWithin((_UD)(delta), (_UD)(expected), (_UD)(actual), (message), (UNITY_LINE_TYPE)line) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((_UD)(expected) * (_UD)UNITY_DOUBLE_PRECISION, (_UD)expected, (_UD)actual, (UNITY_LINE_TYPE)line, message) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualDoubleArray((_UD*)(expected), (_UD*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line) +#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NEG_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NAN) +#define UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_DET) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NOT_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NOT_NEG_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NOT_NAN) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NOT_DET) +#endif + +//End of UNITY_INTERNALS_H +#endif diff --git a/tests/Kconfig b/tests/Kconfig new file mode 100644 index 000000000..89fbb3ec3 --- /dev/null +++ b/tests/Kconfig @@ -0,0 +1,11 @@ +# +# For a description of the syntax of this configuration file, +# see misc/tools/kconfig-language.txt. +# + +menu "Unity test framework" +source "$APPSDIR/tests/testing/Kconfig" +source "$APPSDIR/tests/unity/Kconfig" +source "$APPSDIR/tests/unity_usrsock/Kconfig" +source "$APPSDIR/tests/unity_ramtest/Kconfig" +endmenu diff --git a/tests/Make.defs b/tests/Make.defs new file mode 100644 index 000000000..336f8959f --- /dev/null +++ b/tests/Make.defs @@ -0,0 +1,37 @@ +############################################################################ +# apps/tests/Make.defs +# Adds selected testing applications to apps/ build +# +# Copyright (C) 2015 Haltian Ltd. All rights reserved. +# Author: Roman Saveljev +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +include $(wildcard tests/*/Make.defs) diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 000000000..3e31d5073 --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,114 @@ +############################################################################ +# apps/tests/Makefile +# +# Copyright (C) 2015-2017 Haltian Ltd. All rights reserved. +# Author: Roman Saveljev +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/.config # Current configuration +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +ASRCS = +AOBJS = $(ASRCS:.S=$(OBJEXT)) + +CSRCS = unity.c unity_fixture.c + +DEPPATH = --dep-path . +VPATH = . + +COBJS = $(CSRCS:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +# Sub-directories + +# Wherever is a Makefile should be included +SUBDIRS = $(dir $(wildcard */Makefile)) + +# Sub-directories that might need context setup. Directories may need +# context setup for a variety of reasons, but the most common is because +# the example may be built as an NSH built-in function. + +# Projects that do not need the 'context' rule define it empty and/or +# variate the behavior according to the product configuration +CNTXTDIRS = $(SUBDIRS) + +all: .built + +.PHONY: context .depend depend clean distclean + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +$(BIN): $(OBJS) + $(call ARCHIVE, $@, $(OBJS)) + +.built: $(OBJS) + $(call ARCHIVE, $(BIN), $(OBJS)) + @touch .built + +define SDIR_template +$(1)_$(2): + $(Q) $(MAKE) -C $(1) $(2) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" +endef + +$(foreach SDIR, $(CNTXTDIRS), $(eval $(call SDIR_template,$(SDIR),context))) +$(foreach SDIR, $(SUBDIRS), $(eval $(call SDIR_template,$(SDIR),depend))) +$(foreach SDIR, $(SUBDIRS), $(eval $(call SDIR_template,$(SDIR),clean))) +$(foreach SDIR, $(SUBDIRS), $(eval $(call SDIR_template,$(SDIR),distclean))) + +install: + +context: $(foreach SDIR, $(CNTXTDIRS), $(SDIR)_context) + +.depend: Makefile $(SRCS) + $(Q) $(MKDEP) $(DEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + $(Q) touch $@ + +depend: $(foreach SDIR, $(SUBDIRS), $(SDIR)_depend) .depend + +clean: $(foreach SDIR, $(SUBDIRS), $(SDIR)_clean) + $(call DELFILE, $(BIN)) + $(call CLEAN) + +distclean: $(foreach SDIR, $(SUBDIRS), $(SDIR)_distclean) + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep + +.PHONY: preconfig +preconfig: diff --git a/tests/README.txt b/tests/README.txt new file mode 100644 index 000000000..7bf92a91f --- /dev/null +++ b/tests/README.txt @@ -0,0 +1,34 @@ +README +^^^^^^ + +This folder hosts NuttX unit test framework source files. + +INTRODUCTION +^^^^^^^^^^^^ + +NuttX unit test framework is based on Unity (https://github.com/ThrowTheSwitch/Unity). +The source code bears minimal changes and most of the additional functionality is brought +through the extension. + +NUTTX-SPECIFIC ISSUES +^^^^^^^^^^^^^^^^^^^^^ + +Unity relies on setjmp/longjmp to be available, so a testcase can be aborted. While the +functionality exists in simulator builds, the hardware environment does not have it. To +provide the same baseline we run test bodies and other abortable parts in their own threads. +The main thread blocks until a spawn exits. Thus we create the same context as offered by +setjmp/longjmp. + +RUNNING TESTS +^^^^^^^^^^^^^ + +Tests can be executed both in simulator and in the target. The test application can be built-in +into NSH or provide application entry point. + +Test application supports command line interface: + + application [--list] [test [test...]] + + --list - Lists all available testcases from all included modules + +Test is identified by its module name and function name. diff --git a/tests/docs/Unity_Summary.txt b/tests/docs/Unity_Summary.txt new file mode 100644 index 000000000..a157aaced --- /dev/null +++ b/tests/docs/Unity_Summary.txt @@ -0,0 +1,216 @@ +============== +Unity Test API +============== + +[Copyright (c) 2007 - 2012 Unity Project by Mike Karlesky, Mark VanderVoord, and Greg Williams] + +------------- +Running Tests +------------- + +RUN_TEST(func, linenum) + +Each Test is run within the macro RUN_TEST. This macro performs necessary setup before the test is called and handles cleanup and result tabulation afterwards. + +-------------- +Ignoring Tests +-------------- + +There are times when a test is incomplete or not valid for some reason. At these times, TEST_IGNORE can be called. Control will immediately be returned to the caller of the test, and no failures will be returned. + +TEST_IGNORE() + +Ignore this test and return immediately + +TEST_IGNORE_MESSAGE (message) + +Ignore this test and return immediately. Output a message stating why the test was ignored. + +-------------- +Aborting Tests +-------------- + +There are times when a test will contain an infinite loop on error conditions, or there may be reason to escape from the test early without executing the rest of the test. A pair of macros support this functionality in Unity. The first (TEST_PROTECT) sets up the feature, and handles emergency abort cases. TEST_ABORT can then be used at any time within the tests to return to the last TEST_PROTECT call. + +TEST_PROTECT() + +Setup and Catch macro + +TEST_ABORT() + +Abort Test macro + +Example: + +main() +{ + if (TEST_PROTECT() == 0) + { + MyTest(); + } +} + +If MyTest calls TEST_ABORT, program control will immediately return to TEST_PROTECT with a non-zero return value. + + +======================= +Unity Assertion Summary +======================= + +-------------------- +Basic Validity Tests +-------------------- + +TEST_ASSERT_TRUE(condition) + +Evaluates whatever code is in condition and fails if it evaluates to false + +TEST_ASSERT_FALSE(condition) + +Evaluates whatever code is in condition and fails if it evaluates to true + +TEST_ASSERT(condition) + +Another way of calling TEST_ASSERT_TRUE + +TEST_ASSERT_UNLESS(condition) + +Another way of calling TEST_ASSERT_FALSE + +TEST_FAIL() +TEST_FAIL_MESSAGE(message) + +This test is automatically marked as a failure. The message is output stating why. + +------------------------------ +Numerical Assertions: Integers +------------------------------ + +TEST_ASSERT_EQUAL_INT(expected, actual) +TEST_ASSERT_EQUAL_INT8(expected, actual) +TEST_ASSERT_EQUAL_INT16(expected, actual) +TEST_ASSERT_EQUAL_INT32(expected, actual) +TEST_ASSERT_EQUAL_INT64(expected, actual) + +Compare two integers for equality and display errors as signed integers. A cast will be performed +to your natural integer size so often this can just be used. When you need to specify the exact size, +like when comparing arrays, you can use a specific version: + +TEST_ASSERT_EQUAL_UINT(expected, actual) +TEST_ASSERT_EQUAL_UINT8(expected, actual) +TEST_ASSERT_EQUAL_UINT16(expected, actual) +TEST_ASSERT_EQUAL_UINT32(expected, actual) +TEST_ASSERT_EQUAL_UINT64(expected, actual) + +Compare two integers for equality and display errors as unsigned integers. Like INT, there are +variants for different sizes also. + +TEST_ASSERT_EQUAL_HEX(expected, actual) +TEST_ASSERT_EQUAL_HEX8(expected, actual) +TEST_ASSERT_EQUAL_HEX16(expected, actual) +TEST_ASSERT_EQUAL_HEX32(expected, actual) +TEST_ASSERT_EQUAL_HEX64(expected, actual) + +Compares two integers for equality and display errors as hexadecimal. Like the other integer comparisons, +you can specify the size... here the size will also effect how many nibbles are shown (for example, HEX16 +will show 4 nibbles). + +_ARRAY + +You can append _ARRAY to any of these macros to make an array comparison of that type. Here you will +need to care a bit more about the actual size of the value being checked. You will also specify an +additional argument which is the number of elements to compare. For example: + +TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, elements) + +TEST_ASSERT_EQUAL(expected, actual) + +Another way of calling TEST_ASSERT_EQUAL_INT + +TEST_ASSERT_INT_WITHIN(delta, expected, actual) + +Asserts that the actual value is within plus or minus delta of the expected value. This also comes in +size specific variants. + + +----------------------------- +Numerical Assertions: Bitwise +----------------------------- + +TEST_ASSERT_BITS(mask, expected, actual) + +Use an integer mask to specify which bits should be compared between two other integers. High bits in the mask are compared, low bits ignored. + +TEST_ASSERT_BITS_HIGH(mask, actual) + +Use an integer mask to specify which bits should be inspected to determine if they are all set high. High bits in the mask are compared, low bits ignored. + +TEST_ASSERT_BITS_LOW(mask, actual) + +Use an integer mask to specify which bits should be inspected to determine if they are all set low. High bits in the mask are compared, low bits ignored. + +TEST_ASSERT_BIT_HIGH(bit, actual) + +Test a single bit and verify that it is high. The bit is specified 0-31 for a 32-bit integer. + +TEST_ASSERT_BIT_LOW(bit, actual) + +Test a single bit and verify that it is low. The bit is specified 0-31 for a 32-bit integer. + +---------------------------- +Numerical Assertions: Floats +---------------------------- + +TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual) + +Asserts that the actual value is within plus or minus delta of the expected value. + +TEST_ASSERT_EQUAL_FLOAT(expected, actual) +TEST_ASSERT_EQUAL_DOUBLE(expected, actual) + +Asserts that two floating point values are "equal" within a small % delta of the expected value. + +----------------- +String Assertions +----------------- + +TEST_ASSERT_EQUAL_STRING(expected, actual) + +Compare two null-terminate strings. Fail if any character is different or if the lengths are different. + +TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, actual, message) + +Compare two null-terminate strings. Fail if any character is different or if the lengths are different. Output a custom message on failure. + +------------------ +Pointer Assertions +------------------ + +Most pointer operations can be performed by simply using the integer comparisons above. However, a couple of special cases are added for clarity. + +TEST_ASSERT_NULL(pointer) + +Fails if the pointer is not equal to NULL + +TEST_ASSERT_NOT_NULL(pointer) + +Fails if the pointer is equal to NULL + + +----------------- +Memory Assertions +----------------- + +TEST_ASSERT_EQUAL_MEMORY(expected, actual, len) + +Compare two blocks of memory. This is a good generic assertion for types that can't be coerced into acting like +standard types... but since it's a memory compare, you have to be careful that your data types are packed. + +-------- +_MESSAGE +-------- + +you can append _MESSAGE to any of the macros to make them take an additional argument. This argument +is a string that will be printed at the end of the failure strings. This is useful for specifying more +information about the problem. + diff --git a/tests/docs/license.txt b/tests/docs/license.txt new file mode 100644 index 000000000..d0f635fa3 --- /dev/null +++ b/tests/docs/license.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams + +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. diff --git a/tests/testing/.built b/tests/testing/.built new file mode 100644 index 000000000..e69de29bb diff --git a/tests/testing/Kconfig b/tests/testing/Kconfig new file mode 100644 index 000000000..ae2bf3130 --- /dev/null +++ b/tests/testing/Kconfig @@ -0,0 +1,4 @@ +# +# For a description of the syntax of this configuration file, +# see misc/tools/kconfig-language.txt. +# diff --git a/tests/testing/Make.defs b/tests/testing/Make.defs new file mode 100644 index 000000000..fc761474f --- /dev/null +++ b/tests/testing/Make.defs @@ -0,0 +1,37 @@ +############################################################################ +# apps/tests/unity/Make.defs +# Adds selected testing applications to apps/ build +# +# Copyright (C) 2015 Haltian Ltd. All rights reserved. +# Author: Roman Saveljev +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +CONFIGURED_APPS += tests/testing diff --git a/tests/testing/Makefile b/tests/testing/Makefile new file mode 100644 index 000000000..2ae3d138e --- /dev/null +++ b/tests/testing/Makefile @@ -0,0 +1,95 @@ +############################################################################ +# testing/Makefile +# +# Copyright (C) 2015 Haltian Ltd. All rights reserved. +# Author: Roman Saveljev +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +ASRCS = +CSRCS = unity.c unity_fixture.c + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + BIN = ..\..\libapps$(LIBEXT) +else +ifeq ($(WINTOOL),y) + BIN = ..\\..\\libapps$(LIBEXT) +else + BIN = ../../libapps$(LIBEXT) +endif +endif + +ROOTDEPPATH = --dep-path . +VPATH = + +# Build targets + +all: .built +.PHONY: context .depend depend clean distclean + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +.built: $(OBJS) + $(call ARCHIVE, $(BIN), $(OBJS)) + @touch .built + +install: + +context: + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + $(call DELFILE, .built) + $(call CLEAN) + +distclean: clean + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/tests/testing/unity.c b/tests/testing/unity.c new file mode 100644 index 000000000..689103b6d --- /dev/null +++ b/tests/testing/unity.c @@ -0,0 +1,1268 @@ +/* ========================================================================= + Unity Project - A Test Framework for C + Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +============================================================================ */ + +#include +#include + +#define UNITY_FAIL_AND_BAIL { Unity.CurrentTestFailed = 1; UnityAbort(); } +#define UNITY_IGNORE_AND_BAIL { Unity.CurrentTestIgnored = 1; UnityAbort(); } +/// return prematurely if we are already in failure or ignore state +#define UNITY_SKIP_EXECUTION { if ((Unity.CurrentTestFailed != 0) || (Unity.CurrentTestIgnored != 0)) {return;} } +#define UNITY_PRINT_EOL { UNITY_OUTPUT_CHAR('\n'); } + +#define UNITY_MSEC_IN_USEC 1000 +#define UNITY_MIN_TIMEOUT_MSEC 200 + +#define SIG_UNITYSTOP 15 + +struct _Unity Unity; + +const char UnityStrOk[] = "OK"; +const char UnityStrPass[] = "PASS"; +const char UnityStrFail[] = "FAIL"; +const char UnityStrIgnore[] = "IGNORE"; +const char UnityStrNull[] = "NULL"; +const char UnityStrSpacer[] = ". "; +const char UnityStrExpected[] = " Expected "; +const char UnityStrWas[] = " Was "; +const char UnityStrTo[] = " To "; +const char UnityStrElement[] = " Element "; +const char UnityStrByte[] = " Byte "; +const char UnityStrMemory[] = " Memory Mismatch."; +const char UnityStrDelta[] = " Values Not Within Delta "; +const char UnityStrPointless[] = " You Asked Me To Compare Nothing, Which Was Pointless."; +const char UnityStrNullPointerForExpected[] = " Expected pointer to be NULL"; +const char UnityStrNullPointerForActual[] = " Actual pointer was NULL"; +const char UnityStrNot[] = "Not "; +const char UnityStrInf[] = "Infinity"; +const char UnityStrNegInf[] = "Negative Infinity"; +const char UnityStrNaN[] = "NaN"; +const char UnityStrDet[] = "Determinate"; +const char UnityStrErrFloat[] = "Unity Floating Point Disabled"; +const char UnityStrErrDouble[] = "Unity Double Precision Disabled"; +const char UnityStrErr64[] = "Unity 64-bit Support Disabled"; +const char UnityStrBreaker[] = "-----------------------"; +const char UnityStrResultsTests[] = " Tests "; +const char UnityStrResultsFailures[] = " Failures "; +const char UnityStrResultsIgnored[] = " Ignored "; + +#ifndef UNITY_EXCLUDE_FLOAT +// Dividing by these constants produces +/- infinity. +// The rationale is given in UnityAssertFloatIsInf's body. +static const _UF f_zero = 0.0f; +#ifndef UNITY_EXCLUDE_DOUBLE +static const _UD d_zero = 0.0; +#endif +#endif + +// compiler-generic print formatting masks +const _U_UINT UnitySizeMask[] = +{ + 255u, // 0xFF + 65535u, // 0xFFFF + 65535u, + 4294967295u, // 0xFFFFFFFF + 4294967295u, + 4294967295u, + 4294967295u +#ifdef UNITY_SUPPORT_64 + ,0xFFFFFFFFFFFFFFFF +#endif +}; + +struct UnityTimeoutAction +{ + _U_UINT timeout_msec; + pthread_t thread; + bool cancel_protected; +}; + +void UnityPrintFail(void); +void UnityPrintOk(void); + +static void UnityAbort(void) noreturn_function; + +static void UnityAbort(void) +{ + pthread_exit((void*)1); +} + +//----------------------------------------------- +// Pretty Printers & Test Result Output Handlers +//----------------------------------------------- + +void UnityPrint(const char* string) +{ + const char* pch = string; + + if (pch != NULL) + { + while (*pch) + { + // printable characters plus CR & LF are printed + if ((*pch <= 126) && (*pch >= 32)) + { + UNITY_OUTPUT_CHAR(*pch); + } + //write escaped carriage returns + else if (*pch == 13) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('r'); + } + //write escaped line feeds + else if (*pch == 10) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('n'); + } + // unprintable characters are shown as codes + else + { + UNITY_OUTPUT_CHAR('\\'); + UnityPrintNumberHex((_U_UINT)*pch, 2); + } + pch++; + } + } +} + +//----------------------------------------------- +void UnityPrintNumberByStyle(const _U_SINT number, const UNITY_DISPLAY_STYLE_T style) +{ + if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) + { + UnityPrintNumber(number); + } + else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT) + { + UnityPrintNumberUnsigned( (_U_UINT)number & UnitySizeMask[((_U_UINT)style & (_U_UINT)0x0F) - 1] ); + } + else + { + UnityPrintNumberHex((_U_UINT)number, (char)((style & 0x000F) << 1)); + } +} + +//----------------------------------------------- +/// basically do an itoa using as little ram as possible +void UnityPrintNumber(const _U_SINT number_to_print) +{ + _U_SINT divisor = 1; + _U_SINT next_divisor; + _U_UINT number; + + if (number_to_print == (1l << (UNITY_LONG_WIDTH-1))) + { + //The largest representable negative number + UNITY_OUTPUT_CHAR('-'); + number = (1ul << (UNITY_LONG_WIDTH-1)); + } + else if (number_to_print < 0) + { + //Some other negative number + UNITY_OUTPUT_CHAR('-'); + number = (_U_UINT)(-number_to_print); + } + else + { + //Positive number + number = (_U_UINT)number_to_print; + } + + // figure out initial divisor + while (number / divisor > 9) + { + next_divisor = divisor * 10; + if (next_divisor > divisor) + divisor = next_divisor; + else + break; + } + + // now mod and print, then divide divisor + do + { + UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10))); + divisor /= 10; + } + while (divisor > 0); +} + +//----------------------------------------------- +/// basically do an itoa using as little ram as possible +void UnityPrintNumberUnsigned(const _U_UINT number) +{ + _U_UINT divisor = 1; + _U_UINT next_divisor; + + // figure out initial divisor + while (number / divisor > 9) + { + next_divisor = divisor * 10; + if (next_divisor > divisor) + divisor = next_divisor; + else + break; + } + + // now mod and print, then divide divisor + do + { + UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10))); + divisor /= 10; + } + while (divisor > 0); +} + +//----------------------------------------------- +void UnityPrintNumberHex(const _U_UINT number, const char nibbles_to_print) +{ + _U_UINT nibble; + char nibbles = nibbles_to_print; + UNITY_OUTPUT_CHAR('0'); + UNITY_OUTPUT_CHAR('x'); + + while (nibbles > 0) + { + nibble = (number >> (--nibbles << 2)) & 0x0000000F; + if (nibble <= 9) + { + UNITY_OUTPUT_CHAR((char)('0' + nibble)); + } + else + { + UNITY_OUTPUT_CHAR((char)('A' - 10 + nibble)); + } + } +} + +//----------------------------------------------- +void UnityPrintMask(const _U_UINT mask, const _U_UINT number) +{ + _U_UINT current_bit = (_U_UINT)1 << (UNITY_INT_WIDTH - 1); + _US32 i; + + for (i = 0; i < UNITY_INT_WIDTH; i++) + { + if (current_bit & mask) + { + if (current_bit & number) + { + UNITY_OUTPUT_CHAR('1'); + } + else + { + UNITY_OUTPUT_CHAR('0'); + } + } + else + { + UNITY_OUTPUT_CHAR('X'); + } + current_bit = current_bit >> 1; + } +} + +//----------------------------------------------- +#ifdef UNITY_FLOAT_VERBOSE +#include +void UnityPrintFloat(_UF number) +{ + char TempBuffer[32]; + sprintf(TempBuffer, "%.6f", number); + UnityPrint(TempBuffer); +} +#endif + +//----------------------------------------------- + +void UnityPrintFail(void) +{ + UnityPrint(UnityStrFail); +} + +void UnityPrintOk(void) +{ + UnityPrint(UnityStrOk); +} + +//----------------------------------------------- +static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line) +{ + UnityPrint(file); + UNITY_OUTPUT_CHAR(':'); + UnityPrintNumber((_U_SINT)line); + UNITY_OUTPUT_CHAR(':'); + UnityPrint(Unity.CurrentTestName); + UNITY_OUTPUT_CHAR(':'); +} + +//----------------------------------------------- +static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line) +{ + UnityTestResultsBegin(Unity.TestFile, line); + UnityPrint(UnityStrFail); + UNITY_OUTPUT_CHAR(':'); +} + +//----------------------------------------------- +void UnityConcludeTest(void) +{ + if (Unity.CurrentTestIgnored) + { + Unity.TestIgnores++; + } + else if (!Unity.CurrentTestFailed) + { + UnityTestResultsBegin(Unity.TestFile, Unity.CurrentTestLineNumber); + UnityPrint(UnityStrPass); + } + else + { + Unity.TestFailures++; + } + + Unity.CurrentTestFailed = 0; + Unity.CurrentTestIgnored = 0; + UNITY_PRINT_EOL; +} + +//----------------------------------------------- +static void UnityAddMsgIfSpecified(const char* msg) +{ + if (msg) + { + UnityPrint(UnityStrSpacer); + UnityPrint(msg); + } +} + +//----------------------------------------------- +static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual) +{ + UnityPrint(UnityStrExpected); + if (expected != NULL) + { + UNITY_OUTPUT_CHAR('\''); + UnityPrint(expected); + UNITY_OUTPUT_CHAR('\''); + } + else + { + UnityPrint(UnityStrNull); + } + UnityPrint(UnityStrWas); + if (actual != NULL) + { + UNITY_OUTPUT_CHAR('\''); + UnityPrint(actual); + UNITY_OUTPUT_CHAR('\''); + } + else + { + UnityPrint(UnityStrNull); + } +} + +//----------------------------------------------- +// Assertion & Control Helpers +//----------------------------------------------- + +static int UnityCheckArraysForNull(UNITY_PTR_ATTRIBUTE const void* expected, UNITY_PTR_ATTRIBUTE const void* actual, const UNITY_LINE_TYPE lineNumber, const char* msg) +{ + //return true if they are both NULL + if ((expected == NULL) && (actual == NULL)) + return 1; + + //throw error if just expected is NULL + if (expected == NULL) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrNullPointerForExpected); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + + //throw error if just actual is NULL + if (actual == NULL) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrNullPointerForActual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + + //return false if neither is NULL + return 0; +} + +//----------------------------------------------- +// Assertion Functions +//----------------------------------------------- + +void UnityAssertBits(const _U_SINT mask, + const _U_SINT expected, + const _U_SINT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + UNITY_SKIP_EXECUTION; + + if ((mask & expected) != (mask & actual)) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + UnityPrintMask((_U_UINT)mask, (_U_UINT)expected); + UnityPrint(UnityStrWas); + UnityPrintMask((_U_UINT)mask, (_U_UINT)actual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +//----------------------------------------------- +void UnityAssertEqualNumber(const _U_SINT expected, + const _U_SINT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style) +{ + UNITY_SKIP_EXECUTION; + + if (expected != actual) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(expected, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(actual, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +//----------------------------------------------- +void UnityAssertEqualIntArray(UNITY_PTR_ATTRIBUTE const void* expected, + UNITY_PTR_ATTRIBUTE const void* actual, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style) +{ + _UU32 elements = num_elements; + UNITY_PTR_ATTRIBUTE const _US8* ptr_exp = (UNITY_PTR_ATTRIBUTE const _US8*)expected; + UNITY_PTR_ATTRIBUTE const _US8* ptr_act = (UNITY_PTR_ATTRIBUTE const _US8*)actual; + + UNITY_SKIP_EXECUTION; + + if (elements == 0) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrPointless); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + + if (UnityCheckArraysForNull((UNITY_PTR_ATTRIBUTE const void*)expected, (UNITY_PTR_ATTRIBUTE const void*)actual, lineNumber, msg) == 1) + return; + + // If style is UNITY_DISPLAY_STYLE_INT, we'll fall into the default case rather than the INT16 or INT32 (etc) case + // as UNITY_DISPLAY_STYLE_INT includes a flag for UNITY_DISPLAY_RANGE_AUTO, which the width-specific + // variants do not. Therefore remove this flag. + switch(style & (UNITY_DISPLAY_STYLE_T)(~UNITY_DISPLAY_RANGE_AUTO)) + { + case UNITY_DISPLAY_STYLE_HEX8: + case UNITY_DISPLAY_STYLE_INT8: + case UNITY_DISPLAY_STYLE_UINT8: + while (elements--) + { + if (*ptr_exp != *ptr_act) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(*ptr_exp, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(*ptr_act, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_exp += 1; + ptr_act += 1; + } + break; + case UNITY_DISPLAY_STYLE_HEX16: + case UNITY_DISPLAY_STYLE_INT16: + case UNITY_DISPLAY_STYLE_UINT16: + while (elements--) + { + if (*(UNITY_PTR_ATTRIBUTE _US16*)ptr_exp != *(UNITY_PTR_ATTRIBUTE _US16*)ptr_act) + { + if (*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US16*)ptr_act) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_exp, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_act, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_exp += 2; + ptr_act += 2; + } + ptr_exp += 2; + ptr_act += 2; + } + break; +#ifdef UNITY_SUPPORT_64 + case UNITY_DISPLAY_STYLE_HEX64: + case UNITY_DISPLAY_STYLE_INT64: + case UNITY_DISPLAY_STYLE_UINT64: + while (elements--) + { + if (*(UNITY_PTR_ATTRIBUTE _US64*)ptr_exp != *(UNITY_PTR_ATTRIBUTE _US64*)ptr_act) + { + if (*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US64*)ptr_act) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_exp, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_act, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_exp += 8; + ptr_act += 8; + } + ptr_exp += 8; + ptr_act += 8; + } + break; +#endif + default: + while (elements--) + { + if (*(UNITY_PTR_ATTRIBUTE _US32*)ptr_exp != *(UNITY_PTR_ATTRIBUTE _US32*)ptr_act) + { + if (*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US32*)ptr_act) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_exp, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_act, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_exp += 4; + ptr_act += 4; + } + ptr_exp += 4; + ptr_act += 4; + } + break; + } +} + +//----------------------------------------------- +#ifndef UNITY_EXCLUDE_FLOAT +void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const _UF* expected, + UNITY_PTR_ATTRIBUTE const _UF* actual, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + _UU32 elements = num_elements; + UNITY_PTR_ATTRIBUTE const _UF* ptr_expected = expected; + UNITY_PTR_ATTRIBUTE const _UF* ptr_actual = actual; + _UF diff, tol; + + UNITY_SKIP_EXECUTION; + + if (elements == 0) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrPointless); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + + if (UnityCheckArraysForNull((UNITY_PTR_ATTRIBUTE const void*)expected, (UNITY_PTR_ATTRIBUTE const void*)actual, lineNumber, msg) == 1) + return; + + while (elements--) + { + diff = *ptr_expected - *ptr_actual; + if (diff < 0.0f) + diff = 0.0f - diff; + tol = UNITY_FLOAT_PRECISION **ptr_expected; + if (tol < 0.0f) + tol = 0.0f - tol; + + //This first part of this condition will catch any NaN or Infinite values + if ((diff * 0.0f != 0.0f) || (diff > tol)) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); +#ifdef UNITY_FLOAT_VERBOSE + UnityPrint(UnityStrExpected); + UnityPrintFloat(*ptr_expected); + UnityPrint(UnityStrWas); + UnityPrintFloat(*ptr_actual); +#else + UnityPrint(UnityStrDelta); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_expected++; + ptr_actual++; + } +} + +//----------------------------------------------- +void UnityAssertFloatsWithin(const _UF delta, + const _UF expected, + const _UF actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + _UF diff = actual - expected; + _UF pos_delta = delta; + + UNITY_SKIP_EXECUTION; + + if (diff < 0.0f) + { + diff = 0.0f - diff; + } + if (pos_delta < 0.0f) + { + pos_delta = 0.0f - pos_delta; + } + + //This first part of this condition will catch any NaN or Infinite values + if ((diff * 0.0f != 0.0f) || (pos_delta < diff)) + { + UnityTestResultsFailBegin(lineNumber); +#ifdef UNITY_FLOAT_VERBOSE + UnityPrint(UnityStrExpected); + UnityPrintFloat(expected); + UnityPrint(UnityStrWas); + UnityPrintFloat(actual); +#else + UnityPrint(UnityStrDelta); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +//----------------------------------------------- +void UnityAssertFloatSpecial(const _UF actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style) +{ + const char* trait_names[] = { UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet }; + _U_SINT should_be_trait = ((_U_SINT)style & 1); + _U_SINT is_trait = !should_be_trait; + _U_SINT trait_index = style >> 1; + + UNITY_SKIP_EXECUTION; + + switch(style) + { + //To determine Inf / Neg Inf, we compare to an Inf / Neg Inf value we create on the fly + //We are using a variable to hold the zero value because some compilers complain about dividing by zero otherwise + case UNITY_FLOAT_IS_INF: + case UNITY_FLOAT_IS_NOT_INF: + is_trait = ((1.0f / f_zero) == actual) ? 1 : 0; + break; + case UNITY_FLOAT_IS_NEG_INF: + case UNITY_FLOAT_IS_NOT_NEG_INF: + is_trait = ((-1.0f / f_zero) == actual) ? 1 : 0; + break; + + //NaN is the only floating point value that does NOT equal itself. Therefore if Actual == Actual, then it is NOT NaN. + case UNITY_FLOAT_IS_NAN: + case UNITY_FLOAT_IS_NOT_NAN: + is_trait = (actual == actual) ? 0 : 1; + break; + + //A determinate number is non infinite and not NaN. (therefore the opposite of the two above) + case UNITY_FLOAT_IS_DET: + case UNITY_FLOAT_IS_NOT_DET: + if ( (actual != actual) || ((1.0f / f_zero) == actual) || ((-1.0f / f_zero) == actual) ) + is_trait = 0; + else + is_trait = 1; + break; + default: + ; + } + + if (is_trait != should_be_trait) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + if (!should_be_trait) + UnityPrint(UnityStrNot); + UnityPrint(trait_names[trait_index]); + UnityPrint(UnityStrWas); +#ifdef UNITY_FLOAT_VERBOSE + UnityPrintFloat(actual); +#else + if (should_be_trait) + UnityPrint(UnityStrNot); + UnityPrint(trait_names[trait_index]); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +#endif //not UNITY_EXCLUDE_FLOAT + +//----------------------------------------------- +#ifndef UNITY_EXCLUDE_DOUBLE +void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const _UD* expected, + UNITY_PTR_ATTRIBUTE const _UD* actual, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + _UU32 elements = num_elements; + UNITY_PTR_ATTRIBUTE const _UD* ptr_expected = expected; + UNITY_PTR_ATTRIBUTE const _UD* ptr_actual = actual; + _UD diff, tol; + + UNITY_SKIP_EXECUTION; + + if (elements == 0) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrPointless); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + + if (UnityCheckArraysForNull((UNITY_PTR_ATTRIBUTE void*)expected, (UNITY_PTR_ATTRIBUTE void*)actual, lineNumber, msg) == 1) + return; + + while (elements--) + { + diff = *ptr_expected - *ptr_actual; + if (diff < 0.0) + diff = 0.0 - diff; + tol = UNITY_DOUBLE_PRECISION **ptr_expected; + if (tol < 0.0) + tol = 0.0 - tol; + + //This first part of this condition will catch any NaN or Infinite values + if ((diff * 0.0 != 0.0) || (diff > tol)) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); +#ifdef UNITY_DOUBLE_VERBOSE + UnityPrint(UnityStrExpected); + UnityPrintFloat((float)(*ptr_expected)); + UnityPrint(UnityStrWas); + UnityPrintFloat((float)(*ptr_actual)); +#else + UnityPrint(UnityStrDelta); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_expected++; + ptr_actual++; + } +} + +//----------------------------------------------- +void UnityAssertDoublesWithin(const _UD delta, + const _UD expected, + const _UD actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + _UD diff = actual - expected; + _UD pos_delta = delta; + + UNITY_SKIP_EXECUTION; + + if (diff < 0.0) + { + diff = 0.0 - diff; + } + if (pos_delta < 0.0) + { + pos_delta = 0.0 - pos_delta; + } + + //This first part of this condition will catch any NaN or Infinite values + if ((diff * 0.0 != 0.0) || (pos_delta < diff)) + { + UnityTestResultsFailBegin(lineNumber); +#ifdef UNITY_DOUBLE_VERBOSE + UnityPrint(UnityStrExpected); + UnityPrintFloat((float)expected); + UnityPrint(UnityStrWas); + UnityPrintFloat((float)actual); +#else + UnityPrint(UnityStrDelta); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +//----------------------------------------------- + +void UnityAssertDoubleSpecial(const _UD actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style) +{ + const char* trait_names[] = { UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet }; + _U_SINT should_be_trait = ((_U_SINT)style & 1); + _U_SINT is_trait = !should_be_trait; + _U_SINT trait_index = style >> 1; + + UNITY_SKIP_EXECUTION; + + switch(style) + { + //To determine Inf / Neg Inf, we compare to an Inf / Neg Inf value we create on the fly + //We are using a variable to hold the zero value because some compilers complain about dividing by zero otherwise + case UNITY_FLOAT_IS_INF: + case UNITY_FLOAT_IS_NOT_INF: + is_trait = ((1.0 / d_zero) == actual) ? 1 : 0; + break; + case UNITY_FLOAT_IS_NEG_INF: + case UNITY_FLOAT_IS_NOT_NEG_INF: + is_trait = ((-1.0 / d_zero) == actual) ? 1 : 0; + break; + + //NaN is the only floating point value that does NOT equal itself. Therefore if Actual == Actual, then it is NOT NaN. + case UNITY_FLOAT_IS_NAN: + case UNITY_FLOAT_IS_NOT_NAN: + is_trait = (actual == actual) ? 0 : 1; + break; + + //A determinate number is non infinite and not NaN. (therefore the opposite of the two above) + case UNITY_FLOAT_IS_DET: + case UNITY_FLOAT_IS_NOT_DET: + if ( (actual != actual) || ((1.0 / d_zero) == actual) || ((-1.0 / d_zero) == actual) ) + is_trait = 0; + else + is_trait = 1; + break; + default: + ; + } + + if (is_trait != should_be_trait) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + if (!should_be_trait) + UnityPrint(UnityStrNot); + UnityPrint(trait_names[trait_index]); + UnityPrint(UnityStrWas); +#ifdef UNITY_DOUBLE_VERBOSE + UnityPrintFloat(actual); +#else + if (should_be_trait) + UnityPrint(UnityStrNot); + UnityPrint(trait_names[trait_index]); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + + +#endif // not UNITY_EXCLUDE_DOUBLE + +//----------------------------------------------- +void UnityAssertNumbersWithin( const _U_SINT delta, + const _U_SINT expected, + const _U_SINT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style) +{ + UNITY_SKIP_EXECUTION; + + if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) + { + if (actual > expected) + Unity.CurrentTestFailed = ((actual - expected) > delta); + else + Unity.CurrentTestFailed = ((expected - actual) > delta); + } + else + { + if ((_U_UINT)actual > (_U_UINT)expected) + Unity.CurrentTestFailed = ((_U_UINT)(actual - expected) > (_U_UINT)delta); + else + Unity.CurrentTestFailed = ((_U_UINT)(expected - actual) > (_U_UINT)delta); + } + + if (Unity.CurrentTestFailed) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrDelta); + UnityPrintNumberByStyle(delta, style); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(expected, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(actual, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +//----------------------------------------------- +void UnityAssertEqualString(const char* expected, + const char* actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + _UU32 i; + + UNITY_SKIP_EXECUTION; + + // if both pointers not null compare the strings + if (expected && actual) + { + for (i = 0; expected[i] || actual[i]; i++) + { + if (expected[i] != actual[i]) + { + Unity.CurrentTestFailed = 1; + break; + } + } + } + else + { + // handle case of one pointers being null (if both null, test should pass) + if (expected != actual) + { + Unity.CurrentTestFailed = 1; + } + } + + if (Unity.CurrentTestFailed) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrintExpectedAndActualStrings(expected, actual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +//----------------------------------------------- +void UnityAssertEqualStringArray( const char** expected, + const char** actual, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + _UU32 i, j = 0; + + UNITY_SKIP_EXECUTION; + + // if no elements, it's an error + if (num_elements == 0) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrPointless); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + + if (UnityCheckArraysForNull((UNITY_PTR_ATTRIBUTE void*)expected, (UNITY_PTR_ATTRIBUTE void*)actual, lineNumber, msg) == 1) + return; + + do + { + // if both pointers not null compare the strings + if (expected[j] && actual[j]) + { + for (i = 0; expected[j][i] || actual[j][i]; i++) + { + if (expected[j][i] != actual[j][i]) + { + Unity.CurrentTestFailed = 1; + break; + } + } + } + else + { + // handle case of one pointers being null (if both null, test should pass) + if (expected[j] != actual[j]) + { + Unity.CurrentTestFailed = 1; + } + } + + if (Unity.CurrentTestFailed) + { + UnityTestResultsFailBegin(lineNumber); + if (num_elements > 1) + { + UnityPrint(UnityStrElement); + UnityPrintNumberByStyle((j), UNITY_DISPLAY_STYLE_UINT); + } + UnityPrintExpectedAndActualStrings((const char*)(expected[j]), (const char*)(actual[j])); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + } + while (++j < num_elements); +} + +//----------------------------------------------- +void UnityAssertEqualMemory( UNITY_PTR_ATTRIBUTE const void* expected, + UNITY_PTR_ATTRIBUTE const void* actual, + const _UU32 length, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + UNITY_PTR_ATTRIBUTE const unsigned char* ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected; + UNITY_PTR_ATTRIBUTE const unsigned char* ptr_act = (UNITY_PTR_ATTRIBUTE const unsigned char*)actual; + _UU32 elements = num_elements; + _UU32 bytes; + + UNITY_SKIP_EXECUTION; + + if ((elements == 0) || (length == 0)) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrPointless); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + + if (UnityCheckArraysForNull((UNITY_PTR_ATTRIBUTE const void*)expected, (UNITY_PTR_ATTRIBUTE const void*)actual, lineNumber, msg) == 1) + return; + + while (elements--) + { + ///////////////////////////////////// + bytes = length; + while (bytes--) + { + if (*ptr_exp != *ptr_act) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrMemory); + if (num_elements > 1) + { + UnityPrint(UnityStrElement); + UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); + } + UnityPrint(UnityStrByte); + UnityPrintNumberByStyle((length - bytes - 1), UNITY_DISPLAY_STYLE_UINT); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(*ptr_exp, UNITY_DISPLAY_STYLE_HEX8); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(*ptr_act, UNITY_DISPLAY_STYLE_HEX8); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_exp += 1; + ptr_act += 1; + } + ///////////////////////////////////// + + } +} + +//----------------------------------------------- +// Control Functions +//----------------------------------------------- + +void UnityFail(const char* msg, const UNITY_LINE_TYPE line) +{ + UNITY_SKIP_EXECUTION; + + UnityTestResultsBegin(Unity.TestFile, line); + UnityPrintFail(); + if (msg != NULL) + { + UNITY_OUTPUT_CHAR(':'); + if (msg[0] != ' ') + { + UNITY_OUTPUT_CHAR(' '); + } + UnityPrint(msg); + } + UNITY_FAIL_AND_BAIL; +} + +//----------------------------------------------- +void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line) +{ + UNITY_SKIP_EXECUTION; + + UnityTestResultsBegin(Unity.TestFile, line); + UnityPrint(UnityStrIgnore); + if (msg != NULL) + { + UNITY_OUTPUT_CHAR(':'); + UNITY_OUTPUT_CHAR(' '); + UnityPrint(msg); + } + UNITY_IGNORE_AND_BAIL; +} + +//----------------------------------------------- +#if defined(UNITY_WEAK_ATTRIBUTE) + void setUp(void); + void tearDown(void); + UNITY_WEAK_ATTRIBUTE void setUp(void) { } + UNITY_WEAK_ATTRIBUTE void tearDown(void) { } +#elif defined(UNITY_WEAK_PRAGMA) +# pragma weak setUp + void setUp(void); +# pragma weak tearDown + void tearDown(void); +#else + void setUp(void); + void tearDown(void); +#endif +//----------------------------------------------- +void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum) +{ + Unity.CurrentTestName = FuncName; + Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)FuncLineNum; + Unity.NumberOfTests++; + if (TEST_PROTECTED(setUp) == 0) + { + TEST_PROTECTED(Func); + } + if (!(Unity.CurrentTestIgnored)) + { + TEST_PROTECTED(tearDown); + } + UnityConcludeTest(); +} + +//----------------------------------------------- +void UnityBegin(const char* filename) +{ + Unity.TestFile = filename; + Unity.CurrentTestName = NULL; + Unity.CurrentTestLineNumber = 0; + Unity.NumberOfTests = 0; + Unity.TestFailures = 0; + Unity.TestIgnores = 0; + Unity.CurrentTestFailed = 0; + Unity.CurrentTestIgnored = 0; + Unity.CurrentTestTimeout = 0; + + UNITY_OUTPUT_START(); +} + +//----------------------------------------------- +int UnityEnd(void) +{ + UNITY_PRINT_EOL; + UnityPrint(UnityStrBreaker); + UNITY_PRINT_EOL; + UnityPrintNumber((_U_SINT)(Unity.NumberOfTests)); + UnityPrint(UnityStrResultsTests); + UnityPrintNumber((_U_SINT)(Unity.TestFailures)); + UnityPrint(UnityStrResultsFailures); + UnityPrintNumber((_U_SINT)(Unity.TestIgnores)); + UnityPrint(UnityStrResultsIgnored); + UNITY_PRINT_EOL; + if (Unity.TestFailures == 0U) + { + UnityPrintOk(); + } + else + { + UnityPrintFail(); + } + UNITY_PRINT_EOL; + UNITY_OUTPUT_COMPLETE(); + return (int)(Unity.TestFailures); +} + +static void* UnityTimeoutThread(pthread_addr_t value) +{ + struct UnityTimeoutAction *timeout = (struct UnityTimeoutAction *)value; + + usleep(timeout->timeout_msec * UNITY_MSEC_IN_USEC); + + if (!timeout->cancel_protected) + return NULL; + + (void)pthread_kill(timeout->thread, SIG_UNITYSTOP); + Unity.CurrentTestTimeout = 1; + return NULL; +} + +static void* UnityProtectedThread(pthread_addr_t value) +{ + UnityTestFunction function = (UnityTestFunction)value; + function(); + return NULL; +} + +int UnityProtect(UnityTestFunction function, _U_UINT timeout_msec) +{ + struct UnityTimeoutAction action; + pthread_t thread, timeout_thread; + + if (timeout_msec < UNITY_MIN_TIMEOUT_MSEC) + timeout_msec = UNITY_MIN_TIMEOUT_MSEC; + + action.timeout_msec = timeout_msec; + action.cancel_protected = true; + + int result = pthread_create(&thread, NULL, UnityProtectedThread, (pthread_addr_t)function); + if (result == OK) + { + action.thread = thread; + result = pthread_create(&timeout_thread, NULL, UnityTimeoutThread, (pthread_addr_t)&action); + if (result == OK) + { + pthread_addr_t value; + result = pthread_join(thread, &value); + action.cancel_protected = false; + (void)pthread_kill(timeout_thread, SIG_UNITYSTOP); + (void)pthread_join(timeout_thread, &value); + if (result == 0) + { + result = Unity.CurrentTestFailed || Unity.CurrentTestTimeout ? 1 : 0; + } + } + } + return result; +} + +//----------------------------------------------- diff --git a/tests/testing/unity_fixture.c b/tests/testing/unity_fixture.c new file mode 100644 index 000000000..aedbe4e5e --- /dev/null +++ b/tests/testing/unity_fixture.c @@ -0,0 +1,466 @@ +//- Copyright (c) 2010 James Grenning and Contributed to Unity Project +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#include +#include +#include +#include +#include + +UNITY_FIXTURE_T UnityFixture; + +static char const* emptyList[] = {NULL}; + +int verbose = 0; + +void setUp(void); +void tearDown(void); +void setUp(void) { /*does nothing*/ } +void tearDown(void) { /*does nothing*/ } + +static void announceTestRun(unsigned int runNumber) +{ + UnityPrint("Unity test run "); + UnityPrintNumber(runNumber+1); + UnityPrint(" of "); + UnityPrintNumber(UnityFixture.RepeatCount); + UNITY_OUTPUT_CHAR('\n'); +} + +int UnityMain(int argc, const char* argv[], void (*runAllTests)(void)) +{ + int result = UnityGetCommandLineOptions(argc, argv); + unsigned int r; + if (result != 0) + return result; + + for (r = 0; r < UnityFixture.RepeatCount; r++) + { + UnityBegin(argv[0]); + announceTestRun(r); + runAllTests(); + UNITY_OUTPUT_CHAR('\n'); + UnityEnd(); + } + + return UnityFailureCount(); +} + +static int selected(const char * filter, const char * name) +{ + if (filter == 0) + return 1; + return strstr(name, filter) ? 1 : 0; +} + +static int testSelected(const char* test) +{ + return selected(UnityFixture.NameFilter, test); +} + +static int groupSelected(const char* group) +{ + return selected(UnityFixture.GroupFilter, group); +} + +static int plainSelected(const char* group, const char* test) +{ + if (UnityFixture.PlainListOfTests[0] == NULL) + { + return 1; + } + else + { + const char** plain = UnityFixture.PlainListOfTests; + while (plain[0] != NULL) + { + const char* selector = plain[0]; + int groupLen = strlen(group); + int testLen = strlen(test); + if (groupLen + testLen + 1 == strlen(selector) && + selector[groupLen] == '/' && + strstr(selector, group) == selector && + strstr(selector + groupLen + 1, test) == selector + groupLen + 1) + { + return 1; + } + plain++; + } + return 0; + } +} + +static void runTestCase(void) +{ + +} + +void UnityTestRunner(unityfunction* setup, _U_UINT setupTimeoutMsec, + unityfunction* testBody, _U_UINT bodyTimeoutMsec, + unityfunction* teardown, _U_UINT teardownTimeoutMsec, + const char * printableName, + const char * group, + const char * name, + const char * file, int line) +{ + if (testSelected(name) && groupSelected(group) && plainSelected(group, name)) + { + Unity.CurrentTestFailed = 0; + Unity.TestFile = file; + Unity.CurrentTestName = printableName; + Unity.CurrentTestLineNumber = line; + if (UnityFixture.ListOnly) + { + UnityPrint(group); + UNITY_OUTPUT_CHAR('/'); + UnityPrint(name); + UNITY_OUTPUT_CHAR('\n'); + Unity.NumberOfTests++; + } + else + { + if (!UnityFixture.Verbose) + UNITY_OUTPUT_CHAR('.'); + else + { + UnityPrint(printableName); + UNITY_OUTPUT_CHAR(' '); + } + + Unity.NumberOfTests++; + UnityMalloc_StartTest(); + UnityPointer_Init(); + + runTestCase(); + if (TEST_PROTECTED_WITH_TIMEOUT(setup, setupTimeoutMsec) == 0) + { + TEST_PROTECTED_WITH_TIMEOUT(testBody, bodyTimeoutMsec); + } + TEST_PROTECTED_WITH_TIMEOUT(teardown, teardownTimeoutMsec); + + UnityPointer_UndoAllSets(); + if (!Unity.CurrentTestFailed && !Unity.CurrentTestTimeout) + TEST_PROTECTED(UnityMalloc_EndTest); + + if (Unity.CurrentTestFailed && UnityFixture.Verbose) + { + UNITY_OUTPUT_CHAR('\n'); + } + } + UnityConcludeFixtureTest(); + } +} + +void UnityIgnoreTest(const char * printableName) +{ + Unity.NumberOfTests++; + Unity.CurrentTestIgnored = 1; + if (!UnityFixture.Verbose) + UNITY_OUTPUT_CHAR('!'); + else + UnityPrint(printableName); + UnityConcludeFixtureTest(); +} + + +//------------------------------------------------- +//Malloc and free stuff +// +#define MALLOC_DONT_FAIL -1 +static int malloc_count; +static int malloc_fail_countdown = MALLOC_DONT_FAIL; + +void UnityMalloc_StartTest(void) +{ + malloc_count = 0; + malloc_fail_countdown = MALLOC_DONT_FAIL; +} + +void UnityMalloc_EndTest(void) +{ + malloc_fail_countdown = MALLOC_DONT_FAIL; + if (malloc_count != 0) + { + TEST_FAIL_MESSAGE("This test leaks!"); + } +} + +void UnityMalloc_MakeMallocFailAfterCount(int countdown) +{ + malloc_fail_countdown = countdown; +} + +#ifdef malloc +#undef malloc +#endif + +#ifdef free +#undef free +#endif + +#ifdef calloc +#undef calloc +#endif + +#ifdef realloc +#undef realloc +#endif + +#include +#include + +typedef struct GuardBytes +{ + size_t size; + char guard[sizeof(size_t)]; +} Guard; + + +static const char * end = "END"; + +void * unity_malloc(size_t size) +{ + char* mem; + Guard* guard; + + if (malloc_fail_countdown != MALLOC_DONT_FAIL) + { + if (malloc_fail_countdown == 0) + return 0; + malloc_fail_countdown--; + } + + malloc_count++; + + guard = (Guard*)malloc(size + sizeof(Guard) + 4); + guard->size = size; + mem = (char*)&(guard[1]); + memcpy(&mem[size], end, strlen(end) + 1); + + return (void*)mem; +} + +static int isOverrun(void * mem) +{ + Guard* guard = (Guard*)mem; + char* memAsChar = (char*)mem; + guard--; + + return strcmp(&memAsChar[guard->size], end) != 0; +} + +static void release_memory(void * mem) +{ + Guard* guard = (Guard*)mem; + guard--; + + malloc_count--; + free(guard); +} + +void unity_free(void * mem) +{ + if (!mem) + { + /* Freeing NULL should be always OK */ + return; + } + int overrun = isOverrun(mem);//strcmp(&memAsChar[guard->size], end) != 0; + release_memory(mem); + if (overrun) + { + TEST_FAIL_MESSAGE("Buffer overrun detected during free()"); + } +} + +void* unity_calloc(size_t num, size_t size) +{ + void* mem = unity_malloc(num * size); + memset(mem, 0, num*size); + return mem; +} + +void* unity_realloc(void * oldMem, size_t size) +{ + Guard* guard = (Guard*)oldMem; +// char* memAsChar = (char*)oldMem; + void* newMem; + + if (oldMem == 0) + return unity_malloc(size); + + guard--; + if (isOverrun(oldMem)) + { + release_memory(oldMem); + TEST_FAIL_MESSAGE("Buffer overrun detected during realloc()"); + return 0; /* Above will not abort the test, if the execution is skipped */ + } + + if (size == 0) + { + release_memory(oldMem); + return 0; + } + + if (guard->size >= size) + return oldMem; + + newMem = unity_malloc(size); + memcpy(newMem, oldMem, guard->size); + unity_free(oldMem); + return newMem; +} + + +//-------------------------------------------------------- +//Automatic pointer restoration functions +typedef struct _PointerPair +{ + struct _PointerPair * next; + void ** pointer; + void * old_value; +} PointerPair; + +enum {MAX_POINTERS=50}; +static PointerPair pointer_store[MAX_POINTERS]; +static int pointer_index = 0; + +void UnityPointer_Init(void) +{ + pointer_index = 0; +} + +void UnityPointer_Set(void ** pointer, void * newValue) +{ + if (pointer_index >= MAX_POINTERS) + TEST_FAIL_MESSAGE("Too many pointers set"); + + pointer_store[pointer_index].pointer = pointer; + pointer_store[pointer_index].old_value = *pointer; + *pointer = newValue; + pointer_index++; +} + +void UnityPointer_UndoAllSets(void) +{ + while (pointer_index > 0) + { + pointer_index--; + *(pointer_store[pointer_index].pointer) = + pointer_store[pointer_index].old_value; + + } +} + +int UnityFailureCount(void) +{ + return Unity.TestFailures; +} + +int UnityGetCommandLineOptions(int argc, const char* argv[]) +{ + int i; + UnityFixture.Verbose = 0; + UnityFixture.ListOnly = 0; + UnityFixture.GroupFilter = 0; + UnityFixture.NameFilter = 0; + UnityFixture.RepeatCount = 1; + UnityFixture.PlainListOfTests = emptyList; + + if (argc == 1) + return 0; + + for (i = 1; i < argc; ) + { + if (strcmp(argv[i], "-l") == 0) + { + UnityFixture.ListOnly = 1; + i++; + } + else if (strcmp(argv[i], "-v") == 0) + { + UnityFixture.Verbose = 1; + i++; + } + else if (strcmp(argv[i], "-g") == 0) + { + i++; + if (i >= argc) + return 1; + UnityFixture.GroupFilter = argv[i]; + i++; + } + else if (strcmp(argv[i], "-n") == 0) + { + i++; + if (i >= argc) + return 1; + UnityFixture.NameFilter = argv[i]; + i++; + } + else if (strcmp(argv[i], "-r") == 0) + { + UnityFixture.RepeatCount = 2; + i++; + if (i < argc) + { + if (*(argv[i]) >= '0' && *(argv[i]) <= '9') + { + UnityFixture.RepeatCount = atoi(argv[i]); + i++; + } + } + } + else if (strcmp(argv[i], "--") == 0) + { + UnityFixture.PlainListOfTests = argv + i + 1; + break; + } + else { + // ignore unknown parameter + i++; + } + } + return 0; +} + +void UnityConcludeFixtureTest(void) +{ + if (Unity.CurrentTestIgnored) + { + if (UnityFixture.Verbose) + { + UNITY_OUTPUT_CHAR('\n'); + } + Unity.TestIgnores++; + } + else if (Unity.CurrentTestTimeout) + { + if (UnityFixture.Verbose) + { + UnityPrint(" TIMEOUT"); + UNITY_OUTPUT_CHAR('\n'); + } + Unity.TestFailures++; + } + else if (!Unity.CurrentTestFailed) + { + if (UnityFixture.Verbose) + { + UnityPrint(" PASS"); + UNITY_OUTPUT_CHAR('\n'); + } + } + else if (Unity.CurrentTestFailed) + { + Unity.TestFailures++; + } + + Unity.CurrentTestFailed = 0; + Unity.CurrentTestIgnored = 0; +} diff --git a/tests/tools/auto/colour_prompt.rb b/tests/tools/auto/colour_prompt.rb new file mode 100644 index 000000000..8adab6e61 --- /dev/null +++ b/tests/tools/auto/colour_prompt.rb @@ -0,0 +1,115 @@ +# ========================================== +# Unity Project - A Test Framework for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +if RUBY_PLATFORM =~/(win|w)32$/ + begin + require 'Win32API' + rescue LoadError + puts "ERROR! \"Win32API\" library not found" + puts "\"Win32API\" is required for colour on a windows machine" + puts " try => \"gem install Win32API\" on the command line" + puts + end + # puts + # puts 'Windows Environment Detected...' + # puts 'Win32API Library Found.' + # puts +end + +class ColourCommandLine + def initialize + if RUBY_PLATFORM =~/(win|w)32$/ + get_std_handle = Win32API.new("kernel32", "GetStdHandle", ['L'], 'L') + @set_console_txt_attrb = + Win32API.new("kernel32","SetConsoleTextAttribute",['L','N'], 'I') + @hout = get_std_handle.call(-11) + end + end + + def change_to(new_colour) + if RUBY_PLATFORM =~/(win|w)32$/ + @set_console_txt_attrb.call(@hout,self.win32_colour(new_colour)) + else + "\033[30;#{posix_colour(new_colour)};22m" + end + end + + def win32_colour(colour) + case colour + when :black then 0 + when :dark_blue then 1 + when :dark_green then 2 + when :dark_cyan then 3 + when :dark_red then 4 + when :dark_purple then 5 + when :dark_yellow, :narrative then 6 + when :default_white, :default, :dark_white then 7 + when :silver then 8 + when :blue then 9 + when :green, :success then 10 + when :cyan, :output then 11 + when :red, :failure then 12 + when :purple then 13 + when :yellow then 14 + when :white then 15 + else + 0 + end + end + + def posix_colour(colour) + # ANSI Escape Codes - Foreground colors + # | Code | Color | + # | 39 | Default foreground color | + # | 30 | Black | + # | 31 | Red | + # | 32 | Green | + # | 33 | Yellow | + # | 34 | Blue | + # | 35 | Magenta | + # | 36 | Cyan | + # | 37 | Light gray | + # | 90 | Dark gray | + # | 91 | Light red | + # | 92 | Light green | + # | 93 | Light yellow | + # | 94 | Light blue | + # | 95 | Light magenta | + # | 96 | Light cyan | + # | 97 | White | + + case colour + when :black then 30 + when :red, :failure then 31 + when :green, :success then 32 + when :yellow then 33 + when :blue, :narrative then 34 + when :purple, :magenta then 35 + when :cyan, :output then 36 + when :white, :default_white then 37 + when :default then 39 + else + 39 + end + end + + def out_c(mode, colour, str) + case RUBY_PLATFORM + when /(win|w)32$/ + change_to(colour) + $stdout.puts str if mode == :puts + $stdout.print str if mode == :print + change_to(:default_white) + else + $stdout.puts("#{change_to(colour)}#{str}\033[0m") if mode == :puts + $stdout.print("#{change_to(colour)}#{str}\033[0m") if mode == :print + end + end +end # ColourCommandLine + +def colour_puts(role,str) ColourCommandLine.new.out_c(:puts, role, str) end +def colour_print(role,str) ColourCommandLine.new.out_c(:print, role, str) end + diff --git a/tests/tools/auto/colour_reporter.rb b/tests/tools/auto/colour_reporter.rb new file mode 100644 index 000000000..89e79519c --- /dev/null +++ b/tests/tools/auto/colour_reporter.rb @@ -0,0 +1,39 @@ +# ========================================== +# Unity Project - A Test Framework for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +require "#{File.expand_path(File.dirname(__FILE__))}/colour_prompt" + +$colour_output = true + +def report(message) + if not $colour_output + $stdout.puts(message) + else + message = message.join('\n') if (message.class == Array) + message.each_line do |line| + line.chomp! + colour = case(line) + when /(?:total\s+)?tests:?\s+(\d+)\s+(?:total\s+)?failures:?\s+\d+\s+Ignored:?/i + ($1.to_i == 0) ? :green : :red + when /PASS/ + :green + when /^OK$/ + :green + when /(?:FAIL|ERROR)/ + :red + when /IGNORE/ + :yellow + when /^(?:Creating|Compiling|Linking)/ + :white + else + :silver + end + colour_puts(colour, line) + end + end + $stdout.flush + $stderr.flush +end \ No newline at end of file diff --git a/tests/tools/auto/generate_config.yml b/tests/tools/auto/generate_config.yml new file mode 100644 index 000000000..ce66cead5 --- /dev/null +++ b/tests/tools/auto/generate_config.yml @@ -0,0 +1,36 @@ +#this is a sample configuration file for generate_module +#you would use it by calling generate_module with the -ygenerate_config.yml option +#files like this are useful for customizing generate_module to your environment +:generate_module: + :defaults: + #these defaults are used in place of any missing options at the command line + :path_src: ../src/ + :path_inc: ../src/ + :path_tst: ../test/ + :update_svn: true + :includes: + #use [] for no additional includes, otherwise list the includes on separate lines + :src: + - Defs.h + - Board.h + :inc: [] + :tst: + - Defs.h + - Board.h + - Exception.h + :boilerplates: + #these are inserted at the top of generated files. + #just comment out or remove if not desired. + #use %1$s where you would like the file name to appear (path/extension not included) + :src: | + //------------------------------------------- + // %1$s.c + //------------------------------------------- + :inc: | + //------------------------------------------- + // %1$s.h + //------------------------------------------- + :tst: | + //------------------------------------------- + // Test%1$s.c : Units tests for %1$s.c + //------------------------------------------- diff --git a/tests/tools/auto/generate_module.rb b/tests/tools/auto/generate_module.rb new file mode 100644 index 000000000..4a020ebbf --- /dev/null +++ b/tests/tools/auto/generate_module.rb @@ -0,0 +1,202 @@ +# ========================================== +# Unity Project - A Test Framework for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +# This script creates all the files with start code necessary for a new module. +# A simple module only requires a source file, header file, and test file. +# Triad modules require a source, header, and test file for each triad type (like model, conductor, and hardware). + +require 'rubygems' +require 'fileutils' + +HERE = File.expand_path(File.dirname(__FILE__)) + '/' + +#help text when requested +HELP_TEXT = [ "\nGENERATE MODULE\n-------- ------", + "\nUsage: ruby generate_module [options] module_name", + " -i\"include\" sets the path to output headers to 'include' (DEFAULT ../src)", + " -s\"../src\" sets the path to output source to '../src' (DEFAULT ../src)", + " -t\"C:/test\" sets the path to output source to 'C:/test' (DEFAULT ../test)", + " -p\"MCH\" sets the output pattern to MCH.", + " dh - driver hardware.", + " dih - driver interrupt hardware.", + " mch - model conductor hardware.", + " mvp - model view presenter.", + " src - just a single source module. (DEFAULT)", + " -d destroy module instead of creating it.", + " -u update subversion too (requires subversion command line)", + " -y\"my.yml\" selects a different yaml config file for module generation", + "" ].join("\n") + +#Built in patterns +PATTERNS = { 'src' => {'' => { :inc => [] } }, + 'dh' => {'Driver' => { :inc => ['%1$sHardware.h'] }, + 'Hardware' => { :inc => [] } + }, + 'dih' => {'Driver' => { :inc => ['%1$sHardware.h', '%1$sInterrupt.h'] }, + 'Interrupt'=> { :inc => ['%1$sHardware.h'] }, + 'Hardware' => { :inc => [] } + }, + 'mch' => {'Model' => { :inc => [] }, + 'Conductor'=> { :inc => ['%1$sModel.h', '%1$sHardware.h'] }, + 'Hardware' => { :inc => [] } + }, + 'mvp' => {'Model' => { :inc => [] }, + 'Presenter'=> { :inc => ['%1$sModel.h', '%1$sView.h'] }, + 'View' => { :inc => [] } + } + } + +#TEMPLATE_TST +TEMPLATE_TST = %q[#include "unity.h" +%2$s#include "%1$s.h" + +void setUp(void) +{ +} + +void tearDown(void) +{ +} + +void test_%1$s_NeedToImplement(void) +{ + TEST_IGNORE(); +} +] + +#TEMPLATE_SRC +TEMPLATE_SRC = %q[%2$s#include "%1$s.h" +] + +#TEMPLATE_INC +TEMPLATE_INC = %q[#ifndef _%3$s_H +#define _%3$s_H%2$s + +#endif // _%3$s_H +] + +# Parse the command line parameters. +ARGV.each do |arg| + case(arg) + when /^-d/ then @destroy = true + when /^-u/ then @update_svn = true + when /^-p(\w+)/ then @pattern = $1 + when /^-s(.+)/ then @path_src = $1 + when /^-i(.+)/ then @path_inc = $1 + when /^-t(.+)/ then @path_tst = $1 + when /^-y(.+)/ then @yaml_config = $1 + when /^(\w+)/ + raise "ERROR: You can't have more than one Module name specified!" unless @module_name.nil? + @module_name = arg + when /^-(h|-help)/ + puts HELP_TEXT + exit + else + raise "ERROR: Unknown option specified '#{arg}'" + end +end +raise "ERROR: You must have a Module name specified! (use option -h for help)" if @module_name.nil? + +#load yaml file if one was requested +if @yaml_config + require 'yaml' + cfg = YAML.load_file(HERE + @yaml_config)[:generate_module] + @path_src = cfg[:defaults][:path_src] if @path_src.nil? + @path_inc = cfg[:defaults][:path_inc] if @path_inc.nil? + @path_tst = cfg[:defaults][:path_tst] if @path_tst.nil? + @update_svn = cfg[:defaults][:update_svn] if @update_svn.nil? + @extra_inc = cfg[:includes] + @boilerplates = cfg[:boilerplates] +else + @boilerplates = {} +end + +# Create default file paths if none were provided +@path_src = HERE + "../src/" if @path_src.nil? +@path_inc = @path_src if @path_inc.nil? +@path_tst = HERE + "../test/" if @path_tst.nil? +@path_src += '/' unless (@path_src[-1] == 47) +@path_inc += '/' unless (@path_inc[-1] == 47) +@path_tst += '/' unless (@path_tst[-1] == 47) +@pattern = 'src' if @pattern.nil? +@includes = { :src => [], :inc => [], :tst => [] } +@includes.merge!(@extra_inc) unless @extra_inc.nil? + +#create triad definition +TRIAD = [ { :ext => '.c', :path => @path_src, :template => TEMPLATE_SRC, :inc => :src, :boilerplate => @boilerplates[:src] }, + { :ext => '.h', :path => @path_inc, :template => TEMPLATE_INC, :inc => :inc, :boilerplate => @boilerplates[:inc] }, + { :ext => '.c', :path => @path_tst+'Test', :template => TEMPLATE_TST, :inc => :tst, :boilerplate => @boilerplates[:tst] }, + ] + +#prepare the pattern for use +@patterns = PATTERNS[@pattern.downcase] +raise "ERROR: The design pattern specified isn't one that I recognize!" if @patterns.nil? + +# Assemble the path/names of the files we need to work with. +files = [] +TRIAD.each do |triad| + @patterns.each_pair do |pattern_file, pattern_traits| + files << { + :path => "#{triad[:path]}#{@module_name}#{pattern_file}#{triad[:ext]}", + :name => "#{@module_name}#{pattern_file}", + :template => triad[:template], + :boilerplate => triad[:boilerplate], + :includes => case(triad[:inc]) + when :src then @includes[:src] | pattern_traits[:inc].map{|f| f % [@module_name]} + when :inc then @includes[:inc] + when :tst then @includes[:tst] | pattern_traits[:inc].map{|f| "Mock#{f}"% [@module_name]} + end + } + end +end + +# destroy files if that was what was requested +if @destroy + files.each do |filespec| + file = filespec[:path] + if File.exist?(file) + if @update_svn + `svn delete \"#{file}\" --force` + puts "File #{file} deleted and removed from source control" + else + FileUtils.remove(file) + puts "File #{file} deleted" + end + else + puts "File #{file} does not exist so cannot be removed." + end + end + puts "Destroy Complete" + exit +end + +#Abort if any module already exists +files.each do |file| + raise "ERROR: File #{file[:name]} already exists. Exiting." if File.exist?(file[:path]) +end + +# Create Source Modules +files.each_with_index do |file, i| + File.open(file[:path], 'w') do |f| + f.write(file[:boilerplate] % [file[:name]]) unless file[:boilerplate].nil? + f.write(file[:template] % [ file[:name], + file[:includes].map{|f| "#include \"#{f}\"\n"}.join, + file[:name].upcase ] + ) + end + if (@update_svn) + `svn add \"#{file[:path]}\"` + if $?.exitstatus == 0 + puts "File #{file[:path]} created and added to source control" + else + puts "File #{file[:path]} created but FAILED adding to source control!" + end + else + puts "File #{file[:path]} created" + end +end + +puts 'Generate Complete' diff --git a/tests/tools/auto/generate_test_runner.rb b/tests/tools/auto/generate_test_runner.rb new file mode 100644 index 000000000..85e4e91db --- /dev/null +++ b/tests/tools/auto/generate_test_runner.rb @@ -0,0 +1,349 @@ +# ========================================== +# Unity Project - A Test Framework for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +$QUICK_RUBY_VERSION = RUBY_VERSION.split('.').inject(0){|vv,v| vv * 100 + v.to_i } +File.expand_path(File.join(File.dirname(__FILE__),'colour_prompt')) + +class UnityTestRunnerGenerator + + def initialize(options = nil) + @options = UnityTestRunnerGenerator.default_options + case(options) + when NilClass then @options + when String then @options.merge!(UnityTestRunnerGenerator.grab_config(options)) + when Hash then @options.merge!(options) + else raise "If you specify arguments, it should be a filename or a hash of options" + end + require "#{File.expand_path(File.dirname(__FILE__))}/type_sanitizer" + end + + def self.default_options + { + :includes => [], + :plugins => [], + :framework => :unity, + :test_prefix => "test|spec|should", + :setup_name => "setUp", + :teardown_name => "tearDown", + } + end + + def self.grab_config(config_file) + options = self.default_options + unless (config_file.nil? or config_file.empty?) + require 'yaml' + yaml_guts = YAML.load_file(config_file) + options.merge!(yaml_guts[:unity] || yaml_guts[:cmock]) + raise "No :unity or :cmock section found in #{config_file}" unless options + end + return(options) + end + + def run(input_file, output_file, options=nil) + tests = [] + testfile_includes = [] + used_mocks = [] + + @options.merge!(options) unless options.nil? + module_name = File.basename(input_file) + + #pull required data from source file + source = File.read(input_file) + source = source.force_encoding("ISO-8859-1").encode("utf-8", :replace => nil) if ($QUICK_RUBY_VERSION > 10900) + tests = find_tests(source) + headers = find_includes(source) + testfile_includes = headers[:local] + headers[:system] + used_mocks = find_mocks(testfile_includes) + + #build runner file + generate(input_file, output_file, tests, used_mocks, testfile_includes) + + #determine which files were used to return them + all_files_used = [input_file, output_file] + all_files_used += testfile_includes.map {|filename| filename + '.c'} unless testfile_includes.empty? + all_files_used += @options[:includes] unless @options[:includes].empty? + return all_files_used.uniq + end + + def generate(input_file, output_file, tests, used_mocks, testfile_includes) + File.open(output_file, 'w') do |output| + create_header(output, used_mocks, testfile_includes) + create_externs(output, tests, used_mocks) + create_mock_management(output, used_mocks) + create_suite_setup_and_teardown(output) + create_reset(output, used_mocks) + create_main(output, input_file, tests, used_mocks) + end + end + + def find_tests(source) + tests_raw = [] + tests_args = [] + tests_and_line_numbers = [] + + source_scrubbed = source.gsub(/\/\/.*$/, '') # remove line comments + source_scrubbed = source_scrubbed.gsub(/\/\*.*?\*\//m, '') # remove block comments + lines = source_scrubbed.split(/(^\s*\#.*$) # Treat preprocessor directives as a logical line + | (;|\{|\}) /x) # Match ;, {, and } as end of lines + + lines.each_with_index do |line, index| + #find tests + if line =~ /^((?:\s*TEST_CASE\s*\(.*?\)\s*)*)\s*void\s+((?:#{@options[:test_prefix]}).*)\s*\(\s*(.*)\s*\)/ + arguments = $1 + name = $2 + call = $3 + args = nil + if (@options[:use_param_tests] and !arguments.empty?) + args = [] + arguments.scan(/\s*TEST_CASE\s*\((.*)\)\s*$/) {|a| args << a[0]} + end + tests_and_line_numbers << { :test => name, :args => args, :call => call, :line_number => 0 } + tests_args = [] + end + end + + #determine line numbers and create tests to run + source_lines = source.split("\n") + source_index = 0; + tests_and_line_numbers.size.times do |i| + source_lines[source_index..-1].each_with_index do |line, index| + if (line =~ /#{tests_and_line_numbers[i][:test]}/) + source_index += index + tests_and_line_numbers[i][:line_number] = source_index + 1 + break + end + end + end + + return tests_and_line_numbers + end + + def find_includes(source) + + #remove comments (block and line, in three steps to ensure correct precedence) + source.gsub!(/\/\/(?:.+\/\*|\*(?:$|[^\/])).*$/, '') # remove line comments that comment out the start of blocks + source.gsub!(/\/\*.*?\*\//m, '') # remove block comments + source.gsub!(/\/\/.*$/, '') # remove line comments (all that remain) + + #parse out includes + includes = { + local: source.scan(/^\s*#include\s+\"\s*(.+)\.[hH]\s*\"/).flatten, + system: source.scan(/^\s*#include\s+<\s*(.+)\s*>/).flatten.map { |inc| "<#{inc}>" } + } + return includes + end + + def find_mocks(includes) + mock_headers = [] + includes.each do |include_file| + mock_headers << File.basename(include_file) if (include_file =~ /^mock/i) + end + return mock_headers + end + + def create_header(output, mocks, testfile_includes=[]) + output.puts('/* AUTOGENERATED FILE. DO NOT EDIT. */') + create_runtest(output, mocks) + output.puts("\n//=======Automagically Detected Files To Include=====") + output.puts("#include \"#{@options[:framework].to_s}.h\"") + output.puts('#include "cmock.h"') unless (mocks.empty?) + @options[:includes].flatten.uniq.compact.each do |inc| + output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h','')}.h\""}") + end + output.puts('#include ') + output.puts('#include ') + output.puts('#include "CException.h"') if @options[:plugins].include?(:cexception) + testfile_includes.delete_if{|inc| inc =~ /(unity|cmock)/} + testrunner_includes = testfile_includes - mocks + testrunner_includes.each do |inc| + output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h','')}.h\""}") + end + mocks.each do |mock| + output.puts("#include \"#{mock.gsub('.h','')}.h\"") + end + if @options[:enforce_strict_ordering] + output.puts('') + output.puts('int GlobalExpectCount;') + output.puts('int GlobalVerifyOrder;') + output.puts('char* GlobalOrderError;') + end + end + + def create_externs(output, tests, mocks) + output.puts("\n//=======External Functions This Runner Calls=====") + output.puts("extern void #{@options[:setup_name]}(void);") + output.puts("extern void #{@options[:teardown_name]}(void);") + tests.each do |test| + output.puts("extern void #{test[:test]}(#{test[:call] || 'void'});") + end + output.puts('') + end + + def create_mock_management(output, mocks) + unless (mocks.empty?) + output.puts("\n//=======Mock Management=====") + output.puts("static void CMock_Init(void)") + output.puts("{") + if @options[:enforce_strict_ordering] + output.puts(" GlobalExpectCount = 0;") + output.puts(" GlobalVerifyOrder = 0;") + output.puts(" GlobalOrderError = NULL;") + end + mocks.each do |mock| + mock_clean = TypeSanitizer.sanitize_c_identifier(mock) + output.puts(" #{mock_clean}_Init();") + end + output.puts("}\n") + + output.puts("static void CMock_Verify(void)") + output.puts("{") + mocks.each do |mock| + mock_clean = TypeSanitizer.sanitize_c_identifier(mock) + output.puts(" #{mock_clean}_Verify();") + end + output.puts("}\n") + + output.puts("static void CMock_Destroy(void)") + output.puts("{") + mocks.each do |mock| + mock_clean = TypeSanitizer.sanitize_c_identifier(mock) + output.puts(" #{mock_clean}_Destroy();") + end + output.puts("}\n") + end + end + + def create_suite_setup_and_teardown(output) + unless (@options[:suite_setup].nil?) + output.puts("\n//=======Suite Setup=====") + output.puts("static int suite_setup(void)") + output.puts("{") + output.puts(@options[:suite_setup]) + output.puts("}") + end + unless (@options[:suite_teardown].nil?) + output.puts("\n//=======Suite Teardown=====") + output.puts("static int suite_teardown(int num_failures)") + output.puts("{") + output.puts(@options[:suite_teardown]) + output.puts("}") + end + end + + def create_runtest(output, used_mocks) + cexception = @options[:plugins].include? :cexception + va_args1 = @options[:use_param_tests] ? ', ...' : '' + va_args2 = @options[:use_param_tests] ? '__VA_ARGS__' : '' + output.puts("\n//=======Test Runner Used To Run Each Test Below=====") + output.puts("#define RUN_TEST_NO_ARGS") if @options[:use_param_tests] + output.puts("#define RUN_TEST(TestFunc, TestLineNum#{va_args1}) \\") + output.puts("{ \\") + output.puts(" Unity.CurrentTestName = #TestFunc#{va_args2.empty? ? '' : " \"(\" ##{va_args2} \")\""}; \\") + output.puts(" Unity.CurrentTestLineNumber = TestLineNum; \\") + output.puts(" Unity.NumberOfTests++; \\") + output.puts(" CMock_Init(); \\") unless (used_mocks.empty?) + output.puts(" if (TEST_PROTECT()) \\") + output.puts(" { \\") + output.puts(" CEXCEPTION_T e; \\") if cexception + output.puts(" Try { \\") if cexception + output.puts(" #{@options[:setup_name]}(); \\") + output.puts(" TestFunc(#{va_args2}); \\") + output.puts(" } Catch(e) { TEST_ASSERT_EQUAL_HEX32_MESSAGE(CEXCEPTION_NONE, e, \"Unhandled Exception!\"); } \\") if cexception + output.puts(" } \\") + output.puts(" if (TEST_PROTECT() && !TEST_IS_IGNORED) \\") + output.puts(" { \\") + output.puts(" #{@options[:teardown_name]}(); \\") + output.puts(" CMock_Verify(); \\") unless (used_mocks.empty?) + output.puts(" } \\") + output.puts(" CMock_Destroy(); \\") unless (used_mocks.empty?) + output.puts(" UnityConcludeTest(); \\") + output.puts("}\n") + end + + def create_reset(output, used_mocks) + output.puts("\n//=======Test Reset Option=====") + output.puts("void resetTest(void);") + output.puts("void resetTest(void)") + output.puts("{") + output.puts(" CMock_Verify();") unless (used_mocks.empty?) + output.puts(" CMock_Destroy();") unless (used_mocks.empty?) + output.puts(" #{@options[:teardown_name]}();") + output.puts(" CMock_Init();") unless (used_mocks.empty?) + output.puts(" #{@options[:setup_name]}();") + output.puts("}") + end + + def create_main(output, filename, tests, used_mocks) + output.puts("\n\n//=======MAIN=====") + output.puts("int main(void)") + output.puts("{") + output.puts(" suite_setup();") unless @options[:suite_setup].nil? + output.puts(" UnityBegin(\"#{filename}\");") + if (@options[:use_param_tests]) + tests.each do |test| + if ((test[:args].nil?) or (test[:args].empty?)) + output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]}, RUN_TEST_NO_ARGS);") + else + test[:args].each {|args| output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]}, #{args});")} + end + end + else + tests.each { |test| output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]});") } + end + output.puts() + output.puts(" CMock_Guts_MemFreeFinal();") unless used_mocks.empty? + output.puts(" return #{@options[:suite_teardown].nil? ? "" : "suite_teardown"}(UnityEnd());") + output.puts("}") + end +end + + +if ($0 == __FILE__) + options = { :includes => [] } + yaml_file = nil + + #parse out all the options first (these will all be removed as we go) + ARGV.reject! do |arg| + case(arg) + when '-cexception' + options[:plugins] = [:cexception]; true + when /\.*\.ya?ml/ + options = UnityTestRunnerGenerator.grab_config(arg); true + when /\.*\.h/ + options[:includes] << arg; true + when /--(\w+)=\"?(.*)\"?/ + options[$1.to_sym] = $2; true + else false + end + end + + #make sure there is at least one parameter left (the input file) + if !ARGV[0] + puts ["\nusage: ruby #{__FILE__} (files) (options) input_test_file (output)", + "\n input_test_file - this is the C file you want to create a runner for", + " output - this is the name of the runner file to generate", + " defaults to (input_test_file)_Runner", + " files:", + " *.yml / *.yaml - loads configuration from here in :unity or :cmock", + " *.h - header files are added as #includes in runner", + " options:", + " -cexception - include cexception support", + " --setup_name=\"\" - redefine setUp func name to something else", + " --teardown_name=\"\" - redefine tearDown func name to something else", + " --test_prefix=\"\" - redefine test prefix from default test|spec|should", + " --suite_setup=\"\" - code to execute for setup of entire suite", + " --suite_teardown=\"\" - code to execute for teardown of entire suite", + " --use_param_tests=1 - enable parameterized tests (disabled by default)", + ].join("\n") + exit 1 + end + + #create the default test runner name if not specified + ARGV[1] = ARGV[0].gsub(".c","_Runner.c") if (!ARGV[1]) + + + UnityTestRunnerGenerator.new(options).run(ARGV[0], ARGV[1]) +end diff --git a/tests/tools/auto/parseOutput.rb b/tests/tools/auto/parseOutput.rb new file mode 100644 index 000000000..5165c7f0b --- /dev/null +++ b/tests/tools/auto/parseOutput.rb @@ -0,0 +1,189 @@ +#============================================================ +# Author: John Theofanopoulos +# A simple parser. Takes the output files generated during the build process and +# extracts information relating to the tests. +# +# Notes: +# To capture an output file under VS builds use the following: +# devenv [build instructions] > Output.txt & type Output.txt +# +# To capture an output file under GCC/Linux builds use the following: +# make | tee Output.txt +# +# To use this parser use the following command +# ruby parseOutput.rb [options] [file] +# options: -xml : produce a JUnit compatible XML file +# file : file to scan for results +#============================================================ + + +class ParseOutput +# The following flag is set to true when a test is found or false otherwise. + @testFlag + @xmlOut + @arrayList + @totalTests + @classIndex + +# Set the flag to indicate if there will be an XML output file or not + def setXmlOutput() + @xmlOut = true + end + +# if write our output to XML + def writeXmlOuput() + output = File.open("report.xml", "w") + output << "\n" + @arrayList.each do |item| + output << item << "\n" + end + output << "\n" + end + +# This function will try and determine when the suite is changed. This is +# is the name that gets added to the classname parameter. + def testSuiteVerify(testSuiteName) + if @testFlag == false + @testFlag = true; + # Split the path name + testName = testSuiteName.split("/") + # Remove the extension + baseName = testName[testName.size - 1].split(".") + @testSuite = "test." + baseName[0] + printf "New Test: %s\n", @testSuite + end + end + + +# Test was flagged as having passed so format the output + def testPassed(array) + lastItem = array.length - 1 + testName = array[lastItem - 1] + testSuiteVerify(array[@className]) + printf "%-40s PASS\n", testName + if @xmlOut == true + @arrayList.push " " + end + end + +# Test was flagged as being ingored so format the output + def testIgnored(array) + lastItem = array.length - 1 + testName = array[lastItem - 2] + reason = array[lastItem].chomp + testSuiteVerify(array[@className]) + printf "%-40s IGNORED\n", testName + if @xmlOut == true + @arrayList.push " " + @arrayList.push " " + reason + " " + @arrayList.push " " + end + end + +# Test was flagged as having failed so format the line + def testFailed(array) + lastItem = array.length - 1 + testName = array[lastItem - 2] + reason = array[lastItem].chomp + " at line: " + array[lastItem - 3] + testSuiteVerify(array[@className]) + printf "%-40s FAILED\n", testName + if @xmlOut == true + @arrayList.push " " + @arrayList.push " " + reason + " " + @arrayList.push " " + end + end + + +# Figure out what OS we are running on. For now we are assuming if it's not Windows it must +# be Unix based. + def detectOS() + myOS = RUBY_PLATFORM.split("-") + if myOS.size == 2 + if myOS[1] == "mingw32" + @className = 1 + else + @className = 0 + end + end + + end + +# Main function used to parse the file that was captured. + def process(name) + @testFlag = false + @arrayList = Array.new + + detectOS() + + puts "Parsing file: " + name + + + testPass = 0 + testFail = 0 + testIgnore = 0 + puts "" + puts "=================== RESULTS =====================" + puts "" + File.open(name).each do |line| + # Typical test lines look like this: + # /.c:36:test_tc1000_opsys:FAIL: Expected 1 Was 0 + # /.c:112:test_tc5004_initCanChannel:IGNORE: Not Yet Implemented + # /.c:115:test_tc5100_initCanVoidPtrs:PASS + # + # where path is different on Unix vs Windows devices (Windows leads with a drive letter) + lineArray = line.split(":") + lineSize = lineArray.size + # If we were able to split the line then we can look to see if any of our target words + # were found. Case is important. + if lineSize >= 4 + # Determine if this test passed + if line.include? ":PASS" + testPassed(lineArray) + testPass += 1 + elsif line.include? ":FAIL:" + testFailed(lineArray) + testFail += 1 + elsif line.include? ":IGNORE:" + testIgnored(lineArray) + testIgnore += 1 + # If none of the keywords are found there are no more tests for this suite so clear + # the test flag + else + @testFlag = false + end + else + @testFlag = false + end + end + puts "" + puts "=================== SUMMARY =====================" + puts "" + puts "Tests Passed : " + testPass.to_s + puts "Tests Failed : " + testFail.to_s + puts "Tests Ignored : " + testIgnore.to_s + @totalTests = testPass + testFail + testIgnore + if @xmlOut == true + heading = "" + @arrayList.insert(0, heading) + writeXmlOuput() + end + + # return result + end + + end + +# If the command line has no values in, used a default value of Output.txt +parseMyFile = ParseOutput.new + +if ARGV.size >= 1 + ARGV.each do |a| + if a == "-xml" + parseMyFile.setXmlOutput(); + else + parseMyFile.process(a) + break + end + end +end diff --git a/tests/tools/auto/test_file_filter.rb b/tests/tools/auto/test_file_filter.rb new file mode 100644 index 000000000..3dbc26a28 --- /dev/null +++ b/tests/tools/auto/test_file_filter.rb @@ -0,0 +1,23 @@ +# ========================================== +# Unity Project - A Test Framework for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +require'yaml' + +module RakefileHelpers + class TestFileFilter + def initialize(all_files = false) + @all_files = all_files + if not @all_files == true + if File.exist?('test_file_filter.yml') + filters = YAML.load_file( 'test_file_filter.yml' ) + @all_files, @only_files, @exclude_files = + filters[:all_files], filters[:only_files], filters[:exclude_files] + end + end + end + attr_accessor :all_files, :only_files, :exclude_files + end +end diff --git a/tests/tools/auto/type_sanitizer.rb b/tests/tools/auto/type_sanitizer.rb new file mode 100644 index 000000000..7c2c0ac2c --- /dev/null +++ b/tests/tools/auto/type_sanitizer.rb @@ -0,0 +1,8 @@ +module TypeSanitizer + + def self.sanitize_c_identifier(unsanitized) + # convert filename to valid C identifier by replacing invalid chars with '_' + return unsanitized.gsub(/[-\/\\\.\,\s]/, "_") + end + +end diff --git a/tests/tools/auto/unity_test_summary.py b/tests/tools/auto/unity_test_summary.py new file mode 100644 index 000000000..7426ec8c3 --- /dev/null +++ b/tests/tools/auto/unity_test_summary.py @@ -0,0 +1,135 @@ +#! python3 +# ========================================== +# Unity Project - A Test Framework for C +# Copyright (c) 2015 Alexander Mueller / XelaRellum@web.de +# [Released under MIT License. Please refer to license.txt for details] +# Based on the ruby script by Mike Karlesky, Mark VanderVoord, Greg Williams +# ========================================== +import sys +import os +import re +from glob import glob + +class UnityTestSummary: + def __init__(self): + self.report = '' + self.total_tests = 0 + self.failures = 0 + self.ignored = 0 + + def run(self): + # Clean up result file names + results = [] + for target in self.targets: + results.append(target.replace('\\', '/')) + + # Dig through each result file, looking for details on pass/fail: + failure_output = [] + ignore_output = [] + + for result_file in results: + lines = list(map(lambda line: line.rstrip(), open(result_file, "r").read().split('\n'))) + if len(lines) == 0: + raise Exception("Empty test result file: %s" % result_file) + + details = self.get_details(result_file, lines) + failures = details['failures'] + ignores = details['ignores'] + if len(failures) > 0: failure_output.append('\n'.join(failures)) + if len(ignores) > 0: ignore_output.append('n'.join(ignores)) + tests,failures,ignored = self.parse_test_summary('\n'.join(lines)) + self.total_tests += tests + self.failures += failures + self.ignored += ignored + + if self.ignored > 0: + self.report += "\n" + self.report += "--------------------------\n" + self.report += "UNITY IGNORED TEST SUMMARY\n" + self.report += "--------------------------\n" + self.report += "\n".join(ignore_output) + + if self.failures > 0: + self.report += "\n" + self.report += "--------------------------\n" + self.report += "UNITY FAILED TEST SUMMARY\n" + self.report += "--------------------------\n" + self.report += '\n'.join(failure_output) + + self.report += "\n" + self.report += "--------------------------\n" + self.report += "OVERALL UNITY TEST SUMMARY\n" + self.report += "--------------------------\n" + self.report += "{total_tests} TOTAL TESTS {failures} TOTAL FAILURES {ignored} IGNORED\n".format(total_tests = self.total_tests, failures=self.failures, ignored=self.ignored) + self.report += "\n" + + return self.report + + def set_targets(self, target_array): + self.targets = target_array + + def set_root_path(self, path): + self.root = path + + def usage(self, err_msg=None): + print("\nERROR: ") + if err_msg: + print(err_msg) + print("\nUsage: unity_test_summary.rb result_file_directory/ root_path/") + print(" result_file_directory - The location of your results files.") + print(" Defaults to current directory if not specified.") + print(" Should end in / if specified.") + print(" root_path - Helpful for producing more verbose output if using relative paths.") + sys.exit(1) + + def get_details(self, result_file, lines): + results = { 'failures': [], 'ignores': [], 'successes': [] } + for line in lines: + parts = line.split(':') + if len(parts) != 5: + continue + src_file,src_line,test_name,status,msg = parts + if len(self.root) > 0: + line_out = "%s%s" % (self.root, line) + else: + line_out = line + if status == 'IGNORE': + results['ignores'].append(line_out) + elif status == 'FAIL': + results['failures'].append(line_out) + elif status == 'PASS': + results['successes'].append(line_out) + return results + + def parse_test_summary(self, summary): + m = re.search(r"([0-9]+) Tests ([0-9]+) Failures ([0-9]+) Ignored", summary) + if not m: + raise Exception("Couldn't parse test results: %s" % summary) + + return int(m.group(1)), int(m.group(2)), int(m.group(3)) + + +if __name__ == '__main__': + uts = UnityTestSummary() + try: + #look in the specified or current directory for result files + if len(sys.argv) > 1: + targets_dir = sys.argv[1] + else: + targets_dir = './' + targets = list(map(lambda x: x.replace('\\', '/'), glob(targets_dir + '*.test*'))) + if len(targets) == 0: + raise Exception("No *.testpass or *.testfail files found in '%s'" % targets_dir) + uts.set_targets(targets) + + #set the root path + if len(sys.argv) > 2: + root_path = sys.argv[2] + else: + root_path = os.path.split(__file__)[0] + uts.set_root_path(root_path) + + #run the summarizer + print(uts.run()) + except Exception as e: + uts.usage(e) diff --git a/tests/tools/auto/unity_test_summary.rb b/tests/tools/auto/unity_test_summary.rb new file mode 100644 index 000000000..8cf360f4a --- /dev/null +++ b/tests/tools/auto/unity_test_summary.rb @@ -0,0 +1,139 @@ +# ========================================== +# Unity Project - A Test Framework for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +#!/usr/bin/ruby +# +# unity_test_summary.rb +# +require 'fileutils' +require 'set' + +class UnityTestSummary + include FileUtils::Verbose + + attr_reader :report, :total_tests, :failures, :ignored + + def initialize + @report = '' + @total_tests = 0 + @failures = 0 + @ignored = 0 + end + + def run + # Clean up result file names + results = @targets.map {|target| target.gsub(/\\/,'/')} + + # Dig through each result file, looking for details on pass/fail: + failure_output = [] + ignore_output = [] + + results.each do |result_file| + lines = File.readlines(result_file).map { |line| line.chomp } + if lines.length == 0 + raise "Empty test result file: #{result_file}" + else + output = get_details(result_file, lines) + failure_output << output[:failures] unless output[:failures].empty? + ignore_output << output[:ignores] unless output[:ignores].empty? + tests,failures,ignored = parse_test_summary(lines) + @total_tests += tests + @failures += failures + @ignored += ignored + end + end + + if @ignored > 0 + @report += "\n" + @report += "--------------------------\n" + @report += "UNITY IGNORED TEST SUMMARY\n" + @report += "--------------------------\n" + @report += ignore_output.flatten.join("\n") + end + + if @failures > 0 + @report += "\n" + @report += "--------------------------\n" + @report += "UNITY FAILED TEST SUMMARY\n" + @report += "--------------------------\n" + @report += failure_output.flatten.join("\n") + end + + @report += "\n" + @report += "--------------------------\n" + @report += "OVERALL UNITY TEST SUMMARY\n" + @report += "--------------------------\n" + @report += "#{@total_tests} TOTAL TESTS #{@failures} TOTAL FAILURES #{@ignored} IGNORED\n" + @report += "\n" + end + + def set_targets(target_array) + @targets = target_array + end + + def set_root_path(path) + @root = path + end + + def usage(err_msg=nil) + puts "\nERROR: " + puts err_msg if err_msg + puts "\nUsage: unity_test_summary.rb result_file_directory/ root_path/" + puts " result_file_directory - The location of your results files." + puts " Defaults to current directory if not specified." + puts " Should end in / if specified." + puts " root_path - Helpful for producing more verbose output if using relative paths." + exit 1 + end + + protected + + def get_details(result_file, lines) + results = { :failures => [], :ignores => [], :successes => [] } + lines.each do |line| + src_file,src_line,test_name,status,msg = line.split(/:/) + line_out = ((@root and (@root != 0)) ? "#{@root}#{line}" : line ).gsub(/\//, "\\") + case(status) + when 'IGNORE' then results[:ignores] << line_out + when 'FAIL' then results[:failures] << line_out + when 'PASS' then results[:successes] << line_out + end + end + return results + end + + def parse_test_summary(summary) + if summary.find { |v| v =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ } + [$1.to_i,$2.to_i,$3.to_i] + else + raise "Couldn't parse test results: #{summary}" + end + end + + def here; File.expand_path(File.dirname(__FILE__)); end + +end + +if $0 == __FILE__ + uts = UnityTestSummary.new + begin + #look in the specified or current directory for result files + ARGV[0] ||= './' + targets = "#{ARGV[0].gsub(/\\/, '/')}*.test*" + results = Dir[targets] + raise "No *.testpass or *.testfail files found in '#{targets}'" if results.empty? + uts.set_targets(results) + + #set the root path + ARGV[1] ||= File.expand_path(File.dirname(__FILE__)) + '/' + uts.set_root_path(ARGV[1]) + + #run the summarizer + puts uts.run + rescue Exception => e + uts.usage e.message + end +end diff --git a/tests/tools/build_fixture_runner.pl b/tests/tools/build_fixture_runner.pl new file mode 100644 index 000000000..df7eb1817 --- /dev/null +++ b/tests/tools/build_fixture_runner.pl @@ -0,0 +1,45 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use feature 'say'; + +say "/* THIS IS GENERATED FILE! DO NOT EDIT! DO NOT COMMIT! */"; +say '#include '; +say ''; + +my @run_test_group; +foreach my $file (@ARGV) +{ + my @output = qx(grep -vh '#include' $file | $ENV{CPP} -); + my $test_group_found = 0; + foreach (@output) + { + s/\r//g; + chomp; + if (m/^TEST_GROUP\(/) + { + s/^TEST_GROUP/TEST_GROUP_RUNNER/; + s/;$//; + say "}\n" if ($test_group_found); + say $_; + say '{'; + $test_group_found = 1; + s/TEST_GROUP_RUNNER/\tRUN_TEST_GROUP/; + push @run_test_group, $_; + } + elsif (m/^TEST\(/) + { + s/^TEST/\tRUN_TEST_CASE/; + say "$_;"; + } + elsif (m/^TEST_WITH_TIMEOUT\(/) + { + s/^TEST_WITH_TIMEOUT/\tRUN_TEST_CASE/; + s/,\s+[^,]+\)$/)/; + say "$_;"; + } + } + say "}\n" if ($test_group_found); +} + diff --git a/tests/tools/license.txt b/tests/tools/license.txt new file mode 100644 index 000000000..d66fba53e --- /dev/null +++ b/tests/tools/license.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams + +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. diff --git a/tests/tools/rename_symbols b/tests/tools/rename_symbols new file mode 100644 index 000000000..2d0b40afb --- /dev/null +++ b/tests/tools/rename_symbols @@ -0,0 +1,21 @@ +#!/bin/bash + +if [ -z "$2" ] +then + echo Usage: $(basename $0) " " 1>&2 + echo " Renames symbols generated by Unity inside object by incorporating unique string into them." 1<&2 + echo " Renaming makes it possible to have testcases with the same name and testsuite under" 1>&2 + echo " different executables" 1>&2 + echo " unique - unique string" 1>&2 + echo " object - object file to modify" 1>&2 + echo " Object file is transformed in-place" 1>&2 + exit 1 +fi + +UNIQUE=$1 +OBJECT=$2 +: ${OBJCOPY:=objcopy} + +# Do not hate me.. love me.. + +$OBJCOPY --redefine-syms <(readelf -Ws $OBJECT | tail -n +4 | awk '{if ($5 != "LOCAL") {print $8, $8}}' | grep -vP '^\s+$' | sed 's/\sTEST_/ TEST_'$UNIQUE'_/') $OBJECT diff --git a/tests/tools/unity_test_summary.rb b/tests/tools/unity_test_summary.rb new file mode 100644 index 000000000..90bf487ec --- /dev/null +++ b/tests/tools/unity_test_summary.rb @@ -0,0 +1,139 @@ +# ========================================== +# Unity Project - A Test Framework for C +# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams +# [Released under MIT License. Please refer to license.txt for details] +# ========================================== + +#!/usr/bin/ruby +# +# unity_test_summary.rb +# +require 'fileutils' +require 'set' + +class UnityTestSummary + include FileUtils::Verbose + + attr_reader :report, :total_tests, :failures, :ignored + + def initialize + @report = '' + @total_tests = 0 + @failures = 0 + @ignored = 0 + end + + def run + # Clean up result file names + results = @targets.map {|target| target.gsub(/\\/,'/')} + + # Dig through each result file, looking for details on pass/fail: + failure_output = [] + ignore_output = [] + + results.each do |result_file| + lines = File.readlines(result_file).map { |line| line.chomp } + if lines.length == 0 + raise "Empty test result file: #{result_file}" + else + output = get_details(result_file, lines) + failure_output << output[:failures] unless output[:failures].empty? + ignore_output << output[:ignores] unless output[:ignores].empty? + tests,failures,ignored = parse_test_summary(lines) + @total_tests += tests + @failures += failures + @ignored += ignored + end + end + + if @ignored > 0 + @report += "\n" + @report += "--------------------------\n" + @report += "UNITY IGNORED TEST SUMMARY\n" + @report += "--------------------------\n" + @report += ignore_output.flatten.join("\n") + end + + if @failures > 0 + @report += "\n" + @report += "--------------------------\n" + @report += "UNITY FAILED TEST SUMMARY\n" + @report += "--------------------------\n" + @report += failure_output.flatten.join("\n") + end + + @report += "\n" + @report += "--------------------------\n" + @report += "OVERALL UNITY TEST SUMMARY\n" + @report += "--------------------------\n" + @report += "#{@total_tests} TOTAL TESTS #{@failures} TOTAL FAILURES #{@ignored} IGNORED\n" + @report += "\n" + end + + def set_targets(target_array) + @targets = target_array + end + + def set_root_path(path) + @root = path + end + + def usage(err_msg=nil) + puts "\nERROR: " + puts err_msg if err_msg + puts "\nUsage: unity_test_summary.rb result_file_directory/ root_path/" + puts " result_file_directory - The location of your results files." + puts " Defaults to current directory if not specified." + puts " Should end in / if specified." + puts " root_path - Helpful for producing more verbose output if using relative paths." + exit 1 + end + + protected + + def get_details(result_file, lines) + results = { :failures => [], :ignores => [], :successes => [] } + lines.each do |line| + src_file,src_line,test_name,status,msg = line.split(/:/) + line_out = ((@root and (@root != 0)) ? "#{@root}#{line}" : line ).gsub(/\//, "\\") + case(status) + when 'IGNORE' then results[:ignores] << line_out + when 'FAIL' then results[:failures] << line_out + when 'PASS' then results[:successes] << line_out + end + end + return results + end + + def parse_test_summary(summary) + if summary.find { |v| v =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ } + [$1.to_i,$2.to_i,$3.to_i] + else + raise "Couldn't parse test results: #{summary}" + end + end + + def here; File.expand_path(File.dirname(__FILE__)); end + +end + +if $0 == __FILE__ + uts = UnityTestSummary.new + begin + #look in the specified or current directory for result files + ARGV[0] ||= './' + targets = "#{ARGV[0].gsub(/\\/, '/')}*.test*" + results = Dir[targets] + raise "No *.testpass or *.testfail files found in '#{targets}'" if results.empty? + uts.set_targets(results) + + #set the root path + ARGV[1] ||= File.expand_path(File.dirname(__FILE__)) + '/' + uts.set_root_path(ARGV[1]) + + #run the summarizer + puts uts.run + rescue Exception => e + uts.usage e.message + end +end diff --git a/tests/unity/.gitignore b/tests/unity/.gitignore new file mode 100644 index 000000000..fa1ec7579 --- /dev/null +++ b/tests/unity/.gitignore @@ -0,0 +1,11 @@ +/Make.dep +/.depend +/.built +/*.asm +/*.obj +/*.rel +/*.lst +/*.sym +/*.adb +/*.lib +/*.src diff --git a/tests/unity/Kconfig b/tests/unity/Kconfig new file mode 100644 index 000000000..e4cba1b6d --- /dev/null +++ b/tests/unity/Kconfig @@ -0,0 +1,22 @@ +# +# For a description of the syntax of this configuration file, +# see misc/tools/kconfig-language.txt. +# + +config TESTS_UNITY + bool "Unity fixture example" + default n + ---help--- + Demonstrates Unity fixture and runs its unit test + +if TESTS_UNITY + +config TESTS_UNITY_PROGNAME + string "Program name" + default "unity" + depends on BUILD_KERNEL + ---help--- + This is the name of the program that will be use when the NSH ELF + program is installed. + +endif diff --git a/tests/unity/Make.defs b/tests/unity/Make.defs new file mode 100644 index 000000000..3709e9a6c --- /dev/null +++ b/tests/unity/Make.defs @@ -0,0 +1,39 @@ +############################################################################ +# apps/tests/unity/Make.defs +# Adds selected testing applications to apps/ build +# +# Copyright (C) 2015 Haltian Ltd. All rights reserved. +# Author: Roman Saveljev +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +ifeq ($(CONFIG_TESTS_UNITY),y) +CONFIGURED_APPS += tests/unity +endif diff --git a/tests/unity/Makefile b/tests/unity/Makefile new file mode 100644 index 000000000..8a93d01c1 --- /dev/null +++ b/tests/unity/Makefile @@ -0,0 +1,137 @@ +############################################################################ +# apps/examples/unity/Makefile +# +# Copyright (C) 2015 Haltian Ltd. All rights reserved. +# Author: Roman Saveljev +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# Hello, World! built-in application info + +APPNAME = unity +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +ASRCS = +CSRCS = unity_fixture_Test.c unity_fixture_TestRunner.c unity_output_Spy.c +MAINSRC = main/AllTests.c + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +MAINOBJ = $(MAINSRC:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(MAINSRC) +OBJS = $(AOBJS) $(COBJS) + +ifneq ($(CONFIG_BUILD_KERNEL),y) + OBJS += $(MAINOBJ) +endif + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + BIN = ..\..\libapps$(LIBEXT) +else +ifeq ($(WINTOOL),y) + BIN = ..\\..\\libapps$(LIBEXT) +else + BIN = ../../libapps$(LIBEXT) +endif +endif + +ifeq ($(WINTOOL),y) + INSTALL_DIR = "${shell cygpath -w $(BIN_DIR)}" +else + INSTALL_DIR = $(BIN_DIR) +endif + +CONFIG_EXAMPLES_UNITY_PROGNAME ?= unity$(EXEEXT) +PROGNAME = $(CONFIG_EXAMPLES_UNITY_PROGNAME) + +ROOTDEPPATH = --dep-path . + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend distclean + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS) $(MAINOBJ): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + $(Q) OBJCOPY=$(OBJCOPY) $(APPDIR)/tests/tools/rename_symbols $(APPNAME) $@ + +.built: $(OBJS) + $(call ARCHIVE, $(BIN), $(OBJS)) + @touch .built + +ifeq ($(CONFIG_BUILD_KERNEL),y) +$(BIN_DIR)$(DELIM)$(PROGNAME): $(OBJS) $(MAINOBJ) + @echo "LD: $(PROGNAME)" + $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME) $(ARCHCRT0OBJ) $(MAINOBJ) $(LDLIBS) + $(Q) $(NM) -u $(INSTALL_DIR)$(DELIM)$(PROGNAME) + +install: $(BIN_DIR)$(DELIM)$(PROGNAME) + +else +install: + +endif + +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) +$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) + +context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat +else +context: +endif + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + $(call DELFILE, .built) + $(call CLEAN) + $(Q) rm -f $(OBJS) + +distclean: clean + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/tests/unity/main/AllTests.c b/tests/unity/main/AllTests.c new file mode 100644 index 000000000..18f5278d6 --- /dev/null +++ b/tests/unity/main/AllTests.c @@ -0,0 +1,30 @@ +//- Copyright (c) 2010 James Grenning and Contributed to Unity Project +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#include + +// Enable for manual examination - tests will fail +//#define MANUAL_CHECKING + +static void runAllTests(void) +{ + RUN_TEST_GROUP(UnityFixture); + RUN_TEST_GROUP(UnityCommandOptions); + RUN_TEST_GROUP(LeakDetection); + RUN_TEST_GROUP(Timeout); +#ifdef MANUAL_CHECKING + RUN_TEST_GROUP(TimeoutInSetup); + RUN_TEST_GROUP(TimeoutInBody); + RUN_TEST_GROUP(TimeoutInTearDown); +#endif +} + +int unity_main(int argc, const char* argv[]) +{ + return UnityMain(argc, argv, runAllTests); +} + diff --git a/tests/unity/testunity_fixture.c b/tests/unity/testunity_fixture.c new file mode 100644 index 000000000..8d4db9f93 --- /dev/null +++ b/tests/unity/testunity_fixture.c @@ -0,0 +1,39 @@ +//- Copyright (c) 2010 James Grenning and Contributed to Unity Project +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#include + +static int data = -1; + +TEST_GROUP(mygroup); + +TEST_SETUP(mygroup) +{ + data = 0; +} + +TEST_TEAR_DOWN(mygroup) +{ + data = -1; +} + +TEST(mygroup, test1) +{ + TEST_ASSERT_EQUAL_INT(0, data); +} + +TEST(mygroup, test2) +{ + TEST_ASSERT_EQUAL_INT(0, data); + data = 5; +} + +TEST(mygroup, test3) +{ + data = 7; + TEST_ASSERT_EQUAL_INT(7, data); +} diff --git a/tests/unity/unity_fixture_Test.c b/tests/unity/unity_fixture_Test.c new file mode 100644 index 000000000..cb55858a2 --- /dev/null +++ b/tests/unity/unity_fixture_Test.c @@ -0,0 +1,454 @@ +//- Copyright (c) 2010 James Grenning and Contributed to Unity Project +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#include +#include "unity_output_Spy.h" +#include +#include + +extern UNITY_FIXTURE_T UnityFixture; + +TEST_GROUP(UnityFixture); + +TEST_SETUP(UnityFixture) +{ +} + +TEST_TEAR_DOWN(UnityFixture) +{ +} + +int my_int; +int* pointer1 = 0; +int* pointer2 = (int*)2; +int* pointer3 = (int*)3; +int int1; +int int2; +int int3; +int int4; + +TEST(UnityFixture, PointerSetting) +{ + TEST_ASSERT_POINTERS_EQUAL(pointer1, 0); + UT_PTR_SET(pointer1, &int1); + UT_PTR_SET(pointer2, &int2); + UT_PTR_SET(pointer3, &int3); + TEST_ASSERT_POINTERS_EQUAL(pointer1, &int1); + TEST_ASSERT_POINTERS_EQUAL(pointer2, &int2); + TEST_ASSERT_POINTERS_EQUAL(pointer3, &int3); + UT_PTR_SET(pointer1, &int4); + UnityPointer_UndoAllSets(); + TEST_ASSERT_POINTERS_EQUAL(pointer1, 0); + TEST_ASSERT_POINTERS_EQUAL(pointer2, (int*)2); + TEST_ASSERT_POINTERS_EQUAL(pointer3, (int*)3); +} + +TEST(UnityFixture, ForceMallocFail) +{ + void* m; + void* mfails; + UnityMalloc_MakeMallocFailAfterCount(1); + m = malloc(10); + CHECK(m); + mfails = malloc(10); + TEST_ASSERT_POINTERS_EQUAL(0, mfails); + free(m); +} + +TEST(UnityFixture, ReallocSmallerIsUnchanged) +{ + void* m1 = malloc(10); + void* m2 = realloc(m1, 5); + TEST_ASSERT_POINTERS_EQUAL(m1, m2); + free(m2); +} + +TEST(UnityFixture, ReallocSameIsUnchanged) +{ + void* m1 = malloc(10); + void* m2 = realloc(m1, 10); + TEST_ASSERT_POINTERS_EQUAL(m1, m2); + free(m2); +} + +TEST(UnityFixture, ReallocLargerNeeded) +{ + void* m1 = malloc(10); + void* m2; + strcpy((char*)m1, "123456789"); + m2 = realloc(m1, 15); + CHECK(m1 != m2); + STRCMP_EQUAL("123456789", m2); + free(m2); +} + +TEST(UnityFixture, ReallocNullPointerIsLikeMalloc) +{ + void* m = realloc(0, 15); + CHECK(m != 0); + free(m); +} + +TEST(UnityFixture, ReallocSizeZeroFreesMemAndReturnsNullPointer) +{ + void* m1 = malloc(10); + void* m2 = realloc(m1, 0); + TEST_ASSERT_POINTERS_EQUAL(0, m2); +} + +TEST(UnityFixture, CallocFillsWithZero) +{ + void* m = calloc(3, sizeof(char)); + char* s = (char*)m; + TEST_ASSERT_BYTES_EQUAL(0, s[0]); + TEST_ASSERT_BYTES_EQUAL(0, s[1]); + TEST_ASSERT_BYTES_EQUAL(0, s[2]); + free(m); +} + +char *p1; +char *p2; + +TEST(UnityFixture, PointerSet) +{ + char c1; + char c2; + char newC1; + char newC2; + p1 = &c1; + p2 = &c2; + + UnityPointer_Init(); + UT_PTR_SET(p1, &newC1); + UT_PTR_SET(p2, &newC2); + TEST_ASSERT_POINTERS_EQUAL(&newC1, p1); + TEST_ASSERT_POINTERS_EQUAL(&newC2, p2); + UnityPointer_UndoAllSets(); + TEST_ASSERT_POINTERS_EQUAL(&c1, p1); + TEST_ASSERT_POINTERS_EQUAL(&c2, p2); +} + +//------------------------------------------------------------ + +TEST_GROUP(UnityCommandOptions); + +static int savedVerbose; +static int savedRepeat; +static int savedListOnly; +static const char* savedName; +static const char* savedGroup; +static const char** savedList; + +TEST_SETUP(UnityCommandOptions) +{ + savedVerbose = UnityFixture.Verbose; + savedRepeat = UnityFixture.RepeatCount; + savedListOnly = UnityFixture.ListOnly; + savedName = UnityFixture.NameFilter; + savedGroup = UnityFixture.GroupFilter; + savedList = UnityFixture.PlainListOfTests; +} + +TEST_TEAR_DOWN(UnityCommandOptions) +{ + UnityFixture.Verbose = savedVerbose; + UnityFixture.RepeatCount= savedRepeat; + UnityFixture.ListOnly = savedListOnly; + UnityFixture.NameFilter = savedName; + UnityFixture.GroupFilter = savedGroup; + UnityFixture.PlainListOfTests = savedList; +} + + +static const char* noOptions[] = { + "testrunner.exe" +}; + +TEST(UnityCommandOptions, DefaultOptions) +{ + UnityGetCommandLineOptions(1, noOptions); + TEST_ASSERT_EQUAL(0, UnityFixture.Verbose); + TEST_ASSERT_POINTERS_EQUAL(0, UnityFixture.GroupFilter); + TEST_ASSERT_POINTERS_EQUAL(0, UnityFixture.NameFilter); + TEST_ASSERT_EQUAL(1, UnityFixture.RepeatCount); +} + +static const char* verbose[] = { + "testrunner.exe", + "-v" +}; + +TEST(UnityCommandOptions, OptionVerbose) +{ + TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(2, verbose)); + TEST_ASSERT_EQUAL(1, UnityFixture.Verbose); +} + +static const char* group[] = { + "testrunner.exe", + "-g", "groupname" +}; + +TEST(UnityCommandOptions, OptionSelectTestByGroup) +{ + TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(3, group)); + STRCMP_EQUAL("groupname", UnityFixture.GroupFilter); +} + +static const char* name[] = { + "testrunner.exe", + "-n", "testname" +}; + +TEST(UnityCommandOptions, OptionSelectTestByName) +{ + TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(3, name)); + STRCMP_EQUAL("testname", UnityFixture.NameFilter); +} + +static const char* repeat[] = { + "testrunner.exe", + "-r", "99" +}; + +TEST(UnityCommandOptions, OptionSelectRepeatTestsDefaultCount) +{ + TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(2, repeat)); + TEST_ASSERT_EQUAL(2, UnityFixture.RepeatCount); +} + +TEST(UnityCommandOptions, OptionSelectRepeatTestsSpecificCount) +{ + TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(3, repeat)); + TEST_ASSERT_EQUAL(99, UnityFixture.RepeatCount); +} + +static const char* multiple[] = { + "testrunner.exe", + "-v", + "-g", "groupname", + "-n", "testname", + "-r", "98" +}; + +TEST(UnityCommandOptions, MultipleOptions) +{ + TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(8, multiple)); + TEST_ASSERT_EQUAL(1, UnityFixture.Verbose); + STRCMP_EQUAL("groupname", UnityFixture.GroupFilter); + STRCMP_EQUAL("testname", UnityFixture.NameFilter); + TEST_ASSERT_EQUAL(98, UnityFixture.RepeatCount); +} + +static const char* dashRNotLast[] = { + "testrunner.exe", + "-v", + "-g", "gggg", + "-r", + "-n", "tttt", +}; + +TEST(UnityCommandOptions, MultipleOptionsDashRNotLastAndNoValueSpecified) +{ + TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(7, dashRNotLast)); + TEST_ASSERT_EQUAL(1, UnityFixture.Verbose); + STRCMP_EQUAL("gggg", UnityFixture.GroupFilter); + STRCMP_EQUAL("tttt", UnityFixture.NameFilter); + TEST_ASSERT_EQUAL(2, UnityFixture.RepeatCount); +} + +static const char* unknownCommand[] = { + "testrunner.exe", + "-v", + "-g", "groupname", + "-n", "testname", + "-r", "98", + "-z" +}; +TEST(UnityCommandOptions, UnknownCommandIsIgnored) +{ + TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(9, unknownCommand)); + TEST_ASSERT_EQUAL(1, UnityFixture.Verbose); + STRCMP_EQUAL("groupname", UnityFixture.GroupFilter); + STRCMP_EQUAL("testname", UnityFixture.NameFilter); + TEST_ASSERT_EQUAL(98, UnityFixture.RepeatCount); +} + +static const char* listing[] = { + "testrunner.exe", + "-l", +}; +TEST(UnityCommandOptions, Listing) +{ + TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(2, listing)); + TEST_ASSERT_EQUAL(1, UnityFixture.ListOnly); +} + +static const char* exactListVerbose[] = { + "testrunner.exe", + "-v", + "--", + "MyTest/TestOne", + "MyTest/TestTwo", + NULL +}; +TEST(UnityCommandOptions, ExactList) +{ + TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(5, exactListVerbose)); + TEST_ASSERT_EQUAL(1, UnityFixture.Verbose); + TEST_ASSERT_EQUAL_STRING("MyTest/TestOne", UnityFixture.PlainListOfTests[0]); + TEST_ASSERT_EQUAL_STRING("MyTest/TestTwo", UnityFixture.PlainListOfTests[1]); + TEST_ASSERT_NULL(UnityFixture.PlainListOfTests[2]); +} + +//------------------------------------------------------------ + +TEST_GROUP(LeakDetection); + +TEST_SETUP(LeakDetection) +{ + UnityOutputCharSpy_Create(1000); +} + +TEST_TEAR_DOWN(LeakDetection) +{ + UnityOutputCharSpy_Destroy(); +} + +TEST(LeakDetection, DetectsLeak) +{ + void* m = malloc(10); + UnityOutputCharSpy_Enable(1); + TEST_PROTECTED(UnityMalloc_EndTest); + UnityOutputCharSpy_Enable(0); + CHECK(strstr(UnityOutputCharSpy_Get(), "This test leaks!")); + free(m); + Unity.CurrentTestFailed = 0; +} + +static void BufferOverrunFoundDuringFree_worker(void) +{ + void* m = malloc(10); + char* s = (char*)m; + s[10] = (char)0xFF; + free(m); +} + +TEST(LeakDetection, BufferOverrunFoundDuringFree) +{ + UnityOutputCharSpy_Enable(1); + TEST_PROTECTED(BufferOverrunFoundDuringFree_worker); + UnityOutputCharSpy_Enable(0); + CHECK(strstr(UnityOutputCharSpy_Get(), "Buffer overrun detected during free()")); + Unity.CurrentTestFailed = 0; +} + +static void BufferOverrunFoundDuringRealloc_worker(void) +{ + void* m = malloc(10); + char* s = (char*)m; + s[10] = (char)0xFF; + m = realloc(m, 100); +} + +TEST(LeakDetection, BufferOverrunFoundDuringRealloc) +{ + UnityOutputCharSpy_Enable(1); + TEST_PROTECTED(BufferOverrunFoundDuringRealloc_worker); + UnityOutputCharSpy_Enable(0); + CHECK(strstr(UnityOutputCharSpy_Get(), "Buffer overrun detected during realloc()")); + Unity.CurrentTestFailed = 0; +} + +//------------------------------------------------------------ + +TEST_GROUP(Timeout); + +TEST_SETUP(Timeout) +{ +} + +TEST_TEAR_DOWN(Timeout) +{ +} + +static void SleepSome(void) +{ + usleep(100000); +} + +TEST(Timeout, Triggers) +{ + int result = TEST_PROTECTED_WITH_TIMEOUT(SleepSome, 10); + TEST_ASSERT_TRUE(Unity.CurrentTestTimeout); + TEST_ASSERT_NOT_EQUAL(0, result); + Unity.CurrentTestTimeout = false; +} + +TEST(Timeout, DoesNotTrigger) +{ + int result = TEST_PROTECTED_WITH_TIMEOUT(SleepSome, 200); + UNITY_COUNTER_TYPE isTimeout = Unity.CurrentTestTimeout; + Unity.CurrentTestTimeout = 0; + TEST_ASSERT_EQUAL(0, result); + TEST_ASSERT_FALSE(isTimeout); +} + +//------------------------------------------------------------ +// Manual checking +//------------------------------------------------------------ + +TEST_GROUP(TimeoutInSetup); + +TEST_SETUP_WITH_TIMEOUT(TimeoutInSetup, 100) +{ + usleep(300000); +} + +TEST_TEAR_DOWN_WITH_TIMEOUT(TimeoutInSetup, 100) +{ + usleep(2); +} + +TEST_WITH_TIMEOUT(TimeoutInSetup, Test, 100) +{ + usleep(2); +} + +TEST_GROUP(TimeoutInBody); + +TEST_SETUP_WITH_TIMEOUT(TimeoutInBody, 100) +{ + usleep(2); +} + +TEST_TEAR_DOWN_WITH_TIMEOUT(TimeoutInBody, 100) +{ + usleep(2); +} + +TEST_WITH_TIMEOUT(TimeoutInBody, Test, 100) +{ + usleep(300000); +} + +TEST_GROUP(TimeoutInTearDown); + +TEST_SETUP_WITH_TIMEOUT(TimeoutInTearDown, 100) +{ + usleep(2); +} + +TEST_TEAR_DOWN_WITH_TIMEOUT(TimeoutInTearDown, 100) +{ + usleep(300000); +} + +TEST_WITH_TIMEOUT(TimeoutInTearDown, Test, 100) +{ + usleep(2); +} diff --git a/tests/unity/unity_fixture_TestRunner.c b/tests/unity/unity_fixture_TestRunner.c new file mode 100644 index 000000000..5661e275f --- /dev/null +++ b/tests/unity/unity_fixture_TestRunner.c @@ -0,0 +1,64 @@ +//- Copyright (c) 2010 James Grenning and Contributed to Unity Project +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#include + +TEST_GROUP_RUNNER(UnityFixture) +{ + RUN_TEST_CASE(UnityFixture, PointerSetting); + RUN_TEST_CASE(UnityFixture, ForceMallocFail); + RUN_TEST_CASE(UnityFixture, ReallocSmallerIsUnchanged); + RUN_TEST_CASE(UnityFixture, ReallocSameIsUnchanged); + RUN_TEST_CASE(UnityFixture, ReallocLargerNeeded); + RUN_TEST_CASE(UnityFixture, ReallocNullPointerIsLikeMalloc); + RUN_TEST_CASE(UnityFixture, ReallocSizeZeroFreesMemAndReturnsNullPointer); + RUN_TEST_CASE(UnityFixture, CallocFillsWithZero); + RUN_TEST_CASE(UnityFixture, PointerSet); +} + +TEST_GROUP_RUNNER(UnityCommandOptions) +{ + RUN_TEST_CASE(UnityCommandOptions, DefaultOptions); + RUN_TEST_CASE(UnityCommandOptions, OptionVerbose); + RUN_TEST_CASE(UnityCommandOptions, OptionSelectTestByGroup); + RUN_TEST_CASE(UnityCommandOptions, OptionSelectTestByName); + RUN_TEST_CASE(UnityCommandOptions, OptionSelectRepeatTestsDefaultCount); + RUN_TEST_CASE(UnityCommandOptions, OptionSelectRepeatTestsSpecificCount); + RUN_TEST_CASE(UnityCommandOptions, MultipleOptions); + RUN_TEST_CASE(UnityCommandOptions, MultipleOptionsDashRNotLastAndNoValueSpecified); + RUN_TEST_CASE(UnityCommandOptions, UnknownCommandIsIgnored); + RUN_TEST_CASE(UnityCommandOptions, Listing); + RUN_TEST_CASE(UnityCommandOptions, ExactList); +} + +TEST_GROUP_RUNNER(LeakDetection) +{ + RUN_TEST_CASE(LeakDetection, DetectsLeak); + RUN_TEST_CASE(LeakDetection, BufferOverrunFoundDuringFree); + RUN_TEST_CASE(LeakDetection, BufferOverrunFoundDuringRealloc); +} + +TEST_GROUP_RUNNER(Timeout) +{ + RUN_TEST_CASE(Timeout, Triggers); + RUN_TEST_CASE(Timeout, DoesNotTrigger); +} + +TEST_GROUP_RUNNER(TimeoutInSetup) +{ + RUN_TEST_CASE(TimeoutInSetup, Test); +} + +TEST_GROUP_RUNNER(TimeoutInBody) +{ + RUN_TEST_CASE(TimeoutInBody, Test); +} + +TEST_GROUP_RUNNER(TimeoutInTearDown) +{ + RUN_TEST_CASE(TimeoutInTearDown, Test); +} diff --git a/tests/unity/unity_output_Spy.c b/tests/unity/unity_output_Spy.c new file mode 100644 index 000000000..0a0ad0448 --- /dev/null +++ b/tests/unity/unity_output_Spy.c @@ -0,0 +1,56 @@ +//- Copyright (c) 2010 James Grenning and Contributed to Unity Project +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + + +#include "unity_output_Spy.h" +#include +#include +#include + +static int size; +static int count; +static char* buffer; +static int spy_enable; + +void UnityOutputCharSpy_Create(int s) +{ + size = s; + count = 0; + spy_enable = 0; + buffer = malloc(size); + memset(buffer, 0, size); +} + +void UnityOutputCharSpy_Destroy(void) +{ + size = 0; + free(buffer); +} + +int UnityOutputCharSpy_OutputChar(int c) +{ + if (spy_enable) + { + if (count < (size-1)) + buffer[count++] = c; + } + else + { + putchar(c); + } + return c; +} + +const char * UnityOutputCharSpy_Get(void) +{ + return buffer; +} + +void UnityOutputCharSpy_Enable(int enable) +{ + spy_enable = enable; +} diff --git a/tests/unity/unity_output_Spy.h b/tests/unity/unity_output_Spy.h new file mode 100644 index 000000000..791f6a58d --- /dev/null +++ b/tests/unity/unity_output_Spy.h @@ -0,0 +1,17 @@ +//- Copyright (c) 2010 James Grenning and Contributed to Unity Project +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef D_unity_output_Spy_H +#define D_unity_output_Spy_H + +void UnityOutputCharSpy_Create(int s); +void UnityOutputCharSpy_Destroy(void); +int UnityOutputCharSpy_OutputChar(int c); +const char * UnityOutputCharSpy_Get(void); +void UnityOutputCharSpy_Enable(int enable); + +#endif diff --git a/tests/unity_ramtest/.gitignore b/tests/unity_ramtest/.gitignore new file mode 100644 index 000000000..fa1ec7579 --- /dev/null +++ b/tests/unity_ramtest/.gitignore @@ -0,0 +1,11 @@ +/Make.dep +/.depend +/.built +/*.asm +/*.obj +/*.rel +/*.lst +/*.sym +/*.adb +/*.lib +/*.src diff --git a/tests/unity_ramtest/Kconfig b/tests/unity_ramtest/Kconfig new file mode 100644 index 000000000..554b24819 --- /dev/null +++ b/tests/unity_ramtest/Kconfig @@ -0,0 +1,11 @@ +# +# For a description of the syntax of this configuration file, +# see misc/tools/kconfig-language.txt. +# + +config TESTS_UNITY_RAMTEST + bool "Automated RAM test" + default n + ---help--- + Enable automated RAM test + diff --git a/tests/unity_ramtest/Make.defs b/tests/unity_ramtest/Make.defs new file mode 100644 index 000000000..88a6de118 --- /dev/null +++ b/tests/unity_ramtest/Make.defs @@ -0,0 +1,39 @@ +############################################################################ +# apps/tests/unity_ramtest/Make.defs +# Adds selected testing applications to apps/ build +# +# Copyright (C) 2015 Haltian Ltd. All rights reserved. +# Author: Roman Saveljev +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +ifeq ($(CONFIG_TESTS_UNITY_RAMTEST),y) +CONFIGURED_APPS += tests/unity_ramtest +endif diff --git a/tests/unity_ramtest/Makefile b/tests/unity_ramtest/Makefile new file mode 100644 index 000000000..2517a218d --- /dev/null +++ b/tests/unity_ramtest/Makefile @@ -0,0 +1,146 @@ +############################################################################ +# apps/tests/unity_ramtest/Makefile +# +# Copyright (C) 2015 Haltian Ltd. All rights reserved. +# Author: Roman Saveljev +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +APPNAME = unity_ramtest +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +CFLAGS += -x c + +ASRCS = +RUNNERSRC = unity_ramtest_runner.src +TESTSRCS = marching_zeroes.c marching_ones.c pattern.c addr_in_addr.c +CSRCS = $(TESTSRCS) +MAINSRC = unity_ramtest_main.c + +RUNNEROBJ = $(RUNNERSRC:.src=$(OBJEXT)) +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +MAINOBJ = $(MAINSRC:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(MAINSRC) $(RUNNERSRC) +OBJS = $(AOBJS) $(COBJS) $(RUNNEROBJ) + +ifneq ($(CONFIG_BUILD_KERNEL),y) + OBJS += $(MAINOBJ) +endif + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + BIN = ..\..\libapps$(LIBEXT) +else +ifeq ($(WINTOOL),y) + BIN = ..\\..\\libapps$(LIBEXT) +else + BIN = ../../libapps$(LIBEXT) +endif +endif + +ifeq ($(WINTOOL),y) + INSTALL_DIR = "${shell cygpath -w $(BIN_DIR)}" +else + INSTALL_DIR = $(BIN_DIR) +endif + +PROGNAME = unity_ramtest$(EXEEXT) + +ROOTDEPPATH = --dep-path . + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend distclean + +$(RUNNERSRC) : $(TESTSRCS) + $(Q) CPP="$(CPP)" $(APPDIR)/tests/tools/build_fixture_runner.pl $^ >$@ + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(RUNNEROBJ): $(RUNNERSRC) + $(call COMPILE, $<, $@) + $(Q) OBJCOPY=$(OBJCOPY) $(APPDIR)/tests/tools/rename_symbols $(APPNAME) $@ + +$(COBJS) $(MAINOBJ): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + $(Q) OBJCOPY=$(OBJCOPY) $(APPDIR)/tests/tools/rename_symbols $(APPNAME) $@ + +.built: $(OBJS) + $(call ARCHIVE, $(BIN), $(OBJS)) + @touch .built + +ifeq ($(CONFIG_BUILD_KERNEL),y) +$(BIN_DIR)$(DELIM)$(PROGNAME): $(OBJS) $(MAINOBJ) + @echo "LD: $(PROGNAME)" + $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME) $(ARCHCRT0OBJ) $(MAINOBJ) $(LDLIBS) + $(Q) $(NM) -u $(INSTALL_DIR)$(DELIM)$(PROGNAME) + +install: $(BIN_DIR)$(DELIM)$(PROGNAME) + +else +install: + +endif + +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) +$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) + +context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat +else +context: +endif + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + $(call DELFILE, .built) + $(call DELFILE, unity_dev_err_runner.src) + $(call CLEAN) + +distclean: clean + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/tests/unity_ramtest/addr_in_addr.c b/tests/unity_ramtest/addr_in_addr.c new file mode 100644 index 000000000..edbb9067e --- /dev/null +++ b/tests/unity_ramtest/addr_in_addr.c @@ -0,0 +1,185 @@ +/**************************************************************************** + * apps/tests/unity_ramtest/addr_in_addr.c + * Automated RAM test copied from apps/system/ramtest + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Author: Roman Saveljev + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include "library.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static void* g_memory; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void addr_in_addr(enum memory_access_width width) +{ + unity_ramtest_write_addrinaddr(width, g_memory, MEMORY_ALLOCATION_SIZE); + unity_ramtest_verify_addrinaddr(width, g_memory, MEMORY_ALLOCATION_SIZE); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +TEST_GROUP(AddrInAddr); + +/**************************************************************************** + * Name: AddrInAddr test group setup + * + * Description: + * Setup function executed before each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_SETUP(AddrInAddr) +{ + g_memory = malloc(MEMORY_ALLOCATION_SIZE); + TEST_ASSERT_NOT_NULL(g_memory); +} + +/**************************************************************************** + * Name: AddrInAddr test group tear down + * + * Description: + * Tear down function executed after each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_TEAR_DOWN(AddrInAddr) +{ + free(g_memory); + g_memory = NULL; +} + +/**************************************************************************** + * Name: ByteAccess + * + * Description: + * Daisy-chain writing the memory one byte at a time + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(AddrInAddr, ByteAccess) +{ + addr_in_addr(MEMORY_ACCESS_BYTE); +} + +/**************************************************************************** + * Name: HalfAccess + * + * Description: + * Daisy-chain writing the memory a half-word at a time + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(AddrInAddr, HalfAccess) +{ + addr_in_addr(MEMORY_ACCESS_HALFWORD); +} + +/**************************************************************************** + * Name: WordAccess + * + * Description: + * Daisy-chain writing the memory a word at a time + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(AddrInAddr, WordAccess) +{ + addr_in_addr(MEMORY_ACCESS_WORD); +} diff --git a/tests/unity_ramtest/library.h b/tests/unity_ramtest/library.h new file mode 100644 index 000000000..fd1de1056 --- /dev/null +++ b/tests/unity_ramtest/library.h @@ -0,0 +1,196 @@ +/**************************************************************************** + * apps/examples/unity_ramtest/library.h + * Common functions + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Author: Roman Saveljev + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#ifndef __TESTS_UNITY_RAMTEST_LIBRARY_H +#define __TESTS_UNITY_RAMTEST_LIBRARY_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +#define MEMORY_ALLOCATION_SIZE 0x2000 + +/**************************************************************************** + * Public Types + ****************************************************************************/ +enum memory_access_width +{ + MEMORY_ACCESS_BYTE = 8, + MEMORY_ACCESS_HALFWORD = 16, + MEMORY_ACCESS_WORD = 32 +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: unity_ramtest_write_memory + * + * Description: + * Write memory with specific pattern and access width + * + * Input Parameters: + * value - pattern to write + * width - access width + * start - memory region starting address + * size - number of bytes allocated for the region + * + * Returned Value: + * none, fails the testcase + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +void unity_ramtest_write_memory(uint32_t value, enum memory_access_width width, void *start, size_t size); + +/**************************************************************************** + * Name: unity_ramtest_verify_memory + * + * Description: + * Verifies memory has specific pattern and reading it with access width + * + * Input Parameters: + * value - pattern to expect + * width - access width + * start - memory region starting address + * size - number of bytes allocated for the region + * + * Returned Value: + * none, fails the testcase + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +void unity_ramtest_verify_memory(uint32_t value, enum memory_access_width width, void *start, size_t size); + +/**************************************************************************** + * Name: unity_ramtest_write_memory2 + * + * Description: + * Writes memory with two alternating patterns + * + * Input Parameters: + * value_one - first pattern to write + * value_two - second pattern to write + * width - access width + * start - memory region starting address + * size - number of bytes allocated for the region + * + * Returned Value: + * none, fails the testcase + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +void unity_ramtest_write_memory2(uint32_t value_one, uint32_t value_two, enum memory_access_width width, void *start, size_t size); + +/**************************************************************************** + * Name: unity_ramtest_verify_memory2 + * + * Description: + * Verifies memory is filled with two alternating patterns + * + * Input Parameters: + * value_one - first pattern to expect + * value_two - second pattern to expect + * width - access width + * start - memory region starting address + * size - number of bytes allocated for the region + * + * Returned Value: + * none, fails the testcase + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +void unity_ramtest_verify_memory2(uint32_t value_one, uint32_t value_two, enum memory_access_width width, void *start, size_t size); + +/**************************************************************************** + * Name: unity_ramtest_write_addrinaddr + * + * Description: + * Writes every next memory location with the value from the previous location + * + * Input Parameters: + * width - access width + * start - memory region starting address + * size - number of bytes allocated for the region + * + * Returned Value: + * none, fails the testcase + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +void unity_ramtest_write_addrinaddr(enum memory_access_width width, void *start, size_t size); + +/**************************************************************************** + * Name: unity_ramtest_verify_addrinaddr + * + * Description: + * Verifies every memory location is filled with the value from the previous location + * + * Input Parameters: + * width - access width + * start - memory region starting address + * size - number of bytes allocated for the region + * + * Returned Value: + * none, fails the testcase + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +void unity_ramtest_verify_addrinaddr(enum memory_access_width width, void *start, size_t size); + +#endif /* __TESTS_UNITY_RAMTEST_LIBRARY_H */ diff --git a/tests/unity_ramtest/marching_ones.c b/tests/unity_ramtest/marching_ones.c new file mode 100644 index 000000000..5a77ed3f8 --- /dev/null +++ b/tests/unity_ramtest/marching_ones.c @@ -0,0 +1,191 @@ +/**************************************************************************** + * apps/tests/unity_ramtest/marching_ones.c + * Automated RAM test copied from apps/system/ramtest + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Author: Roman Saveljev + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include "library.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static void* g_memory; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +static void marching_ones(enum memory_access_width width, uint32_t mask) +{ + uint32_t pattern = 0x00000001; + + while (pattern != 0) + { + unity_ramtest_write_memory(pattern, width, g_memory, MEMORY_ALLOCATION_SIZE); + unity_ramtest_verify_memory(pattern, width, g_memory, MEMORY_ALLOCATION_SIZE); + pattern <<= 1; + pattern &= mask; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +TEST_GROUP(MarchingOnes); + +/**************************************************************************** + * Name: MarchingOnes test group setup + * + * Description: + * Setup function executed before each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_SETUP(MarchingOnes) +{ + g_memory = malloc(MEMORY_ALLOCATION_SIZE); + TEST_ASSERT_NOT_NULL(g_memory); +} + +/**************************************************************************** + * Name: MarchingOnes test group tear down + * + * Description: + * Tear down function executed after each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_TEAR_DOWN(MarchingOnes) +{ + free(g_memory); + g_memory = NULL; +} + +/**************************************************************************** + * Name: ByteAccess + * + * Description: + * Running one on every memory location with byte access width + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(MarchingOnes, ByteAccess) +{ + marching_ones(MEMORY_ACCESS_BYTE, 0xff); +} + +/**************************************************************************** + * Name: HalfAccess + * + * Description: + * Running one on every memory location with half-word access width + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(MarchingOnes, HalfAccess) +{ + marching_ones(MEMORY_ACCESS_HALFWORD, 0xffff); +} + +/**************************************************************************** + * Name: WordAccess + * + * Description: + * Running one on every memory location with word access width + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(MarchingOnes, WordAccess) +{ + marching_ones(MEMORY_ACCESS_WORD, 0xffffffff); +} diff --git a/tests/unity_ramtest/marching_zeroes.c b/tests/unity_ramtest/marching_zeroes.c new file mode 100644 index 000000000..bc54be0a2 --- /dev/null +++ b/tests/unity_ramtest/marching_zeroes.c @@ -0,0 +1,193 @@ +/**************************************************************************** + * apps/tests/unity_ramtest/marching_zeroes.c + * Automated RAM test copied from apps/system/ramtest + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Author: Roman Saveljev + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include "library.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static void* g_memory; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void marching_zeroes(enum memory_access_width width, uint32_t mask) +{ + uint32_t pattern = 0xfffffffe; + + while (pattern != 0xffffffff) + { + unity_ramtest_write_memory(pattern, width, g_memory, MEMORY_ALLOCATION_SIZE); + unity_ramtest_verify_memory(pattern, width, g_memory, MEMORY_ALLOCATION_SIZE); + pattern <<= 1; + pattern |= 1; + pattern |= ~mask; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +TEST_GROUP(MarchingZeroes); + +/**************************************************************************** + * Name: MarchingZeroes test group setup + * + * Description: + * Setup function executed before each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_SETUP(MarchingZeroes) +{ + g_memory = malloc(MEMORY_ALLOCATION_SIZE); + TEST_ASSERT_NOT_NULL(g_memory); +} + +/**************************************************************************** + * Name: MarchingZeroes test group tear down + * + * Description: + * Tear down function executed after each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_TEAR_DOWN(MarchingZeroes) +{ + free(g_memory); + g_memory = NULL; +} + +/**************************************************************************** + * Name: ByteAccess + * + * Description: + * Running zero on every memory location with byte access width + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(MarchingZeroes, ByteAccess) +{ + marching_zeroes(MEMORY_ACCESS_BYTE, 0xff); +} + +/**************************************************************************** + * Name: HalfAccess + * + * Description: + * Running zero on every memory location with half-word access width + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(MarchingZeroes, HalfAccess) +{ + marching_zeroes(MEMORY_ACCESS_HALFWORD, 0xffff); +} + +/**************************************************************************** + * Name: WordAccess + * + * Description: + * Running zero on every memory location with word access width + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(MarchingZeroes, WordAccess) +{ + marching_zeroes(MEMORY_ACCESS_WORD, 0xffffffff); +} diff --git a/tests/unity_ramtest/pattern.c b/tests/unity_ramtest/pattern.c new file mode 100644 index 000000000..89d2b705e --- /dev/null +++ b/tests/unity_ramtest/pattern.c @@ -0,0 +1,311 @@ +/**************************************************************************** + * apps/tests/unity_ramtest/pattern.c + * Automated RAM test copied from apps/system/ramtest + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Author: Roman Saveljev + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include "library.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static void* g_memory; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void pattern(enum memory_access_width width, uint32_t value_one, uint32_t value_two) +{ + unity_ramtest_write_memory2(value_one, value_two, width, g_memory, MEMORY_ALLOCATION_SIZE); + unity_ramtest_verify_memory2(value_one, value_two, width, g_memory, MEMORY_ALLOCATION_SIZE); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +TEST_GROUP(Pattern); + +/**************************************************************************** + * Name: Pattern test group setup + * + * Description: + * Setup function executed before each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_SETUP(Pattern) +{ + g_memory = malloc(MEMORY_ALLOCATION_SIZE); + TEST_ASSERT_NOT_NULL(g_memory); +} + +/**************************************************************************** + * Name: Pattern test group tear down + * + * Description: + * Tear down function executed after each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_TEAR_DOWN(Pattern) +{ + free(g_memory); + g_memory = NULL; +} + +/**************************************************************************** + * Name: ByteAccess_5_a + * + * Description: + * Writing pattern 0x55 and 0xaa with byte access + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(Pattern, ByteAccess_5_a) +{ + pattern(MEMORY_ACCESS_BYTE, 0x55, 0xaa); +} + +/**************************************************************************** + * Name: ByteAccess_6_9 + * + * Description: + * Writing pattern 0x66 and 0x99 with byte access + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(Pattern, ByteAccess_6_9) +{ + pattern(MEMORY_ACCESS_BYTE, 0x66, 0x99); +} + +/**************************************************************************** + * Name: ByteAccess_3_c + * + * Description: + * Writing pattern 0x33 and 0xcc with byte access + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(Pattern, ByteAccess_3_c) +{ + pattern(MEMORY_ACCESS_BYTE, 0x33, 0xcc); +} + +/**************************************************************************** + * Name: HalfAccess_5_a + * + * Description: + * Writing pattern 0x5555 and 0xaaaa with byte access + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(Pattern, HalfAccess_5_a) +{ + pattern(MEMORY_ACCESS_BYTE, 0x5555, 0xaaaa); +} + +/**************************************************************************** + * Name: HalfAccess_6_9 + * + * Description: + * Writing pattern 0x6666 and 0x9999 with byte access + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(Pattern, HalfAccess_6_9) +{ + pattern(MEMORY_ACCESS_BYTE, 0x6666, 0x9999); +} + +/**************************************************************************** + * Name: HalfAccess_3_c + * + * Description: + * Writing pattern 0x3333 and 0xcccc with byte access + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(Pattern, HalfAccess_3_c) +{ + pattern(MEMORY_ACCESS_BYTE, 0x3333, 0xcccc); +} + +/**************************************************************************** + * Name: WordAccess_5_a + * + * Description: + * Writing pattern 0x55555555 and 0xaaaaaaaa with byte access + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(Pattern, WordAccess_5_a) +{ + pattern(MEMORY_ACCESS_BYTE, 0x55555555, 0xaaaaaaaa); +} + +/**************************************************************************** + * Name: WordAccess_6_9 + * + * Description: + * Writing pattern 0x66666666 and 0x99999999 with byte access + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(Pattern, WordAccess_6_9) +{ + pattern(MEMORY_ACCESS_BYTE, 0x66666666, 0x99999999); +} + +/**************************************************************************** + * Name: WordAccess_3_c + * + * Description: + * Writing pattern 0x33333333 and 0xcccccccc with byte access + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(Pattern, WordAccess_3_c) +{ + pattern(MEMORY_ACCESS_BYTE, 0x33333333, 0xcccccccc); +} diff --git a/tests/unity_ramtest/unity_ramtest_main.c b/tests/unity_ramtest/unity_ramtest_main.c new file mode 100644 index 000000000..c86b9fba6 --- /dev/null +++ b/tests/unity_ramtest/unity_ramtest_main.c @@ -0,0 +1,503 @@ +/**************************************************************************** + * apps/tests/unity_ramtest/unity_ramtest_main.c + * Main function for Unity test application + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Author: Roman Saveljev + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include + +#include "library.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +static void runAllTests(void); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: runAllTests + * + * Description: + * Sequentially runs all included test groups + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void runAllTests(void) +{ + RUN_TEST_GROUP(MarchingZeroes); + RUN_TEST_GROUP(MarchingOnes); + RUN_TEST_GROUP(Pattern); + RUN_TEST_GROUP(AddrInAddr); +} + +/**************************************************************************** + * Name: number_of_transfers + * + * Description: + * Calculate number of transfers to cover the chunk of memory + * + * Input Parameters: + * width - access width + * size - memory size + * + * Returned Value: + * Number of transfers + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static size_t number_of_transfers(enum memory_access_width width, size_t size) +{ + if (width == MEMORY_ACCESS_BYTE) + { + return size; + } + else if (width == MEMORY_ACCESS_WORD) + { + return size >> 2; + } + else if (width == MEMORY_ACCESS_HALFWORD) + { + return size >> 1; + } + else + { + DEBUGASSERT(0); + return 0; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: unity_ramtest_write_memory + * + * Description: + * Write memory with specific pattern and access width + * + * Input Parameters: + * value - pattern to write + * width - access width + * start - memory region starting address + * size - number of bytes allocated for the region + * + * Returned Value: + * none, fails the testcase + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +void unity_ramtest_write_memory(uint32_t value, enum memory_access_width width, void *start, size_t size) +{ + size_t i, nxfrs = number_of_transfers(width, size); + + if (width == MEMORY_ACCESS_WORD) + { + uint32_t *ptr = (uint32_t*)start; + for (i = 0; i < nxfrs; i++) + { + *ptr++ = value; + } + } + else if (width == MEMORY_ACCESS_HALFWORD) + { + uint16_t *ptr = (uint16_t*)start; + for (i = 0; i < nxfrs; i++) + { + *ptr++ = (uint16_t)value; + } + } + else if (width == MEMORY_ACCESS_BYTE) + { + uint8_t *ptr = (uint8_t*)start; + for (i = 0; i < nxfrs; i++) + { + *ptr++ = (uint8_t)value; + } + } + else + { + TEST_FAIL_MESSAGE("Invalid width value"); + } +} + +/**************************************************************************** + * Name: unity_ramtest_verify_memory + * + * Description: + * Verifies memory has specific pattern and reading it with access width + * + * Input Parameters: + * value - pattern to expect + * width - access width + * start - memory region starting address + * size - number of bytes allocated for the region + * + * Returned Value: + * none, fails the testcase + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +void unity_ramtest_verify_memory(uint32_t value, enum memory_access_width width, void *start, size_t size) +{ + size_t i, nxfrs = number_of_transfers(width, size); + + if (width == MEMORY_ACCESS_WORD) + { + uint32_t *ptr = (uint32_t*)start; + for (i = 0; i < nxfrs; i++) + { + TEST_ASSERT_EQUAL_HEX32(value, *ptr); + ptr++; + } + } + else if (width == MEMORY_ACCESS_HALFWORD) + { + uint16_t value16 = (uint16_t)(value & 0x0000ffff); + uint16_t *ptr = (uint16_t*)start; + for (i = 0; i < nxfrs; i++) + { + TEST_ASSERT_EQUAL_HEX16(value16, *ptr); + ptr++; + } + } + else if (width == MEMORY_ACCESS_BYTE) + { + uint8_t value8 = (uint8_t)(value & 0x000000ff); + uint8_t *ptr = (uint8_t*)start; + for (i = 0; i < nxfrs; i++) + { + TEST_ASSERT_EQUAL_HEX(value8, *ptr); + ptr++; + } + } + else + { + TEST_FAIL_MESSAGE("Invalid width value"); + } +} + +/**************************************************************************** + * Name: unity_ramtest_write_memory2 + * + * Description: + * Writes memory with two alternating patterns + * + * Input Parameters: + * value_one - first pattern to write + * value_two - second pattern to write + * width - access width + * start - memory region starting address + * size - number of bytes allocated for the region + * + * Returned Value: + * none, fails the testcase + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +void unity_ramtest_write_memory2(uint32_t value_one, uint32_t value_two, enum memory_access_width width, void *start, size_t size) +{ + size_t even_nxfrs = number_of_transfers(width, size) & ~1; + size_t i; + + if (width == MEMORY_ACCESS_WORD) + { + uint32_t *ptr = (uint32_t*)start; + for (i = 0; i < even_nxfrs; i += 2) + { + *ptr++ = value_one; + *ptr++ = value_two; + } + } + else if (width == MEMORY_ACCESS_HALFWORD) + { + uint16_t *ptr = (uint16_t*)start; + for (i = 0; i < even_nxfrs; i += 2) + { + *ptr++ = (uint16_t)value_one; + *ptr++ = (uint16_t)value_two; + } + } + else if (width == MEMORY_ACCESS_BYTE) + { + uint8_t *ptr = (uint8_t*)start; + for (i = 0; i < even_nxfrs; i += 2) + { + *ptr++ = (uint8_t)value_one; + *ptr++ = (uint8_t)value_two; + } + } + else + { + TEST_FAIL_MESSAGE("Invalid width value"); + } +} + +/**************************************************************************** + * Name: unity_ramtest_verify_memory2 + * + * Description: + * Verifies memory is filled with two alternating patterns + * + * Input Parameters: + * value_one - first pattern to expect + * value_two - second pattern to expect + * width - access width + * start - memory region starting address + * size - number of bytes allocated for the region + * + * Returned Value: + * none, fails the testcase + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +void unity_ramtest_verify_memory2(uint32_t value_one, uint32_t value_two, enum memory_access_width width, void *start, size_t size) +{ + size_t even_nxfrs = number_of_transfers(width, size) & ~1; + size_t i; + + if (width == MEMORY_ACCESS_WORD) + { + uint32_t *ptr = (uint32_t*)start; + for (i = 0; i < even_nxfrs; i += 2) + { + TEST_ASSERT_EQUAL_HEX32(value_one, ptr[0]); + TEST_ASSERT_EQUAL_HEX32(value_two, ptr[1]); + ptr += 2; + } + } + else if (width == MEMORY_ACCESS_HALFWORD) + { + uint16_t value16_one = (uint16_t)(value_one & 0x0000ffff); + uint16_t value16_two = (uint16_t)(value_two & 0x0000ffff); + uint16_t *ptr = (uint16_t*)start; + for (i = 0; i < even_nxfrs; i += 2) + { + TEST_ASSERT_EQUAL_HEX16(value16_one, ptr[0]); + TEST_ASSERT_EQUAL_HEX16(value16_two, ptr[1]); + ptr += 2; + } + } + else if (width == MEMORY_ACCESS_BYTE) + { + uint8_t value8_one = (uint8_t)(value_one & 0x000000ff); + uint8_t value8_two = (uint8_t)(value_two & 0x000000ff); + uint8_t *ptr = (uint8_t*)start; + for (i = 0; i < even_nxfrs; i += 2) + { + TEST_ASSERT_EQUAL_HEX(value8_one, ptr[0]); + TEST_ASSERT_EQUAL_HEX(value8_two, ptr[1]); + ptr += 2; + } + } + else + { + TEST_FAIL_MESSAGE("Invalid width value"); + } +} + +/**************************************************************************** + * Name: unity_ramtest_write_addrinaddr + * + * Description: + * Writes every next memory location with the value from the previous location + * + * Input Parameters: + * width - access width + * start - memory region starting address + * size - number of bytes allocated for the region + * + * Returned Value: + * none, fails the testcase + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +void unity_ramtest_write_addrinaddr(enum memory_access_width width, void *start, size_t size) +{ + size_t i, nxfrs = number_of_transfers(width, size); + + if (width == MEMORY_ACCESS_WORD) + { + uint32_t *ptr = (uint32_t*)start; + for (i = 0; i < nxfrs; i++) + { + uint32_t value32 = (uint32_t)((uintptr_t)ptr); + *ptr++ = value32; + } + } + else if (width == MEMORY_ACCESS_HALFWORD) + { + uint16_t *ptr = (uint16_t*)start; + for (i = 0; i < nxfrs; i++) + { + uint16_t value16 = (uint16_t)((uintptr_t)ptr & 0x0000ffff); + *ptr++ = value16; + } + } + else if (width == MEMORY_ACCESS_BYTE) + { + uint8_t *ptr = (uint8_t*)start; + for (i = 0; i < nxfrs; i++) + { + uint8_t value8 = (uint8_t)((uintptr_t)ptr & 0x000000ff); + *ptr++ = value8; + } + } + else + { + TEST_FAIL_MESSAGE("Invalid width value"); + } +} + +/**************************************************************************** + * Name: unity_ramtest_verify_addrinaddr + * + * Description: + * Verifies every memory location is filled with the value from the previous location + * + * Input Parameters: + * width - access width + * start - memory region starting address + * size - number of bytes allocated for the region + * + * Returned Value: + * none, fails the testcase + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +void unity_ramtest_verify_addrinaddr(enum memory_access_width width, void *start, size_t size) +{ + size_t i, nxfrs = number_of_transfers(width, size); + + if (width == MEMORY_ACCESS_WORD) + { + uint32_t *ptr = (uint32_t*)start; + for (i = 0; i < nxfrs; i++) + { + uint32_t value32 = (uint32_t)((uintptr_t)ptr); + TEST_ASSERT_EQUAL_HEX32(*ptr, value32); + ptr++; + } + } + else if (width == MEMORY_ACCESS_HALFWORD) + { + uint16_t *ptr = (uint16_t*)start; + for (i = 0; i < nxfrs; i++) + { + uint16_t value16 = (uint16_t)((uintptr_t)ptr & 0x0000ffff); + TEST_ASSERT_EQUAL_HEX16(*ptr, value16); + ptr++; + } + } + else if (width == MEMORY_ACCESS_BYTE) + { + uint8_t *ptr = (uint8_t*)start; + for (i = 0; i < nxfrs; i++) + { + uint16_t value8 = (uint8_t)((uintptr_t)ptr & 0x000000ff); + TEST_ASSERT_EQUAL_HEX(*ptr, value8); + ptr++; + } + } + else + { + TEST_FAIL_MESSAGE("Invalid width value"); + } +} + +/**************************************************************************** + * Name: unity_ramtest_main + * + * Description: + * Application entry point + * + * Input Parameters: + * argc - number of arguments + * argv - arguments themselves + * + * Returned Value: + * exit status + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +int unity_ramtest_main(int argc, const char* argv[]) +{ + return UnityMain(argc, argv, runAllTests); +} diff --git a/tests/unity_usrsock/.gitignore b/tests/unity_usrsock/.gitignore new file mode 100644 index 000000000..fa1ec7579 --- /dev/null +++ b/tests/unity_usrsock/.gitignore @@ -0,0 +1,11 @@ +/Make.dep +/.depend +/.built +/*.asm +/*.obj +/*.rel +/*.lst +/*.sym +/*.adb +/*.lib +/*.src diff --git a/tests/unity_usrsock/Kconfig b/tests/unity_usrsock/Kconfig new file mode 100644 index 000000000..870afe96a --- /dev/null +++ b/tests/unity_usrsock/Kconfig @@ -0,0 +1,15 @@ +# +# For a description of the syntax of this configuration file, +# see misc/tools/kconfig-language.txt. +# + +config TESTS_UNITY_USRSOCK + bool "User-space networking stack API Unity tests" + default n + depends on NET + depends on NET_USRSOCK + depends on !DISABLE_POLL + select PIPES + ---help--- + Enable user-space networking stack API Unity tests + diff --git a/tests/unity_usrsock/Make.defs b/tests/unity_usrsock/Make.defs new file mode 100644 index 000000000..2f6460562 --- /dev/null +++ b/tests/unity_usrsock/Make.defs @@ -0,0 +1,39 @@ +############################################################################ +# apps/tests/unity_usrsock/Make.defs +# Adds selected testing applications to apps/ build +# +# Copyright (C) 2015 Haltian Ltd. All rights reserved. +# Author: Roman Saveljev +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +ifeq ($(CONFIG_TESTS_UNITY_USRSOCK),y) +CONFIGURED_APPS += tests/unity_usrsock +endif diff --git a/tests/unity_usrsock/Makefile b/tests/unity_usrsock/Makefile new file mode 100644 index 000000000..b856fbfd2 --- /dev/null +++ b/tests/unity_usrsock/Makefile @@ -0,0 +1,152 @@ +############################################################################ +# apps/examples/unity_usrsock/Makefile +# +# Copyright (C) 2015 Haltian Ltd. All rights reserved. +# Author: Roman Saveljev +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +APPNAME = unity_usrsock +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +ARCH_SRCDIR = $(TOPDIR)/arch/$(CONFIG_ARCH)/src +CFLAGS += -x c + +ASRCS = +RUNNERSRC = unity_usrsock_runner.src +TESTSRCS = chardev.c nodaemon.c basic_daemon.c basic_connect.c \ + noblock_connect.c basic_send.c noblock_send.c block_send.c \ + noblock_recv.c block_recv.c poll.c remote_disconnect.c \ + basic_setsockopt.c basic_getsockopt.c basic_getsockname.c \ + multi_thread.c wake_with_signal.c + +CSRCS = $(TESTSRCS) usrsocktest_daemon.c +MAINSRC = unity_usrsock_main.c + +RUNNEROBJ = $(RUNNERSRC:.src=$(OBJEXT)) +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +MAINOBJ = $(MAINSRC:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(MAINSRC) $(RUNNERSRC) +OBJS = $(AOBJS) $(COBJS) $(RUNNEROBJ) + +PROGNAME = unity_usrsock$(EXEEXT) + +ifneq ($(CONFIG_BUILD_KERNEL),y) + OBJS += $(MAINOBJ) +endif + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + BIN = ..\..\libapps$(LIBEXT) +else +ifeq ($(WINTOOL),y) + BIN = ..\\..\\libapps$(LIBEXT) +else + BIN = ../../libapps$(LIBEXT) +endif +endif + +ifeq ($(WINTOOL),y) + INSTALL_DIR = "${shell cygpath -w $(BIN_DIR)}" +else + INSTALL_DIR = $(BIN_DIR) +endif + +ROOTDEPPATH = --dep-path . + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend distclean + +$(RUNNERSRC) : $(TESTSRCS) + $(Q) CPP="$(CPP)" $(APPDIR)/tests/tools/build_fixture_runner.pl $^ >$@ + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(RUNNEROBJ): $(RUNNERSRC) + $(call COMPILE, $<, $@) + $(Q) OBJCOPY=$(OBJCOPY) $(APPDIR)/tests/tools/rename_symbols $(APPNAME) $@ + +$(COBJS) $(MAINOBJ): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + $(Q) OBJCOPY=$(OBJCOPY) $(APPDIR)/tests/tools/rename_symbols $(APPNAME) $@ + +.built: $(OBJS) + $(call ARCHIVE, $(BIN), $(OBJS)) + @touch .built + +ifeq ($(CONFIG_BUILD_KERNEL),y) +$(BIN_DIR)$(DELIM)$(PROGNAME): $(OBJS) $(MAINOBJ) + @echo "LD: $(PROGNAME)" + $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME) $(ARCHCRT0OBJ) $(MAINOBJ) $(LDLIBS) + $(Q) $(NM) -u $(INSTALL_DIR)$(DELIM)$(PROGNAME) + +install: $(BIN_DIR)$(DELIM)$(PROGNAME) + +else +install: + +endif + +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) +$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) + +context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat +else +context: +endif + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + $(call DELFILE, .built) + $(call DELFILE, test_runner.src) + $(call CLEAN) + +distclean: clean + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/tests/unity_usrsock/basic_connect.c b/tests/unity_usrsock/basic_connect.c new file mode 100644 index 000000000..5269b3337 --- /dev/null +++ b/tests/unity_usrsock/basic_connect.c @@ -0,0 +1,465 @@ +/**************************************************************************** + * apps/examples/unity_usrsock/basic_connect.c + * Basic connect tests with socket daemon + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Roman Saveljev + * Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "defines.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static bool started; +static int sd; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: Setup + * + * Description: + * Run before every testcase + * + * Input Parameters: + * dconf - test daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void Setup(struct usrsocktest_daemon_conf_s *dconf) +{ + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); +} + +/**************************************************************************** + * Name: Teardown + * + * Description: + * Run after every testcase + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void Teardown(void) +{ + int ret; + + if (sd >= 0) + { + ret = close(sd); + assert(ret >= 0); + } + + if (started) + { + ret = usrsocktest_daemon_stop(); + assert(ret == OK); + } +} + +/**************************************************************************** + * Name: NotConnected + * + * Description: + * Opened socket is not connected + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void NotConnected(void) +{ + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); +} + +/**************************************************************************** + * Name: Connect + * + * Description: + * Open and connect the socket + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void Connect(void) +{ + int ret; + struct sockaddr_in addr; + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + + /* Attempt reconnect to same address */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EISCONN, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + + /* Attempt reconnect to different address */ + + inet_pton(AF_INET, "1.1.1.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(1); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EISCONN, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Name: WrongAF + * + * Description: + * Open and connect the socket with wrong AF + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void WrongAF(void) +{ + int ret; + struct sockaddr_in addr; + + /* Try connect socket with wrong AF */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_UNIX; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EAFNOSUPPORT, errno); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Name: WrongPort + * + * Description: + * Open and connect the socket with wrong port + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void WrongPort(void) +{ + int ret; + struct sockaddr_in addr; + + /* Try connect socket to wrong port */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(127); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(ECONNREFUSED, errno); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Name: WrongEndpoint + * + * Description: + * Open and connect the socket with wrong endpoint + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void WrongEndpoint(void) +{ + int ret; + struct sockaddr_in addr; + + /* Try connect socket to unreachable endpoint */ + + inet_pton(AF_INET, "1.1.1.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(1); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(ENETUNREACH, errno); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + + /* Connect */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +TEST_GROUP(BasicConnect); + +TEST_SETUP(BasicConnect) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + Setup(&usrsocktest_daemon_config); +} + +TEST_TEAR_DOWN(BasicConnect) +{ + Teardown(); +} + +TEST(BasicConnect, NotConnected) +{ + NotConnected(); +} + +TEST(BasicConnect, Connect) +{ + Connect(); +} + +TEST(BasicConnect, WrongAF) +{ + WrongAF(); +} + +TEST(BasicConnect, WrongPort) +{ + WrongPort(); +} + +TEST(BasicConnect, WrongEndpoint) +{ + WrongEndpoint(); +} + +TEST_GROUP(BasicConnectDelay); + +TEST_SETUP(BasicConnectDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + Setup(&usrsocktest_daemon_config); +} + +TEST_TEAR_DOWN(BasicConnectDelay) +{ + Teardown(); +} + +TEST(BasicConnectDelay, NotConnected) +{ + NotConnected(); +} + +TEST(BasicConnectDelay, Connect) +{ + Connect(); +} + +TEST(BasicConnectDelay, WrongAF) +{ + WrongAF(); +} + +TEST(BasicConnectDelay, WrongPort) +{ + WrongPort(); +} + +TEST(BasicConnectDelay, WrongEndpoint) +{ + WrongEndpoint(); +} diff --git a/tests/unity_usrsock/basic_daemon.c b/tests/unity_usrsock/basic_daemon.c new file mode 100644 index 000000000..929f88aec --- /dev/null +++ b/tests/unity_usrsock/basic_daemon.c @@ -0,0 +1,653 @@ +/**************************************************************************** + * apps/examples/unity_usrsock/basic_daemon.c + * Basic tests with socket daemon + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Roman Saveljev + * Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "defines.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static bool started; +static int sd, sd2, sd3; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: NoActiveSockets + * + * Description: + * Checks there is no active sockets on daemon startup + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void NoActiveSockets(struct usrsocktest_daemon_conf_s *dconf) +{ + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); +} + +/**************************************************************************** + * Name: OpenClose + * + * Description: + * Open and close AF_INET socket, check active socket counter updates + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void OpenClose(struct usrsocktest_daemon_conf_s *dconf) +{ + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Name: UnsupportedType + * + * Description: + * Try open socket for unsupported type + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void UnsupportedType(struct usrsocktest_daemon_conf_s *dconf) +{ + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + + sd = socket(AF_INET, SOCK_RDM, 0); + TEST_ASSERT_TRUE(sd < 0); + TEST_ASSERT_EQUAL(EPROTONOSUPPORT, errno); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Name: UnsupportedProto + * + * Description: + * Try open socket for unsupported protocol + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void UnsupportedProto(struct usrsocktest_daemon_conf_s *dconf) +{ + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + + sd = socket(AF_INET, SOCK_STREAM, 1); + TEST_ASSERT_TRUE(sd < 0); + TEST_ASSERT_EQUAL(EPROTONOSUPPORT, errno); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Name: OpenThree + * + * Description: + * Open multiple sockets + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void OpenThree(struct usrsocktest_daemon_conf_s *dconf) +{ + int ret; + + dconf->max_sockets = 3; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + sd2 = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd2 >= 0); + TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); + sd3 = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd3 >= 0); + TEST_ASSERT_EQUAL(3, usrsocktest_daemon_get_num_active_sockets()); + ret = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_FALSE(ret >= 0); + TEST_ASSERT_EQUAL(3, usrsocktest_daemon_get_num_active_sockets()); + + ret = close(sd2); + TEST_ASSERT_EQUAL(0, ret); + sd2 = -1; + TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); + ret = close(sd); + TEST_ASSERT_EQUAL(0, ret); + sd = -1; + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + ret = close(sd3); + TEST_ASSERT_EQUAL(0, ret); + sd3 = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Name: Dup + * + * Description: + * Dup opened socket + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void Dup(struct usrsocktest_daemon_conf_s *dconf) +{ + int ret; + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + + sd2 = dup(sd); + TEST_ASSERT_TRUE(sd2 >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + + sd3 = dup(sd); + TEST_ASSERT_TRUE(sd3 >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + + ret = close(sd2); + TEST_ASSERT_EQUAL(0, ret); + sd2 = -1; + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + ret = close(sd); + TEST_ASSERT_EQUAL(0, ret); + sd = -1; + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + ret = close(sd3); + TEST_ASSERT_EQUAL(0, ret); + sd3 = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Name: Dup2 + * + * Description: + * Clone opened socket with dup2 + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void Dup2(struct usrsocktest_daemon_conf_s *dconf) +{ + int ret; + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + sd2 = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); + + ret = dup2(sd2, sd); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + + ret = close(sd2); + TEST_ASSERT_EQUAL(0, ret); + sd2 = -1; + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + ret = close(sd); + TEST_ASSERT_EQUAL(0, ret); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Name: Stops + * + * Description: + * Daemon stops unexpectedly + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void Stops(struct usrsocktest_daemon_conf_s *dconf) +{ + int ret; + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + sd2 = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd2 >= 0); + TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); + + ret = usrsocktest_daemon_stop(); + TEST_ASSERT_EQUAL(OK, ret); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); + + + TEST_ASSERT_EQUAL(0, close(sd)); + sd = -1; + TEST_ASSERT_EQUAL(0, close(sd2)); + sd2 = -1; +} + +/**************************************************************************** + * Name: StopsStarts + * + * Description: + * Daemon stops and restarts unexpectedly + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void StopsStarts(struct usrsocktest_daemon_conf_s *dconf) +{ + int ret; + struct sockaddr_in addr; + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + sd2 = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd2 >= 0); + TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = 255; + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EPIPE, errno); + + ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EPIPE, errno); + + TEST_ASSERT_EQUAL(0, close(sd)); + sd = -1; + TEST_ASSERT_EQUAL(0, close(sd2)); + sd2 = -1; + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +TEST_GROUP(BasicDaemon); + +/**************************************************************************** + * Name: BasicDaemon test group setup + * + * Description: + * Setup function executed before each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_SETUP(BasicDaemon) +{ + sd = -1; + sd2 = -1; + sd3 = -1; + started = false; +} + +/**************************************************************************** + * Name: BasicDaemon test group teardown + * + * Description: + * Setup function executed after each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_TEAR_DOWN(BasicDaemon) +{ + int ret; + if (sd >= 0) + { + ret = close(sd); + assert(ret >= 0); + } + if (sd2 >= 0) + { + ret = close(sd2); + assert(ret >= 0); + } + if (sd3 >= 0) + { + ret = close(sd3); + assert(ret >= 0); + } + if (started) + { + ret = usrsocktest_daemon_stop(); + assert(ret == OK); + } +} + +TEST(BasicDaemon, NoActiveSockets) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + NoActiveSockets(&usrsocktest_daemon_config); +} + +TEST(BasicDaemon, NoActiveSocketsDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + NoActiveSockets(&usrsocktest_daemon_config); +} + +TEST(BasicDaemon, OpenClose) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + OpenClose(&usrsocktest_daemon_config); +} + +TEST(BasicDaemon, OpenCloseDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + OpenClose(&usrsocktest_daemon_config); +} + +TEST(BasicDaemon, UnsupportedType) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + UnsupportedType(&usrsocktest_daemon_config); +} + +TEST(BasicDaemon, UnsupportedTypeDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + UnsupportedType(&usrsocktest_daemon_config); +} + +TEST(BasicDaemon, UnsupportedProto) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + UnsupportedProto(&usrsocktest_daemon_config); +} + +TEST(BasicDaemon, UnsupportedProtoDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + UnsupportedProto(&usrsocktest_daemon_config); +} + +TEST(BasicDaemon, OpenThree) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + OpenThree(&usrsocktest_daemon_config); +} + +TEST(BasicDaemon, OpenThreeDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + OpenThree(&usrsocktest_daemon_config); +} + +TEST(BasicDaemon, Dup) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + Dup(&usrsocktest_daemon_config); +} + +TEST(BasicDaemon, DupDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + Dup(&usrsocktest_daemon_config); +} + +TEST(BasicDaemon, Dup2) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + Dup2(&usrsocktest_daemon_config); +} + +TEST(BasicDaemon, Dup2Delay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + Dup2(&usrsocktest_daemon_config); +} + +TEST(BasicDaemon, Stops) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + Stops(&usrsocktest_daemon_config); +} + +TEST(BasicDaemon, StopsDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + Stops(&usrsocktest_daemon_config); +} + +TEST(BasicDaemon, StopsStarts) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + StopsStarts(&usrsocktest_daemon_config); +} + +TEST(BasicDaemon, StopsStartsDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + StopsStarts(&usrsocktest_daemon_config); +} diff --git a/tests/unity_usrsock/basic_getsockname.c b/tests/unity_usrsock/basic_getsockname.c new file mode 100644 index 000000000..72f7e07ca --- /dev/null +++ b/tests/unity_usrsock/basic_getsockname.c @@ -0,0 +1,279 @@ +/**************************************************************************** + * apps/examples/unity_usrsock/basic_getsockname.c + * Basic getsockname tests + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Roman Saveljev + * Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "defines.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static bool started; +static int sd; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: Open + * + * Description: + * Open and get socket options + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void Open(struct usrsocktest_daemon_conf_s *dconf) +{ + int ret; + socklen_t addrlen; + union { + struct sockaddr_storage storage; + struct sockaddr_in in; + } addr; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Get socket name */ + + memset(&addr, 0xff, sizeof(addr)); + addrlen = sizeof(addr.in); + ret = getsockname(sd, (FAR void *)&addr.in, &addrlen); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(sizeof(addr.in), addrlen); + TEST_ASSERT_EQUAL(AF_INET, addr.in.sin_family); + TEST_ASSERT_EQUAL(htons(12345), addr.in.sin_port); + TEST_ASSERT_EQUAL(htonl(0x7f000001), addr.in.sin_addr.s_addr); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Get socket name, short buffer */ + + memset(&addr, 0xff, sizeof(addr)); + addrlen = 1; + ret = getsockname(sd, (FAR void *)&addr.in, &addrlen); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(sizeof(addr.in), addrlen); + TEST_ASSERT_EQUAL(AF_INET, ((FAR uint8_t *)&addr.in.sin_family)[0]); + TEST_ASSERT_EQUAL(0xff, ((FAR uint8_t *)&addr.in.sin_family)[1]); + TEST_ASSERT_EQUAL(htons(0xffff), addr.in.sin_port); + TEST_ASSERT_EQUAL(htonl(0xffffffff), addr.in.sin_addr.s_addr); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Get socket name, larger buffer */ + + memset(&addr, 0xff, sizeof(addr)); + addrlen = sizeof(addr.storage); + ret = getsockname(sd, (FAR void *)&addr.in, &addrlen); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(sizeof(addr.in), addrlen); + TEST_ASSERT_EQUAL(AF_INET, addr.in.sin_family); + TEST_ASSERT_EQUAL(htons(12345), addr.in.sin_port); + TEST_ASSERT_EQUAL(htonl(0x7f000001), addr.in.sin_addr.s_addr); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Get socket name, NULL addr */ + + memset(&addr, 0xff, sizeof(addr)); + addrlen = sizeof(addr.in); + ret = getsockname(sd, NULL, &addrlen); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINVAL, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Get socket name, NULL addrlen */ + + memset(&addr, 0xff, sizeof(addr)); + addrlen = sizeof(addr.in); + ret = getsockname(sd, (FAR void *)&addr.in, NULL); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINVAL, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Get socket name, zero length buffer */ + + memset(&addr, 0xff, sizeof(addr)); + addrlen = 0; + ret = getsockname(sd, (FAR void *)&addr.in, &addrlen); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(sizeof(addr.in), addrlen); + TEST_ASSERT_EQUAL(0xffff, addr.in.sin_family); + TEST_ASSERT_EQUAL(htons(0xffff), addr.in.sin_port); + TEST_ASSERT_EQUAL(htonl(0xffffffff), addr.in.sin_addr.s_addr); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +TEST_GROUP(BasicGetSockName); + +/**************************************************************************** + * Name: BasicGetSockName test group setup + * + * Description: + * Setup function executed before each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_SETUP(BasicGetSockName) +{ + sd = -1; + started = false; +} + +/**************************************************************************** + * Name: BasicGetSockName test group teardown + * + * Description: + * Setup function executed after each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_TEAR_DOWN(BasicGetSockName) +{ + int ret; + if (sd >= 0) + { + ret = close(sd); + assert(ret >= 0); + } + if (started) + { + ret = usrsocktest_daemon_stop(); + assert(ret == OK); + } +} + +TEST(BasicGetSockName, Open) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + Open(&usrsocktest_daemon_config); +} + +TEST(BasicGetSockName, OpenDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + Open(&usrsocktest_daemon_config); +} diff --git a/tests/unity_usrsock/basic_getsockopt.c b/tests/unity_usrsock/basic_getsockopt.c new file mode 100644 index 000000000..719380afa --- /dev/null +++ b/tests/unity_usrsock/basic_getsockopt.c @@ -0,0 +1,258 @@ +/**************************************************************************** + * apps/examples/unity_usrsock/basic_getsockopt.c + * Basic getsockopt tests + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Roman Saveljev + * Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include +#include +#include +#include + +#include "defines.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static bool started; +static int sd; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: Open + * + * Description: + * Open and get socket options + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void Open(struct usrsocktest_daemon_conf_s *dconf) +{ + int ret; + int value; + int valuelarge[2]; + socklen_t valuelen; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Get supported option (SO_TYPE handled by nuttx) */ + + value = -2; + valuelen = sizeof(value); + ret = getsockopt(sd, SOL_SOCKET, SO_TYPE, &value, &valuelen); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(sizeof(value), valuelen); + TEST_ASSERT_EQUAL(SOCK_STREAM, value); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Get supported option */ + + value = -1; + valuelen = sizeof(value); + ret = getsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &value, &valuelen); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(sizeof(value), valuelen); + TEST_ASSERT_EQUAL(0, value); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Get supported option, too short buffer */ + + value = -1; + valuelen = 1; + ret = getsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &value, &valuelen); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINVAL, errno); + TEST_ASSERT_EQUAL(-1, value); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Get supported option, larger buffer */ + + valuelarge[0] = -1; + valuelarge[1] = -1; + valuelen = sizeof(valuelarge); + ret = getsockopt(sd, SOL_SOCKET, SO_REUSEADDR, valuelarge, &valuelen); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(sizeof(value), valuelen); + TEST_ASSERT_EQUAL(0, valuelarge[0]); + TEST_ASSERT_EQUAL(-1, valuelarge[1]); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Get unsupported option */ + + value = -1; + valuelen = sizeof(value); + ret = getsockopt(sd, SOL_SOCKET, SO_BROADCAST, &value, &valuelen); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(ENOPROTOOPT, errno); + TEST_ASSERT_EQUAL(-1, value); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +TEST_GROUP(BasicGetSockOpt); + +/**************************************************************************** + * Name: BasicGetSockOpt test group setup + * + * Description: + * Setup function executed before each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_SETUP(BasicGetSockOpt) +{ + sd = -1; + started = false; +} + +/**************************************************************************** + * Name: BasicGetSockOpt test group teardown + * + * Description: + * Setup function executed after each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_TEAR_DOWN(BasicGetSockOpt) +{ + int ret; + if (sd >= 0) + { + ret = close(sd); + assert(ret >= 0); + } + if (started) + { + ret = usrsocktest_daemon_stop(); + assert(ret == OK); + } +} + +TEST(BasicGetSockOpt, Open) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + Open(&usrsocktest_daemon_config); +} + +TEST(BasicGetSockOpt, OpenDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + Open(&usrsocktest_daemon_config); +} diff --git a/tests/unity_usrsock/basic_send.c b/tests/unity_usrsock/basic_send.c new file mode 100644 index 000000000..4ed8e498f --- /dev/null +++ b/tests/unity_usrsock/basic_send.c @@ -0,0 +1,345 @@ +/**************************************************************************** + * apps/examples/unity_usrsock/basic_send.c + * Basic sending tests + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Roman Saveljev + * Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "defines.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static bool started; +static int sd; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: Send + * + * Description: + * Open socket and send + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void Send(struct usrsocktest_daemon_conf_s *dconf) +{ + struct sockaddr_in addr; + ssize_t ret; + size_t datalen; + const void *data; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Send on non-connected socket */ + + data = "data"; + datalen = strlen("data"); + ret = send(sd, data, datalen, 0); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(ENOTCONN, errno); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Sendto with address */ + + data = "data"; + datalen = strlen("data"); + ret = sendto(sd, data, datalen, 0, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(ENOTCONN, errno); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Connect socket to available endpoint */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + + /* Sendto with address */ + + data = "data"; + datalen = strlen("data"); + ret = sendto(sd, data, datalen, 0, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EISCONN, errno); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_send_bytes()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); + +} + +/**************************************************************************** + * Name: ConnectSend + * + * Description: + * Send over connected socket + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void ConnectSend(struct usrsocktest_daemon_conf_s *dconf) +{ + struct sockaddr_in addr; + ssize_t ret; + size_t datalen; + const void *data; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Connect socket to available endpoint */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + + /* Send data to remote */ + + data = "data"; + datalen = strlen("data"); + ret = send(sd, data, datalen, 0); + TEST_ASSERT_EQUAL(datalen, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +TEST_GROUP(BasicSend); + +/**************************************************************************** + * Name: BasicSend test group setup + * + * Description: + * Setup function executed before each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_SETUP(BasicSend) +{ + sd = -1; + started = false; +} + +/**************************************************************************** + * Name: BasicSend test group teardown + * + * Description: + * Setup function executed after each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_TEAR_DOWN(BasicSend) +{ + int ret; + if (sd >= 0) + { + ret = close(sd); + assert(ret >= 0); + } + if (started) + { + ret = usrsocktest_daemon_stop(); + assert(ret == OK); + } +} + +TEST(BasicSend, Send) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + Send(&usrsocktest_daemon_config); +} + +TEST(BasicSend, SendDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + Send(&usrsocktest_daemon_config); +} + +TEST(BasicSend, ConnectSend) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + ConnectSend(&usrsocktest_daemon_config); +} + +TEST(BasicSend, ConnectSendDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + ConnectSend(&usrsocktest_daemon_config); +} diff --git a/tests/unity_usrsock/basic_setsockopt.c b/tests/unity_usrsock/basic_setsockopt.c new file mode 100644 index 000000000..48c0918ac --- /dev/null +++ b/tests/unity_usrsock/basic_setsockopt.c @@ -0,0 +1,226 @@ +/**************************************************************************** + * apps/examples/unity_usrsock/basic_setsockopt.c + * Basic setsockopt tests + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Roman Saveljev + * Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "defines.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static bool started; +static int sd; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: Open + * + * Description: + * Open and set socket options + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void Open(struct usrsocktest_daemon_conf_s *dconf) +{ + int ret; + int value; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Set supported option */ + + value = 1; + ret = setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value)); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Set supported option, too small buffer */ + + value = 1; + ret = setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &value, 1); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINVAL, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Set unsupported option */ + + value = 1; + ret = setsockopt(sd, SOL_SOCKET, SO_BROADCAST, &value, sizeof(value)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(ENOPROTOOPT, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +TEST_GROUP(BasicSetSockOpt); + +/**************************************************************************** + * Name: BasicSetSockOpt test group setup + * + * Description: + * Setup function executed before each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_SETUP(BasicSetSockOpt) +{ + sd = -1; + started = false; +} + +/**************************************************************************** + * Name: BasicSetSockOpt test group teardown + * + * Description: + * Setup function executed after each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_TEAR_DOWN(BasicSetSockOpt) +{ + int ret; + if (sd >= 0) + { + ret = close(sd); + assert(ret >= 0); + } + if (started) + { + ret = usrsocktest_daemon_stop(); + assert(ret == OK); + } +} + +TEST(BasicSetSockOpt, Open) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + Open(&usrsocktest_daemon_config); +} + +TEST(BasicSetSockOpt, OpenDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + Open(&usrsocktest_daemon_config); +} diff --git a/tests/unity_usrsock/block_recv.c b/tests/unity_usrsock/block_recv.c new file mode 100644 index 000000000..8b5329af5 --- /dev/null +++ b/tests/unity_usrsock/block_recv.c @@ -0,0 +1,497 @@ +/**************************************************************************** + * apps/examples/unity_usrsock/block_recv.c + * Receive from the socket in blocking mode + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Roman Saveljev + * Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "defines.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static bool started; +static int sd; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ConnectReceive + * + * Description: + * Blocking connect and receive + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void ConnectReceive(struct usrsocktest_daemon_conf_s *dconf) +{ + ssize_t ret; + size_t datalen; + void *data; + struct sockaddr_in addr; + char databuf[5]; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + dconf->endpoint_block_connect = true; + dconf->endpoint_block_send = true; + dconf->endpoint_recv_avail_from_start = false; + dconf->endpoint_recv_avail = 7; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Do connect, should succeed (after connect block released). */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100)); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Receive data from remote */ + + data = databuf; + datalen = sizeof(databuf); + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 100)); + ret = recvfrom(sd, data, datalen, 0, NULL, 0); + TEST_ASSERT_EQUAL(datalen, ret); + TEST_ASSERT_EQUAL(5, ret); + TEST_ASSERT_EQUAL_UINT8_ARRAY("abcde", data, 5); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(5, usrsocktest_daemon_get_recv_bytes()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Receive data from remote */ + + data = databuf; + datalen = sizeof(databuf); + ret = recvfrom(sd, data, datalen, 0, NULL, 0); + TEST_ASSERT_EQUAL(2, ret); + TEST_ASSERT_EQUAL_UINT8_ARRAY("ab", data, 2); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(7, usrsocktest_daemon_get_recv_bytes()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Name: NoBlockConnect + * + * Description: + * Non-blocking connect and blocking receive + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void NoBlockConnect(struct usrsocktest_daemon_conf_s *dconf) +{ + ssize_t ret; + size_t datalen; + void *data; + struct sockaddr_in addr; + char databuf[5]; + struct sockaddr_in remoteaddr; + socklen_t addrlen; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + dconf->endpoint_block_connect = true; + dconf->endpoint_block_send = true; + dconf->endpoint_recv_avail_from_start = true; + dconf->endpoint_recv_avail = 6; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Do connect, should succeed (after connect block released). */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('W', 100)); + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100)); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Receive data from remote */ + + data = databuf; + datalen = sizeof(databuf); + ret = read(sd, data, datalen); + TEST_ASSERT_EQUAL(datalen, ret); + TEST_ASSERT_EQUAL(5, ret); + TEST_ASSERT_EQUAL_UINT8_ARRAY("abcde", data, 5); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(5, usrsocktest_daemon_get_recv_bytes()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Receive data from remote */ + + data = databuf; + datalen = sizeof(databuf); + addrlen = sizeof(remoteaddr); + ret = recvfrom(sd, data, datalen, 0, (FAR struct sockaddr *)&remoteaddr, &addrlen); + TEST_ASSERT_EQUAL(1, ret); + TEST_ASSERT_EQUAL_UINT8_ARRAY("a", data, 1); + TEST_ASSERT_EQUAL(sizeof(remoteaddr), addrlen); + TEST_ASSERT_EQUAL_UINT8_ARRAY(&remoteaddr, &addr, addrlen); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(6, usrsocktest_daemon_get_recv_bytes()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Receive data from remote */ + + data = databuf; + datalen = sizeof(databuf); + addrlen = sizeof(remoteaddr); + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 100)); + ret = recvfrom(sd, data, datalen, 0, (FAR struct sockaddr *)&remoteaddr, &addrlen); + TEST_ASSERT_EQUAL(5, ret); + TEST_ASSERT_EQUAL_UINT8_ARRAY("abcde", data, 5); + TEST_ASSERT_EQUAL(sizeof(remoteaddr), addrlen); + TEST_ASSERT_EQUAL_UINT8_ARRAY(&remoteaddr, &addr, addrlen); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(11, usrsocktest_daemon_get_recv_bytes()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(11, usrsocktest_daemon_get_recv_bytes()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Name: ReceiveTimeout + * + * Description: + * Blocking connect and receive with SO_RCVTIMEO + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void ReceiveTimeout(struct usrsocktest_daemon_conf_s *dconf) +{ + ssize_t ret; + size_t datalen; + void *data; + struct sockaddr_in addr; + char databuf[5]; + struct timeval tv; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + dconf->endpoint_block_connect = true; + dconf->endpoint_block_send = true; + dconf->endpoint_recv_avail_from_start = false; + dconf->endpoint_recv_avail = 7; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Do connect, should succeed (after connect block released). */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100)); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Setup recv timeout. */ + + tv.tv_sec = 0; + tv.tv_usec = 100 * 1000; + ret = setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (FAR const void *)&tv, + sizeof(tv)); + TEST_ASSERT_EQUAL(0, ret); + + /* Receive data from remote */ + + data = databuf; + datalen = sizeof(databuf); + ret = recvfrom(sd, data, datalen, 0, NULL, 0); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EAGAIN, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_recv_bytes()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +TEST_GROUP(BlockRecv); + +/**************************************************************************** + * Name: BlockRecv test group setup + * + * Description: + * Setup function executed before each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_SETUP(BlockRecv) +{ + sd = -1; + started = false; +} + +/**************************************************************************** + * Name: BlockRecv test group teardown + * + * Description: + * Setup function executed after each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_TEAR_DOWN(BlockRecv) +{ + int ret; + if (sd >= 0) + { + ret = close(sd); + assert(ret >= 0); + } + if (started) + { + ret = usrsocktest_daemon_stop(); + assert(ret == OK); + } +} + +TEST(BlockRecv, ConnectReceive) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + ConnectReceive(&usrsocktest_daemon_config); +} + +TEST(BlockRecv, ConnectReceiveDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + ConnectReceive(&usrsocktest_daemon_config); +} + +TEST(BlockRecv, NoBlockConnect) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + NoBlockConnect(&usrsocktest_daemon_config); +} + +TEST(BlockRecv, NoBlockConnectDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + NoBlockConnect(&usrsocktest_daemon_config); +} + +TEST(BlockRecv, ReceiveTimeout) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + ReceiveTimeout(&usrsocktest_daemon_config); +} + +TEST(BlockRecv, ReceiveTimeoutDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + ReceiveTimeout(&usrsocktest_daemon_config); +} diff --git a/tests/unity_usrsock/block_send.c b/tests/unity_usrsock/block_send.c new file mode 100644 index 000000000..0aa15fb74 --- /dev/null +++ b/tests/unity_usrsock/block_send.c @@ -0,0 +1,428 @@ +/**************************************************************************** + * apps/examples/unity_usrsock/block_send.c + * Send through the socket in blocking mode + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Roman Saveljev + * Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "defines.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static bool started; +static int sd; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ConnectSend + * + * Description: + * Open socket, connect in blocking mode and send + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void ConnectSend(struct usrsocktest_daemon_conf_s *dconf) +{ + ssize_t ret; + size_t datalen; + const void *data; + struct sockaddr_in addr; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + dconf->endpoint_block_connect = true; + dconf->endpoint_block_send = true; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Do connect, should succeed (after connect block released). */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100)); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Send data to remote, */ + + data = "abcde"; + datalen = strlen("abcde"); + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('W', 100)); + ret = sendto(sd, data, datalen, 0, NULL, 0); + TEST_ASSERT_EQUAL(datalen, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); + +} + +/**************************************************************************** + * Name: NonBlockConnectSend + * + * Description: + * Open socket, connect in non-blocking mode and send + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void NonBlockConnectSend(struct usrsocktest_daemon_conf_s *dconf) +{ + ssize_t ret; + size_t datalen; + const void *data; + struct sockaddr_in addr; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + dconf->endpoint_block_connect = true; + dconf->endpoint_block_send = false; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Do connect, should succeed (after connect block released). */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('W', 100)); + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100)); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Send data to remote. */ + + data = "abcde"; + datalen = strlen("abcde"); + ret = write(sd, data, datalen); + TEST_ASSERT_EQUAL(datalen, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Name: SendTimeout + * + * Description: + * Open socket, connect in blocking mode and send with SO_SNDTIMEO + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void SendTimeout(struct usrsocktest_daemon_conf_s *dconf) +{ + ssize_t ret; + size_t datalen; + const void *data; + struct sockaddr_in addr; + struct timeval tv; + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + dconf->endpoint_block_connect = true; + dconf->endpoint_block_send = true; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Do connect, should succeed (after connect block released). */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100)); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Setup send timeout. */ + + tv.tv_sec = 0; + tv.tv_usec = 100 * 1000; + ret = setsockopt(sd, SOL_SOCKET, SO_SNDTIMEO, (FAR const void *)&tv, + sizeof(tv)); + TEST_ASSERT_EQUAL(0, ret); + + /* Try send data to remote. */ + + data = "abcde"; + datalen = strlen("abcde"); + ret = sendto(sd, data, datalen, 0, NULL, 0); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EAGAIN, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +TEST_GROUP(BlockSend); + +/**************************************************************************** + * Name: BlockSend test group setup + * + * Description: + * Setup function executed before each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_SETUP(BlockSend) +{ + sd = -1; + started = false; +} + +/**************************************************************************** + * Name: BlockSend test group teardown + * + * Description: + * Setup function executed after each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_TEAR_DOWN(BlockSend) +{ + int ret; + if (sd >= 0) + { + ret = close(sd); + assert(ret >= 0); + } + if (started) + { + ret = usrsocktest_daemon_stop(); + assert(ret == OK); + } +} + +TEST(BlockSend, ConnectSend) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + ConnectSend(&usrsocktest_daemon_config); +} + +TEST(BlockSend, ConnectSendDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + ConnectSend(&usrsocktest_daemon_config); +} + +TEST(BlockSend, NonBlockConnectSend) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + NonBlockConnectSend(&usrsocktest_daemon_config); +} + +TEST(BlockSend, NonBlockConnectSendDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + NonBlockConnectSend(&usrsocktest_daemon_config); +} + +TEST(BlockSend, SendTimeout) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + SendTimeout(&usrsocktest_daemon_config); +} + +TEST(BlockSend, SendTimeoutDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + SendTimeout(&usrsocktest_daemon_config); +} diff --git a/tests/unity_usrsock/chardev.c b/tests/unity_usrsock/chardev.c new file mode 100644 index 000000000..bf9366032 --- /dev/null +++ b/tests/unity_usrsock/chardev.c @@ -0,0 +1,222 @@ +/**************************************************************************** + * apps/examples/unity_usrsock/chardev.c + * Character device node tests + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Roman Saveljev + * Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include + +#include "defines.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static int us_fd; +static int us_fd_two; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +TEST_GROUP(CharDev); + +/**************************************************************************** + * Name: CharDev test group setup + * + * Description: + * Setup function executed before each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_SETUP(CharDev) +{ + us_fd = -1; + us_fd_two = -1; +} + +/**************************************************************************** + * Name: CharDev test group teardown + * + * Description: + * Setup function executed after each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_TEAR_DOWN(CharDev) +{ + int ret; + + if (us_fd >= 0) + { + ret = close(us_fd); + assert(ret >= 0); + } + if (us_fd_two >= 0) + { + ret = close(us_fd_two); + assert(ret >= 0); + } +} + +/**************************************************************************** + * Name: OpenRw + * + * Description: + * Simple test for opening and closing usrsock node + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(CharDev, OpenRw) +{ + int ret; + + us_fd = open(USRSOCK_NODE, O_RDWR); + TEST_ASSERT_TRUE(us_fd >= 0); + + ret = close(us_fd); + TEST_ASSERT_TRUE(ret >= 0); + us_fd = -1; +} + +/**************************************************************************** + * Name: ReopenRw + * + * Description: + * Repeated simple test for opening and closing usrsock node, reopen should + * work + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(CharDev, ReopenRw) +{ + int ret; + + us_fd = open(USRSOCK_NODE, O_RDWR); + TEST_ASSERT_TRUE(us_fd >= 0); + + ret = close(us_fd); + TEST_ASSERT_TRUE(ret >= 0); + us_fd = -1; + + us_fd = open(USRSOCK_NODE, O_RDWR); + TEST_ASSERT_TRUE(us_fd >= 0); + + ret = close(us_fd); + TEST_ASSERT_TRUE(ret >= 0); + us_fd = -1; +} + +/**************************************************************************** + * Name: NoMultipleOpen + * + * Description: + * No permission for multiple access, + * first user should be only user. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(CharDev, NoMultipleOpen) +{ + us_fd = open(USRSOCK_NODE, O_RDWR); + TEST_ASSERT_TRUE(us_fd >= 0); + + us_fd_two = open(USRSOCK_NODE, O_RDWR); + TEST_ASSERT_FALSE(us_fd_two >= 0); + TEST_ASSERT_EQUAL(EPERM, errno); +} diff --git a/tests/unity_usrsock/defines.h b/tests/unity_usrsock/defines.h new file mode 100644 index 000000000..153efc4f9 --- /dev/null +++ b/tests/unity_usrsock/defines.h @@ -0,0 +1,124 @@ +/**************************************************************************** + * apps/examples/unity_usrsock/defines.h + * Common defines for all testcases + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Author: Roman Saveljev + * Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ +#ifndef __EXAMPLES_UNITY_USRSOCK_DEFINES_H +#define __EXAMPLES_UNITY_USRSOCK_DEFINES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +#define USRSOCK_NODE "/dev/usrsock" + +#define USRSOCKTEST_DAEMON_CONF_DEFAULTS \ + { \ + .max_sockets = UINT_MAX, \ + .supported_domain = AF_INET, \ + .supported_type = SOCK_STREAM, \ + .supported_protocol = 0, \ + .delay_all_responses = false, \ + .endpoint_addr = "127.0.0.1", \ + .endpoint_port = 255, \ + .endpoint_block_connect = false, \ + .endpoint_block_send = false, \ + .endpoint_recv_avail_from_start = true, \ + .endpoint_recv_avail = 4, \ + } + +/**************************************************************************** + * Public Types + ****************************************************************************/ +struct usrsocktest_daemon_conf_s +{ + unsigned int max_sockets; + int8_t supported_domain:8; + int8_t supported_type:8; + int8_t supported_protocol:8; + bool delay_all_responses:1; + bool endpoint_block_connect:1; + bool endpoint_block_send:1; + bool endpoint_recv_avail_from_start:1; + uint8_t endpoint_recv_avail:8; + const char *endpoint_addr; + uint16_t endpoint_port; +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ +extern int usrsocktest_endp_malloc_cnt; +extern int usrsocktest_dcmd_malloc_cnt; +extern const struct usrsocktest_daemon_conf_s usrsocktest_daemon_defconf; +extern struct usrsocktest_daemon_conf_s usrsocktest_daemon_config; + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ +int usrsocktest_daemon_start(const struct usrsocktest_daemon_conf_s *conf); + +int usrsocktest_daemon_stop(void); + +int usrsocktest_daemon_get_num_active_sockets(void); + +int usrsocktest_daemon_get_num_connected_sockets(void); + +int usrsocktest_daemon_get_num_waiting_connect_sockets(void); + +int usrsocktest_daemon_get_num_recv_empty_sockets(void); + +ssize_t usrsocktest_daemon_get_send_bytes(void); + +ssize_t usrsocktest_daemon_get_recv_bytes(void); + +int usrsocktest_daemon_get_num_unreachable_sockets(void); + +int usrsocktest_daemon_get_num_remote_disconnected_sockets(void); + +bool usrsocktest_daemon_establish_waiting_connections(void); + +bool usrsocktest_send_delayed_command(char cmd, unsigned int delay_msec); + +int usrsocktest_daemon_pause_usrsock_handling(bool pause); + +#endif /* __EXAMPLES_UNITY_USRSOCK_DEFINES_H */ diff --git a/tests/unity_usrsock/multi_thread.c b/tests/unity_usrsock/multi_thread.c new file mode 100644 index 000000000..17206d2ef --- /dev/null +++ b/tests/unity_usrsock/multi_thread.c @@ -0,0 +1,256 @@ +/**************************************************************************** + * apps/examples/unity_usrsock/multi_thread.c + * Multi-threaded access to sockets + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Roman Saveljev + * Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include +#include +#include + +#include "defines.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static pthread_t tids[4]; +static int sds[4]; +static bool started; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +static void usrsock_socket_multitask_do_work(int *sd) +{ + struct sockaddr_in addr; + int ret; + int i; + + for (i = 0; i < 10; i++) + { + /* Simple test for opening socket with usrsock daemon running. */ + + *sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(*sd >= 0); + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(*sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(0, ret); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(*sd) >= 0); + *sd = -1; + } +} + +static FAR void *usrsock_socket_multitask_thread(FAR void *param) +{ + usrsock_socket_multitask_do_work((int*)param); + return NULL; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +TEST_GROUP(MultiThread); + +/**************************************************************************** + * Name: MultiThread test group setup + * + * Description: + * Setup function executed before each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_SETUP(MultiThread) +{ + int i; + for (i = 0; i < ARRAY_SIZE(sds); i++) + { + sds[i] = -1; + } + for (i = 0; i < ARRAY_SIZE(tids); i++) + { + tids[i] = -1; + } + started = false; +} + +/**************************************************************************** + * Name: MultiThread test group teardown + * + * Description: + * Setup function executed after each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_TEAR_DOWN(MultiThread) +{ + int ret; + int i; + + for (i = 0; i < ARRAY_SIZE(tids); i++) + { + if (tids[i] != -1) + { + ret = pthread_cancel(tids[i]); + assert(ret == OK); + ret = pthread_join(tids[i], NULL); + assert(ret == OK); + } + } + for (i = 0; i < ARRAY_SIZE(sds); i++) + { + if (sds[i] != -1) + { + ret = close(sds[i]); + assert(ret >= 0); + } + } + if (started) + { + ret = usrsocktest_daemon_stop(); + assert(ret == OK); + } +} + +/**************************************************************************** + * Name: OpenClose + * + * Description: + * Open and close socket with multiple threads + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(MultiThread, OpenClose) +{ + int ret; + int i; + + /* Start test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + usrsocktest_daemon_config.endpoint_block_send = false; + usrsocktest_daemon_config.endpoint_block_connect = false; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config)); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Launch worker threads. */ + + for (i = 0; i < ARRAY_SIZE(tids); i++) + { + ret = pthread_create(&tids[i], NULL, usrsock_socket_multitask_thread, + sds + i); + TEST_ASSERT_EQUAL(OK, ret); + } + + /* Wait threads to complete work. */ + + while (--i > -1) + { + pthread_addr_t tparam; + + ret = pthread_join(tids[i], &tparam); + TEST_ASSERT_EQUAL(OK, ret); + tids[i] = -1; + /* This flag is set whenever a test fails, otherwise it is not touched + * No need for synchronization. Here we bail from main test thread on + * first failure in any thread. + */ + TEST_ASSERT_FALSE(Unity.CurrentTestFailed); + } + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + diff --git a/tests/unity_usrsock/noblock_connect.c b/tests/unity_usrsock/noblock_connect.c new file mode 100644 index 000000000..51cf35115 --- /dev/null +++ b/tests/unity_usrsock/noblock_connect.c @@ -0,0 +1,806 @@ +/**************************************************************************** + * apps/examples/unity_usrsock/noblock_connect.c + * Socket connect tests in non-blocking mode + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Roman Saveljev + * Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "defines.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static bool started; +static int sd, sd2; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +TEST_GROUP(NoBlockConnect); + +TEST_SETUP(NoBlockConnect) +{ + sd = -1; + sd2 = -1; + started = false; +} + +TEST_TEAR_DOWN(NoBlockConnect) +{ + int ret; + + if (sd >= 0) + { + ret = close(sd); + assert(ret == 0); + } + if (sd2 >= 0) + { + ret = close(sd2); + assert(ret == 0); + } + if (started) + { + ret = usrsocktest_daemon_stop(); + assert(ret == OK); + } +} + +TEST(NoBlockConnect, InstantConnect) +{ + int flags; + int ret; + struct sockaddr_in addr; + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Make socket non-blocking */ + + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); + ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); + TEST_ASSERT_EQUAL(0, ret); + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); + + /* Do connect, should succeed instantly. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +TEST(NoBlockConnect, DelayedConnect) +{ + int flags, ret, count; + struct sockaddr_in addr; + + /* Start test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.endpoint_block_connect = true; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + usrsocktest_daemon_config.delay_all_responses = true; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Make socket non-blocking */ + + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); + ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); + TEST_ASSERT_EQUAL(0, ret); + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); + + /* Launch connect attempt, daemon delays actual connection until triggered. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINPROGRESS, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Another connect attempt results EALREADY. */ + + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EALREADY, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Release delayed connect. */ + + TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections()); + for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++) + { + TEST_ASSERT_TRUE(count <= 5); + usleep(10 * 1000); + } + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Another connect attempt results EISCONN. */ + + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EISCONN, errno); + + /* Close socket. */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +TEST(NoBlockConnect, CloseNotConnected) +{ + int flags, ret; + struct sockaddr_in addr; + + /* Start test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.endpoint_block_connect = true; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + usrsocktest_daemon_config.delay_all_responses = true; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Make socket non-blocking */ + + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); + ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); + TEST_ASSERT_EQUAL(0, ret); + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); + + /* Launch connect attempt, daemon delays actual connection until triggered. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINPROGRESS, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Close socket. */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +TEST(NoBlockConnect, EarlyDrop) +{ + int flags, ret; + struct sockaddr_in addr; + + /* Start test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.endpoint_block_connect = true; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + usrsocktest_daemon_config.delay_all_responses = false; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0) + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Make socket non-blocking */ + + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); + ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); + TEST_ASSERT_EQUAL(0, ret); + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); + + /* Launch connect attempt, daemon delays actual connection until triggered. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINPROGRESS, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); + + /* Close socket. */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets()); +} + +TEST(NoBlockConnect, Multiple) +{ + int flags, ret, count; + struct sockaddr_in addr; + + /* Start test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.endpoint_block_connect = true; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + usrsocktest_daemon_config.delay_all_responses = false; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open sockets */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + sd2 = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd2 >= 0); + TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Make socket non-blocking */ + + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); + ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); + TEST_ASSERT_EQUAL(0, ret); + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); + + flags = fcntl(sd2, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); + ret = fcntl(sd2, F_SETFL, flags | O_NONBLOCK); + TEST_ASSERT_EQUAL(0, ret); + flags = fcntl(sd2, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); + + /* Launch connect attempts, daemon delays actual connection until triggered. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINPROGRESS, errno); + TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Release delayed connections. */ + + TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections()); + for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++) + { + TEST_ASSERT_TRUE(count <= 5); + usleep(10 * 1000); + } + TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EISCONN, errno); + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINPROGRESS, errno); + TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Release delayed connections. */ + + TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections()); + for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++) + { + TEST_ASSERT_TRUE(count <= 5); + usleep(10 * 1000); + } + TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Close sockets. */ + + TEST_ASSERT_TRUE(close(sd2) >= 0); + sd2 = -1; + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Open sockets */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + sd2 = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd2 >= 0); + TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Make socket non-blocking */ + + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); + ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); + TEST_ASSERT_EQUAL(0, ret); + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); + + flags = fcntl(sd2, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); + ret = fcntl(sd2, F_SETFL, flags | O_NONBLOCK); + TEST_ASSERT_EQUAL(0, ret); + flags = fcntl(sd2, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); + + /* Launch connect attempts, daemon delays actual connection until triggered. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINPROGRESS, errno); + TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINPROGRESS, errno); + TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Release delayed connections. */ + + TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections()); + for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++) + { + TEST_ASSERT_TRUE(count <= 5); + usleep(10 * 1000); + } + TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Close sockets. */ + + TEST_ASSERT_TRUE(close(sd2) >= 0); + sd2 = -1; + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Open sockets */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + sd2 = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd2 >= 0); + TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Make socket non-blocking */ + + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); + ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); + TEST_ASSERT_EQUAL(0, ret); + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); + + flags = fcntl(sd2, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); + ret = fcntl(sd2, F_SETFL, flags | O_NONBLOCK); + TEST_ASSERT_EQUAL(0, ret); + flags = fcntl(sd2, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); + + /* Launch connect attempt, daemon delays actual connection until triggered. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINPROGRESS, errno); + TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Release delayed connections. */ + + TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections()); + for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++) + { + TEST_ASSERT_TRUE(count <= 5); + usleep(10 * 1000); + } + TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Launch another connect attempt, daemon delays actual connection until triggered. */ + + ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINPROGRESS, errno); + TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Close sockets. */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_TRUE(close(sd2) >= 0); + sd2 = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +TEST(NoBlockConnect, Dup2) +{ + int flags, ret, count; + struct sockaddr_in addr; + + /* Start test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.endpoint_block_connect = true; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + usrsocktest_daemon_config.delay_all_responses = true; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Duplicate socket */ + + sd2 = dup(sd); + TEST_ASSERT_TRUE(sd2 >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + + /* Make socket non-blocking */ + + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); + ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); + TEST_ASSERT_EQUAL(0, ret); + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); + + /* Launch connect attempt, daemon delays actual connection until triggered. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINPROGRESS, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Another connect attempt results EALREADY. */ + + ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EALREADY, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Release delayed connect. */ + + TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections()); + for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++) + { + TEST_ASSERT_TRUE(count <= 5); + usleep(10 * 1000); + } + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Another connect attempt results EISCONN. */ + + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EISCONN, errno); + + /* Close sockets. */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + TEST_ASSERT_TRUE(close(sd2) >= 0); + sd2 = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} diff --git a/tests/unity_usrsock/noblock_recv.c b/tests/unity_usrsock/noblock_recv.c new file mode 100644 index 000000000..4f191ac49 --- /dev/null +++ b/tests/unity_usrsock/noblock_recv.c @@ -0,0 +1,503 @@ +/**************************************************************************** + * apps/examples/unity_usrsock/noblock_recv.c + * Receive from the socket in non-blocking mode + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Roman Saveljev + * Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "defines.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static bool started; +static int sd; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: Receive + * + * Description: + * Non-blocking & instant connect+recv + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void Receive(struct usrsocktest_daemon_conf_s *dconf) +{ + int flags; + int count; + ssize_t ret; + size_t datalen; + void *data; + struct sockaddr_in addr; + char databuf[4]; + struct sockaddr_in remoteaddr; + socklen_t addrlen; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + dconf->endpoint_recv_avail_from_start = true; + dconf->endpoint_recv_avail = 7; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Make socket non-blocking */ + + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); + ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); + TEST_ASSERT_EQUAL(0, ret); + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); + + /* Do connect, should succeed instantly. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + if (!dconf->delay_all_responses) + { + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); + } + else + { + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINPROGRESS, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + for (count = 0; usrsocktest_daemon_get_num_connected_sockets() != 1; count++) + { + TEST_ASSERT_TRUE(count <= 3); + usleep(25 * 1000); + } + + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EISCONN, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); + } + + /* Receive data from remote, daemon returns 4 bytes. */ + + data = databuf; + datalen = sizeof(databuf); + ret = recvfrom(sd, data, datalen, 0, NULL, NULL); + TEST_ASSERT_EQUAL(datalen, ret); + TEST_ASSERT_EQUAL(4, datalen); + TEST_ASSERT_EQUAL_UINT8_ARRAY("abcd", data, 4); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(4, usrsocktest_daemon_get_recv_bytes()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Receive data from remote with address, daemon returns 3 bytes. */ + + addrlen = sizeof(remoteaddr); + ret = recvfrom(sd, data, datalen, 0, (FAR struct sockaddr *)&remoteaddr, &addrlen); + TEST_ASSERT_EQUAL(3, ret); + TEST_ASSERT_EQUAL_UINT8_ARRAY("abc", data, 3); + TEST_ASSERT_EQUAL(addrlen, sizeof(remoteaddr)); + TEST_ASSERT_EQUAL_UINT8_ARRAY(&remoteaddr, &addr, addrlen); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(datalen + ret, usrsocktest_daemon_get_recv_bytes()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Receive data from remote, daemon has 0 bytes buffered => -EAGAIN */ + + data = databuf; + datalen = sizeof(databuf); + ret = recvfrom(sd, data, datalen, 0, NULL, NULL); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EAGAIN, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(7, usrsocktest_daemon_get_recv_bytes()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Receive data from remote, daemon has 0 bytes buffered => -EAGAIN */ + + data = databuf; + datalen = sizeof(databuf); + ret = read(sd, data, datalen); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EAGAIN, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(7, usrsocktest_daemon_get_recv_bytes()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Reset recv buffer for open sockets */ + + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 0)); + for (count = 0; usrsocktest_daemon_get_num_recv_empty_sockets() > 0; count++) + { + TEST_ASSERT_TRUE(count <= 5); + usleep(5 * 1000); + } + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Receive data from remote, daemon returns 4 bytes. */ + + data = databuf; + datalen = sizeof(databuf); + ret = recvfrom(sd, data, datalen, 0, NULL, NULL); + TEST_ASSERT_EQUAL(datalen, ret); + TEST_ASSERT_EQUAL(4, datalen); + TEST_ASSERT_EQUAL_UINT8_ARRAY("abcd", data, 4); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(7 + 4, usrsocktest_daemon_get_recv_bytes()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(7 + 4, usrsocktest_daemon_get_recv_bytes()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Name: DelayedConnect + * + * Description: + * Non-blocking & delayed connect + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void DelayedConnect(struct usrsocktest_daemon_conf_s *dconf) +{ + int flags; + int count; + ssize_t ret; + size_t datalen; + void *data; + struct sockaddr_in addr; + char databuf[4]; + struct sockaddr_in remoteaddr; + socklen_t addrlen; + + /* Start test daemon. */ + + dconf->endpoint_block_connect = true; + dconf->endpoint_recv_avail_from_start = false; + dconf->endpoint_recv_avail = 4; + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Make socket non-blocking */ + + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); + ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); + TEST_ASSERT_EQUAL(0, ret); + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); + + /* Launch connect attempt, daemon delays actual connection until triggered. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINPROGRESS, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Try receive data, not connected yet. */ + + data = databuf; + datalen = sizeof(databuf); + ret = read(sd, data, datalen); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EAGAIN, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); + + /* Release delayed connect. */ + + TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections()); + for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++) + { + TEST_ASSERT_TRUE(count <= 5); + usleep(10 * 1000); + } + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Try receive data, not received data yet. */ + + data = databuf; + datalen = sizeof(databuf); + addrlen = sizeof(remoteaddr); + ret = recvfrom(sd, data, datalen, 0, (FAR struct sockaddr *)&remoteaddr, &addrlen); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EAGAIN, errno); + TEST_ASSERT_EQUAL(0, addrlen); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Reset recv buffer for open sockets */ + + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 0)); + for (count = 0; usrsocktest_daemon_get_num_recv_empty_sockets() > 0; count++) + { + TEST_ASSERT_TRUE(count <= 5); + usleep(5 * 1000); + } + + /* Receive data from remote, daemon returns 4 bytes. */ + + data = databuf; + datalen = sizeof(databuf); + ret = recvfrom(sd, data, datalen, 0, NULL, NULL); + TEST_ASSERT_EQUAL(datalen, ret); + TEST_ASSERT_EQUAL(4, datalen); + TEST_ASSERT_EQUAL_UINT8_ARRAY("abcd", data, 4); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(4, usrsocktest_daemon_get_recv_bytes()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Close socket. */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_recv_empty_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +TEST_GROUP(NoBlockRecv); + +/**************************************************************************** + * Name: NoBlockRecv test group setup + * + * Description: + * Setup function executed before each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_SETUP(NoBlockRecv) +{ + sd = -1; + started = false; +} + +/**************************************************************************** + * Name: NoBlockRecv test group teardown + * + * Description: + * Setup function executed after each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_TEAR_DOWN(NoBlockRecv) +{ + int ret; + if (sd >= 0) + { + ret = close(sd); + assert(ret >= 0); + } + if (started) + { + ret = usrsocktest_daemon_stop(); + assert(ret == OK); + } +} + +TEST(NoBlockRecv, Receive) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + Receive(&usrsocktest_daemon_config); +} + +TEST(NoBlockRecv, ReceiveDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + Receive(&usrsocktest_daemon_config); +} + +TEST(NoBlockRecv, DelayedConnect) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + DelayedConnect(&usrsocktest_daemon_config); +} + +TEST(NoBlockRecv, DelayedConnectDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + DelayedConnect(&usrsocktest_daemon_config); +} diff --git a/tests/unity_usrsock/noblock_send.c b/tests/unity_usrsock/noblock_send.c new file mode 100644 index 000000000..47055f76c --- /dev/null +++ b/tests/unity_usrsock/noblock_send.c @@ -0,0 +1,400 @@ +/**************************************************************************** + * apps/examples/unity_usrsock/noblock_send.c + * Send through the socket in non-blocking mode + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Roman Saveljev + * Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "defines.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static bool started; +static int sd; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: Send + * + * Description: + * Open socket, connect instantly and send + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void Send(struct usrsocktest_daemon_conf_s *dconf) +{ + int flags; + int count; + ssize_t ret; + size_t datalen; + const void *data; + struct sockaddr_in addr; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Make socket non-blocking */ + + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); + ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); + TEST_ASSERT_EQUAL(0, ret); + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); + + /* Do connect, should succeed instantly. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + if (!dconf->delay_all_responses) + { + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + } + else + { + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINPROGRESS, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + for (count = 0; usrsocktest_daemon_get_num_connected_sockets() != 1; count++) + { + TEST_ASSERT_TRUE(count <= 3); + usleep(25 * 1000); + } + + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EISCONN, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + } + + /* Send data to remote */ + + data = "abcde"; + datalen = strlen("abcde"); + ret = sendto(sd, data, datalen, 0, NULL, 0); + TEST_ASSERT_EQUAL(datalen, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); +} + +/**************************************************************************** + * Name: ConnectSend + * + * Description: + * Open socket, connect is delayed and send + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void ConnectSend(struct usrsocktest_daemon_conf_s *dconf) +{ + int flags; + int count; + ssize_t ret; + size_t datalen; + const void *data; + struct sockaddr_in addr; + + /* Start test daemon. */ + + dconf->endpoint_block_connect = true; + dconf->endpoint_block_send = true; + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Make socket non-blocking */ + + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); + ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); + TEST_ASSERT_EQUAL(0, ret); + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); + + /* Launch connect attempt, daemon delays actual connection until triggered. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINPROGRESS, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Send data to remote, not connected yet. */ + + data = "abcde"; + datalen = strlen("abcde"); + ret = write(sd, data, datalen); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EAGAIN, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); + + /* Release delayed connect. */ + + TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections()); + for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++) + { + TEST_ASSERT_TRUE(count <= 5); + usleep(10 * 1000); + } + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Send data to remote */ + + data = "abcde"; + datalen = strlen("abcde"); + ret = write(sd, data, datalen); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EAGAIN, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); + + /* Close socket. */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +TEST_GROUP(NoBlockSend); + +/**************************************************************************** + * Name: NoBlockSend test group setup + * + * Description: + * Setup function executed before each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_SETUP(NoBlockSend) +{ + sd = -1; + started = false; +} + +/**************************************************************************** + * Name: NoBlockSend test group teardown + * + * Description: + * Setup function executed after each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_TEAR_DOWN(NoBlockSend) +{ + int ret; + if (sd >= 0) + { + ret = close(sd); + assert(ret >= 0); + } + if (started) + { + ret = usrsocktest_daemon_stop(); + assert(ret == OK); + } +} + +TEST(NoBlockSend, Send) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + Send(&usrsocktest_daemon_config); +} + +TEST(NoBlockSend, SendDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + Send(&usrsocktest_daemon_config); +} + +TEST(NoBlockSend, ConnectSend) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + ConnectSend(&usrsocktest_daemon_config); +} + +TEST(NoBlockSend, ConnectSendDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + ConnectSend(&usrsocktest_daemon_config); +} diff --git a/tests/unity_usrsock/nodaemon.c b/tests/unity_usrsock/nodaemon.c new file mode 100644 index 000000000..eff1cb744 --- /dev/null +++ b/tests/unity_usrsock/nodaemon.c @@ -0,0 +1,148 @@ +/**************************************************************************** + * apps/examples/unity_usrsock/nodaemon.c + * Tests without user socket daemon + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Roman Saveljev + * Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include + +#include "defines.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static int sd; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +TEST_GROUP(NoDaemon); + +/**************************************************************************** + * Name: NoDaemon test group setup + * + * Description: + * Setup function executed before each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_SETUP(NoDaemon) +{ + sd = -1; +} + +/**************************************************************************** + * Name: NoDaemon test group teardown + * + * Description: + * Setup function executed after each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_TEAR_DOWN(NoDaemon) +{ + int ret; + + if (sd >= 0) + { + ret = close(sd); + assert(ret >= 0); + } +} + +/**************************************************************************** + * Name: NoSocket + * + * Description: + * Simple test for opening socket without usrsock daemon running + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(NoDaemon, NoSocket) +{ + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_EQUAL(-1, sd); + TEST_ASSERT_TRUE(errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT || errno == ENETDOWN); +} + diff --git a/tests/unity_usrsock/poll.c b/tests/unity_usrsock/poll.c new file mode 100644 index 000000000..0a1c46bf9 --- /dev/null +++ b/tests/unity_usrsock/poll.c @@ -0,0 +1,632 @@ +/**************************************************************************** + * apps/examples/unity_usrsock/poll.c + * User socket polling tests + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Roman Saveljev + * Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "defines.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static bool started; +static int sd; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ConnectReceive + * + * Description: + * Non-blocking connect and receive + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void ConnectReceive(struct usrsocktest_daemon_conf_s *dconf) +{ + int flags; + int count; + ssize_t ret; + size_t datalen; + void *data; + struct sockaddr_in addr; + char databuf[4]; + struct pollfd pfd; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + dconf->endpoint_recv_avail_from_start = false; + dconf->endpoint_recv_avail = 3; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Make socket non-blocking */ + + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); + ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); + TEST_ASSERT_EQUAL(0, ret); + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); + + /* Poll for input (instant timeout). */ + + memset(&pfd, 0, sizeof(pfd)); + pfd.fd = sd; + pfd.events = POLLIN; + ret = poll(&pfd, 1, 0); + TEST_ASSERT_EQUAL(1, ret); + TEST_ASSERT_EQUAL(0, pfd.revents & POLLERR); + TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP); + TEST_ASSERT_EQUAL(POLLIN, pfd.revents & POLLIN); + TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT); + + /* Do connect, should succeed instantly. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + if (!dconf->delay_all_responses) + { + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + } + else + { + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINPROGRESS, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + for (count = 0; usrsocktest_daemon_get_num_connected_sockets() != 1; count++) + { + TEST_ASSERT_TRUE(count <= 3); + usleep(25 * 1000); + } + + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EISCONN, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + } + + /* Poll for input (instant timeout). */ + + memset(&pfd, 0, sizeof(pfd)); + pfd.fd = sd; + pfd.events = POLLIN; + ret = poll(&pfd, 1, 0); + TEST_ASSERT_EQUAL(0, ret); + + /* Poll for input (with timeout). */ + + memset(&pfd, 0, sizeof(pfd)); + pfd.fd = sd; + pfd.events = POLLIN; + ret = poll(&pfd, 1, 10); + TEST_ASSERT_EQUAL(0, ret); + + /* Poll for input (no timeout). */ + + memset(&pfd, 0, sizeof(pfd)); + pfd.fd = sd; + pfd.events = POLLIN; + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 100)); + ret = poll(&pfd, 1, -1); + TEST_ASSERT_EQUAL(1, ret); + TEST_ASSERT_EQUAL(POLLIN, pfd.revents); + + /* Receive data from remote, daemon returns 3 bytes. */ + + data = databuf; + datalen = sizeof(databuf); + ret = recvfrom(sd, data, datalen, 0, NULL, NULL); + TEST_ASSERT_EQUAL(3, ret); + TEST_ASSERT_EQUAL_UINT8_ARRAY("abc", data, 3); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(3, usrsocktest_daemon_get_recv_bytes()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Poll for input (instant timeout). */ + + memset(&pfd, 0, sizeof(pfd)); + pfd.fd = sd; + pfd.events = POLLIN; + ret = poll(&pfd, 1, 0); + TEST_ASSERT_EQUAL(0, ret); + + /* Make more data avail */ + + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 0)); + for (count = 0; usrsocktest_daemon_get_num_recv_empty_sockets() > 0; count++) + { + TEST_ASSERT_TRUE(count <= 3); + usleep(5 * 1000); + } + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Poll for input (no timeout). */ + + memset(&pfd, 0, sizeof(pfd)); + pfd.fd = sd; + pfd.events = POLLIN; + ret = poll(&pfd, 1, -1); + TEST_ASSERT_EQUAL(1, ret); + TEST_ASSERT_EQUAL(POLLIN, pfd.revents); + + /* Receive data from remote, daemon returns 3 bytes. */ + + data = databuf; + datalen = sizeof(databuf); + ret = recvfrom(sd, data, datalen, 0, NULL, NULL); + TEST_ASSERT_EQUAL(3, ret); + TEST_ASSERT_EQUAL_UINT8_ARRAY("abc", data, 3); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(6, usrsocktest_daemon_get_recv_bytes()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(6, usrsocktest_daemon_get_recv_bytes()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Name: ConnectSend + * + * Description: + * Non-blocking connect and receive + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void ConnectSend(struct usrsocktest_daemon_conf_s *dconf) +{ + int flags; + ssize_t ret; + size_t datalen; + void *data; + struct sockaddr_in addr; + struct pollfd pfd; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + dconf->endpoint_recv_avail_from_start = true; + dconf->endpoint_recv_avail = 3; + dconf->endpoint_block_send = false; + dconf->endpoint_block_connect = true; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Make socket non-blocking */ + + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); + ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); + TEST_ASSERT_EQUAL(0, ret); + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); + + /* Poll for input (instant timeout). */ + + memset(&pfd, 0, sizeof(pfd)); + pfd.fd = sd; + pfd.events = POLLIN; + ret = poll(&pfd, 1, 0); + TEST_ASSERT_EQUAL(1, ret); + TEST_ASSERT_EQUAL(0, pfd.revents & POLLERR); + TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP); + TEST_ASSERT_EQUAL(POLLIN, pfd.revents & POLLIN); + TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT); + + /* Start non-blocking connect. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINPROGRESS, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Poll for input (no timeout). As send is ready after established connection, + * poll will exit with POLLOUT. */ + + memset(&pfd, 0, sizeof(pfd)); + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100)); + pfd.fd = sd; + pfd.events = POLLOUT; + ret = poll(&pfd, 1, -1); + TEST_ASSERT_EQUAL(1, ret); + TEST_ASSERT_EQUAL(POLLOUT, pfd.revents); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); + + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EISCONN, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Send data to remote. */ + + data = "abcdeFG"; + datalen = strlen(data); + ret = write(sd, data, datalen); + TEST_ASSERT_EQUAL(datalen, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Name: DaemonAbort + * + * Description: + * Poll with daemon abort + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void DaemonAbort(struct usrsocktest_daemon_conf_s *dconf) +{ + int flags; + ssize_t ret; + struct sockaddr_in addr; + struct pollfd pfd; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + dconf->endpoint_recv_avail_from_start = false; + dconf->endpoint_recv_avail = 3; + dconf->endpoint_block_send = false; + dconf->endpoint_block_connect = true; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Make socket non-blocking */ + + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); + ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); + TEST_ASSERT_EQUAL(0, ret); + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); + + /* Poll for input (instant timeout). */ + + memset(&pfd, 0, sizeof(pfd)); + pfd.fd = sd; + pfd.events = POLLIN; + ret = poll(&pfd, 1, 0); + TEST_ASSERT_EQUAL(1, ret); + TEST_ASSERT_EQUAL(0, pfd.revents & POLLERR); + TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP); + TEST_ASSERT_EQUAL(POLLIN, pfd.revents & POLLIN); + TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT); + + /* Start non-blocking connect. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINPROGRESS, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Poll for input (no timeout). Stop daemon forcefully. */ + + memset(&pfd, 0, sizeof(pfd)); + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('S', 100)); + pfd.fd = sd; + pfd.events = POLLOUT; + ret = poll(&pfd, 1, -1); + TEST_ASSERT_EQUAL(1, ret); + TEST_ASSERT_EQUAL(POLLERR, pfd.revents & POLLERR); + TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); + + /* Poll for input (no timeout). */ + + memset(&pfd, 0, sizeof(pfd)); + pfd.fd = sd; + pfd.events = POLLOUT; + ret = poll(&pfd, 1, -1); + TEST_ASSERT_EQUAL(1, ret); + TEST_ASSERT_EQUAL(POLLERR, pfd.revents & POLLERR); + TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP); + TEST_ASSERT_EQUAL(0, pfd.revents & POLLIN); + TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_send_bytes()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_recv_empty_sockets()); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +TEST_GROUP(Poll); + +/**************************************************************************** + * Name: Poll test group setup + * + * Description: + * Setup function executed before each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_SETUP(Poll) +{ + sd = -1; + started = false; +} + +/**************************************************************************** + * Name: Poll test group teardown + * + * Description: + * Setup function executed after each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_TEAR_DOWN(Poll) +{ + int ret; + if (sd >= 0) + { + ret = close(sd); + assert(ret >= 0); + } + if (started) + { + ret = usrsocktest_daemon_stop(); + assert(ret == OK); + } +} + +TEST(Poll, ConnectReceive) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + ConnectReceive(&usrsocktest_daemon_config); +} + +TEST(Poll, ConnectReceiveDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + ConnectReceive(&usrsocktest_daemon_config); +} + +TEST(Poll, ConnectSend) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + ConnectSend(&usrsocktest_daemon_config); +} + +TEST(Poll, ConnectSendDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + ConnectSend(&usrsocktest_daemon_config); +} + +TEST(Poll, DaemonAbort) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + DaemonAbort(&usrsocktest_daemon_config); +} + +TEST(Poll, DaemonAbortDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + DaemonAbort(&usrsocktest_daemon_config); +} diff --git a/tests/unity_usrsock/remote_disconnect.c b/tests/unity_usrsock/remote_disconnect.c new file mode 100644 index 000000000..1baec7ab8 --- /dev/null +++ b/tests/unity_usrsock/remote_disconnect.c @@ -0,0 +1,1055 @@ +/**************************************************************************** + * apps/examples/unity_usrsock/remote_disconnect.c + * Remote end disconnects + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Authors: Roman Saveljev + * Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "defines.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static const uint8_t tevents[] = { POLLIN, POLLOUT, POLLOUT|POLLIN, 0}; +static bool started; +static int sd; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ConnectReceive + * + * Description: + * Remote end is unreachable + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void Unreachable(struct usrsocktest_daemon_conf_s *dconf) +{ + ssize_t ret; + struct sockaddr_in addr; + int flags; + struct pollfd pfd; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + dconf->endpoint_block_connect = true; + dconf->endpoint_block_send = true; + dconf->endpoint_recv_avail_from_start = false; + dconf->endpoint_recv_avail = 7; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); + + /* Try connect, connection not accepted. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('F', 100)); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(ECONNREFUSED, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_unreachable_sockets()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); + + /* Make socket non-blocking */ + + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); + ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); + TEST_ASSERT_EQUAL(0, ret); + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); + + /* Try connect, connection in progress. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINPROGRESS, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); + + /* Disconnect pending connections. */ + + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('F', 100)); + + /* Poll for input (no timeout). */ + + memset(&pfd, 0, sizeof(pfd)); + pfd.fd = sd; + pfd.events = POLLIN; + ret = poll(&pfd, 1, -1); + TEST_ASSERT_EQUAL(1, ret); + TEST_ASSERT_EQUAL(POLLERR, pfd.revents & POLLERR); + TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP); + TEST_ASSERT_EQUAL(0, pfd.revents & POLLIN); + TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); + +} + +/**************************************************************************** + * Name: Send + * + * Description: + * Send and disconnect + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void Send(struct usrsocktest_daemon_conf_s *dconf) +{ + ssize_t ret; + size_t datalen; + void *data; + struct sockaddr_in addr; + int count; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + dconf->endpoint_block_connect = false; + dconf->endpoint_block_send = false; + dconf->endpoint_recv_avail_from_start = false; + dconf->endpoint_recv_avail = 7; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); + + /* Try connect, connection in progress. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_remote_disconnected_sockets()); + + /* Disconnect connections. */ + + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('D', 0)); + for (count = 0; usrsocktest_daemon_get_num_connected_sockets() > 0; count++) + { + TEST_ASSERT_TRUE(count <= 3); + usleep(5 * 1000); + } + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_remote_disconnected_sockets()); + + for (count = 0; count < 2; count++) + { + /* Send data to remote */ + + data = "abcde"; + datalen = strlen("abcde"); + ret = write(sd, data, datalen); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EPIPE, errno); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_remote_disconnected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); + } + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Name: Send2 + * + * Description: + * Send and disconnect + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void Send2(struct usrsocktest_daemon_conf_s *dconf) +{ + ssize_t ret; + size_t datalen; + void *data; + struct sockaddr_in addr; + int count; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + dconf->endpoint_block_connect = false; + dconf->endpoint_block_send = true; + dconf->endpoint_recv_avail_from_start = false; + dconf->endpoint_recv_avail = 7; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_remote_disconnected_sockets()); + + /* Try connect. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_remote_disconnected_sockets()); + + /* Disconnect connections with delay. */ + + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('D', 100)); + + for (count = 0; count < 2; count++) + { + /* Send data to remote */ + + data = "abcde"; + datalen = strlen("abcde"); + ret = write(sd, data, datalen); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EPIPE, errno); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_remote_disconnected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); + } + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Name: Receive + * + * Description: + * Receive and disconnect + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void Receive(struct usrsocktest_daemon_conf_s *dconf) +{ + ssize_t ret; + size_t datalen; + void *data; + struct sockaddr_in addr; + char databuf[5]; + int count; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + dconf->endpoint_block_connect = false; + dconf->endpoint_block_send = false; + dconf->endpoint_recv_avail_from_start = true; + dconf->endpoint_recv_avail = 1; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); + + /* Try connect. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_remote_disconnected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); + + /* Disconnect connections. */ + + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('D', 0)); + for (count = 0; usrsocktest_daemon_get_num_connected_sockets() > 0; count++) + { + TEST_ASSERT_TRUE(count <= 3); + usleep(5 * 1000); + } + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_remote_disconnected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); + + for (count = 0; count < 2; count++) + { + /* Read from closed remote (EOF) */ + + data = databuf; + datalen = sizeof(databuf); + ret = read(sd, data, datalen); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_remote_disconnected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_recv_bytes()); + } + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Name: Receive2 + * + * Description: + * Receive and disconnect + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void Receive2(struct usrsocktest_daemon_conf_s *dconf) +{ + ssize_t ret; + size_t datalen; + void *data; + struct sockaddr_in addr; + char databuf[5]; + int count; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + dconf->endpoint_block_connect = false; + dconf->endpoint_block_send = true; + dconf->endpoint_recv_avail_from_start = false; + dconf->endpoint_recv_avail = 7; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_remote_disconnected_sockets()); + + /* Try connect. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_remote_disconnected_sockets()); + + /* Disconnect connections with delay. */ + + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('D', 100)); + + for (count = 0; count < 2; count++) + { + /* Read from closed remote (EOF) */ + + data = databuf; + datalen = sizeof(databuf); + ret = read(sd, data, datalen); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_remote_disconnected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_recv_bytes()); + } + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Name: Poll + * + * Description: + * Poll and disconnect + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void Poll(struct usrsocktest_daemon_conf_s *dconf) +{ + ssize_t ret; + struct sockaddr_in addr; + int flags; + struct pollfd pfd; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + dconf->endpoint_recv_avail_from_start = false; + dconf->endpoint_recv_avail = 3; + dconf->endpoint_block_send = false; + dconf->endpoint_block_connect = true; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Make socket non-blocking */ + + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); + ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); + TEST_ASSERT_EQUAL(0, ret); + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); + + /* Poll for input (instant timeout). */ + + memset(&pfd, 0, sizeof(pfd)); + pfd.fd = sd; + pfd.events = POLLIN; + ret = poll(&pfd, 1, 0); + TEST_ASSERT_EQUAL(1, ret); + TEST_ASSERT_EQUAL(0, pfd.revents & POLLERR); + TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP); + TEST_ASSERT_EQUAL(POLLIN, pfd.revents & POLLIN); + TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT); + + /* Start non-blocking connect. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINPROGRESS, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Poll for input/output (no timeout). Fail connection. */ + + memset(&pfd, 0, sizeof(pfd)); + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('F', 100)); + pfd.fd = sd; + pfd.events = POLLOUT | POLLIN; + ret = poll(&pfd, 1, -1); + TEST_ASSERT_EQUAL(1, ret); + TEST_ASSERT_EQUAL(POLLERR, pfd.revents & POLLERR); + TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP); + TEST_ASSERT_EQUAL(0, pfd.revents & POLLIN); + TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_remote_disconnected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_unreachable_sockets()); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Name: Poll2 + * + * Description: + * Poll and disconnect + * + * Input Parameters: + * dconf - socket daemon configuration + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void Poll2(struct usrsocktest_daemon_conf_s *dconf) +{ + ssize_t ret; + size_t datalen; + void *data; + struct sockaddr_in addr; + char databuf[5]; + int flags; + struct pollfd pfd; + int count; + const uint8_t *events = tevents; + + /* Start test daemon. */ + + dconf->endpoint_addr = "127.0.0.1"; + dconf->endpoint_port = 255; + dconf->endpoint_recv_avail_from_start = false; + dconf->endpoint_recv_avail = 3; + dconf->endpoint_block_send = true; + dconf->endpoint_block_connect = false; + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); + started = true; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + do + { + TEST_ASSERT_TRUE(*events == POLLIN || *events == POLLOUT || *events == (POLLOUT|POLLIN)); + + /* Open socket */ + + sd = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(sd >= 0); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + + /* Make socket non-blocking */ + + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); + ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); + TEST_ASSERT_EQUAL(0, ret); + flags = fcntl(sd, F_GETFL, 0); + TEST_ASSERT_TRUE(flags >= 0); + TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); + TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); + + /* Poll for input (instant timeout). */ + + memset(&pfd, 0, sizeof(pfd)); + pfd.fd = sd; + pfd.events = *events; + ret = poll(&pfd, 1, 0); + TEST_ASSERT_EQUAL(1, ret); + TEST_ASSERT_EQUAL(0, pfd.revents & POLLERR); + TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP); + TEST_ASSERT_EQUAL(*events & POLLIN, pfd.revents & POLLIN); + TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT); + + /* Start non-blocking connect. */ + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + if (!dconf->delay_all_responses) + { + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + } + else + { + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EINPROGRESS, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + for (count = 0; usrsocktest_daemon_get_num_connected_sockets() != 1; count++) + { + TEST_ASSERT_TRUE(count <= 3); + usleep(25 * 1000); + } + + ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EISCONN, errno); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); + } + + /* Poll for output (no timeout). Close connection. */ + + memset(&pfd, 0, sizeof(pfd)); + TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('D', 100)); + pfd.fd = sd; + pfd.events = *events; + ret = poll(&pfd, 1, -1); + TEST_ASSERT_EQUAL(1, ret); + TEST_ASSERT_EQUAL(0, pfd.revents & POLLERR); + TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP); + TEST_ASSERT_EQUAL(*events & POLLIN, pfd.revents & POLLIN); + TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_remote_disconnected_sockets()); + + for (count = 0; count < 2; count++) + { + /* Read from closed remote (EOF) */ + + data = databuf; + datalen = sizeof(databuf); + ret = read(sd, data, datalen); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_remote_disconnected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_recv_bytes()); + } + + for (count = 0; count < 2; count++) + { + /* Send data to remote */ + + data = "abcde"; + datalen = strlen("abcde"); + ret = write(sd, data, datalen); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EPIPE, errno); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_remote_disconnected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); + } + + /* Close socket */ + + TEST_ASSERT_TRUE(close(sd) >= 0); + sd = -1; + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); + + events++; + } + while (*events); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + started = false; + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); + TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +TEST_GROUP(RemoteDisconnect); + +/**************************************************************************** + * Name: RemoteDisconnect test group setup + * + * Description: + * Setup function executed before each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_SETUP(RemoteDisconnect) +{ + sd = -1; + started = false; +} + +/**************************************************************************** + * Name: RemoteDisconnect test group teardown + * + * Description: + * Setup function executed after each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_TEAR_DOWN(RemoteDisconnect) +{ + int ret; + if (sd >= 0) + { + ret = close(sd); + assert(ret >= 0); + } + if (started) + { + ret = usrsocktest_daemon_stop(); + assert(ret == OK); + } +} + +TEST(RemoteDisconnect, Unreachable) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + Unreachable(&usrsocktest_daemon_config); +} + +TEST(RemoteDisconnect, UnreachableDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + Unreachable(&usrsocktest_daemon_config); +} + +TEST(RemoteDisconnect, Send) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + Send(&usrsocktest_daemon_config); +} + +TEST(RemoteDisconnect, SendDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + Send(&usrsocktest_daemon_config); +} + +TEST(RemoteDisconnect, Send2) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + Send2(&usrsocktest_daemon_config); +} + +TEST(RemoteDisconnect, Send2Delay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + Send2(&usrsocktest_daemon_config); +} + +TEST(RemoteDisconnect, Receive) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + Receive(&usrsocktest_daemon_config); +} + +TEST(RemoteDisconnect, ReceiveDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + Receive(&usrsocktest_daemon_config); +} + +TEST(RemoteDisconnect, Receive2) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + Receive2(&usrsocktest_daemon_config); +} + +TEST(RemoteDisconnect, Receive2Delay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + Receive2(&usrsocktest_daemon_config); +} + +TEST(RemoteDisconnect, Poll) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + Poll(&usrsocktest_daemon_config); +} + +TEST(RemoteDisconnect, PollDelay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + Poll(&usrsocktest_daemon_config); +} + +TEST(RemoteDisconnect, Poll2) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + Poll2(&usrsocktest_daemon_config); +} + +TEST(RemoteDisconnect, Poll2Delay) +{ + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = true; + Poll2(&usrsocktest_daemon_config); +} diff --git a/tests/unity_usrsock/unity_usrsock_main.c b/tests/unity_usrsock/unity_usrsock_main.c new file mode 100644 index 000000000..6025ee804 --- /dev/null +++ b/tests/unity_usrsock/unity_usrsock_main.c @@ -0,0 +1,161 @@ +/**************************************************************************** + * apps/examples/unity_usrsock/unity_usrsock_main.c + * Main function for Unity test application + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Author: Roman Saveljev + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +static void runAllTests(void); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ +int usrsocktest_endp_malloc_cnt = 0; +int usrsocktest_dcmd_malloc_cnt = 0; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void get_mallinfo(struct mallinfo *mem) +{ +#ifdef CONFIG_CAN_PASS_STRUCTS + *mem = mallinfo(); +#else + (void)mallinfo(mem); +#endif +} + +static void print_mallinfo(const struct mallinfo *mem, const char *title) +{ + if (title) + printf("%s:\n", title); + printf(" %11s%11s%11s%11s\n", "total", "used", "free", "largest"); + printf("Mem: %11d%11d%11d%11d\n", + mem->arena, mem->uordblks, mem->fordblks, mem->mxordblk); +} + +/**************************************************************************** + * Name: runAllTests + * + * Description: + * Sequentially runs all included test groups + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +static void runAllTests(void) +{ + RUN_TEST_GROUP(CharDev); + RUN_TEST_GROUP(NoDaemon); + RUN_TEST_GROUP(BasicDaemon); + RUN_TEST_GROUP(BasicConnect); + RUN_TEST_GROUP(BasicConnectDelay); + RUN_TEST_GROUP(NoBlockConnect); + RUN_TEST_GROUP(BasicSend); + RUN_TEST_GROUP(NoBlockSend); + RUN_TEST_GROUP(BlockSend); + RUN_TEST_GROUP(NoBlockRecv); + RUN_TEST_GROUP(BlockRecv); + RUN_TEST_GROUP(RemoteDisconnect); + RUN_TEST_GROUP(BasicSetSockOpt); + RUN_TEST_GROUP(BasicGetSockOpt); + RUN_TEST_GROUP(BasicGetSockName); + RUN_TEST_GROUP(WakeWithSignal); + RUN_TEST_GROUP(MultiThread); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: unity_pwrbtn_main + * + * Description: + * Application entry point + * + * Input Parameters: + * argc - number of arguments + * argv - arguments themselves + * + * Returned Value: + * exit status + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +int unity_usrsock_main(int argc, const char* argv[]) +{ + int ret; + struct mallinfo mem_before, mem_after; + + get_mallinfo(&mem_before); + + ret = UnityMain(argc, argv, runAllTests); + + get_mallinfo(&mem_after); + + print_mallinfo(&mem_before, "HEAP BEFORE TESTS"); + print_mallinfo(&mem_after, "HEAP AFTER TESTS"); + + return ret; +} diff --git a/tests/unity_usrsock/usrsocktest_daemon.c b/tests/unity_usrsock/usrsocktest_daemon.c new file mode 100644 index 000000000..ba47bef06 --- /dev/null +++ b/tests/unity_usrsock/usrsocktest_daemon.c @@ -0,0 +1,1930 @@ +/**************************************************************************** + * examples/nettest/usrsocktest_daemon.c + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Author: Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "defines.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +#ifndef dbg + #define dbg _warn +#endif + +#define TEST_SOCKET_SOCKID_BASE 10000U +#define TEST_SOCKET_COUNT 8 + +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +#define noinline __attribute__((noinline)) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct test_socket_s { + bool opened:1; + bool connected:1; + bool blocked_connect:1; + bool block_send:1; + bool connect_refused:1; + bool disconnected:1; + int recv_avail_bytes; + FAR void *endp; + struct usrsock_message_req_ack_s pending_resp; +}; + +struct delayed_cmd_s { + sq_entry_t node; + pthread_t tid; + sem_t startsem; + int pipefd; + uint16_t delay_msec; + char cmd; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct daemon_priv_s { + const struct usrsocktest_daemon_conf_s *conf; + pthread_t tid; + bool joined; + + int pipefd[2]; + sem_t wakewaitsem; + unsigned int sockets_active; + unsigned int sockets_connected; + unsigned int sockets_waiting_connect; + unsigned int sockets_recv_empty; + unsigned int sockets_not_connected_refused; + unsigned int sockets_remote_disconnected; + size_t total_send_bytes; + size_t total_recv_bytes; + bool do_not_poll_usrsock; + + struct test_socket_s test_sockets[TEST_SOCKET_COUNT]; + sq_queue_t delayed_cmd_threads; +} daemon = { + .joined = true, + .conf = NULL, +}; + +static pthread_mutex_t daemon_mutex = PTHREAD_MUTEX_INITIALIZER; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const struct usrsocktest_daemon_conf_s usrsocktest_daemon_defconf = + USRSOCKTEST_DAEMON_CONF_DEFAULTS; +struct usrsocktest_daemon_conf_s usrsocktest_daemon_config; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int test_socket_alloc(FAR struct daemon_priv_s *priv) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(priv->test_sockets); i++) + { + FAR struct test_socket_s *tsock = &priv->test_sockets[i]; + + if (!tsock->opened) + { + memset(tsock, 0, sizeof(*tsock)); + tsock->opened = true; + tsock->block_send = priv->conf->endpoint_block_send; + tsock->recv_avail_bytes = + priv->conf->endpoint_recv_avail_from_start ? + priv->conf->endpoint_recv_avail : 0; + priv->sockets_active++; + if (tsock->recv_avail_bytes == 0) + priv->sockets_recv_empty++; + return i + TEST_SOCKET_SOCKID_BASE; + } + } + + return -1; +} + +static FAR struct test_socket_s *test_socket_get(FAR struct daemon_priv_s *priv, + int sockid) +{ + if (sockid < TEST_SOCKET_SOCKID_BASE) + return NULL; + + sockid -= TEST_SOCKET_SOCKID_BASE; + if (sockid >= ARRAY_SIZE(priv->test_sockets)) + return NULL; + + return &priv->test_sockets[sockid]; +} + +static int test_socket_free(FAR struct daemon_priv_s *priv, int sockid) +{ + FAR struct test_socket_s *tsock = test_socket_get(priv, sockid); + + if (!tsock) + return -EBADFD; + + if (!tsock->opened) + return -EFAULT; + + if (tsock->connected) + { + priv->sockets_connected--; + tsock->connected = false; + } + if (tsock->blocked_connect) + { + priv->sockets_waiting_connect--; + tsock->blocked_connect = false; + } + if (tsock->endp) + { + free(tsock->endp); + usrsocktest_endp_malloc_cnt--; + tsock->endp = NULL; + } + if (tsock->recv_avail_bytes == 0) + { + priv->sockets_recv_empty--; + } + if (tsock->connect_refused) + { + priv->sockets_not_connected_refused--; + } + if (tsock->disconnected) + { + priv->sockets_remote_disconnected--; + } + + tsock->opened = false; + priv->sockets_active--; + + return 0; +} + +static int tsock_send_event(int fd, FAR struct daemon_priv_s *priv, + FAR struct test_socket_s *tsock, int events) +{ + FAR struct usrsock_message_socket_event_s event = {}; + ssize_t wlen; + int i; + + event.head.flags = USRSOCK_MESSAGE_FLAG_EVENT; + event.head.msgid = USRSOCK_MESSAGE_SOCKET_EVENT; + + for (i = 0; i < ARRAY_SIZE(priv->test_sockets); i++) + { + if (tsock == &priv->test_sockets[i]) + break; + } + + if (i == ARRAY_SIZE(priv->test_sockets)) + return -EINVAL; + + event.usockid = i + TEST_SOCKET_SOCKID_BASE; + event.events = events; + + wlen = write(fd, &event, sizeof(event)); + if (wlen < 0) + return -errno; + if (wlen != sizeof(event)) + return -ENOSPC; + + return OK; +} + + +static FAR void *find_endpoint(FAR struct daemon_priv_s *priv, in_addr_t ipaddr) +{ + FAR struct sockaddr_in *endpaddr; + int ok; + + endpaddr = malloc(sizeof(*endpaddr)); + usrsocktest_endp_malloc_cnt++; + assert(endpaddr); + + ok = inet_pton(AF_INET, priv->conf->endpoint_addr, &endpaddr->sin_addr.s_addr); + endpaddr->sin_family = AF_INET; + endpaddr->sin_port = htons(priv->conf->endpoint_port); + assert(ok); + + if (endpaddr->sin_addr.s_addr == ipaddr) + return endpaddr; + + free(endpaddr); + usrsocktest_endp_malloc_cnt--; + return NULL; +} + +static bool endpoint_connect(FAR struct daemon_priv_s *priv, FAR void *endp, + uint16_t port) +{ + FAR struct sockaddr_in *endpaddr = endp; + + if (endpaddr->sin_port == port) + return true; + else + return false; +} + +static void get_endpoint_sockaddr(FAR void *endp, FAR struct sockaddr_in *endpaddr) +{ + *endpaddr = *(FAR struct sockaddr_in *)endp; +} + +static ssize_t +read_req(int fd, FAR const struct usrsock_request_common_s *common_hdr, + void *req, size_t reqsize) +{ + ssize_t rlen; + int err; + + rlen = read(fd, (uint8_t *)req + sizeof(*common_hdr), + reqsize - sizeof(*common_hdr)); + if (rlen < 0) + { + err = errno; + dbg("Error reading %d bytes of request: ret=%d, errno=%d\n", + reqsize - sizeof(*common_hdr), (int)rlen, errno); + return -err; + } + if (rlen + sizeof(*common_hdr) != reqsize) + { + return -EMSGSIZE; + } + + return rlen; +} + +static int socket_request(int fd, FAR struct daemon_priv_s *priv, + FAR void *hdrbuf) +{ + FAR struct usrsock_request_socket_s *req = hdrbuf; + struct usrsock_message_req_ack_s resp = {}; + int socketid; + ssize_t wlen; + + /* Validate input. */ + + if (req->domain != priv->conf->supported_domain) + { + socketid = -EAFNOSUPPORT; + } + else if (req->type != priv->conf->supported_type || + req->protocol != priv->conf->supported_protocol) + { + socketid = -EPROTONOSUPPORT; + } + else if (priv->sockets_active >= priv->conf->max_sockets) + { + socketid = -EMFILE; + } + else + { + /* Allocate socket. */ + + socketid = test_socket_alloc(priv); + if (socketid < 0) + socketid = -ENFILE; + } + + /* Prepare response. */ + + resp.head.msgid = USRSOCK_MESSAGE_RESPONSE_ACK; + resp.head.flags = 0; + resp.xid = req->head.xid; + resp.result = socketid; + + /* Send response. */ + + wlen = write(fd, &resp, sizeof(resp)); + if (wlen < 0) + return -errno; + if (wlen != sizeof(resp)) + return -ENOSPC; + + return OK; +} + +static int close_request(int fd, FAR struct daemon_priv_s *priv, + FAR void *hdrbuf) +{ + FAR struct usrsock_request_close_s *req = hdrbuf; + struct usrsock_message_req_ack_s resp = {}; + ssize_t wlen; + int ret; + + /* Check if this socket exists. */ + + ret = test_socket_free(priv, req->usockid); + + /* Prepare response. */ + + resp.head.msgid = USRSOCK_MESSAGE_RESPONSE_ACK; + resp.xid = req->head.xid; + if (priv->conf->delay_all_responses) + { + resp.head.flags = USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; + resp.result = -EAGAIN; + } + else + { + resp.head.flags = 0; + resp.result = ret; + } + + /* Send response. */ + + wlen = write(fd, &resp, sizeof(resp)); + if (wlen < 0) + return -errno; + if (wlen != sizeof(resp)) + return -ENOSPC; + + if (priv->conf->delay_all_responses) + { + pthread_mutex_unlock(&daemon_mutex); + usleep(50 * 1000); + pthread_mutex_lock(&daemon_mutex); + + /* Previous write was acknowledgment to request, informing that request + * is still in progress. Now write actual completion response. */ + + resp.result = ret; + resp.head.flags &= ~USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; + + wlen = write(fd, &resp, sizeof(resp)); + if (wlen < 0) + return -errno; + if (wlen != sizeof(resp)) + return -ENOSPC; + } + + return OK; +} + +static int connect_request(int fd, FAR struct daemon_priv_s *priv, + FAR void *hdrbuf) +{ + DEBUGASSERT(priv); + DEBUGASSERT(hdrbuf); + FAR struct usrsock_request_connect_s *req = hdrbuf; + struct sockaddr_in addr; + FAR struct test_socket_s *tsock; + struct usrsock_message_req_ack_s resp = {}; + ssize_t wlen, rlen; + int ret = 0; + + /* Check if this socket exists. */ + + tsock = test_socket_get(priv, req->usockid); + if (!tsock) + { + ret = -EBADFD; + goto prepare; + } + + /* Check if this socket is already connected. */ + + if (tsock->connected) + { + ret = -EISCONN; + goto prepare; + } + + /* Check if address size ok. */ + + if (req->addrlen > sizeof(addr)) + { + ret = -EFAULT; + goto prepare; + } + + /* Read address. */ + + rlen = read(fd, &addr, sizeof(addr)); + if (rlen < 0 || rlen < req->addrlen) + { + ret = -EFAULT; + goto prepare; + } + + /* Check address family. */ + + if (addr.sin_family != priv->conf->supported_domain) + { + ret = -EAFNOSUPPORT; + goto prepare; + } + + /* Check if there is endpoint with target address */ + + tsock->endp = find_endpoint(priv, addr.sin_addr.s_addr); + if (!tsock->endp) + { + ret = -ENETUNREACH; + goto prepare; + } + + /* Check if there is port open at endpoint */ + + if (!endpoint_connect(priv, tsock->endp, addr.sin_port)) + { + free(tsock->endp); + usrsocktest_endp_malloc_cnt--; + tsock->endp = NULL; + ret = -ECONNREFUSED; + goto prepare; + } + + ret = OK; + +prepare: + /* Prepare response. */ + + resp.xid = req->head.xid; + resp.head.msgid = USRSOCK_MESSAGE_RESPONSE_ACK; + resp.head.flags = 0; + + if (priv->conf->endpoint_block_connect) + { + resp.head.flags = USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; + resp.result = ret; + + /* Mark connection as blocked */ + + priv->sockets_waiting_connect++; + tsock->blocked_connect = true; + tsock->pending_resp = resp; + } + else if (priv->conf->delay_all_responses) + { + resp.head.flags = USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; + resp.result = -EINPROGRESS; + tsock->blocked_connect = false; + } + else + { + if (ret == OK) + { + priv->sockets_connected++; + tsock->connected = true; + } + + resp.head.flags = 0; + resp.result = ret; + tsock->blocked_connect = false; + } + + /* Send response. */ + + wlen = write(fd, &resp, sizeof(resp)); + if (wlen < 0) + return -errno; + if (wlen != sizeof(resp)) + return -ENOSPC; + + if (priv->conf->endpoint_block_connect) + { + tsock->pending_resp.head.flags &= ~USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; + } + else + { + int events; + + if (priv->conf->delay_all_responses) + { + pthread_mutex_unlock(&daemon_mutex); + usleep(50 * 1000); + pthread_mutex_lock(&daemon_mutex); + + /* Previous write was acknowledgment to request, informing that request + * is still in progress. Now write actual completion response. */ + + resp.result = ret; + + if (ret == OK) + { + priv->sockets_connected++; + tsock->connected = true; + } + + resp.head.flags &= ~USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; + + wlen = write(fd, &resp, sizeof(resp)); + if (wlen < 0) + return -errno; + if (wlen != sizeof(resp)) + return -ENOSPC; + } + + events = 0; + if (!tsock->block_send) + events |= USRSOCK_EVENT_SENDTO_READY; + if (tsock->recv_avail_bytes > 0) + events |= USRSOCK_EVENT_RECVFROM_AVAIL; + + if (events) + { + wlen = tsock_send_event(fd, priv, tsock, events); + if (wlen < 0) + return wlen; + } + } + + return OK; +} + +static int sendto_request(int fd, FAR struct daemon_priv_s *priv, + FAR void *hdrbuf) +{ + DEBUGASSERT(priv); + DEBUGASSERT(hdrbuf); + FAR struct usrsock_request_sendto_s *req = hdrbuf; + FAR struct test_socket_s *tsock; + struct usrsock_message_req_ack_s resp = {}; + ssize_t wlen, rlen; + int ret = 0; + uint8_t sendbuf[16]; + int sendbuflen = 0; + + /* Check if this socket exists. */ + + tsock = test_socket_get(priv, req->usockid); + if (!tsock) + { + ret = -EBADFD; + goto prepare; + } + + /* Check if this socket is connected. */ + + if (!tsock->connected) + { + ret = -ENOTCONN; + goto prepare; + } + + /* Check if address size non-zero. */ + + if (req->addrlen > 0) + { + ret = -EISCONN; /* connection-mode socket do not accept address */ + goto prepare; + } + + /* Can send? */ + + if (!tsock->block_send) + { + /* Check if request has data. */ + + if (req->buflen > 0) + { + sendbuflen = req->buflen; + if (sendbuflen > sizeof(sendbuf)) + sendbuflen = sizeof(sendbuf); + + /* Read data. */ + + rlen = read(fd, sendbuf, sendbuflen); + if (rlen < 0 || rlen < sendbuflen) + { + ret = -EFAULT; + goto prepare; + } + + /* Debug print */ + + dbg("got %d bytes of data: '%.*s'\n", sendbuflen, sendbuflen, sendbuf); + } + } + else + { + ret = -EAGAIN; /* blocked. */ + goto prepare; + } + + ret = sendbuflen; + +prepare: + /* Prepare response. */ + + resp.xid = req->head.xid; + resp.head.msgid = USRSOCK_MESSAGE_RESPONSE_ACK; + resp.head.flags = 0; + + if (priv->conf->delay_all_responses) + { + resp.head.flags = USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; + resp.result = -EINPROGRESS; + } + else + { + if (ret > 0) + { + priv->total_send_bytes += ret; + } + + resp.head.flags = 0; + resp.result = ret; + } + + /* Send response. */ + + wlen = write(fd, &resp, sizeof(resp)); + if (wlen < 0) + return -errno; + if (wlen != sizeof(resp)) + return -ENOSPC; + + if (priv->conf->delay_all_responses) + { + pthread_mutex_unlock(&daemon_mutex); + usleep(50 * 1000); + pthread_mutex_lock(&daemon_mutex); + + /* Previous write was acknowledgment to request, informing that request + * is still in progress. Now write actual completion response. */ + + resp.result = ret; + + if (ret > 0) + { + priv->total_send_bytes += ret; + } + + resp.head.flags &= ~USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; + + wlen = write(fd, &resp, sizeof(resp)); + if (wlen < 0) + return -errno; + if (wlen != sizeof(resp)) + return -ENOSPC; + } + + if (!tsock->block_send) + { + /* Let kernel-side know that there is space for more send data. */ + + wlen = tsock_send_event(fd, priv, tsock, USRSOCK_EVENT_SENDTO_READY); + if (wlen < 0) + return wlen; + } + + return OK; +} + +static int recvfrom_request(int fd, FAR struct daemon_priv_s *priv, + FAR void *hdrbuf) +{ + DEBUGASSERT(priv); + DEBUGASSERT(hdrbuf); + FAR struct usrsock_request_recvfrom_s *req = hdrbuf; + FAR struct test_socket_s *tsock; + struct usrsock_message_datareq_ack_s resp = {}; + ssize_t wlen; + size_t i; + int ret = 0; + size_t outbuflen; + struct sockaddr_in endpointaddr; + + /* Check if this socket exists. */ + + tsock = test_socket_get(priv, req->usockid); + if (!tsock) + { + ret = -EBADFD; + goto prepare; + } + + /* Check if this socket is connected. */ + + if (!tsock->connected) + { + ret = -ENOTCONN; + goto prepare; + } + + get_endpoint_sockaddr(tsock->endp, &endpointaddr); + + /* Do we have recv data available? */ + + if (tsock->recv_avail_bytes > 0) + { + outbuflen = req->max_buflen; + + if (outbuflen > tsock->recv_avail_bytes) + { + outbuflen = tsock->recv_avail_bytes; + } + } + else + { + ret = -EAGAIN; /* blocked. */ + goto prepare; + } + + ret = outbuflen; + +prepare: + /* Prepare response. */ + + resp.reqack.xid = req->head.xid; + resp.reqack.head.msgid = USRSOCK_MESSAGE_RESPONSE_DATA_ACK; + resp.reqack.head.flags = 0; + + if (priv->conf->delay_all_responses) + { + resp.reqack.head.flags = USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; + resp.reqack.result = -EINPROGRESS; + resp.valuelen = 0; + resp.valuelen_nontrunc = 0; + + /* Send ack response. */ + + wlen = write(fd, &resp, sizeof(resp)); + if (wlen < 0) + return -errno; + if (wlen != sizeof(resp)) + return -ENOSPC; + + pthread_mutex_unlock(&daemon_mutex); + usleep(50 * 1000); + pthread_mutex_lock(&daemon_mutex); + + /* Previous write was acknowledgment to request, informing that request + * is still in progress. Now write actual completion response. */ + + resp.reqack.head.msgid = USRSOCK_MESSAGE_RESPONSE_DATA_ACK; + resp.reqack.head.flags &= ~USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; + } + + resp.reqack.head.flags = 0; + resp.reqack.result = ret; + if (ret >= 0) + { + priv->total_recv_bytes += ret; + resp.valuelen_nontrunc = sizeof(endpointaddr); + resp.valuelen = resp.valuelen_nontrunc; + if (resp.valuelen > req->max_addrlen) + resp.valuelen = req->max_addrlen; + } + else + { + resp.valuelen = 0; + resp.valuelen_nontrunc = 0; + } + + /* Send response. */ + + wlen = write(fd, &resp, sizeof(resp)); + if (wlen < 0) + return -errno; + if (wlen != sizeof(resp)) + return -ENOSPC; + + if (resp.valuelen > 0) + { + /* Send address (value) */ + + wlen = write(fd, &endpointaddr, resp.valuelen); + if (wlen < 0) + return -errno; + if (wlen != resp.valuelen) + return -ENOSPC; + } + + if (resp.reqack.result > 0) + { + /* Send buffer */ + + for (i = 0; i < resp.reqack.result; i++) + { + char tmp = 'a' + i; + + tsock->recv_avail_bytes--; + + wlen = write(fd, &tmp, 1); + if (wlen < 0) + return -errno; + if (wlen != 1) + return -ENOSPC; + } + + if (tsock->recv_avail_bytes == 0) + priv->sockets_recv_empty++; + } + + + if (tsock->recv_avail_bytes > 0) + { + /* Let kernel-side know that there is more recv data. */ + + wlen = tsock_send_event(fd, priv, tsock, USRSOCK_EVENT_RECVFROM_AVAIL); + if (wlen < 0) + return wlen; + } + + return OK; +} + +static int setsockopt_request(int fd, FAR struct daemon_priv_s *priv, + FAR void *hdrbuf) +{ + DEBUGASSERT(priv); + DEBUGASSERT(hdrbuf); + FAR struct usrsock_request_setsockopt_s *req = hdrbuf; + FAR struct test_socket_s *tsock; + struct usrsock_message_req_ack_s resp = {}; + ssize_t wlen, rlen; + int ret = 0; + int value; + + /* Check if this socket exists. */ + + tsock = test_socket_get(priv, req->usockid); + if (!tsock) + { + ret = -EBADFD; + goto prepare; + } + + if (req->level != SOL_SOCKET) + { + dbg("setsockopt: level=%d not supported\n", req->level); + ret = -ENOPROTOOPT; + goto prepare; + } + + if (req->option != SO_REUSEADDR) + { + dbg("setsockopt: option=%d not supported\n", req->option); + ret = -ENOPROTOOPT; + goto prepare; + } + + if (req->valuelen < sizeof(value)) + { + ret = -EINVAL; + goto prepare; + } + + /* Read value. */ + + rlen = read(fd, &value, sizeof(value)); + if (rlen < 0 || rlen < sizeof(value)) + { + ret = -EFAULT; + goto prepare; + } + + /* Debug print */ + + dbg("setsockopt: option=%d value=%d\n", req->option, value); + + ret = OK; + +prepare: + /* Prepare response. */ + + resp.xid = req->head.xid; + resp.head.msgid = USRSOCK_MESSAGE_RESPONSE_ACK; + resp.head.flags = 0; + + if (priv->conf->delay_all_responses) + { + resp.head.flags = USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; + resp.result = -EINPROGRESS; + } + else + { + resp.head.flags = 0; + resp.result = ret; + } + + /* Send response. */ + + wlen = write(fd, &resp, sizeof(resp)); + if (wlen < 0) + return -errno; + if (wlen != sizeof(resp)) + return -ENOSPC; + + if (priv->conf->delay_all_responses) + { + pthread_mutex_unlock(&daemon_mutex); + usleep(50 * 1000); + pthread_mutex_lock(&daemon_mutex); + + /* Previous write was acknowledgment to request, informing that request + * is still in progress. Now write actual completion response. */ + + resp.result = ret; + resp.head.flags &= ~USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; + + wlen = write(fd, &resp, sizeof(resp)); + if (wlen < 0) + return -errno; + if (wlen != sizeof(resp)) + return -ENOSPC; + } + + return OK; +} + +static int getsockopt_request(int fd, FAR struct daemon_priv_s *priv, + FAR void *hdrbuf) +{ + DEBUGASSERT(priv); + DEBUGASSERT(hdrbuf); + FAR struct usrsock_request_getsockopt_s *req = hdrbuf; + FAR struct test_socket_s *tsock; + struct usrsock_message_datareq_ack_s resp = {}; + ssize_t wlen; + int ret = 0; + int value; + + /* Check if this socket exists. */ + + tsock = test_socket_get(priv, req->usockid); + if (!tsock) + { + ret = -EBADFD; + goto prepare; + } + + if (req->level != SOL_SOCKET) + { + dbg("getsockopt: level=%d not supported\n", req->level); + ret = -ENOPROTOOPT; + goto prepare; + } + + if (req->option != SO_REUSEADDR) + { + dbg("getsockopt: option=%d not supported\n", req->option); + ret = -ENOPROTOOPT; + goto prepare; + } + + if (req->max_valuelen < sizeof(value)) + { + ret = -EINVAL; + goto prepare; + } + + value = 0; + ret = OK; + +prepare: + /* Prepare response. */ + + resp.reqack.xid = req->head.xid; + resp.reqack.head.msgid = USRSOCK_MESSAGE_RESPONSE_DATA_ACK; + resp.reqack.head.flags = 0; + + if (priv->conf->delay_all_responses) + { + resp.reqack.head.flags = USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; + resp.reqack.result = -EINPROGRESS; + resp.valuelen = 0; + resp.valuelen_nontrunc = 0; + + /* Send ack response. */ + + wlen = write(fd, &resp, sizeof(resp)); + if (wlen < 0) + return -errno; + if (wlen != sizeof(resp)) + return -ENOSPC; + + pthread_mutex_unlock(&daemon_mutex); + usleep(50 * 1000); + pthread_mutex_lock(&daemon_mutex); + + /* Previous write was acknowledgment to request, informing that request + * is still in progress. Now write actual completion response. */ + + resp.reqack.head.msgid = USRSOCK_MESSAGE_RESPONSE_DATA_ACK; + resp.reqack.head.flags &= ~USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; + } + + resp.reqack.head.flags = 0; + resp.reqack.result = ret; + if (ret >= 0) + { + resp.valuelen = sizeof(value); + } + else + { + resp.valuelen = 0; + } + + /* Send response. */ + + wlen = write(fd, &resp, sizeof(resp)); + if (wlen < 0) + return -errno; + if (wlen != sizeof(resp)) + return -ENOSPC; + + if (resp.valuelen > 0) + { + /* Send address (value) */ + + wlen = write(fd, &value, resp.valuelen); + if (wlen < 0) + return -errno; + if (wlen != resp.valuelen) + return -ENOSPC; + } + + return OK; +} + +static int getsockname_request(int fd, FAR struct daemon_priv_s *priv, + FAR void *hdrbuf) +{ + DEBUGASSERT(priv); + DEBUGASSERT(hdrbuf); + FAR struct usrsock_request_getsockname_s *req = hdrbuf; + FAR struct test_socket_s *tsock; + struct usrsock_message_datareq_ack_s resp = {}; + ssize_t wlen; + int ret = 0; + struct sockaddr_in addr; + + /* Check if this socket exists. */ + + tsock = test_socket_get(priv, req->usockid); + if (!tsock) + { + ret = -EBADFD; + goto prepare; + } + + ret = inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(12345); + ret = ret == 1 ? 0 : -EINVAL; + +prepare: + /* Prepare response. */ + + resp.reqack.xid = req->head.xid; + resp.reqack.head.msgid = USRSOCK_MESSAGE_RESPONSE_DATA_ACK; + resp.reqack.head.flags = 0; + + if (priv->conf->delay_all_responses) + { + resp.reqack.head.flags = USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; + resp.reqack.result = -EINPROGRESS; + resp.valuelen = 0; + resp.valuelen_nontrunc = 0; + + /* Send ack response. */ + + wlen = write(fd, &resp, sizeof(resp)); + if (wlen < 0) + return -errno; + if (wlen != sizeof(resp)) + return -ENOSPC; + + pthread_mutex_unlock(&daemon_mutex); + usleep(50 * 1000); + pthread_mutex_lock(&daemon_mutex); + + /* Previous write was acknowledgment to request, informing that request + * is still in progress. Now write actual completion response. */ + + resp.reqack.head.msgid = USRSOCK_MESSAGE_RESPONSE_DATA_ACK; + resp.reqack.head.flags &= ~USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; + } + + resp.reqack.head.flags = 0; + resp.reqack.result = ret; + if (ret >= 0) + { + resp.valuelen = sizeof(addr); + resp.valuelen_nontrunc = sizeof(addr); + if (resp.valuelen > req->max_addrlen) + resp.valuelen = req->max_addrlen; + } + else + { + resp.valuelen = 0; + resp.valuelen_nontrunc = 0; + } + + /* Send response. */ + + wlen = write(fd, &resp, sizeof(resp)); + if (wlen < 0) + return -errno; + if (wlen != sizeof(resp)) + return -ENOSPC; + + if (resp.valuelen > 0) + { + /* Send address (value) */ + + wlen = write(fd, &addr, resp.valuelen); + if (wlen < 0) + return -errno; + if (wlen != resp.valuelen) + return -ENOSPC; + } + + return OK; +} + +static int handle_usrsock_request(int fd, FAR struct daemon_priv_s *priv) +{ + static const struct { + unsigned int hdrlen; + int (*fn)(int fd, FAR struct daemon_priv_s *priv, FAR void *req); + } handlers[USRSOCK_REQUEST__MAX] = + { + [USRSOCK_REQUEST_SOCKET] = + { + sizeof(struct usrsock_request_socket_s), + socket_request, + }, + [USRSOCK_REQUEST_CLOSE] = + { + sizeof(struct usrsock_request_close_s), + close_request, + }, + [USRSOCK_REQUEST_CONNECT] = + { + sizeof(struct usrsock_request_connect_s), + connect_request, + }, + [USRSOCK_REQUEST_SENDTO] = + { + sizeof(struct usrsock_request_sendto_s), + sendto_request, + }, + [USRSOCK_REQUEST_RECVFROM] = + { + sizeof(struct usrsock_request_recvfrom_s), + recvfrom_request, + }, + [USRSOCK_REQUEST_SETSOCKOPT] = + { + sizeof(struct usrsock_request_setsockopt_s), + setsockopt_request, + }, + [USRSOCK_REQUEST_GETSOCKOPT] = + { + sizeof(struct usrsock_request_getsockopt_s), + getsockopt_request, + }, + [USRSOCK_REQUEST_GETSOCKNAME] = + { + sizeof(struct usrsock_request_getsockname_s), + getsockname_request, + }, + }; + uint8_t hdrbuf[16]; + struct usrsock_request_common_s *common_hdr = (void *)hdrbuf; + ssize_t rlen; + + rlen = read(fd, common_hdr, sizeof(*common_hdr)); + if (rlen < 0) + return -errno; + if (rlen != sizeof(*common_hdr)) + return -EMSGSIZE; + + if (common_hdr->reqid >= USRSOCK_REQUEST__MAX || + !handlers[common_hdr->reqid].fn) + { + dbg("Unknown request type: %d\n", common_hdr->reqid); + return -EIO; + } + + assert(handlers[common_hdr->reqid].hdrlen < sizeof(hdrbuf)); + + rlen = read_req(fd, common_hdr, hdrbuf, handlers[common_hdr->reqid].hdrlen); + if (rlen < 0) + return rlen; + + return handlers[common_hdr->reqid].fn(fd, priv, hdrbuf); +} + +static int unblock_sendto(int fd, FAR struct daemon_priv_s *priv, + FAR struct test_socket_s *tsock) +{ + if (tsock->block_send) + { + int ret; + + tsock->block_send = false; + + ret = tsock_send_event(fd, priv, tsock, USRSOCK_EVENT_SENDTO_READY); + if (ret < 0) + return ret; + } + + return OK; +} + +static int reset_recv_avail(int fd, FAR struct daemon_priv_s *priv, + FAR struct test_socket_s *tsock) +{ + if (tsock->recv_avail_bytes == 0) + { + int ret; + + priv->sockets_recv_empty--; + + tsock->recv_avail_bytes = priv->conf->endpoint_recv_avail; + + ret = tsock_send_event(fd, priv, tsock, + USRSOCK_EVENT_RECVFROM_AVAIL); + if (ret < 0) + return ret; + } + + return OK; +} + +static int disconnect_connection(int fd, FAR struct daemon_priv_s *priv, + FAR struct test_socket_s *tsock) +{ + if (tsock->connected) + { + int ret; + + tsock->disconnected = true; + tsock->connected = false; + + priv->sockets_connected--; + priv->sockets_remote_disconnected++; + + ret = tsock_send_event(fd, priv, tsock, USRSOCK_EVENT_REMOTE_CLOSED); + if (ret < 0) + return ret; + } + + return OK; +} + +static int establish_blocked_connection(int fd, FAR struct daemon_priv_s *priv, + FAR struct test_socket_s *tsock) +{ + if (tsock->blocked_connect) + { + FAR struct usrsock_message_req_ack_s *resp = &tsock->pending_resp; + ssize_t wlen; + int events; + + if (resp->result == OK) + { + priv->sockets_connected++; + tsock->connected = true; + } + + tsock->blocked_connect = false; + + priv->sockets_waiting_connect--; + resp->head.flags &= ~USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; + + wlen = write(fd, resp, sizeof(*resp)); + if (wlen < 0) + return -errno; + if (wlen != sizeof(*resp)) + return -ENOSPC; + + events = 0; + if (!tsock->block_send) + events |= USRSOCK_EVENT_SENDTO_READY; + if (tsock->recv_avail_bytes > 0) + events |= USRSOCK_EVENT_RECVFROM_AVAIL; + + if (events) + { + wlen = tsock_send_event(fd, priv, tsock, events); + if (wlen < 0) + return wlen; + } + } + + return OK; +} + +static int fail_blocked_connection(int fd, FAR struct daemon_priv_s *priv, + FAR struct test_socket_s *tsock) +{ + if (tsock->blocked_connect) + { + FAR struct usrsock_message_req_ack_s *resp = &tsock->pending_resp; + ssize_t wlen; + + resp->result = -ECONNREFUSED; + priv->sockets_not_connected_refused++; + tsock->connect_refused = true; + tsock->blocked_connect = false; + + priv->sockets_waiting_connect--; + resp->head.flags &= ~USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; + + wlen = write(fd, resp, sizeof(*resp)); + if (wlen < 0) + return -errno; + if (wlen != sizeof(*resp)) + return -ENOSPC; + } + + return OK; +} + +static int for_each_connection(int fd, FAR struct daemon_priv_s *priv, + int (*iter_fn)( + int fd, + FAR struct daemon_priv_s *priv, + FAR struct test_socket_s *tsock)) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(priv->test_sockets); i++) + { + FAR struct test_socket_s *tsock = &priv->test_sockets[i]; + + if (tsock->opened) + { + int ret = iter_fn(fd, priv, tsock); + if (ret < 0) + return ret; + } + } + + return OK; +} + +static FAR void *usrsocktest_daemon(FAR void *param) +{ + FAR struct daemon_priv_s *priv = param; + bool stopped; + int ret; + int fd; + + dbg("\n"); + + priv->sockets_active = 0; + + fd = open("/dev/usrsock", O_RDWR); + if (fd < 0) + { + ret = -errno; + goto errout; + } + + do + { + struct pollfd pfd[2] = {}; + int npfds = 0; + int usrsock_pfdpos = -1; + int pipe_pdfpos = -1; + + stopped = false; + + /* Wait for request from kernel side. */ + + pthread_mutex_lock(&daemon_mutex); + if (!priv->do_not_poll_usrsock && fd >= 0) + { + pfd[npfds].fd = fd; + pfd[npfds].events = POLLIN; + usrsock_pfdpos = npfds++; + } + pfd[npfds].fd = priv->pipefd[0]; + pfd[npfds].events = POLLIN; + pipe_pdfpos = npfds++; + pthread_mutex_unlock(&daemon_mutex); + + ret = poll(pfd, npfds, -1); + if (ret < 0) + { + /* Error? */ + ret = -errno; + goto errout; + } + + if (usrsock_pfdpos >= 0 && (pfd[usrsock_pfdpos].revents & POLLIN)) + { + pthread_mutex_lock(&daemon_mutex); + ret = handle_usrsock_request(fd, priv); + pthread_mutex_unlock(&daemon_mutex); + if (ret < 0) + goto errout; + } + + if (pipe_pdfpos >= 0 && (pfd[pipe_pdfpos].revents & POLLIN)) + { + char in; + + if (read(pfd[pipe_pdfpos].fd, &in, 1) == 1) + { + pthread_mutex_lock(&daemon_mutex); + + switch (in) + { + case 'S': + stopped = true; + ret = 0; + break; + case 's': + stopped = false; + ret = 0; + break; + case 'E': + ret = for_each_connection(fd, priv, + &establish_blocked_connection); + break; + case 'F': + ret = for_each_connection(fd, priv, + &fail_blocked_connection); + break; + case 'D': + ret = for_each_connection(fd, priv, + &disconnect_connection); + break; + case 'W': + ret = for_each_connection(fd, priv, + &unblock_sendto); + break; + case 'r': + ret = for_each_connection(fd, priv, + &reset_recv_avail); + break; + case 'K': + /* Kill usrsockdev */ + if (fd >= 0) + { + close(fd); + fd = -1; + } + break; + case '*': + sem_post(&priv->wakewaitsem); + break; /* woke thread. */ + } + + pthread_mutex_unlock(&daemon_mutex); + + if (ret < 0) + goto errout; + } + } + + usleep(1); + } + while (!stopped); + + ret = OK; +errout: + if (fd >= 0) + { + close(fd); + } + + dbg("ret: %d\n", ret); + + return (FAR void *)(intptr_t)ret; +} + +static int get_daemon_value(FAR struct daemon_priv_s *priv, + FAR void *dst, FAR const void *src, size_t len) +{ + int ret = 0; + + if ((uintptr_t)src < (uintptr_t)priv || + (uintptr_t)src >= (uintptr_t)priv + sizeof(*priv) || len <= 0) + { + /* Not daemon value */ + + return -EINVAL; + } + + pthread_mutex_lock(&daemon_mutex); + + if (priv->conf == NULL) + { + /* Not running? */ + + ret = -ENODEV; + goto out; + } + + memmove(dst, src, len); + +out: + pthread_mutex_unlock(&daemon_mutex); + + return ret; +} + +static void *delayed_cmd_thread(void *priv) +{ + FAR struct delayed_cmd_s *cmd = priv; + + if (cmd->delay_msec) + sem_post(&cmd->startsem); + + usleep(cmd->delay_msec * 1000); + + (void)write(cmd->pipefd, &cmd->cmd, 1); + + if (!cmd->delay_msec) + sem_post(&cmd->startsem); + + return NULL; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int usrsocktest_daemon_start(const struct usrsocktest_daemon_conf_s *conf) +{ + FAR struct daemon_priv_s *priv = &daemon; + pthread_attr_t attr; + int ret; + + dbg("\n"); + + pthread_mutex_lock(&daemon_mutex); + + if (priv->conf != NULL || !priv->joined) + { + /* Already running? */ + + ret = -EALREADY; + goto out; + } + + /* Clear daemon private data. */ + + memset(priv, 0, sizeof(*priv)); + + /* Allocate pipe for daemon commands. */ + + ret = pipe(priv->pipefd); + if (ret != OK) + { + ret = -errno; + goto out; + } + + ret = pthread_attr_init(&attr); + if (ret != OK) + { + ret = -ret; + goto errout_closepipe; + } + + sem_init(&priv->wakewaitsem, 0, 0); + + priv->joined = false; + priv->conf = conf; + + ret = pthread_create(&priv->tid, &attr, usrsocktest_daemon, priv); + if (ret != OK) + { + sem_destroy(&priv->wakewaitsem); + priv->joined = true; + priv->conf = NULL; + ret = -ret; + goto errout_closepipe; + } + +errout_closepipe: + if (ret != OK) + { + close(priv->pipefd[0]); + close(priv->pipefd[1]); + } +out: + pthread_mutex_unlock(&daemon_mutex); + dbg("ret: %d\n", ret); + return ret; +} + +int usrsocktest_daemon_stop(void) +{ + FAR struct daemon_priv_s *priv = &daemon; + FAR struct delayed_cmd_s *item, *next; + FAR pthread_addr_t retval; + char stopped; + int ret; + int i; + + dbg("\n"); + + pthread_mutex_lock(&daemon_mutex); + + if (priv->conf == NULL) + { + /* Not running? */ + + ret = -ENODEV; + goto out; + } + + item = (void *)sq_peek(&priv->delayed_cmd_threads); + while (item) + { + next = (void *)sq_next(&item->node); + + pthread_mutex_unlock(&daemon_mutex); + (void)pthread_join(item->tid, &retval); + pthread_mutex_lock(&daemon_mutex); + sq_rem(&item->node, &priv->delayed_cmd_threads); + free(item); + usrsocktest_dcmd_malloc_cnt--; + + item = next; + } + + pthread_mutex_unlock(&daemon_mutex); + stopped = 'S'; + write(priv->pipefd[1], &stopped, 1); + + ret = pthread_join(priv->tid, &retval); + pthread_mutex_lock(&daemon_mutex); + if (ret != OK) + { + ret = -ret; + goto out; + } + + for (i = 0; i < ARRAY_SIZE(priv->test_sockets); i++) + { + if (priv->test_sockets[i].opened && priv->test_sockets[i].endp != NULL) + { + free(priv->test_sockets[i].endp); + priv->test_sockets[i].endp = NULL; + usrsocktest_endp_malloc_cnt--; + } + } + + priv->conf = NULL; + close(priv->pipefd[0]); + close(priv->pipefd[1]); + sem_destroy(&priv->wakewaitsem); + + priv->joined = true; + ret = (intptr_t)retval; + +out: + pthread_mutex_unlock(&daemon_mutex); + dbg("ret: %d\n", ret); + return ret; +} + +int usrsocktest_daemon_get_num_active_sockets(void) +{ + FAR struct daemon_priv_s *priv = &daemon; + int ret, err; + + err = get_daemon_value(priv, &ret, &priv->sockets_active, sizeof(ret)); + if (err < 0) + return err; + + return ret; +} + +int usrsocktest_daemon_get_num_connected_sockets(void) +{ + FAR struct daemon_priv_s *priv = &daemon; + int ret, err; + + err = get_daemon_value(priv, &ret, &priv->sockets_connected, sizeof(ret)); + if (err < 0) + return err; + + return ret; +} + +int usrsocktest_daemon_get_num_waiting_connect_sockets(void) +{ + FAR struct daemon_priv_s *priv = &daemon; + int ret, err; + + err = get_daemon_value(priv, &ret, &priv->sockets_waiting_connect, sizeof(ret)); + if (err < 0) + return err; + + return ret; +} + +int usrsocktest_daemon_get_num_recv_empty_sockets(void) +{ + FAR struct daemon_priv_s *priv = &daemon; + int ret, err; + + err = get_daemon_value(priv, &ret, &priv->sockets_recv_empty, sizeof(ret)); + if (err < 0) + return err; + + return ret; +} + +ssize_t usrsocktest_daemon_get_send_bytes(void) +{ + FAR struct daemon_priv_s *priv = &daemon; + size_t ret; + int err; + + err = get_daemon_value(priv, &ret, &priv->total_send_bytes, sizeof(ret)); + if (err < 0) + return err; + + return ret; +} + +ssize_t usrsocktest_daemon_get_recv_bytes(void) +{ + FAR struct daemon_priv_s *priv = &daemon; + size_t ret; + int err; + + err = get_daemon_value(priv, &ret, &priv->total_recv_bytes, sizeof(ret)); + if (err < 0) + return err; + + return ret; +} + +int usrsocktest_daemon_get_num_unreachable_sockets(void) +{ + FAR struct daemon_priv_s *priv = &daemon; + int ret, err; + + err = get_daemon_value(priv, &ret, &priv->sockets_not_connected_refused, sizeof(ret)); + if (err < 0) + return err; + + return ret; +} + +int usrsocktest_daemon_get_num_remote_disconnected_sockets(void) +{ + FAR struct daemon_priv_s *priv = &daemon; + int ret, err; + + err = get_daemon_value(priv, &ret, &priv->sockets_remote_disconnected, sizeof(ret)); + if (err < 0) + return err; + + return ret; +} + +int usrsocktest_daemon_pause_usrsock_handling(bool pause) +{ + FAR struct daemon_priv_s *priv = &daemon; + int ret; + char cmd = '*'; + + pthread_mutex_lock(&daemon_mutex); + + if (priv->conf == NULL) + { + /* Not running? */ + + pthread_mutex_unlock(&daemon_mutex); + return -ENODEV; + } + + priv->do_not_poll_usrsock = pause; + + (void)write(priv->pipefd[1], &cmd, 1); + ret = OK; + + pthread_mutex_unlock(&daemon_mutex); + + sem_wait(&priv->wakewaitsem); + + return ret; +} + +bool usrsocktest_send_delayed_command(const char cmd, unsigned int delay_msec) +{ + FAR struct daemon_priv_s *priv = &daemon; + pthread_attr_t attr; + FAR struct delayed_cmd_s *delayed_cmd; + int ret; + + if (priv->conf == NULL) + { + /* Not running? */ + + return false; + } + + delayed_cmd = calloc(1, sizeof(*delayed_cmd)); + if (!delayed_cmd) + { + return false; + } + + usrsocktest_dcmd_malloc_cnt++; + + delayed_cmd->delay_msec = delay_msec; + delayed_cmd->cmd = cmd; + delayed_cmd->pipefd = priv->pipefd[1]; + (void)sem_init(&delayed_cmd->startsem, 0, 0); + + ret = pthread_attr_init(&attr); + if (ret != OK) + { + free(delayed_cmd); + usrsocktest_dcmd_malloc_cnt--; + return false; + } + + ret = pthread_create(&delayed_cmd->tid, &attr, delayed_cmd_thread, + delayed_cmd); + if (ret != OK) + { + free(delayed_cmd); + usrsocktest_dcmd_malloc_cnt--; + return false; + } + + while (sem_wait(&delayed_cmd->startsem) != OK); + + sq_addlast(&delayed_cmd->node, &priv->delayed_cmd_threads); + + return true; +} + +bool usrsocktest_daemon_establish_waiting_connections(void) +{ + return usrsocktest_send_delayed_command('E', 0); +} diff --git a/tests/unity_usrsock/wake_with_signal.c b/tests/unity_usrsock/wake_with_signal.c new file mode 100644 index 000000000..2904dc0c7 --- /dev/null +++ b/tests/unity_usrsock/wake_with_signal.c @@ -0,0 +1,1563 @@ +/**************************************************************************** + * apps/examples/unity_usrsock/wake_with_signal.c + * Wake blocked IO with signal or daemon abort + * + * Copyright (C) 2015-2016 Haltian Ltd. All rights reserved. + * Authors: Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +#include "defines.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +#define TEST_FLAG_PAUSE_USRSOCK_HANDLING (1 << 0) +#define TEST_FLAG_DAEMON_ABORT (1 << 1) +#define TEST_FLAG_MULTI_THREAD (1 << 2) + +#define MAX_THREADS 4 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +enum e_test_type +{ + TEST_TYPE_SOCKET = 0, + TEST_TYPE_CLOSE, + TEST_TYPE_CONNECT, + TEST_TYPE_SETSOCKOPT, + TEST_TYPE_GETSOCKOPT, + TEST_TYPE_SEND, + TEST_TYPE_RECV, + TEST_TYPE_POLL, + __TEST_TYPE_MAX, +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static pthread_t tid[MAX_THREADS]; +static sem_t tid_startsem; +static sem_t tid_releasesem; +static int test_sd[MAX_THREADS]; +static enum e_test_type test_type; +static int test_flags; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static FAR void * usrsock_blocking_socket_thread(FAR void *param) +{ + intptr_t tidx = (intptr_t)param; + bool test_abort = !!(test_flags & TEST_FLAG_DAEMON_ABORT); + bool test_hang = !!(test_flags & TEST_FLAG_PAUSE_USRSOCK_HANDLING); + + TEST_ASSERT_TRUE(test_hang); + TEST_ASSERT_TRUE(test_abort); + + /* Allow main thread to hang usrsock daemon at this point. */ + + sem_post(&tid_startsem); + sem_wait(&tid_releasesem); + + /* Attempt hanging open socket. */ + + sem_post(&tid_startsem); + test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_EQUAL(-1, test_sd[tidx]); + TEST_ASSERT_EQUAL(ENETDOWN, errno); + + return NULL; +} + +static FAR void * usrsock_blocking_close_thread(FAR void *param) +{ + intptr_t tidx = (intptr_t)param; + struct sockaddr_in addr; + int ret; + bool test_abort = !!(test_flags & TEST_FLAG_DAEMON_ABORT); + bool test_hang = !!(test_flags & TEST_FLAG_PAUSE_USRSOCK_HANDLING); + + TEST_ASSERT_TRUE(test_hang); + TEST_ASSERT_TRUE(test_abort); + + /* Open socket. */ + + test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(test_sd[tidx] >= 0); + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + + /* Allow main thread to hang usrsock daemon at this point. */ + + sem_post(&tid_startsem); + sem_wait(&tid_releasesem); + + /* Attempt hanging close socket. */ + + sem_post(&tid_startsem); + ret = close(test_sd[tidx]); + TEST_ASSERT_EQUAL(0, ret); + test_sd[tidx] = -1; + + return NULL; +} + +static FAR void * usrsock_blocking_connect_thread(FAR void *param) +{ + intptr_t tidx = (intptr_t)param; + struct sockaddr_in addr; + int ret; + bool test_abort = !!(test_flags & TEST_FLAG_DAEMON_ABORT); + bool test_hang = !!(test_flags & TEST_FLAG_PAUSE_USRSOCK_HANDLING); + + TEST_ASSERT_TRUE(test_hang || !test_hang); + + /* Open socket. */ + + test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(test_sd[tidx] >= 0); + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + + /* Allow main thread to hang usrsock daemon at this point. */ + + sem_post(&tid_startsem); + sem_wait(&tid_releasesem); + + /* Attempt blocking connect. */ + + sem_post(&tid_startsem); + ret = connect(test_sd[tidx], (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(test_abort ? ECONNABORTED : EINTR, errno); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(test_sd[tidx]) >= 0); + test_sd[tidx] = -1; + + return NULL; +} + +static FAR void * usrsock_blocking_setsockopt_thread(FAR void *param) +{ + intptr_t tidx = (intptr_t)param; + struct sockaddr_in addr; + int ret; + int value; + bool test_abort = !!(test_flags & TEST_FLAG_DAEMON_ABORT); + bool test_hang = !!(test_flags & TEST_FLAG_PAUSE_USRSOCK_HANDLING); + + /* Open socket. */ + + test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(test_sd[tidx] >= 0); + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + + TEST_ASSERT_TRUE(test_hang); + TEST_ASSERT_TRUE(test_abort); + + /* Allow main thread to hang usrsock daemon at this point. */ + + sem_post(&tid_startsem); + sem_wait(&tid_releasesem); + + /* Attempt hanging setsockopt. */ + + sem_post(&tid_startsem); + value = 1; + ret = setsockopt(test_sd[tidx], SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value)); + TEST_ASSERT_EQUAL(-1, ret); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(test_sd[tidx]) >= 0); + test_sd[tidx] = -1; + + return NULL; +} + +static FAR void * usrsock_blocking_getsockopt_thread(FAR void *param) +{ + intptr_t tidx = (intptr_t)param; + struct sockaddr_in addr; + int ret; + int value; + socklen_t valuelen; + bool test_abort = !!(test_flags & TEST_FLAG_DAEMON_ABORT); + bool test_hang = !!(test_flags & TEST_FLAG_PAUSE_USRSOCK_HANDLING); + + /* Open socket. */ + + test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(test_sd[tidx] >= 0); + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + + TEST_ASSERT_TRUE(test_hang); + TEST_ASSERT_TRUE(test_abort); + + /* Allow main thread to hang usrsock daemon at this point. */ + + sem_post(&tid_startsem); + sem_wait(&tid_releasesem); + + /* Attempt hanging getsockopt. */ + + sem_post(&tid_startsem); + value = -1; + valuelen = sizeof(value); + ret = getsockopt(test_sd[tidx], SOL_SOCKET, SO_REUSEADDR, &value, &valuelen); + TEST_ASSERT_EQUAL(-1, ret); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(test_sd[tidx]) >= 0); + test_sd[tidx] = -1; + + return NULL; +} + +static FAR void * usrsock_blocking_send_thread(FAR void *param) +{ + intptr_t tidx = (intptr_t)param; + struct sockaddr_in addr; + int ret; + bool test_abort = !!(test_flags & TEST_FLAG_DAEMON_ABORT); + bool test_hang = !!(test_flags & TEST_FLAG_PAUSE_USRSOCK_HANDLING); + + TEST_ASSERT_TRUE(test_hang || !test_hang); + + /* Open socket. */ + + test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(test_sd[tidx] >= 0); + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + + /* Connect socket. */ + + ret = connect(test_sd[tidx], (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(0, ret); + + /* Allow main thread to hang usrsock daemon at this point. */ + + sem_post(&tid_startsem); + sem_wait(&tid_releasesem); + + /* Attempt blocking send. */ + + sem_post(&tid_startsem); + ret = send(test_sd[tidx], &addr, sizeof(addr), 0); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(test_abort ? EPIPE : EINTR, errno); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(test_sd[tidx]) >= 0); + test_sd[tidx] = -1; + + return NULL; +} + +static FAR void * usrsock_blocking_recv_thread(FAR void *param) +{ + intptr_t tidx = (intptr_t)param; + struct sockaddr_in addr; + int ret; + bool test_abort = !!(test_flags & TEST_FLAG_DAEMON_ABORT); + bool test_hang = !!(test_flags & TEST_FLAG_PAUSE_USRSOCK_HANDLING); + + TEST_ASSERT_TRUE(test_hang || !test_hang); + + /* Open socket. */ + + test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(test_sd[tidx] >= 0); + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + + /* Connect socket. */ + + ret = connect(test_sd[tidx], (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(0, ret); + + /* Allow main thread to hang usrsock daemon at this point. */ + + sem_post(&tid_startsem); + sem_wait(&tid_releasesem); + + /* Attempt blocking recv. */ + + sem_post(&tid_startsem); + ret = recv(test_sd[tidx], &addr, sizeof(addr), 0); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(test_abort ? EPIPE : EINTR, errno); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(test_sd[tidx]) >= 0); + test_sd[tidx] = -1; + + return NULL; +} + +static FAR void * usrsock_blocking_poll_thread(FAR void *param) +{ + intptr_t tidx = (intptr_t)param; + struct sockaddr_in addr; + int ret; + struct pollfd pfd = {}; + bool test_abort = !!(test_flags & TEST_FLAG_DAEMON_ABORT); + bool test_hang = !!(test_flags & TEST_FLAG_PAUSE_USRSOCK_HANDLING); + + TEST_ASSERT_TRUE(test_abort); + TEST_ASSERT_TRUE(test_hang || !test_hang); + + /* Open socket. */ + + test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); + TEST_ASSERT_TRUE(test_sd[tidx] >= 0); + + inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(255); + + /* Connect socket. */ + + ret = connect(test_sd[tidx], (FAR const struct sockaddr *)&addr, sizeof(addr)); + TEST_ASSERT_EQUAL(0, ret); + + /* Allow main thread to hang usrsock daemon at this point. */ + + sem_post(&tid_startsem); + sem_wait(&tid_releasesem); + + /* Attempt poll. */ + + pfd.fd = test_sd[tidx]; + pfd.events = POLLIN; + + sem_post(&tid_startsem); + ret = poll(&pfd, 1, -1); + TEST_ASSERT_EQUAL(1, ret); + TEST_ASSERT_EQUAL(POLLERR | POLLHUP, pfd.revents); + + /* Attempt read from aborted socket */ + + ret = recv(test_sd[tidx], &addr, sizeof(addr), 0); + TEST_ASSERT_EQUAL(-1, ret); + TEST_ASSERT_EQUAL(EPIPE, errno); + + /* Close socket */ + + TEST_ASSERT_TRUE(close(test_sd[tidx]) >= 0); + test_sd[tidx] = -1; + + return NULL; +} + +static void do_wake_test(enum e_test_type type, int flags) +{ + static const struct + { + pthread_startroutine_t fn; + bool stop_only_on_hang; + } thread_funcs[__TEST_TYPE_MAX] = + { + [TEST_TYPE_SOCKET] = { usrsock_blocking_socket_thread, false }, + [TEST_TYPE_CLOSE] = { usrsock_blocking_close_thread, false }, + [TEST_TYPE_CONNECT] = { usrsock_blocking_connect_thread, true }, + [TEST_TYPE_SETSOCKOPT] = { usrsock_blocking_setsockopt_thread, false }, + [TEST_TYPE_GETSOCKOPT] = { usrsock_blocking_getsockopt_thread, false }, + [TEST_TYPE_RECV] = { usrsock_blocking_recv_thread, true }, + [TEST_TYPE_SEND] = { usrsock_blocking_send_thread, true }, + [TEST_TYPE_POLL] = { usrsock_blocking_poll_thread, true }, + }; + int ret; + int nthreads = (flags & TEST_FLAG_MULTI_THREAD) ? MAX_THREADS : 1; + int tidx; + bool test_abort = !!(flags & TEST_FLAG_DAEMON_ABORT); + bool test_hang = !!(flags & TEST_FLAG_PAUSE_USRSOCK_HANDLING); + + /* Start test daemon. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config)); + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); + + /* Launch worker threads. */ + + test_type = type; + test_flags = flags; + for (tidx = 0; tidx < nthreads; tidx++) + { + ret = pthread_create(&tid[tidx], NULL, thread_funcs[type].fn, + (pthread_addr_t)(intptr_t)tidx); + TEST_ASSERT_EQUAL(OK, ret); + } + +/* Let workers to start. */ + + for (tidx = 0; tidx < nthreads; tidx++) + { + sem_wait(&tid_startsem); + } + + if (test_hang || !thread_funcs[type].stop_only_on_hang) + { + TEST_ASSERT_EQUAL(0, usrsocktest_daemon_pause_usrsock_handling(true)); + } + + for (tidx = 0; tidx < nthreads; tidx++) + { + sem_post(&tid_releasesem); + } + for (tidx = 0; tidx < nthreads; tidx++) + { + sem_wait(&tid_startsem); + } + + usleep(100 * USEC_PER_MSEC); /* Let worker thread proceed to blocking + * function. */ + + if (!test_abort) + { + /* Wake waiting thread with signal. */ + + /* Send signal to task to break out from blocking send. */ + + for (tidx = 0; tidx < nthreads; tidx++) + { + pthread_kill(tid[tidx], 1); + + /* Wait threads to complete work. */ + + ret = pthread_join(tid[tidx], NULL); + TEST_ASSERT_EQUAL(OK, ret); + tid[tidx] = -1; + } + TEST_ASSERT_FALSE(Unity.CurrentTestFailed); + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); + } + else + { + /* Wake waiting thread with daemon abort. */ + + /* Stopping daemon should succeed. */ + + TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); + TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); + TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); + + /* Wait threads to complete work. */ + + for (tidx = 0; tidx < nthreads; tidx++) + { + ret = pthread_join(tid[tidx], NULL); + TEST_ASSERT_EQUAL(OK, ret); + tid[tidx] = -1; + } + TEST_ASSERT_FALSE(Unity.CurrentTestFailed); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +TEST_GROUP(WakeWithSignal); + +/**************************************************************************** + * Name: WakeWithSignal test group setup + * + * Description: + * Setup function executed before each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_SETUP(WakeWithSignal) +{ + int i; + + for (i = 0; i < MAX_THREADS; i++) + { + tid[i] = -1; + test_sd[i] = -1; + } + sem_init(&tid_startsem, 0, 0); + sem_init(&tid_releasesem, 0, 0); +} + +/**************************************************************************** + * Name: WakeWithSignal test group teardown + * + * Description: + * Setup function executed after each testcase in this test group + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST_TEAR_DOWN(WakeWithSignal) +{ + int ret; + int i; + + for (i = 0; i < MAX_THREADS; i++) + { + if (tid[i] != -1) + { + ret = pthread_cancel(tid[i]); + assert(ret == OK); + ret = pthread_join(tid[i], NULL); + assert(ret == OK); + } + if (test_sd[i] != -1) + { + close(test_sd[i]); + test_sd[i] = -1; + } + } + sem_destroy(&tid_startsem); + sem_destroy(&tid_releasesem); +} + +/**************************************************************************** + * Name: WakeBlockingConnect + * + * Description: + * Wake blocking connect with signal + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, WakeBlockingConnect) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = true; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_CONNECT, 0); +} + +/**************************************************************************** + * Name: WakeBlockingConnectMultiThread + * + * Description: + * Wake multiple blocking connect with signal + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, WakeBlockingConnectMultiThread) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = true; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_CONNECT, TEST_FLAG_MULTI_THREAD); +} + +/**************************************************************************** + * Name: WakeBlockingSend + * + * Description: + * Wake blocking send with signal + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, WakeBlockingSend) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = false; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_SEND, 0); +} + +/**************************************************************************** + * Name: WakeBlockingSendMultiThread + * + * Description: + * Wake multiple blocking send with signal + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, WakeBlockingSendMultiThread) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = false; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_SEND, TEST_FLAG_MULTI_THREAD); +} +/**************************************************************************** + * Name: WakeBlockingRecv + * + * Description: + * Wake blocking recv with signal + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, WakeBlockingRecv) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = false; + usrsocktest_daemon_config.endpoint_block_connect = false; + usrsocktest_daemon_config.endpoint_recv_avail = 0; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_RECV, 0); +} + +/**************************************************************************** + * Name: WakeBlockingRecvMultiThread + * + * Description: + * Wake multiple blocking recv with signal + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, WakeBlockingRecvMultiThread) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = false; + usrsocktest_daemon_config.endpoint_block_connect = false; + usrsocktest_daemon_config.endpoint_recv_avail = 0; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_RECV, TEST_FLAG_MULTI_THREAD); +} + +/**************************************************************************** + * Name: AbortBlockingConnect + * + * Description: + * Wake blocking connect with daemon abort + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, AbortBlockingConnect) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = true; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_CONNECT, TEST_FLAG_DAEMON_ABORT); +} + +/**************************************************************************** + * Name: AbortBlockingConnectMultiThread + * + * Description: + * Wake multiple blocking connect with daemon abort + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, AbortBlockingConnectMultiThread) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = true; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_CONNECT, + TEST_FLAG_DAEMON_ABORT | TEST_FLAG_MULTI_THREAD); +} + +/**************************************************************************** + * Name: AbortBlockingSend + * + * Description: + * Wake blocking send with daemon abort + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, AbortBlockingSend) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = false; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_SEND, TEST_FLAG_DAEMON_ABORT); +} + +/**************************************************************************** + * Name: AbortBlockingSendMultiThread + * + * Description: + * Wake multiple blocking send with daemon abort + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, AbortBlockingSendMultiThread) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = false; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_SEND, + TEST_FLAG_DAEMON_ABORT | TEST_FLAG_MULTI_THREAD); +} + +/**************************************************************************** + * Name: AbortBlockingRecv + * + * Description: + * Wake blocking recv with daemon abort + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, AbortBlockingRecv) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = false; + usrsocktest_daemon_config.endpoint_block_connect = false; + usrsocktest_daemon_config.endpoint_recv_avail = 0; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_RECV, TEST_FLAG_DAEMON_ABORT); +} + +/**************************************************************************** + * Name: AbortBlockingRecvMultiThread + * + * Description: + * Wake multiple blocking recv with daemon abort + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, AbortBlockingRecvMultiThread) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = false; + usrsocktest_daemon_config.endpoint_block_connect = false; + usrsocktest_daemon_config.endpoint_recv_avail = 0; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_RECV, + TEST_FLAG_DAEMON_ABORT | TEST_FLAG_MULTI_THREAD); +} + +/**************************************************************************** + * Name: PendingRequestBlockingConnect + * + * Description: + * Wake blocking connect with daemon abort (and daemon not handling pending + * request before abort) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, PendingRequestBlockingConnect) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = true; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_CONNECT, + TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING); +} + +/**************************************************************************** + * Name: PendingRequestBlockingConnectMultiThread + * + * Description: + * Wake multiple blocking connect with daemon abort (and daemon not handling + * pending requests before abort) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, PendingRequestBlockingConnectMultiThread) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = true; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_CONNECT, + TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING | + TEST_FLAG_MULTI_THREAD); +} + +/**************************************************************************** + * Name: PendingRequestBlockingSend + * + * Description: + * Wake blocking send with daemon abort (and daemon not handling pending + * request before abort) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, PendingRequestBlockingSend) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = false; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_SEND, + TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING); +} + +/**************************************************************************** + * Name: PendingRequestBlockingSendMultiThread + * + * Description: + * Wake multiple blocking send with daemon abort (and daemon not handling + * pending requests before abort) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, PendingRequestBlockingSendMultiThread) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = false; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_SEND, + TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING | + TEST_FLAG_MULTI_THREAD); +} + +/**************************************************************************** + * Name: PendingRequestBlockingRecv + * + * Description: + * Wake blocking recv with daemon abort (and daemon not handling pending + * request before abort) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, PendingRequestBlockingRecv) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = false; + usrsocktest_daemon_config.endpoint_block_connect = false; + usrsocktest_daemon_config.endpoint_recv_avail = 0; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_RECV, + TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING); +} + +/**************************************************************************** + * Name: PendingRequestBlockingRecvMultiThread + * + * Description: + * Wake multiple blocking recv with daemon abort (and daemon not handling + * pending requests before abort) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, PendingRequestBlockingRecvMultiThread) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = false; + usrsocktest_daemon_config.endpoint_block_connect = false; + usrsocktest_daemon_config.endpoint_recv_avail = 0; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_RECV, + TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING | + TEST_FLAG_MULTI_THREAD); +} + +/**************************************************************************** + * Name: PendingRequestBlockingOpen + * + * Description: + * Wake blocking open with daemon abort (and daemon not handling pending + * request before abort) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, PendingRequestBlockingOpen) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = true; + usrsocktest_daemon_config.endpoint_recv_avail = 0; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_SOCKET, + TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING); +} + +/**************************************************************************** + * Name: PendingRequestBlockingOpenMultiThread + * + * Description: + * Wake multiple blocking open with daemon abort (and daemon not handling + * pending requests before abort) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, PendingRequestBlockingOpenMultiThread) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = true; + usrsocktest_daemon_config.endpoint_recv_avail = 0; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_SOCKET, + TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING | + TEST_FLAG_MULTI_THREAD); +} + +/**************************************************************************** + * Name: PendingRequestBlockingClose + * + * Description: + * Wake blocking close with daemon abort (and daemon not handling pending + * request before abort) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, PendingRequestBlockingClose) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = true; + usrsocktest_daemon_config.endpoint_recv_avail = 0; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_CLOSE, + TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING); +} + +/**************************************************************************** + * Name: PendingRequestBlockingCloseMultiThread + * + * Description: + * Wake multiple blocking close with daemon abort (and daemon not handling + * pending requests before abort) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, PendingRequestBlockingCloseMultiThread) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = true; + usrsocktest_daemon_config.endpoint_recv_avail = 0; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_CLOSE, + TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING | + TEST_FLAG_MULTI_THREAD); +} + +/**************************************************************************** + * Name: PendingRequestBlockingPoll + * + * Description: + * Wake blocking poll with daemon abort (and daemon not handling pending + * request before abort) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, PendingRequestBlockingPoll) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = false; + usrsocktest_daemon_config.endpoint_recv_avail = 0; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_POLL, + TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING); +} + +/**************************************************************************** + * Name: PendingRequestBlockingPollMultiThread + * + * Description: + * Wake multiple blocking poll with daemon abort (and daemon not handling + * pending requests before abort) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, PendingRequestBlockingPollMultiThread) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = false; + usrsocktest_daemon_config.endpoint_recv_avail = 0; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_POLL, + TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING | + TEST_FLAG_MULTI_THREAD); +} + +/**************************************************************************** + * Name: PendingRequestBlockingSetSockOpt + * + * Description: + * Wake blocking setsockopt with daemon abort (and daemon not handling pending + * request before abort) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, PendingRequestBlockingSetSockOpt) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = true; + usrsocktest_daemon_config.endpoint_recv_avail = 0; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_SETSOCKOPT, + TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING); +} + +/**************************************************************************** + * Name: PendingRequestBlockingSetSockOptMultiThread + * + * Description: + * Wake multiple blocking setsockopt with daemon abort (and daemon not + * handling pending requests before abort) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, PendingRequestBlockingSetSockOptMultiThread) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = true; + usrsocktest_daemon_config.endpoint_recv_avail = 0; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_SETSOCKOPT, + TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING | + TEST_FLAG_MULTI_THREAD); +} + +/**************************************************************************** + * Name: PendingRequestBlockingGetSockOpt + * + * Description: + * Wake blocking getsockopt with daemon abort (and daemon not handling pending + * request before abort) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, PendingRequestBlockingGetSockOpt) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = true; + usrsocktest_daemon_config.endpoint_recv_avail = 0; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_GETSOCKOPT, + TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING); +} + +/**************************************************************************** + * Name: PendingRequestBlockingGetSockOptMultiThread + * + * Description: + * Wake multiple blocking getsockopt with daemon abort (and daemon not + * handling pending requests before abort) + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions/Limitations: + * None + * + ****************************************************************************/ +TEST(WakeWithSignal, PendingRequestBlockingGetSockOptMultiThread) +{ + /* Configure test daemon. */ + + usrsocktest_daemon_config = usrsocktest_daemon_defconf; + usrsocktest_daemon_config.delay_all_responses = false; + usrsocktest_daemon_config.endpoint_block_send = true; + usrsocktest_daemon_config.endpoint_block_connect = true; + usrsocktest_daemon_config.endpoint_recv_avail = 0; + usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; + usrsocktest_daemon_config.endpoint_port = 255; + + /* Run test. */ + + do_wake_test(TEST_TYPE_GETSOCKOPT, + TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING | + TEST_FLAG_MULTI_THREAD); +} From 6c28268d67e520e5be9ace533100fe3dc22d3a84 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 31 Mar 2017 15:47:13 -0600 Subject: [PATCH 5/5] Revert "Add Unity test framework with usrsock test-cases" Causes build problems and does not follow the coding style. This reverts commit 87fe31f87a381761243dcf58e038b058d6c2c604. --- include/testing/license.txt | 21 - include/testing/unity.h | 272 --- include/testing/unity_fixture.h | 98 - include/testing/unity_fixture_internals.h | 46 - .../testing/unity_fixture_malloc_overrides.h | 27 - include/testing/unity_internals.h | 693 ------ tests/Kconfig | 11 - tests/Make.defs | 37 - tests/Makefile | 114 - tests/README.txt | 34 - tests/docs/Unity_Summary.txt | 216 -- tests/docs/license.txt | 21 - tests/testing/.built | 0 tests/testing/Kconfig | 4 - tests/testing/Make.defs | 37 - tests/testing/Makefile | 95 - tests/testing/unity.c | 1268 ----------- tests/testing/unity_fixture.c | 466 ---- tests/tools/auto/colour_prompt.rb | 115 - tests/tools/auto/colour_reporter.rb | 39 - tests/tools/auto/generate_config.yml | 36 - tests/tools/auto/generate_module.rb | 202 -- tests/tools/auto/generate_test_runner.rb | 349 --- tests/tools/auto/parseOutput.rb | 189 -- tests/tools/auto/test_file_filter.rb | 23 - tests/tools/auto/type_sanitizer.rb | 8 - tests/tools/auto/unity_test_summary.py | 135 -- tests/tools/auto/unity_test_summary.rb | 139 -- tests/tools/build_fixture_runner.pl | 45 - tests/tools/license.txt | 21 - tests/tools/rename_symbols | 21 - tests/tools/unity_test_summary.rb | 139 -- tests/unity/.gitignore | 11 - tests/unity/Kconfig | 22 - tests/unity/Make.defs | 39 - tests/unity/Makefile | 137 -- tests/unity/main/AllTests.c | 30 - tests/unity/testunity_fixture.c | 39 - tests/unity/unity_fixture_Test.c | 454 ---- tests/unity/unity_fixture_TestRunner.c | 64 - tests/unity/unity_output_Spy.c | 56 - tests/unity/unity_output_Spy.h | 17 - tests/unity_ramtest/.gitignore | 11 - tests/unity_ramtest/Kconfig | 11 - tests/unity_ramtest/Make.defs | 39 - tests/unity_ramtest/Makefile | 146 -- tests/unity_ramtest/addr_in_addr.c | 185 -- tests/unity_ramtest/library.h | 196 -- tests/unity_ramtest/marching_ones.c | 191 -- tests/unity_ramtest/marching_zeroes.c | 193 -- tests/unity_ramtest/pattern.c | 311 --- tests/unity_ramtest/unity_ramtest_main.c | 503 ----- tests/unity_usrsock/.gitignore | 11 - tests/unity_usrsock/Kconfig | 15 - tests/unity_usrsock/Make.defs | 39 - tests/unity_usrsock/Makefile | 152 -- tests/unity_usrsock/basic_connect.c | 465 ---- tests/unity_usrsock/basic_daemon.c | 653 ------ tests/unity_usrsock/basic_getsockname.c | 279 --- tests/unity_usrsock/basic_getsockopt.c | 258 --- tests/unity_usrsock/basic_send.c | 345 --- tests/unity_usrsock/basic_setsockopt.c | 226 -- tests/unity_usrsock/block_recv.c | 497 ----- tests/unity_usrsock/block_send.c | 428 ---- tests/unity_usrsock/chardev.c | 222 -- tests/unity_usrsock/defines.h | 124 -- tests/unity_usrsock/multi_thread.c | 256 --- tests/unity_usrsock/noblock_connect.c | 806 ------- tests/unity_usrsock/noblock_recv.c | 503 ----- tests/unity_usrsock/noblock_send.c | 400 ---- tests/unity_usrsock/nodaemon.c | 148 -- tests/unity_usrsock/poll.c | 632 ------ tests/unity_usrsock/remote_disconnect.c | 1055 --------- tests/unity_usrsock/unity_usrsock_main.c | 161 -- tests/unity_usrsock/usrsocktest_daemon.c | 1930 ----------------- tests/unity_usrsock/wake_with_signal.c | 1563 ------------- 76 files changed, 18744 deletions(-) delete mode 100644 include/testing/license.txt delete mode 100644 include/testing/unity.h delete mode 100644 include/testing/unity_fixture.h delete mode 100644 include/testing/unity_fixture_internals.h delete mode 100644 include/testing/unity_fixture_malloc_overrides.h delete mode 100644 include/testing/unity_internals.h delete mode 100644 tests/Kconfig delete mode 100644 tests/Make.defs delete mode 100644 tests/Makefile delete mode 100644 tests/README.txt delete mode 100644 tests/docs/Unity_Summary.txt delete mode 100644 tests/docs/license.txt delete mode 100644 tests/testing/.built delete mode 100644 tests/testing/Kconfig delete mode 100644 tests/testing/Make.defs delete mode 100644 tests/testing/Makefile delete mode 100644 tests/testing/unity.c delete mode 100644 tests/testing/unity_fixture.c delete mode 100644 tests/tools/auto/colour_prompt.rb delete mode 100644 tests/tools/auto/colour_reporter.rb delete mode 100644 tests/tools/auto/generate_config.yml delete mode 100644 tests/tools/auto/generate_module.rb delete mode 100644 tests/tools/auto/generate_test_runner.rb delete mode 100644 tests/tools/auto/parseOutput.rb delete mode 100644 tests/tools/auto/test_file_filter.rb delete mode 100644 tests/tools/auto/type_sanitizer.rb delete mode 100644 tests/tools/auto/unity_test_summary.py delete mode 100644 tests/tools/auto/unity_test_summary.rb delete mode 100644 tests/tools/build_fixture_runner.pl delete mode 100644 tests/tools/license.txt delete mode 100644 tests/tools/rename_symbols delete mode 100644 tests/tools/unity_test_summary.rb delete mode 100644 tests/unity/.gitignore delete mode 100644 tests/unity/Kconfig delete mode 100644 tests/unity/Make.defs delete mode 100644 tests/unity/Makefile delete mode 100644 tests/unity/main/AllTests.c delete mode 100644 tests/unity/testunity_fixture.c delete mode 100644 tests/unity/unity_fixture_Test.c delete mode 100644 tests/unity/unity_fixture_TestRunner.c delete mode 100644 tests/unity/unity_output_Spy.c delete mode 100644 tests/unity/unity_output_Spy.h delete mode 100644 tests/unity_ramtest/.gitignore delete mode 100644 tests/unity_ramtest/Kconfig delete mode 100644 tests/unity_ramtest/Make.defs delete mode 100644 tests/unity_ramtest/Makefile delete mode 100644 tests/unity_ramtest/addr_in_addr.c delete mode 100644 tests/unity_ramtest/library.h delete mode 100644 tests/unity_ramtest/marching_ones.c delete mode 100644 tests/unity_ramtest/marching_zeroes.c delete mode 100644 tests/unity_ramtest/pattern.c delete mode 100644 tests/unity_ramtest/unity_ramtest_main.c delete mode 100644 tests/unity_usrsock/.gitignore delete mode 100644 tests/unity_usrsock/Kconfig delete mode 100644 tests/unity_usrsock/Make.defs delete mode 100644 tests/unity_usrsock/Makefile delete mode 100644 tests/unity_usrsock/basic_connect.c delete mode 100644 tests/unity_usrsock/basic_daemon.c delete mode 100644 tests/unity_usrsock/basic_getsockname.c delete mode 100644 tests/unity_usrsock/basic_getsockopt.c delete mode 100644 tests/unity_usrsock/basic_send.c delete mode 100644 tests/unity_usrsock/basic_setsockopt.c delete mode 100644 tests/unity_usrsock/block_recv.c delete mode 100644 tests/unity_usrsock/block_send.c delete mode 100644 tests/unity_usrsock/chardev.c delete mode 100644 tests/unity_usrsock/defines.h delete mode 100644 tests/unity_usrsock/multi_thread.c delete mode 100644 tests/unity_usrsock/noblock_connect.c delete mode 100644 tests/unity_usrsock/noblock_recv.c delete mode 100644 tests/unity_usrsock/noblock_send.c delete mode 100644 tests/unity_usrsock/nodaemon.c delete mode 100644 tests/unity_usrsock/poll.c delete mode 100644 tests/unity_usrsock/remote_disconnect.c delete mode 100644 tests/unity_usrsock/unity_usrsock_main.c delete mode 100644 tests/unity_usrsock/usrsocktest_daemon.c delete mode 100644 tests/unity_usrsock/wake_with_signal.c diff --git a/include/testing/license.txt b/include/testing/license.txt deleted file mode 100644 index d66fba53e..000000000 --- a/include/testing/license.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams - -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. diff --git a/include/testing/unity.h b/include/testing/unity.h deleted file mode 100644 index d1decd042..000000000 --- a/include/testing/unity.h +++ /dev/null @@ -1,272 +0,0 @@ -/* ========================================== - Unity Project - A Test Framework for C - Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams - [Released under MIT License. Please refer to license.txt for details] -========================================== */ - -#ifndef UNITY_FRAMEWORK_H -#define UNITY_FRAMEWORK_H -#define UNITY - -#include "unity_internals.h" - -//------------------------------------------------------- -// Configuration Options -//------------------------------------------------------- -// All options described below should be passed as a compiler flag to all files using Unity. If you must add #defines, place them BEFORE the #include above. - -// Integers/longs/pointers -// - Unity attempts to automatically discover your integer sizes -// - define UNITY_EXCLUDE_STDINT_H to stop attempting to look in -// - define UNITY_EXCLUDE_LIMITS_H to stop attempting to look in -// - define UNITY_EXCLUDE_SIZEOF to stop attempting to use sizeof in macros -// - If you cannot use the automatic methods above, you can force Unity by using these options: -// - define UNITY_SUPPORT_64 -// - define UNITY_INT_WIDTH -// - UNITY_LONG_WIDTH -// - UNITY_POINTER_WIDTH - -// Floats -// - define UNITY_EXCLUDE_FLOAT to disallow floating point comparisons -// - define UNITY_FLOAT_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_FLOAT -// - define UNITY_FLOAT_TYPE to specify doubles instead of single precision floats -// - define UNITY_FLOAT_VERBOSE to print floating point values in errors (uses sprintf) -// - define UNITY_INCLUDE_DOUBLE to allow double floating point comparisons -// - define UNITY_EXCLUDE_DOUBLE to disallow double floating point comparisons (default) -// - define UNITY_DOUBLE_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_DOUBLE -// - define UNITY_DOUBLE_TYPE to specify something other than double -// - define UNITY_DOUBLE_VERBOSE to print floating point values in errors (uses sprintf) - -// Output -// - by default, Unity prints to standard out with putchar. define UNITY_OUTPUT_CHAR(a) with a different function if desired - -// Optimization -// - by default, line numbers are stored in unsigned shorts. Define UNITY_LINE_TYPE with a different type if your files are huge -// - by default, test and failure counters are unsigned shorts. Define UNITY_COUNTER_TYPE with a different type if you want to save space or have more than 65535 Tests. - -// Test Cases -// - define UNITY_SUPPORT_TEST_CASES to include the TEST_CASE macro, though really it's mostly about the runner generator script - -// Parameterized Tests -// - you'll want to create a define of TEST_CASE(...) which basically evaluates to nothing - -//------------------------------------------------------- -// Basic Fail and Ignore -//------------------------------------------------------- - -#define TEST_FAIL_MESSAGE(message) UNITY_TEST_FAIL(__LINE__, message) -#define TEST_FAIL() UNITY_TEST_FAIL(__LINE__, NULL) -#define TEST_IGNORE_MESSAGE(message) UNITY_TEST_IGNORE(__LINE__, message) -#define TEST_IGNORE() UNITY_TEST_IGNORE(__LINE__, NULL) -#define TEST_ONLY() - -//------------------------------------------------------- -// Test Asserts (simple) -//------------------------------------------------------- - -//Boolean -#define TEST_ASSERT(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expression Evaluated To FALSE") -#define TEST_ASSERT_TRUE(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expected TRUE Was FALSE") -#define TEST_ASSERT_UNLESS(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expression Evaluated To TRUE") -#define TEST_ASSERT_FALSE(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expected FALSE Was TRUE") -#define TEST_ASSERT_NULL(pointer) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, " Expected NULL") -#define TEST_ASSERT_NOT_NULL(pointer) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, " Expected Non-NULL") - -//Integers (of all sizes) -#define TEST_ASSERT_EQUAL_INT(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal") -#define TEST_ASSERT_EQUAL_UINT(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX8(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX16(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX32(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX64(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_BITS(mask, expected, actual) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_BITS_HIGH(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(-1), (actual), __LINE__, NULL) -#define TEST_ASSERT_BITS_LOW(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(0), (actual), __LINE__, NULL) -#define TEST_ASSERT_BIT_HIGH(bit, actual) UNITY_TEST_ASSERT_BITS(((_UU32)1 << bit), (_UU32)(-1), (actual), __LINE__, NULL) -#define TEST_ASSERT_BIT_LOW(bit, actual) UNITY_TEST_ASSERT_BITS(((_UU32)1 << bit), (_UU32)(0), (actual), __LINE__, NULL) - -//Integer Ranges (of all sizes) -#define TEST_ASSERT_INT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, __LINE__, NULL) -#define TEST_ASSERT_INT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT8_WITHIN(delta, expected, actual, __LINE__, NULL) -#define TEST_ASSERT_INT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT16_WITHIN(delta, expected, actual, __LINE__, NULL) -#define TEST_ASSERT_INT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT32_WITHIN(delta, expected, actual, __LINE__, NULL) -#define TEST_ASSERT_INT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, __LINE__, NULL) -#define TEST_ASSERT_UINT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT_WITHIN(delta, expected, actual, __LINE__, NULL) -#define TEST_ASSERT_UINT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT8_WITHIN(delta, expected, actual, __LINE__, NULL) -#define TEST_ASSERT_UINT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT16_WITHIN(delta, expected, actual, __LINE__, NULL) -#define TEST_ASSERT_UINT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT32_WITHIN(delta, expected, actual, __LINE__, NULL) -#define TEST_ASSERT_UINT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, __LINE__, NULL) -#define TEST_ASSERT_HEX_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, __LINE__, NULL) -#define TEST_ASSERT_HEX8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX8_WITHIN(delta, expected, actual, __LINE__, NULL) -#define TEST_ASSERT_HEX16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX16_WITHIN(delta, expected, actual, __LINE__, NULL) -#define TEST_ASSERT_HEX32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, __LINE__, NULL) -#define TEST_ASSERT_HEX64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, __LINE__, NULL) - -//Structs and Strings -#define TEST_ASSERT_EQUAL_PTR(expected, actual) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_STRING(expected, actual) UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_MEMORY(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, __LINE__, NULL) - -//Arrays -#define TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, __LINE__, NULL) - -//Floating Point (If Enabled) -#define TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_FLOAT(expected, actual) UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_NOT_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, __LINE__, NULL) - -//Double (If Enabled) -#define TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_DOUBLE(expected, actual) UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, __LINE__, NULL) -#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_NOT_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, __LINE__, NULL) - -//------------------------------------------------------- -// Test Asserts (with additional messages) -//------------------------------------------------------- - -//Boolean -#define TEST_ASSERT_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, message) -#define TEST_ASSERT_TRUE_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, message) -#define TEST_ASSERT_UNLESS_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, message) -#define TEST_ASSERT_FALSE_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, message) -#define TEST_ASSERT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, message) -#define TEST_ASSERT_NOT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, message) - -//Integers (of all sizes) -#define TEST_ASSERT_EQUAL_INT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, message) -#define TEST_ASSERT_EQUAL_INT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, message) -#define TEST_ASSERT_EQUAL_INT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, message) -#define TEST_ASSERT_EQUAL_INT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, message) -#define TEST_ASSERT_EQUAL_INT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, message) -#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, message) -#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, message) -#define TEST_ASSERT_EQUAL_UINT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, message) -#define TEST_ASSERT_EQUAL_UINT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, message) -#define TEST_ASSERT_EQUAL_UINT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, message) -#define TEST_ASSERT_EQUAL_UINT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, message) -#define TEST_ASSERT_EQUAL_UINT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, message) -#define TEST_ASSERT_EQUAL_HEX_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, message) -#define TEST_ASSERT_EQUAL_HEX8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, message) -#define TEST_ASSERT_EQUAL_HEX16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, message) -#define TEST_ASSERT_EQUAL_HEX32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, message) -#define TEST_ASSERT_EQUAL_HEX64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, message) -#define TEST_ASSERT_BITS_MESSAGE(mask, expected, actual, message) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, message) -#define TEST_ASSERT_BITS_HIGH_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(-1), (actual), __LINE__, message) -#define TEST_ASSERT_BITS_LOW_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(0), (actual), __LINE__, message) -#define TEST_ASSERT_BIT_HIGH_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((_UU32)1 << bit), (_UU32)(-1), (actual), __LINE__, message) -#define TEST_ASSERT_BIT_LOW_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((_UU32)1 << bit), (_UU32)(0), (actual), __LINE__, message) - -//Integer Ranges (of all sizes) -#define TEST_ASSERT_INT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, __LINE__, message) -#define TEST_ASSERT_INT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT8_WITHIN(delta, expected, actual, __LINE__, message) -#define TEST_ASSERT_INT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT16_WITHIN(delta, expected, actual, __LINE__, message) -#define TEST_ASSERT_INT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT32_WITHIN(delta, expected, actual, __LINE__, message) -#define TEST_ASSERT_INT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, __LINE__, message) -#define TEST_ASSERT_UINT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT_WITHIN(delta, expected, actual, __LINE__, message) -#define TEST_ASSERT_UINT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT8_WITHIN(delta, expected, actual, __LINE__, message) -#define TEST_ASSERT_UINT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT16_WITHIN(delta, expected, actual, __LINE__, message) -#define TEST_ASSERT_UINT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT32_WITHIN(delta, expected, actual, __LINE__, message) -#define TEST_ASSERT_UINT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, __LINE__, message) -#define TEST_ASSERT_HEX_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, __LINE__, message) -#define TEST_ASSERT_HEX8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX8_WITHIN(delta, expected, actual, __LINE__, message) -#define TEST_ASSERT_HEX16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX16_WITHIN(delta, expected, actual, __LINE__, message) -#define TEST_ASSERT_HEX32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, __LINE__, message) -#define TEST_ASSERT_HEX64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, __LINE__, message) - -//Structs and Strings -#define TEST_ASSERT_EQUAL_PTR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, __LINE__, message) -#define TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, __LINE__, message) -#define TEST_ASSERT_EQUAL_MEMORY_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, __LINE__, message) - -//Arrays -#define TEST_ASSERT_EQUAL_INT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements, __LINE__, message) -#define TEST_ASSERT_EQUAL_INT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements, __LINE__, message) -#define TEST_ASSERT_EQUAL_INT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements, __LINE__, message) -#define TEST_ASSERT_EQUAL_INT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements, __LINE__, message) -#define TEST_ASSERT_EQUAL_INT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, __LINE__, message) -#define TEST_ASSERT_EQUAL_UINT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements, __LINE__, message) -#define TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements, __LINE__, message) -#define TEST_ASSERT_EQUAL_UINT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements, __LINE__, message) -#define TEST_ASSERT_EQUAL_UINT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements, __LINE__, message) -#define TEST_ASSERT_EQUAL_UINT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, __LINE__, message) -#define TEST_ASSERT_EQUAL_HEX_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, __LINE__, message) -#define TEST_ASSERT_EQUAL_HEX8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements, __LINE__, message) -#define TEST_ASSERT_EQUAL_HEX16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements, __LINE__, message) -#define TEST_ASSERT_EQUAL_HEX32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, __LINE__, message) -#define TEST_ASSERT_EQUAL_HEX64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, __LINE__, message) -#define TEST_ASSERT_EQUAL_PTR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, __LINE__, message) -#define TEST_ASSERT_EQUAL_STRING_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, __LINE__, message) -#define TEST_ASSERT_EQUAL_MEMORY_ARRAY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, __LINE__, message) - -//Floating Point (If Enabled) -#define TEST_ASSERT_FLOAT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, __LINE__, message) -#define TEST_ASSERT_EQUAL_FLOAT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, __LINE__, message) -#define TEST_ASSERT_EQUAL_FLOAT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, __LINE__, message) -#define TEST_ASSERT_FLOAT_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, __LINE__, message) -#define TEST_ASSERT_FLOAT_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, __LINE__, message) -#define TEST_ASSERT_FLOAT_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, __LINE__, message) -#define TEST_ASSERT_FLOAT_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, __LINE__, message) -#define TEST_ASSERT_FLOAT_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, __LINE__, message) -#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, __LINE__, message) -#define TEST_ASSERT_FLOAT_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, __LINE__, message) -#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, __LINE__, message) - -//Double (If Enabled) -#define TEST_ASSERT_DOUBLE_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, __LINE__, message) -#define TEST_ASSERT_EQUAL_DOUBLE_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, __LINE__, message) -#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, __LINE__, message) -#define TEST_ASSERT_DOUBLE_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, __LINE__, message) -#define TEST_ASSERT_DOUBLE_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, __LINE__, message) -#define TEST_ASSERT_DOUBLE_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, __LINE__, message) -#define TEST_ASSERT_DOUBLE_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, __LINE__, message) -#define TEST_ASSERT_DOUBLE_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, __LINE__, message) -#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, __LINE__, message) -#define TEST_ASSERT_DOUBLE_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, __LINE__, message) -#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, __LINE__, message) - -//end of UNITY_FRAMEWORK_H -#endif diff --git a/include/testing/unity_fixture.h b/include/testing/unity_fixture.h deleted file mode 100644 index 304c2f7b7..000000000 --- a/include/testing/unity_fixture.h +++ /dev/null @@ -1,98 +0,0 @@ -//- Copyright (c) 2010 James Grenning and Contributed to Unity Project -/* ========================================== - Unity Project - A Test Framework for C - Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams - [Released under MIT License. Please refer to license.txt for details] -========================================== */ - -#ifndef UNITY_FIXTURE_H_ -#define UNITY_FIXTURE_H_ - -#include "unity.h" -#include "unity_internals.h" -#include "unity_fixture_malloc_overrides.h" -#include "unity_fixture_internals.h" - -int UnityMain(int argc, const char* argv[], void (*runAllTests)(void)); - - -#define TEST_GROUP(group)\ - static const char* TEST_GROUP_##group = #group - -#define TEST_SETUP(group) TEST_SETUP_WITH_TIMEOUT(group, UNITY_DEFAULT_TIMEOUT_MSEC) - -#define TEST_SETUP_WITH_TIMEOUT(group, timeout)\ - static const _U_UINT TEST_##group##_SETUP_TIMEOUT = (timeout);\ - void TEST_##group##_SETUP(void);\ - void TEST_##group##_SETUP(void) - -#define TEST_TEAR_DOWN(group) TEST_TEAR_DOWN_WITH_TIMEOUT(group, UNITY_DEFAULT_TIMEOUT_MSEC) - -#define TEST_TEAR_DOWN_WITH_TIMEOUT(group, timeout)\ - static const _U_UINT TEST_##group##_TEAR_DOWN_TIMEOUT = (timeout);\ - void TEST_##group##_TEAR_DOWN(void);\ - void TEST_##group##_TEAR_DOWN(void) - - -#define TEST(group, name) TEST_WITH_TIMEOUT(group, name, UNITY_DEFAULT_TIMEOUT_MSEC) - -#define TEST_WITH_TIMEOUT(group, name, timeout)\ - void TEST_##group##_##name##_(void);\ - void TEST_##group##_##name##_run(void);\ - void TEST_##group##_##name##_run(void)\ - {\ - UnityTestRunner(TEST_##group##_SETUP, TEST_##group##_SETUP_TIMEOUT,\ - TEST_##group##_##name##_, (timeout),\ - TEST_##group##_TEAR_DOWN, TEST_##group##_TEAR_DOWN_TIMEOUT,\ - #group "/" #name,\ - TEST_GROUP_##group, #name,\ - __FILE__, __LINE__);\ - }\ - void TEST_##group##_##name##_(void) - -#define IGNORE_TEST(group, name) IGNORE_TEST_WITH_TIMEOUT(group, name, UNITY_DEFAULT_TIMEOUT_MSEC) - -#define IGNORE_TEST_WITH_TIMEOUT(group, name, timeout) \ - void TEST_##group##_##name##_(void);\ - void TEST_##group##_##name##_run(void);\ - void TEST_##group##_##name##_run(void)\ - {\ - UnityIgnoreTest("IGNORE_TEST(" #group ", " #name ")");\ - }\ - void TEST_##group##_##name##_(void) - -#define DECLARE_TEST_CASE(group, name) \ - void TEST_##group##_##name##_run(void) - -#define RUN_TEST_CASE(group, name) \ - { DECLARE_TEST_CASE(group, name);\ - TEST_##group##_##name##_run(); } - -//This goes at the bottom of each test file or in a separate c file -#define TEST_GROUP_RUNNER(group)\ - void TEST_##group##_GROUP_RUNNER_runAll(void);\ - void TEST_##group##_GROUP_RUNNER(void);\ - void TEST_##group##_GROUP_RUNNER(void)\ - {\ - TEST_##group##_GROUP_RUNNER_runAll();\ - }\ - void TEST_##group##_GROUP_RUNNER_runAll(void) - -//Call this from main -#define RUN_TEST_GROUP(group)\ - { void TEST_##group##_GROUP_RUNNER(void);\ - TEST_##group##_GROUP_RUNNER(); } - -//CppUTest Compatibility Macros -#define UT_PTR_SET(ptr, newPointerValue) UnityPointer_Set((void**)&ptr, (void*)newPointerValue) -#define TEST_ASSERT_POINTERS_EQUAL(expected, actual) TEST_ASSERT_EQUAL_PTR(expected, actual) -#define TEST_ASSERT_BYTES_EQUAL(expected, actual) TEST_ASSERT_EQUAL_HEX8(0xff & (expected), 0xff & (actual)) -#define FAIL(message) TEST_FAIL((message)) -#define CHECK(condition) TEST_ASSERT_TRUE((condition)) -#define LONGS_EQUAL(expected, actual) TEST_ASSERT_EQUAL_INT((expected), (actual)) -#define STRCMP_EQUAL(expected, actual) TEST_ASSERT_EQUAL_STRING((expected), (actual)) -#define DOUBLES_EQUAL(expected, actual, delta) TEST_ASSERT_FLOAT_WITHIN(((expected), (actual), (delta)) - -void UnityMalloc_MakeMallocFailAfterCount(int count); - -#endif /* UNITY_FIXTURE_H_ */ diff --git a/include/testing/unity_fixture_internals.h b/include/testing/unity_fixture_internals.h deleted file mode 100644 index dd5ceee8b..000000000 --- a/include/testing/unity_fixture_internals.h +++ /dev/null @@ -1,46 +0,0 @@ -//- Copyright (c) 2010 James Grenning and Contributed to Unity Project -/* ========================================== - Unity Project - A Test Framework for C - Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams - [Released under MIT License. Please refer to license.txt for details] -========================================== */ - -#ifndef UNITY_FIXTURE_INTERNALS_H_ -#define UNITY_FIXTURE_INTERNALS_H_ - -typedef struct _UNITY_FIXTURE_T -{ - int Verbose; - int ListOnly; - unsigned int RepeatCount; - const char* NameFilter; - const char* GroupFilter; - const char** PlainListOfTests; -} UNITY_FIXTURE_T; - -typedef void unityfunction(void); -void UnityTestRunner(unityfunction * setup, _U_UINT setupTimeoutMsec, - unityfunction * body, _U_UINT bodyTimeoutMsec, - unityfunction * teardown, _U_UINT teardownTimeoutMsec, - const char * printableName, - const char * group, - const char * name, - const char * file, int line); - -void UnityIgnoreTest(const char * printableName); -void UnityMalloc_StartTest(void); -void UnityMalloc_EndTest(void); -int UnityFailureCount(void); -int UnityGetCommandLineOptions(int argc, const char* argv[]); -void UnityConcludeFixtureTest(void); - -void UnityPointer_Set(void ** ptr, void * newValue); -void UnityPointer_UndoAllSets(void); -void UnityPointer_Init(void); - -void UnityAssertEqualPointer(const void * expected, - const void * actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -#endif /* UNITY_FIXTURE_INTERNALS_H_ */ diff --git a/include/testing/unity_fixture_malloc_overrides.h b/include/testing/unity_fixture_malloc_overrides.h deleted file mode 100644 index 25385f4d7..000000000 --- a/include/testing/unity_fixture_malloc_overrides.h +++ /dev/null @@ -1,27 +0,0 @@ -//- Copyright (c) 2010 James Grenning and Contributed to Unity Project -/* ========================================== - Unity Project - A Test Framework for C - Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams - [Released under MIT License. Please refer to license.txt for details] -========================================== */ - -#ifndef UNITY_FIXTURE_MALLOC_OVERRIDES_H_ -#define UNITY_FIXTURE_MALLOC_OVERRIDES_H_ - -#ifndef UNITY_DISABLE_MEMORY_LEAK_TRACKING - -#include - -#define malloc unity_malloc -#define calloc unity_calloc -#define realloc unity_realloc -#define free unity_free - -void* unity_malloc(size_t size); -void* unity_calloc(size_t num, size_t size); -void* unity_realloc(void * oldMem, size_t size); -void unity_free(void * mem); - -#endif /* UNITY_DISABLE_MEMORY_LEAK_TRACKING */ - -#endif /* UNITY_FIXTURE_MALLOC_OVERRIDES_H_ */ diff --git a/include/testing/unity_internals.h b/include/testing/unity_internals.h deleted file mode 100644 index b73729f13..000000000 --- a/include/testing/unity_internals.h +++ /dev/null @@ -1,693 +0,0 @@ -/* ========================================== - Unity Project - A Test Framework for C - Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams - [Released under MIT License. Please refer to license.txt for details] -========================================== */ - -#ifndef UNITY_INTERNALS_H -#define UNITY_INTERNALS_H - -#ifdef UNITY_INCLUDE_CONFIG_H -#include "unity_config.h" -#endif - -// Unity Attempts to Auto-Detect Integer Types -// Attempt 1: UINT_MAX, ULONG_MAX, etc in -// Attempt 2: UINT_MAX, ULONG_MAX, etc in -// Attempt 3: Deduced from sizeof() macros -#ifndef UNITY_EXCLUDE_STDINT_H -#include -#endif - -#ifndef UNITY_EXCLUDE_LIMITS_H -#include -#endif - -#ifndef UNITY_EXCLUDE_SIZEOF -#ifndef UINT_MAX -#define UINT_MAX (sizeof(unsigned int) * 256 - 1) -#endif -#ifndef ULONG_MAX -#define ULONG_MAX (sizeof(unsigned long) * 256 - 1) -#endif -#ifndef UINTPTR_MAX -//apparently this is not a constant expression: (sizeof(unsigned int *) * 256 - 1) so we have to just let this fall through -#endif -#endif -//------------------------------------------------------- -// Guess Widths If Not Specified -//------------------------------------------------------- - -// Determine the size of an int, if not already specificied. -// We cannot use sizeof(int), because it is not yet defined -// at this stage in the trnslation of the C program. -// Therefore, infer it from UINT_MAX if possible. -#ifndef UNITY_INT_WIDTH - #ifdef UINT_MAX - #if (UINT_MAX == 0xFFFF) - #define UNITY_INT_WIDTH (16) - #elif (UINT_MAX == 0xFFFFFFFF) - #define UNITY_INT_WIDTH (32) - #elif (UINT_MAX == 0xFFFFFFFFFFFFFFFF) - #define UNITY_INT_WIDTH (64) - #endif - #endif -#endif -#ifndef UNITY_INT_WIDTH - #define UNITY_INT_WIDTH (32) -#endif - -// Determine the size of a long, if not already specified, -// by following the process used above to define -// UNITY_INT_WIDTH. -#ifndef UNITY_LONG_WIDTH - #ifdef ULONG_MAX - #if (ULONG_MAX == 0xFFFF) - #define UNITY_LONG_WIDTH (16) - #elif (ULONG_MAX == 0xFFFFFFFF) - #define UNITY_LONG_WIDTH (32) - #elif (ULONG_MAX == 0xFFFFFFFFFFFFFFFF) - #define UNITY_LONG_WIDTH (64) - #endif - #endif -#endif -#ifndef UNITY_LONG_WIDTH - #define UNITY_LONG_WIDTH (32) -#endif - -// Determine the size of a pointer, if not already specified, -// by following the process used above to define -// UNITY_INT_WIDTH. -#ifndef UNITY_POINTER_WIDTH - #ifdef UINTPTR_MAX - #if (UINTPTR_MAX <= 0xFFFF) - #define UNITY_POINTER_WIDTH (16) - #elif (UINTPTR_MAX <= 0xFFFFFFFF) - #define UNITY_POINTER_WIDTH (32) - #elif (UINTPTR_MAX <= 0xFFFFFFFFFFFFFFFF) - #define UNITY_POINTER_WIDTH (64) - #endif - #endif -#endif -#ifndef UNITY_POINTER_WIDTH - #ifdef INTPTR_MAX - #if (INTPTR_MAX <= 0x7FFF) - #define UNITY_POINTER_WIDTH (16) - #elif (INTPTR_MAX <= 0x7FFFFFFF) - #define UNITY_POINTER_WIDTH (32) - #elif (INTPTR_MAX <= 0x7FFFFFFFFFFFFFFF) - #define UNITY_POINTER_WIDTH (64) - #endif - #endif -#endif -#ifndef UNITY_POINTER_WIDTH - #define UNITY_POINTER_WIDTH UNITY_LONG_WIDTH -#endif - -//------------------------------------------------------- -// Int Support (Define types based on detected sizes) -//------------------------------------------------------- - -#if (UNITY_INT_WIDTH == 32) - typedef unsigned char _UU8; - typedef unsigned short _UU16; - typedef unsigned int _UU32; - typedef signed char _US8; - typedef signed short _US16; - typedef signed int _US32; -#elif (UNITY_INT_WIDTH == 16) - typedef unsigned char _UU8; - typedef unsigned int _UU16; - typedef unsigned long _UU32; - typedef signed char _US8; - typedef signed int _US16; - typedef signed long _US32; -#else - #error Invalid UNITY_INT_WIDTH specified! (16 or 32 are supported) -#endif - -//------------------------------------------------------- -// 64-bit Support -//------------------------------------------------------- - -#ifndef UNITY_SUPPORT_64 -#if UNITY_LONG_WIDTH > 32 -#define UNITY_SUPPORT_64 -#endif -#endif -#ifndef UNITY_SUPPORT_64 -#if UNITY_POINTER_WIDTH > 32 -#define UNITY_SUPPORT_64 -#endif -#endif - -#ifndef UNITY_SUPPORT_64 - -//No 64-bit Support -typedef _UU32 _U_UINT; -typedef _US32 _U_SINT; - -#else - -//64-bit Support -#if (UNITY_LONG_WIDTH == 32) - typedef unsigned long long _UU64; - typedef signed long long _US64; -#elif (UNITY_LONG_WIDTH == 64) - typedef unsigned long _UU64; - typedef signed long _US64; -#else - #error Invalid UNITY_LONG_WIDTH specified! (32 or 64 are supported) -#endif -typedef _UU64 _U_UINT; -typedef _US64 _U_SINT; - -#endif - -//------------------------------------------------------- -// Pointer Support -//------------------------------------------------------- - -#if (UNITY_POINTER_WIDTH == 32) - typedef _UU32 _UP; -#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX32 -#elif (UNITY_POINTER_WIDTH == 64) - typedef _UU64 _UP; -#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX64 -#elif (UNITY_POINTER_WIDTH == 16) - typedef _UU16 _UP; -#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX16 -#else - #error Invalid UNITY_POINTER_WIDTH specified! (16, 32 or 64 are supported) -#endif - -#ifndef UNITY_PTR_ATTRIBUTE - #define UNITY_PTR_ATTRIBUTE -#endif - -//------------------------------------------------------- -// Float Support -//------------------------------------------------------- - -#ifdef UNITY_EXCLUDE_FLOAT - -//No Floating Point Support -#undef UNITY_INCLUDE_FLOAT -#undef UNITY_FLOAT_PRECISION -#undef UNITY_FLOAT_TYPE -#undef UNITY_FLOAT_VERBOSE - -#else - -#ifndef UNITY_INCLUDE_FLOAT -#define UNITY_INCLUDE_FLOAT -#endif - -//Floating Point Support -#ifndef UNITY_FLOAT_PRECISION -#define UNITY_FLOAT_PRECISION (0.00001f) -#endif -#ifndef UNITY_FLOAT_TYPE -#define UNITY_FLOAT_TYPE float -#endif -typedef UNITY_FLOAT_TYPE _UF; - -#endif - -//------------------------------------------------------- -// Double Float Support -//------------------------------------------------------- - -//unlike FLOAT, we DON'T include by default -#ifndef UNITY_EXCLUDE_DOUBLE -#ifndef UNITY_INCLUDE_DOUBLE -#define UNITY_EXCLUDE_DOUBLE -#endif -#endif - -#ifdef UNITY_EXCLUDE_DOUBLE - -//No Floating Point Support -#undef UNITY_DOUBLE_PRECISION -#undef UNITY_DOUBLE_TYPE -#undef UNITY_DOUBLE_VERBOSE - -#ifdef UNITY_INCLUDE_DOUBLE -#undef UNITY_INCLUDE_DOUBLE -#endif - -#else - -//Double Floating Point Support -#ifndef UNITY_DOUBLE_PRECISION -#define UNITY_DOUBLE_PRECISION (1e-12f) -#endif -#ifndef UNITY_DOUBLE_TYPE -#define UNITY_DOUBLE_TYPE double -#endif -typedef UNITY_DOUBLE_TYPE _UD; - -#endif - -#ifdef UNITY_DOUBLE_VERBOSE -#ifndef UNITY_FLOAT_VERBOSE -#define UNITY_FLOAT_VERBOSE -#endif -#endif - -//------------------------------------------------------- -// Output Method: stdout (DEFAULT) -//------------------------------------------------------- -#ifndef UNITY_OUTPUT_CHAR -//Default to using putchar, which is defined in stdio.h -#include -#define UNITY_OUTPUT_CHAR(a) putchar(a) -#else -//If defined as something else, make sure we declare it here so it's ready for use -extern int UNITY_OUTPUT_CHAR(int); -#endif - -#ifndef UNITY_OUTPUT_START -#define UNITY_OUTPUT_START() -#endif - -#ifndef UNITY_OUTPUT_COMPLETE -#define UNITY_OUTPUT_COMPLETE() -#endif - -//------------------------------------------------------- -// Footprint -//------------------------------------------------------- - -#ifndef UNITY_LINE_TYPE -#define UNITY_LINE_TYPE _U_UINT -#endif - -#ifndef UNITY_COUNTER_TYPE -#define UNITY_COUNTER_TYPE _U_UINT -#endif - -//------------------------------------------------------- -// Language Features Available -//------------------------------------------------------- -#if !defined(UNITY_WEAK_ATTRIBUTE) && !defined(UNITY_WEAK_PRAGMA) -# ifdef __GNUC__ // includes clang -# if !(defined(__WIN32__) && defined(__clang__)) -# define UNITY_WEAK_ATTRIBUTE __attribute__((weak)) -# endif -# endif -#endif - -#ifdef UNITY_NO_WEAK -# undef UNITY_WEAK_ATTRIBUTE -# undef UNITY_WEAK_PRAGMA -#endif - - -//------------------------------------------------------- -// Internal Structs Needed -//------------------------------------------------------- - -typedef void (*UnityTestFunction)(void); - -#define UNITY_DISPLAY_RANGE_INT (0x10) -#define UNITY_DISPLAY_RANGE_UINT (0x20) -#define UNITY_DISPLAY_RANGE_HEX (0x40) -#define UNITY_DISPLAY_RANGE_AUTO (0x80) - -typedef enum -{ -#if (UNITY_INT_WIDTH == 16) - UNITY_DISPLAY_STYLE_INT = 2 + UNITY_DISPLAY_RANGE_INT + UNITY_DISPLAY_RANGE_AUTO, -#elif (UNITY_INT_WIDTH == 32) - UNITY_DISPLAY_STYLE_INT = 4 + UNITY_DISPLAY_RANGE_INT + UNITY_DISPLAY_RANGE_AUTO, -#elif (UNITY_INT_WIDTH == 64) - UNITY_DISPLAY_STYLE_INT = 8 + UNITY_DISPLAY_RANGE_INT + UNITY_DISPLAY_RANGE_AUTO, -#endif - UNITY_DISPLAY_STYLE_INT8 = 1 + UNITY_DISPLAY_RANGE_INT, - UNITY_DISPLAY_STYLE_INT16 = 2 + UNITY_DISPLAY_RANGE_INT, - UNITY_DISPLAY_STYLE_INT32 = 4 + UNITY_DISPLAY_RANGE_INT, -#ifdef UNITY_SUPPORT_64 - UNITY_DISPLAY_STYLE_INT64 = 8 + UNITY_DISPLAY_RANGE_INT, -#endif - -#if (UNITY_INT_WIDTH == 16) - UNITY_DISPLAY_STYLE_UINT = 2 + UNITY_DISPLAY_RANGE_UINT + UNITY_DISPLAY_RANGE_AUTO, -#elif (UNITY_INT_WIDTH == 32) - UNITY_DISPLAY_STYLE_UINT = 4 + UNITY_DISPLAY_RANGE_UINT + UNITY_DISPLAY_RANGE_AUTO, -#elif (UNITY_INT_WIDTH == 64) - UNITY_DISPLAY_STYLE_UINT = 8 + UNITY_DISPLAY_RANGE_UINT + UNITY_DISPLAY_RANGE_AUTO, -#endif - UNITY_DISPLAY_STYLE_UINT8 = 1 + UNITY_DISPLAY_RANGE_UINT, - UNITY_DISPLAY_STYLE_UINT16 = 2 + UNITY_DISPLAY_RANGE_UINT, - UNITY_DISPLAY_STYLE_UINT32 = 4 + UNITY_DISPLAY_RANGE_UINT, -#ifdef UNITY_SUPPORT_64 - UNITY_DISPLAY_STYLE_UINT64 = 8 + UNITY_DISPLAY_RANGE_UINT, -#endif - UNITY_DISPLAY_STYLE_HEX8 = 1 + UNITY_DISPLAY_RANGE_HEX, - UNITY_DISPLAY_STYLE_HEX16 = 2 + UNITY_DISPLAY_RANGE_HEX, - UNITY_DISPLAY_STYLE_HEX32 = 4 + UNITY_DISPLAY_RANGE_HEX, -#ifdef UNITY_SUPPORT_64 - UNITY_DISPLAY_STYLE_HEX64 = 8 + UNITY_DISPLAY_RANGE_HEX, -#endif - UNITY_DISPLAY_STYLE_UNKNOWN -} UNITY_DISPLAY_STYLE_T; - -#ifndef UNITY_EXCLUDE_FLOAT -typedef enum _UNITY_FLOAT_TRAIT_T -{ - UNITY_FLOAT_IS_NOT_INF = 0, - UNITY_FLOAT_IS_INF, - UNITY_FLOAT_IS_NOT_NEG_INF, - UNITY_FLOAT_IS_NEG_INF, - UNITY_FLOAT_IS_NOT_NAN, - UNITY_FLOAT_IS_NAN, - UNITY_FLOAT_IS_NOT_DET, - UNITY_FLOAT_IS_DET, -} UNITY_FLOAT_TRAIT_T; -#endif - -struct _Unity -{ - const char* TestFile; - const char* CurrentTestName; - UNITY_LINE_TYPE CurrentTestLineNumber; - UNITY_COUNTER_TYPE NumberOfTests; - UNITY_COUNTER_TYPE TestFailures; - UNITY_COUNTER_TYPE TestIgnores; - UNITY_COUNTER_TYPE CurrentTestFailed; - UNITY_COUNTER_TYPE CurrentTestIgnored; - UNITY_COUNTER_TYPE CurrentTestTimeout; -}; - -extern struct _Unity Unity; - -//------------------------------------------------------- -// Test Suite Management -//------------------------------------------------------- - -void UnityBegin(const char* filename); -int UnityEnd(void); -void UnityConcludeTest(void); -void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum); - -//------------------------------------------------------- -// Test Output -//------------------------------------------------------- - -void UnityPrint(const char* string); -void UnityPrintMask(const _U_UINT mask, const _U_UINT number); -void UnityPrintNumberByStyle(const _U_SINT number, const UNITY_DISPLAY_STYLE_T style); -void UnityPrintNumber(const _U_SINT number); -void UnityPrintNumberUnsigned(const _U_UINT number); -void UnityPrintNumberHex(const _U_UINT number, const char nibbles); - -#ifdef UNITY_FLOAT_VERBOSE -void UnityPrintFloat(const _UF number); -#endif - -//------------------------------------------------------- -// Test Assertion Fuctions -//------------------------------------------------------- -// Use the macros below this section instead of calling -// these directly. The macros have a consistent naming -// convention and will pull in file and line information -// for you. - -void UnityAssertEqualNumber(const _U_SINT expected, - const _U_SINT actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_DISPLAY_STYLE_T style); - -void UnityAssertEqualIntArray(UNITY_PTR_ATTRIBUTE const void* expected, - UNITY_PTR_ATTRIBUTE const void* actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_DISPLAY_STYLE_T style); - -void UnityAssertBits(const _U_SINT mask, - const _U_SINT expected, - const _U_SINT actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertEqualString(const char* expected, - const char* actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertEqualStringArray( const char** expected, - const char** actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertEqualMemory( UNITY_PTR_ATTRIBUTE const void* expected, - UNITY_PTR_ATTRIBUTE const void* actual, - const _UU32 length, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertNumbersWithin(const _U_SINT delta, - const _U_SINT expected, - const _U_SINT actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_DISPLAY_STYLE_T style); - -void UnityFail(const char* message, const UNITY_LINE_TYPE line); - -void UnityIgnore(const char* message, const UNITY_LINE_TYPE line); - -#ifndef UNITY_EXCLUDE_FLOAT -void UnityAssertFloatsWithin(const _UF delta, - const _UF expected, - const _UF actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const _UF* expected, - UNITY_PTR_ATTRIBUTE const _UF* actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertFloatSpecial(const _UF actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_FLOAT_TRAIT_T style); -#endif - -#ifndef UNITY_EXCLUDE_DOUBLE -void UnityAssertDoublesWithin(const _UD delta, - const _UD expected, - const _UD actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const _UD* expected, - UNITY_PTR_ATTRIBUTE const _UD* actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertDoubleSpecial(const _UD actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_FLOAT_TRAIT_T style); -#endif - -int UnityProtect(UnityTestFunction function, _U_UINT timeout_msec); - -//------------------------------------------------------- -// Error Strings We Might Need -//------------------------------------------------------- - -extern const char UnityStrErrFloat[]; -extern const char UnityStrErrDouble[]; -extern const char UnityStrErr64[]; - -//------------------------------------------------------- -// Test Running Macros -//------------------------------------------------------- - -#define UNITY_DEFAULT_TIMEOUT_MSEC 120000 - -#define TEST_PROTECTED_WITH_TIMEOUT(function, timeout) UnityProtect(function, timeout) -#define TEST_PROTECTED(function) TEST_PROTECTED_WITH_TIMEOUT(function, UNITY_DEFAULT_TIMEOUT_MSEC) - -//This tricky series of macros gives us an optional line argument to treat it as RUN_TEST(func, num=__LINE__) -#ifndef RUN_TEST -#ifdef __STDC_VERSION__ -#if __STDC_VERSION__ >= 199901L -#define RUN_TEST(...) UnityDefaultTestRun(RUN_TEST_FIRST(__VA_ARGS__), RUN_TEST_SECOND(__VA_ARGS__)) -#define RUN_TEST_FIRST(...) RUN_TEST_FIRST_HELPER(__VA_ARGS__, throwaway) -#define RUN_TEST_FIRST_HELPER(first,...) first, #first -#define RUN_TEST_SECOND(...) RUN_TEST_SECOND_HELPER(__VA_ARGS__, __LINE__, throwaway) -#define RUN_TEST_SECOND_HELPER(first,second,...) second -#endif -#endif -#endif - -//If we can't do the tricky version, we'll just have to require them to always include the line number -#ifndef RUN_TEST -#ifdef CMOCK -#define RUN_TEST(func, num) UnityDefaultTestRun(func, #func, num) -#else -#define RUN_TEST(func) UnityDefaultTestRun(func, #func, __LINE__) -#endif -#endif - -#define TEST_LINE_NUM (Unity.CurrentTestLineNumber) -#define TEST_IS_IGNORED (Unity.CurrentTestIgnored) -#define UNITY_NEW_TEST(a) \ - Unity.CurrentTestName = a; \ - Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)(__LINE__); \ - Unity.NumberOfTests++; - -#ifndef UNITY_BEGIN -#define UNITY_BEGIN() UnityBegin(__FILE__) -#endif - -#ifndef UNITY_END -#define UNITY_END() UnityEnd() -#endif - -//------------------------------------------------------- -// Basic Fail and Ignore -//------------------------------------------------------- - -#define UNITY_TEST_FAIL(line, message) UnityFail( (message), (UNITY_LINE_TYPE)line); -#define UNITY_TEST_IGNORE(line, message) UnityIgnore( (message), (UNITY_LINE_TYPE)line); - -//------------------------------------------------------- -// Test Asserts -//------------------------------------------------------- - -#define UNITY_TEST_ASSERT(condition, line, message) if (condition) {} else {UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, message);} -#define UNITY_TEST_ASSERT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) == NULL), (UNITY_LINE_TYPE)line, message) -#define UNITY_TEST_ASSERT_NOT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) != NULL), (UNITY_LINE_TYPE)line, message) - -#define UNITY_TEST_ASSERT_EQUAL_INT(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT) -#define UNITY_TEST_ASSERT_EQUAL_INT8(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US8 )(expected), (_U_SINT)(_US8 )(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT8) -#define UNITY_TEST_ASSERT_EQUAL_INT16(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US16)(expected), (_U_SINT)(_US16)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT16) -#define UNITY_TEST_ASSERT_EQUAL_INT32(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US32)(expected), (_U_SINT)(_US32)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT32) -#define UNITY_TEST_ASSERT_EQUAL_UINT(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT) -#define UNITY_TEST_ASSERT_EQUAL_UINT8(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UU8 )(expected), (_U_SINT)(_UU8 )(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT8) -#define UNITY_TEST_ASSERT_EQUAL_UINT16(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UU16)(expected), (_U_SINT)(_UU16)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT16) -#define UNITY_TEST_ASSERT_EQUAL_UINT32(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UU32)(expected), (_U_SINT)(_UU32)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT32) -#define UNITY_TEST_ASSERT_EQUAL_HEX8(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US8 )(expected), (_U_SINT)(_US8 )(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX8) -#define UNITY_TEST_ASSERT_EQUAL_HEX16(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US16)(expected), (_U_SINT)(_US16)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX16) -#define UNITY_TEST_ASSERT_EQUAL_HEX32(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US32)(expected), (_U_SINT)(_US32)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX32) -#define UNITY_TEST_ASSERT_BITS(mask, expected, actual, line, message) UnityAssertBits((_U_SINT)(mask), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line) - -#define UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT) -#define UNITY_TEST_ASSERT_INT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_US8 )(delta), (_U_SINT)(_US8 )(expected), (_U_SINT)(_US8 )(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT8) -#define UNITY_TEST_ASSERT_INT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_US16)(delta), (_U_SINT)(_US16)(expected), (_U_SINT)(_US16)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT16) -#define UNITY_TEST_ASSERT_INT32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_US32)(delta), (_U_SINT)(_US32)(expected), (_U_SINT)(_US32)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT32) -#define UNITY_TEST_ASSERT_UINT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT) -#define UNITY_TEST_ASSERT_UINT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_U_UINT)(_UU8 )(delta), (_U_SINT)(_U_UINT)(_UU8 )(expected), (_U_SINT)(_U_UINT)(_UU8 )(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT8) -#define UNITY_TEST_ASSERT_UINT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_U_UINT)(_UU16)(delta), (_U_SINT)(_U_UINT)(_UU16)(expected), (_U_SINT)(_U_UINT)(_UU16)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT16) -#define UNITY_TEST_ASSERT_UINT32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_U_UINT)(_UU32)(delta), (_U_SINT)(_U_UINT)(_UU32)(expected), (_U_SINT)(_U_UINT)(_UU32)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT32) -#define UNITY_TEST_ASSERT_HEX8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_U_UINT)(_UU8 )(delta), (_U_SINT)(_U_UINT)(_UU8 )(expected), (_U_SINT)(_U_UINT)(_UU8 )(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX8) -#define UNITY_TEST_ASSERT_HEX16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_U_UINT)(_UU16)(delta), (_U_SINT)(_U_UINT)(_UU16)(expected), (_U_SINT)(_U_UINT)(_UU16)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX16) -#define UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(_U_UINT)(_UU32)(delta), (_U_SINT)(_U_UINT)(_UU32)(expected), (_U_SINT)(_U_UINT)(_UU32)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX32) - -#define UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UP)(expected), (_U_SINT)(_UP)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_POINTER) -#define UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, line, message) UnityAssertEqualString((const char*)(expected), (const char*)(actual), (message), (UNITY_LINE_TYPE)line) -#define UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, line, message) UnityAssertEqualMemory((UNITY_PTR_ATTRIBUTE void*)(expected), (UNITY_PTR_ATTRIBUTE void*)(actual), (_UU32)(len), 1, (message), (UNITY_LINE_TYPE)line) - -#define UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT) -#define UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT8) -#define UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT16) -#define UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT32) -#define UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT) -#define UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT8) -#define UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT16) -#define UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT32) -#define UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX8) -#define UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX16) -#define UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(expected), (UNITY_PTR_ATTRIBUTE const void*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX32) -#define UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const void*)(_UP*)(expected), (const void*)(_UP*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_POINTER) -#define UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualStringArray((const char**)(expected), (const char**)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line) -#define UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, line, message) UnityAssertEqualMemory((UNITY_PTR_ATTRIBUTE void*)(expected), (UNITY_PTR_ATTRIBUTE void*)(actual), (_UU32)(len), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line) - -#ifdef UNITY_SUPPORT_64 -#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT64) -#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT64) -#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX64) -#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const _U_SINT*)(expected), (UNITY_PTR_ATTRIBUTE const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT64) -#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const _U_SINT*)(expected), (UNITY_PTR_ATTRIBUTE const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT64) -#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_PTR_ATTRIBUTE const _U_SINT*)(expected), (UNITY_PTR_ATTRIBUTE const _U_SINT*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX64) -#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(delta), (_U_SINT)(expected), (_U_SINT)(actual), NULL, (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_INT64) -#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(delta), (_U_SINT)(expected), (_U_SINT)(actual), NULL, (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_UINT64) -#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_U_SINT)(delta), (_U_SINT)(expected), (_U_SINT)(actual), NULL, (UNITY_LINE_TYPE)line, UNITY_DISPLAY_STYLE_HEX64) -#else -#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErr64) -#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErr64) -#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErr64) -#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErr64) -#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErr64) -#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErr64) -#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErr64) -#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErr64) -#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErr64) -#endif - -#ifdef UNITY_EXCLUDE_FLOAT -#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) -#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) -#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrFloat) -#else -#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UnityAssertFloatsWithin((_UF)(delta), (_UF)(expected), (_UF)(actual), (message), (UNITY_LINE_TYPE)line) -#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((_UF)(expected) * (_UF)UNITY_FLOAT_PRECISION, (_UF)expected, (_UF)actual, (UNITY_LINE_TYPE)line, message) -#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualFloatArray((_UF*)(expected), (_UF*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line) -#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_INF) -#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NEG_INF) -#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NAN) -#define UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_DET) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NOT_INF) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NOT_NEG_INF) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NOT_NAN) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NOT_DET) -#endif - -#ifdef UNITY_EXCLUDE_DOUBLE -#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) -#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) -#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)line, UnityStrErrDouble) -#else -#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UnityAssertDoublesWithin((_UD)(delta), (_UD)(expected), (_UD)(actual), (message), (UNITY_LINE_TYPE)line) -#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((_UD)(expected) * (_UD)UNITY_DOUBLE_PRECISION, (_UD)expected, (_UD)actual, (UNITY_LINE_TYPE)line, message) -#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualDoubleArray((_UD*)(expected), (_UD*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line) -#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_INF) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NEG_INF) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NAN) -#define UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_DET) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NOT_INF) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NOT_NEG_INF) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NOT_NAN) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)line, UNITY_FLOAT_IS_NOT_DET) -#endif - -//End of UNITY_INTERNALS_H -#endif diff --git a/tests/Kconfig b/tests/Kconfig deleted file mode 100644 index 89fbb3ec3..000000000 --- a/tests/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -# -# For a description of the syntax of this configuration file, -# see misc/tools/kconfig-language.txt. -# - -menu "Unity test framework" -source "$APPSDIR/tests/testing/Kconfig" -source "$APPSDIR/tests/unity/Kconfig" -source "$APPSDIR/tests/unity_usrsock/Kconfig" -source "$APPSDIR/tests/unity_ramtest/Kconfig" -endmenu diff --git a/tests/Make.defs b/tests/Make.defs deleted file mode 100644 index 336f8959f..000000000 --- a/tests/Make.defs +++ /dev/null @@ -1,37 +0,0 @@ -############################################################################ -# apps/tests/Make.defs -# Adds selected testing applications to apps/ build -# -# Copyright (C) 2015 Haltian Ltd. All rights reserved. -# Author: Roman Saveljev -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# 3. Neither the name NuttX nor the names of its contributors may be -# used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -############################################################################ - -include $(wildcard tests/*/Make.defs) diff --git a/tests/Makefile b/tests/Makefile deleted file mode 100644 index 3e31d5073..000000000 --- a/tests/Makefile +++ /dev/null @@ -1,114 +0,0 @@ -############################################################################ -# apps/tests/Makefile -# -# Copyright (C) 2015-2017 Haltian Ltd. All rights reserved. -# Author: Roman Saveljev -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# 3. Neither the name NuttX nor the names of its contributors may be -# used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -############################################################################ - --include $(TOPDIR)/.config # Current configuration --include $(TOPDIR)/Make.defs -include $(APPDIR)/Make.defs - -ASRCS = -AOBJS = $(ASRCS:.S=$(OBJEXT)) - -CSRCS = unity.c unity_fixture.c - -DEPPATH = --dep-path . -VPATH = . - -COBJS = $(CSRCS:.c=$(OBJEXT)) - -SRCS = $(ASRCS) $(CSRCS) -OBJS = $(AOBJS) $(COBJS) - -# Sub-directories - -# Wherever is a Makefile should be included -SUBDIRS = $(dir $(wildcard */Makefile)) - -# Sub-directories that might need context setup. Directories may need -# context setup for a variety of reasons, but the most common is because -# the example may be built as an NSH built-in function. - -# Projects that do not need the 'context' rule define it empty and/or -# variate the behavior according to the product configuration -CNTXTDIRS = $(SUBDIRS) - -all: .built - -.PHONY: context .depend depend clean distclean - -$(AOBJS): %$(OBJEXT): %.S - $(call ASSEMBLE, $<, $@) - -$(COBJS): %$(OBJEXT): %.c - $(call COMPILE, $<, $@) - -$(BIN): $(OBJS) - $(call ARCHIVE, $@, $(OBJS)) - -.built: $(OBJS) - $(call ARCHIVE, $(BIN), $(OBJS)) - @touch .built - -define SDIR_template -$(1)_$(2): - $(Q) $(MAKE) -C $(1) $(2) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" -endef - -$(foreach SDIR, $(CNTXTDIRS), $(eval $(call SDIR_template,$(SDIR),context))) -$(foreach SDIR, $(SUBDIRS), $(eval $(call SDIR_template,$(SDIR),depend))) -$(foreach SDIR, $(SUBDIRS), $(eval $(call SDIR_template,$(SDIR),clean))) -$(foreach SDIR, $(SUBDIRS), $(eval $(call SDIR_template,$(SDIR),distclean))) - -install: - -context: $(foreach SDIR, $(CNTXTDIRS), $(SDIR)_context) - -.depend: Makefile $(SRCS) - $(Q) $(MKDEP) $(DEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep - $(Q) touch $@ - -depend: $(foreach SDIR, $(SUBDIRS), $(SDIR)_depend) .depend - -clean: $(foreach SDIR, $(SUBDIRS), $(SDIR)_clean) - $(call DELFILE, $(BIN)) - $(call CLEAN) - -distclean: $(foreach SDIR, $(SUBDIRS), $(SDIR)_distclean) - $(call DELFILE, Make.dep) - $(call DELFILE, .depend) - --include Make.dep - -.PHONY: preconfig -preconfig: diff --git a/tests/README.txt b/tests/README.txt deleted file mode 100644 index 7bf92a91f..000000000 --- a/tests/README.txt +++ /dev/null @@ -1,34 +0,0 @@ -README -^^^^^^ - -This folder hosts NuttX unit test framework source files. - -INTRODUCTION -^^^^^^^^^^^^ - -NuttX unit test framework is based on Unity (https://github.com/ThrowTheSwitch/Unity). -The source code bears minimal changes and most of the additional functionality is brought -through the extension. - -NUTTX-SPECIFIC ISSUES -^^^^^^^^^^^^^^^^^^^^^ - -Unity relies on setjmp/longjmp to be available, so a testcase can be aborted. While the -functionality exists in simulator builds, the hardware environment does not have it. To -provide the same baseline we run test bodies and other abortable parts in their own threads. -The main thread blocks until a spawn exits. Thus we create the same context as offered by -setjmp/longjmp. - -RUNNING TESTS -^^^^^^^^^^^^^ - -Tests can be executed both in simulator and in the target. The test application can be built-in -into NSH or provide application entry point. - -Test application supports command line interface: - - application [--list] [test [test...]] - - --list - Lists all available testcases from all included modules - -Test is identified by its module name and function name. diff --git a/tests/docs/Unity_Summary.txt b/tests/docs/Unity_Summary.txt deleted file mode 100644 index a157aaced..000000000 --- a/tests/docs/Unity_Summary.txt +++ /dev/null @@ -1,216 +0,0 @@ -============== -Unity Test API -============== - -[Copyright (c) 2007 - 2012 Unity Project by Mike Karlesky, Mark VanderVoord, and Greg Williams] - -------------- -Running Tests -------------- - -RUN_TEST(func, linenum) - -Each Test is run within the macro RUN_TEST. This macro performs necessary setup before the test is called and handles cleanup and result tabulation afterwards. - --------------- -Ignoring Tests --------------- - -There are times when a test is incomplete or not valid for some reason. At these times, TEST_IGNORE can be called. Control will immediately be returned to the caller of the test, and no failures will be returned. - -TEST_IGNORE() - -Ignore this test and return immediately - -TEST_IGNORE_MESSAGE (message) - -Ignore this test and return immediately. Output a message stating why the test was ignored. - --------------- -Aborting Tests --------------- - -There are times when a test will contain an infinite loop on error conditions, or there may be reason to escape from the test early without executing the rest of the test. A pair of macros support this functionality in Unity. The first (TEST_PROTECT) sets up the feature, and handles emergency abort cases. TEST_ABORT can then be used at any time within the tests to return to the last TEST_PROTECT call. - -TEST_PROTECT() - -Setup and Catch macro - -TEST_ABORT() - -Abort Test macro - -Example: - -main() -{ - if (TEST_PROTECT() == 0) - { - MyTest(); - } -} - -If MyTest calls TEST_ABORT, program control will immediately return to TEST_PROTECT with a non-zero return value. - - -======================= -Unity Assertion Summary -======================= - --------------------- -Basic Validity Tests --------------------- - -TEST_ASSERT_TRUE(condition) - -Evaluates whatever code is in condition and fails if it evaluates to false - -TEST_ASSERT_FALSE(condition) - -Evaluates whatever code is in condition and fails if it evaluates to true - -TEST_ASSERT(condition) - -Another way of calling TEST_ASSERT_TRUE - -TEST_ASSERT_UNLESS(condition) - -Another way of calling TEST_ASSERT_FALSE - -TEST_FAIL() -TEST_FAIL_MESSAGE(message) - -This test is automatically marked as a failure. The message is output stating why. - ------------------------------- -Numerical Assertions: Integers ------------------------------- - -TEST_ASSERT_EQUAL_INT(expected, actual) -TEST_ASSERT_EQUAL_INT8(expected, actual) -TEST_ASSERT_EQUAL_INT16(expected, actual) -TEST_ASSERT_EQUAL_INT32(expected, actual) -TEST_ASSERT_EQUAL_INT64(expected, actual) - -Compare two integers for equality and display errors as signed integers. A cast will be performed -to your natural integer size so often this can just be used. When you need to specify the exact size, -like when comparing arrays, you can use a specific version: - -TEST_ASSERT_EQUAL_UINT(expected, actual) -TEST_ASSERT_EQUAL_UINT8(expected, actual) -TEST_ASSERT_EQUAL_UINT16(expected, actual) -TEST_ASSERT_EQUAL_UINT32(expected, actual) -TEST_ASSERT_EQUAL_UINT64(expected, actual) - -Compare two integers for equality and display errors as unsigned integers. Like INT, there are -variants for different sizes also. - -TEST_ASSERT_EQUAL_HEX(expected, actual) -TEST_ASSERT_EQUAL_HEX8(expected, actual) -TEST_ASSERT_EQUAL_HEX16(expected, actual) -TEST_ASSERT_EQUAL_HEX32(expected, actual) -TEST_ASSERT_EQUAL_HEX64(expected, actual) - -Compares two integers for equality and display errors as hexadecimal. Like the other integer comparisons, -you can specify the size... here the size will also effect how many nibbles are shown (for example, HEX16 -will show 4 nibbles). - -_ARRAY - -You can append _ARRAY to any of these macros to make an array comparison of that type. Here you will -need to care a bit more about the actual size of the value being checked. You will also specify an -additional argument which is the number of elements to compare. For example: - -TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, elements) - -TEST_ASSERT_EQUAL(expected, actual) - -Another way of calling TEST_ASSERT_EQUAL_INT - -TEST_ASSERT_INT_WITHIN(delta, expected, actual) - -Asserts that the actual value is within plus or minus delta of the expected value. This also comes in -size specific variants. - - ------------------------------ -Numerical Assertions: Bitwise ------------------------------ - -TEST_ASSERT_BITS(mask, expected, actual) - -Use an integer mask to specify which bits should be compared between two other integers. High bits in the mask are compared, low bits ignored. - -TEST_ASSERT_BITS_HIGH(mask, actual) - -Use an integer mask to specify which bits should be inspected to determine if they are all set high. High bits in the mask are compared, low bits ignored. - -TEST_ASSERT_BITS_LOW(mask, actual) - -Use an integer mask to specify which bits should be inspected to determine if they are all set low. High bits in the mask are compared, low bits ignored. - -TEST_ASSERT_BIT_HIGH(bit, actual) - -Test a single bit and verify that it is high. The bit is specified 0-31 for a 32-bit integer. - -TEST_ASSERT_BIT_LOW(bit, actual) - -Test a single bit and verify that it is low. The bit is specified 0-31 for a 32-bit integer. - ----------------------------- -Numerical Assertions: Floats ----------------------------- - -TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual) - -Asserts that the actual value is within plus or minus delta of the expected value. - -TEST_ASSERT_EQUAL_FLOAT(expected, actual) -TEST_ASSERT_EQUAL_DOUBLE(expected, actual) - -Asserts that two floating point values are "equal" within a small % delta of the expected value. - ------------------ -String Assertions ------------------ - -TEST_ASSERT_EQUAL_STRING(expected, actual) - -Compare two null-terminate strings. Fail if any character is different or if the lengths are different. - -TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, actual, message) - -Compare two null-terminate strings. Fail if any character is different or if the lengths are different. Output a custom message on failure. - ------------------- -Pointer Assertions ------------------- - -Most pointer operations can be performed by simply using the integer comparisons above. However, a couple of special cases are added for clarity. - -TEST_ASSERT_NULL(pointer) - -Fails if the pointer is not equal to NULL - -TEST_ASSERT_NOT_NULL(pointer) - -Fails if the pointer is equal to NULL - - ------------------ -Memory Assertions ------------------ - -TEST_ASSERT_EQUAL_MEMORY(expected, actual, len) - -Compare two blocks of memory. This is a good generic assertion for types that can't be coerced into acting like -standard types... but since it's a memory compare, you have to be careful that your data types are packed. - --------- -_MESSAGE --------- - -you can append _MESSAGE to any of the macros to make them take an additional argument. This argument -is a string that will be printed at the end of the failure strings. This is useful for specifying more -information about the problem. - diff --git a/tests/docs/license.txt b/tests/docs/license.txt deleted file mode 100644 index d0f635fa3..000000000 --- a/tests/docs/license.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams - -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. diff --git a/tests/testing/.built b/tests/testing/.built deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/testing/Kconfig b/tests/testing/Kconfig deleted file mode 100644 index ae2bf3130..000000000 --- a/tests/testing/Kconfig +++ /dev/null @@ -1,4 +0,0 @@ -# -# For a description of the syntax of this configuration file, -# see misc/tools/kconfig-language.txt. -# diff --git a/tests/testing/Make.defs b/tests/testing/Make.defs deleted file mode 100644 index fc761474f..000000000 --- a/tests/testing/Make.defs +++ /dev/null @@ -1,37 +0,0 @@ -############################################################################ -# apps/tests/unity/Make.defs -# Adds selected testing applications to apps/ build -# -# Copyright (C) 2015 Haltian Ltd. All rights reserved. -# Author: Roman Saveljev -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# 3. Neither the name NuttX nor the names of its contributors may be -# used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -############################################################################ - -CONFIGURED_APPS += tests/testing diff --git a/tests/testing/Makefile b/tests/testing/Makefile deleted file mode 100644 index 2ae3d138e..000000000 --- a/tests/testing/Makefile +++ /dev/null @@ -1,95 +0,0 @@ -############################################################################ -# testing/Makefile -# -# Copyright (C) 2015 Haltian Ltd. All rights reserved. -# Author: Roman Saveljev -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# 3. Neither the name NuttX nor the names of its contributors may be -# used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -############################################################################ - --include $(TOPDIR)/.config --include $(TOPDIR)/Make.defs -include $(APPDIR)/Make.defs - -ASRCS = -CSRCS = unity.c unity_fixture.c - -AOBJS = $(ASRCS:.S=$(OBJEXT)) -COBJS = $(CSRCS:.c=$(OBJEXT)) - -SRCS = $(ASRCS) $(CSRCS) -OBJS = $(AOBJS) $(COBJS) - -ifeq ($(CONFIG_WINDOWS_NATIVE),y) - BIN = ..\..\libapps$(LIBEXT) -else -ifeq ($(WINTOOL),y) - BIN = ..\\..\\libapps$(LIBEXT) -else - BIN = ../../libapps$(LIBEXT) -endif -endif - -ROOTDEPPATH = --dep-path . -VPATH = - -# Build targets - -all: .built -.PHONY: context .depend depend clean distclean - -$(AOBJS): %$(OBJEXT): %.S - $(call ASSEMBLE, $<, $@) - -$(COBJS): %$(OBJEXT): %.c - $(call COMPILE, $<, $@) - -.built: $(OBJS) - $(call ARCHIVE, $(BIN), $(OBJS)) - @touch .built - -install: - -context: - -.depend: Makefile $(SRCS) - @$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep - @touch $@ - -depend: .depend - -clean: - $(call DELFILE, .built) - $(call CLEAN) - -distclean: clean - $(call DELFILE, Make.dep) - $(call DELFILE, .depend) - --include Make.dep diff --git a/tests/testing/unity.c b/tests/testing/unity.c deleted file mode 100644 index 689103b6d..000000000 --- a/tests/testing/unity.c +++ /dev/null @@ -1,1268 +0,0 @@ -/* ========================================================================= - Unity Project - A Test Framework for C - Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams - [Released under MIT License. Please refer to license.txt for details] -============================================================================ */ - -#include -#include - -#define UNITY_FAIL_AND_BAIL { Unity.CurrentTestFailed = 1; UnityAbort(); } -#define UNITY_IGNORE_AND_BAIL { Unity.CurrentTestIgnored = 1; UnityAbort(); } -/// return prematurely if we are already in failure or ignore state -#define UNITY_SKIP_EXECUTION { if ((Unity.CurrentTestFailed != 0) || (Unity.CurrentTestIgnored != 0)) {return;} } -#define UNITY_PRINT_EOL { UNITY_OUTPUT_CHAR('\n'); } - -#define UNITY_MSEC_IN_USEC 1000 -#define UNITY_MIN_TIMEOUT_MSEC 200 - -#define SIG_UNITYSTOP 15 - -struct _Unity Unity; - -const char UnityStrOk[] = "OK"; -const char UnityStrPass[] = "PASS"; -const char UnityStrFail[] = "FAIL"; -const char UnityStrIgnore[] = "IGNORE"; -const char UnityStrNull[] = "NULL"; -const char UnityStrSpacer[] = ". "; -const char UnityStrExpected[] = " Expected "; -const char UnityStrWas[] = " Was "; -const char UnityStrTo[] = " To "; -const char UnityStrElement[] = " Element "; -const char UnityStrByte[] = " Byte "; -const char UnityStrMemory[] = " Memory Mismatch."; -const char UnityStrDelta[] = " Values Not Within Delta "; -const char UnityStrPointless[] = " You Asked Me To Compare Nothing, Which Was Pointless."; -const char UnityStrNullPointerForExpected[] = " Expected pointer to be NULL"; -const char UnityStrNullPointerForActual[] = " Actual pointer was NULL"; -const char UnityStrNot[] = "Not "; -const char UnityStrInf[] = "Infinity"; -const char UnityStrNegInf[] = "Negative Infinity"; -const char UnityStrNaN[] = "NaN"; -const char UnityStrDet[] = "Determinate"; -const char UnityStrErrFloat[] = "Unity Floating Point Disabled"; -const char UnityStrErrDouble[] = "Unity Double Precision Disabled"; -const char UnityStrErr64[] = "Unity 64-bit Support Disabled"; -const char UnityStrBreaker[] = "-----------------------"; -const char UnityStrResultsTests[] = " Tests "; -const char UnityStrResultsFailures[] = " Failures "; -const char UnityStrResultsIgnored[] = " Ignored "; - -#ifndef UNITY_EXCLUDE_FLOAT -// Dividing by these constants produces +/- infinity. -// The rationale is given in UnityAssertFloatIsInf's body. -static const _UF f_zero = 0.0f; -#ifndef UNITY_EXCLUDE_DOUBLE -static const _UD d_zero = 0.0; -#endif -#endif - -// compiler-generic print formatting masks -const _U_UINT UnitySizeMask[] = -{ - 255u, // 0xFF - 65535u, // 0xFFFF - 65535u, - 4294967295u, // 0xFFFFFFFF - 4294967295u, - 4294967295u, - 4294967295u -#ifdef UNITY_SUPPORT_64 - ,0xFFFFFFFFFFFFFFFF -#endif -}; - -struct UnityTimeoutAction -{ - _U_UINT timeout_msec; - pthread_t thread; - bool cancel_protected; -}; - -void UnityPrintFail(void); -void UnityPrintOk(void); - -static void UnityAbort(void) noreturn_function; - -static void UnityAbort(void) -{ - pthread_exit((void*)1); -} - -//----------------------------------------------- -// Pretty Printers & Test Result Output Handlers -//----------------------------------------------- - -void UnityPrint(const char* string) -{ - const char* pch = string; - - if (pch != NULL) - { - while (*pch) - { - // printable characters plus CR & LF are printed - if ((*pch <= 126) && (*pch >= 32)) - { - UNITY_OUTPUT_CHAR(*pch); - } - //write escaped carriage returns - else if (*pch == 13) - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('r'); - } - //write escaped line feeds - else if (*pch == 10) - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('n'); - } - // unprintable characters are shown as codes - else - { - UNITY_OUTPUT_CHAR('\\'); - UnityPrintNumberHex((_U_UINT)*pch, 2); - } - pch++; - } - } -} - -//----------------------------------------------- -void UnityPrintNumberByStyle(const _U_SINT number, const UNITY_DISPLAY_STYLE_T style) -{ - if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) - { - UnityPrintNumber(number); - } - else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT) - { - UnityPrintNumberUnsigned( (_U_UINT)number & UnitySizeMask[((_U_UINT)style & (_U_UINT)0x0F) - 1] ); - } - else - { - UnityPrintNumberHex((_U_UINT)number, (char)((style & 0x000F) << 1)); - } -} - -//----------------------------------------------- -/// basically do an itoa using as little ram as possible -void UnityPrintNumber(const _U_SINT number_to_print) -{ - _U_SINT divisor = 1; - _U_SINT next_divisor; - _U_UINT number; - - if (number_to_print == (1l << (UNITY_LONG_WIDTH-1))) - { - //The largest representable negative number - UNITY_OUTPUT_CHAR('-'); - number = (1ul << (UNITY_LONG_WIDTH-1)); - } - else if (number_to_print < 0) - { - //Some other negative number - UNITY_OUTPUT_CHAR('-'); - number = (_U_UINT)(-number_to_print); - } - else - { - //Positive number - number = (_U_UINT)number_to_print; - } - - // figure out initial divisor - while (number / divisor > 9) - { - next_divisor = divisor * 10; - if (next_divisor > divisor) - divisor = next_divisor; - else - break; - } - - // now mod and print, then divide divisor - do - { - UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10))); - divisor /= 10; - } - while (divisor > 0); -} - -//----------------------------------------------- -/// basically do an itoa using as little ram as possible -void UnityPrintNumberUnsigned(const _U_UINT number) -{ - _U_UINT divisor = 1; - _U_UINT next_divisor; - - // figure out initial divisor - while (number / divisor > 9) - { - next_divisor = divisor * 10; - if (next_divisor > divisor) - divisor = next_divisor; - else - break; - } - - // now mod and print, then divide divisor - do - { - UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10))); - divisor /= 10; - } - while (divisor > 0); -} - -//----------------------------------------------- -void UnityPrintNumberHex(const _U_UINT number, const char nibbles_to_print) -{ - _U_UINT nibble; - char nibbles = nibbles_to_print; - UNITY_OUTPUT_CHAR('0'); - UNITY_OUTPUT_CHAR('x'); - - while (nibbles > 0) - { - nibble = (number >> (--nibbles << 2)) & 0x0000000F; - if (nibble <= 9) - { - UNITY_OUTPUT_CHAR((char)('0' + nibble)); - } - else - { - UNITY_OUTPUT_CHAR((char)('A' - 10 + nibble)); - } - } -} - -//----------------------------------------------- -void UnityPrintMask(const _U_UINT mask, const _U_UINT number) -{ - _U_UINT current_bit = (_U_UINT)1 << (UNITY_INT_WIDTH - 1); - _US32 i; - - for (i = 0; i < UNITY_INT_WIDTH; i++) - { - if (current_bit & mask) - { - if (current_bit & number) - { - UNITY_OUTPUT_CHAR('1'); - } - else - { - UNITY_OUTPUT_CHAR('0'); - } - } - else - { - UNITY_OUTPUT_CHAR('X'); - } - current_bit = current_bit >> 1; - } -} - -//----------------------------------------------- -#ifdef UNITY_FLOAT_VERBOSE -#include -void UnityPrintFloat(_UF number) -{ - char TempBuffer[32]; - sprintf(TempBuffer, "%.6f", number); - UnityPrint(TempBuffer); -} -#endif - -//----------------------------------------------- - -void UnityPrintFail(void) -{ - UnityPrint(UnityStrFail); -} - -void UnityPrintOk(void) -{ - UnityPrint(UnityStrOk); -} - -//----------------------------------------------- -static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line) -{ - UnityPrint(file); - UNITY_OUTPUT_CHAR(':'); - UnityPrintNumber((_U_SINT)line); - UNITY_OUTPUT_CHAR(':'); - UnityPrint(Unity.CurrentTestName); - UNITY_OUTPUT_CHAR(':'); -} - -//----------------------------------------------- -static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line) -{ - UnityTestResultsBegin(Unity.TestFile, line); - UnityPrint(UnityStrFail); - UNITY_OUTPUT_CHAR(':'); -} - -//----------------------------------------------- -void UnityConcludeTest(void) -{ - if (Unity.CurrentTestIgnored) - { - Unity.TestIgnores++; - } - else if (!Unity.CurrentTestFailed) - { - UnityTestResultsBegin(Unity.TestFile, Unity.CurrentTestLineNumber); - UnityPrint(UnityStrPass); - } - else - { - Unity.TestFailures++; - } - - Unity.CurrentTestFailed = 0; - Unity.CurrentTestIgnored = 0; - UNITY_PRINT_EOL; -} - -//----------------------------------------------- -static void UnityAddMsgIfSpecified(const char* msg) -{ - if (msg) - { - UnityPrint(UnityStrSpacer); - UnityPrint(msg); - } -} - -//----------------------------------------------- -static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual) -{ - UnityPrint(UnityStrExpected); - if (expected != NULL) - { - UNITY_OUTPUT_CHAR('\''); - UnityPrint(expected); - UNITY_OUTPUT_CHAR('\''); - } - else - { - UnityPrint(UnityStrNull); - } - UnityPrint(UnityStrWas); - if (actual != NULL) - { - UNITY_OUTPUT_CHAR('\''); - UnityPrint(actual); - UNITY_OUTPUT_CHAR('\''); - } - else - { - UnityPrint(UnityStrNull); - } -} - -//----------------------------------------------- -// Assertion & Control Helpers -//----------------------------------------------- - -static int UnityCheckArraysForNull(UNITY_PTR_ATTRIBUTE const void* expected, UNITY_PTR_ATTRIBUTE const void* actual, const UNITY_LINE_TYPE lineNumber, const char* msg) -{ - //return true if they are both NULL - if ((expected == NULL) && (actual == NULL)) - return 1; - - //throw error if just expected is NULL - if (expected == NULL) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrNullPointerForExpected); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - - //throw error if just actual is NULL - if (actual == NULL) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrNullPointerForActual); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - - //return false if neither is NULL - return 0; -} - -//----------------------------------------------- -// Assertion Functions -//----------------------------------------------- - -void UnityAssertBits(const _U_SINT mask, - const _U_SINT expected, - const _U_SINT actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - UNITY_SKIP_EXECUTION; - - if ((mask & expected) != (mask & actual)) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrExpected); - UnityPrintMask((_U_UINT)mask, (_U_UINT)expected); - UnityPrint(UnityStrWas); - UnityPrintMask((_U_UINT)mask, (_U_UINT)actual); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -//----------------------------------------------- -void UnityAssertEqualNumber(const _U_SINT expected, - const _U_SINT actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_DISPLAY_STYLE_T style) -{ - UNITY_SKIP_EXECUTION; - - if (expected != actual) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(expected, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(actual, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -//----------------------------------------------- -void UnityAssertEqualIntArray(UNITY_PTR_ATTRIBUTE const void* expected, - UNITY_PTR_ATTRIBUTE const void* actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_DISPLAY_STYLE_T style) -{ - _UU32 elements = num_elements; - UNITY_PTR_ATTRIBUTE const _US8* ptr_exp = (UNITY_PTR_ATTRIBUTE const _US8*)expected; - UNITY_PTR_ATTRIBUTE const _US8* ptr_act = (UNITY_PTR_ATTRIBUTE const _US8*)actual; - - UNITY_SKIP_EXECUTION; - - if (elements == 0) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrPointless); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - - if (UnityCheckArraysForNull((UNITY_PTR_ATTRIBUTE const void*)expected, (UNITY_PTR_ATTRIBUTE const void*)actual, lineNumber, msg) == 1) - return; - - // If style is UNITY_DISPLAY_STYLE_INT, we'll fall into the default case rather than the INT16 or INT32 (etc) case - // as UNITY_DISPLAY_STYLE_INT includes a flag for UNITY_DISPLAY_RANGE_AUTO, which the width-specific - // variants do not. Therefore remove this flag. - switch(style & (UNITY_DISPLAY_STYLE_T)(~UNITY_DISPLAY_RANGE_AUTO)) - { - case UNITY_DISPLAY_STYLE_HEX8: - case UNITY_DISPLAY_STYLE_INT8: - case UNITY_DISPLAY_STYLE_UINT8: - while (elements--) - { - if (*ptr_exp != *ptr_act) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(*ptr_exp, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(*ptr_act, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_exp += 1; - ptr_act += 1; - } - break; - case UNITY_DISPLAY_STYLE_HEX16: - case UNITY_DISPLAY_STYLE_INT16: - case UNITY_DISPLAY_STYLE_UINT16: - while (elements--) - { - if (*(UNITY_PTR_ATTRIBUTE _US16*)ptr_exp != *(UNITY_PTR_ATTRIBUTE _US16*)ptr_act) - { - if (*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US16*)ptr_act) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_exp, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_act, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_exp += 2; - ptr_act += 2; - } - ptr_exp += 2; - ptr_act += 2; - } - break; -#ifdef UNITY_SUPPORT_64 - case UNITY_DISPLAY_STYLE_HEX64: - case UNITY_DISPLAY_STYLE_INT64: - case UNITY_DISPLAY_STYLE_UINT64: - while (elements--) - { - if (*(UNITY_PTR_ATTRIBUTE _US64*)ptr_exp != *(UNITY_PTR_ATTRIBUTE _US64*)ptr_act) - { - if (*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US64*)ptr_act) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_exp, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_act, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_exp += 8; - ptr_act += 8; - } - ptr_exp += 8; - ptr_act += 8; - } - break; -#endif - default: - while (elements--) - { - if (*(UNITY_PTR_ATTRIBUTE _US32*)ptr_exp != *(UNITY_PTR_ATTRIBUTE _US32*)ptr_act) - { - if (*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US32*)ptr_act) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_exp, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_act, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_exp += 4; - ptr_act += 4; - } - ptr_exp += 4; - ptr_act += 4; - } - break; - } -} - -//----------------------------------------------- -#ifndef UNITY_EXCLUDE_FLOAT -void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const _UF* expected, - UNITY_PTR_ATTRIBUTE const _UF* actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UU32 elements = num_elements; - UNITY_PTR_ATTRIBUTE const _UF* ptr_expected = expected; - UNITY_PTR_ATTRIBUTE const _UF* ptr_actual = actual; - _UF diff, tol; - - UNITY_SKIP_EXECUTION; - - if (elements == 0) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrPointless); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - - if (UnityCheckArraysForNull((UNITY_PTR_ATTRIBUTE const void*)expected, (UNITY_PTR_ATTRIBUTE const void*)actual, lineNumber, msg) == 1) - return; - - while (elements--) - { - diff = *ptr_expected - *ptr_actual; - if (diff < 0.0f) - diff = 0.0f - diff; - tol = UNITY_FLOAT_PRECISION **ptr_expected; - if (tol < 0.0f) - tol = 0.0f - tol; - - //This first part of this condition will catch any NaN or Infinite values - if ((diff * 0.0f != 0.0f) || (diff > tol)) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); -#ifdef UNITY_FLOAT_VERBOSE - UnityPrint(UnityStrExpected); - UnityPrintFloat(*ptr_expected); - UnityPrint(UnityStrWas); - UnityPrintFloat(*ptr_actual); -#else - UnityPrint(UnityStrDelta); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_expected++; - ptr_actual++; - } -} - -//----------------------------------------------- -void UnityAssertFloatsWithin(const _UF delta, - const _UF expected, - const _UF actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UF diff = actual - expected; - _UF pos_delta = delta; - - UNITY_SKIP_EXECUTION; - - if (diff < 0.0f) - { - diff = 0.0f - diff; - } - if (pos_delta < 0.0f) - { - pos_delta = 0.0f - pos_delta; - } - - //This first part of this condition will catch any NaN or Infinite values - if ((diff * 0.0f != 0.0f) || (pos_delta < diff)) - { - UnityTestResultsFailBegin(lineNumber); -#ifdef UNITY_FLOAT_VERBOSE - UnityPrint(UnityStrExpected); - UnityPrintFloat(expected); - UnityPrint(UnityStrWas); - UnityPrintFloat(actual); -#else - UnityPrint(UnityStrDelta); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -//----------------------------------------------- -void UnityAssertFloatSpecial(const _UF actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_FLOAT_TRAIT_T style) -{ - const char* trait_names[] = { UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet }; - _U_SINT should_be_trait = ((_U_SINT)style & 1); - _U_SINT is_trait = !should_be_trait; - _U_SINT trait_index = style >> 1; - - UNITY_SKIP_EXECUTION; - - switch(style) - { - //To determine Inf / Neg Inf, we compare to an Inf / Neg Inf value we create on the fly - //We are using a variable to hold the zero value because some compilers complain about dividing by zero otherwise - case UNITY_FLOAT_IS_INF: - case UNITY_FLOAT_IS_NOT_INF: - is_trait = ((1.0f / f_zero) == actual) ? 1 : 0; - break; - case UNITY_FLOAT_IS_NEG_INF: - case UNITY_FLOAT_IS_NOT_NEG_INF: - is_trait = ((-1.0f / f_zero) == actual) ? 1 : 0; - break; - - //NaN is the only floating point value that does NOT equal itself. Therefore if Actual == Actual, then it is NOT NaN. - case UNITY_FLOAT_IS_NAN: - case UNITY_FLOAT_IS_NOT_NAN: - is_trait = (actual == actual) ? 0 : 1; - break; - - //A determinate number is non infinite and not NaN. (therefore the opposite of the two above) - case UNITY_FLOAT_IS_DET: - case UNITY_FLOAT_IS_NOT_DET: - if ( (actual != actual) || ((1.0f / f_zero) == actual) || ((-1.0f / f_zero) == actual) ) - is_trait = 0; - else - is_trait = 1; - break; - default: - ; - } - - if (is_trait != should_be_trait) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrExpected); - if (!should_be_trait) - UnityPrint(UnityStrNot); - UnityPrint(trait_names[trait_index]); - UnityPrint(UnityStrWas); -#ifdef UNITY_FLOAT_VERBOSE - UnityPrintFloat(actual); -#else - if (should_be_trait) - UnityPrint(UnityStrNot); - UnityPrint(trait_names[trait_index]); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -#endif //not UNITY_EXCLUDE_FLOAT - -//----------------------------------------------- -#ifndef UNITY_EXCLUDE_DOUBLE -void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const _UD* expected, - UNITY_PTR_ATTRIBUTE const _UD* actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UU32 elements = num_elements; - UNITY_PTR_ATTRIBUTE const _UD* ptr_expected = expected; - UNITY_PTR_ATTRIBUTE const _UD* ptr_actual = actual; - _UD diff, tol; - - UNITY_SKIP_EXECUTION; - - if (elements == 0) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrPointless); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - - if (UnityCheckArraysForNull((UNITY_PTR_ATTRIBUTE void*)expected, (UNITY_PTR_ATTRIBUTE void*)actual, lineNumber, msg) == 1) - return; - - while (elements--) - { - diff = *ptr_expected - *ptr_actual; - if (diff < 0.0) - diff = 0.0 - diff; - tol = UNITY_DOUBLE_PRECISION **ptr_expected; - if (tol < 0.0) - tol = 0.0 - tol; - - //This first part of this condition will catch any NaN or Infinite values - if ((diff * 0.0 != 0.0) || (diff > tol)) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); -#ifdef UNITY_DOUBLE_VERBOSE - UnityPrint(UnityStrExpected); - UnityPrintFloat((float)(*ptr_expected)); - UnityPrint(UnityStrWas); - UnityPrintFloat((float)(*ptr_actual)); -#else - UnityPrint(UnityStrDelta); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_expected++; - ptr_actual++; - } -} - -//----------------------------------------------- -void UnityAssertDoublesWithin(const _UD delta, - const _UD expected, - const _UD actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UD diff = actual - expected; - _UD pos_delta = delta; - - UNITY_SKIP_EXECUTION; - - if (diff < 0.0) - { - diff = 0.0 - diff; - } - if (pos_delta < 0.0) - { - pos_delta = 0.0 - pos_delta; - } - - //This first part of this condition will catch any NaN or Infinite values - if ((diff * 0.0 != 0.0) || (pos_delta < diff)) - { - UnityTestResultsFailBegin(lineNumber); -#ifdef UNITY_DOUBLE_VERBOSE - UnityPrint(UnityStrExpected); - UnityPrintFloat((float)expected); - UnityPrint(UnityStrWas); - UnityPrintFloat((float)actual); -#else - UnityPrint(UnityStrDelta); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -//----------------------------------------------- - -void UnityAssertDoubleSpecial(const _UD actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_FLOAT_TRAIT_T style) -{ - const char* trait_names[] = { UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet }; - _U_SINT should_be_trait = ((_U_SINT)style & 1); - _U_SINT is_trait = !should_be_trait; - _U_SINT trait_index = style >> 1; - - UNITY_SKIP_EXECUTION; - - switch(style) - { - //To determine Inf / Neg Inf, we compare to an Inf / Neg Inf value we create on the fly - //We are using a variable to hold the zero value because some compilers complain about dividing by zero otherwise - case UNITY_FLOAT_IS_INF: - case UNITY_FLOAT_IS_NOT_INF: - is_trait = ((1.0 / d_zero) == actual) ? 1 : 0; - break; - case UNITY_FLOAT_IS_NEG_INF: - case UNITY_FLOAT_IS_NOT_NEG_INF: - is_trait = ((-1.0 / d_zero) == actual) ? 1 : 0; - break; - - //NaN is the only floating point value that does NOT equal itself. Therefore if Actual == Actual, then it is NOT NaN. - case UNITY_FLOAT_IS_NAN: - case UNITY_FLOAT_IS_NOT_NAN: - is_trait = (actual == actual) ? 0 : 1; - break; - - //A determinate number is non infinite and not NaN. (therefore the opposite of the two above) - case UNITY_FLOAT_IS_DET: - case UNITY_FLOAT_IS_NOT_DET: - if ( (actual != actual) || ((1.0 / d_zero) == actual) || ((-1.0 / d_zero) == actual) ) - is_trait = 0; - else - is_trait = 1; - break; - default: - ; - } - - if (is_trait != should_be_trait) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrExpected); - if (!should_be_trait) - UnityPrint(UnityStrNot); - UnityPrint(trait_names[trait_index]); - UnityPrint(UnityStrWas); -#ifdef UNITY_DOUBLE_VERBOSE - UnityPrintFloat(actual); -#else - if (should_be_trait) - UnityPrint(UnityStrNot); - UnityPrint(trait_names[trait_index]); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - - -#endif // not UNITY_EXCLUDE_DOUBLE - -//----------------------------------------------- -void UnityAssertNumbersWithin( const _U_SINT delta, - const _U_SINT expected, - const _U_SINT actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_DISPLAY_STYLE_T style) -{ - UNITY_SKIP_EXECUTION; - - if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) - { - if (actual > expected) - Unity.CurrentTestFailed = ((actual - expected) > delta); - else - Unity.CurrentTestFailed = ((expected - actual) > delta); - } - else - { - if ((_U_UINT)actual > (_U_UINT)expected) - Unity.CurrentTestFailed = ((_U_UINT)(actual - expected) > (_U_UINT)delta); - else - Unity.CurrentTestFailed = ((_U_UINT)(expected - actual) > (_U_UINT)delta); - } - - if (Unity.CurrentTestFailed) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrDelta); - UnityPrintNumberByStyle(delta, style); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(expected, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(actual, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -//----------------------------------------------- -void UnityAssertEqualString(const char* expected, - const char* actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UU32 i; - - UNITY_SKIP_EXECUTION; - - // if both pointers not null compare the strings - if (expected && actual) - { - for (i = 0; expected[i] || actual[i]; i++) - { - if (expected[i] != actual[i]) - { - Unity.CurrentTestFailed = 1; - break; - } - } - } - else - { - // handle case of one pointers being null (if both null, test should pass) - if (expected != actual) - { - Unity.CurrentTestFailed = 1; - } - } - - if (Unity.CurrentTestFailed) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrintExpectedAndActualStrings(expected, actual); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -//----------------------------------------------- -void UnityAssertEqualStringArray( const char** expected, - const char** actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UU32 i, j = 0; - - UNITY_SKIP_EXECUTION; - - // if no elements, it's an error - if (num_elements == 0) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrPointless); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - - if (UnityCheckArraysForNull((UNITY_PTR_ATTRIBUTE void*)expected, (UNITY_PTR_ATTRIBUTE void*)actual, lineNumber, msg) == 1) - return; - - do - { - // if both pointers not null compare the strings - if (expected[j] && actual[j]) - { - for (i = 0; expected[j][i] || actual[j][i]; i++) - { - if (expected[j][i] != actual[j][i]) - { - Unity.CurrentTestFailed = 1; - break; - } - } - } - else - { - // handle case of one pointers being null (if both null, test should pass) - if (expected[j] != actual[j]) - { - Unity.CurrentTestFailed = 1; - } - } - - if (Unity.CurrentTestFailed) - { - UnityTestResultsFailBegin(lineNumber); - if (num_elements > 1) - { - UnityPrint(UnityStrElement); - UnityPrintNumberByStyle((j), UNITY_DISPLAY_STYLE_UINT); - } - UnityPrintExpectedAndActualStrings((const char*)(expected[j]), (const char*)(actual[j])); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - } - while (++j < num_elements); -} - -//----------------------------------------------- -void UnityAssertEqualMemory( UNITY_PTR_ATTRIBUTE const void* expected, - UNITY_PTR_ATTRIBUTE const void* actual, - const _UU32 length, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - UNITY_PTR_ATTRIBUTE const unsigned char* ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected; - UNITY_PTR_ATTRIBUTE const unsigned char* ptr_act = (UNITY_PTR_ATTRIBUTE const unsigned char*)actual; - _UU32 elements = num_elements; - _UU32 bytes; - - UNITY_SKIP_EXECUTION; - - if ((elements == 0) || (length == 0)) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrPointless); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - - if (UnityCheckArraysForNull((UNITY_PTR_ATTRIBUTE const void*)expected, (UNITY_PTR_ATTRIBUTE const void*)actual, lineNumber, msg) == 1) - return; - - while (elements--) - { - ///////////////////////////////////// - bytes = length; - while (bytes--) - { - if (*ptr_exp != *ptr_act) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrMemory); - if (num_elements > 1) - { - UnityPrint(UnityStrElement); - UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT); - } - UnityPrint(UnityStrByte); - UnityPrintNumberByStyle((length - bytes - 1), UNITY_DISPLAY_STYLE_UINT); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(*ptr_exp, UNITY_DISPLAY_STYLE_HEX8); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(*ptr_act, UNITY_DISPLAY_STYLE_HEX8); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_exp += 1; - ptr_act += 1; - } - ///////////////////////////////////// - - } -} - -//----------------------------------------------- -// Control Functions -//----------------------------------------------- - -void UnityFail(const char* msg, const UNITY_LINE_TYPE line) -{ - UNITY_SKIP_EXECUTION; - - UnityTestResultsBegin(Unity.TestFile, line); - UnityPrintFail(); - if (msg != NULL) - { - UNITY_OUTPUT_CHAR(':'); - if (msg[0] != ' ') - { - UNITY_OUTPUT_CHAR(' '); - } - UnityPrint(msg); - } - UNITY_FAIL_AND_BAIL; -} - -//----------------------------------------------- -void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line) -{ - UNITY_SKIP_EXECUTION; - - UnityTestResultsBegin(Unity.TestFile, line); - UnityPrint(UnityStrIgnore); - if (msg != NULL) - { - UNITY_OUTPUT_CHAR(':'); - UNITY_OUTPUT_CHAR(' '); - UnityPrint(msg); - } - UNITY_IGNORE_AND_BAIL; -} - -//----------------------------------------------- -#if defined(UNITY_WEAK_ATTRIBUTE) - void setUp(void); - void tearDown(void); - UNITY_WEAK_ATTRIBUTE void setUp(void) { } - UNITY_WEAK_ATTRIBUTE void tearDown(void) { } -#elif defined(UNITY_WEAK_PRAGMA) -# pragma weak setUp - void setUp(void); -# pragma weak tearDown - void tearDown(void); -#else - void setUp(void); - void tearDown(void); -#endif -//----------------------------------------------- -void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum) -{ - Unity.CurrentTestName = FuncName; - Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)FuncLineNum; - Unity.NumberOfTests++; - if (TEST_PROTECTED(setUp) == 0) - { - TEST_PROTECTED(Func); - } - if (!(Unity.CurrentTestIgnored)) - { - TEST_PROTECTED(tearDown); - } - UnityConcludeTest(); -} - -//----------------------------------------------- -void UnityBegin(const char* filename) -{ - Unity.TestFile = filename; - Unity.CurrentTestName = NULL; - Unity.CurrentTestLineNumber = 0; - Unity.NumberOfTests = 0; - Unity.TestFailures = 0; - Unity.TestIgnores = 0; - Unity.CurrentTestFailed = 0; - Unity.CurrentTestIgnored = 0; - Unity.CurrentTestTimeout = 0; - - UNITY_OUTPUT_START(); -} - -//----------------------------------------------- -int UnityEnd(void) -{ - UNITY_PRINT_EOL; - UnityPrint(UnityStrBreaker); - UNITY_PRINT_EOL; - UnityPrintNumber((_U_SINT)(Unity.NumberOfTests)); - UnityPrint(UnityStrResultsTests); - UnityPrintNumber((_U_SINT)(Unity.TestFailures)); - UnityPrint(UnityStrResultsFailures); - UnityPrintNumber((_U_SINT)(Unity.TestIgnores)); - UnityPrint(UnityStrResultsIgnored); - UNITY_PRINT_EOL; - if (Unity.TestFailures == 0U) - { - UnityPrintOk(); - } - else - { - UnityPrintFail(); - } - UNITY_PRINT_EOL; - UNITY_OUTPUT_COMPLETE(); - return (int)(Unity.TestFailures); -} - -static void* UnityTimeoutThread(pthread_addr_t value) -{ - struct UnityTimeoutAction *timeout = (struct UnityTimeoutAction *)value; - - usleep(timeout->timeout_msec * UNITY_MSEC_IN_USEC); - - if (!timeout->cancel_protected) - return NULL; - - (void)pthread_kill(timeout->thread, SIG_UNITYSTOP); - Unity.CurrentTestTimeout = 1; - return NULL; -} - -static void* UnityProtectedThread(pthread_addr_t value) -{ - UnityTestFunction function = (UnityTestFunction)value; - function(); - return NULL; -} - -int UnityProtect(UnityTestFunction function, _U_UINT timeout_msec) -{ - struct UnityTimeoutAction action; - pthread_t thread, timeout_thread; - - if (timeout_msec < UNITY_MIN_TIMEOUT_MSEC) - timeout_msec = UNITY_MIN_TIMEOUT_MSEC; - - action.timeout_msec = timeout_msec; - action.cancel_protected = true; - - int result = pthread_create(&thread, NULL, UnityProtectedThread, (pthread_addr_t)function); - if (result == OK) - { - action.thread = thread; - result = pthread_create(&timeout_thread, NULL, UnityTimeoutThread, (pthread_addr_t)&action); - if (result == OK) - { - pthread_addr_t value; - result = pthread_join(thread, &value); - action.cancel_protected = false; - (void)pthread_kill(timeout_thread, SIG_UNITYSTOP); - (void)pthread_join(timeout_thread, &value); - if (result == 0) - { - result = Unity.CurrentTestFailed || Unity.CurrentTestTimeout ? 1 : 0; - } - } - } - return result; -} - -//----------------------------------------------- diff --git a/tests/testing/unity_fixture.c b/tests/testing/unity_fixture.c deleted file mode 100644 index aedbe4e5e..000000000 --- a/tests/testing/unity_fixture.c +++ /dev/null @@ -1,466 +0,0 @@ -//- Copyright (c) 2010 James Grenning and Contributed to Unity Project -/* ========================================== - Unity Project - A Test Framework for C - Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams - [Released under MIT License. Please refer to license.txt for details] -========================================== */ - -#include -#include -#include -#include -#include - -UNITY_FIXTURE_T UnityFixture; - -static char const* emptyList[] = {NULL}; - -int verbose = 0; - -void setUp(void); -void tearDown(void); -void setUp(void) { /*does nothing*/ } -void tearDown(void) { /*does nothing*/ } - -static void announceTestRun(unsigned int runNumber) -{ - UnityPrint("Unity test run "); - UnityPrintNumber(runNumber+1); - UnityPrint(" of "); - UnityPrintNumber(UnityFixture.RepeatCount); - UNITY_OUTPUT_CHAR('\n'); -} - -int UnityMain(int argc, const char* argv[], void (*runAllTests)(void)) -{ - int result = UnityGetCommandLineOptions(argc, argv); - unsigned int r; - if (result != 0) - return result; - - for (r = 0; r < UnityFixture.RepeatCount; r++) - { - UnityBegin(argv[0]); - announceTestRun(r); - runAllTests(); - UNITY_OUTPUT_CHAR('\n'); - UnityEnd(); - } - - return UnityFailureCount(); -} - -static int selected(const char * filter, const char * name) -{ - if (filter == 0) - return 1; - return strstr(name, filter) ? 1 : 0; -} - -static int testSelected(const char* test) -{ - return selected(UnityFixture.NameFilter, test); -} - -static int groupSelected(const char* group) -{ - return selected(UnityFixture.GroupFilter, group); -} - -static int plainSelected(const char* group, const char* test) -{ - if (UnityFixture.PlainListOfTests[0] == NULL) - { - return 1; - } - else - { - const char** plain = UnityFixture.PlainListOfTests; - while (plain[0] != NULL) - { - const char* selector = plain[0]; - int groupLen = strlen(group); - int testLen = strlen(test); - if (groupLen + testLen + 1 == strlen(selector) && - selector[groupLen] == '/' && - strstr(selector, group) == selector && - strstr(selector + groupLen + 1, test) == selector + groupLen + 1) - { - return 1; - } - plain++; - } - return 0; - } -} - -static void runTestCase(void) -{ - -} - -void UnityTestRunner(unityfunction* setup, _U_UINT setupTimeoutMsec, - unityfunction* testBody, _U_UINT bodyTimeoutMsec, - unityfunction* teardown, _U_UINT teardownTimeoutMsec, - const char * printableName, - const char * group, - const char * name, - const char * file, int line) -{ - if (testSelected(name) && groupSelected(group) && plainSelected(group, name)) - { - Unity.CurrentTestFailed = 0; - Unity.TestFile = file; - Unity.CurrentTestName = printableName; - Unity.CurrentTestLineNumber = line; - if (UnityFixture.ListOnly) - { - UnityPrint(group); - UNITY_OUTPUT_CHAR('/'); - UnityPrint(name); - UNITY_OUTPUT_CHAR('\n'); - Unity.NumberOfTests++; - } - else - { - if (!UnityFixture.Verbose) - UNITY_OUTPUT_CHAR('.'); - else - { - UnityPrint(printableName); - UNITY_OUTPUT_CHAR(' '); - } - - Unity.NumberOfTests++; - UnityMalloc_StartTest(); - UnityPointer_Init(); - - runTestCase(); - if (TEST_PROTECTED_WITH_TIMEOUT(setup, setupTimeoutMsec) == 0) - { - TEST_PROTECTED_WITH_TIMEOUT(testBody, bodyTimeoutMsec); - } - TEST_PROTECTED_WITH_TIMEOUT(teardown, teardownTimeoutMsec); - - UnityPointer_UndoAllSets(); - if (!Unity.CurrentTestFailed && !Unity.CurrentTestTimeout) - TEST_PROTECTED(UnityMalloc_EndTest); - - if (Unity.CurrentTestFailed && UnityFixture.Verbose) - { - UNITY_OUTPUT_CHAR('\n'); - } - } - UnityConcludeFixtureTest(); - } -} - -void UnityIgnoreTest(const char * printableName) -{ - Unity.NumberOfTests++; - Unity.CurrentTestIgnored = 1; - if (!UnityFixture.Verbose) - UNITY_OUTPUT_CHAR('!'); - else - UnityPrint(printableName); - UnityConcludeFixtureTest(); -} - - -//------------------------------------------------- -//Malloc and free stuff -// -#define MALLOC_DONT_FAIL -1 -static int malloc_count; -static int malloc_fail_countdown = MALLOC_DONT_FAIL; - -void UnityMalloc_StartTest(void) -{ - malloc_count = 0; - malloc_fail_countdown = MALLOC_DONT_FAIL; -} - -void UnityMalloc_EndTest(void) -{ - malloc_fail_countdown = MALLOC_DONT_FAIL; - if (malloc_count != 0) - { - TEST_FAIL_MESSAGE("This test leaks!"); - } -} - -void UnityMalloc_MakeMallocFailAfterCount(int countdown) -{ - malloc_fail_countdown = countdown; -} - -#ifdef malloc -#undef malloc -#endif - -#ifdef free -#undef free -#endif - -#ifdef calloc -#undef calloc -#endif - -#ifdef realloc -#undef realloc -#endif - -#include -#include - -typedef struct GuardBytes -{ - size_t size; - char guard[sizeof(size_t)]; -} Guard; - - -static const char * end = "END"; - -void * unity_malloc(size_t size) -{ - char* mem; - Guard* guard; - - if (malloc_fail_countdown != MALLOC_DONT_FAIL) - { - if (malloc_fail_countdown == 0) - return 0; - malloc_fail_countdown--; - } - - malloc_count++; - - guard = (Guard*)malloc(size + sizeof(Guard) + 4); - guard->size = size; - mem = (char*)&(guard[1]); - memcpy(&mem[size], end, strlen(end) + 1); - - return (void*)mem; -} - -static int isOverrun(void * mem) -{ - Guard* guard = (Guard*)mem; - char* memAsChar = (char*)mem; - guard--; - - return strcmp(&memAsChar[guard->size], end) != 0; -} - -static void release_memory(void * mem) -{ - Guard* guard = (Guard*)mem; - guard--; - - malloc_count--; - free(guard); -} - -void unity_free(void * mem) -{ - if (!mem) - { - /* Freeing NULL should be always OK */ - return; - } - int overrun = isOverrun(mem);//strcmp(&memAsChar[guard->size], end) != 0; - release_memory(mem); - if (overrun) - { - TEST_FAIL_MESSAGE("Buffer overrun detected during free()"); - } -} - -void* unity_calloc(size_t num, size_t size) -{ - void* mem = unity_malloc(num * size); - memset(mem, 0, num*size); - return mem; -} - -void* unity_realloc(void * oldMem, size_t size) -{ - Guard* guard = (Guard*)oldMem; -// char* memAsChar = (char*)oldMem; - void* newMem; - - if (oldMem == 0) - return unity_malloc(size); - - guard--; - if (isOverrun(oldMem)) - { - release_memory(oldMem); - TEST_FAIL_MESSAGE("Buffer overrun detected during realloc()"); - return 0; /* Above will not abort the test, if the execution is skipped */ - } - - if (size == 0) - { - release_memory(oldMem); - return 0; - } - - if (guard->size >= size) - return oldMem; - - newMem = unity_malloc(size); - memcpy(newMem, oldMem, guard->size); - unity_free(oldMem); - return newMem; -} - - -//-------------------------------------------------------- -//Automatic pointer restoration functions -typedef struct _PointerPair -{ - struct _PointerPair * next; - void ** pointer; - void * old_value; -} PointerPair; - -enum {MAX_POINTERS=50}; -static PointerPair pointer_store[MAX_POINTERS]; -static int pointer_index = 0; - -void UnityPointer_Init(void) -{ - pointer_index = 0; -} - -void UnityPointer_Set(void ** pointer, void * newValue) -{ - if (pointer_index >= MAX_POINTERS) - TEST_FAIL_MESSAGE("Too many pointers set"); - - pointer_store[pointer_index].pointer = pointer; - pointer_store[pointer_index].old_value = *pointer; - *pointer = newValue; - pointer_index++; -} - -void UnityPointer_UndoAllSets(void) -{ - while (pointer_index > 0) - { - pointer_index--; - *(pointer_store[pointer_index].pointer) = - pointer_store[pointer_index].old_value; - - } -} - -int UnityFailureCount(void) -{ - return Unity.TestFailures; -} - -int UnityGetCommandLineOptions(int argc, const char* argv[]) -{ - int i; - UnityFixture.Verbose = 0; - UnityFixture.ListOnly = 0; - UnityFixture.GroupFilter = 0; - UnityFixture.NameFilter = 0; - UnityFixture.RepeatCount = 1; - UnityFixture.PlainListOfTests = emptyList; - - if (argc == 1) - return 0; - - for (i = 1; i < argc; ) - { - if (strcmp(argv[i], "-l") == 0) - { - UnityFixture.ListOnly = 1; - i++; - } - else if (strcmp(argv[i], "-v") == 0) - { - UnityFixture.Verbose = 1; - i++; - } - else if (strcmp(argv[i], "-g") == 0) - { - i++; - if (i >= argc) - return 1; - UnityFixture.GroupFilter = argv[i]; - i++; - } - else if (strcmp(argv[i], "-n") == 0) - { - i++; - if (i >= argc) - return 1; - UnityFixture.NameFilter = argv[i]; - i++; - } - else if (strcmp(argv[i], "-r") == 0) - { - UnityFixture.RepeatCount = 2; - i++; - if (i < argc) - { - if (*(argv[i]) >= '0' && *(argv[i]) <= '9') - { - UnityFixture.RepeatCount = atoi(argv[i]); - i++; - } - } - } - else if (strcmp(argv[i], "--") == 0) - { - UnityFixture.PlainListOfTests = argv + i + 1; - break; - } - else { - // ignore unknown parameter - i++; - } - } - return 0; -} - -void UnityConcludeFixtureTest(void) -{ - if (Unity.CurrentTestIgnored) - { - if (UnityFixture.Verbose) - { - UNITY_OUTPUT_CHAR('\n'); - } - Unity.TestIgnores++; - } - else if (Unity.CurrentTestTimeout) - { - if (UnityFixture.Verbose) - { - UnityPrint(" TIMEOUT"); - UNITY_OUTPUT_CHAR('\n'); - } - Unity.TestFailures++; - } - else if (!Unity.CurrentTestFailed) - { - if (UnityFixture.Verbose) - { - UnityPrint(" PASS"); - UNITY_OUTPUT_CHAR('\n'); - } - } - else if (Unity.CurrentTestFailed) - { - Unity.TestFailures++; - } - - Unity.CurrentTestFailed = 0; - Unity.CurrentTestIgnored = 0; -} diff --git a/tests/tools/auto/colour_prompt.rb b/tests/tools/auto/colour_prompt.rb deleted file mode 100644 index 8adab6e61..000000000 --- a/tests/tools/auto/colour_prompt.rb +++ /dev/null @@ -1,115 +0,0 @@ -# ========================================== -# Unity Project - A Test Framework for C -# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams -# [Released under MIT License. Please refer to license.txt for details] -# ========================================== - -if RUBY_PLATFORM =~/(win|w)32$/ - begin - require 'Win32API' - rescue LoadError - puts "ERROR! \"Win32API\" library not found" - puts "\"Win32API\" is required for colour on a windows machine" - puts " try => \"gem install Win32API\" on the command line" - puts - end - # puts - # puts 'Windows Environment Detected...' - # puts 'Win32API Library Found.' - # puts -end - -class ColourCommandLine - def initialize - if RUBY_PLATFORM =~/(win|w)32$/ - get_std_handle = Win32API.new("kernel32", "GetStdHandle", ['L'], 'L') - @set_console_txt_attrb = - Win32API.new("kernel32","SetConsoleTextAttribute",['L','N'], 'I') - @hout = get_std_handle.call(-11) - end - end - - def change_to(new_colour) - if RUBY_PLATFORM =~/(win|w)32$/ - @set_console_txt_attrb.call(@hout,self.win32_colour(new_colour)) - else - "\033[30;#{posix_colour(new_colour)};22m" - end - end - - def win32_colour(colour) - case colour - when :black then 0 - when :dark_blue then 1 - when :dark_green then 2 - when :dark_cyan then 3 - when :dark_red then 4 - when :dark_purple then 5 - when :dark_yellow, :narrative then 6 - when :default_white, :default, :dark_white then 7 - when :silver then 8 - when :blue then 9 - when :green, :success then 10 - when :cyan, :output then 11 - when :red, :failure then 12 - when :purple then 13 - when :yellow then 14 - when :white then 15 - else - 0 - end - end - - def posix_colour(colour) - # ANSI Escape Codes - Foreground colors - # | Code | Color | - # | 39 | Default foreground color | - # | 30 | Black | - # | 31 | Red | - # | 32 | Green | - # | 33 | Yellow | - # | 34 | Blue | - # | 35 | Magenta | - # | 36 | Cyan | - # | 37 | Light gray | - # | 90 | Dark gray | - # | 91 | Light red | - # | 92 | Light green | - # | 93 | Light yellow | - # | 94 | Light blue | - # | 95 | Light magenta | - # | 96 | Light cyan | - # | 97 | White | - - case colour - when :black then 30 - when :red, :failure then 31 - when :green, :success then 32 - when :yellow then 33 - when :blue, :narrative then 34 - when :purple, :magenta then 35 - when :cyan, :output then 36 - when :white, :default_white then 37 - when :default then 39 - else - 39 - end - end - - def out_c(mode, colour, str) - case RUBY_PLATFORM - when /(win|w)32$/ - change_to(colour) - $stdout.puts str if mode == :puts - $stdout.print str if mode == :print - change_to(:default_white) - else - $stdout.puts("#{change_to(colour)}#{str}\033[0m") if mode == :puts - $stdout.print("#{change_to(colour)}#{str}\033[0m") if mode == :print - end - end -end # ColourCommandLine - -def colour_puts(role,str) ColourCommandLine.new.out_c(:puts, role, str) end -def colour_print(role,str) ColourCommandLine.new.out_c(:print, role, str) end - diff --git a/tests/tools/auto/colour_reporter.rb b/tests/tools/auto/colour_reporter.rb deleted file mode 100644 index 89e79519c..000000000 --- a/tests/tools/auto/colour_reporter.rb +++ /dev/null @@ -1,39 +0,0 @@ -# ========================================== -# Unity Project - A Test Framework for C -# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams -# [Released under MIT License. Please refer to license.txt for details] -# ========================================== - -require "#{File.expand_path(File.dirname(__FILE__))}/colour_prompt" - -$colour_output = true - -def report(message) - if not $colour_output - $stdout.puts(message) - else - message = message.join('\n') if (message.class == Array) - message.each_line do |line| - line.chomp! - colour = case(line) - when /(?:total\s+)?tests:?\s+(\d+)\s+(?:total\s+)?failures:?\s+\d+\s+Ignored:?/i - ($1.to_i == 0) ? :green : :red - when /PASS/ - :green - when /^OK$/ - :green - when /(?:FAIL|ERROR)/ - :red - when /IGNORE/ - :yellow - when /^(?:Creating|Compiling|Linking)/ - :white - else - :silver - end - colour_puts(colour, line) - end - end - $stdout.flush - $stderr.flush -end \ No newline at end of file diff --git a/tests/tools/auto/generate_config.yml b/tests/tools/auto/generate_config.yml deleted file mode 100644 index ce66cead5..000000000 --- a/tests/tools/auto/generate_config.yml +++ /dev/null @@ -1,36 +0,0 @@ -#this is a sample configuration file for generate_module -#you would use it by calling generate_module with the -ygenerate_config.yml option -#files like this are useful for customizing generate_module to your environment -:generate_module: - :defaults: - #these defaults are used in place of any missing options at the command line - :path_src: ../src/ - :path_inc: ../src/ - :path_tst: ../test/ - :update_svn: true - :includes: - #use [] for no additional includes, otherwise list the includes on separate lines - :src: - - Defs.h - - Board.h - :inc: [] - :tst: - - Defs.h - - Board.h - - Exception.h - :boilerplates: - #these are inserted at the top of generated files. - #just comment out or remove if not desired. - #use %1$s where you would like the file name to appear (path/extension not included) - :src: | - //------------------------------------------- - // %1$s.c - //------------------------------------------- - :inc: | - //------------------------------------------- - // %1$s.h - //------------------------------------------- - :tst: | - //------------------------------------------- - // Test%1$s.c : Units tests for %1$s.c - //------------------------------------------- diff --git a/tests/tools/auto/generate_module.rb b/tests/tools/auto/generate_module.rb deleted file mode 100644 index 4a020ebbf..000000000 --- a/tests/tools/auto/generate_module.rb +++ /dev/null @@ -1,202 +0,0 @@ -# ========================================== -# Unity Project - A Test Framework for C -# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams -# [Released under MIT License. Please refer to license.txt for details] -# ========================================== - -# This script creates all the files with start code necessary for a new module. -# A simple module only requires a source file, header file, and test file. -# Triad modules require a source, header, and test file for each triad type (like model, conductor, and hardware). - -require 'rubygems' -require 'fileutils' - -HERE = File.expand_path(File.dirname(__FILE__)) + '/' - -#help text when requested -HELP_TEXT = [ "\nGENERATE MODULE\n-------- ------", - "\nUsage: ruby generate_module [options] module_name", - " -i\"include\" sets the path to output headers to 'include' (DEFAULT ../src)", - " -s\"../src\" sets the path to output source to '../src' (DEFAULT ../src)", - " -t\"C:/test\" sets the path to output source to 'C:/test' (DEFAULT ../test)", - " -p\"MCH\" sets the output pattern to MCH.", - " dh - driver hardware.", - " dih - driver interrupt hardware.", - " mch - model conductor hardware.", - " mvp - model view presenter.", - " src - just a single source module. (DEFAULT)", - " -d destroy module instead of creating it.", - " -u update subversion too (requires subversion command line)", - " -y\"my.yml\" selects a different yaml config file for module generation", - "" ].join("\n") - -#Built in patterns -PATTERNS = { 'src' => {'' => { :inc => [] } }, - 'dh' => {'Driver' => { :inc => ['%1$sHardware.h'] }, - 'Hardware' => { :inc => [] } - }, - 'dih' => {'Driver' => { :inc => ['%1$sHardware.h', '%1$sInterrupt.h'] }, - 'Interrupt'=> { :inc => ['%1$sHardware.h'] }, - 'Hardware' => { :inc => [] } - }, - 'mch' => {'Model' => { :inc => [] }, - 'Conductor'=> { :inc => ['%1$sModel.h', '%1$sHardware.h'] }, - 'Hardware' => { :inc => [] } - }, - 'mvp' => {'Model' => { :inc => [] }, - 'Presenter'=> { :inc => ['%1$sModel.h', '%1$sView.h'] }, - 'View' => { :inc => [] } - } - } - -#TEMPLATE_TST -TEMPLATE_TST = %q[#include "unity.h" -%2$s#include "%1$s.h" - -void setUp(void) -{ -} - -void tearDown(void) -{ -} - -void test_%1$s_NeedToImplement(void) -{ - TEST_IGNORE(); -} -] - -#TEMPLATE_SRC -TEMPLATE_SRC = %q[%2$s#include "%1$s.h" -] - -#TEMPLATE_INC -TEMPLATE_INC = %q[#ifndef _%3$s_H -#define _%3$s_H%2$s - -#endif // _%3$s_H -] - -# Parse the command line parameters. -ARGV.each do |arg| - case(arg) - when /^-d/ then @destroy = true - when /^-u/ then @update_svn = true - when /^-p(\w+)/ then @pattern = $1 - when /^-s(.+)/ then @path_src = $1 - when /^-i(.+)/ then @path_inc = $1 - when /^-t(.+)/ then @path_tst = $1 - when /^-y(.+)/ then @yaml_config = $1 - when /^(\w+)/ - raise "ERROR: You can't have more than one Module name specified!" unless @module_name.nil? - @module_name = arg - when /^-(h|-help)/ - puts HELP_TEXT - exit - else - raise "ERROR: Unknown option specified '#{arg}'" - end -end -raise "ERROR: You must have a Module name specified! (use option -h for help)" if @module_name.nil? - -#load yaml file if one was requested -if @yaml_config - require 'yaml' - cfg = YAML.load_file(HERE + @yaml_config)[:generate_module] - @path_src = cfg[:defaults][:path_src] if @path_src.nil? - @path_inc = cfg[:defaults][:path_inc] if @path_inc.nil? - @path_tst = cfg[:defaults][:path_tst] if @path_tst.nil? - @update_svn = cfg[:defaults][:update_svn] if @update_svn.nil? - @extra_inc = cfg[:includes] - @boilerplates = cfg[:boilerplates] -else - @boilerplates = {} -end - -# Create default file paths if none were provided -@path_src = HERE + "../src/" if @path_src.nil? -@path_inc = @path_src if @path_inc.nil? -@path_tst = HERE + "../test/" if @path_tst.nil? -@path_src += '/' unless (@path_src[-1] == 47) -@path_inc += '/' unless (@path_inc[-1] == 47) -@path_tst += '/' unless (@path_tst[-1] == 47) -@pattern = 'src' if @pattern.nil? -@includes = { :src => [], :inc => [], :tst => [] } -@includes.merge!(@extra_inc) unless @extra_inc.nil? - -#create triad definition -TRIAD = [ { :ext => '.c', :path => @path_src, :template => TEMPLATE_SRC, :inc => :src, :boilerplate => @boilerplates[:src] }, - { :ext => '.h', :path => @path_inc, :template => TEMPLATE_INC, :inc => :inc, :boilerplate => @boilerplates[:inc] }, - { :ext => '.c', :path => @path_tst+'Test', :template => TEMPLATE_TST, :inc => :tst, :boilerplate => @boilerplates[:tst] }, - ] - -#prepare the pattern for use -@patterns = PATTERNS[@pattern.downcase] -raise "ERROR: The design pattern specified isn't one that I recognize!" if @patterns.nil? - -# Assemble the path/names of the files we need to work with. -files = [] -TRIAD.each do |triad| - @patterns.each_pair do |pattern_file, pattern_traits| - files << { - :path => "#{triad[:path]}#{@module_name}#{pattern_file}#{triad[:ext]}", - :name => "#{@module_name}#{pattern_file}", - :template => triad[:template], - :boilerplate => triad[:boilerplate], - :includes => case(triad[:inc]) - when :src then @includes[:src] | pattern_traits[:inc].map{|f| f % [@module_name]} - when :inc then @includes[:inc] - when :tst then @includes[:tst] | pattern_traits[:inc].map{|f| "Mock#{f}"% [@module_name]} - end - } - end -end - -# destroy files if that was what was requested -if @destroy - files.each do |filespec| - file = filespec[:path] - if File.exist?(file) - if @update_svn - `svn delete \"#{file}\" --force` - puts "File #{file} deleted and removed from source control" - else - FileUtils.remove(file) - puts "File #{file} deleted" - end - else - puts "File #{file} does not exist so cannot be removed." - end - end - puts "Destroy Complete" - exit -end - -#Abort if any module already exists -files.each do |file| - raise "ERROR: File #{file[:name]} already exists. Exiting." if File.exist?(file[:path]) -end - -# Create Source Modules -files.each_with_index do |file, i| - File.open(file[:path], 'w') do |f| - f.write(file[:boilerplate] % [file[:name]]) unless file[:boilerplate].nil? - f.write(file[:template] % [ file[:name], - file[:includes].map{|f| "#include \"#{f}\"\n"}.join, - file[:name].upcase ] - ) - end - if (@update_svn) - `svn add \"#{file[:path]}\"` - if $?.exitstatus == 0 - puts "File #{file[:path]} created and added to source control" - else - puts "File #{file[:path]} created but FAILED adding to source control!" - end - else - puts "File #{file[:path]} created" - end -end - -puts 'Generate Complete' diff --git a/tests/tools/auto/generate_test_runner.rb b/tests/tools/auto/generate_test_runner.rb deleted file mode 100644 index 85e4e91db..000000000 --- a/tests/tools/auto/generate_test_runner.rb +++ /dev/null @@ -1,349 +0,0 @@ -# ========================================== -# Unity Project - A Test Framework for C -# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams -# [Released under MIT License. Please refer to license.txt for details] -# ========================================== - -$QUICK_RUBY_VERSION = RUBY_VERSION.split('.').inject(0){|vv,v| vv * 100 + v.to_i } -File.expand_path(File.join(File.dirname(__FILE__),'colour_prompt')) - -class UnityTestRunnerGenerator - - def initialize(options = nil) - @options = UnityTestRunnerGenerator.default_options - case(options) - when NilClass then @options - when String then @options.merge!(UnityTestRunnerGenerator.grab_config(options)) - when Hash then @options.merge!(options) - else raise "If you specify arguments, it should be a filename or a hash of options" - end - require "#{File.expand_path(File.dirname(__FILE__))}/type_sanitizer" - end - - def self.default_options - { - :includes => [], - :plugins => [], - :framework => :unity, - :test_prefix => "test|spec|should", - :setup_name => "setUp", - :teardown_name => "tearDown", - } - end - - def self.grab_config(config_file) - options = self.default_options - unless (config_file.nil? or config_file.empty?) - require 'yaml' - yaml_guts = YAML.load_file(config_file) - options.merge!(yaml_guts[:unity] || yaml_guts[:cmock]) - raise "No :unity or :cmock section found in #{config_file}" unless options - end - return(options) - end - - def run(input_file, output_file, options=nil) - tests = [] - testfile_includes = [] - used_mocks = [] - - @options.merge!(options) unless options.nil? - module_name = File.basename(input_file) - - #pull required data from source file - source = File.read(input_file) - source = source.force_encoding("ISO-8859-1").encode("utf-8", :replace => nil) if ($QUICK_RUBY_VERSION > 10900) - tests = find_tests(source) - headers = find_includes(source) - testfile_includes = headers[:local] + headers[:system] - used_mocks = find_mocks(testfile_includes) - - #build runner file - generate(input_file, output_file, tests, used_mocks, testfile_includes) - - #determine which files were used to return them - all_files_used = [input_file, output_file] - all_files_used += testfile_includes.map {|filename| filename + '.c'} unless testfile_includes.empty? - all_files_used += @options[:includes] unless @options[:includes].empty? - return all_files_used.uniq - end - - def generate(input_file, output_file, tests, used_mocks, testfile_includes) - File.open(output_file, 'w') do |output| - create_header(output, used_mocks, testfile_includes) - create_externs(output, tests, used_mocks) - create_mock_management(output, used_mocks) - create_suite_setup_and_teardown(output) - create_reset(output, used_mocks) - create_main(output, input_file, tests, used_mocks) - end - end - - def find_tests(source) - tests_raw = [] - tests_args = [] - tests_and_line_numbers = [] - - source_scrubbed = source.gsub(/\/\/.*$/, '') # remove line comments - source_scrubbed = source_scrubbed.gsub(/\/\*.*?\*\//m, '') # remove block comments - lines = source_scrubbed.split(/(^\s*\#.*$) # Treat preprocessor directives as a logical line - | (;|\{|\}) /x) # Match ;, {, and } as end of lines - - lines.each_with_index do |line, index| - #find tests - if line =~ /^((?:\s*TEST_CASE\s*\(.*?\)\s*)*)\s*void\s+((?:#{@options[:test_prefix]}).*)\s*\(\s*(.*)\s*\)/ - arguments = $1 - name = $2 - call = $3 - args = nil - if (@options[:use_param_tests] and !arguments.empty?) - args = [] - arguments.scan(/\s*TEST_CASE\s*\((.*)\)\s*$/) {|a| args << a[0]} - end - tests_and_line_numbers << { :test => name, :args => args, :call => call, :line_number => 0 } - tests_args = [] - end - end - - #determine line numbers and create tests to run - source_lines = source.split("\n") - source_index = 0; - tests_and_line_numbers.size.times do |i| - source_lines[source_index..-1].each_with_index do |line, index| - if (line =~ /#{tests_and_line_numbers[i][:test]}/) - source_index += index - tests_and_line_numbers[i][:line_number] = source_index + 1 - break - end - end - end - - return tests_and_line_numbers - end - - def find_includes(source) - - #remove comments (block and line, in three steps to ensure correct precedence) - source.gsub!(/\/\/(?:.+\/\*|\*(?:$|[^\/])).*$/, '') # remove line comments that comment out the start of blocks - source.gsub!(/\/\*.*?\*\//m, '') # remove block comments - source.gsub!(/\/\/.*$/, '') # remove line comments (all that remain) - - #parse out includes - includes = { - local: source.scan(/^\s*#include\s+\"\s*(.+)\.[hH]\s*\"/).flatten, - system: source.scan(/^\s*#include\s+<\s*(.+)\s*>/).flatten.map { |inc| "<#{inc}>" } - } - return includes - end - - def find_mocks(includes) - mock_headers = [] - includes.each do |include_file| - mock_headers << File.basename(include_file) if (include_file =~ /^mock/i) - end - return mock_headers - end - - def create_header(output, mocks, testfile_includes=[]) - output.puts('/* AUTOGENERATED FILE. DO NOT EDIT. */') - create_runtest(output, mocks) - output.puts("\n//=======Automagically Detected Files To Include=====") - output.puts("#include \"#{@options[:framework].to_s}.h\"") - output.puts('#include "cmock.h"') unless (mocks.empty?) - @options[:includes].flatten.uniq.compact.each do |inc| - output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h','')}.h\""}") - end - output.puts('#include ') - output.puts('#include ') - output.puts('#include "CException.h"') if @options[:plugins].include?(:cexception) - testfile_includes.delete_if{|inc| inc =~ /(unity|cmock)/} - testrunner_includes = testfile_includes - mocks - testrunner_includes.each do |inc| - output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h','')}.h\""}") - end - mocks.each do |mock| - output.puts("#include \"#{mock.gsub('.h','')}.h\"") - end - if @options[:enforce_strict_ordering] - output.puts('') - output.puts('int GlobalExpectCount;') - output.puts('int GlobalVerifyOrder;') - output.puts('char* GlobalOrderError;') - end - end - - def create_externs(output, tests, mocks) - output.puts("\n//=======External Functions This Runner Calls=====") - output.puts("extern void #{@options[:setup_name]}(void);") - output.puts("extern void #{@options[:teardown_name]}(void);") - tests.each do |test| - output.puts("extern void #{test[:test]}(#{test[:call] || 'void'});") - end - output.puts('') - end - - def create_mock_management(output, mocks) - unless (mocks.empty?) - output.puts("\n//=======Mock Management=====") - output.puts("static void CMock_Init(void)") - output.puts("{") - if @options[:enforce_strict_ordering] - output.puts(" GlobalExpectCount = 0;") - output.puts(" GlobalVerifyOrder = 0;") - output.puts(" GlobalOrderError = NULL;") - end - mocks.each do |mock| - mock_clean = TypeSanitizer.sanitize_c_identifier(mock) - output.puts(" #{mock_clean}_Init();") - end - output.puts("}\n") - - output.puts("static void CMock_Verify(void)") - output.puts("{") - mocks.each do |mock| - mock_clean = TypeSanitizer.sanitize_c_identifier(mock) - output.puts(" #{mock_clean}_Verify();") - end - output.puts("}\n") - - output.puts("static void CMock_Destroy(void)") - output.puts("{") - mocks.each do |mock| - mock_clean = TypeSanitizer.sanitize_c_identifier(mock) - output.puts(" #{mock_clean}_Destroy();") - end - output.puts("}\n") - end - end - - def create_suite_setup_and_teardown(output) - unless (@options[:suite_setup].nil?) - output.puts("\n//=======Suite Setup=====") - output.puts("static int suite_setup(void)") - output.puts("{") - output.puts(@options[:suite_setup]) - output.puts("}") - end - unless (@options[:suite_teardown].nil?) - output.puts("\n//=======Suite Teardown=====") - output.puts("static int suite_teardown(int num_failures)") - output.puts("{") - output.puts(@options[:suite_teardown]) - output.puts("}") - end - end - - def create_runtest(output, used_mocks) - cexception = @options[:plugins].include? :cexception - va_args1 = @options[:use_param_tests] ? ', ...' : '' - va_args2 = @options[:use_param_tests] ? '__VA_ARGS__' : '' - output.puts("\n//=======Test Runner Used To Run Each Test Below=====") - output.puts("#define RUN_TEST_NO_ARGS") if @options[:use_param_tests] - output.puts("#define RUN_TEST(TestFunc, TestLineNum#{va_args1}) \\") - output.puts("{ \\") - output.puts(" Unity.CurrentTestName = #TestFunc#{va_args2.empty? ? '' : " \"(\" ##{va_args2} \")\""}; \\") - output.puts(" Unity.CurrentTestLineNumber = TestLineNum; \\") - output.puts(" Unity.NumberOfTests++; \\") - output.puts(" CMock_Init(); \\") unless (used_mocks.empty?) - output.puts(" if (TEST_PROTECT()) \\") - output.puts(" { \\") - output.puts(" CEXCEPTION_T e; \\") if cexception - output.puts(" Try { \\") if cexception - output.puts(" #{@options[:setup_name]}(); \\") - output.puts(" TestFunc(#{va_args2}); \\") - output.puts(" } Catch(e) { TEST_ASSERT_EQUAL_HEX32_MESSAGE(CEXCEPTION_NONE, e, \"Unhandled Exception!\"); } \\") if cexception - output.puts(" } \\") - output.puts(" if (TEST_PROTECT() && !TEST_IS_IGNORED) \\") - output.puts(" { \\") - output.puts(" #{@options[:teardown_name]}(); \\") - output.puts(" CMock_Verify(); \\") unless (used_mocks.empty?) - output.puts(" } \\") - output.puts(" CMock_Destroy(); \\") unless (used_mocks.empty?) - output.puts(" UnityConcludeTest(); \\") - output.puts("}\n") - end - - def create_reset(output, used_mocks) - output.puts("\n//=======Test Reset Option=====") - output.puts("void resetTest(void);") - output.puts("void resetTest(void)") - output.puts("{") - output.puts(" CMock_Verify();") unless (used_mocks.empty?) - output.puts(" CMock_Destroy();") unless (used_mocks.empty?) - output.puts(" #{@options[:teardown_name]}();") - output.puts(" CMock_Init();") unless (used_mocks.empty?) - output.puts(" #{@options[:setup_name]}();") - output.puts("}") - end - - def create_main(output, filename, tests, used_mocks) - output.puts("\n\n//=======MAIN=====") - output.puts("int main(void)") - output.puts("{") - output.puts(" suite_setup();") unless @options[:suite_setup].nil? - output.puts(" UnityBegin(\"#{filename}\");") - if (@options[:use_param_tests]) - tests.each do |test| - if ((test[:args].nil?) or (test[:args].empty?)) - output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]}, RUN_TEST_NO_ARGS);") - else - test[:args].each {|args| output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]}, #{args});")} - end - end - else - tests.each { |test| output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]});") } - end - output.puts() - output.puts(" CMock_Guts_MemFreeFinal();") unless used_mocks.empty? - output.puts(" return #{@options[:suite_teardown].nil? ? "" : "suite_teardown"}(UnityEnd());") - output.puts("}") - end -end - - -if ($0 == __FILE__) - options = { :includes => [] } - yaml_file = nil - - #parse out all the options first (these will all be removed as we go) - ARGV.reject! do |arg| - case(arg) - when '-cexception' - options[:plugins] = [:cexception]; true - when /\.*\.ya?ml/ - options = UnityTestRunnerGenerator.grab_config(arg); true - when /\.*\.h/ - options[:includes] << arg; true - when /--(\w+)=\"?(.*)\"?/ - options[$1.to_sym] = $2; true - else false - end - end - - #make sure there is at least one parameter left (the input file) - if !ARGV[0] - puts ["\nusage: ruby #{__FILE__} (files) (options) input_test_file (output)", - "\n input_test_file - this is the C file you want to create a runner for", - " output - this is the name of the runner file to generate", - " defaults to (input_test_file)_Runner", - " files:", - " *.yml / *.yaml - loads configuration from here in :unity or :cmock", - " *.h - header files are added as #includes in runner", - " options:", - " -cexception - include cexception support", - " --setup_name=\"\" - redefine setUp func name to something else", - " --teardown_name=\"\" - redefine tearDown func name to something else", - " --test_prefix=\"\" - redefine test prefix from default test|spec|should", - " --suite_setup=\"\" - code to execute for setup of entire suite", - " --suite_teardown=\"\" - code to execute for teardown of entire suite", - " --use_param_tests=1 - enable parameterized tests (disabled by default)", - ].join("\n") - exit 1 - end - - #create the default test runner name if not specified - ARGV[1] = ARGV[0].gsub(".c","_Runner.c") if (!ARGV[1]) - - - UnityTestRunnerGenerator.new(options).run(ARGV[0], ARGV[1]) -end diff --git a/tests/tools/auto/parseOutput.rb b/tests/tools/auto/parseOutput.rb deleted file mode 100644 index 5165c7f0b..000000000 --- a/tests/tools/auto/parseOutput.rb +++ /dev/null @@ -1,189 +0,0 @@ -#============================================================ -# Author: John Theofanopoulos -# A simple parser. Takes the output files generated during the build process and -# extracts information relating to the tests. -# -# Notes: -# To capture an output file under VS builds use the following: -# devenv [build instructions] > Output.txt & type Output.txt -# -# To capture an output file under GCC/Linux builds use the following: -# make | tee Output.txt -# -# To use this parser use the following command -# ruby parseOutput.rb [options] [file] -# options: -xml : produce a JUnit compatible XML file -# file : file to scan for results -#============================================================ - - -class ParseOutput -# The following flag is set to true when a test is found or false otherwise. - @testFlag - @xmlOut - @arrayList - @totalTests - @classIndex - -# Set the flag to indicate if there will be an XML output file or not - def setXmlOutput() - @xmlOut = true - end - -# if write our output to XML - def writeXmlOuput() - output = File.open("report.xml", "w") - output << "\n" - @arrayList.each do |item| - output << item << "\n" - end - output << "\n" - end - -# This function will try and determine when the suite is changed. This is -# is the name that gets added to the classname parameter. - def testSuiteVerify(testSuiteName) - if @testFlag == false - @testFlag = true; - # Split the path name - testName = testSuiteName.split("/") - # Remove the extension - baseName = testName[testName.size - 1].split(".") - @testSuite = "test." + baseName[0] - printf "New Test: %s\n", @testSuite - end - end - - -# Test was flagged as having passed so format the output - def testPassed(array) - lastItem = array.length - 1 - testName = array[lastItem - 1] - testSuiteVerify(array[@className]) - printf "%-40s PASS\n", testName - if @xmlOut == true - @arrayList.push " " - end - end - -# Test was flagged as being ingored so format the output - def testIgnored(array) - lastItem = array.length - 1 - testName = array[lastItem - 2] - reason = array[lastItem].chomp - testSuiteVerify(array[@className]) - printf "%-40s IGNORED\n", testName - if @xmlOut == true - @arrayList.push " " - @arrayList.push " " + reason + " " - @arrayList.push " " - end - end - -# Test was flagged as having failed so format the line - def testFailed(array) - lastItem = array.length - 1 - testName = array[lastItem - 2] - reason = array[lastItem].chomp + " at line: " + array[lastItem - 3] - testSuiteVerify(array[@className]) - printf "%-40s FAILED\n", testName - if @xmlOut == true - @arrayList.push " " - @arrayList.push " " + reason + " " - @arrayList.push " " - end - end - - -# Figure out what OS we are running on. For now we are assuming if it's not Windows it must -# be Unix based. - def detectOS() - myOS = RUBY_PLATFORM.split("-") - if myOS.size == 2 - if myOS[1] == "mingw32" - @className = 1 - else - @className = 0 - end - end - - end - -# Main function used to parse the file that was captured. - def process(name) - @testFlag = false - @arrayList = Array.new - - detectOS() - - puts "Parsing file: " + name - - - testPass = 0 - testFail = 0 - testIgnore = 0 - puts "" - puts "=================== RESULTS =====================" - puts "" - File.open(name).each do |line| - # Typical test lines look like this: - # /.c:36:test_tc1000_opsys:FAIL: Expected 1 Was 0 - # /.c:112:test_tc5004_initCanChannel:IGNORE: Not Yet Implemented - # /.c:115:test_tc5100_initCanVoidPtrs:PASS - # - # where path is different on Unix vs Windows devices (Windows leads with a drive letter) - lineArray = line.split(":") - lineSize = lineArray.size - # If we were able to split the line then we can look to see if any of our target words - # were found. Case is important. - if lineSize >= 4 - # Determine if this test passed - if line.include? ":PASS" - testPassed(lineArray) - testPass += 1 - elsif line.include? ":FAIL:" - testFailed(lineArray) - testFail += 1 - elsif line.include? ":IGNORE:" - testIgnored(lineArray) - testIgnore += 1 - # If none of the keywords are found there are no more tests for this suite so clear - # the test flag - else - @testFlag = false - end - else - @testFlag = false - end - end - puts "" - puts "=================== SUMMARY =====================" - puts "" - puts "Tests Passed : " + testPass.to_s - puts "Tests Failed : " + testFail.to_s - puts "Tests Ignored : " + testIgnore.to_s - @totalTests = testPass + testFail + testIgnore - if @xmlOut == true - heading = "" - @arrayList.insert(0, heading) - writeXmlOuput() - end - - # return result - end - - end - -# If the command line has no values in, used a default value of Output.txt -parseMyFile = ParseOutput.new - -if ARGV.size >= 1 - ARGV.each do |a| - if a == "-xml" - parseMyFile.setXmlOutput(); - else - parseMyFile.process(a) - break - end - end -end diff --git a/tests/tools/auto/test_file_filter.rb b/tests/tools/auto/test_file_filter.rb deleted file mode 100644 index 3dbc26a28..000000000 --- a/tests/tools/auto/test_file_filter.rb +++ /dev/null @@ -1,23 +0,0 @@ -# ========================================== -# Unity Project - A Test Framework for C -# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams -# [Released under MIT License. Please refer to license.txt for details] -# ========================================== - -require'yaml' - -module RakefileHelpers - class TestFileFilter - def initialize(all_files = false) - @all_files = all_files - if not @all_files == true - if File.exist?('test_file_filter.yml') - filters = YAML.load_file( 'test_file_filter.yml' ) - @all_files, @only_files, @exclude_files = - filters[:all_files], filters[:only_files], filters[:exclude_files] - end - end - end - attr_accessor :all_files, :only_files, :exclude_files - end -end diff --git a/tests/tools/auto/type_sanitizer.rb b/tests/tools/auto/type_sanitizer.rb deleted file mode 100644 index 7c2c0ac2c..000000000 --- a/tests/tools/auto/type_sanitizer.rb +++ /dev/null @@ -1,8 +0,0 @@ -module TypeSanitizer - - def self.sanitize_c_identifier(unsanitized) - # convert filename to valid C identifier by replacing invalid chars with '_' - return unsanitized.gsub(/[-\/\\\.\,\s]/, "_") - end - -end diff --git a/tests/tools/auto/unity_test_summary.py b/tests/tools/auto/unity_test_summary.py deleted file mode 100644 index 7426ec8c3..000000000 --- a/tests/tools/auto/unity_test_summary.py +++ /dev/null @@ -1,135 +0,0 @@ -#! python3 -# ========================================== -# Unity Project - A Test Framework for C -# Copyright (c) 2015 Alexander Mueller / XelaRellum@web.de -# [Released under MIT License. Please refer to license.txt for details] -# Based on the ruby script by Mike Karlesky, Mark VanderVoord, Greg Williams -# ========================================== -import sys -import os -import re -from glob import glob - -class UnityTestSummary: - def __init__(self): - self.report = '' - self.total_tests = 0 - self.failures = 0 - self.ignored = 0 - - def run(self): - # Clean up result file names - results = [] - for target in self.targets: - results.append(target.replace('\\', '/')) - - # Dig through each result file, looking for details on pass/fail: - failure_output = [] - ignore_output = [] - - for result_file in results: - lines = list(map(lambda line: line.rstrip(), open(result_file, "r").read().split('\n'))) - if len(lines) == 0: - raise Exception("Empty test result file: %s" % result_file) - - details = self.get_details(result_file, lines) - failures = details['failures'] - ignores = details['ignores'] - if len(failures) > 0: failure_output.append('\n'.join(failures)) - if len(ignores) > 0: ignore_output.append('n'.join(ignores)) - tests,failures,ignored = self.parse_test_summary('\n'.join(lines)) - self.total_tests += tests - self.failures += failures - self.ignored += ignored - - if self.ignored > 0: - self.report += "\n" - self.report += "--------------------------\n" - self.report += "UNITY IGNORED TEST SUMMARY\n" - self.report += "--------------------------\n" - self.report += "\n".join(ignore_output) - - if self.failures > 0: - self.report += "\n" - self.report += "--------------------------\n" - self.report += "UNITY FAILED TEST SUMMARY\n" - self.report += "--------------------------\n" - self.report += '\n'.join(failure_output) - - self.report += "\n" - self.report += "--------------------------\n" - self.report += "OVERALL UNITY TEST SUMMARY\n" - self.report += "--------------------------\n" - self.report += "{total_tests} TOTAL TESTS {failures} TOTAL FAILURES {ignored} IGNORED\n".format(total_tests = self.total_tests, failures=self.failures, ignored=self.ignored) - self.report += "\n" - - return self.report - - def set_targets(self, target_array): - self.targets = target_array - - def set_root_path(self, path): - self.root = path - - def usage(self, err_msg=None): - print("\nERROR: ") - if err_msg: - print(err_msg) - print("\nUsage: unity_test_summary.rb result_file_directory/ root_path/") - print(" result_file_directory - The location of your results files.") - print(" Defaults to current directory if not specified.") - print(" Should end in / if specified.") - print(" root_path - Helpful for producing more verbose output if using relative paths.") - sys.exit(1) - - def get_details(self, result_file, lines): - results = { 'failures': [], 'ignores': [], 'successes': [] } - for line in lines: - parts = line.split(':') - if len(parts) != 5: - continue - src_file,src_line,test_name,status,msg = parts - if len(self.root) > 0: - line_out = "%s%s" % (self.root, line) - else: - line_out = line - if status == 'IGNORE': - results['ignores'].append(line_out) - elif status == 'FAIL': - results['failures'].append(line_out) - elif status == 'PASS': - results['successes'].append(line_out) - return results - - def parse_test_summary(self, summary): - m = re.search(r"([0-9]+) Tests ([0-9]+) Failures ([0-9]+) Ignored", summary) - if not m: - raise Exception("Couldn't parse test results: %s" % summary) - - return int(m.group(1)), int(m.group(2)), int(m.group(3)) - - -if __name__ == '__main__': - uts = UnityTestSummary() - try: - #look in the specified or current directory for result files - if len(sys.argv) > 1: - targets_dir = sys.argv[1] - else: - targets_dir = './' - targets = list(map(lambda x: x.replace('\\', '/'), glob(targets_dir + '*.test*'))) - if len(targets) == 0: - raise Exception("No *.testpass or *.testfail files found in '%s'" % targets_dir) - uts.set_targets(targets) - - #set the root path - if len(sys.argv) > 2: - root_path = sys.argv[2] - else: - root_path = os.path.split(__file__)[0] - uts.set_root_path(root_path) - - #run the summarizer - print(uts.run()) - except Exception as e: - uts.usage(e) diff --git a/tests/tools/auto/unity_test_summary.rb b/tests/tools/auto/unity_test_summary.rb deleted file mode 100644 index 8cf360f4a..000000000 --- a/tests/tools/auto/unity_test_summary.rb +++ /dev/null @@ -1,139 +0,0 @@ -# ========================================== -# Unity Project - A Test Framework for C -# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams -# [Released under MIT License. Please refer to license.txt for details] -# ========================================== - -#!/usr/bin/ruby -# -# unity_test_summary.rb -# -require 'fileutils' -require 'set' - -class UnityTestSummary - include FileUtils::Verbose - - attr_reader :report, :total_tests, :failures, :ignored - - def initialize - @report = '' - @total_tests = 0 - @failures = 0 - @ignored = 0 - end - - def run - # Clean up result file names - results = @targets.map {|target| target.gsub(/\\/,'/')} - - # Dig through each result file, looking for details on pass/fail: - failure_output = [] - ignore_output = [] - - results.each do |result_file| - lines = File.readlines(result_file).map { |line| line.chomp } - if lines.length == 0 - raise "Empty test result file: #{result_file}" - else - output = get_details(result_file, lines) - failure_output << output[:failures] unless output[:failures].empty? - ignore_output << output[:ignores] unless output[:ignores].empty? - tests,failures,ignored = parse_test_summary(lines) - @total_tests += tests - @failures += failures - @ignored += ignored - end - end - - if @ignored > 0 - @report += "\n" - @report += "--------------------------\n" - @report += "UNITY IGNORED TEST SUMMARY\n" - @report += "--------------------------\n" - @report += ignore_output.flatten.join("\n") - end - - if @failures > 0 - @report += "\n" - @report += "--------------------------\n" - @report += "UNITY FAILED TEST SUMMARY\n" - @report += "--------------------------\n" - @report += failure_output.flatten.join("\n") - end - - @report += "\n" - @report += "--------------------------\n" - @report += "OVERALL UNITY TEST SUMMARY\n" - @report += "--------------------------\n" - @report += "#{@total_tests} TOTAL TESTS #{@failures} TOTAL FAILURES #{@ignored} IGNORED\n" - @report += "\n" - end - - def set_targets(target_array) - @targets = target_array - end - - def set_root_path(path) - @root = path - end - - def usage(err_msg=nil) - puts "\nERROR: " - puts err_msg if err_msg - puts "\nUsage: unity_test_summary.rb result_file_directory/ root_path/" - puts " result_file_directory - The location of your results files." - puts " Defaults to current directory if not specified." - puts " Should end in / if specified." - puts " root_path - Helpful for producing more verbose output if using relative paths." - exit 1 - end - - protected - - def get_details(result_file, lines) - results = { :failures => [], :ignores => [], :successes => [] } - lines.each do |line| - src_file,src_line,test_name,status,msg = line.split(/:/) - line_out = ((@root and (@root != 0)) ? "#{@root}#{line}" : line ).gsub(/\//, "\\") - case(status) - when 'IGNORE' then results[:ignores] << line_out - when 'FAIL' then results[:failures] << line_out - when 'PASS' then results[:successes] << line_out - end - end - return results - end - - def parse_test_summary(summary) - if summary.find { |v| v =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ } - [$1.to_i,$2.to_i,$3.to_i] - else - raise "Couldn't parse test results: #{summary}" - end - end - - def here; File.expand_path(File.dirname(__FILE__)); end - -end - -if $0 == __FILE__ - uts = UnityTestSummary.new - begin - #look in the specified or current directory for result files - ARGV[0] ||= './' - targets = "#{ARGV[0].gsub(/\\/, '/')}*.test*" - results = Dir[targets] - raise "No *.testpass or *.testfail files found in '#{targets}'" if results.empty? - uts.set_targets(results) - - #set the root path - ARGV[1] ||= File.expand_path(File.dirname(__FILE__)) + '/' - uts.set_root_path(ARGV[1]) - - #run the summarizer - puts uts.run - rescue Exception => e - uts.usage e.message - end -end diff --git a/tests/tools/build_fixture_runner.pl b/tests/tools/build_fixture_runner.pl deleted file mode 100644 index df7eb1817..000000000 --- a/tests/tools/build_fixture_runner.pl +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; -use feature 'say'; - -say "/* THIS IS GENERATED FILE! DO NOT EDIT! DO NOT COMMIT! */"; -say '#include '; -say ''; - -my @run_test_group; -foreach my $file (@ARGV) -{ - my @output = qx(grep -vh '#include' $file | $ENV{CPP} -); - my $test_group_found = 0; - foreach (@output) - { - s/\r//g; - chomp; - if (m/^TEST_GROUP\(/) - { - s/^TEST_GROUP/TEST_GROUP_RUNNER/; - s/;$//; - say "}\n" if ($test_group_found); - say $_; - say '{'; - $test_group_found = 1; - s/TEST_GROUP_RUNNER/\tRUN_TEST_GROUP/; - push @run_test_group, $_; - } - elsif (m/^TEST\(/) - { - s/^TEST/\tRUN_TEST_CASE/; - say "$_;"; - } - elsif (m/^TEST_WITH_TIMEOUT\(/) - { - s/^TEST_WITH_TIMEOUT/\tRUN_TEST_CASE/; - s/,\s+[^,]+\)$/)/; - say "$_;"; - } - } - say "}\n" if ($test_group_found); -} - diff --git a/tests/tools/license.txt b/tests/tools/license.txt deleted file mode 100644 index d66fba53e..000000000 --- a/tests/tools/license.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams - -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. diff --git a/tests/tools/rename_symbols b/tests/tools/rename_symbols deleted file mode 100644 index 2d0b40afb..000000000 --- a/tests/tools/rename_symbols +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -if [ -z "$2" ] -then - echo Usage: $(basename $0) " " 1>&2 - echo " Renames symbols generated by Unity inside object by incorporating unique string into them." 1<&2 - echo " Renaming makes it possible to have testcases with the same name and testsuite under" 1>&2 - echo " different executables" 1>&2 - echo " unique - unique string" 1>&2 - echo " object - object file to modify" 1>&2 - echo " Object file is transformed in-place" 1>&2 - exit 1 -fi - -UNIQUE=$1 -OBJECT=$2 -: ${OBJCOPY:=objcopy} - -# Do not hate me.. love me.. - -$OBJCOPY --redefine-syms <(readelf -Ws $OBJECT | tail -n +4 | awk '{if ($5 != "LOCAL") {print $8, $8}}' | grep -vP '^\s+$' | sed 's/\sTEST_/ TEST_'$UNIQUE'_/') $OBJECT diff --git a/tests/tools/unity_test_summary.rb b/tests/tools/unity_test_summary.rb deleted file mode 100644 index 90bf487ec..000000000 --- a/tests/tools/unity_test_summary.rb +++ /dev/null @@ -1,139 +0,0 @@ -# ========================================== -# Unity Project - A Test Framework for C -# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams -# [Released under MIT License. Please refer to license.txt for details] -# ========================================== - -#!/usr/bin/ruby -# -# unity_test_summary.rb -# -require 'fileutils' -require 'set' - -class UnityTestSummary - include FileUtils::Verbose - - attr_reader :report, :total_tests, :failures, :ignored - - def initialize - @report = '' - @total_tests = 0 - @failures = 0 - @ignored = 0 - end - - def run - # Clean up result file names - results = @targets.map {|target| target.gsub(/\\/,'/')} - - # Dig through each result file, looking for details on pass/fail: - failure_output = [] - ignore_output = [] - - results.each do |result_file| - lines = File.readlines(result_file).map { |line| line.chomp } - if lines.length == 0 - raise "Empty test result file: #{result_file}" - else - output = get_details(result_file, lines) - failure_output << output[:failures] unless output[:failures].empty? - ignore_output << output[:ignores] unless output[:ignores].empty? - tests,failures,ignored = parse_test_summary(lines) - @total_tests += tests - @failures += failures - @ignored += ignored - end - end - - if @ignored > 0 - @report += "\n" - @report += "--------------------------\n" - @report += "UNITY IGNORED TEST SUMMARY\n" - @report += "--------------------------\n" - @report += ignore_output.flatten.join("\n") - end - - if @failures > 0 - @report += "\n" - @report += "--------------------------\n" - @report += "UNITY FAILED TEST SUMMARY\n" - @report += "--------------------------\n" - @report += failure_output.flatten.join("\n") - end - - @report += "\n" - @report += "--------------------------\n" - @report += "OVERALL UNITY TEST SUMMARY\n" - @report += "--------------------------\n" - @report += "#{@total_tests} TOTAL TESTS #{@failures} TOTAL FAILURES #{@ignored} IGNORED\n" - @report += "\n" - end - - def set_targets(target_array) - @targets = target_array - end - - def set_root_path(path) - @root = path - end - - def usage(err_msg=nil) - puts "\nERROR: " - puts err_msg if err_msg - puts "\nUsage: unity_test_summary.rb result_file_directory/ root_path/" - puts " result_file_directory - The location of your results files." - puts " Defaults to current directory if not specified." - puts " Should end in / if specified." - puts " root_path - Helpful for producing more verbose output if using relative paths." - exit 1 - end - - protected - - def get_details(result_file, lines) - results = { :failures => [], :ignores => [], :successes => [] } - lines.each do |line| - src_file,src_line,test_name,status,msg = line.split(/:/) - line_out = ((@root and (@root != 0)) ? "#{@root}#{line}" : line ).gsub(/\//, "\\") - case(status) - when 'IGNORE' then results[:ignores] << line_out - when 'FAIL' then results[:failures] << line_out - when 'PASS' then results[:successes] << line_out - end - end - return results - end - - def parse_test_summary(summary) - if summary.find { |v| v =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ } - [$1.to_i,$2.to_i,$3.to_i] - else - raise "Couldn't parse test results: #{summary}" - end - end - - def here; File.expand_path(File.dirname(__FILE__)); end - -end - -if $0 == __FILE__ - uts = UnityTestSummary.new - begin - #look in the specified or current directory for result files - ARGV[0] ||= './' - targets = "#{ARGV[0].gsub(/\\/, '/')}*.test*" - results = Dir[targets] - raise "No *.testpass or *.testfail files found in '#{targets}'" if results.empty? - uts.set_targets(results) - - #set the root path - ARGV[1] ||= File.expand_path(File.dirname(__FILE__)) + '/' - uts.set_root_path(ARGV[1]) - - #run the summarizer - puts uts.run - rescue Exception => e - uts.usage e.message - end -end diff --git a/tests/unity/.gitignore b/tests/unity/.gitignore deleted file mode 100644 index fa1ec7579..000000000 --- a/tests/unity/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -/Make.dep -/.depend -/.built -/*.asm -/*.obj -/*.rel -/*.lst -/*.sym -/*.adb -/*.lib -/*.src diff --git a/tests/unity/Kconfig b/tests/unity/Kconfig deleted file mode 100644 index e4cba1b6d..000000000 --- a/tests/unity/Kconfig +++ /dev/null @@ -1,22 +0,0 @@ -# -# For a description of the syntax of this configuration file, -# see misc/tools/kconfig-language.txt. -# - -config TESTS_UNITY - bool "Unity fixture example" - default n - ---help--- - Demonstrates Unity fixture and runs its unit test - -if TESTS_UNITY - -config TESTS_UNITY_PROGNAME - string "Program name" - default "unity" - depends on BUILD_KERNEL - ---help--- - This is the name of the program that will be use when the NSH ELF - program is installed. - -endif diff --git a/tests/unity/Make.defs b/tests/unity/Make.defs deleted file mode 100644 index 3709e9a6c..000000000 --- a/tests/unity/Make.defs +++ /dev/null @@ -1,39 +0,0 @@ -############################################################################ -# apps/tests/unity/Make.defs -# Adds selected testing applications to apps/ build -# -# Copyright (C) 2015 Haltian Ltd. All rights reserved. -# Author: Roman Saveljev -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# 3. Neither the name NuttX nor the names of its contributors may be -# used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -############################################################################ - -ifeq ($(CONFIG_TESTS_UNITY),y) -CONFIGURED_APPS += tests/unity -endif diff --git a/tests/unity/Makefile b/tests/unity/Makefile deleted file mode 100644 index 8a93d01c1..000000000 --- a/tests/unity/Makefile +++ /dev/null @@ -1,137 +0,0 @@ -############################################################################ -# apps/examples/unity/Makefile -# -# Copyright (C) 2015 Haltian Ltd. All rights reserved. -# Author: Roman Saveljev -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# 3. Neither the name NuttX nor the names of its contributors may be -# used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -############################################################################ - --include $(TOPDIR)/.config --include $(TOPDIR)/Make.defs -include $(APPDIR)/Make.defs - -# Hello, World! built-in application info - -APPNAME = unity -PRIORITY = SCHED_PRIORITY_DEFAULT -STACKSIZE = 2048 - -ASRCS = -CSRCS = unity_fixture_Test.c unity_fixture_TestRunner.c unity_output_Spy.c -MAINSRC = main/AllTests.c - -AOBJS = $(ASRCS:.S=$(OBJEXT)) -COBJS = $(CSRCS:.c=$(OBJEXT)) -MAINOBJ = $(MAINSRC:.c=$(OBJEXT)) - -SRCS = $(ASRCS) $(CSRCS) $(MAINSRC) -OBJS = $(AOBJS) $(COBJS) - -ifneq ($(CONFIG_BUILD_KERNEL),y) - OBJS += $(MAINOBJ) -endif - -ifeq ($(CONFIG_WINDOWS_NATIVE),y) - BIN = ..\..\libapps$(LIBEXT) -else -ifeq ($(WINTOOL),y) - BIN = ..\\..\\libapps$(LIBEXT) -else - BIN = ../../libapps$(LIBEXT) -endif -endif - -ifeq ($(WINTOOL),y) - INSTALL_DIR = "${shell cygpath -w $(BIN_DIR)}" -else - INSTALL_DIR = $(BIN_DIR) -endif - -CONFIG_EXAMPLES_UNITY_PROGNAME ?= unity$(EXEEXT) -PROGNAME = $(CONFIG_EXAMPLES_UNITY_PROGNAME) - -ROOTDEPPATH = --dep-path . - -# Common build - -VPATH = - -all: .built -.PHONY: clean depend distclean - -$(AOBJS): %$(OBJEXT): %.S - $(call ASSEMBLE, $<, $@) - -$(COBJS) $(MAINOBJ): %$(OBJEXT): %.c - $(call COMPILE, $<, $@) - $(Q) OBJCOPY=$(OBJCOPY) $(APPDIR)/tests/tools/rename_symbols $(APPNAME) $@ - -.built: $(OBJS) - $(call ARCHIVE, $(BIN), $(OBJS)) - @touch .built - -ifeq ($(CONFIG_BUILD_KERNEL),y) -$(BIN_DIR)$(DELIM)$(PROGNAME): $(OBJS) $(MAINOBJ) - @echo "LD: $(PROGNAME)" - $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME) $(ARCHCRT0OBJ) $(MAINOBJ) $(LDLIBS) - $(Q) $(NM) -u $(INSTALL_DIR)$(DELIM)$(PROGNAME) - -install: $(BIN_DIR)$(DELIM)$(PROGNAME) - -else -install: - -endif - -ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) -$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile - $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) - -context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat -else -context: -endif - -.depend: Makefile $(SRCS) - @$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep - @touch $@ - -depend: .depend - -clean: - $(call DELFILE, .built) - $(call CLEAN) - $(Q) rm -f $(OBJS) - -distclean: clean - $(call DELFILE, Make.dep) - $(call DELFILE, .depend) - --include Make.dep diff --git a/tests/unity/main/AllTests.c b/tests/unity/main/AllTests.c deleted file mode 100644 index 18f5278d6..000000000 --- a/tests/unity/main/AllTests.c +++ /dev/null @@ -1,30 +0,0 @@ -//- Copyright (c) 2010 James Grenning and Contributed to Unity Project -/* ========================================== - Unity Project - A Test Framework for C - Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams - [Released under MIT License. Please refer to license.txt for details] -========================================== */ - -#include - -// Enable for manual examination - tests will fail -//#define MANUAL_CHECKING - -static void runAllTests(void) -{ - RUN_TEST_GROUP(UnityFixture); - RUN_TEST_GROUP(UnityCommandOptions); - RUN_TEST_GROUP(LeakDetection); - RUN_TEST_GROUP(Timeout); -#ifdef MANUAL_CHECKING - RUN_TEST_GROUP(TimeoutInSetup); - RUN_TEST_GROUP(TimeoutInBody); - RUN_TEST_GROUP(TimeoutInTearDown); -#endif -} - -int unity_main(int argc, const char* argv[]) -{ - return UnityMain(argc, argv, runAllTests); -} - diff --git a/tests/unity/testunity_fixture.c b/tests/unity/testunity_fixture.c deleted file mode 100644 index 8d4db9f93..000000000 --- a/tests/unity/testunity_fixture.c +++ /dev/null @@ -1,39 +0,0 @@ -//- Copyright (c) 2010 James Grenning and Contributed to Unity Project -/* ========================================== - Unity Project - A Test Framework for C - Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams - [Released under MIT License. Please refer to license.txt for details] -========================================== */ - -#include - -static int data = -1; - -TEST_GROUP(mygroup); - -TEST_SETUP(mygroup) -{ - data = 0; -} - -TEST_TEAR_DOWN(mygroup) -{ - data = -1; -} - -TEST(mygroup, test1) -{ - TEST_ASSERT_EQUAL_INT(0, data); -} - -TEST(mygroup, test2) -{ - TEST_ASSERT_EQUAL_INT(0, data); - data = 5; -} - -TEST(mygroup, test3) -{ - data = 7; - TEST_ASSERT_EQUAL_INT(7, data); -} diff --git a/tests/unity/unity_fixture_Test.c b/tests/unity/unity_fixture_Test.c deleted file mode 100644 index cb55858a2..000000000 --- a/tests/unity/unity_fixture_Test.c +++ /dev/null @@ -1,454 +0,0 @@ -//- Copyright (c) 2010 James Grenning and Contributed to Unity Project -/* ========================================== - Unity Project - A Test Framework for C - Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams - [Released under MIT License. Please refer to license.txt for details] -========================================== */ - -#include -#include "unity_output_Spy.h" -#include -#include - -extern UNITY_FIXTURE_T UnityFixture; - -TEST_GROUP(UnityFixture); - -TEST_SETUP(UnityFixture) -{ -} - -TEST_TEAR_DOWN(UnityFixture) -{ -} - -int my_int; -int* pointer1 = 0; -int* pointer2 = (int*)2; -int* pointer3 = (int*)3; -int int1; -int int2; -int int3; -int int4; - -TEST(UnityFixture, PointerSetting) -{ - TEST_ASSERT_POINTERS_EQUAL(pointer1, 0); - UT_PTR_SET(pointer1, &int1); - UT_PTR_SET(pointer2, &int2); - UT_PTR_SET(pointer3, &int3); - TEST_ASSERT_POINTERS_EQUAL(pointer1, &int1); - TEST_ASSERT_POINTERS_EQUAL(pointer2, &int2); - TEST_ASSERT_POINTERS_EQUAL(pointer3, &int3); - UT_PTR_SET(pointer1, &int4); - UnityPointer_UndoAllSets(); - TEST_ASSERT_POINTERS_EQUAL(pointer1, 0); - TEST_ASSERT_POINTERS_EQUAL(pointer2, (int*)2); - TEST_ASSERT_POINTERS_EQUAL(pointer3, (int*)3); -} - -TEST(UnityFixture, ForceMallocFail) -{ - void* m; - void* mfails; - UnityMalloc_MakeMallocFailAfterCount(1); - m = malloc(10); - CHECK(m); - mfails = malloc(10); - TEST_ASSERT_POINTERS_EQUAL(0, mfails); - free(m); -} - -TEST(UnityFixture, ReallocSmallerIsUnchanged) -{ - void* m1 = malloc(10); - void* m2 = realloc(m1, 5); - TEST_ASSERT_POINTERS_EQUAL(m1, m2); - free(m2); -} - -TEST(UnityFixture, ReallocSameIsUnchanged) -{ - void* m1 = malloc(10); - void* m2 = realloc(m1, 10); - TEST_ASSERT_POINTERS_EQUAL(m1, m2); - free(m2); -} - -TEST(UnityFixture, ReallocLargerNeeded) -{ - void* m1 = malloc(10); - void* m2; - strcpy((char*)m1, "123456789"); - m2 = realloc(m1, 15); - CHECK(m1 != m2); - STRCMP_EQUAL("123456789", m2); - free(m2); -} - -TEST(UnityFixture, ReallocNullPointerIsLikeMalloc) -{ - void* m = realloc(0, 15); - CHECK(m != 0); - free(m); -} - -TEST(UnityFixture, ReallocSizeZeroFreesMemAndReturnsNullPointer) -{ - void* m1 = malloc(10); - void* m2 = realloc(m1, 0); - TEST_ASSERT_POINTERS_EQUAL(0, m2); -} - -TEST(UnityFixture, CallocFillsWithZero) -{ - void* m = calloc(3, sizeof(char)); - char* s = (char*)m; - TEST_ASSERT_BYTES_EQUAL(0, s[0]); - TEST_ASSERT_BYTES_EQUAL(0, s[1]); - TEST_ASSERT_BYTES_EQUAL(0, s[2]); - free(m); -} - -char *p1; -char *p2; - -TEST(UnityFixture, PointerSet) -{ - char c1; - char c2; - char newC1; - char newC2; - p1 = &c1; - p2 = &c2; - - UnityPointer_Init(); - UT_PTR_SET(p1, &newC1); - UT_PTR_SET(p2, &newC2); - TEST_ASSERT_POINTERS_EQUAL(&newC1, p1); - TEST_ASSERT_POINTERS_EQUAL(&newC2, p2); - UnityPointer_UndoAllSets(); - TEST_ASSERT_POINTERS_EQUAL(&c1, p1); - TEST_ASSERT_POINTERS_EQUAL(&c2, p2); -} - -//------------------------------------------------------------ - -TEST_GROUP(UnityCommandOptions); - -static int savedVerbose; -static int savedRepeat; -static int savedListOnly; -static const char* savedName; -static const char* savedGroup; -static const char** savedList; - -TEST_SETUP(UnityCommandOptions) -{ - savedVerbose = UnityFixture.Verbose; - savedRepeat = UnityFixture.RepeatCount; - savedListOnly = UnityFixture.ListOnly; - savedName = UnityFixture.NameFilter; - savedGroup = UnityFixture.GroupFilter; - savedList = UnityFixture.PlainListOfTests; -} - -TEST_TEAR_DOWN(UnityCommandOptions) -{ - UnityFixture.Verbose = savedVerbose; - UnityFixture.RepeatCount= savedRepeat; - UnityFixture.ListOnly = savedListOnly; - UnityFixture.NameFilter = savedName; - UnityFixture.GroupFilter = savedGroup; - UnityFixture.PlainListOfTests = savedList; -} - - -static const char* noOptions[] = { - "testrunner.exe" -}; - -TEST(UnityCommandOptions, DefaultOptions) -{ - UnityGetCommandLineOptions(1, noOptions); - TEST_ASSERT_EQUAL(0, UnityFixture.Verbose); - TEST_ASSERT_POINTERS_EQUAL(0, UnityFixture.GroupFilter); - TEST_ASSERT_POINTERS_EQUAL(0, UnityFixture.NameFilter); - TEST_ASSERT_EQUAL(1, UnityFixture.RepeatCount); -} - -static const char* verbose[] = { - "testrunner.exe", - "-v" -}; - -TEST(UnityCommandOptions, OptionVerbose) -{ - TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(2, verbose)); - TEST_ASSERT_EQUAL(1, UnityFixture.Verbose); -} - -static const char* group[] = { - "testrunner.exe", - "-g", "groupname" -}; - -TEST(UnityCommandOptions, OptionSelectTestByGroup) -{ - TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(3, group)); - STRCMP_EQUAL("groupname", UnityFixture.GroupFilter); -} - -static const char* name[] = { - "testrunner.exe", - "-n", "testname" -}; - -TEST(UnityCommandOptions, OptionSelectTestByName) -{ - TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(3, name)); - STRCMP_EQUAL("testname", UnityFixture.NameFilter); -} - -static const char* repeat[] = { - "testrunner.exe", - "-r", "99" -}; - -TEST(UnityCommandOptions, OptionSelectRepeatTestsDefaultCount) -{ - TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(2, repeat)); - TEST_ASSERT_EQUAL(2, UnityFixture.RepeatCount); -} - -TEST(UnityCommandOptions, OptionSelectRepeatTestsSpecificCount) -{ - TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(3, repeat)); - TEST_ASSERT_EQUAL(99, UnityFixture.RepeatCount); -} - -static const char* multiple[] = { - "testrunner.exe", - "-v", - "-g", "groupname", - "-n", "testname", - "-r", "98" -}; - -TEST(UnityCommandOptions, MultipleOptions) -{ - TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(8, multiple)); - TEST_ASSERT_EQUAL(1, UnityFixture.Verbose); - STRCMP_EQUAL("groupname", UnityFixture.GroupFilter); - STRCMP_EQUAL("testname", UnityFixture.NameFilter); - TEST_ASSERT_EQUAL(98, UnityFixture.RepeatCount); -} - -static const char* dashRNotLast[] = { - "testrunner.exe", - "-v", - "-g", "gggg", - "-r", - "-n", "tttt", -}; - -TEST(UnityCommandOptions, MultipleOptionsDashRNotLastAndNoValueSpecified) -{ - TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(7, dashRNotLast)); - TEST_ASSERT_EQUAL(1, UnityFixture.Verbose); - STRCMP_EQUAL("gggg", UnityFixture.GroupFilter); - STRCMP_EQUAL("tttt", UnityFixture.NameFilter); - TEST_ASSERT_EQUAL(2, UnityFixture.RepeatCount); -} - -static const char* unknownCommand[] = { - "testrunner.exe", - "-v", - "-g", "groupname", - "-n", "testname", - "-r", "98", - "-z" -}; -TEST(UnityCommandOptions, UnknownCommandIsIgnored) -{ - TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(9, unknownCommand)); - TEST_ASSERT_EQUAL(1, UnityFixture.Verbose); - STRCMP_EQUAL("groupname", UnityFixture.GroupFilter); - STRCMP_EQUAL("testname", UnityFixture.NameFilter); - TEST_ASSERT_EQUAL(98, UnityFixture.RepeatCount); -} - -static const char* listing[] = { - "testrunner.exe", - "-l", -}; -TEST(UnityCommandOptions, Listing) -{ - TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(2, listing)); - TEST_ASSERT_EQUAL(1, UnityFixture.ListOnly); -} - -static const char* exactListVerbose[] = { - "testrunner.exe", - "-v", - "--", - "MyTest/TestOne", - "MyTest/TestTwo", - NULL -}; -TEST(UnityCommandOptions, ExactList) -{ - TEST_ASSERT_EQUAL(0, UnityGetCommandLineOptions(5, exactListVerbose)); - TEST_ASSERT_EQUAL(1, UnityFixture.Verbose); - TEST_ASSERT_EQUAL_STRING("MyTest/TestOne", UnityFixture.PlainListOfTests[0]); - TEST_ASSERT_EQUAL_STRING("MyTest/TestTwo", UnityFixture.PlainListOfTests[1]); - TEST_ASSERT_NULL(UnityFixture.PlainListOfTests[2]); -} - -//------------------------------------------------------------ - -TEST_GROUP(LeakDetection); - -TEST_SETUP(LeakDetection) -{ - UnityOutputCharSpy_Create(1000); -} - -TEST_TEAR_DOWN(LeakDetection) -{ - UnityOutputCharSpy_Destroy(); -} - -TEST(LeakDetection, DetectsLeak) -{ - void* m = malloc(10); - UnityOutputCharSpy_Enable(1); - TEST_PROTECTED(UnityMalloc_EndTest); - UnityOutputCharSpy_Enable(0); - CHECK(strstr(UnityOutputCharSpy_Get(), "This test leaks!")); - free(m); - Unity.CurrentTestFailed = 0; -} - -static void BufferOverrunFoundDuringFree_worker(void) -{ - void* m = malloc(10); - char* s = (char*)m; - s[10] = (char)0xFF; - free(m); -} - -TEST(LeakDetection, BufferOverrunFoundDuringFree) -{ - UnityOutputCharSpy_Enable(1); - TEST_PROTECTED(BufferOverrunFoundDuringFree_worker); - UnityOutputCharSpy_Enable(0); - CHECK(strstr(UnityOutputCharSpy_Get(), "Buffer overrun detected during free()")); - Unity.CurrentTestFailed = 0; -} - -static void BufferOverrunFoundDuringRealloc_worker(void) -{ - void* m = malloc(10); - char* s = (char*)m; - s[10] = (char)0xFF; - m = realloc(m, 100); -} - -TEST(LeakDetection, BufferOverrunFoundDuringRealloc) -{ - UnityOutputCharSpy_Enable(1); - TEST_PROTECTED(BufferOverrunFoundDuringRealloc_worker); - UnityOutputCharSpy_Enable(0); - CHECK(strstr(UnityOutputCharSpy_Get(), "Buffer overrun detected during realloc()")); - Unity.CurrentTestFailed = 0; -} - -//------------------------------------------------------------ - -TEST_GROUP(Timeout); - -TEST_SETUP(Timeout) -{ -} - -TEST_TEAR_DOWN(Timeout) -{ -} - -static void SleepSome(void) -{ - usleep(100000); -} - -TEST(Timeout, Triggers) -{ - int result = TEST_PROTECTED_WITH_TIMEOUT(SleepSome, 10); - TEST_ASSERT_TRUE(Unity.CurrentTestTimeout); - TEST_ASSERT_NOT_EQUAL(0, result); - Unity.CurrentTestTimeout = false; -} - -TEST(Timeout, DoesNotTrigger) -{ - int result = TEST_PROTECTED_WITH_TIMEOUT(SleepSome, 200); - UNITY_COUNTER_TYPE isTimeout = Unity.CurrentTestTimeout; - Unity.CurrentTestTimeout = 0; - TEST_ASSERT_EQUAL(0, result); - TEST_ASSERT_FALSE(isTimeout); -} - -//------------------------------------------------------------ -// Manual checking -//------------------------------------------------------------ - -TEST_GROUP(TimeoutInSetup); - -TEST_SETUP_WITH_TIMEOUT(TimeoutInSetup, 100) -{ - usleep(300000); -} - -TEST_TEAR_DOWN_WITH_TIMEOUT(TimeoutInSetup, 100) -{ - usleep(2); -} - -TEST_WITH_TIMEOUT(TimeoutInSetup, Test, 100) -{ - usleep(2); -} - -TEST_GROUP(TimeoutInBody); - -TEST_SETUP_WITH_TIMEOUT(TimeoutInBody, 100) -{ - usleep(2); -} - -TEST_TEAR_DOWN_WITH_TIMEOUT(TimeoutInBody, 100) -{ - usleep(2); -} - -TEST_WITH_TIMEOUT(TimeoutInBody, Test, 100) -{ - usleep(300000); -} - -TEST_GROUP(TimeoutInTearDown); - -TEST_SETUP_WITH_TIMEOUT(TimeoutInTearDown, 100) -{ - usleep(2); -} - -TEST_TEAR_DOWN_WITH_TIMEOUT(TimeoutInTearDown, 100) -{ - usleep(300000); -} - -TEST_WITH_TIMEOUT(TimeoutInTearDown, Test, 100) -{ - usleep(2); -} diff --git a/tests/unity/unity_fixture_TestRunner.c b/tests/unity/unity_fixture_TestRunner.c deleted file mode 100644 index 5661e275f..000000000 --- a/tests/unity/unity_fixture_TestRunner.c +++ /dev/null @@ -1,64 +0,0 @@ -//- Copyright (c) 2010 James Grenning and Contributed to Unity Project -/* ========================================== - Unity Project - A Test Framework for C - Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams - [Released under MIT License. Please refer to license.txt for details] -========================================== */ - -#include - -TEST_GROUP_RUNNER(UnityFixture) -{ - RUN_TEST_CASE(UnityFixture, PointerSetting); - RUN_TEST_CASE(UnityFixture, ForceMallocFail); - RUN_TEST_CASE(UnityFixture, ReallocSmallerIsUnchanged); - RUN_TEST_CASE(UnityFixture, ReallocSameIsUnchanged); - RUN_TEST_CASE(UnityFixture, ReallocLargerNeeded); - RUN_TEST_CASE(UnityFixture, ReallocNullPointerIsLikeMalloc); - RUN_TEST_CASE(UnityFixture, ReallocSizeZeroFreesMemAndReturnsNullPointer); - RUN_TEST_CASE(UnityFixture, CallocFillsWithZero); - RUN_TEST_CASE(UnityFixture, PointerSet); -} - -TEST_GROUP_RUNNER(UnityCommandOptions) -{ - RUN_TEST_CASE(UnityCommandOptions, DefaultOptions); - RUN_TEST_CASE(UnityCommandOptions, OptionVerbose); - RUN_TEST_CASE(UnityCommandOptions, OptionSelectTestByGroup); - RUN_TEST_CASE(UnityCommandOptions, OptionSelectTestByName); - RUN_TEST_CASE(UnityCommandOptions, OptionSelectRepeatTestsDefaultCount); - RUN_TEST_CASE(UnityCommandOptions, OptionSelectRepeatTestsSpecificCount); - RUN_TEST_CASE(UnityCommandOptions, MultipleOptions); - RUN_TEST_CASE(UnityCommandOptions, MultipleOptionsDashRNotLastAndNoValueSpecified); - RUN_TEST_CASE(UnityCommandOptions, UnknownCommandIsIgnored); - RUN_TEST_CASE(UnityCommandOptions, Listing); - RUN_TEST_CASE(UnityCommandOptions, ExactList); -} - -TEST_GROUP_RUNNER(LeakDetection) -{ - RUN_TEST_CASE(LeakDetection, DetectsLeak); - RUN_TEST_CASE(LeakDetection, BufferOverrunFoundDuringFree); - RUN_TEST_CASE(LeakDetection, BufferOverrunFoundDuringRealloc); -} - -TEST_GROUP_RUNNER(Timeout) -{ - RUN_TEST_CASE(Timeout, Triggers); - RUN_TEST_CASE(Timeout, DoesNotTrigger); -} - -TEST_GROUP_RUNNER(TimeoutInSetup) -{ - RUN_TEST_CASE(TimeoutInSetup, Test); -} - -TEST_GROUP_RUNNER(TimeoutInBody) -{ - RUN_TEST_CASE(TimeoutInBody, Test); -} - -TEST_GROUP_RUNNER(TimeoutInTearDown) -{ - RUN_TEST_CASE(TimeoutInTearDown, Test); -} diff --git a/tests/unity/unity_output_Spy.c b/tests/unity/unity_output_Spy.c deleted file mode 100644 index 0a0ad0448..000000000 --- a/tests/unity/unity_output_Spy.c +++ /dev/null @@ -1,56 +0,0 @@ -//- Copyright (c) 2010 James Grenning and Contributed to Unity Project -/* ========================================== - Unity Project - A Test Framework for C - Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams - [Released under MIT License. Please refer to license.txt for details] -========================================== */ - - -#include "unity_output_Spy.h" -#include -#include -#include - -static int size; -static int count; -static char* buffer; -static int spy_enable; - -void UnityOutputCharSpy_Create(int s) -{ - size = s; - count = 0; - spy_enable = 0; - buffer = malloc(size); - memset(buffer, 0, size); -} - -void UnityOutputCharSpy_Destroy(void) -{ - size = 0; - free(buffer); -} - -int UnityOutputCharSpy_OutputChar(int c) -{ - if (spy_enable) - { - if (count < (size-1)) - buffer[count++] = c; - } - else - { - putchar(c); - } - return c; -} - -const char * UnityOutputCharSpy_Get(void) -{ - return buffer; -} - -void UnityOutputCharSpy_Enable(int enable) -{ - spy_enable = enable; -} diff --git a/tests/unity/unity_output_Spy.h b/tests/unity/unity_output_Spy.h deleted file mode 100644 index 791f6a58d..000000000 --- a/tests/unity/unity_output_Spy.h +++ /dev/null @@ -1,17 +0,0 @@ -//- Copyright (c) 2010 James Grenning and Contributed to Unity Project -/* ========================================== - Unity Project - A Test Framework for C - Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams - [Released under MIT License. Please refer to license.txt for details] -========================================== */ - -#ifndef D_unity_output_Spy_H -#define D_unity_output_Spy_H - -void UnityOutputCharSpy_Create(int s); -void UnityOutputCharSpy_Destroy(void); -int UnityOutputCharSpy_OutputChar(int c); -const char * UnityOutputCharSpy_Get(void); -void UnityOutputCharSpy_Enable(int enable); - -#endif diff --git a/tests/unity_ramtest/.gitignore b/tests/unity_ramtest/.gitignore deleted file mode 100644 index fa1ec7579..000000000 --- a/tests/unity_ramtest/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -/Make.dep -/.depend -/.built -/*.asm -/*.obj -/*.rel -/*.lst -/*.sym -/*.adb -/*.lib -/*.src diff --git a/tests/unity_ramtest/Kconfig b/tests/unity_ramtest/Kconfig deleted file mode 100644 index 554b24819..000000000 --- a/tests/unity_ramtest/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -# -# For a description of the syntax of this configuration file, -# see misc/tools/kconfig-language.txt. -# - -config TESTS_UNITY_RAMTEST - bool "Automated RAM test" - default n - ---help--- - Enable automated RAM test - diff --git a/tests/unity_ramtest/Make.defs b/tests/unity_ramtest/Make.defs deleted file mode 100644 index 88a6de118..000000000 --- a/tests/unity_ramtest/Make.defs +++ /dev/null @@ -1,39 +0,0 @@ -############################################################################ -# apps/tests/unity_ramtest/Make.defs -# Adds selected testing applications to apps/ build -# -# Copyright (C) 2015 Haltian Ltd. All rights reserved. -# Author: Roman Saveljev -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# 3. Neither the name NuttX nor the names of its contributors may be -# used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -############################################################################ - -ifeq ($(CONFIG_TESTS_UNITY_RAMTEST),y) -CONFIGURED_APPS += tests/unity_ramtest -endif diff --git a/tests/unity_ramtest/Makefile b/tests/unity_ramtest/Makefile deleted file mode 100644 index 2517a218d..000000000 --- a/tests/unity_ramtest/Makefile +++ /dev/null @@ -1,146 +0,0 @@ -############################################################################ -# apps/tests/unity_ramtest/Makefile -# -# Copyright (C) 2015 Haltian Ltd. All rights reserved. -# Author: Roman Saveljev -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# 3. Neither the name NuttX nor the names of its contributors may be -# used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -############################################################################ - --include $(TOPDIR)/.config --include $(TOPDIR)/Make.defs -include $(APPDIR)/Make.defs - -APPNAME = unity_ramtest -PRIORITY = SCHED_PRIORITY_DEFAULT -STACKSIZE = 2048 - -CFLAGS += -x c - -ASRCS = -RUNNERSRC = unity_ramtest_runner.src -TESTSRCS = marching_zeroes.c marching_ones.c pattern.c addr_in_addr.c -CSRCS = $(TESTSRCS) -MAINSRC = unity_ramtest_main.c - -RUNNEROBJ = $(RUNNERSRC:.src=$(OBJEXT)) -AOBJS = $(ASRCS:.S=$(OBJEXT)) -COBJS = $(CSRCS:.c=$(OBJEXT)) -MAINOBJ = $(MAINSRC:.c=$(OBJEXT)) - -SRCS = $(ASRCS) $(CSRCS) $(MAINSRC) $(RUNNERSRC) -OBJS = $(AOBJS) $(COBJS) $(RUNNEROBJ) - -ifneq ($(CONFIG_BUILD_KERNEL),y) - OBJS += $(MAINOBJ) -endif - -ifeq ($(CONFIG_WINDOWS_NATIVE),y) - BIN = ..\..\libapps$(LIBEXT) -else -ifeq ($(WINTOOL),y) - BIN = ..\\..\\libapps$(LIBEXT) -else - BIN = ../../libapps$(LIBEXT) -endif -endif - -ifeq ($(WINTOOL),y) - INSTALL_DIR = "${shell cygpath -w $(BIN_DIR)}" -else - INSTALL_DIR = $(BIN_DIR) -endif - -PROGNAME = unity_ramtest$(EXEEXT) - -ROOTDEPPATH = --dep-path . - -# Common build - -VPATH = - -all: .built -.PHONY: clean depend distclean - -$(RUNNERSRC) : $(TESTSRCS) - $(Q) CPP="$(CPP)" $(APPDIR)/tests/tools/build_fixture_runner.pl $^ >$@ - -$(AOBJS): %$(OBJEXT): %.S - $(call ASSEMBLE, $<, $@) - -$(RUNNEROBJ): $(RUNNERSRC) - $(call COMPILE, $<, $@) - $(Q) OBJCOPY=$(OBJCOPY) $(APPDIR)/tests/tools/rename_symbols $(APPNAME) $@ - -$(COBJS) $(MAINOBJ): %$(OBJEXT): %.c - $(call COMPILE, $<, $@) - $(Q) OBJCOPY=$(OBJCOPY) $(APPDIR)/tests/tools/rename_symbols $(APPNAME) $@ - -.built: $(OBJS) - $(call ARCHIVE, $(BIN), $(OBJS)) - @touch .built - -ifeq ($(CONFIG_BUILD_KERNEL),y) -$(BIN_DIR)$(DELIM)$(PROGNAME): $(OBJS) $(MAINOBJ) - @echo "LD: $(PROGNAME)" - $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME) $(ARCHCRT0OBJ) $(MAINOBJ) $(LDLIBS) - $(Q) $(NM) -u $(INSTALL_DIR)$(DELIM)$(PROGNAME) - -install: $(BIN_DIR)$(DELIM)$(PROGNAME) - -else -install: - -endif - -ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) -$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile - $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) - -context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat -else -context: -endif - -.depend: Makefile $(SRCS) - @$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep - @touch $@ - -depend: .depend - -clean: - $(call DELFILE, .built) - $(call DELFILE, unity_dev_err_runner.src) - $(call CLEAN) - -distclean: clean - $(call DELFILE, Make.dep) - $(call DELFILE, .depend) - --include Make.dep diff --git a/tests/unity_ramtest/addr_in_addr.c b/tests/unity_ramtest/addr_in_addr.c deleted file mode 100644 index edbb9067e..000000000 --- a/tests/unity_ramtest/addr_in_addr.c +++ /dev/null @@ -1,185 +0,0 @@ -/**************************************************************************** - * apps/tests/unity_ramtest/addr_in_addr.c - * Automated RAM test copied from apps/system/ramtest - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Author: Roman Saveljev - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include "library.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ -static void* g_memory; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -static void addr_in_addr(enum memory_access_width width) -{ - unity_ramtest_write_addrinaddr(width, g_memory, MEMORY_ALLOCATION_SIZE); - unity_ramtest_verify_addrinaddr(width, g_memory, MEMORY_ALLOCATION_SIZE); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -TEST_GROUP(AddrInAddr); - -/**************************************************************************** - * Name: AddrInAddr test group setup - * - * Description: - * Setup function executed before each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_SETUP(AddrInAddr) -{ - g_memory = malloc(MEMORY_ALLOCATION_SIZE); - TEST_ASSERT_NOT_NULL(g_memory); -} - -/**************************************************************************** - * Name: AddrInAddr test group tear down - * - * Description: - * Tear down function executed after each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_TEAR_DOWN(AddrInAddr) -{ - free(g_memory); - g_memory = NULL; -} - -/**************************************************************************** - * Name: ByteAccess - * - * Description: - * Daisy-chain writing the memory one byte at a time - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(AddrInAddr, ByteAccess) -{ - addr_in_addr(MEMORY_ACCESS_BYTE); -} - -/**************************************************************************** - * Name: HalfAccess - * - * Description: - * Daisy-chain writing the memory a half-word at a time - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(AddrInAddr, HalfAccess) -{ - addr_in_addr(MEMORY_ACCESS_HALFWORD); -} - -/**************************************************************************** - * Name: WordAccess - * - * Description: - * Daisy-chain writing the memory a word at a time - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(AddrInAddr, WordAccess) -{ - addr_in_addr(MEMORY_ACCESS_WORD); -} diff --git a/tests/unity_ramtest/library.h b/tests/unity_ramtest/library.h deleted file mode 100644 index fd1de1056..000000000 --- a/tests/unity_ramtest/library.h +++ /dev/null @@ -1,196 +0,0 @@ -/**************************************************************************** - * apps/examples/unity_ramtest/library.h - * Common functions - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Author: Roman Saveljev - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ -#ifndef __TESTS_UNITY_RAMTEST_LIBRARY_H -#define __TESTS_UNITY_RAMTEST_LIBRARY_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ -#define MEMORY_ALLOCATION_SIZE 0x2000 - -/**************************************************************************** - * Public Types - ****************************************************************************/ -enum memory_access_width -{ - MEMORY_ACCESS_BYTE = 8, - MEMORY_ACCESS_HALFWORD = 16, - MEMORY_ACCESS_WORD = 32 -}; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Inline Functions - ****************************************************************************/ - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Name: unity_ramtest_write_memory - * - * Description: - * Write memory with specific pattern and access width - * - * Input Parameters: - * value - pattern to write - * width - access width - * start - memory region starting address - * size - number of bytes allocated for the region - * - * Returned Value: - * none, fails the testcase - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -void unity_ramtest_write_memory(uint32_t value, enum memory_access_width width, void *start, size_t size); - -/**************************************************************************** - * Name: unity_ramtest_verify_memory - * - * Description: - * Verifies memory has specific pattern and reading it with access width - * - * Input Parameters: - * value - pattern to expect - * width - access width - * start - memory region starting address - * size - number of bytes allocated for the region - * - * Returned Value: - * none, fails the testcase - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -void unity_ramtest_verify_memory(uint32_t value, enum memory_access_width width, void *start, size_t size); - -/**************************************************************************** - * Name: unity_ramtest_write_memory2 - * - * Description: - * Writes memory with two alternating patterns - * - * Input Parameters: - * value_one - first pattern to write - * value_two - second pattern to write - * width - access width - * start - memory region starting address - * size - number of bytes allocated for the region - * - * Returned Value: - * none, fails the testcase - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -void unity_ramtest_write_memory2(uint32_t value_one, uint32_t value_two, enum memory_access_width width, void *start, size_t size); - -/**************************************************************************** - * Name: unity_ramtest_verify_memory2 - * - * Description: - * Verifies memory is filled with two alternating patterns - * - * Input Parameters: - * value_one - first pattern to expect - * value_two - second pattern to expect - * width - access width - * start - memory region starting address - * size - number of bytes allocated for the region - * - * Returned Value: - * none, fails the testcase - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -void unity_ramtest_verify_memory2(uint32_t value_one, uint32_t value_two, enum memory_access_width width, void *start, size_t size); - -/**************************************************************************** - * Name: unity_ramtest_write_addrinaddr - * - * Description: - * Writes every next memory location with the value from the previous location - * - * Input Parameters: - * width - access width - * start - memory region starting address - * size - number of bytes allocated for the region - * - * Returned Value: - * none, fails the testcase - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -void unity_ramtest_write_addrinaddr(enum memory_access_width width, void *start, size_t size); - -/**************************************************************************** - * Name: unity_ramtest_verify_addrinaddr - * - * Description: - * Verifies every memory location is filled with the value from the previous location - * - * Input Parameters: - * width - access width - * start - memory region starting address - * size - number of bytes allocated for the region - * - * Returned Value: - * none, fails the testcase - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -void unity_ramtest_verify_addrinaddr(enum memory_access_width width, void *start, size_t size); - -#endif /* __TESTS_UNITY_RAMTEST_LIBRARY_H */ diff --git a/tests/unity_ramtest/marching_ones.c b/tests/unity_ramtest/marching_ones.c deleted file mode 100644 index 5a77ed3f8..000000000 --- a/tests/unity_ramtest/marching_ones.c +++ /dev/null @@ -1,191 +0,0 @@ -/**************************************************************************** - * apps/tests/unity_ramtest/marching_ones.c - * Automated RAM test copied from apps/system/ramtest - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Author: Roman Saveljev - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include "library.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ -static void* g_memory; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ -static void marching_ones(enum memory_access_width width, uint32_t mask) -{ - uint32_t pattern = 0x00000001; - - while (pattern != 0) - { - unity_ramtest_write_memory(pattern, width, g_memory, MEMORY_ALLOCATION_SIZE); - unity_ramtest_verify_memory(pattern, width, g_memory, MEMORY_ALLOCATION_SIZE); - pattern <<= 1; - pattern &= mask; - } -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -TEST_GROUP(MarchingOnes); - -/**************************************************************************** - * Name: MarchingOnes test group setup - * - * Description: - * Setup function executed before each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_SETUP(MarchingOnes) -{ - g_memory = malloc(MEMORY_ALLOCATION_SIZE); - TEST_ASSERT_NOT_NULL(g_memory); -} - -/**************************************************************************** - * Name: MarchingOnes test group tear down - * - * Description: - * Tear down function executed after each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_TEAR_DOWN(MarchingOnes) -{ - free(g_memory); - g_memory = NULL; -} - -/**************************************************************************** - * Name: ByteAccess - * - * Description: - * Running one on every memory location with byte access width - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(MarchingOnes, ByteAccess) -{ - marching_ones(MEMORY_ACCESS_BYTE, 0xff); -} - -/**************************************************************************** - * Name: HalfAccess - * - * Description: - * Running one on every memory location with half-word access width - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(MarchingOnes, HalfAccess) -{ - marching_ones(MEMORY_ACCESS_HALFWORD, 0xffff); -} - -/**************************************************************************** - * Name: WordAccess - * - * Description: - * Running one on every memory location with word access width - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(MarchingOnes, WordAccess) -{ - marching_ones(MEMORY_ACCESS_WORD, 0xffffffff); -} diff --git a/tests/unity_ramtest/marching_zeroes.c b/tests/unity_ramtest/marching_zeroes.c deleted file mode 100644 index bc54be0a2..000000000 --- a/tests/unity_ramtest/marching_zeroes.c +++ /dev/null @@ -1,193 +0,0 @@ -/**************************************************************************** - * apps/tests/unity_ramtest/marching_zeroes.c - * Automated RAM test copied from apps/system/ramtest - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Author: Roman Saveljev - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include "library.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ -static void* g_memory; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -static void marching_zeroes(enum memory_access_width width, uint32_t mask) -{ - uint32_t pattern = 0xfffffffe; - - while (pattern != 0xffffffff) - { - unity_ramtest_write_memory(pattern, width, g_memory, MEMORY_ALLOCATION_SIZE); - unity_ramtest_verify_memory(pattern, width, g_memory, MEMORY_ALLOCATION_SIZE); - pattern <<= 1; - pattern |= 1; - pattern |= ~mask; - } -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -TEST_GROUP(MarchingZeroes); - -/**************************************************************************** - * Name: MarchingZeroes test group setup - * - * Description: - * Setup function executed before each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_SETUP(MarchingZeroes) -{ - g_memory = malloc(MEMORY_ALLOCATION_SIZE); - TEST_ASSERT_NOT_NULL(g_memory); -} - -/**************************************************************************** - * Name: MarchingZeroes test group tear down - * - * Description: - * Tear down function executed after each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_TEAR_DOWN(MarchingZeroes) -{ - free(g_memory); - g_memory = NULL; -} - -/**************************************************************************** - * Name: ByteAccess - * - * Description: - * Running zero on every memory location with byte access width - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(MarchingZeroes, ByteAccess) -{ - marching_zeroes(MEMORY_ACCESS_BYTE, 0xff); -} - -/**************************************************************************** - * Name: HalfAccess - * - * Description: - * Running zero on every memory location with half-word access width - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(MarchingZeroes, HalfAccess) -{ - marching_zeroes(MEMORY_ACCESS_HALFWORD, 0xffff); -} - -/**************************************************************************** - * Name: WordAccess - * - * Description: - * Running zero on every memory location with word access width - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(MarchingZeroes, WordAccess) -{ - marching_zeroes(MEMORY_ACCESS_WORD, 0xffffffff); -} diff --git a/tests/unity_ramtest/pattern.c b/tests/unity_ramtest/pattern.c deleted file mode 100644 index 89d2b705e..000000000 --- a/tests/unity_ramtest/pattern.c +++ /dev/null @@ -1,311 +0,0 @@ -/**************************************************************************** - * apps/tests/unity_ramtest/pattern.c - * Automated RAM test copied from apps/system/ramtest - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Author: Roman Saveljev - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include "library.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ -static void* g_memory; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -static void pattern(enum memory_access_width width, uint32_t value_one, uint32_t value_two) -{ - unity_ramtest_write_memory2(value_one, value_two, width, g_memory, MEMORY_ALLOCATION_SIZE); - unity_ramtest_verify_memory2(value_one, value_two, width, g_memory, MEMORY_ALLOCATION_SIZE); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -TEST_GROUP(Pattern); - -/**************************************************************************** - * Name: Pattern test group setup - * - * Description: - * Setup function executed before each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_SETUP(Pattern) -{ - g_memory = malloc(MEMORY_ALLOCATION_SIZE); - TEST_ASSERT_NOT_NULL(g_memory); -} - -/**************************************************************************** - * Name: Pattern test group tear down - * - * Description: - * Tear down function executed after each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_TEAR_DOWN(Pattern) -{ - free(g_memory); - g_memory = NULL; -} - -/**************************************************************************** - * Name: ByteAccess_5_a - * - * Description: - * Writing pattern 0x55 and 0xaa with byte access - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(Pattern, ByteAccess_5_a) -{ - pattern(MEMORY_ACCESS_BYTE, 0x55, 0xaa); -} - -/**************************************************************************** - * Name: ByteAccess_6_9 - * - * Description: - * Writing pattern 0x66 and 0x99 with byte access - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(Pattern, ByteAccess_6_9) -{ - pattern(MEMORY_ACCESS_BYTE, 0x66, 0x99); -} - -/**************************************************************************** - * Name: ByteAccess_3_c - * - * Description: - * Writing pattern 0x33 and 0xcc with byte access - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(Pattern, ByteAccess_3_c) -{ - pattern(MEMORY_ACCESS_BYTE, 0x33, 0xcc); -} - -/**************************************************************************** - * Name: HalfAccess_5_a - * - * Description: - * Writing pattern 0x5555 and 0xaaaa with byte access - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(Pattern, HalfAccess_5_a) -{ - pattern(MEMORY_ACCESS_BYTE, 0x5555, 0xaaaa); -} - -/**************************************************************************** - * Name: HalfAccess_6_9 - * - * Description: - * Writing pattern 0x6666 and 0x9999 with byte access - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(Pattern, HalfAccess_6_9) -{ - pattern(MEMORY_ACCESS_BYTE, 0x6666, 0x9999); -} - -/**************************************************************************** - * Name: HalfAccess_3_c - * - * Description: - * Writing pattern 0x3333 and 0xcccc with byte access - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(Pattern, HalfAccess_3_c) -{ - pattern(MEMORY_ACCESS_BYTE, 0x3333, 0xcccc); -} - -/**************************************************************************** - * Name: WordAccess_5_a - * - * Description: - * Writing pattern 0x55555555 and 0xaaaaaaaa with byte access - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(Pattern, WordAccess_5_a) -{ - pattern(MEMORY_ACCESS_BYTE, 0x55555555, 0xaaaaaaaa); -} - -/**************************************************************************** - * Name: WordAccess_6_9 - * - * Description: - * Writing pattern 0x66666666 and 0x99999999 with byte access - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(Pattern, WordAccess_6_9) -{ - pattern(MEMORY_ACCESS_BYTE, 0x66666666, 0x99999999); -} - -/**************************************************************************** - * Name: WordAccess_3_c - * - * Description: - * Writing pattern 0x33333333 and 0xcccccccc with byte access - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(Pattern, WordAccess_3_c) -{ - pattern(MEMORY_ACCESS_BYTE, 0x33333333, 0xcccccccc); -} diff --git a/tests/unity_ramtest/unity_ramtest_main.c b/tests/unity_ramtest/unity_ramtest_main.c deleted file mode 100644 index c86b9fba6..000000000 --- a/tests/unity_ramtest/unity_ramtest_main.c +++ /dev/null @@ -1,503 +0,0 @@ -/**************************************************************************** - * apps/tests/unity_ramtest/unity_ramtest_main.c - * Main function for Unity test application - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Author: Roman Saveljev - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include - -#include "library.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ -static void runAllTests(void); - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: runAllTests - * - * Description: - * Sequentially runs all included test groups - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void runAllTests(void) -{ - RUN_TEST_GROUP(MarchingZeroes); - RUN_TEST_GROUP(MarchingOnes); - RUN_TEST_GROUP(Pattern); - RUN_TEST_GROUP(AddrInAddr); -} - -/**************************************************************************** - * Name: number_of_transfers - * - * Description: - * Calculate number of transfers to cover the chunk of memory - * - * Input Parameters: - * width - access width - * size - memory size - * - * Returned Value: - * Number of transfers - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static size_t number_of_transfers(enum memory_access_width width, size_t size) -{ - if (width == MEMORY_ACCESS_BYTE) - { - return size; - } - else if (width == MEMORY_ACCESS_WORD) - { - return size >> 2; - } - else if (width == MEMORY_ACCESS_HALFWORD) - { - return size >> 1; - } - else - { - DEBUGASSERT(0); - return 0; - } -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: unity_ramtest_write_memory - * - * Description: - * Write memory with specific pattern and access width - * - * Input Parameters: - * value - pattern to write - * width - access width - * start - memory region starting address - * size - number of bytes allocated for the region - * - * Returned Value: - * none, fails the testcase - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -void unity_ramtest_write_memory(uint32_t value, enum memory_access_width width, void *start, size_t size) -{ - size_t i, nxfrs = number_of_transfers(width, size); - - if (width == MEMORY_ACCESS_WORD) - { - uint32_t *ptr = (uint32_t*)start; - for (i = 0; i < nxfrs; i++) - { - *ptr++ = value; - } - } - else if (width == MEMORY_ACCESS_HALFWORD) - { - uint16_t *ptr = (uint16_t*)start; - for (i = 0; i < nxfrs; i++) - { - *ptr++ = (uint16_t)value; - } - } - else if (width == MEMORY_ACCESS_BYTE) - { - uint8_t *ptr = (uint8_t*)start; - for (i = 0; i < nxfrs; i++) - { - *ptr++ = (uint8_t)value; - } - } - else - { - TEST_FAIL_MESSAGE("Invalid width value"); - } -} - -/**************************************************************************** - * Name: unity_ramtest_verify_memory - * - * Description: - * Verifies memory has specific pattern and reading it with access width - * - * Input Parameters: - * value - pattern to expect - * width - access width - * start - memory region starting address - * size - number of bytes allocated for the region - * - * Returned Value: - * none, fails the testcase - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -void unity_ramtest_verify_memory(uint32_t value, enum memory_access_width width, void *start, size_t size) -{ - size_t i, nxfrs = number_of_transfers(width, size); - - if (width == MEMORY_ACCESS_WORD) - { - uint32_t *ptr = (uint32_t*)start; - for (i = 0; i < nxfrs; i++) - { - TEST_ASSERT_EQUAL_HEX32(value, *ptr); - ptr++; - } - } - else if (width == MEMORY_ACCESS_HALFWORD) - { - uint16_t value16 = (uint16_t)(value & 0x0000ffff); - uint16_t *ptr = (uint16_t*)start; - for (i = 0; i < nxfrs; i++) - { - TEST_ASSERT_EQUAL_HEX16(value16, *ptr); - ptr++; - } - } - else if (width == MEMORY_ACCESS_BYTE) - { - uint8_t value8 = (uint8_t)(value & 0x000000ff); - uint8_t *ptr = (uint8_t*)start; - for (i = 0; i < nxfrs; i++) - { - TEST_ASSERT_EQUAL_HEX(value8, *ptr); - ptr++; - } - } - else - { - TEST_FAIL_MESSAGE("Invalid width value"); - } -} - -/**************************************************************************** - * Name: unity_ramtest_write_memory2 - * - * Description: - * Writes memory with two alternating patterns - * - * Input Parameters: - * value_one - first pattern to write - * value_two - second pattern to write - * width - access width - * start - memory region starting address - * size - number of bytes allocated for the region - * - * Returned Value: - * none, fails the testcase - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -void unity_ramtest_write_memory2(uint32_t value_one, uint32_t value_two, enum memory_access_width width, void *start, size_t size) -{ - size_t even_nxfrs = number_of_transfers(width, size) & ~1; - size_t i; - - if (width == MEMORY_ACCESS_WORD) - { - uint32_t *ptr = (uint32_t*)start; - for (i = 0; i < even_nxfrs; i += 2) - { - *ptr++ = value_one; - *ptr++ = value_two; - } - } - else if (width == MEMORY_ACCESS_HALFWORD) - { - uint16_t *ptr = (uint16_t*)start; - for (i = 0; i < even_nxfrs; i += 2) - { - *ptr++ = (uint16_t)value_one; - *ptr++ = (uint16_t)value_two; - } - } - else if (width == MEMORY_ACCESS_BYTE) - { - uint8_t *ptr = (uint8_t*)start; - for (i = 0; i < even_nxfrs; i += 2) - { - *ptr++ = (uint8_t)value_one; - *ptr++ = (uint8_t)value_two; - } - } - else - { - TEST_FAIL_MESSAGE("Invalid width value"); - } -} - -/**************************************************************************** - * Name: unity_ramtest_verify_memory2 - * - * Description: - * Verifies memory is filled with two alternating patterns - * - * Input Parameters: - * value_one - first pattern to expect - * value_two - second pattern to expect - * width - access width - * start - memory region starting address - * size - number of bytes allocated for the region - * - * Returned Value: - * none, fails the testcase - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -void unity_ramtest_verify_memory2(uint32_t value_one, uint32_t value_two, enum memory_access_width width, void *start, size_t size) -{ - size_t even_nxfrs = number_of_transfers(width, size) & ~1; - size_t i; - - if (width == MEMORY_ACCESS_WORD) - { - uint32_t *ptr = (uint32_t*)start; - for (i = 0; i < even_nxfrs; i += 2) - { - TEST_ASSERT_EQUAL_HEX32(value_one, ptr[0]); - TEST_ASSERT_EQUAL_HEX32(value_two, ptr[1]); - ptr += 2; - } - } - else if (width == MEMORY_ACCESS_HALFWORD) - { - uint16_t value16_one = (uint16_t)(value_one & 0x0000ffff); - uint16_t value16_two = (uint16_t)(value_two & 0x0000ffff); - uint16_t *ptr = (uint16_t*)start; - for (i = 0; i < even_nxfrs; i += 2) - { - TEST_ASSERT_EQUAL_HEX16(value16_one, ptr[0]); - TEST_ASSERT_EQUAL_HEX16(value16_two, ptr[1]); - ptr += 2; - } - } - else if (width == MEMORY_ACCESS_BYTE) - { - uint8_t value8_one = (uint8_t)(value_one & 0x000000ff); - uint8_t value8_two = (uint8_t)(value_two & 0x000000ff); - uint8_t *ptr = (uint8_t*)start; - for (i = 0; i < even_nxfrs; i += 2) - { - TEST_ASSERT_EQUAL_HEX(value8_one, ptr[0]); - TEST_ASSERT_EQUAL_HEX(value8_two, ptr[1]); - ptr += 2; - } - } - else - { - TEST_FAIL_MESSAGE("Invalid width value"); - } -} - -/**************************************************************************** - * Name: unity_ramtest_write_addrinaddr - * - * Description: - * Writes every next memory location with the value from the previous location - * - * Input Parameters: - * width - access width - * start - memory region starting address - * size - number of bytes allocated for the region - * - * Returned Value: - * none, fails the testcase - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -void unity_ramtest_write_addrinaddr(enum memory_access_width width, void *start, size_t size) -{ - size_t i, nxfrs = number_of_transfers(width, size); - - if (width == MEMORY_ACCESS_WORD) - { - uint32_t *ptr = (uint32_t*)start; - for (i = 0; i < nxfrs; i++) - { - uint32_t value32 = (uint32_t)((uintptr_t)ptr); - *ptr++ = value32; - } - } - else if (width == MEMORY_ACCESS_HALFWORD) - { - uint16_t *ptr = (uint16_t*)start; - for (i = 0; i < nxfrs; i++) - { - uint16_t value16 = (uint16_t)((uintptr_t)ptr & 0x0000ffff); - *ptr++ = value16; - } - } - else if (width == MEMORY_ACCESS_BYTE) - { - uint8_t *ptr = (uint8_t*)start; - for (i = 0; i < nxfrs; i++) - { - uint8_t value8 = (uint8_t)((uintptr_t)ptr & 0x000000ff); - *ptr++ = value8; - } - } - else - { - TEST_FAIL_MESSAGE("Invalid width value"); - } -} - -/**************************************************************************** - * Name: unity_ramtest_verify_addrinaddr - * - * Description: - * Verifies every memory location is filled with the value from the previous location - * - * Input Parameters: - * width - access width - * start - memory region starting address - * size - number of bytes allocated for the region - * - * Returned Value: - * none, fails the testcase - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -void unity_ramtest_verify_addrinaddr(enum memory_access_width width, void *start, size_t size) -{ - size_t i, nxfrs = number_of_transfers(width, size); - - if (width == MEMORY_ACCESS_WORD) - { - uint32_t *ptr = (uint32_t*)start; - for (i = 0; i < nxfrs; i++) - { - uint32_t value32 = (uint32_t)((uintptr_t)ptr); - TEST_ASSERT_EQUAL_HEX32(*ptr, value32); - ptr++; - } - } - else if (width == MEMORY_ACCESS_HALFWORD) - { - uint16_t *ptr = (uint16_t*)start; - for (i = 0; i < nxfrs; i++) - { - uint16_t value16 = (uint16_t)((uintptr_t)ptr & 0x0000ffff); - TEST_ASSERT_EQUAL_HEX16(*ptr, value16); - ptr++; - } - } - else if (width == MEMORY_ACCESS_BYTE) - { - uint8_t *ptr = (uint8_t*)start; - for (i = 0; i < nxfrs; i++) - { - uint16_t value8 = (uint8_t)((uintptr_t)ptr & 0x000000ff); - TEST_ASSERT_EQUAL_HEX(*ptr, value8); - ptr++; - } - } - else - { - TEST_FAIL_MESSAGE("Invalid width value"); - } -} - -/**************************************************************************** - * Name: unity_ramtest_main - * - * Description: - * Application entry point - * - * Input Parameters: - * argc - number of arguments - * argv - arguments themselves - * - * Returned Value: - * exit status - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -int unity_ramtest_main(int argc, const char* argv[]) -{ - return UnityMain(argc, argv, runAllTests); -} diff --git a/tests/unity_usrsock/.gitignore b/tests/unity_usrsock/.gitignore deleted file mode 100644 index fa1ec7579..000000000 --- a/tests/unity_usrsock/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -/Make.dep -/.depend -/.built -/*.asm -/*.obj -/*.rel -/*.lst -/*.sym -/*.adb -/*.lib -/*.src diff --git a/tests/unity_usrsock/Kconfig b/tests/unity_usrsock/Kconfig deleted file mode 100644 index 870afe96a..000000000 --- a/tests/unity_usrsock/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -# -# For a description of the syntax of this configuration file, -# see misc/tools/kconfig-language.txt. -# - -config TESTS_UNITY_USRSOCK - bool "User-space networking stack API Unity tests" - default n - depends on NET - depends on NET_USRSOCK - depends on !DISABLE_POLL - select PIPES - ---help--- - Enable user-space networking stack API Unity tests - diff --git a/tests/unity_usrsock/Make.defs b/tests/unity_usrsock/Make.defs deleted file mode 100644 index 2f6460562..000000000 --- a/tests/unity_usrsock/Make.defs +++ /dev/null @@ -1,39 +0,0 @@ -############################################################################ -# apps/tests/unity_usrsock/Make.defs -# Adds selected testing applications to apps/ build -# -# Copyright (C) 2015 Haltian Ltd. All rights reserved. -# Author: Roman Saveljev -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# 3. Neither the name NuttX nor the names of its contributors may be -# used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -############################################################################ - -ifeq ($(CONFIG_TESTS_UNITY_USRSOCK),y) -CONFIGURED_APPS += tests/unity_usrsock -endif diff --git a/tests/unity_usrsock/Makefile b/tests/unity_usrsock/Makefile deleted file mode 100644 index b856fbfd2..000000000 --- a/tests/unity_usrsock/Makefile +++ /dev/null @@ -1,152 +0,0 @@ -############################################################################ -# apps/examples/unity_usrsock/Makefile -# -# Copyright (C) 2015 Haltian Ltd. All rights reserved. -# Author: Roman Saveljev -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# 3. Neither the name NuttX nor the names of its contributors may be -# used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -############################################################################ - --include $(TOPDIR)/.config --include $(TOPDIR)/Make.defs -include $(APPDIR)/Make.defs - -APPNAME = unity_usrsock -PRIORITY = SCHED_PRIORITY_DEFAULT -STACKSIZE = 2048 - -ARCH_SRCDIR = $(TOPDIR)/arch/$(CONFIG_ARCH)/src -CFLAGS += -x c - -ASRCS = -RUNNERSRC = unity_usrsock_runner.src -TESTSRCS = chardev.c nodaemon.c basic_daemon.c basic_connect.c \ - noblock_connect.c basic_send.c noblock_send.c block_send.c \ - noblock_recv.c block_recv.c poll.c remote_disconnect.c \ - basic_setsockopt.c basic_getsockopt.c basic_getsockname.c \ - multi_thread.c wake_with_signal.c - -CSRCS = $(TESTSRCS) usrsocktest_daemon.c -MAINSRC = unity_usrsock_main.c - -RUNNEROBJ = $(RUNNERSRC:.src=$(OBJEXT)) -AOBJS = $(ASRCS:.S=$(OBJEXT)) -COBJS = $(CSRCS:.c=$(OBJEXT)) -MAINOBJ = $(MAINSRC:.c=$(OBJEXT)) - -SRCS = $(ASRCS) $(CSRCS) $(MAINSRC) $(RUNNERSRC) -OBJS = $(AOBJS) $(COBJS) $(RUNNEROBJ) - -PROGNAME = unity_usrsock$(EXEEXT) - -ifneq ($(CONFIG_BUILD_KERNEL),y) - OBJS += $(MAINOBJ) -endif - -ifeq ($(CONFIG_WINDOWS_NATIVE),y) - BIN = ..\..\libapps$(LIBEXT) -else -ifeq ($(WINTOOL),y) - BIN = ..\\..\\libapps$(LIBEXT) -else - BIN = ../../libapps$(LIBEXT) -endif -endif - -ifeq ($(WINTOOL),y) - INSTALL_DIR = "${shell cygpath -w $(BIN_DIR)}" -else - INSTALL_DIR = $(BIN_DIR) -endif - -ROOTDEPPATH = --dep-path . - -# Common build - -VPATH = - -all: .built -.PHONY: clean depend distclean - -$(RUNNERSRC) : $(TESTSRCS) - $(Q) CPP="$(CPP)" $(APPDIR)/tests/tools/build_fixture_runner.pl $^ >$@ - -$(AOBJS): %$(OBJEXT): %.S - $(call ASSEMBLE, $<, $@) - -$(RUNNEROBJ): $(RUNNERSRC) - $(call COMPILE, $<, $@) - $(Q) OBJCOPY=$(OBJCOPY) $(APPDIR)/tests/tools/rename_symbols $(APPNAME) $@ - -$(COBJS) $(MAINOBJ): %$(OBJEXT): %.c - $(call COMPILE, $<, $@) - $(Q) OBJCOPY=$(OBJCOPY) $(APPDIR)/tests/tools/rename_symbols $(APPNAME) $@ - -.built: $(OBJS) - $(call ARCHIVE, $(BIN), $(OBJS)) - @touch .built - -ifeq ($(CONFIG_BUILD_KERNEL),y) -$(BIN_DIR)$(DELIM)$(PROGNAME): $(OBJS) $(MAINOBJ) - @echo "LD: $(PROGNAME)" - $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME) $(ARCHCRT0OBJ) $(MAINOBJ) $(LDLIBS) - $(Q) $(NM) -u $(INSTALL_DIR)$(DELIM)$(PROGNAME) - -install: $(BIN_DIR)$(DELIM)$(PROGNAME) - -else -install: - -endif - -ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) -$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile - $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) - -context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat -else -context: -endif - -.depend: Makefile $(SRCS) - @$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep - @touch $@ - -depend: .depend - -clean: - $(call DELFILE, .built) - $(call DELFILE, test_runner.src) - $(call CLEAN) - -distclean: clean - $(call DELFILE, Make.dep) - $(call DELFILE, .depend) - --include Make.dep diff --git a/tests/unity_usrsock/basic_connect.c b/tests/unity_usrsock/basic_connect.c deleted file mode 100644 index 5269b3337..000000000 --- a/tests/unity_usrsock/basic_connect.c +++ /dev/null @@ -1,465 +0,0 @@ -/**************************************************************************** - * apps/examples/unity_usrsock/basic_connect.c - * Basic connect tests with socket daemon - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Authors: Roman Saveljev - * Jussi Kivilinna - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "defines.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ -static bool started; -static int sd; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: Setup - * - * Description: - * Run before every testcase - * - * Input Parameters: - * dconf - test daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void Setup(struct usrsocktest_daemon_conf_s *dconf) -{ - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); -} - -/**************************************************************************** - * Name: Teardown - * - * Description: - * Run after every testcase - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void Teardown(void) -{ - int ret; - - if (sd >= 0) - { - ret = close(sd); - assert(ret >= 0); - } - - if (started) - { - ret = usrsocktest_daemon_stop(); - assert(ret == OK); - } -} - -/**************************************************************************** - * Name: NotConnected - * - * Description: - * Opened socket is not connected - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void NotConnected(void) -{ - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); -} - -/**************************************************************************** - * Name: Connect - * - * Description: - * Open and connect the socket - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void Connect(void) -{ - int ret; - struct sockaddr_in addr; - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - - /* Attempt reconnect to same address */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EISCONN, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - - /* Attempt reconnect to different address */ - - inet_pton(AF_INET, "1.1.1.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(1); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EISCONN, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Name: WrongAF - * - * Description: - * Open and connect the socket with wrong AF - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void WrongAF(void) -{ - int ret; - struct sockaddr_in addr; - - /* Try connect socket with wrong AF */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_UNIX; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EAFNOSUPPORT, errno); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Name: WrongPort - * - * Description: - * Open and connect the socket with wrong port - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void WrongPort(void) -{ - int ret; - struct sockaddr_in addr; - - /* Try connect socket to wrong port */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(127); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(ECONNREFUSED, errno); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Name: WrongEndpoint - * - * Description: - * Open and connect the socket with wrong endpoint - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void WrongEndpoint(void) -{ - int ret; - struct sockaddr_in addr; - - /* Try connect socket to unreachable endpoint */ - - inet_pton(AF_INET, "1.1.1.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(1); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(ENETUNREACH, errno); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - - /* Connect */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -TEST_GROUP(BasicConnect); - -TEST_SETUP(BasicConnect) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - Setup(&usrsocktest_daemon_config); -} - -TEST_TEAR_DOWN(BasicConnect) -{ - Teardown(); -} - -TEST(BasicConnect, NotConnected) -{ - NotConnected(); -} - -TEST(BasicConnect, Connect) -{ - Connect(); -} - -TEST(BasicConnect, WrongAF) -{ - WrongAF(); -} - -TEST(BasicConnect, WrongPort) -{ - WrongPort(); -} - -TEST(BasicConnect, WrongEndpoint) -{ - WrongEndpoint(); -} - -TEST_GROUP(BasicConnectDelay); - -TEST_SETUP(BasicConnectDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - Setup(&usrsocktest_daemon_config); -} - -TEST_TEAR_DOWN(BasicConnectDelay) -{ - Teardown(); -} - -TEST(BasicConnectDelay, NotConnected) -{ - NotConnected(); -} - -TEST(BasicConnectDelay, Connect) -{ - Connect(); -} - -TEST(BasicConnectDelay, WrongAF) -{ - WrongAF(); -} - -TEST(BasicConnectDelay, WrongPort) -{ - WrongPort(); -} - -TEST(BasicConnectDelay, WrongEndpoint) -{ - WrongEndpoint(); -} diff --git a/tests/unity_usrsock/basic_daemon.c b/tests/unity_usrsock/basic_daemon.c deleted file mode 100644 index 929f88aec..000000000 --- a/tests/unity_usrsock/basic_daemon.c +++ /dev/null @@ -1,653 +0,0 @@ -/**************************************************************************** - * apps/examples/unity_usrsock/basic_daemon.c - * Basic tests with socket daemon - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Authors: Roman Saveljev - * Jussi Kivilinna - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "defines.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ -static bool started; -static int sd, sd2, sd3; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: NoActiveSockets - * - * Description: - * Checks there is no active sockets on daemon startup - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void NoActiveSockets(struct usrsocktest_daemon_conf_s *dconf) -{ - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); -} - -/**************************************************************************** - * Name: OpenClose - * - * Description: - * Open and close AF_INET socket, check active socket counter updates - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void OpenClose(struct usrsocktest_daemon_conf_s *dconf) -{ - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Name: UnsupportedType - * - * Description: - * Try open socket for unsupported type - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void UnsupportedType(struct usrsocktest_daemon_conf_s *dconf) -{ - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - - sd = socket(AF_INET, SOCK_RDM, 0); - TEST_ASSERT_TRUE(sd < 0); - TEST_ASSERT_EQUAL(EPROTONOSUPPORT, errno); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Name: UnsupportedProto - * - * Description: - * Try open socket for unsupported protocol - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void UnsupportedProto(struct usrsocktest_daemon_conf_s *dconf) -{ - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - - sd = socket(AF_INET, SOCK_STREAM, 1); - TEST_ASSERT_TRUE(sd < 0); - TEST_ASSERT_EQUAL(EPROTONOSUPPORT, errno); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Name: OpenThree - * - * Description: - * Open multiple sockets - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void OpenThree(struct usrsocktest_daemon_conf_s *dconf) -{ - int ret; - - dconf->max_sockets = 3; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - sd2 = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd2 >= 0); - TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); - sd3 = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd3 >= 0); - TEST_ASSERT_EQUAL(3, usrsocktest_daemon_get_num_active_sockets()); - ret = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_FALSE(ret >= 0); - TEST_ASSERT_EQUAL(3, usrsocktest_daemon_get_num_active_sockets()); - - ret = close(sd2); - TEST_ASSERT_EQUAL(0, ret); - sd2 = -1; - TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); - ret = close(sd); - TEST_ASSERT_EQUAL(0, ret); - sd = -1; - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - ret = close(sd3); - TEST_ASSERT_EQUAL(0, ret); - sd3 = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Name: Dup - * - * Description: - * Dup opened socket - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void Dup(struct usrsocktest_daemon_conf_s *dconf) -{ - int ret; - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - - sd2 = dup(sd); - TEST_ASSERT_TRUE(sd2 >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - - sd3 = dup(sd); - TEST_ASSERT_TRUE(sd3 >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - - ret = close(sd2); - TEST_ASSERT_EQUAL(0, ret); - sd2 = -1; - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - ret = close(sd); - TEST_ASSERT_EQUAL(0, ret); - sd = -1; - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - ret = close(sd3); - TEST_ASSERT_EQUAL(0, ret); - sd3 = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Name: Dup2 - * - * Description: - * Clone opened socket with dup2 - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void Dup2(struct usrsocktest_daemon_conf_s *dconf) -{ - int ret; - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - sd2 = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); - - ret = dup2(sd2, sd); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - - ret = close(sd2); - TEST_ASSERT_EQUAL(0, ret); - sd2 = -1; - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - ret = close(sd); - TEST_ASSERT_EQUAL(0, ret); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Name: Stops - * - * Description: - * Daemon stops unexpectedly - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void Stops(struct usrsocktest_daemon_conf_s *dconf) -{ - int ret; - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - sd2 = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd2 >= 0); - TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); - - ret = usrsocktest_daemon_stop(); - TEST_ASSERT_EQUAL(OK, ret); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); - - - TEST_ASSERT_EQUAL(0, close(sd)); - sd = -1; - TEST_ASSERT_EQUAL(0, close(sd2)); - sd2 = -1; -} - -/**************************************************************************** - * Name: StopsStarts - * - * Description: - * Daemon stops and restarts unexpectedly - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void StopsStarts(struct usrsocktest_daemon_conf_s *dconf) -{ - int ret; - struct sockaddr_in addr; - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - sd2 = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd2 >= 0); - TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = 255; - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EPIPE, errno); - - ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EPIPE, errno); - - TEST_ASSERT_EQUAL(0, close(sd)); - sd = -1; - TEST_ASSERT_EQUAL(0, close(sd2)); - sd2 = -1; - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -TEST_GROUP(BasicDaemon); - -/**************************************************************************** - * Name: BasicDaemon test group setup - * - * Description: - * Setup function executed before each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_SETUP(BasicDaemon) -{ - sd = -1; - sd2 = -1; - sd3 = -1; - started = false; -} - -/**************************************************************************** - * Name: BasicDaemon test group teardown - * - * Description: - * Setup function executed after each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_TEAR_DOWN(BasicDaemon) -{ - int ret; - if (sd >= 0) - { - ret = close(sd); - assert(ret >= 0); - } - if (sd2 >= 0) - { - ret = close(sd2); - assert(ret >= 0); - } - if (sd3 >= 0) - { - ret = close(sd3); - assert(ret >= 0); - } - if (started) - { - ret = usrsocktest_daemon_stop(); - assert(ret == OK); - } -} - -TEST(BasicDaemon, NoActiveSockets) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - NoActiveSockets(&usrsocktest_daemon_config); -} - -TEST(BasicDaemon, NoActiveSocketsDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - NoActiveSockets(&usrsocktest_daemon_config); -} - -TEST(BasicDaemon, OpenClose) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - OpenClose(&usrsocktest_daemon_config); -} - -TEST(BasicDaemon, OpenCloseDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - OpenClose(&usrsocktest_daemon_config); -} - -TEST(BasicDaemon, UnsupportedType) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - UnsupportedType(&usrsocktest_daemon_config); -} - -TEST(BasicDaemon, UnsupportedTypeDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - UnsupportedType(&usrsocktest_daemon_config); -} - -TEST(BasicDaemon, UnsupportedProto) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - UnsupportedProto(&usrsocktest_daemon_config); -} - -TEST(BasicDaemon, UnsupportedProtoDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - UnsupportedProto(&usrsocktest_daemon_config); -} - -TEST(BasicDaemon, OpenThree) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - OpenThree(&usrsocktest_daemon_config); -} - -TEST(BasicDaemon, OpenThreeDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - OpenThree(&usrsocktest_daemon_config); -} - -TEST(BasicDaemon, Dup) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - Dup(&usrsocktest_daemon_config); -} - -TEST(BasicDaemon, DupDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - Dup(&usrsocktest_daemon_config); -} - -TEST(BasicDaemon, Dup2) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - Dup2(&usrsocktest_daemon_config); -} - -TEST(BasicDaemon, Dup2Delay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - Dup2(&usrsocktest_daemon_config); -} - -TEST(BasicDaemon, Stops) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - Stops(&usrsocktest_daemon_config); -} - -TEST(BasicDaemon, StopsDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - Stops(&usrsocktest_daemon_config); -} - -TEST(BasicDaemon, StopsStarts) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - StopsStarts(&usrsocktest_daemon_config); -} - -TEST(BasicDaemon, StopsStartsDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - StopsStarts(&usrsocktest_daemon_config); -} diff --git a/tests/unity_usrsock/basic_getsockname.c b/tests/unity_usrsock/basic_getsockname.c deleted file mode 100644 index 72f7e07ca..000000000 --- a/tests/unity_usrsock/basic_getsockname.c +++ /dev/null @@ -1,279 +0,0 @@ -/**************************************************************************** - * apps/examples/unity_usrsock/basic_getsockname.c - * Basic getsockname tests - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Authors: Roman Saveljev - * Jussi Kivilinna - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "defines.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ -static bool started; -static int sd; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: Open - * - * Description: - * Open and get socket options - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void Open(struct usrsocktest_daemon_conf_s *dconf) -{ - int ret; - socklen_t addrlen; - union { - struct sockaddr_storage storage; - struct sockaddr_in in; - } addr; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Get socket name */ - - memset(&addr, 0xff, sizeof(addr)); - addrlen = sizeof(addr.in); - ret = getsockname(sd, (FAR void *)&addr.in, &addrlen); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(sizeof(addr.in), addrlen); - TEST_ASSERT_EQUAL(AF_INET, addr.in.sin_family); - TEST_ASSERT_EQUAL(htons(12345), addr.in.sin_port); - TEST_ASSERT_EQUAL(htonl(0x7f000001), addr.in.sin_addr.s_addr); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Get socket name, short buffer */ - - memset(&addr, 0xff, sizeof(addr)); - addrlen = 1; - ret = getsockname(sd, (FAR void *)&addr.in, &addrlen); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(sizeof(addr.in), addrlen); - TEST_ASSERT_EQUAL(AF_INET, ((FAR uint8_t *)&addr.in.sin_family)[0]); - TEST_ASSERT_EQUAL(0xff, ((FAR uint8_t *)&addr.in.sin_family)[1]); - TEST_ASSERT_EQUAL(htons(0xffff), addr.in.sin_port); - TEST_ASSERT_EQUAL(htonl(0xffffffff), addr.in.sin_addr.s_addr); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Get socket name, larger buffer */ - - memset(&addr, 0xff, sizeof(addr)); - addrlen = sizeof(addr.storage); - ret = getsockname(sd, (FAR void *)&addr.in, &addrlen); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(sizeof(addr.in), addrlen); - TEST_ASSERT_EQUAL(AF_INET, addr.in.sin_family); - TEST_ASSERT_EQUAL(htons(12345), addr.in.sin_port); - TEST_ASSERT_EQUAL(htonl(0x7f000001), addr.in.sin_addr.s_addr); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Get socket name, NULL addr */ - - memset(&addr, 0xff, sizeof(addr)); - addrlen = sizeof(addr.in); - ret = getsockname(sd, NULL, &addrlen); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINVAL, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Get socket name, NULL addrlen */ - - memset(&addr, 0xff, sizeof(addr)); - addrlen = sizeof(addr.in); - ret = getsockname(sd, (FAR void *)&addr.in, NULL); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINVAL, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Get socket name, zero length buffer */ - - memset(&addr, 0xff, sizeof(addr)); - addrlen = 0; - ret = getsockname(sd, (FAR void *)&addr.in, &addrlen); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(sizeof(addr.in), addrlen); - TEST_ASSERT_EQUAL(0xffff, addr.in.sin_family); - TEST_ASSERT_EQUAL(htons(0xffff), addr.in.sin_port); - TEST_ASSERT_EQUAL(htonl(0xffffffff), addr.in.sin_addr.s_addr); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -TEST_GROUP(BasicGetSockName); - -/**************************************************************************** - * Name: BasicGetSockName test group setup - * - * Description: - * Setup function executed before each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_SETUP(BasicGetSockName) -{ - sd = -1; - started = false; -} - -/**************************************************************************** - * Name: BasicGetSockName test group teardown - * - * Description: - * Setup function executed after each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_TEAR_DOWN(BasicGetSockName) -{ - int ret; - if (sd >= 0) - { - ret = close(sd); - assert(ret >= 0); - } - if (started) - { - ret = usrsocktest_daemon_stop(); - assert(ret == OK); - } -} - -TEST(BasicGetSockName, Open) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - Open(&usrsocktest_daemon_config); -} - -TEST(BasicGetSockName, OpenDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - Open(&usrsocktest_daemon_config); -} diff --git a/tests/unity_usrsock/basic_getsockopt.c b/tests/unity_usrsock/basic_getsockopt.c deleted file mode 100644 index 719380afa..000000000 --- a/tests/unity_usrsock/basic_getsockopt.c +++ /dev/null @@ -1,258 +0,0 @@ -/**************************************************************************** - * apps/examples/unity_usrsock/basic_getsockopt.c - * Basic getsockopt tests - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Authors: Roman Saveljev - * Jussi Kivilinna - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include -#include -#include -#include -#include - -#include "defines.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ -static bool started; -static int sd; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: Open - * - * Description: - * Open and get socket options - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void Open(struct usrsocktest_daemon_conf_s *dconf) -{ - int ret; - int value; - int valuelarge[2]; - socklen_t valuelen; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Get supported option (SO_TYPE handled by nuttx) */ - - value = -2; - valuelen = sizeof(value); - ret = getsockopt(sd, SOL_SOCKET, SO_TYPE, &value, &valuelen); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(sizeof(value), valuelen); - TEST_ASSERT_EQUAL(SOCK_STREAM, value); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Get supported option */ - - value = -1; - valuelen = sizeof(value); - ret = getsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &value, &valuelen); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(sizeof(value), valuelen); - TEST_ASSERT_EQUAL(0, value); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Get supported option, too short buffer */ - - value = -1; - valuelen = 1; - ret = getsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &value, &valuelen); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINVAL, errno); - TEST_ASSERT_EQUAL(-1, value); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Get supported option, larger buffer */ - - valuelarge[0] = -1; - valuelarge[1] = -1; - valuelen = sizeof(valuelarge); - ret = getsockopt(sd, SOL_SOCKET, SO_REUSEADDR, valuelarge, &valuelen); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(sizeof(value), valuelen); - TEST_ASSERT_EQUAL(0, valuelarge[0]); - TEST_ASSERT_EQUAL(-1, valuelarge[1]); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Get unsupported option */ - - value = -1; - valuelen = sizeof(value); - ret = getsockopt(sd, SOL_SOCKET, SO_BROADCAST, &value, &valuelen); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(ENOPROTOOPT, errno); - TEST_ASSERT_EQUAL(-1, value); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -TEST_GROUP(BasicGetSockOpt); - -/**************************************************************************** - * Name: BasicGetSockOpt test group setup - * - * Description: - * Setup function executed before each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_SETUP(BasicGetSockOpt) -{ - sd = -1; - started = false; -} - -/**************************************************************************** - * Name: BasicGetSockOpt test group teardown - * - * Description: - * Setup function executed after each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_TEAR_DOWN(BasicGetSockOpt) -{ - int ret; - if (sd >= 0) - { - ret = close(sd); - assert(ret >= 0); - } - if (started) - { - ret = usrsocktest_daemon_stop(); - assert(ret == OK); - } -} - -TEST(BasicGetSockOpt, Open) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - Open(&usrsocktest_daemon_config); -} - -TEST(BasicGetSockOpt, OpenDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - Open(&usrsocktest_daemon_config); -} diff --git a/tests/unity_usrsock/basic_send.c b/tests/unity_usrsock/basic_send.c deleted file mode 100644 index 4ed8e498f..000000000 --- a/tests/unity_usrsock/basic_send.c +++ /dev/null @@ -1,345 +0,0 @@ -/**************************************************************************** - * apps/examples/unity_usrsock/basic_send.c - * Basic sending tests - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Authors: Roman Saveljev - * Jussi Kivilinna - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "defines.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ -static bool started; -static int sd; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: Send - * - * Description: - * Open socket and send - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void Send(struct usrsocktest_daemon_conf_s *dconf) -{ - struct sockaddr_in addr; - ssize_t ret; - size_t datalen; - const void *data; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Send on non-connected socket */ - - data = "data"; - datalen = strlen("data"); - ret = send(sd, data, datalen, 0); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(ENOTCONN, errno); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Sendto with address */ - - data = "data"; - datalen = strlen("data"); - ret = sendto(sd, data, datalen, 0, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(ENOTCONN, errno); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Connect socket to available endpoint */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - - /* Sendto with address */ - - data = "data"; - datalen = strlen("data"); - ret = sendto(sd, data, datalen, 0, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EISCONN, errno); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_send_bytes()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); - -} - -/**************************************************************************** - * Name: ConnectSend - * - * Description: - * Send over connected socket - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void ConnectSend(struct usrsocktest_daemon_conf_s *dconf) -{ - struct sockaddr_in addr; - ssize_t ret; - size_t datalen; - const void *data; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Connect socket to available endpoint */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - - /* Send data to remote */ - - data = "data"; - datalen = strlen("data"); - ret = send(sd, data, datalen, 0); - TEST_ASSERT_EQUAL(datalen, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -TEST_GROUP(BasicSend); - -/**************************************************************************** - * Name: BasicSend test group setup - * - * Description: - * Setup function executed before each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_SETUP(BasicSend) -{ - sd = -1; - started = false; -} - -/**************************************************************************** - * Name: BasicSend test group teardown - * - * Description: - * Setup function executed after each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_TEAR_DOWN(BasicSend) -{ - int ret; - if (sd >= 0) - { - ret = close(sd); - assert(ret >= 0); - } - if (started) - { - ret = usrsocktest_daemon_stop(); - assert(ret == OK); - } -} - -TEST(BasicSend, Send) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - Send(&usrsocktest_daemon_config); -} - -TEST(BasicSend, SendDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - Send(&usrsocktest_daemon_config); -} - -TEST(BasicSend, ConnectSend) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - ConnectSend(&usrsocktest_daemon_config); -} - -TEST(BasicSend, ConnectSendDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - ConnectSend(&usrsocktest_daemon_config); -} diff --git a/tests/unity_usrsock/basic_setsockopt.c b/tests/unity_usrsock/basic_setsockopt.c deleted file mode 100644 index 48c0918ac..000000000 --- a/tests/unity_usrsock/basic_setsockopt.c +++ /dev/null @@ -1,226 +0,0 @@ -/**************************************************************************** - * apps/examples/unity_usrsock/basic_setsockopt.c - * Basic setsockopt tests - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Authors: Roman Saveljev - * Jussi Kivilinna - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "defines.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ -static bool started; -static int sd; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: Open - * - * Description: - * Open and set socket options - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void Open(struct usrsocktest_daemon_conf_s *dconf) -{ - int ret; - int value; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Set supported option */ - - value = 1; - ret = setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value)); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Set supported option, too small buffer */ - - value = 1; - ret = setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &value, 1); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINVAL, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Set unsupported option */ - - value = 1; - ret = setsockopt(sd, SOL_SOCKET, SO_BROADCAST, &value, sizeof(value)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(ENOPROTOOPT, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -TEST_GROUP(BasicSetSockOpt); - -/**************************************************************************** - * Name: BasicSetSockOpt test group setup - * - * Description: - * Setup function executed before each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_SETUP(BasicSetSockOpt) -{ - sd = -1; - started = false; -} - -/**************************************************************************** - * Name: BasicSetSockOpt test group teardown - * - * Description: - * Setup function executed after each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_TEAR_DOWN(BasicSetSockOpt) -{ - int ret; - if (sd >= 0) - { - ret = close(sd); - assert(ret >= 0); - } - if (started) - { - ret = usrsocktest_daemon_stop(); - assert(ret == OK); - } -} - -TEST(BasicSetSockOpt, Open) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - Open(&usrsocktest_daemon_config); -} - -TEST(BasicSetSockOpt, OpenDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - Open(&usrsocktest_daemon_config); -} diff --git a/tests/unity_usrsock/block_recv.c b/tests/unity_usrsock/block_recv.c deleted file mode 100644 index 8b5329af5..000000000 --- a/tests/unity_usrsock/block_recv.c +++ /dev/null @@ -1,497 +0,0 @@ -/**************************************************************************** - * apps/examples/unity_usrsock/block_recv.c - * Receive from the socket in blocking mode - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Authors: Roman Saveljev - * Jussi Kivilinna - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "defines.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ -static bool started; -static int sd; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: ConnectReceive - * - * Description: - * Blocking connect and receive - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void ConnectReceive(struct usrsocktest_daemon_conf_s *dconf) -{ - ssize_t ret; - size_t datalen; - void *data; - struct sockaddr_in addr; - char databuf[5]; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - dconf->endpoint_block_connect = true; - dconf->endpoint_block_send = true; - dconf->endpoint_recv_avail_from_start = false; - dconf->endpoint_recv_avail = 7; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Do connect, should succeed (after connect block released). */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100)); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Receive data from remote */ - - data = databuf; - datalen = sizeof(databuf); - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 100)); - ret = recvfrom(sd, data, datalen, 0, NULL, 0); - TEST_ASSERT_EQUAL(datalen, ret); - TEST_ASSERT_EQUAL(5, ret); - TEST_ASSERT_EQUAL_UINT8_ARRAY("abcde", data, 5); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(5, usrsocktest_daemon_get_recv_bytes()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Receive data from remote */ - - data = databuf; - datalen = sizeof(databuf); - ret = recvfrom(sd, data, datalen, 0, NULL, 0); - TEST_ASSERT_EQUAL(2, ret); - TEST_ASSERT_EQUAL_UINT8_ARRAY("ab", data, 2); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(7, usrsocktest_daemon_get_recv_bytes()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Name: NoBlockConnect - * - * Description: - * Non-blocking connect and blocking receive - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void NoBlockConnect(struct usrsocktest_daemon_conf_s *dconf) -{ - ssize_t ret; - size_t datalen; - void *data; - struct sockaddr_in addr; - char databuf[5]; - struct sockaddr_in remoteaddr; - socklen_t addrlen; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - dconf->endpoint_block_connect = true; - dconf->endpoint_block_send = true; - dconf->endpoint_recv_avail_from_start = true; - dconf->endpoint_recv_avail = 6; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Do connect, should succeed (after connect block released). */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('W', 100)); - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100)); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Receive data from remote */ - - data = databuf; - datalen = sizeof(databuf); - ret = read(sd, data, datalen); - TEST_ASSERT_EQUAL(datalen, ret); - TEST_ASSERT_EQUAL(5, ret); - TEST_ASSERT_EQUAL_UINT8_ARRAY("abcde", data, 5); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(5, usrsocktest_daemon_get_recv_bytes()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Receive data from remote */ - - data = databuf; - datalen = sizeof(databuf); - addrlen = sizeof(remoteaddr); - ret = recvfrom(sd, data, datalen, 0, (FAR struct sockaddr *)&remoteaddr, &addrlen); - TEST_ASSERT_EQUAL(1, ret); - TEST_ASSERT_EQUAL_UINT8_ARRAY("a", data, 1); - TEST_ASSERT_EQUAL(sizeof(remoteaddr), addrlen); - TEST_ASSERT_EQUAL_UINT8_ARRAY(&remoteaddr, &addr, addrlen); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(6, usrsocktest_daemon_get_recv_bytes()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Receive data from remote */ - - data = databuf; - datalen = sizeof(databuf); - addrlen = sizeof(remoteaddr); - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 100)); - ret = recvfrom(sd, data, datalen, 0, (FAR struct sockaddr *)&remoteaddr, &addrlen); - TEST_ASSERT_EQUAL(5, ret); - TEST_ASSERT_EQUAL_UINT8_ARRAY("abcde", data, 5); - TEST_ASSERT_EQUAL(sizeof(remoteaddr), addrlen); - TEST_ASSERT_EQUAL_UINT8_ARRAY(&remoteaddr, &addr, addrlen); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(11, usrsocktest_daemon_get_recv_bytes()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(11, usrsocktest_daemon_get_recv_bytes()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Name: ReceiveTimeout - * - * Description: - * Blocking connect and receive with SO_RCVTIMEO - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void ReceiveTimeout(struct usrsocktest_daemon_conf_s *dconf) -{ - ssize_t ret; - size_t datalen; - void *data; - struct sockaddr_in addr; - char databuf[5]; - struct timeval tv; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - dconf->endpoint_block_connect = true; - dconf->endpoint_block_send = true; - dconf->endpoint_recv_avail_from_start = false; - dconf->endpoint_recv_avail = 7; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Do connect, should succeed (after connect block released). */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100)); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Setup recv timeout. */ - - tv.tv_sec = 0; - tv.tv_usec = 100 * 1000; - ret = setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (FAR const void *)&tv, - sizeof(tv)); - TEST_ASSERT_EQUAL(0, ret); - - /* Receive data from remote */ - - data = databuf; - datalen = sizeof(databuf); - ret = recvfrom(sd, data, datalen, 0, NULL, 0); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EAGAIN, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_recv_bytes()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -TEST_GROUP(BlockRecv); - -/**************************************************************************** - * Name: BlockRecv test group setup - * - * Description: - * Setup function executed before each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_SETUP(BlockRecv) -{ - sd = -1; - started = false; -} - -/**************************************************************************** - * Name: BlockRecv test group teardown - * - * Description: - * Setup function executed after each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_TEAR_DOWN(BlockRecv) -{ - int ret; - if (sd >= 0) - { - ret = close(sd); - assert(ret >= 0); - } - if (started) - { - ret = usrsocktest_daemon_stop(); - assert(ret == OK); - } -} - -TEST(BlockRecv, ConnectReceive) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - ConnectReceive(&usrsocktest_daemon_config); -} - -TEST(BlockRecv, ConnectReceiveDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - ConnectReceive(&usrsocktest_daemon_config); -} - -TEST(BlockRecv, NoBlockConnect) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - NoBlockConnect(&usrsocktest_daemon_config); -} - -TEST(BlockRecv, NoBlockConnectDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - NoBlockConnect(&usrsocktest_daemon_config); -} - -TEST(BlockRecv, ReceiveTimeout) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - ReceiveTimeout(&usrsocktest_daemon_config); -} - -TEST(BlockRecv, ReceiveTimeoutDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - ReceiveTimeout(&usrsocktest_daemon_config); -} diff --git a/tests/unity_usrsock/block_send.c b/tests/unity_usrsock/block_send.c deleted file mode 100644 index 0aa15fb74..000000000 --- a/tests/unity_usrsock/block_send.c +++ /dev/null @@ -1,428 +0,0 @@ -/**************************************************************************** - * apps/examples/unity_usrsock/block_send.c - * Send through the socket in blocking mode - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Authors: Roman Saveljev - * Jussi Kivilinna - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "defines.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ -static bool started; -static int sd; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: ConnectSend - * - * Description: - * Open socket, connect in blocking mode and send - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void ConnectSend(struct usrsocktest_daemon_conf_s *dconf) -{ - ssize_t ret; - size_t datalen; - const void *data; - struct sockaddr_in addr; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - dconf->endpoint_block_connect = true; - dconf->endpoint_block_send = true; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Do connect, should succeed (after connect block released). */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100)); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Send data to remote, */ - - data = "abcde"; - datalen = strlen("abcde"); - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('W', 100)); - ret = sendto(sd, data, datalen, 0, NULL, 0); - TEST_ASSERT_EQUAL(datalen, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); - -} - -/**************************************************************************** - * Name: NonBlockConnectSend - * - * Description: - * Open socket, connect in non-blocking mode and send - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void NonBlockConnectSend(struct usrsocktest_daemon_conf_s *dconf) -{ - ssize_t ret; - size_t datalen; - const void *data; - struct sockaddr_in addr; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - dconf->endpoint_block_connect = true; - dconf->endpoint_block_send = false; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Do connect, should succeed (after connect block released). */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('W', 100)); - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100)); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Send data to remote. */ - - data = "abcde"; - datalen = strlen("abcde"); - ret = write(sd, data, datalen); - TEST_ASSERT_EQUAL(datalen, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Name: SendTimeout - * - * Description: - * Open socket, connect in blocking mode and send with SO_SNDTIMEO - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void SendTimeout(struct usrsocktest_daemon_conf_s *dconf) -{ - ssize_t ret; - size_t datalen; - const void *data; - struct sockaddr_in addr; - struct timeval tv; - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - dconf->endpoint_block_connect = true; - dconf->endpoint_block_send = true; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Do connect, should succeed (after connect block released). */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100)); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Setup send timeout. */ - - tv.tv_sec = 0; - tv.tv_usec = 100 * 1000; - ret = setsockopt(sd, SOL_SOCKET, SO_SNDTIMEO, (FAR const void *)&tv, - sizeof(tv)); - TEST_ASSERT_EQUAL(0, ret); - - /* Try send data to remote. */ - - data = "abcde"; - datalen = strlen("abcde"); - ret = sendto(sd, data, datalen, 0, NULL, 0); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EAGAIN, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -TEST_GROUP(BlockSend); - -/**************************************************************************** - * Name: BlockSend test group setup - * - * Description: - * Setup function executed before each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_SETUP(BlockSend) -{ - sd = -1; - started = false; -} - -/**************************************************************************** - * Name: BlockSend test group teardown - * - * Description: - * Setup function executed after each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_TEAR_DOWN(BlockSend) -{ - int ret; - if (sd >= 0) - { - ret = close(sd); - assert(ret >= 0); - } - if (started) - { - ret = usrsocktest_daemon_stop(); - assert(ret == OK); - } -} - -TEST(BlockSend, ConnectSend) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - ConnectSend(&usrsocktest_daemon_config); -} - -TEST(BlockSend, ConnectSendDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - ConnectSend(&usrsocktest_daemon_config); -} - -TEST(BlockSend, NonBlockConnectSend) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - NonBlockConnectSend(&usrsocktest_daemon_config); -} - -TEST(BlockSend, NonBlockConnectSendDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - NonBlockConnectSend(&usrsocktest_daemon_config); -} - -TEST(BlockSend, SendTimeout) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - SendTimeout(&usrsocktest_daemon_config); -} - -TEST(BlockSend, SendTimeoutDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - SendTimeout(&usrsocktest_daemon_config); -} diff --git a/tests/unity_usrsock/chardev.c b/tests/unity_usrsock/chardev.c deleted file mode 100644 index bf9366032..000000000 --- a/tests/unity_usrsock/chardev.c +++ /dev/null @@ -1,222 +0,0 @@ -/**************************************************************************** - * apps/examples/unity_usrsock/chardev.c - * Character device node tests - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Authors: Roman Saveljev - * Jussi Kivilinna - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include -#include - -#include "defines.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ -static int us_fd; -static int us_fd_two; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -TEST_GROUP(CharDev); - -/**************************************************************************** - * Name: CharDev test group setup - * - * Description: - * Setup function executed before each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_SETUP(CharDev) -{ - us_fd = -1; - us_fd_two = -1; -} - -/**************************************************************************** - * Name: CharDev test group teardown - * - * Description: - * Setup function executed after each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_TEAR_DOWN(CharDev) -{ - int ret; - - if (us_fd >= 0) - { - ret = close(us_fd); - assert(ret >= 0); - } - if (us_fd_two >= 0) - { - ret = close(us_fd_two); - assert(ret >= 0); - } -} - -/**************************************************************************** - * Name: OpenRw - * - * Description: - * Simple test for opening and closing usrsock node - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(CharDev, OpenRw) -{ - int ret; - - us_fd = open(USRSOCK_NODE, O_RDWR); - TEST_ASSERT_TRUE(us_fd >= 0); - - ret = close(us_fd); - TEST_ASSERT_TRUE(ret >= 0); - us_fd = -1; -} - -/**************************************************************************** - * Name: ReopenRw - * - * Description: - * Repeated simple test for opening and closing usrsock node, reopen should - * work - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(CharDev, ReopenRw) -{ - int ret; - - us_fd = open(USRSOCK_NODE, O_RDWR); - TEST_ASSERT_TRUE(us_fd >= 0); - - ret = close(us_fd); - TEST_ASSERT_TRUE(ret >= 0); - us_fd = -1; - - us_fd = open(USRSOCK_NODE, O_RDWR); - TEST_ASSERT_TRUE(us_fd >= 0); - - ret = close(us_fd); - TEST_ASSERT_TRUE(ret >= 0); - us_fd = -1; -} - -/**************************************************************************** - * Name: NoMultipleOpen - * - * Description: - * No permission for multiple access, - * first user should be only user. - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(CharDev, NoMultipleOpen) -{ - us_fd = open(USRSOCK_NODE, O_RDWR); - TEST_ASSERT_TRUE(us_fd >= 0); - - us_fd_two = open(USRSOCK_NODE, O_RDWR); - TEST_ASSERT_FALSE(us_fd_two >= 0); - TEST_ASSERT_EQUAL(EPERM, errno); -} diff --git a/tests/unity_usrsock/defines.h b/tests/unity_usrsock/defines.h deleted file mode 100644 index 153efc4f9..000000000 --- a/tests/unity_usrsock/defines.h +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** - * apps/examples/unity_usrsock/defines.h - * Common defines for all testcases - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Author: Roman Saveljev - * Jussi Kivilinna - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ -#ifndef __EXAMPLES_UNITY_USRSOCK_DEFINES_H -#define __EXAMPLES_UNITY_USRSOCK_DEFINES_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ -#define USRSOCK_NODE "/dev/usrsock" - -#define USRSOCKTEST_DAEMON_CONF_DEFAULTS \ - { \ - .max_sockets = UINT_MAX, \ - .supported_domain = AF_INET, \ - .supported_type = SOCK_STREAM, \ - .supported_protocol = 0, \ - .delay_all_responses = false, \ - .endpoint_addr = "127.0.0.1", \ - .endpoint_port = 255, \ - .endpoint_block_connect = false, \ - .endpoint_block_send = false, \ - .endpoint_recv_avail_from_start = true, \ - .endpoint_recv_avail = 4, \ - } - -/**************************************************************************** - * Public Types - ****************************************************************************/ -struct usrsocktest_daemon_conf_s -{ - unsigned int max_sockets; - int8_t supported_domain:8; - int8_t supported_type:8; - int8_t supported_protocol:8; - bool delay_all_responses:1; - bool endpoint_block_connect:1; - bool endpoint_block_send:1; - bool endpoint_recv_avail_from_start:1; - uint8_t endpoint_recv_avail:8; - const char *endpoint_addr; - uint16_t endpoint_port; -}; - -/**************************************************************************** - * Public Data - ****************************************************************************/ -extern int usrsocktest_endp_malloc_cnt; -extern int usrsocktest_dcmd_malloc_cnt; -extern const struct usrsocktest_daemon_conf_s usrsocktest_daemon_defconf; -extern struct usrsocktest_daemon_conf_s usrsocktest_daemon_config; - -/**************************************************************************** - * Inline Functions - ****************************************************************************/ - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ -int usrsocktest_daemon_start(const struct usrsocktest_daemon_conf_s *conf); - -int usrsocktest_daemon_stop(void); - -int usrsocktest_daemon_get_num_active_sockets(void); - -int usrsocktest_daemon_get_num_connected_sockets(void); - -int usrsocktest_daemon_get_num_waiting_connect_sockets(void); - -int usrsocktest_daemon_get_num_recv_empty_sockets(void); - -ssize_t usrsocktest_daemon_get_send_bytes(void); - -ssize_t usrsocktest_daemon_get_recv_bytes(void); - -int usrsocktest_daemon_get_num_unreachable_sockets(void); - -int usrsocktest_daemon_get_num_remote_disconnected_sockets(void); - -bool usrsocktest_daemon_establish_waiting_connections(void); - -bool usrsocktest_send_delayed_command(char cmd, unsigned int delay_msec); - -int usrsocktest_daemon_pause_usrsock_handling(bool pause); - -#endif /* __EXAMPLES_UNITY_USRSOCK_DEFINES_H */ diff --git a/tests/unity_usrsock/multi_thread.c b/tests/unity_usrsock/multi_thread.c deleted file mode 100644 index 17206d2ef..000000000 --- a/tests/unity_usrsock/multi_thread.c +++ /dev/null @@ -1,256 +0,0 @@ -/**************************************************************************** - * apps/examples/unity_usrsock/multi_thread.c - * Multi-threaded access to sockets - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Authors: Roman Saveljev - * Jussi Kivilinna - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include -#include -#include -#include - -#include "defines.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ -#ifndef ARRAY_SIZE -# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -#endif - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ -static pthread_t tids[4]; -static int sds[4]; -static bool started; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ -static void usrsock_socket_multitask_do_work(int *sd) -{ - struct sockaddr_in addr; - int ret; - int i; - - for (i = 0; i < 10; i++) - { - /* Simple test for opening socket with usrsock daemon running. */ - - *sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(*sd >= 0); - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(*sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(0, ret); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(*sd) >= 0); - *sd = -1; - } -} - -static FAR void *usrsock_socket_multitask_thread(FAR void *param) -{ - usrsock_socket_multitask_do_work((int*)param); - return NULL; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -TEST_GROUP(MultiThread); - -/**************************************************************************** - * Name: MultiThread test group setup - * - * Description: - * Setup function executed before each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_SETUP(MultiThread) -{ - int i; - for (i = 0; i < ARRAY_SIZE(sds); i++) - { - sds[i] = -1; - } - for (i = 0; i < ARRAY_SIZE(tids); i++) - { - tids[i] = -1; - } - started = false; -} - -/**************************************************************************** - * Name: MultiThread test group teardown - * - * Description: - * Setup function executed after each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_TEAR_DOWN(MultiThread) -{ - int ret; - int i; - - for (i = 0; i < ARRAY_SIZE(tids); i++) - { - if (tids[i] != -1) - { - ret = pthread_cancel(tids[i]); - assert(ret == OK); - ret = pthread_join(tids[i], NULL); - assert(ret == OK); - } - } - for (i = 0; i < ARRAY_SIZE(sds); i++) - { - if (sds[i] != -1) - { - ret = close(sds[i]); - assert(ret >= 0); - } - } - if (started) - { - ret = usrsocktest_daemon_stop(); - assert(ret == OK); - } -} - -/**************************************************************************** - * Name: OpenClose - * - * Description: - * Open and close socket with multiple threads - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(MultiThread, OpenClose) -{ - int ret; - int i; - - /* Start test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - usrsocktest_daemon_config.endpoint_block_send = false; - usrsocktest_daemon_config.endpoint_block_connect = false; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config)); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Launch worker threads. */ - - for (i = 0; i < ARRAY_SIZE(tids); i++) - { - ret = pthread_create(&tids[i], NULL, usrsock_socket_multitask_thread, - sds + i); - TEST_ASSERT_EQUAL(OK, ret); - } - - /* Wait threads to complete work. */ - - while (--i > -1) - { - pthread_addr_t tparam; - - ret = pthread_join(tids[i], &tparam); - TEST_ASSERT_EQUAL(OK, ret); - tids[i] = -1; - /* This flag is set whenever a test fails, otherwise it is not touched - * No need for synchronization. Here we bail from main test thread on - * first failure in any thread. - */ - TEST_ASSERT_FALSE(Unity.CurrentTestFailed); - } - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - diff --git a/tests/unity_usrsock/noblock_connect.c b/tests/unity_usrsock/noblock_connect.c deleted file mode 100644 index 51cf35115..000000000 --- a/tests/unity_usrsock/noblock_connect.c +++ /dev/null @@ -1,806 +0,0 @@ -/**************************************************************************** - * apps/examples/unity_usrsock/noblock_connect.c - * Socket connect tests in non-blocking mode - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Authors: Roman Saveljev - * Jussi Kivilinna - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include "defines.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ -static bool started; -static int sd, sd2; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -TEST_GROUP(NoBlockConnect); - -TEST_SETUP(NoBlockConnect) -{ - sd = -1; - sd2 = -1; - started = false; -} - -TEST_TEAR_DOWN(NoBlockConnect) -{ - int ret; - - if (sd >= 0) - { - ret = close(sd); - assert(ret == 0); - } - if (sd2 >= 0) - { - ret = close(sd2); - assert(ret == 0); - } - if (started) - { - ret = usrsocktest_daemon_stop(); - assert(ret == OK); - } -} - -TEST(NoBlockConnect, InstantConnect) -{ - int flags; - int ret; - struct sockaddr_in addr; - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Make socket non-blocking */ - - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); - ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); - TEST_ASSERT_EQUAL(0, ret); - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); - - /* Do connect, should succeed instantly. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -TEST(NoBlockConnect, DelayedConnect) -{ - int flags, ret, count; - struct sockaddr_in addr; - - /* Start test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.endpoint_block_connect = true; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - usrsocktest_daemon_config.delay_all_responses = true; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Make socket non-blocking */ - - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); - ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); - TEST_ASSERT_EQUAL(0, ret); - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); - - /* Launch connect attempt, daemon delays actual connection until triggered. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINPROGRESS, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Another connect attempt results EALREADY. */ - - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EALREADY, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Release delayed connect. */ - - TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections()); - for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++) - { - TEST_ASSERT_TRUE(count <= 5); - usleep(10 * 1000); - } - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Another connect attempt results EISCONN. */ - - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EISCONN, errno); - - /* Close socket. */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -TEST(NoBlockConnect, CloseNotConnected) -{ - int flags, ret; - struct sockaddr_in addr; - - /* Start test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.endpoint_block_connect = true; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - usrsocktest_daemon_config.delay_all_responses = true; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Make socket non-blocking */ - - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); - ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); - TEST_ASSERT_EQUAL(0, ret); - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); - - /* Launch connect attempt, daemon delays actual connection until triggered. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINPROGRESS, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Close socket. */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -TEST(NoBlockConnect, EarlyDrop) -{ - int flags, ret; - struct sockaddr_in addr; - - /* Start test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.endpoint_block_connect = true; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - usrsocktest_daemon_config.delay_all_responses = false; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0) - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Make socket non-blocking */ - - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); - ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); - TEST_ASSERT_EQUAL(0, ret); - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); - - /* Launch connect attempt, daemon delays actual connection until triggered. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINPROGRESS, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); - - /* Close socket. */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets()); -} - -TEST(NoBlockConnect, Multiple) -{ - int flags, ret, count; - struct sockaddr_in addr; - - /* Start test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.endpoint_block_connect = true; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - usrsocktest_daemon_config.delay_all_responses = false; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open sockets */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - sd2 = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd2 >= 0); - TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Make socket non-blocking */ - - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); - ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); - TEST_ASSERT_EQUAL(0, ret); - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); - - flags = fcntl(sd2, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); - ret = fcntl(sd2, F_SETFL, flags | O_NONBLOCK); - TEST_ASSERT_EQUAL(0, ret); - flags = fcntl(sd2, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); - - /* Launch connect attempts, daemon delays actual connection until triggered. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINPROGRESS, errno); - TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Release delayed connections. */ - - TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections()); - for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++) - { - TEST_ASSERT_TRUE(count <= 5); - usleep(10 * 1000); - } - TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EISCONN, errno); - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINPROGRESS, errno); - TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Release delayed connections. */ - - TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections()); - for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++) - { - TEST_ASSERT_TRUE(count <= 5); - usleep(10 * 1000); - } - TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Close sockets. */ - - TEST_ASSERT_TRUE(close(sd2) >= 0); - sd2 = -1; - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Open sockets */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - sd2 = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd2 >= 0); - TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Make socket non-blocking */ - - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); - ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); - TEST_ASSERT_EQUAL(0, ret); - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); - - flags = fcntl(sd2, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); - ret = fcntl(sd2, F_SETFL, flags | O_NONBLOCK); - TEST_ASSERT_EQUAL(0, ret); - flags = fcntl(sd2, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); - - /* Launch connect attempts, daemon delays actual connection until triggered. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINPROGRESS, errno); - TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINPROGRESS, errno); - TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Release delayed connections. */ - - TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections()); - for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++) - { - TEST_ASSERT_TRUE(count <= 5); - usleep(10 * 1000); - } - TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Close sockets. */ - - TEST_ASSERT_TRUE(close(sd2) >= 0); - sd2 = -1; - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Open sockets */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - sd2 = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd2 >= 0); - TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Make socket non-blocking */ - - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); - ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); - TEST_ASSERT_EQUAL(0, ret); - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); - - flags = fcntl(sd2, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); - ret = fcntl(sd2, F_SETFL, flags | O_NONBLOCK); - TEST_ASSERT_EQUAL(0, ret); - flags = fcntl(sd2, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); - - /* Launch connect attempt, daemon delays actual connection until triggered. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINPROGRESS, errno); - TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Release delayed connections. */ - - TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections()); - for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++) - { - TEST_ASSERT_TRUE(count <= 5); - usleep(10 * 1000); - } - TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Launch another connect attempt, daemon delays actual connection until triggered. */ - - ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINPROGRESS, errno); - TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Close sockets. */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_TRUE(close(sd2) >= 0); - sd2 = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -TEST(NoBlockConnect, Dup2) -{ - int flags, ret, count; - struct sockaddr_in addr; - - /* Start test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.endpoint_block_connect = true; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - usrsocktest_daemon_config.delay_all_responses = true; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Duplicate socket */ - - sd2 = dup(sd); - TEST_ASSERT_TRUE(sd2 >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - - /* Make socket non-blocking */ - - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); - ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); - TEST_ASSERT_EQUAL(0, ret); - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); - - /* Launch connect attempt, daemon delays actual connection until triggered. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINPROGRESS, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Another connect attempt results EALREADY. */ - - ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EALREADY, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Release delayed connect. */ - - TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections()); - for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++) - { - TEST_ASSERT_TRUE(count <= 5); - usleep(10 * 1000); - } - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Another connect attempt results EISCONN. */ - - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EISCONN, errno); - - /* Close sockets. */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - TEST_ASSERT_TRUE(close(sd2) >= 0); - sd2 = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} diff --git a/tests/unity_usrsock/noblock_recv.c b/tests/unity_usrsock/noblock_recv.c deleted file mode 100644 index 4f191ac49..000000000 --- a/tests/unity_usrsock/noblock_recv.c +++ /dev/null @@ -1,503 +0,0 @@ -/**************************************************************************** - * apps/examples/unity_usrsock/noblock_recv.c - * Receive from the socket in non-blocking mode - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Authors: Roman Saveljev - * Jussi Kivilinna - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "defines.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ -static bool started; -static int sd; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: Receive - * - * Description: - * Non-blocking & instant connect+recv - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void Receive(struct usrsocktest_daemon_conf_s *dconf) -{ - int flags; - int count; - ssize_t ret; - size_t datalen; - void *data; - struct sockaddr_in addr; - char databuf[4]; - struct sockaddr_in remoteaddr; - socklen_t addrlen; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - dconf->endpoint_recv_avail_from_start = true; - dconf->endpoint_recv_avail = 7; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Make socket non-blocking */ - - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); - ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); - TEST_ASSERT_EQUAL(0, ret); - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); - - /* Do connect, should succeed instantly. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - if (!dconf->delay_all_responses) - { - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); - } - else - { - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINPROGRESS, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - for (count = 0; usrsocktest_daemon_get_num_connected_sockets() != 1; count++) - { - TEST_ASSERT_TRUE(count <= 3); - usleep(25 * 1000); - } - - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EISCONN, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); - } - - /* Receive data from remote, daemon returns 4 bytes. */ - - data = databuf; - datalen = sizeof(databuf); - ret = recvfrom(sd, data, datalen, 0, NULL, NULL); - TEST_ASSERT_EQUAL(datalen, ret); - TEST_ASSERT_EQUAL(4, datalen); - TEST_ASSERT_EQUAL_UINT8_ARRAY("abcd", data, 4); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(4, usrsocktest_daemon_get_recv_bytes()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Receive data from remote with address, daemon returns 3 bytes. */ - - addrlen = sizeof(remoteaddr); - ret = recvfrom(sd, data, datalen, 0, (FAR struct sockaddr *)&remoteaddr, &addrlen); - TEST_ASSERT_EQUAL(3, ret); - TEST_ASSERT_EQUAL_UINT8_ARRAY("abc", data, 3); - TEST_ASSERT_EQUAL(addrlen, sizeof(remoteaddr)); - TEST_ASSERT_EQUAL_UINT8_ARRAY(&remoteaddr, &addr, addrlen); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(datalen + ret, usrsocktest_daemon_get_recv_bytes()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Receive data from remote, daemon has 0 bytes buffered => -EAGAIN */ - - data = databuf; - datalen = sizeof(databuf); - ret = recvfrom(sd, data, datalen, 0, NULL, NULL); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EAGAIN, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(7, usrsocktest_daemon_get_recv_bytes()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Receive data from remote, daemon has 0 bytes buffered => -EAGAIN */ - - data = databuf; - datalen = sizeof(databuf); - ret = read(sd, data, datalen); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EAGAIN, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(7, usrsocktest_daemon_get_recv_bytes()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Reset recv buffer for open sockets */ - - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 0)); - for (count = 0; usrsocktest_daemon_get_num_recv_empty_sockets() > 0; count++) - { - TEST_ASSERT_TRUE(count <= 5); - usleep(5 * 1000); - } - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Receive data from remote, daemon returns 4 bytes. */ - - data = databuf; - datalen = sizeof(databuf); - ret = recvfrom(sd, data, datalen, 0, NULL, NULL); - TEST_ASSERT_EQUAL(datalen, ret); - TEST_ASSERT_EQUAL(4, datalen); - TEST_ASSERT_EQUAL_UINT8_ARRAY("abcd", data, 4); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(7 + 4, usrsocktest_daemon_get_recv_bytes()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(7 + 4, usrsocktest_daemon_get_recv_bytes()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Name: DelayedConnect - * - * Description: - * Non-blocking & delayed connect - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void DelayedConnect(struct usrsocktest_daemon_conf_s *dconf) -{ - int flags; - int count; - ssize_t ret; - size_t datalen; - void *data; - struct sockaddr_in addr; - char databuf[4]; - struct sockaddr_in remoteaddr; - socklen_t addrlen; - - /* Start test daemon. */ - - dconf->endpoint_block_connect = true; - dconf->endpoint_recv_avail_from_start = false; - dconf->endpoint_recv_avail = 4; - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Make socket non-blocking */ - - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); - ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); - TEST_ASSERT_EQUAL(0, ret); - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); - - /* Launch connect attempt, daemon delays actual connection until triggered. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINPROGRESS, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Try receive data, not connected yet. */ - - data = databuf; - datalen = sizeof(databuf); - ret = read(sd, data, datalen); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EAGAIN, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); - - /* Release delayed connect. */ - - TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections()); - for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++) - { - TEST_ASSERT_TRUE(count <= 5); - usleep(10 * 1000); - } - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Try receive data, not received data yet. */ - - data = databuf; - datalen = sizeof(databuf); - addrlen = sizeof(remoteaddr); - ret = recvfrom(sd, data, datalen, 0, (FAR struct sockaddr *)&remoteaddr, &addrlen); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EAGAIN, errno); - TEST_ASSERT_EQUAL(0, addrlen); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Reset recv buffer for open sockets */ - - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 0)); - for (count = 0; usrsocktest_daemon_get_num_recv_empty_sockets() > 0; count++) - { - TEST_ASSERT_TRUE(count <= 5); - usleep(5 * 1000); - } - - /* Receive data from remote, daemon returns 4 bytes. */ - - data = databuf; - datalen = sizeof(databuf); - ret = recvfrom(sd, data, datalen, 0, NULL, NULL); - TEST_ASSERT_EQUAL(datalen, ret); - TEST_ASSERT_EQUAL(4, datalen); - TEST_ASSERT_EQUAL_UINT8_ARRAY("abcd", data, 4); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(4, usrsocktest_daemon_get_recv_bytes()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Close socket. */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_recv_empty_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -TEST_GROUP(NoBlockRecv); - -/**************************************************************************** - * Name: NoBlockRecv test group setup - * - * Description: - * Setup function executed before each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_SETUP(NoBlockRecv) -{ - sd = -1; - started = false; -} - -/**************************************************************************** - * Name: NoBlockRecv test group teardown - * - * Description: - * Setup function executed after each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_TEAR_DOWN(NoBlockRecv) -{ - int ret; - if (sd >= 0) - { - ret = close(sd); - assert(ret >= 0); - } - if (started) - { - ret = usrsocktest_daemon_stop(); - assert(ret == OK); - } -} - -TEST(NoBlockRecv, Receive) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - Receive(&usrsocktest_daemon_config); -} - -TEST(NoBlockRecv, ReceiveDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - Receive(&usrsocktest_daemon_config); -} - -TEST(NoBlockRecv, DelayedConnect) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - DelayedConnect(&usrsocktest_daemon_config); -} - -TEST(NoBlockRecv, DelayedConnectDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - DelayedConnect(&usrsocktest_daemon_config); -} diff --git a/tests/unity_usrsock/noblock_send.c b/tests/unity_usrsock/noblock_send.c deleted file mode 100644 index 47055f76c..000000000 --- a/tests/unity_usrsock/noblock_send.c +++ /dev/null @@ -1,400 +0,0 @@ -/**************************************************************************** - * apps/examples/unity_usrsock/noblock_send.c - * Send through the socket in non-blocking mode - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Authors: Roman Saveljev - * Jussi Kivilinna - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "defines.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ -static bool started; -static int sd; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: Send - * - * Description: - * Open socket, connect instantly and send - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void Send(struct usrsocktest_daemon_conf_s *dconf) -{ - int flags; - int count; - ssize_t ret; - size_t datalen; - const void *data; - struct sockaddr_in addr; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Make socket non-blocking */ - - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); - ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); - TEST_ASSERT_EQUAL(0, ret); - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); - - /* Do connect, should succeed instantly. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - if (!dconf->delay_all_responses) - { - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - } - else - { - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINPROGRESS, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - for (count = 0; usrsocktest_daemon_get_num_connected_sockets() != 1; count++) - { - TEST_ASSERT_TRUE(count <= 3); - usleep(25 * 1000); - } - - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EISCONN, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - } - - /* Send data to remote */ - - data = "abcde"; - datalen = strlen("abcde"); - ret = sendto(sd, data, datalen, 0, NULL, 0); - TEST_ASSERT_EQUAL(datalen, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); -} - -/**************************************************************************** - * Name: ConnectSend - * - * Description: - * Open socket, connect is delayed and send - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void ConnectSend(struct usrsocktest_daemon_conf_s *dconf) -{ - int flags; - int count; - ssize_t ret; - size_t datalen; - const void *data; - struct sockaddr_in addr; - - /* Start test daemon. */ - - dconf->endpoint_block_connect = true; - dconf->endpoint_block_send = true; - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Make socket non-blocking */ - - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); - ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); - TEST_ASSERT_EQUAL(0, ret); - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); - - /* Launch connect attempt, daemon delays actual connection until triggered. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINPROGRESS, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Send data to remote, not connected yet. */ - - data = "abcde"; - datalen = strlen("abcde"); - ret = write(sd, data, datalen); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EAGAIN, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); - - /* Release delayed connect. */ - - TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections()); - for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++) - { - TEST_ASSERT_TRUE(count <= 5); - usleep(10 * 1000); - } - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Send data to remote */ - - data = "abcde"; - datalen = strlen("abcde"); - ret = write(sd, data, datalen); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EAGAIN, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); - - /* Close socket. */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -TEST_GROUP(NoBlockSend); - -/**************************************************************************** - * Name: NoBlockSend test group setup - * - * Description: - * Setup function executed before each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_SETUP(NoBlockSend) -{ - sd = -1; - started = false; -} - -/**************************************************************************** - * Name: NoBlockSend test group teardown - * - * Description: - * Setup function executed after each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_TEAR_DOWN(NoBlockSend) -{ - int ret; - if (sd >= 0) - { - ret = close(sd); - assert(ret >= 0); - } - if (started) - { - ret = usrsocktest_daemon_stop(); - assert(ret == OK); - } -} - -TEST(NoBlockSend, Send) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - Send(&usrsocktest_daemon_config); -} - -TEST(NoBlockSend, SendDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - Send(&usrsocktest_daemon_config); -} - -TEST(NoBlockSend, ConnectSend) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - ConnectSend(&usrsocktest_daemon_config); -} - -TEST(NoBlockSend, ConnectSendDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - ConnectSend(&usrsocktest_daemon_config); -} diff --git a/tests/unity_usrsock/nodaemon.c b/tests/unity_usrsock/nodaemon.c deleted file mode 100644 index eff1cb744..000000000 --- a/tests/unity_usrsock/nodaemon.c +++ /dev/null @@ -1,148 +0,0 @@ -/**************************************************************************** - * apps/examples/unity_usrsock/nodaemon.c - * Tests without user socket daemon - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Authors: Roman Saveljev - * Jussi Kivilinna - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include -#include - -#include "defines.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ -static int sd; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -TEST_GROUP(NoDaemon); - -/**************************************************************************** - * Name: NoDaemon test group setup - * - * Description: - * Setup function executed before each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_SETUP(NoDaemon) -{ - sd = -1; -} - -/**************************************************************************** - * Name: NoDaemon test group teardown - * - * Description: - * Setup function executed after each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_TEAR_DOWN(NoDaemon) -{ - int ret; - - if (sd >= 0) - { - ret = close(sd); - assert(ret >= 0); - } -} - -/**************************************************************************** - * Name: NoSocket - * - * Description: - * Simple test for opening socket without usrsock daemon running - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(NoDaemon, NoSocket) -{ - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_EQUAL(-1, sd); - TEST_ASSERT_TRUE(errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT || errno == ENETDOWN); -} - diff --git a/tests/unity_usrsock/poll.c b/tests/unity_usrsock/poll.c deleted file mode 100644 index 0a1c46bf9..000000000 --- a/tests/unity_usrsock/poll.c +++ /dev/null @@ -1,632 +0,0 @@ -/**************************************************************************** - * apps/examples/unity_usrsock/poll.c - * User socket polling tests - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Authors: Roman Saveljev - * Jussi Kivilinna - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "defines.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ -static bool started; -static int sd; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: ConnectReceive - * - * Description: - * Non-blocking connect and receive - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void ConnectReceive(struct usrsocktest_daemon_conf_s *dconf) -{ - int flags; - int count; - ssize_t ret; - size_t datalen; - void *data; - struct sockaddr_in addr; - char databuf[4]; - struct pollfd pfd; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - dconf->endpoint_recv_avail_from_start = false; - dconf->endpoint_recv_avail = 3; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Make socket non-blocking */ - - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); - ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); - TEST_ASSERT_EQUAL(0, ret); - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); - - /* Poll for input (instant timeout). */ - - memset(&pfd, 0, sizeof(pfd)); - pfd.fd = sd; - pfd.events = POLLIN; - ret = poll(&pfd, 1, 0); - TEST_ASSERT_EQUAL(1, ret); - TEST_ASSERT_EQUAL(0, pfd.revents & POLLERR); - TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP); - TEST_ASSERT_EQUAL(POLLIN, pfd.revents & POLLIN); - TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT); - - /* Do connect, should succeed instantly. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - if (!dconf->delay_all_responses) - { - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - } - else - { - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINPROGRESS, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - for (count = 0; usrsocktest_daemon_get_num_connected_sockets() != 1; count++) - { - TEST_ASSERT_TRUE(count <= 3); - usleep(25 * 1000); - } - - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EISCONN, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - } - - /* Poll for input (instant timeout). */ - - memset(&pfd, 0, sizeof(pfd)); - pfd.fd = sd; - pfd.events = POLLIN; - ret = poll(&pfd, 1, 0); - TEST_ASSERT_EQUAL(0, ret); - - /* Poll for input (with timeout). */ - - memset(&pfd, 0, sizeof(pfd)); - pfd.fd = sd; - pfd.events = POLLIN; - ret = poll(&pfd, 1, 10); - TEST_ASSERT_EQUAL(0, ret); - - /* Poll for input (no timeout). */ - - memset(&pfd, 0, sizeof(pfd)); - pfd.fd = sd; - pfd.events = POLLIN; - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 100)); - ret = poll(&pfd, 1, -1); - TEST_ASSERT_EQUAL(1, ret); - TEST_ASSERT_EQUAL(POLLIN, pfd.revents); - - /* Receive data from remote, daemon returns 3 bytes. */ - - data = databuf; - datalen = sizeof(databuf); - ret = recvfrom(sd, data, datalen, 0, NULL, NULL); - TEST_ASSERT_EQUAL(3, ret); - TEST_ASSERT_EQUAL_UINT8_ARRAY("abc", data, 3); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(3, usrsocktest_daemon_get_recv_bytes()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Poll for input (instant timeout). */ - - memset(&pfd, 0, sizeof(pfd)); - pfd.fd = sd; - pfd.events = POLLIN; - ret = poll(&pfd, 1, 0); - TEST_ASSERT_EQUAL(0, ret); - - /* Make more data avail */ - - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 0)); - for (count = 0; usrsocktest_daemon_get_num_recv_empty_sockets() > 0; count++) - { - TEST_ASSERT_TRUE(count <= 3); - usleep(5 * 1000); - } - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Poll for input (no timeout). */ - - memset(&pfd, 0, sizeof(pfd)); - pfd.fd = sd; - pfd.events = POLLIN; - ret = poll(&pfd, 1, -1); - TEST_ASSERT_EQUAL(1, ret); - TEST_ASSERT_EQUAL(POLLIN, pfd.revents); - - /* Receive data from remote, daemon returns 3 bytes. */ - - data = databuf; - datalen = sizeof(databuf); - ret = recvfrom(sd, data, datalen, 0, NULL, NULL); - TEST_ASSERT_EQUAL(3, ret); - TEST_ASSERT_EQUAL_UINT8_ARRAY("abc", data, 3); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(6, usrsocktest_daemon_get_recv_bytes()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(6, usrsocktest_daemon_get_recv_bytes()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Name: ConnectSend - * - * Description: - * Non-blocking connect and receive - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void ConnectSend(struct usrsocktest_daemon_conf_s *dconf) -{ - int flags; - ssize_t ret; - size_t datalen; - void *data; - struct sockaddr_in addr; - struct pollfd pfd; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - dconf->endpoint_recv_avail_from_start = true; - dconf->endpoint_recv_avail = 3; - dconf->endpoint_block_send = false; - dconf->endpoint_block_connect = true; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Make socket non-blocking */ - - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); - ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); - TEST_ASSERT_EQUAL(0, ret); - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); - - /* Poll for input (instant timeout). */ - - memset(&pfd, 0, sizeof(pfd)); - pfd.fd = sd; - pfd.events = POLLIN; - ret = poll(&pfd, 1, 0); - TEST_ASSERT_EQUAL(1, ret); - TEST_ASSERT_EQUAL(0, pfd.revents & POLLERR); - TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP); - TEST_ASSERT_EQUAL(POLLIN, pfd.revents & POLLIN); - TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT); - - /* Start non-blocking connect. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINPROGRESS, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Poll for input (no timeout). As send is ready after established connection, - * poll will exit with POLLOUT. */ - - memset(&pfd, 0, sizeof(pfd)); - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100)); - pfd.fd = sd; - pfd.events = POLLOUT; - ret = poll(&pfd, 1, -1); - TEST_ASSERT_EQUAL(1, ret); - TEST_ASSERT_EQUAL(POLLOUT, pfd.revents); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); - - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EISCONN, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Send data to remote. */ - - data = "abcdeFG"; - datalen = strlen(data); - ret = write(sd, data, datalen); - TEST_ASSERT_EQUAL(datalen, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Name: DaemonAbort - * - * Description: - * Poll with daemon abort - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void DaemonAbort(struct usrsocktest_daemon_conf_s *dconf) -{ - int flags; - ssize_t ret; - struct sockaddr_in addr; - struct pollfd pfd; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - dconf->endpoint_recv_avail_from_start = false; - dconf->endpoint_recv_avail = 3; - dconf->endpoint_block_send = false; - dconf->endpoint_block_connect = true; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Make socket non-blocking */ - - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); - ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); - TEST_ASSERT_EQUAL(0, ret); - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); - - /* Poll for input (instant timeout). */ - - memset(&pfd, 0, sizeof(pfd)); - pfd.fd = sd; - pfd.events = POLLIN; - ret = poll(&pfd, 1, 0); - TEST_ASSERT_EQUAL(1, ret); - TEST_ASSERT_EQUAL(0, pfd.revents & POLLERR); - TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP); - TEST_ASSERT_EQUAL(POLLIN, pfd.revents & POLLIN); - TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT); - - /* Start non-blocking connect. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINPROGRESS, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Poll for input (no timeout). Stop daemon forcefully. */ - - memset(&pfd, 0, sizeof(pfd)); - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('S', 100)); - pfd.fd = sd; - pfd.events = POLLOUT; - ret = poll(&pfd, 1, -1); - TEST_ASSERT_EQUAL(1, ret); - TEST_ASSERT_EQUAL(POLLERR, pfd.revents & POLLERR); - TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); - - /* Poll for input (no timeout). */ - - memset(&pfd, 0, sizeof(pfd)); - pfd.fd = sd; - pfd.events = POLLOUT; - ret = poll(&pfd, 1, -1); - TEST_ASSERT_EQUAL(1, ret); - TEST_ASSERT_EQUAL(POLLERR, pfd.revents & POLLERR); - TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP); - TEST_ASSERT_EQUAL(0, pfd.revents & POLLIN); - TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_send_bytes()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_recv_empty_sockets()); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -TEST_GROUP(Poll); - -/**************************************************************************** - * Name: Poll test group setup - * - * Description: - * Setup function executed before each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_SETUP(Poll) -{ - sd = -1; - started = false; -} - -/**************************************************************************** - * Name: Poll test group teardown - * - * Description: - * Setup function executed after each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_TEAR_DOWN(Poll) -{ - int ret; - if (sd >= 0) - { - ret = close(sd); - assert(ret >= 0); - } - if (started) - { - ret = usrsocktest_daemon_stop(); - assert(ret == OK); - } -} - -TEST(Poll, ConnectReceive) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - ConnectReceive(&usrsocktest_daemon_config); -} - -TEST(Poll, ConnectReceiveDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - ConnectReceive(&usrsocktest_daemon_config); -} - -TEST(Poll, ConnectSend) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - ConnectSend(&usrsocktest_daemon_config); -} - -TEST(Poll, ConnectSendDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - ConnectSend(&usrsocktest_daemon_config); -} - -TEST(Poll, DaemonAbort) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - DaemonAbort(&usrsocktest_daemon_config); -} - -TEST(Poll, DaemonAbortDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - DaemonAbort(&usrsocktest_daemon_config); -} diff --git a/tests/unity_usrsock/remote_disconnect.c b/tests/unity_usrsock/remote_disconnect.c deleted file mode 100644 index 1baec7ab8..000000000 --- a/tests/unity_usrsock/remote_disconnect.c +++ /dev/null @@ -1,1055 +0,0 @@ -/**************************************************************************** - * apps/examples/unity_usrsock/remote_disconnect.c - * Remote end disconnects - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Authors: Roman Saveljev - * Jussi Kivilinna - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "defines.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ -static const uint8_t tevents[] = { POLLIN, POLLOUT, POLLOUT|POLLIN, 0}; -static bool started; -static int sd; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: ConnectReceive - * - * Description: - * Remote end is unreachable - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void Unreachable(struct usrsocktest_daemon_conf_s *dconf) -{ - ssize_t ret; - struct sockaddr_in addr; - int flags; - struct pollfd pfd; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - dconf->endpoint_block_connect = true; - dconf->endpoint_block_send = true; - dconf->endpoint_recv_avail_from_start = false; - dconf->endpoint_recv_avail = 7; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); - - /* Try connect, connection not accepted. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('F', 100)); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(ECONNREFUSED, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_unreachable_sockets()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); - - /* Make socket non-blocking */ - - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); - ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); - TEST_ASSERT_EQUAL(0, ret); - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); - - /* Try connect, connection in progress. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINPROGRESS, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); - - /* Disconnect pending connections. */ - - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('F', 100)); - - /* Poll for input (no timeout). */ - - memset(&pfd, 0, sizeof(pfd)); - pfd.fd = sd; - pfd.events = POLLIN; - ret = poll(&pfd, 1, -1); - TEST_ASSERT_EQUAL(1, ret); - TEST_ASSERT_EQUAL(POLLERR, pfd.revents & POLLERR); - TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP); - TEST_ASSERT_EQUAL(0, pfd.revents & POLLIN); - TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); - -} - -/**************************************************************************** - * Name: Send - * - * Description: - * Send and disconnect - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void Send(struct usrsocktest_daemon_conf_s *dconf) -{ - ssize_t ret; - size_t datalen; - void *data; - struct sockaddr_in addr; - int count; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - dconf->endpoint_block_connect = false; - dconf->endpoint_block_send = false; - dconf->endpoint_recv_avail_from_start = false; - dconf->endpoint_recv_avail = 7; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); - - /* Try connect, connection in progress. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_remote_disconnected_sockets()); - - /* Disconnect connections. */ - - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('D', 0)); - for (count = 0; usrsocktest_daemon_get_num_connected_sockets() > 0; count++) - { - TEST_ASSERT_TRUE(count <= 3); - usleep(5 * 1000); - } - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_remote_disconnected_sockets()); - - for (count = 0; count < 2; count++) - { - /* Send data to remote */ - - data = "abcde"; - datalen = strlen("abcde"); - ret = write(sd, data, datalen); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EPIPE, errno); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_remote_disconnected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); - } - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Name: Send2 - * - * Description: - * Send and disconnect - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void Send2(struct usrsocktest_daemon_conf_s *dconf) -{ - ssize_t ret; - size_t datalen; - void *data; - struct sockaddr_in addr; - int count; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - dconf->endpoint_block_connect = false; - dconf->endpoint_block_send = true; - dconf->endpoint_recv_avail_from_start = false; - dconf->endpoint_recv_avail = 7; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_remote_disconnected_sockets()); - - /* Try connect. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_remote_disconnected_sockets()); - - /* Disconnect connections with delay. */ - - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('D', 100)); - - for (count = 0; count < 2; count++) - { - /* Send data to remote */ - - data = "abcde"; - datalen = strlen("abcde"); - ret = write(sd, data, datalen); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EPIPE, errno); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_remote_disconnected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); - } - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Name: Receive - * - * Description: - * Receive and disconnect - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void Receive(struct usrsocktest_daemon_conf_s *dconf) -{ - ssize_t ret; - size_t datalen; - void *data; - struct sockaddr_in addr; - char databuf[5]; - int count; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - dconf->endpoint_block_connect = false; - dconf->endpoint_block_send = false; - dconf->endpoint_recv_avail_from_start = true; - dconf->endpoint_recv_avail = 1; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); - - /* Try connect. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_remote_disconnected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); - - /* Disconnect connections. */ - - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('D', 0)); - for (count = 0; usrsocktest_daemon_get_num_connected_sockets() > 0; count++) - { - TEST_ASSERT_TRUE(count <= 3); - usleep(5 * 1000); - } - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_remote_disconnected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets()); - - for (count = 0; count < 2; count++) - { - /* Read from closed remote (EOF) */ - - data = databuf; - datalen = sizeof(databuf); - ret = read(sd, data, datalen); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_remote_disconnected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_recv_bytes()); - } - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Name: Receive2 - * - * Description: - * Receive and disconnect - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void Receive2(struct usrsocktest_daemon_conf_s *dconf) -{ - ssize_t ret; - size_t datalen; - void *data; - struct sockaddr_in addr; - char databuf[5]; - int count; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - dconf->endpoint_block_connect = false; - dconf->endpoint_block_send = true; - dconf->endpoint_recv_avail_from_start = false; - dconf->endpoint_recv_avail = 7; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_remote_disconnected_sockets()); - - /* Try connect. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_unreachable_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_remote_disconnected_sockets()); - - /* Disconnect connections with delay. */ - - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('D', 100)); - - for (count = 0; count < 2; count++) - { - /* Read from closed remote (EOF) */ - - data = databuf; - datalen = sizeof(databuf); - ret = read(sd, data, datalen); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_remote_disconnected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_recv_bytes()); - } - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Name: Poll - * - * Description: - * Poll and disconnect - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void Poll(struct usrsocktest_daemon_conf_s *dconf) -{ - ssize_t ret; - struct sockaddr_in addr; - int flags; - struct pollfd pfd; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - dconf->endpoint_recv_avail_from_start = false; - dconf->endpoint_recv_avail = 3; - dconf->endpoint_block_send = false; - dconf->endpoint_block_connect = true; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Make socket non-blocking */ - - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); - ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); - TEST_ASSERT_EQUAL(0, ret); - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); - - /* Poll for input (instant timeout). */ - - memset(&pfd, 0, sizeof(pfd)); - pfd.fd = sd; - pfd.events = POLLIN; - ret = poll(&pfd, 1, 0); - TEST_ASSERT_EQUAL(1, ret); - TEST_ASSERT_EQUAL(0, pfd.revents & POLLERR); - TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP); - TEST_ASSERT_EQUAL(POLLIN, pfd.revents & POLLIN); - TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT); - - /* Start non-blocking connect. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINPROGRESS, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Poll for input/output (no timeout). Fail connection. */ - - memset(&pfd, 0, sizeof(pfd)); - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('F', 100)); - pfd.fd = sd; - pfd.events = POLLOUT | POLLIN; - ret = poll(&pfd, 1, -1); - TEST_ASSERT_EQUAL(1, ret); - TEST_ASSERT_EQUAL(POLLERR, pfd.revents & POLLERR); - TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP); - TEST_ASSERT_EQUAL(0, pfd.revents & POLLIN); - TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_remote_disconnected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_unreachable_sockets()); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Name: Poll2 - * - * Description: - * Poll and disconnect - * - * Input Parameters: - * dconf - socket daemon configuration - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void Poll2(struct usrsocktest_daemon_conf_s *dconf) -{ - ssize_t ret; - size_t datalen; - void *data; - struct sockaddr_in addr; - char databuf[5]; - int flags; - struct pollfd pfd; - int count; - const uint8_t *events = tevents; - - /* Start test daemon. */ - - dconf->endpoint_addr = "127.0.0.1"; - dconf->endpoint_port = 255; - dconf->endpoint_recv_avail_from_start = false; - dconf->endpoint_recv_avail = 3; - dconf->endpoint_block_send = true; - dconf->endpoint_block_connect = false; - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf)); - started = true; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - do - { - TEST_ASSERT_TRUE(*events == POLLIN || *events == POLLOUT || *events == (POLLOUT|POLLIN)); - - /* Open socket */ - - sd = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(sd >= 0); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - - /* Make socket non-blocking */ - - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK); - ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK); - TEST_ASSERT_EQUAL(0, ret); - flags = fcntl(sd, F_GETFL, 0); - TEST_ASSERT_TRUE(flags >= 0); - TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR); - TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK); - - /* Poll for input (instant timeout). */ - - memset(&pfd, 0, sizeof(pfd)); - pfd.fd = sd; - pfd.events = *events; - ret = poll(&pfd, 1, 0); - TEST_ASSERT_EQUAL(1, ret); - TEST_ASSERT_EQUAL(0, pfd.revents & POLLERR); - TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP); - TEST_ASSERT_EQUAL(*events & POLLIN, pfd.revents & POLLIN); - TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT); - - /* Start non-blocking connect. */ - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - if (!dconf->delay_all_responses) - { - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - } - else - { - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EINPROGRESS, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - for (count = 0; usrsocktest_daemon_get_num_connected_sockets() != 1; count++) - { - TEST_ASSERT_TRUE(count <= 3); - usleep(25 * 1000); - } - - ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EISCONN, errno); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets()); - } - - /* Poll for output (no timeout). Close connection. */ - - memset(&pfd, 0, sizeof(pfd)); - TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('D', 100)); - pfd.fd = sd; - pfd.events = *events; - ret = poll(&pfd, 1, -1); - TEST_ASSERT_EQUAL(1, ret); - TEST_ASSERT_EQUAL(0, pfd.revents & POLLERR); - TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP); - TEST_ASSERT_EQUAL(*events & POLLIN, pfd.revents & POLLIN); - TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_remote_disconnected_sockets()); - - for (count = 0; count < 2; count++) - { - /* Read from closed remote (EOF) */ - - data = databuf; - datalen = sizeof(databuf); - ret = read(sd, data, datalen); - TEST_ASSERT_EQUAL(0, ret); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_remote_disconnected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_recv_bytes()); - } - - for (count = 0; count < 2; count++) - { - /* Send data to remote */ - - data = "abcde"; - datalen = strlen("abcde"); - ret = write(sd, data, datalen); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EPIPE, errno); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_remote_disconnected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes()); - } - - /* Close socket */ - - TEST_ASSERT_TRUE(close(sd) >= 0); - sd = -1; - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets()); - - events++; - } - while (*events); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - started = false; - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets()); - TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -TEST_GROUP(RemoteDisconnect); - -/**************************************************************************** - * Name: RemoteDisconnect test group setup - * - * Description: - * Setup function executed before each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_SETUP(RemoteDisconnect) -{ - sd = -1; - started = false; -} - -/**************************************************************************** - * Name: RemoteDisconnect test group teardown - * - * Description: - * Setup function executed after each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_TEAR_DOWN(RemoteDisconnect) -{ - int ret; - if (sd >= 0) - { - ret = close(sd); - assert(ret >= 0); - } - if (started) - { - ret = usrsocktest_daemon_stop(); - assert(ret == OK); - } -} - -TEST(RemoteDisconnect, Unreachable) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - Unreachable(&usrsocktest_daemon_config); -} - -TEST(RemoteDisconnect, UnreachableDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - Unreachable(&usrsocktest_daemon_config); -} - -TEST(RemoteDisconnect, Send) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - Send(&usrsocktest_daemon_config); -} - -TEST(RemoteDisconnect, SendDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - Send(&usrsocktest_daemon_config); -} - -TEST(RemoteDisconnect, Send2) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - Send2(&usrsocktest_daemon_config); -} - -TEST(RemoteDisconnect, Send2Delay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - Send2(&usrsocktest_daemon_config); -} - -TEST(RemoteDisconnect, Receive) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - Receive(&usrsocktest_daemon_config); -} - -TEST(RemoteDisconnect, ReceiveDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - Receive(&usrsocktest_daemon_config); -} - -TEST(RemoteDisconnect, Receive2) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - Receive2(&usrsocktest_daemon_config); -} - -TEST(RemoteDisconnect, Receive2Delay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - Receive2(&usrsocktest_daemon_config); -} - -TEST(RemoteDisconnect, Poll) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - Poll(&usrsocktest_daemon_config); -} - -TEST(RemoteDisconnect, PollDelay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - Poll(&usrsocktest_daemon_config); -} - -TEST(RemoteDisconnect, Poll2) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - Poll2(&usrsocktest_daemon_config); -} - -TEST(RemoteDisconnect, Poll2Delay) -{ - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = true; - Poll2(&usrsocktest_daemon_config); -} diff --git a/tests/unity_usrsock/unity_usrsock_main.c b/tests/unity_usrsock/unity_usrsock_main.c deleted file mode 100644 index 6025ee804..000000000 --- a/tests/unity_usrsock/unity_usrsock_main.c +++ /dev/null @@ -1,161 +0,0 @@ -/**************************************************************************** - * apps/examples/unity_usrsock/unity_usrsock_main.c - * Main function for Unity test application - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Author: Roman Saveljev - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ -static void runAllTests(void); - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ -int usrsocktest_endp_malloc_cnt = 0; -int usrsocktest_dcmd_malloc_cnt = 0; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -static void get_mallinfo(struct mallinfo *mem) -{ -#ifdef CONFIG_CAN_PASS_STRUCTS - *mem = mallinfo(); -#else - (void)mallinfo(mem); -#endif -} - -static void print_mallinfo(const struct mallinfo *mem, const char *title) -{ - if (title) - printf("%s:\n", title); - printf(" %11s%11s%11s%11s\n", "total", "used", "free", "largest"); - printf("Mem: %11d%11d%11d%11d\n", - mem->arena, mem->uordblks, mem->fordblks, mem->mxordblk); -} - -/**************************************************************************** - * Name: runAllTests - * - * Description: - * Sequentially runs all included test groups - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -static void runAllTests(void) -{ - RUN_TEST_GROUP(CharDev); - RUN_TEST_GROUP(NoDaemon); - RUN_TEST_GROUP(BasicDaemon); - RUN_TEST_GROUP(BasicConnect); - RUN_TEST_GROUP(BasicConnectDelay); - RUN_TEST_GROUP(NoBlockConnect); - RUN_TEST_GROUP(BasicSend); - RUN_TEST_GROUP(NoBlockSend); - RUN_TEST_GROUP(BlockSend); - RUN_TEST_GROUP(NoBlockRecv); - RUN_TEST_GROUP(BlockRecv); - RUN_TEST_GROUP(RemoteDisconnect); - RUN_TEST_GROUP(BasicSetSockOpt); - RUN_TEST_GROUP(BasicGetSockOpt); - RUN_TEST_GROUP(BasicGetSockName); - RUN_TEST_GROUP(WakeWithSignal); - RUN_TEST_GROUP(MultiThread); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: unity_pwrbtn_main - * - * Description: - * Application entry point - * - * Input Parameters: - * argc - number of arguments - * argv - arguments themselves - * - * Returned Value: - * exit status - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -int unity_usrsock_main(int argc, const char* argv[]) -{ - int ret; - struct mallinfo mem_before, mem_after; - - get_mallinfo(&mem_before); - - ret = UnityMain(argc, argv, runAllTests); - - get_mallinfo(&mem_after); - - print_mallinfo(&mem_before, "HEAP BEFORE TESTS"); - print_mallinfo(&mem_after, "HEAP AFTER TESTS"); - - return ret; -} diff --git a/tests/unity_usrsock/usrsocktest_daemon.c b/tests/unity_usrsock/usrsocktest_daemon.c deleted file mode 100644 index ba47bef06..000000000 --- a/tests/unity_usrsock/usrsocktest_daemon.c +++ /dev/null @@ -1,1930 +0,0 @@ -/**************************************************************************** - * examples/nettest/usrsocktest_daemon.c - * - * Copyright (C) 2015 Haltian Ltd. All rights reserved. - * Author: Jussi Kivilinna - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "defines.h" - -/**************************************************************************** - * Definitions - ****************************************************************************/ - -#ifndef dbg - #define dbg _warn -#endif - -#define TEST_SOCKET_SOCKID_BASE 10000U -#define TEST_SOCKET_COUNT 8 - -#ifndef ARRAY_SIZE -# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -#endif - -#define noinline __attribute__((noinline)) - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -struct test_socket_s { - bool opened:1; - bool connected:1; - bool blocked_connect:1; - bool block_send:1; - bool connect_refused:1; - bool disconnected:1; - int recv_avail_bytes; - FAR void *endp; - struct usrsock_message_req_ack_s pending_resp; -}; - -struct delayed_cmd_s { - sq_entry_t node; - pthread_t tid; - sem_t startsem; - int pipefd; - uint16_t delay_msec; - char cmd; -}; - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static struct daemon_priv_s { - const struct usrsocktest_daemon_conf_s *conf; - pthread_t tid; - bool joined; - - int pipefd[2]; - sem_t wakewaitsem; - unsigned int sockets_active; - unsigned int sockets_connected; - unsigned int sockets_waiting_connect; - unsigned int sockets_recv_empty; - unsigned int sockets_not_connected_refused; - unsigned int sockets_remote_disconnected; - size_t total_send_bytes; - size_t total_recv_bytes; - bool do_not_poll_usrsock; - - struct test_socket_s test_sockets[TEST_SOCKET_COUNT]; - sq_queue_t delayed_cmd_threads; -} daemon = { - .joined = true, - .conf = NULL, -}; - -static pthread_mutex_t daemon_mutex = PTHREAD_MUTEX_INITIALIZER; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -const struct usrsocktest_daemon_conf_s usrsocktest_daemon_defconf = - USRSOCKTEST_DAEMON_CONF_DEFAULTS; -struct usrsocktest_daemon_conf_s usrsocktest_daemon_config; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -static int test_socket_alloc(FAR struct daemon_priv_s *priv) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(priv->test_sockets); i++) - { - FAR struct test_socket_s *tsock = &priv->test_sockets[i]; - - if (!tsock->opened) - { - memset(tsock, 0, sizeof(*tsock)); - tsock->opened = true; - tsock->block_send = priv->conf->endpoint_block_send; - tsock->recv_avail_bytes = - priv->conf->endpoint_recv_avail_from_start ? - priv->conf->endpoint_recv_avail : 0; - priv->sockets_active++; - if (tsock->recv_avail_bytes == 0) - priv->sockets_recv_empty++; - return i + TEST_SOCKET_SOCKID_BASE; - } - } - - return -1; -} - -static FAR struct test_socket_s *test_socket_get(FAR struct daemon_priv_s *priv, - int sockid) -{ - if (sockid < TEST_SOCKET_SOCKID_BASE) - return NULL; - - sockid -= TEST_SOCKET_SOCKID_BASE; - if (sockid >= ARRAY_SIZE(priv->test_sockets)) - return NULL; - - return &priv->test_sockets[sockid]; -} - -static int test_socket_free(FAR struct daemon_priv_s *priv, int sockid) -{ - FAR struct test_socket_s *tsock = test_socket_get(priv, sockid); - - if (!tsock) - return -EBADFD; - - if (!tsock->opened) - return -EFAULT; - - if (tsock->connected) - { - priv->sockets_connected--; - tsock->connected = false; - } - if (tsock->blocked_connect) - { - priv->sockets_waiting_connect--; - tsock->blocked_connect = false; - } - if (tsock->endp) - { - free(tsock->endp); - usrsocktest_endp_malloc_cnt--; - tsock->endp = NULL; - } - if (tsock->recv_avail_bytes == 0) - { - priv->sockets_recv_empty--; - } - if (tsock->connect_refused) - { - priv->sockets_not_connected_refused--; - } - if (tsock->disconnected) - { - priv->sockets_remote_disconnected--; - } - - tsock->opened = false; - priv->sockets_active--; - - return 0; -} - -static int tsock_send_event(int fd, FAR struct daemon_priv_s *priv, - FAR struct test_socket_s *tsock, int events) -{ - FAR struct usrsock_message_socket_event_s event = {}; - ssize_t wlen; - int i; - - event.head.flags = USRSOCK_MESSAGE_FLAG_EVENT; - event.head.msgid = USRSOCK_MESSAGE_SOCKET_EVENT; - - for (i = 0; i < ARRAY_SIZE(priv->test_sockets); i++) - { - if (tsock == &priv->test_sockets[i]) - break; - } - - if (i == ARRAY_SIZE(priv->test_sockets)) - return -EINVAL; - - event.usockid = i + TEST_SOCKET_SOCKID_BASE; - event.events = events; - - wlen = write(fd, &event, sizeof(event)); - if (wlen < 0) - return -errno; - if (wlen != sizeof(event)) - return -ENOSPC; - - return OK; -} - - -static FAR void *find_endpoint(FAR struct daemon_priv_s *priv, in_addr_t ipaddr) -{ - FAR struct sockaddr_in *endpaddr; - int ok; - - endpaddr = malloc(sizeof(*endpaddr)); - usrsocktest_endp_malloc_cnt++; - assert(endpaddr); - - ok = inet_pton(AF_INET, priv->conf->endpoint_addr, &endpaddr->sin_addr.s_addr); - endpaddr->sin_family = AF_INET; - endpaddr->sin_port = htons(priv->conf->endpoint_port); - assert(ok); - - if (endpaddr->sin_addr.s_addr == ipaddr) - return endpaddr; - - free(endpaddr); - usrsocktest_endp_malloc_cnt--; - return NULL; -} - -static bool endpoint_connect(FAR struct daemon_priv_s *priv, FAR void *endp, - uint16_t port) -{ - FAR struct sockaddr_in *endpaddr = endp; - - if (endpaddr->sin_port == port) - return true; - else - return false; -} - -static void get_endpoint_sockaddr(FAR void *endp, FAR struct sockaddr_in *endpaddr) -{ - *endpaddr = *(FAR struct sockaddr_in *)endp; -} - -static ssize_t -read_req(int fd, FAR const struct usrsock_request_common_s *common_hdr, - void *req, size_t reqsize) -{ - ssize_t rlen; - int err; - - rlen = read(fd, (uint8_t *)req + sizeof(*common_hdr), - reqsize - sizeof(*common_hdr)); - if (rlen < 0) - { - err = errno; - dbg("Error reading %d bytes of request: ret=%d, errno=%d\n", - reqsize - sizeof(*common_hdr), (int)rlen, errno); - return -err; - } - if (rlen + sizeof(*common_hdr) != reqsize) - { - return -EMSGSIZE; - } - - return rlen; -} - -static int socket_request(int fd, FAR struct daemon_priv_s *priv, - FAR void *hdrbuf) -{ - FAR struct usrsock_request_socket_s *req = hdrbuf; - struct usrsock_message_req_ack_s resp = {}; - int socketid; - ssize_t wlen; - - /* Validate input. */ - - if (req->domain != priv->conf->supported_domain) - { - socketid = -EAFNOSUPPORT; - } - else if (req->type != priv->conf->supported_type || - req->protocol != priv->conf->supported_protocol) - { - socketid = -EPROTONOSUPPORT; - } - else if (priv->sockets_active >= priv->conf->max_sockets) - { - socketid = -EMFILE; - } - else - { - /* Allocate socket. */ - - socketid = test_socket_alloc(priv); - if (socketid < 0) - socketid = -ENFILE; - } - - /* Prepare response. */ - - resp.head.msgid = USRSOCK_MESSAGE_RESPONSE_ACK; - resp.head.flags = 0; - resp.xid = req->head.xid; - resp.result = socketid; - - /* Send response. */ - - wlen = write(fd, &resp, sizeof(resp)); - if (wlen < 0) - return -errno; - if (wlen != sizeof(resp)) - return -ENOSPC; - - return OK; -} - -static int close_request(int fd, FAR struct daemon_priv_s *priv, - FAR void *hdrbuf) -{ - FAR struct usrsock_request_close_s *req = hdrbuf; - struct usrsock_message_req_ack_s resp = {}; - ssize_t wlen; - int ret; - - /* Check if this socket exists. */ - - ret = test_socket_free(priv, req->usockid); - - /* Prepare response. */ - - resp.head.msgid = USRSOCK_MESSAGE_RESPONSE_ACK; - resp.xid = req->head.xid; - if (priv->conf->delay_all_responses) - { - resp.head.flags = USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; - resp.result = -EAGAIN; - } - else - { - resp.head.flags = 0; - resp.result = ret; - } - - /* Send response. */ - - wlen = write(fd, &resp, sizeof(resp)); - if (wlen < 0) - return -errno; - if (wlen != sizeof(resp)) - return -ENOSPC; - - if (priv->conf->delay_all_responses) - { - pthread_mutex_unlock(&daemon_mutex); - usleep(50 * 1000); - pthread_mutex_lock(&daemon_mutex); - - /* Previous write was acknowledgment to request, informing that request - * is still in progress. Now write actual completion response. */ - - resp.result = ret; - resp.head.flags &= ~USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; - - wlen = write(fd, &resp, sizeof(resp)); - if (wlen < 0) - return -errno; - if (wlen != sizeof(resp)) - return -ENOSPC; - } - - return OK; -} - -static int connect_request(int fd, FAR struct daemon_priv_s *priv, - FAR void *hdrbuf) -{ - DEBUGASSERT(priv); - DEBUGASSERT(hdrbuf); - FAR struct usrsock_request_connect_s *req = hdrbuf; - struct sockaddr_in addr; - FAR struct test_socket_s *tsock; - struct usrsock_message_req_ack_s resp = {}; - ssize_t wlen, rlen; - int ret = 0; - - /* Check if this socket exists. */ - - tsock = test_socket_get(priv, req->usockid); - if (!tsock) - { - ret = -EBADFD; - goto prepare; - } - - /* Check if this socket is already connected. */ - - if (tsock->connected) - { - ret = -EISCONN; - goto prepare; - } - - /* Check if address size ok. */ - - if (req->addrlen > sizeof(addr)) - { - ret = -EFAULT; - goto prepare; - } - - /* Read address. */ - - rlen = read(fd, &addr, sizeof(addr)); - if (rlen < 0 || rlen < req->addrlen) - { - ret = -EFAULT; - goto prepare; - } - - /* Check address family. */ - - if (addr.sin_family != priv->conf->supported_domain) - { - ret = -EAFNOSUPPORT; - goto prepare; - } - - /* Check if there is endpoint with target address */ - - tsock->endp = find_endpoint(priv, addr.sin_addr.s_addr); - if (!tsock->endp) - { - ret = -ENETUNREACH; - goto prepare; - } - - /* Check if there is port open at endpoint */ - - if (!endpoint_connect(priv, tsock->endp, addr.sin_port)) - { - free(tsock->endp); - usrsocktest_endp_malloc_cnt--; - tsock->endp = NULL; - ret = -ECONNREFUSED; - goto prepare; - } - - ret = OK; - -prepare: - /* Prepare response. */ - - resp.xid = req->head.xid; - resp.head.msgid = USRSOCK_MESSAGE_RESPONSE_ACK; - resp.head.flags = 0; - - if (priv->conf->endpoint_block_connect) - { - resp.head.flags = USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; - resp.result = ret; - - /* Mark connection as blocked */ - - priv->sockets_waiting_connect++; - tsock->blocked_connect = true; - tsock->pending_resp = resp; - } - else if (priv->conf->delay_all_responses) - { - resp.head.flags = USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; - resp.result = -EINPROGRESS; - tsock->blocked_connect = false; - } - else - { - if (ret == OK) - { - priv->sockets_connected++; - tsock->connected = true; - } - - resp.head.flags = 0; - resp.result = ret; - tsock->blocked_connect = false; - } - - /* Send response. */ - - wlen = write(fd, &resp, sizeof(resp)); - if (wlen < 0) - return -errno; - if (wlen != sizeof(resp)) - return -ENOSPC; - - if (priv->conf->endpoint_block_connect) - { - tsock->pending_resp.head.flags &= ~USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; - } - else - { - int events; - - if (priv->conf->delay_all_responses) - { - pthread_mutex_unlock(&daemon_mutex); - usleep(50 * 1000); - pthread_mutex_lock(&daemon_mutex); - - /* Previous write was acknowledgment to request, informing that request - * is still in progress. Now write actual completion response. */ - - resp.result = ret; - - if (ret == OK) - { - priv->sockets_connected++; - tsock->connected = true; - } - - resp.head.flags &= ~USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; - - wlen = write(fd, &resp, sizeof(resp)); - if (wlen < 0) - return -errno; - if (wlen != sizeof(resp)) - return -ENOSPC; - } - - events = 0; - if (!tsock->block_send) - events |= USRSOCK_EVENT_SENDTO_READY; - if (tsock->recv_avail_bytes > 0) - events |= USRSOCK_EVENT_RECVFROM_AVAIL; - - if (events) - { - wlen = tsock_send_event(fd, priv, tsock, events); - if (wlen < 0) - return wlen; - } - } - - return OK; -} - -static int sendto_request(int fd, FAR struct daemon_priv_s *priv, - FAR void *hdrbuf) -{ - DEBUGASSERT(priv); - DEBUGASSERT(hdrbuf); - FAR struct usrsock_request_sendto_s *req = hdrbuf; - FAR struct test_socket_s *tsock; - struct usrsock_message_req_ack_s resp = {}; - ssize_t wlen, rlen; - int ret = 0; - uint8_t sendbuf[16]; - int sendbuflen = 0; - - /* Check if this socket exists. */ - - tsock = test_socket_get(priv, req->usockid); - if (!tsock) - { - ret = -EBADFD; - goto prepare; - } - - /* Check if this socket is connected. */ - - if (!tsock->connected) - { - ret = -ENOTCONN; - goto prepare; - } - - /* Check if address size non-zero. */ - - if (req->addrlen > 0) - { - ret = -EISCONN; /* connection-mode socket do not accept address */ - goto prepare; - } - - /* Can send? */ - - if (!tsock->block_send) - { - /* Check if request has data. */ - - if (req->buflen > 0) - { - sendbuflen = req->buflen; - if (sendbuflen > sizeof(sendbuf)) - sendbuflen = sizeof(sendbuf); - - /* Read data. */ - - rlen = read(fd, sendbuf, sendbuflen); - if (rlen < 0 || rlen < sendbuflen) - { - ret = -EFAULT; - goto prepare; - } - - /* Debug print */ - - dbg("got %d bytes of data: '%.*s'\n", sendbuflen, sendbuflen, sendbuf); - } - } - else - { - ret = -EAGAIN; /* blocked. */ - goto prepare; - } - - ret = sendbuflen; - -prepare: - /* Prepare response. */ - - resp.xid = req->head.xid; - resp.head.msgid = USRSOCK_MESSAGE_RESPONSE_ACK; - resp.head.flags = 0; - - if (priv->conf->delay_all_responses) - { - resp.head.flags = USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; - resp.result = -EINPROGRESS; - } - else - { - if (ret > 0) - { - priv->total_send_bytes += ret; - } - - resp.head.flags = 0; - resp.result = ret; - } - - /* Send response. */ - - wlen = write(fd, &resp, sizeof(resp)); - if (wlen < 0) - return -errno; - if (wlen != sizeof(resp)) - return -ENOSPC; - - if (priv->conf->delay_all_responses) - { - pthread_mutex_unlock(&daemon_mutex); - usleep(50 * 1000); - pthread_mutex_lock(&daemon_mutex); - - /* Previous write was acknowledgment to request, informing that request - * is still in progress. Now write actual completion response. */ - - resp.result = ret; - - if (ret > 0) - { - priv->total_send_bytes += ret; - } - - resp.head.flags &= ~USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; - - wlen = write(fd, &resp, sizeof(resp)); - if (wlen < 0) - return -errno; - if (wlen != sizeof(resp)) - return -ENOSPC; - } - - if (!tsock->block_send) - { - /* Let kernel-side know that there is space for more send data. */ - - wlen = tsock_send_event(fd, priv, tsock, USRSOCK_EVENT_SENDTO_READY); - if (wlen < 0) - return wlen; - } - - return OK; -} - -static int recvfrom_request(int fd, FAR struct daemon_priv_s *priv, - FAR void *hdrbuf) -{ - DEBUGASSERT(priv); - DEBUGASSERT(hdrbuf); - FAR struct usrsock_request_recvfrom_s *req = hdrbuf; - FAR struct test_socket_s *tsock; - struct usrsock_message_datareq_ack_s resp = {}; - ssize_t wlen; - size_t i; - int ret = 0; - size_t outbuflen; - struct sockaddr_in endpointaddr; - - /* Check if this socket exists. */ - - tsock = test_socket_get(priv, req->usockid); - if (!tsock) - { - ret = -EBADFD; - goto prepare; - } - - /* Check if this socket is connected. */ - - if (!tsock->connected) - { - ret = -ENOTCONN; - goto prepare; - } - - get_endpoint_sockaddr(tsock->endp, &endpointaddr); - - /* Do we have recv data available? */ - - if (tsock->recv_avail_bytes > 0) - { - outbuflen = req->max_buflen; - - if (outbuflen > tsock->recv_avail_bytes) - { - outbuflen = tsock->recv_avail_bytes; - } - } - else - { - ret = -EAGAIN; /* blocked. */ - goto prepare; - } - - ret = outbuflen; - -prepare: - /* Prepare response. */ - - resp.reqack.xid = req->head.xid; - resp.reqack.head.msgid = USRSOCK_MESSAGE_RESPONSE_DATA_ACK; - resp.reqack.head.flags = 0; - - if (priv->conf->delay_all_responses) - { - resp.reqack.head.flags = USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; - resp.reqack.result = -EINPROGRESS; - resp.valuelen = 0; - resp.valuelen_nontrunc = 0; - - /* Send ack response. */ - - wlen = write(fd, &resp, sizeof(resp)); - if (wlen < 0) - return -errno; - if (wlen != sizeof(resp)) - return -ENOSPC; - - pthread_mutex_unlock(&daemon_mutex); - usleep(50 * 1000); - pthread_mutex_lock(&daemon_mutex); - - /* Previous write was acknowledgment to request, informing that request - * is still in progress. Now write actual completion response. */ - - resp.reqack.head.msgid = USRSOCK_MESSAGE_RESPONSE_DATA_ACK; - resp.reqack.head.flags &= ~USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; - } - - resp.reqack.head.flags = 0; - resp.reqack.result = ret; - if (ret >= 0) - { - priv->total_recv_bytes += ret; - resp.valuelen_nontrunc = sizeof(endpointaddr); - resp.valuelen = resp.valuelen_nontrunc; - if (resp.valuelen > req->max_addrlen) - resp.valuelen = req->max_addrlen; - } - else - { - resp.valuelen = 0; - resp.valuelen_nontrunc = 0; - } - - /* Send response. */ - - wlen = write(fd, &resp, sizeof(resp)); - if (wlen < 0) - return -errno; - if (wlen != sizeof(resp)) - return -ENOSPC; - - if (resp.valuelen > 0) - { - /* Send address (value) */ - - wlen = write(fd, &endpointaddr, resp.valuelen); - if (wlen < 0) - return -errno; - if (wlen != resp.valuelen) - return -ENOSPC; - } - - if (resp.reqack.result > 0) - { - /* Send buffer */ - - for (i = 0; i < resp.reqack.result; i++) - { - char tmp = 'a' + i; - - tsock->recv_avail_bytes--; - - wlen = write(fd, &tmp, 1); - if (wlen < 0) - return -errno; - if (wlen != 1) - return -ENOSPC; - } - - if (tsock->recv_avail_bytes == 0) - priv->sockets_recv_empty++; - } - - - if (tsock->recv_avail_bytes > 0) - { - /* Let kernel-side know that there is more recv data. */ - - wlen = tsock_send_event(fd, priv, tsock, USRSOCK_EVENT_RECVFROM_AVAIL); - if (wlen < 0) - return wlen; - } - - return OK; -} - -static int setsockopt_request(int fd, FAR struct daemon_priv_s *priv, - FAR void *hdrbuf) -{ - DEBUGASSERT(priv); - DEBUGASSERT(hdrbuf); - FAR struct usrsock_request_setsockopt_s *req = hdrbuf; - FAR struct test_socket_s *tsock; - struct usrsock_message_req_ack_s resp = {}; - ssize_t wlen, rlen; - int ret = 0; - int value; - - /* Check if this socket exists. */ - - tsock = test_socket_get(priv, req->usockid); - if (!tsock) - { - ret = -EBADFD; - goto prepare; - } - - if (req->level != SOL_SOCKET) - { - dbg("setsockopt: level=%d not supported\n", req->level); - ret = -ENOPROTOOPT; - goto prepare; - } - - if (req->option != SO_REUSEADDR) - { - dbg("setsockopt: option=%d not supported\n", req->option); - ret = -ENOPROTOOPT; - goto prepare; - } - - if (req->valuelen < sizeof(value)) - { - ret = -EINVAL; - goto prepare; - } - - /* Read value. */ - - rlen = read(fd, &value, sizeof(value)); - if (rlen < 0 || rlen < sizeof(value)) - { - ret = -EFAULT; - goto prepare; - } - - /* Debug print */ - - dbg("setsockopt: option=%d value=%d\n", req->option, value); - - ret = OK; - -prepare: - /* Prepare response. */ - - resp.xid = req->head.xid; - resp.head.msgid = USRSOCK_MESSAGE_RESPONSE_ACK; - resp.head.flags = 0; - - if (priv->conf->delay_all_responses) - { - resp.head.flags = USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; - resp.result = -EINPROGRESS; - } - else - { - resp.head.flags = 0; - resp.result = ret; - } - - /* Send response. */ - - wlen = write(fd, &resp, sizeof(resp)); - if (wlen < 0) - return -errno; - if (wlen != sizeof(resp)) - return -ENOSPC; - - if (priv->conf->delay_all_responses) - { - pthread_mutex_unlock(&daemon_mutex); - usleep(50 * 1000); - pthread_mutex_lock(&daemon_mutex); - - /* Previous write was acknowledgment to request, informing that request - * is still in progress. Now write actual completion response. */ - - resp.result = ret; - resp.head.flags &= ~USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; - - wlen = write(fd, &resp, sizeof(resp)); - if (wlen < 0) - return -errno; - if (wlen != sizeof(resp)) - return -ENOSPC; - } - - return OK; -} - -static int getsockopt_request(int fd, FAR struct daemon_priv_s *priv, - FAR void *hdrbuf) -{ - DEBUGASSERT(priv); - DEBUGASSERT(hdrbuf); - FAR struct usrsock_request_getsockopt_s *req = hdrbuf; - FAR struct test_socket_s *tsock; - struct usrsock_message_datareq_ack_s resp = {}; - ssize_t wlen; - int ret = 0; - int value; - - /* Check if this socket exists. */ - - tsock = test_socket_get(priv, req->usockid); - if (!tsock) - { - ret = -EBADFD; - goto prepare; - } - - if (req->level != SOL_SOCKET) - { - dbg("getsockopt: level=%d not supported\n", req->level); - ret = -ENOPROTOOPT; - goto prepare; - } - - if (req->option != SO_REUSEADDR) - { - dbg("getsockopt: option=%d not supported\n", req->option); - ret = -ENOPROTOOPT; - goto prepare; - } - - if (req->max_valuelen < sizeof(value)) - { - ret = -EINVAL; - goto prepare; - } - - value = 0; - ret = OK; - -prepare: - /* Prepare response. */ - - resp.reqack.xid = req->head.xid; - resp.reqack.head.msgid = USRSOCK_MESSAGE_RESPONSE_DATA_ACK; - resp.reqack.head.flags = 0; - - if (priv->conf->delay_all_responses) - { - resp.reqack.head.flags = USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; - resp.reqack.result = -EINPROGRESS; - resp.valuelen = 0; - resp.valuelen_nontrunc = 0; - - /* Send ack response. */ - - wlen = write(fd, &resp, sizeof(resp)); - if (wlen < 0) - return -errno; - if (wlen != sizeof(resp)) - return -ENOSPC; - - pthread_mutex_unlock(&daemon_mutex); - usleep(50 * 1000); - pthread_mutex_lock(&daemon_mutex); - - /* Previous write was acknowledgment to request, informing that request - * is still in progress. Now write actual completion response. */ - - resp.reqack.head.msgid = USRSOCK_MESSAGE_RESPONSE_DATA_ACK; - resp.reqack.head.flags &= ~USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; - } - - resp.reqack.head.flags = 0; - resp.reqack.result = ret; - if (ret >= 0) - { - resp.valuelen = sizeof(value); - } - else - { - resp.valuelen = 0; - } - - /* Send response. */ - - wlen = write(fd, &resp, sizeof(resp)); - if (wlen < 0) - return -errno; - if (wlen != sizeof(resp)) - return -ENOSPC; - - if (resp.valuelen > 0) - { - /* Send address (value) */ - - wlen = write(fd, &value, resp.valuelen); - if (wlen < 0) - return -errno; - if (wlen != resp.valuelen) - return -ENOSPC; - } - - return OK; -} - -static int getsockname_request(int fd, FAR struct daemon_priv_s *priv, - FAR void *hdrbuf) -{ - DEBUGASSERT(priv); - DEBUGASSERT(hdrbuf); - FAR struct usrsock_request_getsockname_s *req = hdrbuf; - FAR struct test_socket_s *tsock; - struct usrsock_message_datareq_ack_s resp = {}; - ssize_t wlen; - int ret = 0; - struct sockaddr_in addr; - - /* Check if this socket exists. */ - - tsock = test_socket_get(priv, req->usockid); - if (!tsock) - { - ret = -EBADFD; - goto prepare; - } - - ret = inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(12345); - ret = ret == 1 ? 0 : -EINVAL; - -prepare: - /* Prepare response. */ - - resp.reqack.xid = req->head.xid; - resp.reqack.head.msgid = USRSOCK_MESSAGE_RESPONSE_DATA_ACK; - resp.reqack.head.flags = 0; - - if (priv->conf->delay_all_responses) - { - resp.reqack.head.flags = USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; - resp.reqack.result = -EINPROGRESS; - resp.valuelen = 0; - resp.valuelen_nontrunc = 0; - - /* Send ack response. */ - - wlen = write(fd, &resp, sizeof(resp)); - if (wlen < 0) - return -errno; - if (wlen != sizeof(resp)) - return -ENOSPC; - - pthread_mutex_unlock(&daemon_mutex); - usleep(50 * 1000); - pthread_mutex_lock(&daemon_mutex); - - /* Previous write was acknowledgment to request, informing that request - * is still in progress. Now write actual completion response. */ - - resp.reqack.head.msgid = USRSOCK_MESSAGE_RESPONSE_DATA_ACK; - resp.reqack.head.flags &= ~USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; - } - - resp.reqack.head.flags = 0; - resp.reqack.result = ret; - if (ret >= 0) - { - resp.valuelen = sizeof(addr); - resp.valuelen_nontrunc = sizeof(addr); - if (resp.valuelen > req->max_addrlen) - resp.valuelen = req->max_addrlen; - } - else - { - resp.valuelen = 0; - resp.valuelen_nontrunc = 0; - } - - /* Send response. */ - - wlen = write(fd, &resp, sizeof(resp)); - if (wlen < 0) - return -errno; - if (wlen != sizeof(resp)) - return -ENOSPC; - - if (resp.valuelen > 0) - { - /* Send address (value) */ - - wlen = write(fd, &addr, resp.valuelen); - if (wlen < 0) - return -errno; - if (wlen != resp.valuelen) - return -ENOSPC; - } - - return OK; -} - -static int handle_usrsock_request(int fd, FAR struct daemon_priv_s *priv) -{ - static const struct { - unsigned int hdrlen; - int (*fn)(int fd, FAR struct daemon_priv_s *priv, FAR void *req); - } handlers[USRSOCK_REQUEST__MAX] = - { - [USRSOCK_REQUEST_SOCKET] = - { - sizeof(struct usrsock_request_socket_s), - socket_request, - }, - [USRSOCK_REQUEST_CLOSE] = - { - sizeof(struct usrsock_request_close_s), - close_request, - }, - [USRSOCK_REQUEST_CONNECT] = - { - sizeof(struct usrsock_request_connect_s), - connect_request, - }, - [USRSOCK_REQUEST_SENDTO] = - { - sizeof(struct usrsock_request_sendto_s), - sendto_request, - }, - [USRSOCK_REQUEST_RECVFROM] = - { - sizeof(struct usrsock_request_recvfrom_s), - recvfrom_request, - }, - [USRSOCK_REQUEST_SETSOCKOPT] = - { - sizeof(struct usrsock_request_setsockopt_s), - setsockopt_request, - }, - [USRSOCK_REQUEST_GETSOCKOPT] = - { - sizeof(struct usrsock_request_getsockopt_s), - getsockopt_request, - }, - [USRSOCK_REQUEST_GETSOCKNAME] = - { - sizeof(struct usrsock_request_getsockname_s), - getsockname_request, - }, - }; - uint8_t hdrbuf[16]; - struct usrsock_request_common_s *common_hdr = (void *)hdrbuf; - ssize_t rlen; - - rlen = read(fd, common_hdr, sizeof(*common_hdr)); - if (rlen < 0) - return -errno; - if (rlen != sizeof(*common_hdr)) - return -EMSGSIZE; - - if (common_hdr->reqid >= USRSOCK_REQUEST__MAX || - !handlers[common_hdr->reqid].fn) - { - dbg("Unknown request type: %d\n", common_hdr->reqid); - return -EIO; - } - - assert(handlers[common_hdr->reqid].hdrlen < sizeof(hdrbuf)); - - rlen = read_req(fd, common_hdr, hdrbuf, handlers[common_hdr->reqid].hdrlen); - if (rlen < 0) - return rlen; - - return handlers[common_hdr->reqid].fn(fd, priv, hdrbuf); -} - -static int unblock_sendto(int fd, FAR struct daemon_priv_s *priv, - FAR struct test_socket_s *tsock) -{ - if (tsock->block_send) - { - int ret; - - tsock->block_send = false; - - ret = tsock_send_event(fd, priv, tsock, USRSOCK_EVENT_SENDTO_READY); - if (ret < 0) - return ret; - } - - return OK; -} - -static int reset_recv_avail(int fd, FAR struct daemon_priv_s *priv, - FAR struct test_socket_s *tsock) -{ - if (tsock->recv_avail_bytes == 0) - { - int ret; - - priv->sockets_recv_empty--; - - tsock->recv_avail_bytes = priv->conf->endpoint_recv_avail; - - ret = tsock_send_event(fd, priv, tsock, - USRSOCK_EVENT_RECVFROM_AVAIL); - if (ret < 0) - return ret; - } - - return OK; -} - -static int disconnect_connection(int fd, FAR struct daemon_priv_s *priv, - FAR struct test_socket_s *tsock) -{ - if (tsock->connected) - { - int ret; - - tsock->disconnected = true; - tsock->connected = false; - - priv->sockets_connected--; - priv->sockets_remote_disconnected++; - - ret = tsock_send_event(fd, priv, tsock, USRSOCK_EVENT_REMOTE_CLOSED); - if (ret < 0) - return ret; - } - - return OK; -} - -static int establish_blocked_connection(int fd, FAR struct daemon_priv_s *priv, - FAR struct test_socket_s *tsock) -{ - if (tsock->blocked_connect) - { - FAR struct usrsock_message_req_ack_s *resp = &tsock->pending_resp; - ssize_t wlen; - int events; - - if (resp->result == OK) - { - priv->sockets_connected++; - tsock->connected = true; - } - - tsock->blocked_connect = false; - - priv->sockets_waiting_connect--; - resp->head.flags &= ~USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; - - wlen = write(fd, resp, sizeof(*resp)); - if (wlen < 0) - return -errno; - if (wlen != sizeof(*resp)) - return -ENOSPC; - - events = 0; - if (!tsock->block_send) - events |= USRSOCK_EVENT_SENDTO_READY; - if (tsock->recv_avail_bytes > 0) - events |= USRSOCK_EVENT_RECVFROM_AVAIL; - - if (events) - { - wlen = tsock_send_event(fd, priv, tsock, events); - if (wlen < 0) - return wlen; - } - } - - return OK; -} - -static int fail_blocked_connection(int fd, FAR struct daemon_priv_s *priv, - FAR struct test_socket_s *tsock) -{ - if (tsock->blocked_connect) - { - FAR struct usrsock_message_req_ack_s *resp = &tsock->pending_resp; - ssize_t wlen; - - resp->result = -ECONNREFUSED; - priv->sockets_not_connected_refused++; - tsock->connect_refused = true; - tsock->blocked_connect = false; - - priv->sockets_waiting_connect--; - resp->head.flags &= ~USRSOCK_MESSAGE_FLAG_REQ_IN_PROGRESS; - - wlen = write(fd, resp, sizeof(*resp)); - if (wlen < 0) - return -errno; - if (wlen != sizeof(*resp)) - return -ENOSPC; - } - - return OK; -} - -static int for_each_connection(int fd, FAR struct daemon_priv_s *priv, - int (*iter_fn)( - int fd, - FAR struct daemon_priv_s *priv, - FAR struct test_socket_s *tsock)) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(priv->test_sockets); i++) - { - FAR struct test_socket_s *tsock = &priv->test_sockets[i]; - - if (tsock->opened) - { - int ret = iter_fn(fd, priv, tsock); - if (ret < 0) - return ret; - } - } - - return OK; -} - -static FAR void *usrsocktest_daemon(FAR void *param) -{ - FAR struct daemon_priv_s *priv = param; - bool stopped; - int ret; - int fd; - - dbg("\n"); - - priv->sockets_active = 0; - - fd = open("/dev/usrsock", O_RDWR); - if (fd < 0) - { - ret = -errno; - goto errout; - } - - do - { - struct pollfd pfd[2] = {}; - int npfds = 0; - int usrsock_pfdpos = -1; - int pipe_pdfpos = -1; - - stopped = false; - - /* Wait for request from kernel side. */ - - pthread_mutex_lock(&daemon_mutex); - if (!priv->do_not_poll_usrsock && fd >= 0) - { - pfd[npfds].fd = fd; - pfd[npfds].events = POLLIN; - usrsock_pfdpos = npfds++; - } - pfd[npfds].fd = priv->pipefd[0]; - pfd[npfds].events = POLLIN; - pipe_pdfpos = npfds++; - pthread_mutex_unlock(&daemon_mutex); - - ret = poll(pfd, npfds, -1); - if (ret < 0) - { - /* Error? */ - ret = -errno; - goto errout; - } - - if (usrsock_pfdpos >= 0 && (pfd[usrsock_pfdpos].revents & POLLIN)) - { - pthread_mutex_lock(&daemon_mutex); - ret = handle_usrsock_request(fd, priv); - pthread_mutex_unlock(&daemon_mutex); - if (ret < 0) - goto errout; - } - - if (pipe_pdfpos >= 0 && (pfd[pipe_pdfpos].revents & POLLIN)) - { - char in; - - if (read(pfd[pipe_pdfpos].fd, &in, 1) == 1) - { - pthread_mutex_lock(&daemon_mutex); - - switch (in) - { - case 'S': - stopped = true; - ret = 0; - break; - case 's': - stopped = false; - ret = 0; - break; - case 'E': - ret = for_each_connection(fd, priv, - &establish_blocked_connection); - break; - case 'F': - ret = for_each_connection(fd, priv, - &fail_blocked_connection); - break; - case 'D': - ret = for_each_connection(fd, priv, - &disconnect_connection); - break; - case 'W': - ret = for_each_connection(fd, priv, - &unblock_sendto); - break; - case 'r': - ret = for_each_connection(fd, priv, - &reset_recv_avail); - break; - case 'K': - /* Kill usrsockdev */ - if (fd >= 0) - { - close(fd); - fd = -1; - } - break; - case '*': - sem_post(&priv->wakewaitsem); - break; /* woke thread. */ - } - - pthread_mutex_unlock(&daemon_mutex); - - if (ret < 0) - goto errout; - } - } - - usleep(1); - } - while (!stopped); - - ret = OK; -errout: - if (fd >= 0) - { - close(fd); - } - - dbg("ret: %d\n", ret); - - return (FAR void *)(intptr_t)ret; -} - -static int get_daemon_value(FAR struct daemon_priv_s *priv, - FAR void *dst, FAR const void *src, size_t len) -{ - int ret = 0; - - if ((uintptr_t)src < (uintptr_t)priv || - (uintptr_t)src >= (uintptr_t)priv + sizeof(*priv) || len <= 0) - { - /* Not daemon value */ - - return -EINVAL; - } - - pthread_mutex_lock(&daemon_mutex); - - if (priv->conf == NULL) - { - /* Not running? */ - - ret = -ENODEV; - goto out; - } - - memmove(dst, src, len); - -out: - pthread_mutex_unlock(&daemon_mutex); - - return ret; -} - -static void *delayed_cmd_thread(void *priv) -{ - FAR struct delayed_cmd_s *cmd = priv; - - if (cmd->delay_msec) - sem_post(&cmd->startsem); - - usleep(cmd->delay_msec * 1000); - - (void)write(cmd->pipefd, &cmd->cmd, 1); - - if (!cmd->delay_msec) - sem_post(&cmd->startsem); - - return NULL; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -int usrsocktest_daemon_start(const struct usrsocktest_daemon_conf_s *conf) -{ - FAR struct daemon_priv_s *priv = &daemon; - pthread_attr_t attr; - int ret; - - dbg("\n"); - - pthread_mutex_lock(&daemon_mutex); - - if (priv->conf != NULL || !priv->joined) - { - /* Already running? */ - - ret = -EALREADY; - goto out; - } - - /* Clear daemon private data. */ - - memset(priv, 0, sizeof(*priv)); - - /* Allocate pipe for daemon commands. */ - - ret = pipe(priv->pipefd); - if (ret != OK) - { - ret = -errno; - goto out; - } - - ret = pthread_attr_init(&attr); - if (ret != OK) - { - ret = -ret; - goto errout_closepipe; - } - - sem_init(&priv->wakewaitsem, 0, 0); - - priv->joined = false; - priv->conf = conf; - - ret = pthread_create(&priv->tid, &attr, usrsocktest_daemon, priv); - if (ret != OK) - { - sem_destroy(&priv->wakewaitsem); - priv->joined = true; - priv->conf = NULL; - ret = -ret; - goto errout_closepipe; - } - -errout_closepipe: - if (ret != OK) - { - close(priv->pipefd[0]); - close(priv->pipefd[1]); - } -out: - pthread_mutex_unlock(&daemon_mutex); - dbg("ret: %d\n", ret); - return ret; -} - -int usrsocktest_daemon_stop(void) -{ - FAR struct daemon_priv_s *priv = &daemon; - FAR struct delayed_cmd_s *item, *next; - FAR pthread_addr_t retval; - char stopped; - int ret; - int i; - - dbg("\n"); - - pthread_mutex_lock(&daemon_mutex); - - if (priv->conf == NULL) - { - /* Not running? */ - - ret = -ENODEV; - goto out; - } - - item = (void *)sq_peek(&priv->delayed_cmd_threads); - while (item) - { - next = (void *)sq_next(&item->node); - - pthread_mutex_unlock(&daemon_mutex); - (void)pthread_join(item->tid, &retval); - pthread_mutex_lock(&daemon_mutex); - sq_rem(&item->node, &priv->delayed_cmd_threads); - free(item); - usrsocktest_dcmd_malloc_cnt--; - - item = next; - } - - pthread_mutex_unlock(&daemon_mutex); - stopped = 'S'; - write(priv->pipefd[1], &stopped, 1); - - ret = pthread_join(priv->tid, &retval); - pthread_mutex_lock(&daemon_mutex); - if (ret != OK) - { - ret = -ret; - goto out; - } - - for (i = 0; i < ARRAY_SIZE(priv->test_sockets); i++) - { - if (priv->test_sockets[i].opened && priv->test_sockets[i].endp != NULL) - { - free(priv->test_sockets[i].endp); - priv->test_sockets[i].endp = NULL; - usrsocktest_endp_malloc_cnt--; - } - } - - priv->conf = NULL; - close(priv->pipefd[0]); - close(priv->pipefd[1]); - sem_destroy(&priv->wakewaitsem); - - priv->joined = true; - ret = (intptr_t)retval; - -out: - pthread_mutex_unlock(&daemon_mutex); - dbg("ret: %d\n", ret); - return ret; -} - -int usrsocktest_daemon_get_num_active_sockets(void) -{ - FAR struct daemon_priv_s *priv = &daemon; - int ret, err; - - err = get_daemon_value(priv, &ret, &priv->sockets_active, sizeof(ret)); - if (err < 0) - return err; - - return ret; -} - -int usrsocktest_daemon_get_num_connected_sockets(void) -{ - FAR struct daemon_priv_s *priv = &daemon; - int ret, err; - - err = get_daemon_value(priv, &ret, &priv->sockets_connected, sizeof(ret)); - if (err < 0) - return err; - - return ret; -} - -int usrsocktest_daemon_get_num_waiting_connect_sockets(void) -{ - FAR struct daemon_priv_s *priv = &daemon; - int ret, err; - - err = get_daemon_value(priv, &ret, &priv->sockets_waiting_connect, sizeof(ret)); - if (err < 0) - return err; - - return ret; -} - -int usrsocktest_daemon_get_num_recv_empty_sockets(void) -{ - FAR struct daemon_priv_s *priv = &daemon; - int ret, err; - - err = get_daemon_value(priv, &ret, &priv->sockets_recv_empty, sizeof(ret)); - if (err < 0) - return err; - - return ret; -} - -ssize_t usrsocktest_daemon_get_send_bytes(void) -{ - FAR struct daemon_priv_s *priv = &daemon; - size_t ret; - int err; - - err = get_daemon_value(priv, &ret, &priv->total_send_bytes, sizeof(ret)); - if (err < 0) - return err; - - return ret; -} - -ssize_t usrsocktest_daemon_get_recv_bytes(void) -{ - FAR struct daemon_priv_s *priv = &daemon; - size_t ret; - int err; - - err = get_daemon_value(priv, &ret, &priv->total_recv_bytes, sizeof(ret)); - if (err < 0) - return err; - - return ret; -} - -int usrsocktest_daemon_get_num_unreachable_sockets(void) -{ - FAR struct daemon_priv_s *priv = &daemon; - int ret, err; - - err = get_daemon_value(priv, &ret, &priv->sockets_not_connected_refused, sizeof(ret)); - if (err < 0) - return err; - - return ret; -} - -int usrsocktest_daemon_get_num_remote_disconnected_sockets(void) -{ - FAR struct daemon_priv_s *priv = &daemon; - int ret, err; - - err = get_daemon_value(priv, &ret, &priv->sockets_remote_disconnected, sizeof(ret)); - if (err < 0) - return err; - - return ret; -} - -int usrsocktest_daemon_pause_usrsock_handling(bool pause) -{ - FAR struct daemon_priv_s *priv = &daemon; - int ret; - char cmd = '*'; - - pthread_mutex_lock(&daemon_mutex); - - if (priv->conf == NULL) - { - /* Not running? */ - - pthread_mutex_unlock(&daemon_mutex); - return -ENODEV; - } - - priv->do_not_poll_usrsock = pause; - - (void)write(priv->pipefd[1], &cmd, 1); - ret = OK; - - pthread_mutex_unlock(&daemon_mutex); - - sem_wait(&priv->wakewaitsem); - - return ret; -} - -bool usrsocktest_send_delayed_command(const char cmd, unsigned int delay_msec) -{ - FAR struct daemon_priv_s *priv = &daemon; - pthread_attr_t attr; - FAR struct delayed_cmd_s *delayed_cmd; - int ret; - - if (priv->conf == NULL) - { - /* Not running? */ - - return false; - } - - delayed_cmd = calloc(1, sizeof(*delayed_cmd)); - if (!delayed_cmd) - { - return false; - } - - usrsocktest_dcmd_malloc_cnt++; - - delayed_cmd->delay_msec = delay_msec; - delayed_cmd->cmd = cmd; - delayed_cmd->pipefd = priv->pipefd[1]; - (void)sem_init(&delayed_cmd->startsem, 0, 0); - - ret = pthread_attr_init(&attr); - if (ret != OK) - { - free(delayed_cmd); - usrsocktest_dcmd_malloc_cnt--; - return false; - } - - ret = pthread_create(&delayed_cmd->tid, &attr, delayed_cmd_thread, - delayed_cmd); - if (ret != OK) - { - free(delayed_cmd); - usrsocktest_dcmd_malloc_cnt--; - return false; - } - - while (sem_wait(&delayed_cmd->startsem) != OK); - - sq_addlast(&delayed_cmd->node, &priv->delayed_cmd_threads); - - return true; -} - -bool usrsocktest_daemon_establish_waiting_connections(void) -{ - return usrsocktest_send_delayed_command('E', 0); -} diff --git a/tests/unity_usrsock/wake_with_signal.c b/tests/unity_usrsock/wake_with_signal.c deleted file mode 100644 index 2904dc0c7..000000000 --- a/tests/unity_usrsock/wake_with_signal.c +++ /dev/null @@ -1,1563 +0,0 @@ -/**************************************************************************** - * apps/examples/unity_usrsock/wake_with_signal.c - * Wake blocked IO with signal or daemon abort - * - * Copyright (C) 2015-2016 Haltian Ltd. All rights reserved. - * Authors: Jussi Kivilinna - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include - -#include "defines.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ -#ifndef ARRAY_SIZE -# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -#endif - -#define TEST_FLAG_PAUSE_USRSOCK_HANDLING (1 << 0) -#define TEST_FLAG_DAEMON_ABORT (1 << 1) -#define TEST_FLAG_MULTI_THREAD (1 << 2) - -#define MAX_THREADS 4 - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -enum e_test_type -{ - TEST_TYPE_SOCKET = 0, - TEST_TYPE_CLOSE, - TEST_TYPE_CONNECT, - TEST_TYPE_SETSOCKOPT, - TEST_TYPE_GETSOCKOPT, - TEST_TYPE_SEND, - TEST_TYPE_RECV, - TEST_TYPE_POLL, - __TEST_TYPE_MAX, -}; - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ -static pthread_t tid[MAX_THREADS]; -static sem_t tid_startsem; -static sem_t tid_releasesem; -static int test_sd[MAX_THREADS]; -static enum e_test_type test_type; -static int test_flags; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -static FAR void * usrsock_blocking_socket_thread(FAR void *param) -{ - intptr_t tidx = (intptr_t)param; - bool test_abort = !!(test_flags & TEST_FLAG_DAEMON_ABORT); - bool test_hang = !!(test_flags & TEST_FLAG_PAUSE_USRSOCK_HANDLING); - - TEST_ASSERT_TRUE(test_hang); - TEST_ASSERT_TRUE(test_abort); - - /* Allow main thread to hang usrsock daemon at this point. */ - - sem_post(&tid_startsem); - sem_wait(&tid_releasesem); - - /* Attempt hanging open socket. */ - - sem_post(&tid_startsem); - test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_EQUAL(-1, test_sd[tidx]); - TEST_ASSERT_EQUAL(ENETDOWN, errno); - - return NULL; -} - -static FAR void * usrsock_blocking_close_thread(FAR void *param) -{ - intptr_t tidx = (intptr_t)param; - struct sockaddr_in addr; - int ret; - bool test_abort = !!(test_flags & TEST_FLAG_DAEMON_ABORT); - bool test_hang = !!(test_flags & TEST_FLAG_PAUSE_USRSOCK_HANDLING); - - TEST_ASSERT_TRUE(test_hang); - TEST_ASSERT_TRUE(test_abort); - - /* Open socket. */ - - test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(test_sd[tidx] >= 0); - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - - /* Allow main thread to hang usrsock daemon at this point. */ - - sem_post(&tid_startsem); - sem_wait(&tid_releasesem); - - /* Attempt hanging close socket. */ - - sem_post(&tid_startsem); - ret = close(test_sd[tidx]); - TEST_ASSERT_EQUAL(0, ret); - test_sd[tidx] = -1; - - return NULL; -} - -static FAR void * usrsock_blocking_connect_thread(FAR void *param) -{ - intptr_t tidx = (intptr_t)param; - struct sockaddr_in addr; - int ret; - bool test_abort = !!(test_flags & TEST_FLAG_DAEMON_ABORT); - bool test_hang = !!(test_flags & TEST_FLAG_PAUSE_USRSOCK_HANDLING); - - TEST_ASSERT_TRUE(test_hang || !test_hang); - - /* Open socket. */ - - test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(test_sd[tidx] >= 0); - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - - /* Allow main thread to hang usrsock daemon at this point. */ - - sem_post(&tid_startsem); - sem_wait(&tid_releasesem); - - /* Attempt blocking connect. */ - - sem_post(&tid_startsem); - ret = connect(test_sd[tidx], (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(test_abort ? ECONNABORTED : EINTR, errno); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(test_sd[tidx]) >= 0); - test_sd[tidx] = -1; - - return NULL; -} - -static FAR void * usrsock_blocking_setsockopt_thread(FAR void *param) -{ - intptr_t tidx = (intptr_t)param; - struct sockaddr_in addr; - int ret; - int value; - bool test_abort = !!(test_flags & TEST_FLAG_DAEMON_ABORT); - bool test_hang = !!(test_flags & TEST_FLAG_PAUSE_USRSOCK_HANDLING); - - /* Open socket. */ - - test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(test_sd[tidx] >= 0); - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - - TEST_ASSERT_TRUE(test_hang); - TEST_ASSERT_TRUE(test_abort); - - /* Allow main thread to hang usrsock daemon at this point. */ - - sem_post(&tid_startsem); - sem_wait(&tid_releasesem); - - /* Attempt hanging setsockopt. */ - - sem_post(&tid_startsem); - value = 1; - ret = setsockopt(test_sd[tidx], SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value)); - TEST_ASSERT_EQUAL(-1, ret); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(test_sd[tidx]) >= 0); - test_sd[tidx] = -1; - - return NULL; -} - -static FAR void * usrsock_blocking_getsockopt_thread(FAR void *param) -{ - intptr_t tidx = (intptr_t)param; - struct sockaddr_in addr; - int ret; - int value; - socklen_t valuelen; - bool test_abort = !!(test_flags & TEST_FLAG_DAEMON_ABORT); - bool test_hang = !!(test_flags & TEST_FLAG_PAUSE_USRSOCK_HANDLING); - - /* Open socket. */ - - test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(test_sd[tidx] >= 0); - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - - TEST_ASSERT_TRUE(test_hang); - TEST_ASSERT_TRUE(test_abort); - - /* Allow main thread to hang usrsock daemon at this point. */ - - sem_post(&tid_startsem); - sem_wait(&tid_releasesem); - - /* Attempt hanging getsockopt. */ - - sem_post(&tid_startsem); - value = -1; - valuelen = sizeof(value); - ret = getsockopt(test_sd[tidx], SOL_SOCKET, SO_REUSEADDR, &value, &valuelen); - TEST_ASSERT_EQUAL(-1, ret); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(test_sd[tidx]) >= 0); - test_sd[tidx] = -1; - - return NULL; -} - -static FAR void * usrsock_blocking_send_thread(FAR void *param) -{ - intptr_t tidx = (intptr_t)param; - struct sockaddr_in addr; - int ret; - bool test_abort = !!(test_flags & TEST_FLAG_DAEMON_ABORT); - bool test_hang = !!(test_flags & TEST_FLAG_PAUSE_USRSOCK_HANDLING); - - TEST_ASSERT_TRUE(test_hang || !test_hang); - - /* Open socket. */ - - test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(test_sd[tidx] >= 0); - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - - /* Connect socket. */ - - ret = connect(test_sd[tidx], (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(0, ret); - - /* Allow main thread to hang usrsock daemon at this point. */ - - sem_post(&tid_startsem); - sem_wait(&tid_releasesem); - - /* Attempt blocking send. */ - - sem_post(&tid_startsem); - ret = send(test_sd[tidx], &addr, sizeof(addr), 0); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(test_abort ? EPIPE : EINTR, errno); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(test_sd[tidx]) >= 0); - test_sd[tidx] = -1; - - return NULL; -} - -static FAR void * usrsock_blocking_recv_thread(FAR void *param) -{ - intptr_t tidx = (intptr_t)param; - struct sockaddr_in addr; - int ret; - bool test_abort = !!(test_flags & TEST_FLAG_DAEMON_ABORT); - bool test_hang = !!(test_flags & TEST_FLAG_PAUSE_USRSOCK_HANDLING); - - TEST_ASSERT_TRUE(test_hang || !test_hang); - - /* Open socket. */ - - test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(test_sd[tidx] >= 0); - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - - /* Connect socket. */ - - ret = connect(test_sd[tidx], (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(0, ret); - - /* Allow main thread to hang usrsock daemon at this point. */ - - sem_post(&tid_startsem); - sem_wait(&tid_releasesem); - - /* Attempt blocking recv. */ - - sem_post(&tid_startsem); - ret = recv(test_sd[tidx], &addr, sizeof(addr), 0); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(test_abort ? EPIPE : EINTR, errno); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(test_sd[tidx]) >= 0); - test_sd[tidx] = -1; - - return NULL; -} - -static FAR void * usrsock_blocking_poll_thread(FAR void *param) -{ - intptr_t tidx = (intptr_t)param; - struct sockaddr_in addr; - int ret; - struct pollfd pfd = {}; - bool test_abort = !!(test_flags & TEST_FLAG_DAEMON_ABORT); - bool test_hang = !!(test_flags & TEST_FLAG_PAUSE_USRSOCK_HANDLING); - - TEST_ASSERT_TRUE(test_abort); - TEST_ASSERT_TRUE(test_hang || !test_hang); - - /* Open socket. */ - - test_sd[tidx] = socket(AF_INET, SOCK_STREAM, 0); - TEST_ASSERT_TRUE(test_sd[tidx] >= 0); - - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr); - addr.sin_family = AF_INET; - addr.sin_port = htons(255); - - /* Connect socket. */ - - ret = connect(test_sd[tidx], (FAR const struct sockaddr *)&addr, sizeof(addr)); - TEST_ASSERT_EQUAL(0, ret); - - /* Allow main thread to hang usrsock daemon at this point. */ - - sem_post(&tid_startsem); - sem_wait(&tid_releasesem); - - /* Attempt poll. */ - - pfd.fd = test_sd[tidx]; - pfd.events = POLLIN; - - sem_post(&tid_startsem); - ret = poll(&pfd, 1, -1); - TEST_ASSERT_EQUAL(1, ret); - TEST_ASSERT_EQUAL(POLLERR | POLLHUP, pfd.revents); - - /* Attempt read from aborted socket */ - - ret = recv(test_sd[tidx], &addr, sizeof(addr), 0); - TEST_ASSERT_EQUAL(-1, ret); - TEST_ASSERT_EQUAL(EPIPE, errno); - - /* Close socket */ - - TEST_ASSERT_TRUE(close(test_sd[tidx]) >= 0); - test_sd[tidx] = -1; - - return NULL; -} - -static void do_wake_test(enum e_test_type type, int flags) -{ - static const struct - { - pthread_startroutine_t fn; - bool stop_only_on_hang; - } thread_funcs[__TEST_TYPE_MAX] = - { - [TEST_TYPE_SOCKET] = { usrsock_blocking_socket_thread, false }, - [TEST_TYPE_CLOSE] = { usrsock_blocking_close_thread, false }, - [TEST_TYPE_CONNECT] = { usrsock_blocking_connect_thread, true }, - [TEST_TYPE_SETSOCKOPT] = { usrsock_blocking_setsockopt_thread, false }, - [TEST_TYPE_GETSOCKOPT] = { usrsock_blocking_getsockopt_thread, false }, - [TEST_TYPE_RECV] = { usrsock_blocking_recv_thread, true }, - [TEST_TYPE_SEND] = { usrsock_blocking_send_thread, true }, - [TEST_TYPE_POLL] = { usrsock_blocking_poll_thread, true }, - }; - int ret; - int nthreads = (flags & TEST_FLAG_MULTI_THREAD) ? MAX_THREADS : 1; - int tidx; - bool test_abort = !!(flags & TEST_FLAG_DAEMON_ABORT); - bool test_hang = !!(flags & TEST_FLAG_PAUSE_USRSOCK_HANDLING); - - /* Start test daemon. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config)); - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets()); - - /* Launch worker threads. */ - - test_type = type; - test_flags = flags; - for (tidx = 0; tidx < nthreads; tidx++) - { - ret = pthread_create(&tid[tidx], NULL, thread_funcs[type].fn, - (pthread_addr_t)(intptr_t)tidx); - TEST_ASSERT_EQUAL(OK, ret); - } - -/* Let workers to start. */ - - for (tidx = 0; tidx < nthreads; tidx++) - { - sem_wait(&tid_startsem); - } - - if (test_hang || !thread_funcs[type].stop_only_on_hang) - { - TEST_ASSERT_EQUAL(0, usrsocktest_daemon_pause_usrsock_handling(true)); - } - - for (tidx = 0; tidx < nthreads; tidx++) - { - sem_post(&tid_releasesem); - } - for (tidx = 0; tidx < nthreads; tidx++) - { - sem_wait(&tid_startsem); - } - - usleep(100 * USEC_PER_MSEC); /* Let worker thread proceed to blocking - * function. */ - - if (!test_abort) - { - /* Wake waiting thread with signal. */ - - /* Send signal to task to break out from blocking send. */ - - for (tidx = 0; tidx < nthreads; tidx++) - { - pthread_kill(tid[tidx], 1); - - /* Wait threads to complete work. */ - - ret = pthread_join(tid[tidx], NULL); - TEST_ASSERT_EQUAL(OK, ret); - tid[tidx] = -1; - } - TEST_ASSERT_FALSE(Unity.CurrentTestFailed); - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); - } - else - { - /* Wake waiting thread with daemon abort. */ - - /* Stopping daemon should succeed. */ - - TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop()); - TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt); - TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt); - - /* Wait threads to complete work. */ - - for (tidx = 0; tidx < nthreads; tidx++) - { - ret = pthread_join(tid[tidx], NULL); - TEST_ASSERT_EQUAL(OK, ret); - tid[tidx] = -1; - } - TEST_ASSERT_FALSE(Unity.CurrentTestFailed); - } -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -TEST_GROUP(WakeWithSignal); - -/**************************************************************************** - * Name: WakeWithSignal test group setup - * - * Description: - * Setup function executed before each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_SETUP(WakeWithSignal) -{ - int i; - - for (i = 0; i < MAX_THREADS; i++) - { - tid[i] = -1; - test_sd[i] = -1; - } - sem_init(&tid_startsem, 0, 0); - sem_init(&tid_releasesem, 0, 0); -} - -/**************************************************************************** - * Name: WakeWithSignal test group teardown - * - * Description: - * Setup function executed after each testcase in this test group - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST_TEAR_DOWN(WakeWithSignal) -{ - int ret; - int i; - - for (i = 0; i < MAX_THREADS; i++) - { - if (tid[i] != -1) - { - ret = pthread_cancel(tid[i]); - assert(ret == OK); - ret = pthread_join(tid[i], NULL); - assert(ret == OK); - } - if (test_sd[i] != -1) - { - close(test_sd[i]); - test_sd[i] = -1; - } - } - sem_destroy(&tid_startsem); - sem_destroy(&tid_releasesem); -} - -/**************************************************************************** - * Name: WakeBlockingConnect - * - * Description: - * Wake blocking connect with signal - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, WakeBlockingConnect) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = true; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_CONNECT, 0); -} - -/**************************************************************************** - * Name: WakeBlockingConnectMultiThread - * - * Description: - * Wake multiple blocking connect with signal - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, WakeBlockingConnectMultiThread) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = true; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_CONNECT, TEST_FLAG_MULTI_THREAD); -} - -/**************************************************************************** - * Name: WakeBlockingSend - * - * Description: - * Wake blocking send with signal - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, WakeBlockingSend) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = false; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_SEND, 0); -} - -/**************************************************************************** - * Name: WakeBlockingSendMultiThread - * - * Description: - * Wake multiple blocking send with signal - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, WakeBlockingSendMultiThread) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = false; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_SEND, TEST_FLAG_MULTI_THREAD); -} -/**************************************************************************** - * Name: WakeBlockingRecv - * - * Description: - * Wake blocking recv with signal - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, WakeBlockingRecv) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = false; - usrsocktest_daemon_config.endpoint_block_connect = false; - usrsocktest_daemon_config.endpoint_recv_avail = 0; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_RECV, 0); -} - -/**************************************************************************** - * Name: WakeBlockingRecvMultiThread - * - * Description: - * Wake multiple blocking recv with signal - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, WakeBlockingRecvMultiThread) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = false; - usrsocktest_daemon_config.endpoint_block_connect = false; - usrsocktest_daemon_config.endpoint_recv_avail = 0; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_RECV, TEST_FLAG_MULTI_THREAD); -} - -/**************************************************************************** - * Name: AbortBlockingConnect - * - * Description: - * Wake blocking connect with daemon abort - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, AbortBlockingConnect) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = true; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_CONNECT, TEST_FLAG_DAEMON_ABORT); -} - -/**************************************************************************** - * Name: AbortBlockingConnectMultiThread - * - * Description: - * Wake multiple blocking connect with daemon abort - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, AbortBlockingConnectMultiThread) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = true; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_CONNECT, - TEST_FLAG_DAEMON_ABORT | TEST_FLAG_MULTI_THREAD); -} - -/**************************************************************************** - * Name: AbortBlockingSend - * - * Description: - * Wake blocking send with daemon abort - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, AbortBlockingSend) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = false; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_SEND, TEST_FLAG_DAEMON_ABORT); -} - -/**************************************************************************** - * Name: AbortBlockingSendMultiThread - * - * Description: - * Wake multiple blocking send with daemon abort - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, AbortBlockingSendMultiThread) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = false; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_SEND, - TEST_FLAG_DAEMON_ABORT | TEST_FLAG_MULTI_THREAD); -} - -/**************************************************************************** - * Name: AbortBlockingRecv - * - * Description: - * Wake blocking recv with daemon abort - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, AbortBlockingRecv) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = false; - usrsocktest_daemon_config.endpoint_block_connect = false; - usrsocktest_daemon_config.endpoint_recv_avail = 0; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_RECV, TEST_FLAG_DAEMON_ABORT); -} - -/**************************************************************************** - * Name: AbortBlockingRecvMultiThread - * - * Description: - * Wake multiple blocking recv with daemon abort - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, AbortBlockingRecvMultiThread) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = false; - usrsocktest_daemon_config.endpoint_block_connect = false; - usrsocktest_daemon_config.endpoint_recv_avail = 0; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_RECV, - TEST_FLAG_DAEMON_ABORT | TEST_FLAG_MULTI_THREAD); -} - -/**************************************************************************** - * Name: PendingRequestBlockingConnect - * - * Description: - * Wake blocking connect with daemon abort (and daemon not handling pending - * request before abort) - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, PendingRequestBlockingConnect) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = true; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_CONNECT, - TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING); -} - -/**************************************************************************** - * Name: PendingRequestBlockingConnectMultiThread - * - * Description: - * Wake multiple blocking connect with daemon abort (and daemon not handling - * pending requests before abort) - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, PendingRequestBlockingConnectMultiThread) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = true; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_CONNECT, - TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING | - TEST_FLAG_MULTI_THREAD); -} - -/**************************************************************************** - * Name: PendingRequestBlockingSend - * - * Description: - * Wake blocking send with daemon abort (and daemon not handling pending - * request before abort) - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, PendingRequestBlockingSend) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = false; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_SEND, - TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING); -} - -/**************************************************************************** - * Name: PendingRequestBlockingSendMultiThread - * - * Description: - * Wake multiple blocking send with daemon abort (and daemon not handling - * pending requests before abort) - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, PendingRequestBlockingSendMultiThread) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = false; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_SEND, - TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING | - TEST_FLAG_MULTI_THREAD); -} - -/**************************************************************************** - * Name: PendingRequestBlockingRecv - * - * Description: - * Wake blocking recv with daemon abort (and daemon not handling pending - * request before abort) - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, PendingRequestBlockingRecv) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = false; - usrsocktest_daemon_config.endpoint_block_connect = false; - usrsocktest_daemon_config.endpoint_recv_avail = 0; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_RECV, - TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING); -} - -/**************************************************************************** - * Name: PendingRequestBlockingRecvMultiThread - * - * Description: - * Wake multiple blocking recv with daemon abort (and daemon not handling - * pending requests before abort) - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, PendingRequestBlockingRecvMultiThread) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = false; - usrsocktest_daemon_config.endpoint_block_connect = false; - usrsocktest_daemon_config.endpoint_recv_avail = 0; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_RECV, - TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING | - TEST_FLAG_MULTI_THREAD); -} - -/**************************************************************************** - * Name: PendingRequestBlockingOpen - * - * Description: - * Wake blocking open with daemon abort (and daemon not handling pending - * request before abort) - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, PendingRequestBlockingOpen) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = true; - usrsocktest_daemon_config.endpoint_recv_avail = 0; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_SOCKET, - TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING); -} - -/**************************************************************************** - * Name: PendingRequestBlockingOpenMultiThread - * - * Description: - * Wake multiple blocking open with daemon abort (and daemon not handling - * pending requests before abort) - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, PendingRequestBlockingOpenMultiThread) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = true; - usrsocktest_daemon_config.endpoint_recv_avail = 0; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_SOCKET, - TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING | - TEST_FLAG_MULTI_THREAD); -} - -/**************************************************************************** - * Name: PendingRequestBlockingClose - * - * Description: - * Wake blocking close with daemon abort (and daemon not handling pending - * request before abort) - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, PendingRequestBlockingClose) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = true; - usrsocktest_daemon_config.endpoint_recv_avail = 0; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_CLOSE, - TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING); -} - -/**************************************************************************** - * Name: PendingRequestBlockingCloseMultiThread - * - * Description: - * Wake multiple blocking close with daemon abort (and daemon not handling - * pending requests before abort) - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, PendingRequestBlockingCloseMultiThread) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = true; - usrsocktest_daemon_config.endpoint_recv_avail = 0; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_CLOSE, - TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING | - TEST_FLAG_MULTI_THREAD); -} - -/**************************************************************************** - * Name: PendingRequestBlockingPoll - * - * Description: - * Wake blocking poll with daemon abort (and daemon not handling pending - * request before abort) - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, PendingRequestBlockingPoll) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = false; - usrsocktest_daemon_config.endpoint_recv_avail = 0; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_POLL, - TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING); -} - -/**************************************************************************** - * Name: PendingRequestBlockingPollMultiThread - * - * Description: - * Wake multiple blocking poll with daemon abort (and daemon not handling - * pending requests before abort) - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, PendingRequestBlockingPollMultiThread) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = false; - usrsocktest_daemon_config.endpoint_recv_avail = 0; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_POLL, - TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING | - TEST_FLAG_MULTI_THREAD); -} - -/**************************************************************************** - * Name: PendingRequestBlockingSetSockOpt - * - * Description: - * Wake blocking setsockopt with daemon abort (and daemon not handling pending - * request before abort) - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, PendingRequestBlockingSetSockOpt) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = true; - usrsocktest_daemon_config.endpoint_recv_avail = 0; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_SETSOCKOPT, - TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING); -} - -/**************************************************************************** - * Name: PendingRequestBlockingSetSockOptMultiThread - * - * Description: - * Wake multiple blocking setsockopt with daemon abort (and daemon not - * handling pending requests before abort) - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, PendingRequestBlockingSetSockOptMultiThread) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = true; - usrsocktest_daemon_config.endpoint_recv_avail = 0; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_SETSOCKOPT, - TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING | - TEST_FLAG_MULTI_THREAD); -} - -/**************************************************************************** - * Name: PendingRequestBlockingGetSockOpt - * - * Description: - * Wake blocking getsockopt with daemon abort (and daemon not handling pending - * request before abort) - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, PendingRequestBlockingGetSockOpt) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = true; - usrsocktest_daemon_config.endpoint_recv_avail = 0; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_GETSOCKOPT, - TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING); -} - -/**************************************************************************** - * Name: PendingRequestBlockingGetSockOptMultiThread - * - * Description: - * Wake multiple blocking getsockopt with daemon abort (and daemon not - * handling pending requests before abort) - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - * Assumptions/Limitations: - * None - * - ****************************************************************************/ -TEST(WakeWithSignal, PendingRequestBlockingGetSockOptMultiThread) -{ - /* Configure test daemon. */ - - usrsocktest_daemon_config = usrsocktest_daemon_defconf; - usrsocktest_daemon_config.delay_all_responses = false; - usrsocktest_daemon_config.endpoint_block_send = true; - usrsocktest_daemon_config.endpoint_block_connect = true; - usrsocktest_daemon_config.endpoint_recv_avail = 0; - usrsocktest_daemon_config.endpoint_addr = "127.0.0.1"; - usrsocktest_daemon_config.endpoint_port = 255; - - /* Run test. */ - - do_wake_test(TEST_TYPE_GETSOCKOPT, - TEST_FLAG_DAEMON_ABORT | TEST_FLAG_PAUSE_USRSOCK_HANDLING | - TEST_FLAG_MULTI_THREAD); -}