| // SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) | |
| #include <stdio.h> | |
| #include <stdbool.h> | |
| #include <valgrind/memcheck.h> | |
| #include <ccan/array_size.h> | |
| #include <util/bitmap.h> | |
| static int failed_tests; | |
| #define EXPECT_EQ(expected, actual) \ | |
| ({ \ | |
| typeof(expected) _expected = (expected); \ | |
| typeof(actual) _actual = (actual); \ | |
| if (_expected != _actual) { \ | |
| printf(" FAIL at line %d: %s not %s\n", __LINE__, \ | |
| #expected, #actual); \ | |
| printf("\tExpected: %ld\n", (long) _expected); \ | |
| printf("\t Actual: %ld\n", (long) _actual); \ | |
| failed_tests++; \ | |
| } \ | |
| }) | |
| #define EXPECT_TRUE(actual) EXPECT_EQ(true, actual) | |
| #define EXPECT_FALSE(actual) EXPECT_EQ(false, actual) | |
| static void test_bitmap_empty(unsigned long *bmp, const int nbits) | |
| { | |
| for (int i = 1; i < nbits; i++) { | |
| bitmap_zero(bmp, nbits); | |
| EXPECT_TRUE(bitmap_empty(bmp, nbits)); | |
| bitmap_set_bit(bmp, i); | |
| EXPECT_TRUE(bitmap_empty(bmp, i)); | |
| EXPECT_FALSE(bitmap_empty(bmp, i + 1)); | |
| } | |
| } | |
| static void test_bitmap_find_first_bit(unsigned long *bmp, const int nbits) | |
| { | |
| bitmap_zero(bmp, nbits); | |
| for (int i = 0; i < nbits; i++) { | |
| EXPECT_EQ(nbits, bitmap_find_first_bit(bmp, 0, nbits)); | |
| bitmap_set_bit(bmp, i); | |
| EXPECT_EQ(i, bitmap_find_first_bit(bmp, 0, nbits)); | |
| EXPECT_EQ(i, bitmap_find_first_bit(bmp, i, nbits)); | |
| EXPECT_EQ(i, bitmap_find_first_bit(bmp, 0, i + 1)); | |
| EXPECT_EQ(i, bitmap_find_first_bit(bmp, 0, i)); | |
| EXPECT_EQ(nbits, bitmap_find_first_bit(bmp, i + 1, nbits)); | |
| bitmap_clear_bit(bmp, i); | |
| } | |
| } | |
| static void test_bitmap_zero_region(unsigned long *bmp, const int nbits) | |
| { | |
| for (int end = 0; end <= nbits; end++) { | |
| int bit = end / 2; | |
| bitmap_fill(bmp, nbits); | |
| bitmap_zero_region(bmp, bit, end); | |
| for (int i = 0; i < nbits; i++) { | |
| bool expected = i < bit || i >= end; | |
| EXPECT_EQ(expected, bitmap_test_bit(bmp, i)); | |
| } | |
| } | |
| } | |
| static void test_bitmap_fill_region(unsigned long *bmp, const int nbits) | |
| { | |
| for (int end = 0; end <= nbits; end++) { | |
| int bit = end / 2; | |
| bitmap_zero(bmp, nbits); | |
| bitmap_fill_region(bmp, bit, end); | |
| for (int i = 0; i < nbits; i++) { | |
| bool expected = i >= bit && i < end; | |
| EXPECT_EQ(expected, bitmap_test_bit(bmp, i)); | |
| } | |
| } | |
| } | |
| static void test_bitmap_find_free_region(unsigned long *bmp, const int nbits) | |
| { | |
| for (int region_size = 1; region_size <= nbits; region_size++) { | |
| int start = nbits - region_size; | |
| bitmap_zero(bmp, nbits); | |
| EXPECT_EQ(0, bitmap_find_free_region(bmp, nbits, region_size)); | |
| if (start > region_size) | |
| bitmap_fill_region(bmp, region_size - 1, start); | |
| else | |
| bitmap_fill_region(bmp, 0, start); | |
| EXPECT_EQ(start, bitmap_find_free_region(bmp, nbits, region_size)); | |
| } | |
| } | |
| int main(int argc, char **argv) | |
| { | |
| int all_failed_tests = 0; | |
| int nbitsv[] = { | |
| BITS_PER_LONG, | |
| BITS_PER_LONG - 1, | |
| BITS_PER_LONG + 1, | |
| BITS_PER_LONG / 2, | |
| BITS_PER_LONG * 2, | |
| }; | |
| for (int i = 0; i < ARRAY_SIZE(nbitsv); i++) { | |
| int nbits = nbitsv[i]; | |
| unsigned long *bmp = bitmap_alloc0(nbits); | |
| #define TEST(func_name) do { \ | |
| VALGRIND_MAKE_MEM_UNDEFINED(bmp, BITS_TO_LONGS(nbits) * sizeof(long)); \ | |
| failed_tests = 0; \ | |
| (func_name)(bmp, nbits); \ | |
| printf("%6s %s(nbits=%d)\n", failed_tests ? "FAILED" : "OK", #func_name, \ | |
| nbits); \ | |
| all_failed_tests += failed_tests; \ | |
| } while (0) | |
| TEST(test_bitmap_empty); | |
| TEST(test_bitmap_find_first_bit); | |
| TEST(test_bitmap_zero_region); | |
| TEST(test_bitmap_fill_region); | |
| TEST(test_bitmap_find_free_region); | |
| #undef TEST | |
| printf("\n"); | |
| free(bmp); | |
| } | |
| if (all_failed_tests) { | |
| printf("%d tests failed\n", all_failed_tests); | |
| return 1; | |
| } | |
| return 0; | |
| } |