Files
flexnbd-c/tests/unit/check_bitset.c

501 lines
12 KiB
C
Raw Normal View History

#include <check.h>
#include "bitset.h"
#define assert_bitset_is( map, val ) {\
uint64_t *num = (uint64_t*) map->bits; \
ck_assert_int_eq( val, *num ); \
}
START_TEST(test_bit_set)
{
uint64_t num = 0;
char *bits = (char*) &num;
#define TEST_BIT_SET(bit, newvalue) \
bit_set(bits, (bit)); \
fail_unless(num == (newvalue), "num was %x instead of %x", num, (newvalue));
TEST_BIT_SET(0, 1);
TEST_BIT_SET(1, 3);
TEST_BIT_SET(2, 7);
TEST_BIT_SET(7, 0x87);
TEST_BIT_SET(63, 0x8000000000000087);
}
END_TEST
START_TEST(test_bit_clear)
{
uint64_t num = 0xffffffffffffffff;
char *bits = (char*) &num;
#define TEST_BIT_CLEAR(bit, newvalue) \
bit_clear(bits, (bit)); \
fail_unless(num == (newvalue), "num was %x instead of %x", num, (newvalue));
TEST_BIT_CLEAR(0, 0xfffffffffffffffe);
TEST_BIT_CLEAR(1, 0xfffffffffffffffc);
TEST_BIT_CLEAR(2, 0xfffffffffffffff8);
TEST_BIT_CLEAR(7, 0xffffffffffffff78);
TEST_BIT_CLEAR(63,0x7fffffffffffff78);
}
END_TEST
START_TEST(test_bit_tests)
{
uint64_t num = 0x5555555555555555;
char *bits = (char*) &num;
fail_unless(bit_has_value(bits, 0, 1), "bit_has_value malfunction");
fail_unless(bit_has_value(bits, 1, 0), "bit_has_value malfunction");
fail_unless(bit_has_value(bits, 63, 0), "bit_has_value malfunction");
fail_unless(bit_is_set(bits, 0), "bit_is_set malfunction");
fail_unless(bit_is_clear(bits, 1), "bit_is_clear malfunction");
fail_unless(bit_is_set(bits, 62), "bit_is_set malfunction");
fail_unless(bit_is_clear(bits, 63), "bit_is_clear malfunction");
}
END_TEST
START_TEST(test_bit_ranges)
{
char buffer[4160];
uint64_t *longs = (unsigned long*) buffer;
uint64_t i;
memset(buffer, 0, 4160);
for (i=0; i<64; i++) {
bit_set_range(buffer, i*64, i);
fail_unless(
longs[i] == (1UL<<i)-1,
"longs[%ld] = %lx SHOULD BE %lx",
i, longs[i], (1L<<i)-1
);
fail_unless(longs[i+1] == 0, "bit_set_range overshot at i=%d", i);
}
for (i=0; i<64; i++) {
bit_clear_range(buffer, i*64, i);
fail_unless(longs[i] == 0, "bit_clear_range didn't work at i=%d", i);
}
}
END_TEST
START_TEST(test_bit_runs)
{
char buffer[256];
int i, ptr=0, runs[] = {
56,97,22,12,83,1,45,80,85,51,64,40,63,67,75,64,94,81,79,62
};
memset(buffer,0,256);
for (i=0; i < 20; i += 2) {
ptr += runs[i];
bit_set_range(buffer, ptr, runs[i+1]);
ptr += runs[i+1];
}
ptr = 0;
for (i=0; i < 20; i += 1) {
int run = bit_run_count(buffer, ptr, 2048-ptr, NULL);
fail_unless(
run == runs[i],
"run %d should have been %d, was %d",
i, runs[i], run
);
ptr += runs[i];
}
}
END_TEST
START_TEST(test_bitset)
{
struct bitset * map;
uint64_t *num;
map = bitset_alloc(6400, 100);
num = (uint64_t*) map->bits;
bitset_set_range(map,0,50);
ck_assert_int_eq(1, *num);
bitset_set_range(map,99,1);
ck_assert_int_eq(1, *num);
bitset_set_range(map,100,1);
ck_assert_int_eq(3, *num);
bitset_set_range(map,0,800);
ck_assert_int_eq(255, *num);
bitset_set_range(map,1499,2);
ck_assert_int_eq(0xc0ff, *num);
bitset_clear_range(map,1499,2);
ck_assert_int_eq(255, *num);
*num = 0;
bitset_set_range(map, 1499, 2);
bitset_clear_range(map, 1300, 200);
ck_assert_int_eq(0x8000, *num);
*num = 0;
bitset_set_range(map, 0, 6400);
ck_assert_int_eq(0xffffffffffffffff, *num);
bitset_clear_range(map, 3200, 400);
ck_assert_int_eq(0xfffffff0ffffffff, *num);
}
END_TEST
2012-06-22 10:05:41 +01:00
START_TEST( test_bitset_set )
{
struct bitset * map;
2013-07-25 10:58:50 +01:00
uint64_t run;
2012-06-22 10:05:41 +01:00
map = bitset_alloc(64, 1);
assert_bitset_is( map, 0x0000000000000000 );
bitset_set( map );
assert_bitset_is( map, 0xffffffffffffffff );
bitset_free( map );
map = bitset_alloc( 6400, 100 );
assert_bitset_is( map, 0x0000000000000000 );
2012-06-22 10:05:41 +01:00
bitset_set( map );
assert_bitset_is( map, 0xffffffffffffffff );
bitset_free( map );
2013-07-25 10:58:50 +01:00
// Now do something large and representative
map = bitset_alloc( 53687091200, 4096 );
bitset_set( map );
run = bitset_run_count( map, 0, 53687091200 );
ck_assert_int_eq( run, 53687091200 );
bitset_free( map );
2013-07-25 10:58:50 +01:00
2012-06-22 10:05:41 +01:00
}
END_TEST
START_TEST( test_bitset_clear )
{
struct bitset * map;
2012-06-22 10:05:41 +01:00
uint64_t *num;
2013-07-25 10:58:50 +01:00
uint64_t run;
2012-06-22 10:05:41 +01:00
map = bitset_alloc(64, 1);
num = (uint64_t*) map->bits;
ck_assert_int_eq( 0x0000000000000000, *num );
bitset_set( map );
bitset_clear( map );
ck_assert_int_eq( 0x0000000000000000, *num );
2013-07-25 10:58:50 +01:00
bitset_free( map );
2013-07-25 10:58:50 +01:00
// Now do something large and representative
map = bitset_alloc( 53687091200, 4096 );
bitset_set( map );
bitset_clear( map );
run = bitset_run_count( map, 0, 53687091200 );
ck_assert_int_eq( run, 53687091200 );
bitset_free( map );
2013-07-25 10:58:50 +01:00
}
END_TEST
START_TEST( test_bitset_set_range )
{
struct bitset* map = bitset_alloc( 64, 1 );
2013-07-25 10:58:50 +01:00
assert_bitset_is( map, 0x0000000000000000 );
bitset_set_range( map, 8, 8 );
assert_bitset_is( map, 0x000000000000ff00 );
bitset_clear( map );
assert_bitset_is( map, 0x0000000000000000 );
bitset_set_range( map, 0, 0 );
assert_bitset_is( map, 0x0000000000000000 );
bitset_free( map );
2013-07-25 10:58:50 +01:00
}
END_TEST
START_TEST( test_bitset_clear_range )
{
struct bitset* map = bitset_alloc( 64, 1 );
2013-07-25 10:58:50 +01:00
bitset_set( map );
assert_bitset_is( map, 0xffffffffffffffff );
bitset_clear_range( map, 8, 8 );
assert_bitset_is( map, 0xffffffffffff00ff );
bitset_set( map );
assert_bitset_is( map, 0xffffffffffffffff );
bitset_clear_range( map, 0, 0 );
assert_bitset_is( map, 0xffffffffffffffff );
bitset_free( map );
2012-06-22 10:05:41 +01:00
}
END_TEST
START_TEST( test_bitset_run_count )
{
struct bitset* map = bitset_alloc( 64, 1 );
uint64_t run;
assert_bitset_is( map, 0x0000000000000000 );
2013-07-24 17:42:08 +01:00
run = bitset_run_count( map, 0, 64 );
ck_assert_int_eq( 64, run );
bitset_set_range( map, 0, 32 );
assert_bitset_is( map, 0x00000000ffffffff );
run = bitset_run_count( map, 0, 64 );
ck_assert_int_eq( 32, run );
run = bitset_run_count( map, 0, 16 );
ck_assert_int_eq( 16, run );
run = bitset_run_count( map, 16, 64 );
ck_assert_int_eq( 16, run );
run = bitset_run_count( map, 31, 64 );
ck_assert_int_eq( 1, run );
run = bitset_run_count( map, 32, 64 );
ck_assert_int_eq( 32, run );
run = bitset_run_count( map, 32, 32 );
ck_assert_int_eq( 32, run );
run = bitset_run_count( map, 32, 16 );
ck_assert_int_eq( 16, run );
bitset_free( map );
map = bitset_alloc( 6400, 100 );
2013-07-24 17:42:08 +01:00
assert_bitset_is( map, 0x0000000000000000 );
run = bitset_run_count( map, 0, 6400 );
ck_assert_int_eq( 6400, run );
bitset_set_range( map, 0, 3200 );
run = bitset_run_count( map, 0, 6400 );
ck_assert_int_eq( 3200, run );
run = bitset_run_count( map, 1, 6400 );
ck_assert_int_eq( 3199, run );
run = bitset_run_count( map, 3200, 6400 );
ck_assert_int_eq( 3200, run );
run = bitset_run_count( map, 6500, 6400 );
ck_assert_int_eq( 0, run );
bitset_free( map );
2013-07-24 17:42:08 +01:00
// Now do something large and representative
map = bitset_alloc( 53687091200, 4096 );
bitset_set( map );
run = bitset_run_count( map, 0, 53687091200 );
ck_assert_int_eq( run, 53687091200 );
bitset_free( map );
2013-07-24 17:42:08 +01:00
}
END_TEST
2012-06-22 10:05:41 +01:00
START_TEST( test_bitset_set_range_doesnt_push_to_stream )
{
struct bitset *map = bitset_alloc( 64, 1 );
bitset_set_range( map, 0, 64 );
ck_assert_int_eq( 0, bitset_stream_size( map ) );
bitset_free( map );
}
END_TEST
START_TEST( test_bitset_clear_range_doesnt_push_to_stream )
{
struct bitset *map = bitset_alloc( 64, 1 );
bitset_clear_range( map, 0, 64 );
ck_assert_int_eq( 0, bitset_stream_size( map ) );
bitset_free( map );
}
END_TEST
START_TEST(test_bitset_enable_stream)
{
struct bitset *map = bitset_alloc( 64, 1 );
struct bitset_stream_entry result;
memset( &result, 0, sizeof( result ) );
bitset_enable_stream( map );
ck_assert_int_eq( 1, map->stream_enabled );
bitset_stream_dequeue( map, &result );
ck_assert_int_eq( BITSET_STREAM_ON, result.event );
ck_assert_int_eq( 0, result.from );
ck_assert_int_eq( 64, result.len );
bitset_free( map );
}
END_TEST
START_TEST(test_bitset_disable_stream)
{
struct bitset *map = bitset_alloc( 64, 1 );
struct bitset_stream_entry result;
memset( &result, 0, sizeof( result ) );
bitset_enable_stream( map );
bitset_disable_stream( map );
ck_assert_int_eq( 0, map->stream_enabled );
ck_assert_int_eq( 2, bitset_stream_size( map ) );
bitset_stream_dequeue( map, NULL ); // ON
bitset_stream_dequeue( map, &result ); // OFF
ck_assert_int_eq( BITSET_STREAM_OFF, result.event );
ck_assert_int_eq( 0, result.from );
ck_assert_int_eq( 64, result.len );
bitset_free( map );
}
END_TEST
START_TEST(test_bitset_stream_with_set_range)
{
struct bitset *map = bitset_alloc( 64, 1 );
struct bitset_stream_entry result;
memset( &result, 0, sizeof( result ) );
bitset_enable_stream( map );
bitset_set_range( map, 0, 32 );
ck_assert_int_eq( 2, bitset_stream_size( map ) );
bitset_stream_dequeue( map, NULL ); // ON
bitset_stream_dequeue( map, &result ); // SET
ck_assert_int_eq( BITSET_STREAM_SET, result.event );
ck_assert_int_eq( 0, result.from );
ck_assert_int_eq( 32, result.len );
bitset_free( map );
}
END_TEST
START_TEST(test_bitset_stream_with_clear_range)
{
struct bitset *map = bitset_alloc( 64, 1 );
struct bitset_stream_entry result;
memset( &result, 0, sizeof( result ) );
bitset_enable_stream( map );
bitset_clear_range( map, 0, 32 );
ck_assert_int_eq( 2, bitset_stream_size( map ) );
bitset_stream_dequeue( map, NULL ); // ON
bitset_stream_dequeue( map, &result ); // UNSET
ck_assert_int_eq( BITSET_STREAM_UNSET, result.event );
ck_assert_int_eq( 0, result.from );
ck_assert_int_eq( 32, result.len );
bitset_free( map );
}
END_TEST
START_TEST(test_bitset_stream_size)
{
struct bitset *map = bitset_alloc( 64, 1 );
bitset_enable_stream( map );
bitset_set_range( map, 0, 32 );
bitset_set_range( map, 16, 32 );
bitset_set_range( map, 7, 16 );
bitset_clear_range( map, 0, 32 );
bitset_clear_range( map, 16, 32 );
bitset_clear_range( map, 48, 16 );
bitset_disable_stream( map );
ck_assert_int_eq( 8, bitset_stream_size( map ) );
bitset_free( map );
}
END_TEST
START_TEST(test_bitset_stream_queued_bytes)
{
struct bitset *map = bitset_alloc( 64, 1 );
bitset_enable_stream( map );
bitset_set_range( map, 0, 32 );
bitset_set_range( map, 16, 32 );
bitset_set_range( map, 7, 16 );
bitset_clear_range( map, 0, 32 );
bitset_clear_range( map, 16, 32 );
bitset_clear_range( map, 48, 16 );
bitset_clear_range( map, 0, 2 );
bitset_disable_stream( map );
ck_assert_int_eq( 64, bitset_stream_queued_bytes( map, BITSET_STREAM_ON ) );
ck_assert_int_eq( 80, bitset_stream_queued_bytes( map, BITSET_STREAM_SET ) );
ck_assert_int_eq( 82, bitset_stream_queued_bytes( map, BITSET_STREAM_UNSET ) );
ck_assert_int_eq( 64, bitset_stream_queued_bytes( map, BITSET_STREAM_OFF ) );
bitset_free( map );
}
END_TEST
Suite* bitset_suite(void)
{
Suite *s = suite_create("bitset");
2012-06-22 10:05:41 +01:00
TCase *tc_bit = tcase_create("bit");
tcase_add_test(tc_bit, test_bit_set);
tcase_add_test(tc_bit, test_bit_clear);
tcase_add_test(tc_bit, test_bit_tests);
tcase_add_test(tc_bit, test_bit_ranges);
tcase_add_test(tc_bit, test_bit_runs);
suite_add_tcase(s, tc_bit);
TCase *tc_bitset = tcase_create("bitset");
2012-06-22 10:05:41 +01:00
tcase_add_test(tc_bitset, test_bitset);
tcase_add_test(tc_bitset, test_bitset_set);
tcase_add_test(tc_bitset, test_bitset_clear);
tcase_add_test(tc_bitset, test_bitset_run_count);
2013-07-25 10:58:50 +01:00
tcase_add_test(tc_bitset, test_bitset_set_range);
tcase_add_test(tc_bitset, test_bitset_clear_range);
tcase_add_test(tc_bitset, test_bitset_set_range_doesnt_push_to_stream);
tcase_add_test(tc_bitset, test_bitset_clear_range_doesnt_push_to_stream);
2012-06-22 10:05:41 +01:00
suite_add_tcase(s, tc_bitset);
TCase *tc_bitset_stream = tcase_create("bitset_stream");
tcase_add_test(tc_bitset_stream, test_bitset_enable_stream);
tcase_add_test(tc_bitset_stream, test_bitset_disable_stream);
tcase_add_test(tc_bitset_stream, test_bitset_stream_with_set_range);
tcase_add_test(tc_bitset_stream, test_bitset_stream_with_clear_range);
tcase_add_test(tc_bitset_stream, test_bitset_stream_size);
tcase_add_test(tc_bitset_stream, test_bitset_stream_queued_bytes);
suite_add_tcase(s, tc_bitset_stream);
return s;
}
int main(void)
{
int number_failed;
Suite *s = bitset_suite();
SRunner *sr = srunner_create(s);
srunner_run_all(sr, CK_NORMAL);
number_failed = srunner_ntests_failed(sr);
srunner_free(sr);
return (number_failed == 0) ? 0 : 1;
}