/*
 * Copyright (c) 2016,2021 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include <ztest.h>
#include <arch/cpu.h>

#include <tc_util.h>
#include <sys/bitarray.h>
#include <sys/util.h>
#include <toolchain.h>

#ifdef CONFIG_BIG_ENDIAN
#define BIT_INDEX(bit)  ((3 - ((bit >> 3) & 0x3)) + 4*(bit >> 5))
#else
#define BIT_INDEX(bit)  (bit >> 3)
#endif
#define BIT_VAL(bit)    (1 << (bit & 0x7))
#define BITFIELD_SIZE   512

/**
 * @addtogroup kernel_common_tests
 * @{
 */

/* Helper function to compare two bitarrays */
static bool cmp_u32_arrays(uint32_t *a1, uint32_t *a2, size_t sz)
{
	bool are_equal = true;
	size_t i;

	for (i = 0; i < sz; i++) {
		if (a1[i] != a2[i]) {
			are_equal = false;
			printk("%s: [%zu] 0x%x != 0x%x", __func__,
			       i, a1[i], a2[i]);
			break;
		}
	}

	return are_equal;
}

#define FAIL_ALLOC_MSG_FMT "sys_bitarray_alloc with region size %i allocated incorrectly"
#define FAIL_ALLOC_RET_MSG_FMT "sys_bitarray_alloc with region size %i returned incorrect result"
#define FAIL_ALLOC_OFFSET_MSG_FMT "sys_bitarray_alloc with region size %i gave incorrect offset"
#define FAIL_FREE_MSG_FMT "sys_bitarray_free with region size %i and offset %i failed"
#define FREE 0U

void validate_bitarray_define(sys_bitarray_t *ba, size_t num_bits)
{
	size_t num_bundles;
	int i;

	num_bundles = ROUND_UP(ROUND_UP(num_bits, 8) / 8, sizeof(uint32_t))
		      / sizeof(uint32_t);

	zassert_equal(ba->num_bits, num_bits,
		      "SYS_BITARRAY_DEFINE num_bits expected %u, got %u",
		      num_bits, ba->num_bits);

	zassert_equal(ba->num_bundles, num_bundles,
		      "SYS_BITARRAY_DEFINE num_bundles expected %u, got %u",
		      num_bundles, ba->num_bundles);

	for (i = 0; i < num_bundles; i++) {
		zassert_equal(ba->bundles[i], FREE,
			      "SYS_BITARRAY_DEFINE bundles[%u] not free for num_bits %u",
			      i, num_bits);
	}
}

/**
 * @brief Test defining of bitarrays
 *
 * @see SYS_BITARRAY_DEFINE()
 */
void test_bitarray_declare(void)
{
	SYS_BITARRAY_DEFINE(ba_1_bit, 1);
	SYS_BITARRAY_DEFINE(ba_32_bit, 32);
	SYS_BITARRAY_DEFINE(ba_33_bit, 33);
	SYS_BITARRAY_DEFINE(ba_64_bit, 64);
	SYS_BITARRAY_DEFINE(ba_65_bit, 65);
	SYS_BITARRAY_DEFINE(ba_128_bit, 128);
	SYS_BITARRAY_DEFINE(ba_129_bit, 129);

	/* Test SYS_BITFIELD_DECLARE by asserting that a sufficent number of uint32_t
	 * in the declared array are set as free to represent the number of bits
	 */

	validate_bitarray_define(&ba_1_bit, 1);
	validate_bitarray_define(&ba_32_bit, 32);
	validate_bitarray_define(&ba_33_bit, 33);
	validate_bitarray_define(&ba_64_bit, 64);
	validate_bitarray_define(&ba_65_bit, 65);
	validate_bitarray_define(&ba_128_bit, 128);
	validate_bitarray_define(&ba_129_bit, 129);
}

bool bitarray_bundles_is_zero(sys_bitarray_t *ba)
{
	bool ret = true;
	unsigned int i;

	for (i = 0; i < ba->num_bundles; i++) {
		if (ba->bundles[i] != 0) {
			ret = false;
			break;
		}
	}

	return ret;
}

/**
 * @brief Test bitarrays set and clear
 *
 * @see sys_bitarray_set_bit()
 * @see sys_bitarray_clear_bit()
 * @see sys_bitarray_test_bit()
 * @see sys_bitarray_test_and_set_bit()
 * @see sys_bitarray_test_and_clear_bit()
 */
void test_bitarray_set_clear(void)
{
	int ret;
	int bit_val;
	size_t bit, bundle_idx, bit_idx_in_bundle;

	/* Bitarrays have embedded spinlocks and can't on the stack. */
	if (IS_ENABLED(CONFIG_KERNEL_COHERENCE)) {
		ztest_test_skip();
	}

	SYS_BITARRAY_DEFINE(ba, 234);

	for (bit = 0U; bit < ba.num_bits; ++bit) {
		bundle_idx = bit / (sizeof(ba.bundles[0]) * 8);
		bit_idx_in_bundle = bit % (sizeof(ba.bundles[0]) * 8);

		ret = sys_bitarray_set_bit(&ba, bit);
		zassert_equal(ret, 0,
			      "sys_bitarray_set_bit failed on bit %d", bit);
		zassert_equal(ba.bundles[bundle_idx], BIT(bit_idx_in_bundle),
			      "sys_bitarray_set_bit did not set bit %d\n", bit);
		zassert_not_equal(sys_bitfield_test_bit((mem_addr_t)ba.bundles, bit),
				  0, "sys_bitarray_set_bit did not set bit %d\n", bit);

		ret = sys_bitarray_test_bit(&ba, bit, &bit_val);
		zassert_equal(ret, 0,
			      "sys_bitarray_test_bit failed at bit %d", bit);
		zassert_equal(bit_val, 1,
			      "sys_bitarray_test_bit did not detect bit %d\n", bit);

		ret = sys_bitarray_clear_bit(&ba, bit);
		zassert_equal(ret, 0,
			      "sys_bitarray_clear_bit failed at bit %d", bit);
		zassert_equal(ba.bundles[bundle_idx], 0,
			      "sys_bitarray_clear_bit did not clear bit %d\n", bit);
		zassert_equal(sys_bitfield_test_bit((mem_addr_t)ba.bundles, bit),
			      0, "sys_bitarray_set_bit did not set bit %d\n", bit);

		ret = sys_bitarray_test_bit(&ba, bit, &bit_val);
		zassert_equal(ret, 0,
			      "sys_bitarray_test_bit failed at bit %d", bit);
		zassert_equal(bit_val, 0,
			      "sys_bitarray_test_bit erroneously detected bit %d\n",
			      bit);

		ret = sys_bitarray_test_and_set_bit(&ba, bit, &bit_val);
		zassert_equal(ret, 0,
			      "sys_bitarray_test_and_set_bit failed at bit %d", bit);
		zassert_equal(bit_val, 0,
			      "sys_bitarray_test_and_set_bit erroneously detected bit %d\n",
			      bit);
		zassert_equal(ba.bundles[bundle_idx], BIT(bit_idx_in_bundle),
			      "sys_bitarray_test_and_set_bit did not set bit %d\n", bit);
		zassert_not_equal(sys_bitfield_test_bit((mem_addr_t)ba.bundles, bit),
				  0, "sys_bitarray_set_bit did not set bit %d\n", bit);

		ret = sys_bitarray_test_and_set_bit(&ba, bit, &bit_val);
		zassert_equal(ret, 0,
			      "sys_bitarray_test_and_set_bit failed at bit %d", bit);
		zassert_equal(bit_val, 1,
			      "sys_bitarray_test_and_set_bit did not detect bit %d\n",
			      bit);
		zassert_equal(ba.bundles[bundle_idx], BIT(bit_idx_in_bundle),
			      "sys_bitarray_test_and_set_bit cleared bit %d\n", bit);
		zassert_not_equal(sys_bitfield_test_bit((mem_addr_t)ba.bundles, bit),
				  0, "sys_bitarray_set_bit did not set bit %d\n", bit);

		ret = sys_bitarray_test_and_clear_bit(&ba, bit, &bit_val);
		zassert_equal(ret, 0,
			      "sys_bitarray_test_and_clear_bit failed at bit %d", bit);
		zassert_equal(bit_val, 1,
			      "sys_bitarray_test_and_clear_bit did not detect bit %d\n",
			      bit);
		zassert_equal(ba.bundles[bundle_idx], 0,
			      "sys_bitarray_test_and_clear_bit did not clear bit %d\n",
			      bit);
		zassert_equal(sys_bitfield_test_bit((mem_addr_t)ba.bundles, bit),
			      0, "sys_bitarray_set_bit did not set bit %d\n", bit);

		ret = sys_bitarray_test_and_clear_bit(&ba, bit, &bit_val);
		zassert_equal(ret, 0,
			      "sys_bitarray_test_and_clear_bit failed at bit %d", bit);
		zassert_equal(bit_val, 0,
			      "sys_bitarray_test_and_clear_bit erroneously detected bit %d\n",
			      bit);
		zassert_equal(ba.bundles[bundle_idx], 0,
			      "sys_bitarray_test_and_clear_bit set bit %d\n",
			      bit);
		zassert_equal(sys_bitfield_test_bit((mem_addr_t)ba.bundles, bit),
			      0, "sys_bitarray_set_bit did not set bit %d\n", bit);
	}

	/* All this should fail because we go outside of
	 * total bits in bit array. Also needs to make sure bits
	 * are not changed.
	 */
	ret = sys_bitarray_set_bit(&ba, ba.num_bits);
	zassert_not_equal(ret, 0, "sys_bitarray_set_bit() should fail but not");
	zassert_true(bitarray_bundles_is_zero(&ba),
		     "sys_bitarray_set_bit() erroneously changed bitarray");

	ret = sys_bitarray_clear_bit(&ba, ba.num_bits);
	zassert_not_equal(ret, 0, "sys_bitarray_clear_bit() should fail but not");
	zassert_true(bitarray_bundles_is_zero(&ba),
		     "sys_bitarray_clear_bit() erroneously changed bitarray");

	ret = sys_bitarray_test_bit(&ba, ba.num_bits, &bit_val);
	zassert_not_equal(ret, 0, "sys_bitarray_test_bit() should fail but not");
	zassert_true(bitarray_bundles_is_zero(&ba),
		     "sys_bitarray_test_bit() erroneously changed bitarray");

	ret = sys_bitarray_test_and_set_bit(&ba, ba.num_bits, &bit_val);
	zassert_not_equal(ret, 0,
			  "sys_bitarray_test_and_set_bit() should fail but not");
	zassert_true(bitarray_bundles_is_zero(&ba),
		     "sys_bitarray_test_and_set_bit() erroneously changed bitarray");

	ret = sys_bitarray_test_and_clear_bit(&ba, ba.num_bits, &bit_val);
	zassert_not_equal(ret, 0,
			  "sys_bitarray_test_and_clear_bit() should fail but not");
	zassert_true(bitarray_bundles_is_zero(&ba),
		     "sys_bitarray_test_and_clear_bit() erroneously changed bitarray");

	ret = sys_bitarray_set_bit(&ba, -1);
	zassert_not_equal(ret, 0, "sys_bitarray_set_bit() should fail but not");
	zassert_true(bitarray_bundles_is_zero(&ba),
		     "sys_bitarray_set_bit() erroneously changed bitarray");

	ret = sys_bitarray_clear_bit(&ba, -1);
	zassert_not_equal(ret, 0, "sys_bitarray_clear_bit() should fail but not");
	zassert_true(bitarray_bundles_is_zero(&ba),
		     "sys_bitarray_clear_bit() erroneously changed bitarray");

	ret = sys_bitarray_test_bit(&ba, -1, &bit_val);
	zassert_not_equal(ret, 0, "sys_bitarray_test_bit() should fail but not");
	zassert_true(bitarray_bundles_is_zero(&ba),
		     "sys_bitarray_test_bit() erroneously changed bitarray");

	ret = sys_bitarray_test_and_set_bit(&ba, -1, &bit_val);
	zassert_not_equal(ret, 0,
			  "sys_bitarray_test_and_set_bit() should fail but not");
	zassert_true(bitarray_bundles_is_zero(&ba),
		     "sys_bitarray_test_and_set_bit() erroneously changed bitarray");

	ret = sys_bitarray_test_and_clear_bit(&ba, -1, &bit_val);
	zassert_not_equal(ret, 0,
			  "sys_bitarray_test_and_clear_bit() should fail but not");
	zassert_true(bitarray_bundles_is_zero(&ba),
		     "sys_bitarray_test_and_clear_bit() erroneously changed bitarray");
}

void alloc_and_free_predefined(void)
{
	int ret;
	size_t offset;

	uint32_t ba_128_expected[4];

	SYS_BITARRAY_DEFINE(ba_128, 128);

	printk("Testing bit array alloc and free with predefined patterns\n");

	/* Pre-populate the bits */
	ba_128.bundles[0] = 0x0F0F070F;
	ba_128.bundles[1] = 0x0F0F0F0F;
	ba_128.bundles[2] = 0x0F0F0F0F;
	ba_128.bundles[3] = 0x0F0F0000;

	/* Expected values */
	ba_128_expected[0] = 0x0F0FFF0F;
	ba_128_expected[1] = 0x0F0F0F0F;
	ba_128_expected[2] = 0x0F0F0F0F;
	ba_128_expected[3] = 0x0F0F0000;

	ret = sys_bitarray_alloc(&ba_128, 5, &offset);
	zassert_equal(ret, 0, "sys_bitarray_alloc() failed: %d", ret);
	zassert_equal(offset, 11, "sys_bitarray_alloc() offset expected %d, got %d", 11, offset);
	zassert_true(cmp_u32_arrays(ba_128.bundles, ba_128_expected, ba_128.num_bundles),
		     "sys_bitarray_alloc() failed bits comparison");

	ret = sys_bitarray_alloc(&ba_128, 16, &offset);
	ba_128_expected[2] = 0xFF0F0F0F;
	ba_128_expected[3] = 0x0F0F0FFF;
	zassert_equal(ret, 0, "sys_bitarray_alloc() failed: %d", ret);
	zassert_equal(offset, 92, "sys_bitarray_alloc() offset expected %d, got %d", 92, offset);
	zassert_true(cmp_u32_arrays(ba_128.bundles, ba_128_expected, ba_128.num_bundles),
		     "sys_bitarray_alloc() failed bits comparison");

	ret = sys_bitarray_free(&ba_128, 5, 11);
	ba_128_expected[0] = 0x0F0F070F;
	zassert_equal(ret, 0, "sys_bitarray_free() failed: %d", ret);
	zassert_true(cmp_u32_arrays(ba_128.bundles, ba_128_expected, ba_128.num_bundles),
		     "sys_bitarray_free() failed bits comparison");

	ret = sys_bitarray_free(&ba_128, 5, 0);
	zassert_not_equal(ret, 0, "sys_bitarray_free() should fail but not");
	zassert_true(cmp_u32_arrays(ba_128.bundles, ba_128_expected, ba_128.num_bundles),
		     "sys_bitarray_free() failed bits comparison");

	ret = sys_bitarray_free(&ba_128, 24, 92);
	zassert_not_equal(ret, 0, "sys_bitarray_free() should fail but not");
	zassert_true(cmp_u32_arrays(ba_128.bundles, ba_128_expected, ba_128.num_bundles),
		     "sys_bitarray_free() failed bits comparison");

	ret = sys_bitarray_free(&ba_128, 16, 92);
	ba_128_expected[2] = 0x0F0F0F0F;
	ba_128_expected[3] = 0x0F0F0000;
	zassert_equal(ret, 0, "sys_bitarray_free() failed: %d", ret);
	zassert_true(cmp_u32_arrays(ba_128.bundles, ba_128_expected, ba_128.num_bundles),
		     "sys_bitarray_free() failed bits comparison");
}

size_t get_bitarray_popcnt(sys_bitarray_t *ba)
{
	size_t popcnt = 0;
	unsigned int idx;

	for (idx = 0; idx < ba->num_bundles; idx++) {
		popcnt += popcount(ba->bundles[idx]);
	}

	return popcnt;
}

void alloc_and_free_loop(int divisor)
{
	int ret;
	size_t offset;
	size_t bit;
	size_t num_bits;
	size_t cur_popcnt;
	size_t expected_popcnt = 0;

	SYS_BITARRAY_DEFINE(ba, 234);

	printk("Testing bit array alloc and free with divisor %d\n", divisor);

	for (bit = 0U; bit < ba.num_bits; ++bit) {
		cur_popcnt = get_bitarray_popcnt(&ba);
		zassert_equal(cur_popcnt, expected_popcnt,
			      "bit count expeceted %u, got %u (at bit %u)",
			      expected_popcnt, cur_popcnt, bit);

		/* Allocate half of remaining bits */
		num_bits = (ba.num_bits - bit) / divisor;

		ret = sys_bitarray_alloc(&ba, num_bits, &offset);
		if (num_bits == 0) {
			zassert_not_equal(ret, 0,
					  "sys_bitarray_free() should fail but not (bit %u)",
					  bit);
		} else {
			zassert_equal(ret, 0,
				      "sys_bitarray_alloc() failed (%d) at bit %u",
				      ret, bit);
			zassert_equal(offset, bit,
				      "sys_bitarray_alloc() offset expected %d, got %d",
				      bit, offset);

			expected_popcnt += num_bits;
		}

		cur_popcnt = get_bitarray_popcnt(&ba);
		zassert_equal(cur_popcnt, expected_popcnt,
			      "bit count expeceted %u, got %u (at bit %u)",
			      expected_popcnt, cur_popcnt, bit);

		/* Free all but the first bit of allocated region */
		ret = sys_bitarray_free(&ba, (num_bits - 1), (bit + 1));
		if ((num_bits == 0) || ((num_bits - 1) == 0)) {
			zassert_not_equal(ret, 0,
					  "sys_bitarray_free() should fail but not (bit %u)",
					  bit);
		} else {
			zassert_equal(ret, 0,
				      "sys_bitarray_free() failed (%d) at bit %u",
				      ret, (bit + 1));

			expected_popcnt -= num_bits - 1;
		}
	}
}

void alloc_and_free_interval(void)
{
	int ret;
	size_t cnt;
	size_t offset;
	size_t expected_offset;
	size_t expected_popcnt, cur_popcnt;

	/* Make sure number of bits is multiple of 8 */
	SYS_BITARRAY_DEFINE(ba, 152);

	printk("Testing bit array interval alloc and free\n");

	/* Pre-populate the bits so that 4-bit already allocated,
	 * then 4 free bits, and repeat.
	 */
	for (cnt = 0; cnt < ba.num_bundles; cnt++) {
		ba.bundles[cnt] = 0x0F0F0F0F;
	}

	expected_offset = 4;
	expected_popcnt = get_bitarray_popcnt(&ba);
	for (cnt = 0; cnt <= (ba.num_bits / 8); cnt++) {

		ret = sys_bitarray_alloc(&ba, 4, &offset);
		if (cnt == (ba.num_bits / 8)) {
			zassert_not_equal(ret, 0,
					  "sys_bitarray_free() should fail but not (cnt %u)",
					  cnt);
		} else {
			zassert_equal(ret, 0,
				      "sys_bitarray_alloc() failed (%d) (cnt %u)",
				      ret, cnt);

			zassert_equal(offset, expected_offset,
				      "offset expeceted %u, got %u (cnt %u)",
				      expected_offset, offset, cnt);

			expected_popcnt += 4;

			cur_popcnt = get_bitarray_popcnt(&ba);
			zassert_equal(cur_popcnt, expected_popcnt,
				      "bit count expeceted %u, got %u (cnt %u)",
				      expected_popcnt, cur_popcnt, cnt);


			expected_offset += 8;
		}
	}
}

/**
 * @brief Test bitarrays allocation and free
 *
 * @see sys_bitarray_alloc()
 * @see sys_bitarray_free()
 */
void test_bitarray_alloc_free(void)
{
	int i;

	/* Bitarrays have embedded spinlocks and can't on the stack. */
	if (IS_ENABLED(CONFIG_KERNEL_COHERENCE)) {
		ztest_test_skip();
	}

	alloc_and_free_predefined();

	i = 1;
	while (i < 65) {
		alloc_and_free_loop(i);

		i *= 2;
	}

	alloc_and_free_interval();
}

void test_bitarray_region_set_clear(void)
{
	int ret;

	/* Bitarrays have embedded spinlocks and can't on the stack. */
	if (IS_ENABLED(CONFIG_KERNEL_COHERENCE)) {
		ztest_test_skip();
	}

	uint32_t ba_expected[4];

	SYS_BITARRAY_DEFINE(ba, 64);

	printk("Testing bit array region bit tests\n");

	/* Pre-populate the bits */
	ba.bundles[0] = 0xFF0F0F0F;
	ba.bundles[1] = 0x0F0F0FFF;

	zassert_true(sys_bitarray_is_region_set(&ba,  4,  0), NULL);
	zassert_true(sys_bitarray_is_region_set(&ba, 12, 32), NULL);
	zassert_true(sys_bitarray_is_region_set(&ba,  8, 32), NULL);
	zassert_true(sys_bitarray_is_region_set(&ba, 14, 30), NULL);
	zassert_true(sys_bitarray_is_region_set(&ba, 20, 24), NULL);

	zassert_false(sys_bitarray_is_region_cleared(&ba,  4,  0), NULL);
	zassert_false(sys_bitarray_is_region_cleared(&ba, 12, 32), NULL);
	zassert_false(sys_bitarray_is_region_cleared(&ba,  8, 32), NULL);
	zassert_false(sys_bitarray_is_region_cleared(&ba, 14, 30), NULL);
	zassert_false(sys_bitarray_is_region_cleared(&ba, 20, 24), NULL);

	ba.bundles[0] = ~ba.bundles[0];
	ba.bundles[1] = ~ba.bundles[1];

	zassert_true(sys_bitarray_is_region_cleared(&ba,  4,  0), NULL);
	zassert_true(sys_bitarray_is_region_cleared(&ba, 12, 32), NULL);
	zassert_true(sys_bitarray_is_region_cleared(&ba,  8, 32), NULL);
	zassert_true(sys_bitarray_is_region_cleared(&ba, 14, 30), NULL);
	zassert_true(sys_bitarray_is_region_cleared(&ba, 20, 24), NULL);

	zassert_false(sys_bitarray_is_region_set(&ba,  4,  0), NULL);
	zassert_false(sys_bitarray_is_region_set(&ba, 12, 32), NULL);
	zassert_false(sys_bitarray_is_region_set(&ba,  8, 32), NULL);
	zassert_false(sys_bitarray_is_region_set(&ba, 14, 30), NULL);
	zassert_false(sys_bitarray_is_region_set(&ba, 20, 24), NULL);

	zassert_false(sys_bitarray_is_region_set(&ba, 10, 60), NULL);
	zassert_false(sys_bitarray_is_region_cleared(&ba, 10, 60), NULL);
	zassert_false(sys_bitarray_is_region_set(&ba, 8, 120), NULL);
	zassert_false(sys_bitarray_is_region_cleared(&ba, 8, 120), NULL);

	printk("Testing bit array region bit manipulations\n");

	/* Pre-populate the bits */
	ba.bundles[0] = 0xFF0F0F0F;
	ba.bundles[1] = 0x0F0F0FFF;

	/* Expected values */
	ba_expected[0] = 0xFF0F0F0F;
	ba_expected[1] = 0x0F0F0FFF;

	ret = sys_bitarray_set_region(&ba, 4, 0);
	zassert_equal(ret, 0, "sys_bitarray_set_region() failed: %d", ret);
	zassert_true(cmp_u32_arrays(ba.bundles, ba_expected, ba.num_bundles),
		     "sys_bitarray_set_region() failed bits comparison");

	ret = sys_bitarray_set_region(&ba, 4, 4);
	ba_expected[0] = 0xFF0F0FFF;
	zassert_equal(ret, 0, "sys_bitarray_set_region() failed: %d", ret);
	zassert_true(cmp_u32_arrays(ba.bundles, ba_expected, ba.num_bundles),
		     "sys_bitarray_set_region() failed bits comparison");

	ret = sys_bitarray_clear_region(&ba, 4, 4);
	ba_expected[0] = 0xFF0F0F0F;
	zassert_equal(ret, 0, "sys_bitarray_clear_region() failed: %d", ret);
	zassert_true(cmp_u32_arrays(ba.bundles, ba_expected, ba.num_bundles),
		     "sys_bitarray_clear_region() failed bits comparison");

	ret = sys_bitarray_clear_region(&ba, 14, 30);
	ba_expected[0] = 0x3F0F0F0F;
	ba_expected[1] = 0x0F0F0000;
	zassert_equal(ret, 0, "sys_bitarray_clear_region() failed: %d", ret);
	zassert_true(cmp_u32_arrays(ba.bundles, ba_expected, ba.num_bundles),
		     "sys_bitarray_clear_region() failed bits comparison");

	ret = sys_bitarray_set_region(&ba, 14, 30);
	ba_expected[0] = 0xFF0F0F0F;
	ba_expected[1] = 0x0F0F0FFF;
	zassert_equal(ret, 0, "sys_bitarray_set_region() failed: %d", ret);
	zassert_true(cmp_u32_arrays(ba.bundles, ba_expected, ba.num_bundles),
		     "sys_bitarray_set_region() failed bits comparison");

	ret = sys_bitarray_set_region(&ba, 10, 60);
	zassert_equal(ret, -EINVAL, "sys_bitarray_set_region() should fail but not");
	zassert_true(cmp_u32_arrays(ba.bundles, ba_expected, ba.num_bundles),
		     "sys_bitarray_set_region() failed bits comparison");

	ret = sys_bitarray_set_region(&ba, 8, 120);
	zassert_equal(ret, -EINVAL, "sys_bitarray_set_region() should fail but not");
	zassert_true(cmp_u32_arrays(ba.bundles, ba_expected, ba.num_bundles),
		     "sys_bitarray_set_region() failed bits comparison");

	ret = sys_bitarray_clear_region(&ba, 10, 60);
	zassert_equal(ret, -EINVAL, "sys_bitarray_clear_region() should fail but not");
	zassert_true(cmp_u32_arrays(ba.bundles, ba_expected, ba.num_bundles),
		     "sys_bitarray_clear_region() failed bits comparison");

	ret = sys_bitarray_clear_region(&ba, 8, 120);
	zassert_equal(ret, -EINVAL, "sys_bitarray_clear_region() should fail but not");
	zassert_true(cmp_u32_arrays(ba.bundles, ba_expected, ba.num_bundles),
		     "sys_bitarray_clear_region() failed bits comparison");
}

/**
 * @}
 */
