summaryrefslogtreecommitdiffstats
path: root/testsuites/unit
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--testsuites/unit/tc-base64-decode.c186
-rw-r--r--testsuites/unit/tc-compiler-builtins.c1141
-rw-r--r--testsuites/unit/tc-config.c171
-rw-r--r--testsuites/unit/tc-crc.c48
-rw-r--r--testsuites/unit/tc-misaligned-builtin-memcpy.c57
-rw-r--r--testsuites/unit/tc-score-msgq.c452
-rw-r--r--testsuites/unit/tc-score-rbtree.c1195
-rw-r--r--testsuites/unit/ts-unit-no-clock-0.c80
8 files changed, 3330 insertions, 0 deletions
diff --git a/testsuites/unit/tc-base64-decode.c b/testsuites/unit/tc-base64-decode.c
new file mode 100644
index 0000000000..4b0672d310
--- /dev/null
+++ b/testsuites/unit/tc-base64-decode.c
@@ -0,0 +1,186 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesUnitNoClock0
+ */
+
+/*
+ * Copyright (C) 2023 embedded brains GmbH & Co. KG
+ *
+ * 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.
+ *
+ * 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 <rtems/base64.h>
+
+#include <rtems/test.h>
+
+typedef struct {
+ Base64_Decode_control base;
+ uint8_t buf[64];
+} test_control;
+
+static int test_run(test_control* self, const char* payload) {
+ size_t len = strlen(payload);
+
+ for (size_t i = 0; i < len; ++i) {
+ int rv = _Base64_Decode(&self->base, payload[i]);
+
+ if (rv != 0) {
+ return rv;
+ }
+ }
+
+ return 0;
+}
+
+static int test_payload(test_control* self, const char* payload) {
+ memset(self->buf, 0xff, sizeof(self->buf));
+ _Base64_Decode_initialize(&self->base, &self->buf[0], sizeof(self->buf));
+ return test_run(self, payload);
+}
+
+T_TEST_CASE(IOBase64Decode) {
+ int rv;
+ test_control instance;
+ test_control* self = &instance;
+
+ rv = test_payload(self, "POOL");
+ T_eq_int(rv, BASE64_DECODE_SUCCESS);
+ T_eq_int(self->base.state, BASE64_DECODE_STATE_0);
+ T_eq_ptr(self->base.target, &self->buf[3]);
+ const uint8_t expected1[] = {0x3c, 0xe3, 0x8b, 0xff};
+ T_eq_mem(&self->buf[0], expected1, sizeof(expected1));
+
+ rv = test_payload(self, "ABCDEFGH");
+ T_eq_int(rv, BASE64_DECODE_SUCCESS);
+ T_eq_int(self->base.state, BASE64_DECODE_STATE_0);
+ T_eq_ptr(self->base.target, &self->buf[6]);
+ const uint8_t expected2[] = {0x00, 0x10, 0x83, 0x10, 0x51, 0x87, 0xff};
+ T_eq_mem(&self->buf[0], expected2, sizeof(expected2));
+
+ /* Non-base64 character results in an error */
+ rv = test_payload(self, "PO*OL");
+ T_eq_int(rv, BASE64_DECODE_INVALID_INPUT);
+ T_eq_int(self->base.state, BASE64_DECODE_STATE_2);
+ T_eq_ptr(self->base.target, &self->buf[1]);
+ const uint8_t expected3[] = {0x3c};
+ T_eq_mem(&self->buf[0], expected3, sizeof(expected3));
+
+ /* Other non-base64 character results in an error */
+ rv = test_payload(self, "PO\x80OL");
+ T_eq_int(rv, BASE64_DECODE_INVALID_INPUT);
+ T_eq_int(self->base.state, BASE64_DECODE_STATE_2);
+ T_eq_ptr(self->base.target, &self->buf[1]);
+ T_eq_mem(&self->buf[0], expected3, sizeof(expected3));
+
+ /* Space characters should be ignored */
+ rv = test_payload(self, "P OOL");
+ T_eq_int(rv, BASE64_DECODE_SUCCESS);
+ T_eq_int(self->base.state, BASE64_DECODE_STATE_0);
+ T_eq_ptr(self->base.target, &self->buf[3]);
+ const uint8_t expected4[] = {0x3c, 0xe3, 0x8b, 0xff};
+ T_eq_mem(&self->buf[0], expected4, sizeof(expected4));
+
+ /* Handle pad characters */
+ rv = test_payload(self, "POOL==");
+ T_eq_int(rv, BASE64_DECODE_SUCCESS);
+ T_eq_int(self->base.state, BASE64_DECODE_STATE_0);
+ T_eq_ptr(self->base.target, &self->buf[3]);
+ T_eq_ptr(self->base.target, self->base.target_end);
+ const uint8_t expected5[] = {0x3c, 0xe3, 0x8b, 0xff};
+ T_eq_mem(&self->buf[0], expected5, sizeof(expected5));
+
+ /* If characters come after pad characters, an error results */
+ rv = test_payload(self, "POOL==xy");
+ T_eq_int(rv, BASE64_DECODE_OVERFLOW);
+ T_eq_int(self->base.state, BASE64_DECODE_SUCCESS);
+ T_eq_ptr(self->base.target, &self->buf[3]);
+ T_eq_ptr(self->base.target, self->base.target_end);
+ const uint8_t expected6[] = {0x3c, 0xe3, 0x8b, 0xff};
+ T_eq_mem(&self->buf[0], expected6, sizeof(expected6));
+
+ rv = test_payload(self, "POOLPOOL");
+ T_eq_int(rv, BASE64_DECODE_SUCCESS);
+ T_eq_int(self->base.state, BASE64_DECODE_STATE_0);
+ T_eq_ptr(self->base.target, &self->buf[6]);
+ const uint8_t expected7[] = {0x3c, 0xe3, 0x8b, 0x3c, 0xe3, 0x8b, 0xff};
+ T_eq_mem(&self->buf[0], expected7, sizeof(expected7));
+
+ /*
+ * Test valid payload with series of target sizes. All target sizes
+ * less than three are invalid for the given payload and will result
+ * in an error.
+ */
+ const uint8_t expected9[] = {0x3c, 0xe3, 0x8b, 0xff};
+
+ for (size_t i = 0; i < 4; ++i) {
+ memset(&self->buf[0], 0xff, sizeof(self->buf));
+ _Base64_Decode_initialize(&self->base, &self->buf[0], i);
+ rv = test_run(self, "POOL");
+
+ if (i < 3) {
+ T_eq_int(rv, BASE64_DECODE_OVERFLOW);
+ T_eq_int(self->base.state, i);
+ T_ne_ptr(self->base.target, &self->buf[3]);
+ T_ne_mem(&self->buf[0], expected9, sizeof(expected9));
+ } else {
+ T_eq_int(rv, BASE64_DECODE_SUCCESS);
+ T_eq_int(self->base.state, BASE64_DECODE_STATE_0);
+ T_eq_ptr(self->base.target, &self->buf[3]);
+ T_eq_mem(&self->buf[0], expected9, sizeof(expected9));
+ }
+ }
+
+ /* No overflow in state 1 */
+ memset(&self->buf[0], 0xff, sizeof(self->buf));
+ _Base64_Decode_initialize(&self->base, &self->buf[0], 1);
+ rv = test_run(self, "AA");
+ T_eq_int(rv, BASE64_DECODE_SUCCESS);
+ T_eq_int(self->base.state, BASE64_DECODE_STATE_2);
+ T_eq_ptr(self->base.target, &self->buf[1]);
+ const uint8_t expected10[] = {0x00, 0xff};
+ T_eq_mem(&self->buf[0], expected10, sizeof(expected10));
+
+ /* No overflow in state 2 */
+ memset(&self->buf[0], 0xff, sizeof(self->buf));
+ _Base64_Decode_initialize(&self->base, &self->buf[0], 2);
+ rv = test_run(self, "AAA");
+ T_eq_int(rv, BASE64_DECODE_SUCCESS);
+ T_eq_int(self->base.state, BASE64_DECODE_STATE_3);
+ T_eq_ptr(self->base.target, &self->buf[2]);
+ const uint8_t expected11[] = {0x00, 0x00, 0xff};
+ T_eq_mem(&self->buf[0], expected11, sizeof(expected11));
+}
+
+T_TEST_CASE(IOBase64DecodeInitialize) {
+ Base64_Decode_control instance;
+ Base64_Decode_control* self = &instance;
+ uint8_t buf[1];
+
+ memset(self, 0xff, sizeof(*self));
+ _Base64_Decode_initialize(self, buf, sizeof(buf));
+ T_eq_int(self->state, BASE64_DECODE_STATE_0);
+ T_eq_ptr(self->target, &buf[0]);
+ T_eq_ptr(self->target_end, &buf[1]);
+}
diff --git a/testsuites/unit/tc-compiler-builtins.c b/testsuites/unit/tc-compiler-builtins.c
new file mode 100644
index 0000000000..7a470b6632
--- /dev/null
+++ b/testsuites/unit/tc-compiler-builtins.c
@@ -0,0 +1,1141 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup CompilerUnitBuiltins
+ */
+
+/*
+ * Copyright (C) 2023 embedded brains GmbH & Co. KG
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <setjmp.h>
+#include <stdint.h>
+
+#include "../validation/tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup CompilerUnitBuiltins spec:/compiler/unit/builtins
+ *
+ * @ingroup TestsuitesUnitNoClock0
+ *
+ * @brief These unit tests check compiler builtins.
+ *
+ * Explicitly test the 64-bit integer division and modulo operations. They are
+ * essential for the timekeeping services. On most 32-bit targets, they need a
+ * software implementation.
+ *
+ * This test case performs the following actions:
+ *
+ * - Check the return value of __builtin_clz() for a sample set of inputs.
+ *
+ * - Check the return value of __builtin_clzll() for a sample set of inputs.
+ *
+ * - Check the return value of __builtin_ctz() for a sample set of inputs.
+ *
+ * - Check the return value of __builtin_ctzll() for a sample set of inputs.
+ *
+ * - Check the return value of __builtin_ffs() for a sample set of inputs.
+ *
+ * - Check the return value of __builtin_ffsll() for a sample set of inputs.
+ *
+ * - Check the return value of __builtin_parity() for a sample set of inputs.
+ *
+ * - Check the return value of __builtin_parityll() for a sample set of inputs.
+ *
+ * - Check the return value of __builtin_popcount() for a sample set of inputs.
+ *
+ * - Check the return value of __builtin_popcountll() for a sample set of
+ * inputs.
+ *
+ * - Check the return value of __builtin_bswap32() for a sample set of inputs.
+ *
+ * - Check the return value of __builtin_bswap64() for a sample set of inputs.
+ *
+ * - Check signed 64-bit comparisons for a sample set of values.
+ *
+ * - Check unsigned 64-bit comparisons for a sample set of values.
+ *
+ * - Check signed 64-bit arithmetic left shift for a sample set of values.
+ *
+ * - Check signed 64-bit arithmetic right shift for a sample set of values.
+ *
+ * - Check unsigned 64-bit logical right shift for a sample set of values.
+ *
+ * - Check signed 64-bit multiplication for a sample set of values.
+ *
+ * - Check signed 64-bit negation for a sample set of values.
+ *
+ * - Check signed 64-bit divisions for a sample set of values.
+ *
+ * - Check unsigned 64-bit divisions for a sample set of values.
+ *
+ * - Check signed 64-bit modulo operations for a sample set of values.
+ *
+ * - Check unsigned 64-bit modulo operations for a sample set of values.
+ *
+ * @{
+ */
+
+#if __LONG_MAX__ == 0x7fffffffL && !defined(__aarch64__)
+#define TEST_UDIVMODDI4
+#endif
+
+#if defined(TEST_UDIVMODDI4)
+uint64_t __udivmoddi4( uint64_t n, uint64_t d, uint64_t *r );
+#endif
+
+#if defined(TEST_UDIVMODDI4) && defined(__arm__)
+/*
+ * Here __aeabi_uldivmod() may be used to carry out integer division
+ * operations even though the reminder is unused. This function is
+ * implemented by __udivmoddi4() which may never get called without a
+ * reminder for compiler generated code.
+ */
+#define TEST_UDIVMODDI4_WITHOUT_REMINDER
+#endif
+
+static bool do_longjmp;
+
+static jmp_buf exception_return_context;
+
+static void Fatal(
+ rtems_fatal_source source,
+ rtems_fatal_code code,
+ void *arg
+)
+{
+ (void) code;
+
+ if ( source == RTEMS_FATAL_SOURCE_EXCEPTION && do_longjmp ) {
+ do_longjmp = false;
+ _ISR_Set_level( 0 );
+ longjmp( arg, 1 );
+ }
+}
+
+static void CompilerUnitBuiltins_Setup( void *ctx )
+{
+ SetFatalHandler( Fatal, exception_return_context );
+}
+
+static void CompilerUnitBuiltins_Teardown( void *ctx )
+{
+ SetFatalHandler( NULL, NULL );
+}
+
+static T_fixture CompilerUnitBuiltins_Fixture = {
+ .setup = CompilerUnitBuiltins_Setup,
+ .stop = NULL,
+ .teardown = CompilerUnitBuiltins_Teardown,
+ .scope = NULL,
+ .initial_context = NULL
+};
+
+/**
+ * @brief Check the return value of __builtin_clz() for a sample set of inputs.
+ */
+static void CompilerUnitBuiltins_Action_0( void )
+{
+ volatile unsigned int n;
+
+ n = 0;
+ RTEMS_OBFUSCATE_VARIABLE( n );
+
+ n = 1U;
+ T_eq_int( __builtin_clz( n ), 31 );
+
+ n = 1U << 31;
+ T_eq_int( __builtin_clz( n ), 0 );
+
+ n = ~0U;
+ T_eq_int( __builtin_clz( n ), 0 );
+}
+
+/**
+ * @brief Check the return value of __builtin_clzll() for a sample set of
+ * inputs.
+ */
+static void CompilerUnitBuiltins_Action_1( void )
+{
+ volatile unsigned long long n;
+
+ n = 0;
+ RTEMS_OBFUSCATE_VARIABLE( n );
+
+ n = 1ULL;
+ T_eq_int( __builtin_clzll( n ), 63 );
+
+ n = 1ULL << 31;
+ T_eq_int( __builtin_clzll( n ), 32 );
+
+ n = 1ULL << 32;
+ T_eq_int( __builtin_clzll( n ), 31 );
+
+ n = 1ULL << 63;
+ T_eq_int( __builtin_clzll( n ), 0 );
+
+ n = ~0ULL;
+ T_eq_int( __builtin_clzll( n ), 0 );
+}
+
+/**
+ * @brief Check the return value of __builtin_ctz() for a sample set of inputs.
+ */
+static void CompilerUnitBuiltins_Action_2( void )
+{
+ volatile unsigned int n;
+
+ n = 0;
+ RTEMS_OBFUSCATE_VARIABLE( n );
+
+ n = 1U;
+ T_eq_int( __builtin_ctz( n ), 0 );
+
+ n = 1U << 31;
+ T_eq_int( __builtin_ctz( n ), 31 );
+
+ n = ~0U;
+ T_eq_int( __builtin_ctz( n ), 0 );
+}
+
+/**
+ * @brief Check the return value of __builtin_ctzll() for a sample set of
+ * inputs.
+ */
+static void CompilerUnitBuiltins_Action_3( void )
+{
+ volatile unsigned long long n;
+
+ n = 0;
+ RTEMS_OBFUSCATE_VARIABLE( n );
+
+ n = 1ULL;
+ T_eq_int( __builtin_ctzll( n ), 0 );
+
+ n = 1ULL << 31;
+ T_eq_int( __builtin_ctzll( n ), 31 );
+
+ n = 1ULL << 32;
+ T_eq_int( __builtin_ctzll( n ), 32 );
+
+ n = 1ULL << 63;
+ T_eq_int( __builtin_ctzll( n ), 63 );
+
+ n = ~0ULL;
+ T_eq_int( __builtin_ctzll( n ), 0 );
+}
+
+/**
+ * @brief Check the return value of __builtin_ffs() for a sample set of inputs.
+ */
+static void CompilerUnitBuiltins_Action_4( void )
+{
+ volatile unsigned int n;
+
+ n = 0;
+ RTEMS_OBFUSCATE_VARIABLE( n );
+
+ n = 1U;
+ T_eq_int( __builtin_ffs( n ), 1 );
+
+ n = 1U << 31;
+ T_eq_int( __builtin_ffs( n ), 32 );
+
+ n = 0U;
+ T_eq_int( __builtin_ffs( n ), 0 );
+}
+
+/**
+ * @brief Check the return value of __builtin_ffsll() for a sample set of
+ * inputs.
+ */
+static void CompilerUnitBuiltins_Action_5( void )
+{
+ volatile unsigned long long n;
+
+ n = 0;
+ RTEMS_OBFUSCATE_VARIABLE( n );
+
+ n = 1ULL;
+ T_eq_int( __builtin_ffsll( n ), 1 );
+
+ n = 1ULL << 31;
+ T_eq_int( __builtin_ffsll( n ), 32 );
+
+ n = 1ULL << 32;
+ T_eq_int( __builtin_ffsll( n ), 33 );
+
+ n = 1ULL << 63;
+ T_eq_int( __builtin_ffsll( n ), 64 );
+
+ n = 0ULL;
+ T_eq_int( __builtin_ffsll( n ), 0 );
+}
+
+/**
+ * @brief Check the return value of __builtin_parity() for a sample set of
+ * inputs.
+ */
+static void CompilerUnitBuiltins_Action_6( void )
+{
+ volatile unsigned int n;
+
+ n = 0;
+ RTEMS_OBFUSCATE_VARIABLE( n );
+
+ n = 1U;
+ T_eq_int( __builtin_parity( n ), 1 );
+
+ n = ~0U;
+ T_eq_int( __builtin_parity( n ), 0 );
+}
+
+/**
+ * @brief Check the return value of __builtin_parityll() for a sample set of
+ * inputs.
+ */
+static void CompilerUnitBuiltins_Action_7( void )
+{
+ volatile unsigned long long n;
+
+ n = 0;
+ RTEMS_OBFUSCATE_VARIABLE( n );
+
+ n = 1ULL;
+ T_eq_int( __builtin_parityll( n ), 1 );
+
+ n = ~0ULL;
+ T_eq_int( __builtin_parityll( n ), 0 );
+}
+
+/**
+ * @brief Check the return value of __builtin_popcount() for a sample set of
+ * inputs.
+ */
+static void CompilerUnitBuiltins_Action_8( void )
+{
+ volatile unsigned int n;
+
+ n = 0;
+ RTEMS_OBFUSCATE_VARIABLE( n );
+
+ n = 0U;
+ T_eq_int( __builtin_popcount( n ), 0 );
+
+ n = 1U;
+ T_eq_int( __builtin_popcount( n ), 1 );
+
+ n = ~0U;
+ T_eq_int( __builtin_popcount( n ), 32 );
+}
+
+/**
+ * @brief Check the return value of __builtin_popcountll() for a sample set of
+ * inputs.
+ */
+static void CompilerUnitBuiltins_Action_9( void )
+{
+ volatile unsigned long long n;
+
+ n = 0;
+ RTEMS_OBFUSCATE_VARIABLE( n );
+
+ n = 0ULL;
+ T_eq_int( __builtin_popcountll( n ), 0 );
+
+ n = 1ULL;
+ T_eq_int( __builtin_popcountll( n ), 1 );
+
+ n = ~0ULL;
+ T_eq_int( __builtin_popcountll( n ), 64 );
+}
+
+/**
+ * @brief Check the return value of __builtin_bswap32() for a sample set of
+ * inputs.
+ */
+static void CompilerUnitBuiltins_Action_10( void )
+{
+ volatile uint32_t n;
+
+ n = 0;
+ RTEMS_OBFUSCATE_VARIABLE( n );
+
+ n = UINT32_C( 0 );
+ T_eq_u32( __builtin_bswap32( n ), n );
+
+ n = UINT32_C( 1 );
+ T_eq_u32( __builtin_bswap32( n ), n << 24 );
+
+ n = UINT32_C( 0x12345678 );
+ T_eq_u32( __builtin_bswap32( n ), UINT32_C( 0x78563412 ) );
+
+ n = ~UINT32_C( 0 );
+ T_eq_u32( __builtin_bswap32( n ), n );
+}
+
+/**
+ * @brief Check the return value of __builtin_bswap64() for a sample set of
+ * inputs.
+ */
+static void CompilerUnitBuiltins_Action_11( void )
+{
+ volatile uint64_t n;
+
+ n = 0;
+ RTEMS_OBFUSCATE_VARIABLE( n );
+
+ n = UINT64_C( 0 );
+ T_eq_u64( __builtin_bswap64( n ), n );
+
+ n = UINT64_C( 1 );
+ T_eq_u64( __builtin_bswap64( n ), n << 56 );
+
+ n = UINT64_C( 0x123456789abcdef0 );
+ T_eq_u64( __builtin_bswap64( n ), UINT64_C( 0xf0debc9a78563412 ) );
+
+ n = ~UINT64_C( 0 );
+ T_eq_u64( __builtin_bswap64( n ), n );
+}
+
+/**
+ * @brief Check signed 64-bit comparisons for a sample set of values.
+ */
+static void CompilerUnitBuiltins_Action_12( void )
+{
+ volatile int64_t a;
+ volatile int64_t b;
+
+ a = 0;
+ RTEMS_OBFUSCATE_VARIABLE( a );
+ b = 0;
+ RTEMS_OBFUSCATE_VARIABLE( b );
+
+ a = INT64_C( 0 );
+ b = INT64_C( 0 );
+ T_false( a < b );
+
+ a = INT64_C( 0 );
+ b = INT64_C( 1 );
+ T_true( a < b );
+
+ a = INT64_C( 0x123456789abcdef0 );
+ b = INT64_C( 0xf0debc9a78563412 );
+ T_false( a < b );
+
+ a = INT64_C( 0xf0debc9a78563412 );
+ b = INT64_C( 0x123456789abcdef0 );
+ T_true( a < b );
+}
+
+/**
+ * @brief Check unsigned 64-bit comparisons for a sample set of values.
+ */
+static void CompilerUnitBuiltins_Action_13( void )
+{
+ volatile uint64_t a;
+ volatile uint64_t b;
+
+ a = 0;
+ RTEMS_OBFUSCATE_VARIABLE( a );
+ b = 0;
+ RTEMS_OBFUSCATE_VARIABLE( b );
+
+ a = UINT64_C( 0 );
+ b = UINT64_C( 0 );
+ T_false( a < b );
+
+ a = UINT64_C( 0 );
+ b = UINT64_C( 1 );
+ T_true( a < b );
+
+ a = UINT64_C( 0x123456789abcdef0 );
+ b = UINT64_C( 0xf0debc9a78563412 );
+ T_true( a < b );
+
+ a = UINT64_C( 0xf0debc9a78563412 );
+ b = UINT64_C( 0x123456789abcdef0 );
+ T_false( a < b );
+}
+
+/**
+ * @brief Check signed 64-bit arithmetic left shift for a sample set of values.
+ */
+static void CompilerUnitBuiltins_Action_14( void )
+{
+ volatile int64_t i;
+ volatile int s;
+
+ i = 0;
+ RTEMS_OBFUSCATE_VARIABLE( i );
+ s = 0;
+ RTEMS_OBFUSCATE_VARIABLE( s );
+
+ i = INT64_C( 1 );
+ s = 0;
+ T_eq_i64( i << s, INT64_C( 1 ) );
+
+ i = -INT64_C( 1 );
+ s = 0;
+ T_eq_i64( i << s, -INT64_C( 1 ) );
+
+ i = INT64_C( 1 );
+ s = 1;
+ T_eq_i64( i << s, INT64_C( 2 ) );
+
+ i = -INT64_C( 1 );
+ s = 1;
+ T_eq_i64( i << s, -INT64_C( 2 ) );
+}
+
+/**
+ * @brief Check signed 64-bit arithmetic right shift for a sample set of
+ * values.
+ */
+static void CompilerUnitBuiltins_Action_15( void )
+{
+ volatile int64_t i;
+ volatile int s;
+
+ i = 0;
+ RTEMS_OBFUSCATE_VARIABLE( i );
+ s = 0;
+ RTEMS_OBFUSCATE_VARIABLE( s );
+
+ i = INT64_C( 1 );
+ s = 0;
+ T_eq_i64( i >> s, INT64_C( 1 ) );
+
+ i = -INT64_C( 1 );
+ s = 0;
+ T_eq_i64( i >> s, -INT64_C( 1 ) );
+
+ i = INT64_C( 2 );
+ s = 1;
+ T_eq_i64( i >> s, INT64_C( 1 ) );
+
+ i = -INT64_C( 2 );
+ s = 1;
+ T_eq_i64( i >> s, -INT64_C( 1 ) );
+}
+
+/**
+ * @brief Check unsigned 64-bit logical right shift for a sample set of values.
+ */
+static void CompilerUnitBuiltins_Action_16( void )
+{
+ volatile uint64_t i;
+ volatile int s;
+
+ i = 0;
+ RTEMS_OBFUSCATE_VARIABLE( i );
+ s = 0;
+ RTEMS_OBFUSCATE_VARIABLE( s );
+
+ i = UINT64_C( 1 );
+ s = 0;
+ T_eq_u64( i >> s, UINT64_C( 1 ) );
+
+ i = -UINT64_C( 1 );
+ s = 0;
+ T_eq_u64( i >> s, UINT64_C( 0xffffffffffffffff ) );
+
+ i = UINT64_C( 2 );
+ s = 1;
+ T_eq_u64( i >> s, UINT64_C( 1 ) );
+
+ i = -UINT64_C( 2 );
+ s = 1;
+ T_eq_u64( i >> s, UINT64_C( 0x7fffffffffffffff ) );
+}
+
+/**
+ * @brief Check signed 64-bit multiplication for a sample set of values.
+ */
+static void CompilerUnitBuiltins_Action_17( void )
+{
+ volatile int64_t a;
+ volatile int64_t b;
+
+ a = 0;
+ RTEMS_OBFUSCATE_VARIABLE( a );
+ b = 0;
+ RTEMS_OBFUSCATE_VARIABLE( b );
+
+ a = INT64_C( 1 );
+ b = INT64_C( 1 );
+ T_eq_i64( a * b, INT64_C( 1 ) );
+
+ a = INT64_C( 1 );
+ b = INT64_C( 0 );
+ T_eq_i64( a * b, INT64_C( 0 ) );
+
+ a = INT64_C( 0 );
+ b = INT64_C( 1 );
+ T_eq_i64( a * b, INT64_C( 0 ) );
+}
+
+/**
+ * @brief Check signed 64-bit negation for a sample set of values.
+ */
+static void CompilerUnitBuiltins_Action_18( void )
+{
+ volatile int64_t i;
+
+ i = 0;
+ RTEMS_OBFUSCATE_VARIABLE( i );
+
+ i = INT64_C( 1 );
+ T_eq_i64( -i, -INT64_C( 1 ) );
+
+ i = -INT64_C( 1 );
+ T_eq_i64( -i, INT64_C( 1 ) );
+}
+
+/**
+ * @brief Check signed 64-bit divisions for a sample set of values.
+ */
+static void CompilerUnitBuiltins_Action_19( void )
+{
+ volatile int64_t n;
+ volatile int64_t d;
+ volatile int64_t x;
+
+ n = 0;
+ RTEMS_OBFUSCATE_VARIABLE( n );
+ d = 0;
+ RTEMS_OBFUSCATE_VARIABLE( d );
+ x = 0;
+ RTEMS_OBFUSCATE_VARIABLE( x );
+
+ n = INT64_C( 0 );
+ d = INT64_C( 0 );
+ do_longjmp = true;
+
+ if ( setjmp( exception_return_context ) == 0 ) {
+ x = n / d;
+ }
+
+ n = INT64_C( 1 );
+ d = INT64_C( 0 );
+ do_longjmp = true;
+
+ if ( setjmp( exception_return_context ) == 0 ) {
+ x = n / d;
+ }
+
+ n = INT64_C( 0x7fffffffffffffff );
+ d = INT64_C( 0 );
+ do_longjmp = true;
+
+ if ( setjmp( exception_return_context ) == 0 ) {
+ x = n / d;
+ }
+
+ n = INT64_C( 0x7fffffff00000000 );
+ d = INT64_C( 0 );
+ do_longjmp = true;
+
+ if ( setjmp( exception_return_context ) == 0 ) {
+ x = n / d;
+ }
+
+ n = INT64_C( 0 );
+ d = INT64_C( 1 );
+ T_eq_i64( n / d, INT64_C( 0 ) );
+
+ n = INT64_C( 1 );
+ d = INT64_C( 1 );
+ T_eq_i64( n / d, INT64_C( 1 ) );
+
+ n = INT64_C( 0x7fffffffffffffff );
+ d = INT64_C( 1 );
+ T_eq_i64( n / d, INT64_C( 9223372036854775807 ) );
+
+ n = INT64_C( 2 );
+ d = INT64_C( 1 );
+ T_eq_i64( n / d, INT64_C( 2 ) );
+
+ n = INT64_C( 2 );
+ d = INT64_C( 1 );
+ T_eq_i64( n / d, INT64_C( 2 ) );
+
+ n = INT64_C( 1 );
+ d = INT64_C( 0x7fffffffffffffff );
+ T_eq_i64( n / d, INT64_C( 0 ) );
+
+ n = INT64_C( 0x7fffffffffffffff );
+ d = INT64_C( 0x7fffffffffffffff );
+ T_eq_i64( n / d, INT64_C( 1 ) );
+
+ n = INT64_C( 1 );
+ d = INT64_C( 0x7fffffff00000000 );
+ T_eq_i64( n / d, INT64_C( 0 ) );
+
+ n = INT64_C( 0x7fffffff00000000 );
+ d = INT64_C( 0x7fffffff00000000 );
+ T_eq_i64( n / d, INT64_C( 1 ) );
+
+ n = INT64_C( 0x7fffffffffffffff );
+ d = INT64_C( 0x7fffffff00000000 );
+ T_eq_i64( n / d, INT64_C( 1 ) );
+
+ n = INT64_C( 0x7fffffffffffffff );
+ d = INT64_C( 0x8000000000000000 );
+ T_eq_i64( n / d, INT64_C( 0 ) );
+
+ n = INT64_C( 0x7fffffffffffffff );
+ d = INT64_C( 0x0000000080000000 );
+ T_eq_i64( n / d, INT64_C( 0xffffffff ) );
+
+ n = INT64_C( 0x7fffffffffffffff );
+ d = INT64_C( 0x00000000f0000000 );
+ T_eq_i64( n / d, INT64_C( 2290649224 ) );
+
+ n = INT64_C( 0x00000001ffffffff );
+ d = INT64_C( 0x00000000f0000000 );
+ T_eq_i64( n / d, INT64_C( 2 ) );
+
+ n = INT64_C( 0x0000000fffffffff );
+ d = INT64_C( 0x000000000000000f );
+ T_eq_i64( n / d, INT64_C( 4581298449 ) );
+
+ n = INT64_C( 0x0000000100000001 );
+ d = INT64_C( 0x0000000f00000000 );
+ T_eq_i64( n / d, INT64_C( 0 ) );
+
+ n = INT64_C( 0x0000000f0000000f );
+ d = INT64_C( 0x000000ff0000000f );
+ T_eq_i64( n / d, INT64_C( 0 ) );
+}
+
+/**
+ * @brief Check unsigned 64-bit divisions for a sample set of values.
+ */
+static void CompilerUnitBuiltins_Action_20( void )
+{
+ volatile uint64_t n;
+ volatile uint64_t d;
+ volatile uint64_t x;
+
+ n = 0;
+ RTEMS_OBFUSCATE_VARIABLE( n );
+ d = 0;
+ RTEMS_OBFUSCATE_VARIABLE( d );
+ x = 0;
+ RTEMS_OBFUSCATE_VARIABLE( x );
+
+ n = UINT64_C( 0 );
+ d = UINT64_C( 0 );
+ do_longjmp = true;
+
+ if ( setjmp( exception_return_context ) == 0 ) {
+ x = n / d;
+ }
+
+ #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER)
+ do_longjmp = true;
+
+ if ( setjmp( exception_return_context ) == 0 ) {
+ __udivmoddi4( n, d, NULL );
+ }
+ #endif
+
+ n = UINT64_C( 1 );
+ d = UINT64_C( 0 );
+ do_longjmp = true;
+
+ if ( setjmp( exception_return_context ) == 0 ) {
+ x = n / d;
+ }
+
+ #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER)
+ do_longjmp = true;
+
+ if ( setjmp( exception_return_context ) == 0 ) {
+ __udivmoddi4( n, d, NULL );
+ }
+ #endif
+
+ n = UINT64_C( 0x7fffffffffffffff );
+ d = UINT64_C( 0 );
+ do_longjmp = true;
+
+ if ( setjmp( exception_return_context ) == 0 ) {
+ x = n / d;
+ }
+
+ #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER)
+ do_longjmp = true;
+
+ if ( setjmp( exception_return_context ) == 0 ) {
+ __udivmoddi4( n, d, NULL );
+ }
+ #endif
+
+ n = UINT64_C( 0x7fffffff00000000 );
+ d = UINT64_C( 0 );
+ do_longjmp = true;
+
+ if ( setjmp( exception_return_context ) == 0 ) {
+ x = n / d;
+ }
+
+ #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER)
+ do_longjmp = true;
+
+ if ( setjmp( exception_return_context ) == 0 ) {
+ __udivmoddi4( n, d, NULL );
+ }
+ #endif
+
+ n = UINT64_C( 0x7fffffff00000000 );
+ d = UINT64_C( 0x7fffffff00000000 );
+ do_longjmp = true;
+
+ if ( setjmp( exception_return_context ) == 0 ) {
+ x = n / d;
+ }
+
+ #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER)
+ do_longjmp = true;
+
+ if ( setjmp( exception_return_context ) == 0 ) {
+ __udivmoddi4( n, d, NULL );
+ }
+ #endif
+
+ n = UINT64_C( 0 );
+ d = UINT64_C( 1 );
+ T_eq_u64( n / d, UINT64_C( 0 ) );
+ #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER)
+ T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 0 ) );
+ #endif
+
+ n = UINT64_C( 1 );
+ d = UINT64_C( 1 );
+ T_eq_u64( n / d, UINT64_C( 1 ) );
+ #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER)
+ T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 1 ) );
+ #endif
+
+ n = UINT64_C( 0xffffffffffffffff );
+ d = UINT64_C( 1 );
+ T_eq_u64( n / d, UINT64_C( 0xffffffffffffffff ) );
+ #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER)
+ T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 0xffffffffffffffff ) );
+ #endif
+
+ n = UINT64_C( 2 );
+ d = UINT64_C( 1 );
+ T_eq_u64( n / d, UINT64_C( 2 ) );
+ #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER)
+ T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 2 ) );
+ #endif
+
+ n = UINT64_C( 1 );
+ d = UINT64_C( 0xffffffffffffffff );
+ T_eq_u64( n / d, UINT64_C( 0 ) );
+ #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER)
+ T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 0 ) );
+ #endif
+
+ n = UINT64_C( 0xffffffffffffffff );
+ d = UINT64_C( 0xffffffffffffffff );
+ T_eq_u64( n / d, UINT64_C( 1 ) );
+ #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER)
+ T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 1 ) );
+ #endif
+
+ n = UINT64_C( 0xffffffffffffffff );
+ d = UINT64_C( 0x8000000000000000 );
+ T_eq_u64( n / d, UINT64_C( 1 ) );
+ #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER)
+ T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 1 ) );
+ #endif
+
+ n = UINT64_C( 0x0000000100000001 );
+ d = UINT64_C( 0x0000000f00000000 );
+ T_eq_u64( n / d, UINT64_C( 0 ) );
+ #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER)
+ T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 0 ) );
+ #endif
+
+ n = UINT64_C( 0x0000000100000000 );
+ d = UINT64_C( 0x0000000f00000001 );
+ T_eq_u64( n / d, UINT64_C( 0 ) );
+ #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER)
+ T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 0 ) );
+ #endif
+
+ n = UINT64_C( 0xffffffff0000000f );
+ d = UINT64_C( 0x000000010000000f );
+ T_eq_u64( n / d, UINT64_C( 4294967280 ) );
+ #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER)
+ T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 4294967280 ) );
+ #endif
+}
+
+/**
+ * @brief Check signed 64-bit modulo operations for a sample set of values.
+ */
+static void CompilerUnitBuiltins_Action_21( void )
+{
+ volatile int64_t n;
+ volatile int64_t d;
+ volatile int64_t x;
+
+ n = 0;
+ RTEMS_OBFUSCATE_VARIABLE( n );
+ d = 0;
+ RTEMS_OBFUSCATE_VARIABLE( d );
+ x = 0;
+ RTEMS_OBFUSCATE_VARIABLE( x );
+
+ n = INT64_C( 0 );
+ d = INT64_C( 0 );
+ do_longjmp = true;
+
+ if ( setjmp( exception_return_context ) == 0 ) {
+ x = n % d;
+ }
+
+ n = INT64_C( 1 );
+ d = INT64_C( 0 );
+ do_longjmp = true;
+
+ if ( setjmp( exception_return_context ) == 0 ) {
+ x = n % d;
+ }
+
+ n = INT64_C( 0x7fffffffffffffff );
+ d = INT64_C( 0 );
+ do_longjmp = true;
+
+ if ( setjmp( exception_return_context ) == 0 ) {
+ x = n % d;
+ }
+
+ n = INT64_C( 0x7fffffff00000000 );
+ d = INT64_C( 0 );
+ do_longjmp = true;
+
+ if ( setjmp( exception_return_context ) == 0 ) {
+ x = n % d;
+ }
+
+ n = INT64_C( 0 );
+ d = INT64_C( 1 );
+ T_eq_i64( n % d, INT64_C( 0 ) );
+
+ n = INT64_C( 1 );
+ d = INT64_C( 1 );
+ T_eq_i64( n % d, INT64_C( 0 ) );
+
+ n = INT64_C( 0x7fffffffffffffff );
+ d = INT64_C( 1 );
+ T_eq_i64( n % d, INT64_C( 0 ) );
+
+ n = INT64_C( 2 );
+ d = INT64_C( 1 );
+ T_eq_i64( n % d, INT64_C( 0 ) );
+
+ n = INT64_C( 2 );
+ d = INT64_C( 1 );
+ T_eq_i64( n % d, INT64_C( 0 ) );
+
+ n = INT64_C( 1 );
+ d = INT64_C( 0x7fffffffffffffff );
+ T_eq_i64( n % d, INT64_C( 1 ) );
+
+ n = INT64_C( 0x7fffffffffffffff );
+ d = INT64_C( 0x7fffffffffffffff );
+ T_eq_i64( n % d, INT64_C( 0 ) );
+
+ n = INT64_C( 1 );
+ d = INT64_C( 0x7fffffff00000000 );
+ T_eq_i64( n % d, INT64_C( 1 ) );
+
+ n = INT64_C( 0x7fffffff00000000 );
+ d = INT64_C( 0x7fffffff00000000 );
+ T_eq_i64( n % d, INT64_C( 0 ) );
+
+ n = INT64_C( 0x7fffffffffffffff );
+ d = INT64_C( 0x7fffffff00000000 );
+ T_eq_i64( n % d, INT64_C( 0xffffffff ) );
+
+ n = INT64_C( 0x7fffffffffffffff );
+ d = INT64_C( 0x8000000000000000 );
+ T_eq_i64( n % d, INT64_C( 0x7fffffffffffffff ) );
+
+ n = INT64_C( 0x7fffffffffffffff );
+ d = INT64_C( 0x0000000080000000 );
+ T_eq_i64( n % d, INT64_C( 2147483647 ) );
+
+ n = INT64_C( 0x7fffffffffffffff );
+ d = INT64_C( 0x00000000f0000000 );
+ T_eq_i64( n % d, INT64_C( 2147483647 ) );
+
+ n = INT64_C( 0x00000001ffffffff );
+ d = INT64_C( 0x00000000f0000000 );
+ T_eq_i64( n % d, INT64_C( 536870911 ) );
+
+ n = INT64_C( 0x0000000fffffffff );
+ d = INT64_C( 0x000000000000000f );
+ T_eq_i64( n % d, INT64_C( 0 ) );
+
+ n = INT64_C( 0x0000000100000001 );
+ d = INT64_C( 0x0000000f00000000 );
+ T_eq_i64( n % d, INT64_C( 4294967297 ) );
+
+ n = INT64_C( 0x0000000f0000000f );
+ d = INT64_C( 0x000000ff0000000f );
+ T_eq_i64( n % d, INT64_C( 64424509455 ) );
+
+ #if defined(TEST_UDIVMODDI4)
+ /*
+ * The above test cases may use __udivmoddi4(). However, the below
+ * parameter values for __udivmoddi4() cannot be obtained through the
+ * signed modulo or division operations. On some targets, calls to
+ * __udivmoddi4() may result from complex optimizations.
+ */
+ n = INT64_C( 0xffffffff0000000f );
+ d = INT64_C( 0x000000010000000f );
+ T_eq_u64( __udivmoddi4( n, d, NULL ), INT64_C( 4294967280 ) );
+ #endif
+}
+
+/**
+ * @brief Check unsigned 64-bit modulo operations for a sample set of values.
+ */
+static void CompilerUnitBuiltins_Action_22( void )
+{
+ volatile uint64_t n;
+ volatile uint64_t d;
+ volatile uint64_t x;
+
+ n = 0;
+ RTEMS_OBFUSCATE_VARIABLE( n );
+ d = 0;
+ RTEMS_OBFUSCATE_VARIABLE( d );
+ x = 0;
+ RTEMS_OBFUSCATE_VARIABLE( x );
+
+ n = UINT64_C( 0 );
+ d = UINT64_C( 0 );
+ do_longjmp = true;
+
+ if ( setjmp( exception_return_context ) == 0 ) {
+ x = n % d;
+ }
+
+ n = UINT64_C( 1 );
+ d = UINT64_C( 0 );
+ do_longjmp = true;
+
+ if ( setjmp( exception_return_context ) == 0 ) {
+ x = n % d;
+ }
+
+ n = UINT64_C( 0 );
+ d = UINT64_C( 1 );
+ T_eq_u64( n % d, UINT64_C( 0 ) );
+
+ n = UINT64_C( 1 );
+ d = UINT64_C( 1 );
+ T_eq_u64( n % d, UINT64_C( 0 ) );
+
+ n = UINT64_C( 0xffffffffffffffff );
+ d = UINT64_C( 1 );
+ T_eq_u64( n % d, UINT64_C( 0 ) );
+
+ n = UINT64_C( 2 );
+ d = UINT64_C( 1 );
+ T_eq_u64( n % d, UINT64_C( 0 ) );
+
+ n = UINT64_C( 1 );
+ d = UINT64_C( 0xffffffffffffffff );
+ T_eq_u64( n % d, UINT64_C( 1 ) );
+
+ n = UINT64_C( 0xffffffffffffffff );
+ d = UINT64_C( 0xffffffffffffffff );
+ T_eq_u64( n % d, UINT64_C( 0 ) );
+}
+
+/**
+ * @fn void T_case_body_CompilerUnitBuiltins( void )
+ */
+T_TEST_CASE_FIXTURE( CompilerUnitBuiltins, &CompilerUnitBuiltins_Fixture )
+{
+ CompilerUnitBuiltins_Action_0();
+ CompilerUnitBuiltins_Action_1();
+ CompilerUnitBuiltins_Action_2();
+ CompilerUnitBuiltins_Action_3();
+ CompilerUnitBuiltins_Action_4();
+ CompilerUnitBuiltins_Action_5();
+ CompilerUnitBuiltins_Action_6();
+ CompilerUnitBuiltins_Action_7();
+ CompilerUnitBuiltins_Action_8();
+ CompilerUnitBuiltins_Action_9();
+ CompilerUnitBuiltins_Action_10();
+ CompilerUnitBuiltins_Action_11();
+ CompilerUnitBuiltins_Action_12();
+ CompilerUnitBuiltins_Action_13();
+ CompilerUnitBuiltins_Action_14();
+ CompilerUnitBuiltins_Action_15();
+ CompilerUnitBuiltins_Action_16();
+ CompilerUnitBuiltins_Action_17();
+ CompilerUnitBuiltins_Action_18();
+ CompilerUnitBuiltins_Action_19();
+ CompilerUnitBuiltins_Action_20();
+ CompilerUnitBuiltins_Action_21();
+ CompilerUnitBuiltins_Action_22();
+}
+
+/** @} */
diff --git a/testsuites/unit/tc-config.c b/testsuites/unit/tc-config.c
new file mode 100644
index 0000000000..415142e1b4
--- /dev/null
+++ b/testsuites/unit/tc-config.c
@@ -0,0 +1,171 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsConfigUnitConfig
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/rtems/semdata.h>
+#include <rtems/score/object.h>
+#include <rtems/score/objectdata.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsConfigUnitConfig spec:/rtems/config/unit/config
+ *
+ * @ingroup TestsuitesUnitNoClock0
+ *
+ * @brief Unit tests for the configuration manager.
+ *
+ * Parts of the file ``cpukit/sapi/src/getconfigmax.c`` are only executed when
+ * unlimited objects are configured. The space qualified code subset does not
+ * support this feature. This test exercises the code parts otherwise not
+ * reached in order to achieve full code coverage.
+ *
+ * This test case performs the following actions:
+ *
+ * - Call get_config_max() indirectly through
+ * rtems_configuration_get_maximum_semaphores() with a specially manipulated
+ * argument to enter an if-branch only accessed when unlimited objects are
+ * configured.
+ *
+ * - The value returned by the function call must be the one artificially
+ * injected by this test.
+ *
+ * @{
+ */
+
+#define SEMAPHORES_PER_BLOCK 32
+
+/**
+ * @brief Test context for spec:/rtems/config/unit/config test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the original value of
+ * ``_Semaphore_Information->objects_per_block``.
+ */
+ Objects_Maximum objects_per_block_ori;
+} RtemsConfigUnitConfig_Context;
+
+static RtemsConfigUnitConfig_Context
+ RtemsConfigUnitConfig_Instance;
+
+static void RtemsConfigUnitConfig_Setup( RtemsConfigUnitConfig_Context *ctx )
+{
+ ctx->objects_per_block_ori = _Semaphore_Information.objects_per_block;
+ _Semaphore_Information.objects_per_block = SEMAPHORES_PER_BLOCK;
+}
+
+static void RtemsConfigUnitConfig_Setup_Wrap( void *arg )
+{
+ RtemsConfigUnitConfig_Context *ctx;
+
+ ctx = arg;
+ RtemsConfigUnitConfig_Setup( ctx );
+}
+
+static void RtemsConfigUnitConfig_Teardown(
+ RtemsConfigUnitConfig_Context *ctx
+)
+{
+ _Semaphore_Information.objects_per_block = ctx->objects_per_block_ori;
+}
+
+static void RtemsConfigUnitConfig_Teardown_Wrap( void *arg )
+{
+ RtemsConfigUnitConfig_Context *ctx;
+
+ ctx = arg;
+ RtemsConfigUnitConfig_Teardown( ctx );
+}
+
+static T_fixture RtemsConfigUnitConfig_Fixture = {
+ .setup = RtemsConfigUnitConfig_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsConfigUnitConfig_Teardown_Wrap,
+ .scope = NULL,
+ .initial_context = &RtemsConfigUnitConfig_Instance
+};
+
+/**
+ * @brief Call get_config_max() indirectly through
+ * rtems_configuration_get_maximum_semaphores() with a specially manipulated
+ * argument to enter an if-branch only accessed when unlimited objects are
+ * configured.
+ */
+static void RtemsConfigUnitConfig_Action_0(
+ RtemsConfigUnitConfig_Context *ctx
+)
+{
+ uint32_t max = rtems_configuration_get_maximum_semaphores();
+
+ /*
+ * The value returned by the function call must be the one artificially
+ * injected by this test.
+ */
+ T_eq_u32( max, SEMAPHORES_PER_BLOCK | RTEMS_UNLIMITED_OBJECTS );
+}
+
+/**
+ * @fn void T_case_body_RtemsConfigUnitConfig( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsConfigUnitConfig, &RtemsConfigUnitConfig_Fixture )
+{
+ RtemsConfigUnitConfig_Context *ctx;
+
+ ctx = T_fixture_context();
+
+ RtemsConfigUnitConfig_Action_0( ctx );
+}
+
+/** @} */
diff --git a/testsuites/unit/tc-crc.c b/testsuites/unit/tc-crc.c
new file mode 100644
index 0000000000..d33a837860
--- /dev/null
+++ b/testsuites/unit/tc-crc.c
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesUnitNoClock0
+ */
+
+/*
+ * Copyright (C) 2023 embedded brains GmbH & Co. KG
+ *
+ * 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.
+ *
+ * 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 <rtems/crc.h>
+
+#include <rtems/test.h>
+
+T_TEST_CASE(CRC24Q) {
+ uint32_t state = _CRC24Q_Update(CRC24Q_SEED, 0);
+ T_eq_u32(state, 0);
+ state = _CRC24Q_Update(CRC24Q_SEED, '1');
+ state = _CRC24Q_Update(state, '2');
+ state = _CRC24Q_Update(state, '3');
+ T_eq_u32(state & CRC24Q_MASK, 0x2c3045);
+ uint8_t bytes[] = {'1', '2', '3'};
+ state = _CRC24Q_Sequence_update(CRC24Q_SEED, &bytes[0], sizeof(bytes));
+ T_eq_u32(state & CRC24Q_MASK, 0x2c3045);
+}
diff --git a/testsuites/unit/tc-misaligned-builtin-memcpy.c b/testsuites/unit/tc-misaligned-builtin-memcpy.c
new file mode 100644
index 0000000000..6ce19e0521
--- /dev/null
+++ b/testsuites/unit/tc-misaligned-builtin-memcpy.c
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesUnitNoClock0
+ */
+
+/*
+ * Copyright (C) 2019 embedded brains GmbH & Co. KG
+ *
+ * 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.
+ *
+ * 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 <string.h>
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+T_TEST_CASE(MisalignedBuiltinMemcpy)
+{
+ double a;
+ double b;
+ char buf[2 * sizeof(double)];
+ void *p;
+
+ p = &buf[0];
+ p = (void *)((uintptr_t)p | 1);
+ RTEMS_OBFUSCATE_VARIABLE(p);
+ a = 123e4;
+ RTEMS_OBFUSCATE_VARIABLE(a);
+ a *= a;
+ memcpy(p, &a, sizeof(a));
+ RTEMS_OBFUSCATE_VARIABLE(p);
+ memcpy(&b, p, sizeof(b));
+ T_eq(a, b, "%f == %f", a, b);
+}
diff --git a/testsuites/unit/tc-score-msgq.c b/testsuites/unit/tc-score-msgq.c
new file mode 100644
index 0000000000..c4cb690c2f
--- /dev/null
+++ b/testsuites/unit/tc-score-msgq.c
@@ -0,0 +1,452 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreMsgqUnitMsgq
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/rtems/messageimpl.h>
+#include <rtems/rtems/statusimpl.h>
+#include <rtems/score/coremsgimpl.h>
+
+#include "../validation/tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreMsgqUnitMsgq spec:/score/msgq/unit/msgq
+ *
+ * @ingroup TestsuitesUnitNoClock0
+ *
+ * @brief Unit tests for the Message Queue Handler.
+ *
+ * Parts of the files ``cpukit/score/src/coremsginsert.c``,
+ * ``cpukit/score/src/coremsgseize.c``, and
+ * ``cpukit/score/src/coremsgsubmit.c`` are only executed by the POSIX API.
+ * Currently, the pre-qualified subset of RTEMS does not contain the POSIX API.
+ * This test exercises the code parts otherwise only reached by the POSIX API
+ * to achieve full code coverage.
+ *
+ * This test case performs the following actions:
+ *
+ * - Use _CORE_message_queue_Insert_message() to insert two messages into a
+ * message queue and use the POSIX message priority to define their order in
+ * the queue.
+ *
+ * - Check that _CORE_message_queue_Submit() was executed successfully.
+ *
+ * - Check that the messages are in the right order in the message queue.
+ *
+ * - Submit three messages into a message queue which can only store two and
+ * have the third submit() blocked till a seize() occurs.
+ *
+ * - Check that the third _CORE_message_queue_Submit() did actually block
+ * till there was room for the message in the message queue.
+ *
+ * - Submit messages in the queue from within an ISR.
+ *
+ * - Check that the first two messages were successfully send.
+ *
+ * - Check that trying to send the third message from ISR when the message
+ * queue was full was rejected.
+ *
+ * @{
+ */
+
+#define MAXIMUM_PENDING_MESSAGES 2
+#define MAXIMUM_MESSAGE_SIZE 3
+
+static void WorkerTask( rtems_task_argument argument );
+
+/**
+ * @brief Test context for spec:/score/msgq/unit/msgq test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a valid ID of a message queue.
+ */
+ rtems_id message_queue_id;
+
+ /**
+ * @brief This member is used as storage area for the message queue.
+ */
+ RTEMS_MESSAGE_QUEUE_BUFFER( MAXIMUM_MESSAGE_SIZE )
+ storage_area[ MAXIMUM_PENDING_MESSAGES];
+
+ /**
+ * @brief This member contains the task identifier of the worker task.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member indicated whether the worker task is currently sending
+ * a message (``true``) or whether it is waiting to receive an event
+ * (``false``).
+ */
+ bool is_worker_working;
+
+ /**
+ * @brief This member contains the returned status code of the SendMessage()
+ * function.
+ */
+ rtems_status_code send_status;
+} ScoreMsgqUnitMsgq_Context;
+
+static ScoreMsgqUnitMsgq_Context
+ ScoreMsgqUnitMsgq_Instance;
+
+#define EVENT_SEND RTEMS_EVENT_17
+#define MESSAGE_CONTENT_LOW { 1, 2, 3 }
+#define MESSAGE_CONTENT_HIGH { 4, 5 }
+#define MESSAGE_PRIORITY_LOW 5
+#define MESSAGE_PRIORITY_HIGH 7
+#define DO_WAIT true
+
+typedef ScoreMsgqUnitMsgq_Context Context;
+
+/*
+ * This is a code fragment from rtems_message_queue_send() with the
+ * specialty that it uses a POSIX priority and the sender
+ * task will wait in case the queue is full.
+ */
+static rtems_status_code SubmitMessage(
+ rtems_id id,
+ uint8_t *message,
+ size_t message_size,
+ unsigned int posix_piority
+)
+{
+ rtems_status_code status;
+ Thread_queue_Context queue_context;
+ Message_queue_Control *the_message_queue;
+
+ T_assert_lt_uint( posix_piority, MQ_PRIO_MAX );
+
+ the_message_queue = _Message_queue_Get(
+ id,
+ &queue_context
+ );
+ T_assert_not_null( the_message_queue );
+
+ /* The next two calls are from _POSIX_Message_queue_Send_support() */
+ _Thread_queue_Context_set_enqueue_callout(
+ &queue_context,
+ _Thread_queue_Enqueue_do_nothing_extra
+ );
+ _Thread_queue_Context_set_timeout_argument( &queue_context, NULL, true );
+
+ _CORE_message_queue_Acquire_critical(
+ &the_message_queue->message_queue,
+ &queue_context
+ );
+
+ status = _CORE_message_queue_Submit(
+ &the_message_queue->message_queue,
+ _Thread_Executing,
+ message,
+ message_size,
+ (CORE_message_queue_Submit_types) ( posix_piority * -1 ),
+ DO_WAIT,
+ &queue_context
+ );
+
+ return _Status_Get( status );
+}
+
+static rtems_status_code ReceiveMessage(
+ rtems_id id,
+ void *buffer,
+ size_t *size
+)
+{
+ return rtems_message_queue_receive(
+ id,
+ buffer,
+ size,
+ RTEMS_LOCAL | RTEMS_NO_WAIT,
+ RTEMS_NO_TIMEOUT
+ );
+}
+
+static rtems_status_code ReceiveOneMessages( Context *ctx )
+{
+ uint8_t message_buffer[ MAXIMUM_MESSAGE_SIZE ];
+ size_t message_size;
+
+ return ReceiveMessage(
+ ctx->message_queue_id,
+ &message_buffer,
+ &message_size
+ );
+}
+
+static void SendMessage( Context *ctx )
+{
+ uint8_t message[] = { 100, 101, 102 };
+ ctx->send_status = SubmitMessage(
+ ctx->message_queue_id,
+ message,
+ sizeof( message ),
+ MESSAGE_PRIORITY_LOW
+ );
+}
+
+static void WorkerTask( rtems_task_argument argument )
+{
+ Context *ctx = (Context *) argument;
+
+ while ( true ) {
+ ctx->is_worker_working = false;
+ ReceiveAnyEvents();
+ ctx->is_worker_working = true;
+ SendMessage( ctx );
+ T_assert_rsc_success( ctx->send_status );
+ }
+}
+
+static void WorkerSendMessage( Context *ctx )
+{
+ SendEvents( ctx->worker_id, EVENT_SEND );
+}
+
+static void ScoreMsgqUnitMsgq_Setup( ScoreMsgqUnitMsgq_Context *ctx )
+{
+ rtems_status_code status;
+ rtems_message_queue_config config = {
+ .name = rtems_build_name( 'M', 'S', 'G', 'Q' ),
+ .maximum_pending_messages = MAXIMUM_PENDING_MESSAGES,
+ .maximum_message_size = MAXIMUM_MESSAGE_SIZE,
+ .storage_area = ctx->storage_area,
+ .storage_size = sizeof( ctx->storage_area ),
+ .storage_free = NULL,
+ .attributes = RTEMS_DEFAULT_ATTRIBUTES
+ };
+
+ status = rtems_message_queue_construct(
+ &config,
+ &ctx->message_queue_id
+ );
+ T_rsc_success( status );
+
+ SetSelfPriority( PRIO_NORMAL );
+
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id, WorkerTask, ctx );
+}
+
+static void ScoreMsgqUnitMsgq_Setup_Wrap( void *arg )
+{
+ ScoreMsgqUnitMsgq_Context *ctx;
+
+ ctx = arg;
+ ScoreMsgqUnitMsgq_Setup( ctx );
+}
+
+static void ScoreMsgqUnitMsgq_Teardown( ScoreMsgqUnitMsgq_Context *ctx )
+{
+ DeleteTask( ctx->worker_id );
+ RestoreRunnerPriority();
+ T_rsc_success( rtems_message_queue_delete( ctx->message_queue_id ) );
+}
+
+static void ScoreMsgqUnitMsgq_Teardown_Wrap( void *arg )
+{
+ ScoreMsgqUnitMsgq_Context *ctx;
+
+ ctx = arg;
+ ScoreMsgqUnitMsgq_Teardown( ctx );
+}
+
+static T_fixture ScoreMsgqUnitMsgq_Fixture = {
+ .setup = ScoreMsgqUnitMsgq_Setup_Wrap,
+ .stop = NULL,
+ .teardown = ScoreMsgqUnitMsgq_Teardown_Wrap,
+ .scope = NULL,
+ .initial_context = &ScoreMsgqUnitMsgq_Instance
+};
+
+/**
+ * @brief Use _CORE_message_queue_Insert_message() to insert two messages into
+ * a message queue and use the POSIX message priority to define their order
+ * in the queue.
+ */
+static void ScoreMsgqUnitMsgq_Action_0( ScoreMsgqUnitMsgq_Context *ctx )
+{
+ rtems_status_code status_submit_low;
+ rtems_status_code status_submit_high;
+ rtems_status_code status_receive_low;
+ rtems_status_code status_receive_high;
+ uint8_t message_low[] = MESSAGE_CONTENT_LOW;
+ uint8_t message_high[] = MESSAGE_CONTENT_HIGH;
+ uint8_t message_buffer_low[ MAXIMUM_MESSAGE_SIZE ];
+ uint8_t message_buffer_high[ MAXIMUM_MESSAGE_SIZE ];
+ size_t message_size_low;
+ size_t message_size_high;
+
+ status_submit_low = SubmitMessage(
+ ctx->message_queue_id,
+ message_low,
+ sizeof( message_low ),
+ MESSAGE_PRIORITY_LOW
+ );
+
+ status_submit_high = SubmitMessage(
+ ctx->message_queue_id,
+ message_high,
+ sizeof( message_high ),
+ MESSAGE_PRIORITY_HIGH
+ );
+
+ status_receive_high = ReceiveMessage(
+ ctx->message_queue_id,
+ &message_buffer_high,
+ &message_size_high
+ );
+
+ status_receive_low = ReceiveMessage(
+ ctx->message_queue_id,
+ &message_buffer_low,
+ &message_size_low
+ );
+
+ /*
+ * Check that _CORE_message_queue_Submit() was executed successfully.
+ */
+ T_rsc_success( status_submit_low );
+ T_rsc_success( status_submit_high );
+
+ /*
+ * Check that the messages are in the right order in the message queue.
+ */
+ T_rsc_success( status_receive_high );
+ T_eq_sz( message_size_high, sizeof( message_high ) );
+ T_eq_mem( message_buffer_high, message_high, message_size_high );
+
+ T_rsc_success( status_receive_low );
+ T_eq_sz( message_size_low, sizeof( message_low ) );
+ T_eq_mem( message_buffer_low, message_low, message_size_low );
+}
+
+/**
+ * @brief Submit three messages into a message queue which can only store two
+ * and have the third submit() blocked till a seize() occurs.
+ */
+static void ScoreMsgqUnitMsgq_Action_1( ScoreMsgqUnitMsgq_Context *ctx )
+{
+ bool is_worker_blocked_after_third_send;
+ bool is_worker_blocked_after_first_receive;
+
+ WorkerSendMessage( ctx );
+ WorkerSendMessage( ctx );
+ WorkerSendMessage( ctx );
+ is_worker_blocked_after_third_send = ctx->is_worker_working;
+
+ T_rsc_success( ReceiveOneMessages( ctx ) );
+ is_worker_blocked_after_first_receive = ctx->is_worker_working;
+
+ T_rsc_success( ReceiveOneMessages( ctx ) );
+ T_rsc_success( ReceiveOneMessages( ctx ) );
+
+ /*
+ * Check that the third _CORE_message_queue_Submit() did actually block till
+ * there was room for the message in the message queue.
+ */
+ T_true( is_worker_blocked_after_third_send );
+ T_true( !is_worker_blocked_after_first_receive );
+}
+
+/**
+ * @brief Submit messages in the queue from within an ISR.
+ */
+static void ScoreMsgqUnitMsgq_Action_2( ScoreMsgqUnitMsgq_Context *ctx )
+{
+ rtems_status_code status_send_first_message;
+ rtems_status_code status_send_second_message;
+ rtems_status_code status_send_third_message;
+
+ CallWithinISR( ( void (*)(void*) ) SendMessage, ctx );
+ status_send_first_message = ctx->send_status;
+ CallWithinISR( ( void (*)(void*) ) SendMessage, ctx );
+ status_send_second_message = ctx->send_status;
+ CallWithinISR( ( void (*)(void*) ) SendMessage, ctx );
+ status_send_third_message = ctx->send_status;
+
+ T_rsc_success( ReceiveOneMessages( ctx ) );
+ T_rsc_success( ReceiveOneMessages( ctx ) );
+
+ /*
+ * Check that the first two messages were successfully send.
+ */
+ T_assert_rsc_success( status_send_first_message );
+ T_assert_rsc_success( status_send_second_message );
+
+ /*
+ * Check that trying to send the third message from ISR when the message
+ * queue was full was rejected.
+ */
+ T_rsc( status_send_third_message, STATUS_CLASSIC_INTERNAL_ERROR );
+}
+
+/**
+ * @fn void T_case_body_ScoreMsgqUnitMsgq( void )
+ */
+T_TEST_CASE_FIXTURE( ScoreMsgqUnitMsgq, &ScoreMsgqUnitMsgq_Fixture )
+{
+ ScoreMsgqUnitMsgq_Context *ctx;
+
+ ctx = T_fixture_context();
+
+ ScoreMsgqUnitMsgq_Action_0( ctx );
+ ScoreMsgqUnitMsgq_Action_1( ctx );
+ ScoreMsgqUnitMsgq_Action_2( ctx );
+}
+
+/** @} */
diff --git a/testsuites/unit/tc-score-rbtree.c b/testsuites/unit/tc-score-rbtree.c
new file mode 100644
index 0000000000..ec286838d0
--- /dev/null
+++ b/testsuites/unit/tc-score-rbtree.c
@@ -0,0 +1,1195 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreRbtreeUnitRbtree
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ * Copyright (C) 2010 Gedare Bloom
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <rtems/score/rbtreeimpl.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreRbtreeUnitRbtree spec:/score/rbtree/unit/rbtree
+ *
+ * @ingroup TestsuitesUnitNoClock0
+ *
+ * @brief Unit tests for the red-black tree implementation.
+ *
+ * The red-black trees are used by various handlers for priority queues and the
+ * timers.
+ *
+ * This test case performs the following actions:
+ *
+ * - Call _RBTree_Initialize_one() and check the tree properties.
+ *
+ * - Check that the tree is not emtpy.
+ *
+ * - Check that the tree root is is the only node.
+ *
+ * - Check that the node is not off the tree.
+ *
+ * - Check that the node has no left child.
+ *
+ * - Check that the node has no right child.
+ *
+ * - Check that the node has no parent.
+ *
+ * - Check that the node has no successor.
+ *
+ * - Check that the node has no predecessor.
+ *
+ * - Check that the minimum node is the node.
+ *
+ * - Check that the maximum node is the node.
+ *
+ * - Check that the tree is emtpy after extraction of the node.
+ *
+ * - Call _RBTree_Insert_inline() and check the return status for a sample set
+ * of nodes.
+ *
+ * - Insert the first node. Check that it is the new minimum node.
+ *
+ * - Insert the second node. Check that it is not the new minimum node.
+ *
+ * - Insert the third node. Check that it is the new minimum node.
+ *
+ * - Call _RBTree_Insert_inline() and _RBTree_Extract() for a sample set of
+ * trees.
+ *
+ * @{
+ */
+
+typedef struct {
+ int id;
+ int key;
+ RBTree_Node Node;
+} TestNode;
+
+static TestNode node_array[ 100 ];
+
+static int Color( const RBTree_Node *n )
+{
+ return RB_COLOR( n, Node );
+}
+
+static bool Less( const void *left, const RBTree_Node *right )
+{
+ const int *the_left;
+ const TestNode *the_right;
+
+ the_left = left;
+ the_right = RTEMS_CONTAINER_OF( right, TestNode, Node );
+
+ return *the_left < the_right->key;
+}
+
+/*
+ * recursively checks tree. if the tree is built properly it should only
+ * be a depth of 7 function calls for 100 entries in the tree.
+ */
+static int VerifyTree( RBTree_Node *root )
+{
+ RBTree_Node *ln;
+ RBTree_Node *rn;
+ TestNode *tn;
+ TestNode *ltn;
+ TestNode *rtn;
+ int lh;
+ int rh;
+
+ if ( root == NULL ) {
+ return 1;
+ }
+
+ ln = _RBTree_Left( root );
+ rn = _RBTree_Right( root );
+ tn = RTEMS_CONTAINER_OF( root, TestNode, Node );
+ ltn = RTEMS_CONTAINER_OF( ln, TestNode, Node );
+ rtn = RTEMS_CONTAINER_OF( rn, TestNode, Node );
+
+ /* Consecutive red links */
+ if (
+ Color( root ) == RB_RED &&
+ ( ( ln != NULL && Color( ln ) == RB_RED ) ||
+ ( rn != NULL && Color( rn ) == RB_RED ) )
+ ) {
+ return -1;
+ }
+
+ lh = VerifyTree ( ln );
+ rh = VerifyTree ( rn );
+
+ if ( lh == -1 || rh == -1 ) {
+ return -1;
+ }
+
+ /* Black height mismatch */
+ if ( lh != rh ) {
+ return -1;
+ }
+
+ /* Invalid binary search tree */
+ if (
+ ( ln != NULL && tn->key != ltn->key && !Less( &ltn->key, root ) ) ||
+ ( rn != NULL && tn->key != rtn->key && !Less( &tn->key, rn ) )
+ ) {
+ return -1;
+ }
+
+ /* Only count black links */
+ return Color( root ) == RB_BLACK ? lh + 1 : lh;
+}
+
+#define TN( i ) &node_array[ i ].Node
+
+typedef struct {
+ int key;
+ const RBTree_Node *parent;
+ const RBTree_Node *left;
+ const RBTree_Node *right;
+ int color;
+} TestNodeDescription;
+
+typedef struct {
+ int current;
+ int count;
+ const TestNodeDescription *tree;
+} VisitorContext;
+
+static bool VisitNodes(
+ const RBTree_Node *node,
+ void *visitor_arg
+)
+{
+ VisitorContext *ctx;
+ const TestNodeDescription *td;
+ const TestNode *tn;
+
+ ctx = visitor_arg;
+ td = &ctx->tree[ ctx->current ];
+ tn = RTEMS_CONTAINER_OF( node, TestNode, Node );
+
+ T_lt_int( ctx->current, ctx->count );
+
+ T_eq_int( td->key, tn->key );
+
+ if ( td->parent == NULL ) {
+ T_true( _RBTree_Is_root( &tn->Node ) );
+ } else {
+ T_eq_ptr( td->parent, _RBTree_Parent( &tn->Node ) );
+ }
+
+ T_eq_ptr( td->left, _RBTree_Left( &tn->Node ) );
+ T_eq_ptr( td->right, _RBTree_Right( &tn->Node ) );
+ T_eq_int( td->color, Color( &tn->Node ) );
+
+ ++ctx->current;
+
+ return false;
+}
+
+static const TestNodeDescription random_ops_tree_unique_1[] = {
+ { 0, NULL, NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_1[] = {
+ { 0, NULL, NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_unique_2[] = {
+};
+
+static const TestNodeDescription random_ops_tree_multiple_2[] = {
+};
+
+static const TestNodeDescription random_ops_tree_unique_3[] = {
+ { 2, NULL, NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_3[] = {
+ { 1, NULL, NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_unique_4[] = {
+ { 0, TN( 3 ), NULL, NULL, RB_RED },
+ { 3, NULL, TN( 0 ), NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_4[] = {
+ { 0, NULL, NULL, TN( 3 ), RB_BLACK },
+ { 1, TN( 0 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_unique_5[] = {
+ { 0, TN( 1 ), NULL, NULL, RB_RED },
+ { 1, NULL, TN( 0 ), TN( 4 ), RB_BLACK },
+ { 4, TN( 1 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_5[] = {
+ { 0, TN( 1 ), NULL, NULL, RB_RED },
+ { 0, NULL, TN( 0 ), TN( 4 ), RB_BLACK },
+ { 2, TN( 1 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_unique_6[] = {
+ { 0, TN( 2 ), NULL, NULL, RB_RED },
+ { 2, NULL, TN( 0 ), NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_6[] = {
+ { 0, TN( 2 ), NULL, NULL, RB_RED },
+ { 1, NULL, TN( 0 ), NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_unique_7[] = {
+ { 0, TN( 2 ), NULL, TN( 1 ), RB_BLACK },
+ { 1, TN( 0 ), NULL, NULL, RB_RED },
+ { 2, NULL, TN( 0 ), TN( 5 ), RB_BLACK },
+ { 4, TN( 5 ), NULL, NULL, RB_RED },
+ { 5, TN( 2 ), TN( 4 ), NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_7[] = {
+ { 0, TN( 2 ), NULL, TN( 1 ), RB_BLACK },
+ { 0, TN( 0 ), NULL, NULL, RB_RED },
+ { 1, NULL, TN( 0 ), TN( 4 ), RB_BLACK },
+ { 2, TN( 4 ), NULL, NULL, RB_RED },
+ { 2, TN( 2 ), TN( 5 ), NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_unique_8[] = {
+ { 0, TN( 1 ), NULL, NULL, RB_BLACK },
+ { 1, NULL, TN( 0 ), TN( 6 ), RB_BLACK },
+ { 5, TN( 6 ), NULL, NULL, RB_RED },
+ { 6, TN( 1 ), TN( 5 ), NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_8[] = {
+ { 0, TN( 5 ), NULL, TN( 0 ), RB_BLACK },
+ { 0, TN( 1 ), NULL, NULL, RB_RED },
+ { 2, NULL, TN( 1 ), TN( 6 ), RB_BLACK },
+ { 3, TN( 5 ), NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_unique_9[] = {
+ { 1, TN( 2 ), NULL, NULL, RB_BLACK },
+ { 2, TN( 6 ), TN( 1 ), TN( 4 ), RB_RED },
+ { 4, TN( 2 ), NULL, TN( 5 ), RB_BLACK },
+ { 5, TN( 4 ), NULL, NULL, RB_RED },
+ { 6, NULL, TN( 2 ), TN( 7 ), RB_BLACK },
+ { 7, TN( 6 ), NULL, TN( 8 ), RB_BLACK },
+ { 8, TN( 7 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_9[] = {
+ { 0, TN( 2 ), NULL, NULL, RB_BLACK },
+ { 1, TN( 6 ), TN( 1 ), TN( 4 ), RB_RED },
+ { 2, TN( 2 ), NULL, TN( 5 ), RB_BLACK },
+ { 2, TN( 4 ), NULL, NULL, RB_RED },
+ { 3, NULL, TN( 2 ), TN( 7 ), RB_BLACK },
+ { 3, TN( 6 ), NULL, TN( 8 ), RB_BLACK },
+ { 4, TN( 7 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_unique_10[] = {
+ { 0, TN( 2 ), NULL, NULL, RB_BLACK },
+ { 2, TN( 6 ), TN( 0 ), TN( 4 ), RB_RED },
+ { 3, TN( 4 ), NULL, NULL, RB_RED },
+ { 4, TN( 2 ), TN( 3 ), NULL, RB_BLACK },
+ { 6, NULL, TN( 2 ), TN( 8 ), RB_BLACK },
+ { 8, TN( 6 ), NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_10[] = {
+ { 0, TN( 2 ), NULL, NULL, RB_BLACK },
+ { 1, TN( 6 ), TN( 0 ), TN( 4 ), RB_RED },
+ { 1, TN( 4 ), NULL, NULL, RB_RED },
+ { 2, TN( 2 ), TN( 3 ), NULL, RB_BLACK },
+ { 3, NULL, TN( 2 ), TN( 8 ), RB_BLACK },
+ { 4, TN( 6 ), NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_unique_11[] = {
+ { 2, TN( 6 ), NULL, NULL, RB_BLACK },
+ { 6, NULL, TN( 2 ), TN( 8 ), RB_BLACK },
+ { 7, TN( 8 ), NULL, NULL, RB_RED },
+ { 8, TN( 6 ), TN( 7 ), TN( 9 ), RB_BLACK },
+ { 9, TN( 8 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_11[] = {
+ { 1, TN( 6 ), NULL, NULL, RB_BLACK },
+ { 3, NULL, TN( 2 ), TN( 8 ), RB_BLACK },
+ { 3, TN( 8 ), NULL, NULL, RB_RED },
+ { 4, TN( 6 ), TN( 7 ), TN( 9 ), RB_BLACK },
+ { 4, TN( 8 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_unique_12[] = {
+ { 0, TN( 1 ), NULL, NULL, RB_RED },
+ { 1, TN( 3 ), TN( 0 ), TN( 2 ), RB_BLACK },
+ { 2, TN( 1 ), NULL, NULL, RB_RED },
+ { 3, TN( 5 ), TN( 1 ), TN( 4 ), RB_RED },
+ { 4, TN( 3 ), NULL, NULL, RB_BLACK },
+ { 5, NULL, TN( 3 ), TN( 9 ), RB_BLACK },
+ { 9, TN( 5 ), NULL, TN( 11 ), RB_BLACK },
+ { 11, TN( 9 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_12[] = {
+ { 0, TN( 1 ), NULL, NULL, RB_BLACK },
+ { 0, TN( 5 ), TN( 0 ), TN( 3 ), RB_RED },
+ { 1, TN( 1 ), NULL, TN( 2 ), RB_BLACK },
+ { 1, TN( 3 ), NULL, NULL, RB_RED },
+ { 2, NULL, TN( 1 ), TN( 9 ), RB_BLACK },
+ { 2, TN( 9 ), NULL, NULL, RB_BLACK },
+ { 4, TN( 5 ), TN( 4 ), TN( 11 ), RB_RED },
+ { 5, TN( 9 ), NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_unique_13[] = {
+ { 0, TN( 1 ), NULL, NULL, RB_RED },
+ { 1, TN( 3 ), TN( 0 ), NULL, RB_BLACK },
+ { 3, TN( 8 ), TN( 1 ), TN( 5 ), RB_RED },
+ { 4, TN( 5 ), NULL, NULL, RB_RED },
+ { 5, TN( 3 ), TN( 4 ), TN( 6 ), RB_BLACK },
+ { 6, TN( 5 ), NULL, NULL, RB_RED },
+ { 8, NULL, TN( 3 ), TN( 11 ), RB_BLACK },
+ { 10, TN( 11 ), NULL, NULL, RB_RED },
+ { 11, TN( 8 ), TN( 10 ), NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_13[] = {
+ { 0, TN( 0 ), NULL, NULL, RB_RED },
+ { 0, TN( 3 ), TN( 1 ), NULL, RB_BLACK },
+ { 1, TN( 6 ), TN( 0 ), TN( 4 ), RB_RED },
+ { 2, TN( 3 ), NULL, TN( 5 ), RB_BLACK },
+ { 2, TN( 4 ), NULL, NULL, RB_RED },
+ { 3, NULL, TN( 3 ), TN( 11 ), RB_BLACK },
+ { 4, TN( 11 ), NULL, NULL, RB_RED },
+ { 5, TN( 6 ), TN( 8 ), TN( 10 ), RB_BLACK },
+ { 5, TN( 11 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_unique_14[] = {
+ { 3, TN( 5 ), NULL, NULL, RB_RED },
+ { 5, TN( 6 ), TN( 3 ), NULL, RB_BLACK },
+ { 6, NULL, TN( 5 ), TN( 12 ), RB_BLACK },
+ { 8, TN( 12 ), NULL, NULL, RB_BLACK },
+ { 12, TN( 6 ), TN( 8 ), TN( 13 ), RB_RED },
+ { 13, TN( 12 ), NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_14[] = {
+ { 1, TN( 5 ), NULL, NULL, RB_RED },
+ { 2, TN( 6 ), TN( 3 ), NULL, RB_BLACK },
+ { 3, NULL, TN( 5 ), TN( 13 ), RB_BLACK },
+ { 4, TN( 13 ), NULL, NULL, RB_BLACK },
+ { 6, TN( 6 ), TN( 8 ), TN( 12 ), RB_RED },
+ { 6, TN( 13 ), NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_unique_15[] = {
+ { 0, TN( 2 ), NULL, NULL, RB_RED },
+ { 2, TN( 8 ), TN( 0 ), TN( 7 ), RB_BLACK },
+ { 7, TN( 2 ), NULL, NULL, RB_RED },
+ { 8, NULL, TN( 2 ), TN( 12 ), RB_BLACK },
+ { 9, TN( 12 ), NULL, TN( 10 ), RB_BLACK },
+ { 10, TN( 9 ), NULL, NULL, RB_RED },
+ { 12, TN( 8 ), TN( 9 ), TN( 13 ), RB_RED },
+ { 13, TN( 12 ), NULL, TN( 14 ), RB_BLACK },
+ { 14, TN( 13 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_15[] = {
+ { 0, TN( 2 ), NULL, NULL, RB_RED },
+ { 1, TN( 9 ), TN( 0 ), TN( 7 ), RB_BLACK },
+ { 3, TN( 2 ), NULL, NULL, RB_RED },
+ { 4, NULL, TN( 2 ), TN( 10 ), RB_BLACK },
+ { 4, TN( 10 ), NULL, NULL, RB_BLACK },
+ { 5, TN( 9 ), TN( 8 ), TN( 12 ), RB_RED },
+ { 6, TN( 12 ), NULL, NULL, RB_RED },
+ { 6, TN( 10 ), TN( 13 ), TN( 14 ), RB_BLACK },
+ { 7, TN( 12 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_unique_16[] = {
+ { 0, TN( 5 ), NULL, TN( 3 ), RB_BLACK },
+ { 3, TN( 0 ), NULL, NULL, RB_RED },
+ { 5, TN( 10 ), TN( 0 ), TN( 7 ), RB_RED },
+ { 7, TN( 5 ), NULL, NULL, RB_BLACK },
+ { 10, NULL, TN( 5 ), TN( 12 ), RB_BLACK },
+ { 12, TN( 10 ), NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_16[] = {
+ { 0, TN( 5 ), NULL, TN( 3 ), RB_BLACK },
+ { 1, TN( 0 ), NULL, NULL, RB_RED },
+ { 2, TN( 10 ), TN( 0 ), TN( 7 ), RB_RED },
+ { 3, TN( 5 ), NULL, NULL, RB_BLACK },
+ { 5, NULL, TN( 5 ), TN( 12 ), RB_BLACK },
+ { 6, TN( 10 ), NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_unique_17[] = {
+ { 0, TN( 1 ), NULL, NULL, RB_RED },
+ { 1, TN( 3 ), TN( 0 ), NULL, RB_BLACK },
+ { 3, TN( 7 ), TN( 1 ), TN( 5 ), RB_RED },
+ { 4, TN( 5 ), NULL, NULL, RB_RED },
+ { 5, TN( 3 ), TN( 4 ), NULL, RB_BLACK },
+ { 7, NULL, TN( 3 ), TN( 9 ), RB_BLACK },
+ { 8, TN( 9 ), NULL, NULL, RB_BLACK },
+ { 9, TN( 7 ), TN( 8 ), TN( 16 ), RB_RED },
+ { 16, TN( 9 ), NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_17[] = {
+ { 0, TN( 0 ), NULL, NULL, RB_RED },
+ { 0, TN( 3 ), TN( 1 ), NULL, RB_BLACK },
+ { 1, TN( 7 ), TN( 0 ), TN( 5 ), RB_RED },
+ { 2, TN( 3 ), NULL, TN( 4 ), RB_BLACK },
+ { 2, TN( 5 ), NULL, NULL, RB_RED },
+ { 3, NULL, TN( 3 ), TN( 8 ), RB_BLACK },
+ { 4, TN( 8 ), NULL, NULL, RB_BLACK },
+ { 4, TN( 7 ), TN( 9 ), TN( 16 ), RB_RED },
+ { 8, TN( 8 ), NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_unique_18[] = {
+ { 0, TN( 2 ), NULL, TN( 1 ), RB_BLACK },
+ { 1, TN( 0 ), NULL, NULL, RB_RED },
+ { 2, TN( 4 ), TN( 0 ), TN( 3 ), RB_BLACK },
+ { 3, TN( 2 ), NULL, NULL, RB_BLACK },
+ { 4, NULL, TN( 2 ), TN( 12 ), RB_BLACK },
+ { 5, TN( 6 ), NULL, NULL, RB_RED },
+ { 6, TN( 8 ), TN( 5 ), TN( 7 ), RB_BLACK },
+ { 7, TN( 6 ), NULL, NULL, RB_RED },
+ { 8, TN( 12 ), TN( 6 ), TN( 10 ), RB_RED },
+ { 9, TN( 10 ), NULL, NULL, RB_RED },
+ { 10, TN( 8 ), TN( 9 ), NULL, RB_BLACK },
+ { 12, TN( 4 ), TN( 8 ), TN( 17 ), RB_BLACK },
+ { 14, TN( 17 ), NULL, NULL, RB_RED },
+ { 17, TN( 12 ), TN( 14 ), NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_18[] = {
+ { 0, TN( 3 ), NULL, TN( 1 ), RB_BLACK },
+ { 0, TN( 0 ), NULL, NULL, RB_RED },
+ { 1, TN( 4 ), TN( 0 ), TN( 2 ), RB_BLACK },
+ { 1, TN( 3 ), NULL, NULL, RB_BLACK },
+ { 2, NULL, TN( 3 ), TN( 12 ), RB_BLACK },
+ { 2, TN( 6 ), NULL, NULL, RB_RED },
+ { 3, TN( 8 ), TN( 5 ), TN( 7 ), RB_BLACK },
+ { 3, TN( 6 ), NULL, NULL, RB_RED },
+ { 4, TN( 12 ), TN( 6 ), TN( 10 ), RB_RED },
+ { 4, TN( 10 ), NULL, NULL, RB_RED },
+ { 5, TN( 8 ), TN( 9 ), NULL, RB_BLACK },
+ { 6, TN( 4 ), TN( 8 ), TN( 14 ), RB_BLACK },
+ { 7, TN( 12 ), NULL, TN( 17 ), RB_BLACK },
+ { 8, TN( 14 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_unique_19[] = {
+ { 1, TN( 2 ), NULL, NULL, RB_RED },
+ { 2, TN( 6 ), TN( 1 ), NULL, RB_BLACK },
+ { 6, TN( 11 ), TN( 2 ), TN( 8 ), RB_BLACK },
+ { 8, TN( 6 ), NULL, TN( 9 ), RB_BLACK },
+ { 9, TN( 8 ), NULL, NULL, RB_RED },
+ { 11, NULL, TN( 6 ), TN( 14 ), RB_BLACK },
+ { 12, TN( 14 ), NULL, NULL, RB_BLACK },
+ { 14, TN( 11 ), TN( 12 ), TN( 16 ), RB_BLACK },
+ { 16, TN( 14 ), NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_19[] = {
+ { 0, TN( 2 ), NULL, NULL, RB_RED },
+ { 1, TN( 6 ), TN( 1 ), NULL, RB_BLACK },
+ { 3, TN( 11 ), TN( 2 ), TN( 9 ), RB_BLACK },
+ { 4, TN( 6 ), NULL, TN( 8 ), RB_BLACK },
+ { 4, TN( 9 ), NULL, NULL, RB_RED },
+ { 5, NULL, TN( 6 ), TN( 14 ), RB_BLACK },
+ { 6, TN( 14 ), NULL, NULL, RB_BLACK },
+ { 7, TN( 11 ), TN( 12 ), TN( 16 ), RB_BLACK },
+ { 8, TN( 14 ), NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_unique_20[] = {
+ { 0, TN( 3 ), NULL, TN( 1 ), RB_BLACK },
+ { 1, TN( 0 ), NULL, NULL, RB_RED },
+ { 3, TN( 9 ), TN( 0 ), TN( 7 ), RB_BLACK },
+ { 4, TN( 7 ), NULL, NULL, RB_RED },
+ { 7, TN( 3 ), TN( 4 ), NULL, RB_BLACK },
+ { 9, NULL, TN( 3 ), TN( 12 ), RB_BLACK },
+ { 10, TN( 12 ), NULL, NULL, RB_BLACK },
+ { 12, TN( 9 ), TN( 10 ), TN( 17 ), RB_BLACK },
+ { 14, TN( 17 ), NULL, NULL, RB_BLACK },
+ { 17, TN( 12 ), TN( 14 ), TN( 18 ), RB_RED },
+ { 18, TN( 17 ), NULL, TN( 19 ), RB_BLACK },
+ { 19, TN( 18 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_20[] = {
+ { 0, TN( 3 ), NULL, TN( 1 ), RB_BLACK },
+ { 0, TN( 0 ), NULL, NULL, RB_RED },
+ { 1, TN( 9 ), TN( 0 ), TN( 7 ), RB_BLACK },
+ { 2, TN( 7 ), NULL, NULL, RB_RED },
+ { 3, TN( 3 ), TN( 4 ), NULL, RB_BLACK },
+ { 4, NULL, TN( 3 ), TN( 14 ), RB_BLACK },
+ { 5, TN( 14 ), NULL, TN( 12 ), RB_BLACK },
+ { 6, TN( 10 ), NULL, NULL, RB_RED },
+ { 7, TN( 9 ), TN( 10 ), TN( 18 ), RB_BLACK },
+ { 8, TN( 18 ), NULL, NULL, RB_RED },
+ { 9, TN( 14 ), TN( 17 ), TN( 19 ), RB_BLACK },
+ { 9, TN( 18 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_unique_21[] = {
+ { 0, TN( 3 ), NULL, TN( 1 ), RB_BLACK },
+ { 1, TN( 0 ), NULL, NULL, RB_RED },
+ { 3, TN( 11 ), TN( 0 ), TN( 5 ), RB_BLACK },
+ { 4, TN( 5 ), NULL, NULL, RB_BLACK },
+ { 5, TN( 3 ), TN( 4 ), TN( 8 ), RB_RED },
+ { 8, TN( 5 ), NULL, NULL, RB_BLACK },
+ { 11, NULL, TN( 3 ), TN( 15 ), RB_BLACK },
+ { 13, TN( 15 ), NULL, NULL, RB_BLACK },
+ { 15, TN( 11 ), TN( 13 ), TN( 17 ), RB_BLACK },
+ { 16, TN( 17 ), NULL, NULL, RB_RED },
+ { 17, TN( 15 ), TN( 16 ), NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_21[] = {
+ { 0, TN( 3 ), NULL, TN( 1 ), RB_BLACK },
+ { 0, TN( 0 ), NULL, NULL, RB_RED },
+ { 1, TN( 8 ), TN( 0 ), TN( 4 ), RB_BLACK },
+ { 2, TN( 3 ), NULL, TN( 5 ), RB_BLACK },
+ { 2, TN( 4 ), NULL, NULL, RB_RED },
+ { 4, NULL, TN( 3 ), TN( 13 ), RB_BLACK },
+ { 5, TN( 13 ), NULL, NULL, RB_BLACK },
+ { 6, TN( 8 ), TN( 11 ), TN( 17 ), RB_BLACK },
+ { 7, TN( 17 ), NULL, NULL, RB_BLACK },
+ { 8, TN( 13 ), TN( 15 ), TN( 16 ), RB_RED },
+ { 8, TN( 17 ), NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_unique_22[] = {
+ { 1, TN( 3 ), NULL, TN( 2 ), RB_BLACK },
+ { 2, TN( 1 ), NULL, NULL, RB_RED },
+ { 3, TN( 8 ), TN( 1 ), TN( 7 ), RB_BLACK },
+ { 4, TN( 7 ), NULL, NULL, RB_RED },
+ { 7, TN( 3 ), TN( 4 ), NULL, RB_BLACK },
+ { 8, NULL, TN( 3 ), TN( 14 ), RB_BLACK },
+ { 10, TN( 11 ), NULL, NULL, RB_RED },
+ { 11, TN( 14 ), TN( 10 ), NULL, RB_BLACK },
+ { 14, TN( 8 ), TN( 11 ), TN( 18 ), RB_BLACK },
+ { 15, TN( 18 ), NULL, NULL, RB_BLACK },
+ { 18, TN( 14 ), TN( 15 ), TN( 21 ), RB_RED },
+ { 21, TN( 18 ), NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_22[] = {
+ { 0, TN( 3 ), NULL, NULL, RB_BLACK },
+ { 1, TN( 8 ), TN( 1 ), TN( 4 ), RB_BLACK },
+ { 1, TN( 4 ), NULL, NULL, RB_BLACK },
+ { 2, TN( 3 ), TN( 2 ), TN( 7 ), RB_RED },
+ { 3, TN( 4 ), NULL, NULL, RB_BLACK },
+ { 4, NULL, TN( 3 ), TN( 14 ), RB_BLACK },
+ { 5, TN( 14 ), NULL, TN( 10 ), RB_BLACK },
+ { 5, TN( 11 ), NULL, NULL, RB_RED },
+ { 7, TN( 8 ), TN( 11 ), TN( 18 ), RB_BLACK },
+ { 7, TN( 18 ), NULL, NULL, RB_BLACK },
+ { 9, TN( 14 ), TN( 15 ), TN( 21 ), RB_RED },
+ { 10, TN( 18 ), NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_unique_23[] = {
+ { 0, TN( 2 ), NULL, NULL, RB_RED },
+ { 2, TN( 8 ), TN( 0 ), TN( 7 ), RB_BLACK },
+ { 7, TN( 2 ), NULL, NULL, RB_RED },
+ { 8, TN( 12 ), TN( 2 ), TN( 11 ), RB_BLACK },
+ { 11, TN( 8 ), NULL, NULL, RB_BLACK },
+ { 12, NULL, TN( 8 ), TN( 17 ), RB_BLACK },
+ { 13, TN( 15 ), NULL, TN( 14 ), RB_BLACK },
+ { 14, TN( 13 ), NULL, NULL, RB_RED },
+ { 15, TN( 17 ), TN( 13 ), TN( 16 ), RB_RED },
+ { 16, TN( 15 ), NULL, NULL, RB_BLACK },
+ { 17, TN( 12 ), TN( 15 ), TN( 20 ), RB_BLACK },
+ { 20, TN( 17 ), NULL, TN( 21 ), RB_BLACK },
+ { 21, TN( 20 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_23[] = {
+ { 0, TN( 2 ), NULL, NULL, RB_RED },
+ { 1, TN( 8 ), TN( 0 ), TN( 7 ), RB_BLACK },
+ { 3, TN( 2 ), NULL, NULL, RB_RED },
+ { 4, TN( 12 ), TN( 2 ), TN( 11 ), RB_BLACK },
+ { 5, TN( 8 ), NULL, NULL, RB_BLACK },
+ { 6, NULL, TN( 8 ), TN( 17 ), RB_BLACK },
+ { 6, TN( 15 ), NULL, NULL, RB_BLACK },
+ { 7, TN( 17 ), TN( 13 ), TN( 16 ), RB_RED },
+ { 7, TN( 16 ), NULL, NULL, RB_RED },
+ { 8, TN( 15 ), TN( 14 ), NULL, RB_BLACK },
+ { 8, TN( 12 ), TN( 15 ), TN( 20 ), RB_BLACK },
+ { 10, TN( 17 ), NULL, TN( 21 ), RB_BLACK },
+ { 10, TN( 20 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_unique_24[] = {
+ { 4, TN( 6 ), NULL, TN( 5 ), RB_BLACK },
+ { 5, TN( 4 ), NULL, NULL, RB_RED },
+ { 6, TN( 14 ), TN( 4 ), TN( 10 ), RB_BLACK },
+ { 8, TN( 10 ), NULL, NULL, RB_RED },
+ { 10, TN( 6 ), TN( 8 ), NULL, RB_BLACK },
+ { 14, NULL, TN( 6 ), TN( 20 ), RB_BLACK },
+ { 15, TN( 16 ), NULL, NULL, RB_RED },
+ { 16, TN( 20 ), TN( 15 ), NULL, RB_BLACK },
+ { 20, TN( 14 ), TN( 16 ), TN( 22 ), RB_BLACK },
+ { 22, TN( 20 ), NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_24[] = {
+ { 2, TN( 6 ), NULL, TN( 5 ), RB_BLACK },
+ { 2, TN( 4 ), NULL, NULL, RB_RED },
+ { 3, TN( 14 ), TN( 4 ), TN( 10 ), RB_BLACK },
+ { 4, TN( 10 ), NULL, NULL, RB_RED },
+ { 5, TN( 6 ), TN( 8 ), NULL, RB_BLACK },
+ { 7, NULL, TN( 6 ), TN( 20 ), RB_BLACK },
+ { 7, TN( 16 ), NULL, NULL, RB_RED },
+ { 8, TN( 20 ), TN( 15 ), NULL, RB_BLACK },
+ { 10, TN( 14 ), TN( 16 ), TN( 22 ), RB_BLACK },
+ { 11, TN( 20 ), NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_unique_25[] = {
+ { 0, TN( 1 ), NULL, NULL, RB_RED },
+ { 1, TN( 3 ), TN( 0 ), NULL, RB_BLACK },
+ { 3, TN( 13 ), TN( 1 ), TN( 5 ), RB_BLACK },
+ { 4, TN( 5 ), NULL, NULL, RB_BLACK },
+ { 5, TN( 3 ), TN( 4 ), TN( 6 ), RB_RED },
+ { 6, TN( 5 ), NULL, TN( 9 ), RB_BLACK },
+ { 9, TN( 6 ), NULL, NULL, RB_RED },
+ { 13, NULL, TN( 3 ), TN( 19 ), RB_BLACK },
+ { 14, TN( 15 ), NULL, NULL, RB_RED },
+ { 15, TN( 16 ), TN( 14 ), NULL, RB_BLACK },
+ { 16, TN( 19 ), TN( 15 ), TN( 17 ), RB_RED },
+ { 17, TN( 16 ), NULL, NULL, RB_BLACK },
+ { 19, TN( 13 ), TN( 16 ), TN( 23 ), RB_BLACK },
+ { 23, TN( 19 ), NULL, TN( 24 ), RB_BLACK },
+ { 24, TN( 23 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_25[] = {
+ { 0, TN( 3 ), NULL, TN( 1 ), RB_BLACK },
+ { 0, TN( 0 ), NULL, NULL, RB_RED },
+ { 1, TN( 13 ), TN( 0 ), TN( 4 ), RB_BLACK },
+ { 2, TN( 4 ), NULL, NULL, RB_BLACK },
+ { 2, TN( 3 ), TN( 5 ), TN( 6 ), RB_RED },
+ { 3, TN( 4 ), NULL, TN( 9 ), RB_BLACK },
+ { 4, TN( 6 ), NULL, NULL, RB_RED },
+ { 6, NULL, TN( 3 ), TN( 19 ), RB_BLACK },
+ { 7, TN( 17 ), NULL, TN( 14 ), RB_BLACK },
+ { 7, TN( 15 ), NULL, NULL, RB_RED },
+ { 8, TN( 19 ), TN( 15 ), TN( 16 ), RB_RED },
+ { 8, TN( 17 ), NULL, NULL, RB_BLACK },
+ { 9, TN( 13 ), TN( 17 ), TN( 23 ), RB_BLACK },
+ { 11, TN( 19 ), NULL, TN( 24 ), RB_BLACK },
+ { 12, TN( 23 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_unique_26[] = {
+ { 0, TN( 1 ), NULL, NULL, RB_RED },
+ { 1, TN( 3 ), TN( 0 ), NULL, RB_BLACK },
+ { 3, TN( 11 ), TN( 1 ), TN( 9 ), RB_BLACK },
+ { 6, TN( 9 ), NULL, NULL, RB_RED },
+ { 9, TN( 3 ), TN( 6 ), TN( 10 ), RB_BLACK },
+ { 10, TN( 9 ), NULL, NULL, RB_RED },
+ { 11, NULL, TN( 3 ), TN( 14 ), RB_BLACK },
+ { 12, TN( 14 ), NULL, TN( 13 ), RB_BLACK },
+ { 13, TN( 12 ), NULL, NULL, RB_RED },
+ { 14, TN( 11 ), TN( 12 ), TN( 20 ), RB_BLACK },
+ { 18, TN( 20 ), NULL, NULL, RB_BLACK },
+ { 20, TN( 14 ), TN( 18 ), TN( 23 ), RB_RED },
+ { 21, TN( 23 ), NULL, NULL, RB_RED },
+ { 23, TN( 20 ), TN( 21 ), NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_26[] = {
+ { 0, TN( 3 ), NULL, TN( 0 ), RB_BLACK },
+ { 0, TN( 1 ), NULL, NULL, RB_RED },
+ { 1, TN( 9 ), TN( 1 ), TN( 6 ), RB_BLACK },
+ { 3, TN( 3 ), NULL, NULL, RB_BLACK },
+ { 4, NULL, TN( 3 ), TN( 14 ), RB_BLACK },
+ { 5, TN( 12 ), NULL, TN( 10 ), RB_BLACK },
+ { 5, TN( 11 ), NULL, NULL, RB_RED },
+ { 6, TN( 14 ), TN( 11 ), TN( 13 ), RB_RED },
+ { 6, TN( 12 ), NULL, NULL, RB_BLACK },
+ { 7, TN( 9 ), TN( 12 ), TN( 20 ), RB_BLACK },
+ { 9, TN( 20 ), NULL, NULL, RB_BLACK },
+ { 10, TN( 14 ), TN( 18 ), TN( 23 ), RB_RED },
+ { 10, TN( 23 ), NULL, NULL, RB_RED },
+ { 11, TN( 20 ), TN( 21 ), NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_unique_27[] = {
+ { 3, TN( 8 ), NULL, NULL, RB_BLACK },
+ { 8, TN( 19 ), TN( 3 ), TN( 17 ), RB_BLACK },
+ { 12, TN( 17 ), NULL, NULL, RB_RED },
+ { 17, TN( 8 ), TN( 12 ), NULL, RB_BLACK },
+ { 19, NULL, TN( 8 ), TN( 24 ), RB_BLACK },
+ { 20, TN( 21 ), NULL, NULL, RB_RED },
+ { 21, TN( 24 ), TN( 20 ), TN( 23 ), RB_BLACK },
+ { 23, TN( 21 ), NULL, NULL, RB_RED },
+ { 24, TN( 19 ), TN( 21 ), TN( 25 ), RB_BLACK },
+ { 25, TN( 24 ), NULL, TN( 26 ), RB_BLACK },
+ { 26, TN( 25 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_27[] = {
+ { 1, TN( 8 ), NULL, NULL, RB_BLACK },
+ { 4, TN( 19 ), TN( 3 ), TN( 17 ), RB_BLACK },
+ { 6, TN( 17 ), NULL, NULL, RB_RED },
+ { 8, TN( 8 ), TN( 12 ), NULL, RB_BLACK },
+ { 9, NULL, TN( 8 ), TN( 25 ), RB_BLACK },
+ { 10, TN( 21 ), NULL, NULL, RB_RED },
+ { 10, TN( 25 ), TN( 20 ), TN( 23 ), RB_BLACK },
+ { 11, TN( 21 ), NULL, NULL, RB_RED },
+ { 12, TN( 19 ), TN( 21 ), TN( 24 ), RB_BLACK },
+ { 12, TN( 25 ), NULL, TN( 26 ), RB_BLACK },
+ { 13, TN( 24 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_unique_28[] = {
+ { 0, TN( 5 ), NULL, NULL, RB_BLACK },
+ { 5, TN( 13 ), TN( 0 ), TN( 7 ), RB_RED },
+ { 7, TN( 5 ), NULL, NULL, RB_BLACK },
+ { 13, NULL, TN( 5 ), TN( 17 ), RB_BLACK },
+ { 15, TN( 17 ), NULL, NULL, RB_BLACK },
+ { 17, TN( 13 ), TN( 15 ), TN( 26 ), RB_RED },
+ { 21, TN( 26 ), NULL, NULL, RB_RED },
+ { 26, TN( 17 ), TN( 21 ), NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_28[] = {
+ { 0, TN( 5 ), NULL, NULL, RB_BLACK },
+ { 2, TN( 13 ), TN( 0 ), TN( 7 ), RB_RED },
+ { 3, TN( 5 ), NULL, NULL, RB_BLACK },
+ { 6, NULL, TN( 5 ), TN( 17 ), RB_BLACK },
+ { 7, TN( 17 ), NULL, NULL, RB_BLACK },
+ { 8, TN( 13 ), TN( 15 ), TN( 26 ), RB_RED },
+ { 10, TN( 26 ), NULL, NULL, RB_RED },
+ { 13, TN( 17 ), TN( 21 ), NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_unique_29[] = {
+ { 0, TN( 3 ), NULL, TN( 1 ), RB_BLACK },
+ { 1, TN( 0 ), NULL, NULL, RB_RED },
+ { 3, TN( 12 ), TN( 0 ), TN( 6 ), RB_BLACK },
+ { 4, TN( 6 ), NULL, NULL, RB_BLACK },
+ { 6, TN( 3 ), TN( 4 ), TN( 8 ), RB_RED },
+ { 7, TN( 8 ), NULL, NULL, RB_RED },
+ { 8, TN( 6 ), TN( 7 ), TN( 11 ), RB_BLACK },
+ { 11, TN( 8 ), NULL, NULL, RB_RED },
+ { 12, NULL, TN( 3 ), TN( 17 ), RB_BLACK },
+ { 13, TN( 17 ), NULL, TN( 14 ), RB_BLACK },
+ { 14, TN( 13 ), NULL, NULL, RB_RED },
+ { 17, TN( 12 ), TN( 13 ), TN( 25 ), RB_BLACK },
+ { 22, TN( 25 ), NULL, NULL, RB_RED },
+ { 25, TN( 17 ), TN( 22 ), TN( 27 ), RB_BLACK },
+ { 27, TN( 25 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_29[] = {
+ { 0, TN( 3 ), NULL, TN( 1 ), RB_BLACK },
+ { 0, TN( 0 ), NULL, NULL, RB_RED },
+ { 1, TN( 11 ), TN( 0 ), TN( 6 ), RB_BLACK },
+ { 2, TN( 6 ), NULL, NULL, RB_BLACK },
+ { 3, TN( 3 ), TN( 4 ), TN( 7 ), RB_RED },
+ { 3, TN( 6 ), NULL, TN( 8 ), RB_BLACK },
+ { 4, TN( 7 ), NULL, NULL, RB_RED },
+ { 5, NULL, TN( 3 ), TN( 22 ), RB_BLACK },
+ { 6, TN( 12 ), NULL, NULL, RB_BLACK },
+ { 6, TN( 22 ), TN( 13 ), TN( 17 ), RB_RED },
+ { 7, TN( 17 ), NULL, NULL, RB_RED },
+ { 8, TN( 12 ), TN( 14 ), NULL, RB_BLACK },
+ { 11, TN( 11 ), TN( 12 ), TN( 25 ), RB_BLACK },
+ { 12, TN( 22 ), NULL, TN( 27 ), RB_BLACK },
+ { 13, TN( 25 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_unique_30[] = {
+ { 0, TN( 4 ), NULL, NULL, RB_RED },
+ { 4, TN( 6 ), TN( 0 ), NULL, RB_BLACK },
+ { 6, TN( 13 ), TN( 4 ), TN( 9 ), RB_RED },
+ { 8, TN( 9 ), NULL, NULL, RB_RED },
+ { 9, TN( 6 ), TN( 8 ), TN( 12 ), RB_BLACK },
+ { 12, TN( 9 ), NULL, NULL, RB_RED },
+ { 13, NULL, TN( 6 ), TN( 18 ), RB_BLACK },
+ { 14, TN( 16 ), NULL, NULL, RB_RED },
+ { 16, TN( 18 ), TN( 14 ), TN( 17 ), RB_BLACK },
+ { 17, TN( 16 ), NULL, NULL, RB_RED },
+ { 18, TN( 13 ), TN( 16 ), TN( 27 ), RB_RED },
+ { 20, TN( 27 ), NULL, NULL, RB_RED },
+ { 27, TN( 18 ), TN( 20 ), TN( 28 ), RB_BLACK },
+ { 28, TN( 27 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_30[] = {
+ { 0, TN( 4 ), NULL, NULL, RB_BLACK },
+ { 2, TN( 13 ), TN( 0 ), TN( 9 ), RB_RED },
+ { 3, TN( 9 ), NULL, NULL, RB_RED },
+ { 4, TN( 4 ), TN( 6 ), TN( 8 ), RB_BLACK },
+ { 4, TN( 9 ), NULL, NULL, RB_RED },
+ { 6, TN( 14 ), TN( 4 ), TN( 12 ), RB_BLACK },
+ { 6, TN( 13 ), NULL, NULL, RB_BLACK },
+ { 7, NULL, TN( 13 ), TN( 18 ), RB_BLACK },
+ { 8, TN( 18 ), NULL, TN( 16 ), RB_BLACK },
+ { 8, TN( 17 ), NULL, NULL, RB_RED },
+ { 9, TN( 14 ), TN( 17 ), TN( 27 ), RB_BLACK },
+ { 10, TN( 27 ), NULL, NULL, RB_RED },
+ { 13, TN( 18 ), TN( 20 ), TN( 28 ), RB_BLACK },
+ { 14, TN( 27 ), NULL, NULL, RB_RED }
+};
+
+static const TestNodeDescription random_ops_tree_unique_31[] = {
+ { 0, TN( 2 ), NULL, NULL, RB_RED },
+ { 2, TN( 5 ), TN( 0 ), NULL, RB_BLACK },
+ { 5, TN( 11 ), TN( 2 ), TN( 9 ), RB_BLACK },
+ { 7, TN( 9 ), NULL, NULL, RB_RED },
+ { 9, TN( 5 ), TN( 7 ), NULL, RB_BLACK },
+ { 11, NULL, TN( 5 ), TN( 21 ), RB_BLACK },
+ { 14, TN( 16 ), NULL, NULL, RB_RED },
+ { 16, TN( 21 ), TN( 14 ), TN( 18 ), RB_BLACK },
+ { 18, TN( 16 ), NULL, NULL, RB_RED },
+ { 21, TN( 11 ), TN( 16 ), TN( 30 ), RB_BLACK },
+ { 30, TN( 21 ), NULL, NULL, RB_BLACK }
+};
+
+static const TestNodeDescription random_ops_tree_multiple_31[] = {
+ { 0, TN( 2 ), NULL, NULL, RB_RED },
+ { 1, TN( 5 ), TN( 0 ), NULL, RB_BLACK },
+ { 2, TN( 11 ), TN( 2 ), TN( 9 ), RB_BLACK },
+ { 3, TN( 9 ), NULL, NULL, RB_RED },
+ { 4, TN( 5 ), TN( 7 ), NULL, RB_BLACK },
+ { 5, NULL, TN( 5 ), TN( 21 ), RB_BLACK },
+ { 7, TN( 16 ), NULL, NULL, RB_RED },
+ { 8, TN( 21 ), TN( 14 ), TN( 18 ), RB_BLACK },
+ { 9, TN( 16 ), NULL, NULL, RB_RED },
+ { 10, TN( 11 ), TN( 16 ), TN( 30 ), RB_BLACK },
+ { 15, TN( 21 ), NULL, NULL, RB_BLACK }
+};
+
+#define RANDOM_OPS_TREE( i ) \
+ { &random_ops_tree_multiple_##i[ 0 ], &random_ops_tree_unique_##i[ 0 ] }
+
+static const TestNodeDescription *const random_ops_trees[][2] = {
+ RANDOM_OPS_TREE( 1 ),
+ RANDOM_OPS_TREE( 2 ),
+ RANDOM_OPS_TREE( 3 ),
+ RANDOM_OPS_TREE( 4 ),
+ RANDOM_OPS_TREE( 5 ),
+ RANDOM_OPS_TREE( 6 ),
+ RANDOM_OPS_TREE( 7 ),
+ RANDOM_OPS_TREE( 8 ),
+ RANDOM_OPS_TREE( 9 ),
+ RANDOM_OPS_TREE( 10 ),
+ RANDOM_OPS_TREE( 11 ),
+ RANDOM_OPS_TREE( 12 ),
+ RANDOM_OPS_TREE( 13 ),
+ RANDOM_OPS_TREE( 14 ),
+ RANDOM_OPS_TREE( 15 ),
+ RANDOM_OPS_TREE( 16 ),
+ RANDOM_OPS_TREE( 17 ),
+ RANDOM_OPS_TREE( 18 ),
+ RANDOM_OPS_TREE( 19 ),
+ RANDOM_OPS_TREE( 20 ),
+ RANDOM_OPS_TREE( 21 ),
+ RANDOM_OPS_TREE( 22 ),
+ RANDOM_OPS_TREE( 23 ),
+ RANDOM_OPS_TREE( 24 ),
+ RANDOM_OPS_TREE( 25 ),
+ RANDOM_OPS_TREE( 26 ),
+ RANDOM_OPS_TREE( 27 ),
+ RANDOM_OPS_TREE( 28 ),
+ RANDOM_OPS_TREE( 29 ),
+ RANDOM_OPS_TREE( 30 ),
+ RANDOM_OPS_TREE( 31 )
+};
+
+#define RANDOM_OPS_TREE_COUNT( i ) \
+ { \
+ RTEMS_ARRAY_SIZE( random_ops_tree_multiple_##i ), \
+ RTEMS_ARRAY_SIZE( random_ops_tree_unique_##i ) \
+ }
+
+static const size_t random_ops_tree_counts[][2] = {
+ RANDOM_OPS_TREE_COUNT( 1 ),
+ RANDOM_OPS_TREE_COUNT( 2 ),
+ RANDOM_OPS_TREE_COUNT( 3 ),
+ RANDOM_OPS_TREE_COUNT( 4 ),
+ RANDOM_OPS_TREE_COUNT( 5 ),
+ RANDOM_OPS_TREE_COUNT( 6 ),
+ RANDOM_OPS_TREE_COUNT( 7 ),
+ RANDOM_OPS_TREE_COUNT( 8 ),
+ RANDOM_OPS_TREE_COUNT( 9 ),
+ RANDOM_OPS_TREE_COUNT( 10 ),
+ RANDOM_OPS_TREE_COUNT( 11 ),
+ RANDOM_OPS_TREE_COUNT( 12 ),
+ RANDOM_OPS_TREE_COUNT( 13 ),
+ RANDOM_OPS_TREE_COUNT( 14 ),
+ RANDOM_OPS_TREE_COUNT( 15 ),
+ RANDOM_OPS_TREE_COUNT( 16 ),
+ RANDOM_OPS_TREE_COUNT( 17 ),
+ RANDOM_OPS_TREE_COUNT( 18 ),
+ RANDOM_OPS_TREE_COUNT( 19 ),
+ RANDOM_OPS_TREE_COUNT( 20 ),
+ RANDOM_OPS_TREE_COUNT( 21 ),
+ RANDOM_OPS_TREE_COUNT( 22 ),
+ RANDOM_OPS_TREE_COUNT( 23 ),
+ RANDOM_OPS_TREE_COUNT( 24 ),
+ RANDOM_OPS_TREE_COUNT( 25 ),
+ RANDOM_OPS_TREE_COUNT( 26 ),
+ RANDOM_OPS_TREE_COUNT( 27 ),
+ RANDOM_OPS_TREE_COUNT( 28 ),
+ RANDOM_OPS_TREE_COUNT( 29 ),
+ RANDOM_OPS_TREE_COUNT( 30 ),
+ RANDOM_OPS_TREE_COUNT( 31 )
+};
+
+static uint32_t SimpleRandom( uint32_t v )
+{
+ v *= 1664525;
+ v += 1013904223;
+
+ return v;
+}
+
+static void RandomOps( size_t n, bool unique )
+{
+ VisitorContext ctx = {
+ .current = 0,
+ .count = random_ops_tree_counts[ n - 1 ][ unique ],
+ .tree = random_ops_trees[ n - 1 ][ unique ]
+ };
+ RBTree_Control tree;
+ TestNode *nodes;
+ size_t m;
+ size_t s;
+ uint32_t v;
+ size_t i;
+
+ nodes = &node_array[ 0 ];
+ m = n * n * n;
+ s = unique ? 1 : 2;
+ v = 0xdeadbeef;
+ _RBTree_Initialize_empty( &tree );
+
+ memset( nodes, 0, n * sizeof( *nodes ) );
+
+ for ( i = 0; i < n; ++i ) {
+ nodes[ i ].key = (int) ( i / s );
+ }
+
+ for ( i = 0; i < m; ++i ) {
+ size_t j = ( v >> 13 ) % n;
+ TestNode *tn = &nodes[ j ];
+
+ if ( tn->id == 0 ) {
+ tn->id = 1;
+ _RBTree_Initialize_node( &tn->Node );
+ _RBTree_Insert_inline( &tree, &tn->Node, &tn->key, Less );
+ } else {
+ tn->id = 0;
+ _RBTree_Extract( &tree, &tn->Node );
+ }
+
+ T_ne_int( VerifyTree( _RBTree_Root( &tree ) ), -1 );
+
+ v = SimpleRandom( v );
+ }
+
+ _RBTree_Iterate( &tree, VisitNodes, &ctx );
+ T_true( ctx.current == ctx.count );
+}
+
+/**
+ * @brief Call _RBTree_Initialize_one() and check the tree properties.
+ */
+static void ScoreRbtreeUnitRbtree_Action_0( void )
+{
+ RBTree_Control tree;
+ RBTree_Node node;
+
+ _RBTree_Initialize_node( &node );
+ _RBTree_Initialize_one( &tree, &node );
+
+ /*
+ * Check that the tree is not emtpy.
+ */
+ T_false( _RBTree_Is_empty( &tree ) );
+
+ /*
+ * Check that the tree root is is the only node.
+ */
+ T_true( _RBTree_Is_root( &node ) );
+
+ /*
+ * Check that the node is not off the tree.
+ */
+ T_false( _RBTree_Is_node_off_tree( &node ) );
+
+ /*
+ * Check that the node has no left child.
+ */
+ T_null( _RBTree_Left( &node ) );
+
+ /*
+ * Check that the node has no right child.
+ */
+ T_null( _RBTree_Right( &node ) );
+
+ /*
+ * Check that the node has no parent.
+ */
+ T_null( _RBTree_Parent( &node ) );
+
+ /*
+ * Check that the node has no successor.
+ */
+ T_null( _RBTree_Successor( &node ) );
+
+ /*
+ * Check that the node has no predecessor.
+ */
+ T_null( _RBTree_Predecessor( &node ) );
+
+ /*
+ * Check that the minimum node is the node.
+ */
+ T_eq_ptr( _RBTree_Minimum( &tree ), &node );
+
+ /*
+ * Check that the maximum node is the node.
+ */
+ T_eq_ptr( _RBTree_Maximum( &tree ), &node );
+
+ /*
+ * Check that the tree is emtpy after extraction of the node.
+ */
+ _RBTree_Extract( &tree, &node );
+ T_true( _RBTree_Is_empty( &tree ) );
+}
+
+/**
+ * @brief Call _RBTree_Insert_inline() and check the return status for a sample
+ * set of nodes.
+ */
+static void ScoreRbtreeUnitRbtree_Action_1( void )
+{
+ RBTree_Control tree;
+ TestNode a;
+ TestNode b;
+ TestNode c;
+ bool is_new_minimum;
+
+ _RBTree_Initialize_empty( &tree );
+
+ /*
+ * Insert the first node. Check that it is the new minimum node.
+ */
+ _RBTree_Initialize_node( &b.Node );
+ b.key = 2;
+ is_new_minimum = _RBTree_Insert_inline( &tree, &b.Node, &b.key, Less );
+ T_true( is_new_minimum );
+
+ /*
+ * Insert the second node. Check that it is not the new minimum node.
+ */
+ _RBTree_Initialize_node( &c.Node );
+ c.key = 3;
+ is_new_minimum = _RBTree_Insert_inline( &tree, &c.Node, &c.key, Less );
+ T_false( is_new_minimum );
+
+ /*
+ * Insert the third node. Check that it is the new minimum node.
+ */
+ _RBTree_Initialize_node( &a.Node );
+ a.key = 1;
+ is_new_minimum = _RBTree_Insert_inline( &tree, &a.Node, &a.key, Less );
+ T_true( is_new_minimum );
+}
+
+/**
+ * @brief Call _RBTree_Insert_inline() and _RBTree_Extract() for a sample set
+ * of trees.
+ */
+static void ScoreRbtreeUnitRbtree_Action_2( void )
+{
+ size_t n;
+
+ for ( n = 0; n < RTEMS_ARRAY_SIZE( random_ops_trees ); ++n ) {
+ RandomOps( n + 1, true );
+ RandomOps( n + 1, false );
+ }
+}
+
+/**
+ * @fn void T_case_body_ScoreRbtreeUnitRbtree( void )
+ */
+T_TEST_CASE( ScoreRbtreeUnitRbtree )
+{
+ ScoreRbtreeUnitRbtree_Action_0();
+ ScoreRbtreeUnitRbtree_Action_1();
+ ScoreRbtreeUnitRbtree_Action_2();
+}
+
+/** @} */
diff --git a/testsuites/unit/ts-unit-no-clock-0.c b/testsuites/unit/ts-unit-no-clock-0.c
new file mode 100644
index 0000000000..88e67f91bd
--- /dev/null
+++ b/testsuites/unit/ts-unit-no-clock-0.c
@@ -0,0 +1,80 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesUnitNoClock0
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesUnitNoClock0 spec:/testsuites/unit-no-clock-0
+ *
+ * @ingroup RTEMSTestSuitesUnit
+ *
+ * @brief This general purpose unit test suite provides enough resources to run
+ * basic tests without a Clock Driver for all specified managers and
+ * functions.
+ *
+ * In SMP configurations, up to three scheduler instances using the SMP EDF
+ * scheduler are provided using up to four processors.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesUnitNoClock0";
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 4
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#include "../validation/ts-default.h"
+
+/** @} */