|
From: Kenn H. <ke...@us...> - 2005-03-21 18:56:20
|
Update of /cvsroot/linux-vax/kernel-2.5/init In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14413 Modified Files: apitest.c Log Message: Add some checksum tests. Use 'archtest' as the function prefix, rather than 'apitest'. Re-design the TEST() macro to handle different types and print both actual and expected results. Add a module parameter to verbosely print passes as well as failures. Index: apitest.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.5/init/apitest.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- apitest.c 27 Feb 2005 21:33:14 -0000 1.2 +++ apitest.c 21 Mar 2005 18:55:57 -0000 1.3 @@ -1,5 +1,15 @@ +/* + * This code tests various, easily-testable parts of the "API" + * implemented by the arch-dependent code. + * You can run the tests on a live system by compiling it as + * a loadable module and loading it. + * If you compile this module into the kernel, the tests will be + * run shortly after computing the BogoMIPS value. + */ + #include <linux/module.h> #include <linux/bitops.h> +#include <net/checksum.h> #include <asm/atomic.h> #include <asm/byteorder.h> @@ -8,44 +18,109 @@ * TODO: * o Fire off kernel threads to test atomicity of atomic operations. * o Test operations exported by <asm/bitops.h> - * o Test operations exported by <asm/checksum.h> + * o Test more operations exported by <asm/checksum.h> */ +static int verbose; + +module_param(verbose, int, 0444); +MODULE_PARM_DESC(verbose, "Run tests verbosely (i.e. print PASS as well as FAIL)"); + #define TEST(expr) do { \ if (!(expr)) { \ - test_failed = 1; \ - printk("apitest: FAIL line %d: %s\n", __LINE__, #expr); \ + failed++; \ + printk("archtest:%d: FAIL %s\n", __LINE__, #expr); \ } else if (verbose) { \ - printk("apitest: PASS line %d: %s\n", __LINE__, #expr); \ + printk("archtest:%d: PASS %s\n", __LINE__, #expr); \ } \ } while (0) -static int test_failed; +#define TEST_(sign, type, format, expr, v) do { \ + sign type actual = (expr); \ + sign type expected = (v); \ + if (actual != expected) { \ + failed++; \ + printk("archtest:%d: FAIL %s == %s (was %" format "/0x%x)\n", __LINE__, #expr, #v, actual, actual); \ + } else if (verbose) { \ + printk("archtest:%d: PASS %s == %s\n", __LINE__, #expr, #v); \ + } \ +} while (0) -/* Fixme: make this a module parameter */ -static int verbose = 0; +#define TEST_USHORT(expr, v) TEST_(unsigned, short, "u", (expr), (v)) + +#define TEST_UINT(expr, v) TEST_(unsigned, int, "u", (expr), (v)) + +#define TEST_INT(expr, v) TEST_(signed, int, "d", (expr), (v)) + +static int failed; + +static void test_csum(void) +{ + unsigned char data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + unsigned char data2[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + + + TEST_USHORT(ip_compute_csum(data, sizeof(data)), 0xe6eb); + TEST_USHORT(ip_compute_csum(data, 1), 0xffff); + TEST_USHORT(ip_compute_csum(data, 2), 0xfeff); + TEST_USHORT(ip_compute_csum(data, 3), 0xfefd); + TEST_USHORT(ip_compute_csum(data, 4), 0xfbfd); + + /* Test that alignment doesn't matter */ + TEST_USHORT(ip_compute_csum(data + 1, 1), 0xfffe); + TEST_USHORT(ip_compute_csum(data + 1, 2), 0xfdfe); + TEST_USHORT(ip_compute_csum(data + 1, 3), 0xfdfb); + TEST_USHORT(ip_compute_csum(data + 1, 4), 0xf9fb); + TEST_USHORT(ip_compute_csum(data2, 1), 0xfffe); + TEST_USHORT(ip_compute_csum(data2, 2), 0xfdfe); + TEST_USHORT(ip_compute_csum(data2, 3), 0xfdfb); + TEST_USHORT(ip_compute_csum(data2, 4), 0xf9fb); + + TEST_USHORT(ip_compute_csum(data+1, sizeof(data)-1), 0xebe6); + TEST_USHORT(ip_compute_csum(data+2, sizeof(data)-2), 0xe7eb); + TEST_USHORT(ip_compute_csum(data+3, sizeof(data)-3), 0xede7); + TEST_USHORT(ip_compute_csum(data+4, sizeof(data)-4), 0xeaed); + + /* Test with non-zero initial sum */ + TEST_USHORT(csum_fold(csum_partial(data, sizeof(data), 0x12345678)), 0x7e3f); + TEST_USHORT(csum_fold(csum_partial(data+1, sizeof(data)-1, 0x12345678)), 0x833a); + + /* TODO: test csum_fold */ + /* TODO: test csum_tcpudp_nofold */ + /* TODO: test csum_tcpudp_magic */ + + /* TODO: test ip_fast_csum */ +} static void test_div64(void) { uint64_t n; n = 20; - TEST(do_div(n,6) == 2); - TEST(n == 3); + TEST_UINT(do_div(n,6), 2); + TEST_UINT(n, 3); n = 20; - TEST(do_div(n,4) == 0); - TEST(n == 5); + TEST_UINT(do_div(n,4), 0); + TEST_UINT(n, 5); n = 1234567890123ULL; - TEST(do_div(n,1000) == 123); - TEST(n == 1234567890); + TEST_UINT(do_div(n,1000), 123); + TEST_UINT(n, 1234567890); } static void test_swab(void) { - TEST(swab16(0x1234) == 0x3412); - TEST(swab32(0x12345678) == 0x78563412); + unsigned int x; + + x = 0x1234; + TEST_UINT(swab16(x), 0x3412); + + x = 0x12345678; + TEST_UINT(swab32(x), 0x78563412); + + TEST_UINT(swab16(0x1234), 0x3412); + TEST_UINT(swab32(0x12345678), 0x78563412); } @@ -53,26 +128,26 @@ { atomic_t a = ATOMIC_INIT(5); - TEST(atomic_read(&a) == 5); + TEST_INT(atomic_read(&a), 5); atomic_set(&a, 10); - TEST(atomic_read(&a) == 10); + TEST_INT(atomic_read(&a), 10); atomic_add(3, &a); - TEST(atomic_read(&a) == 13); + TEST_INT(atomic_read(&a), 13); atomic_sub(5, &a); - TEST(atomic_read(&a) == 8); + TEST_INT(atomic_read(&a), 8); TEST(!atomic_sub_and_test(5, &a)); TEST(atomic_sub_and_test(3, &a)); atomic_set(&a, 2); atomic_inc(&a); - TEST(atomic_read(&a) == 3); + TEST_INT(atomic_read(&a), 3); atomic_dec(&a); - TEST(atomic_read(&a) == 2); + TEST_INT(atomic_read(&a), 2); TEST(!atomic_dec_and_test(&a)); TEST(atomic_dec_and_test(&a)); @@ -96,27 +171,27 @@ atomic_set(&a, 0); atomic_clear_mask(0x123456, &a); - TEST(atomic_read(&a) == 0); + TEST_INT(atomic_read(&a), 0); atomic_set(&a, 0x123456); atomic_clear_mask(0x123456, &a); - TEST(atomic_read(&a) == 0); + TEST_INT(atomic_read(&a), 0); atomic_set(&a, 0xffffff); atomic_clear_mask(0x123456, &a); - TEST(atomic_read(&a) == 0xedcba9); + TEST_INT(atomic_read(&a), 0xedcba9); atomic_set(&a, 0); atomic_set_mask(0x123456, &a); - TEST(atomic_read(&a) == 0x123456); + TEST_INT(atomic_read(&a), 0x123456); atomic_set(&a, 0x123456); atomic_set_mask(0x123456, &a); - TEST(atomic_read(&a) == 0x123456); + TEST_INT(atomic_read(&a), 0x123456); atomic_set(&a, 0xffffff); atomic_set_mask(0x123456, &a); - TEST(atomic_read(&a) == 0xffffff); + TEST_INT(atomic_read(&a), 0xffffff); } static void test_find_next_bit(void) @@ -124,70 +199,71 @@ long mask[] = { 0, 0, 0, 0 }; int size = sizeof(mask) * 8; - TEST(find_next_bit(mask, size, 0) == size); - TEST(find_next_bit(mask, size, 1) == size); - TEST(find_next_bit(mask, size, 2) == size); - TEST(find_next_bit(mask, size, 7) == size); - TEST(find_next_bit(mask, size, 8) == size); + TEST_UINT(find_next_bit(mask, size, 0), size); + TEST_UINT(find_next_bit(mask, size, 1), size); + TEST_UINT(find_next_bit(mask, size, 2), size); + TEST_UINT(find_next_bit(mask, size, 7), size); + TEST_UINT(find_next_bit(mask, size, 8), size); mask[0] = 0x7e; - TEST(find_next_bit(mask, size, 0) == 1); - TEST(find_next_bit(mask, size, 1) == 1); - TEST(find_next_bit(mask, size, 2) == 2); - TEST(find_next_bit(mask, size, 6) == 6); - TEST(find_next_bit(mask, size, 7) == size); - TEST(find_next_bit(mask, size, 8) == size); + TEST_UINT(find_next_bit(mask, size, 0), 1); + TEST_UINT(find_next_bit(mask, size, 1), 1); + TEST_UINT(find_next_bit(mask, size, 2), 2); + TEST_UINT(find_next_bit(mask, size, 6), 6); + TEST_UINT(find_next_bit(mask, size, 7), size); + TEST_UINT(find_next_bit(mask, size, 8), size); mask[0] = 0xff; - TEST(find_next_bit(mask, size, 0) == 0); - TEST(find_next_bit(mask, size, 1) == 1); - TEST(find_next_bit(mask, size, 2) == 2); - TEST(find_next_bit(mask, size, 7) == 7); - TEST(find_next_bit(mask, size, 8) == size); + TEST_UINT(find_next_bit(mask, size, 0), 0); + TEST_UINT(find_next_bit(mask, size, 1), 1); + TEST_UINT(find_next_bit(mask, size, 2), 2); + TEST_UINT(find_next_bit(mask, size, 7), 7); + TEST_UINT(find_next_bit(mask, size, 8), size); mask[0] = 0xfe00; - TEST(find_next_bit(mask, size, 0) == 9); - TEST(find_next_bit(mask, size, 7) == 9); - TEST(find_next_bit(mask, size, 8) == 9); - TEST(find_next_bit(mask, size, 9) == 9); - TEST(find_next_bit(mask, size, 10) == 10); - TEST(find_next_bit(mask, size, 11) == 11); - TEST(find_next_bit(mask, size, 15) == 15); - TEST(find_next_bit(mask, size, 16) == size); + TEST_UINT(find_next_bit(mask, size, 0), 9); + TEST_UINT(find_next_bit(mask, size, 7), 9); + TEST_UINT(find_next_bit(mask, size, 8), 9); + TEST_UINT(find_next_bit(mask, size, 9), 9); + TEST_UINT(find_next_bit(mask, size, 10), 10); + TEST_UINT(find_next_bit(mask, size, 11), 11); + TEST_UINT(find_next_bit(mask, size, 15), 15); + TEST_UINT(find_next_bit(mask, size, 16), size); mask[0] = 0; mask[1] = 0xfe; - TEST(find_next_bit(mask, size, 0) == 33); - TEST(find_next_bit(mask, size, 1) == 33); - TEST(find_next_bit(mask, size, 31) == 33); - TEST(find_next_bit(mask, size, 32) == 33); - TEST(find_next_bit(mask, size, 33) == 33); - TEST(find_next_bit(mask, size, 34) == 34); - TEST(find_next_bit(mask, size, 39) == 39); - TEST(find_next_bit(mask, size, 40) == size); + TEST_UINT(find_next_bit(mask, size, 0), 33); + TEST_UINT(find_next_bit(mask, size, 1), 33); + TEST_UINT(find_next_bit(mask, size, 31), 33); + TEST_UINT(find_next_bit(mask, size, 32), 33); + TEST_UINT(find_next_bit(mask, size, 33), 33); + TEST_UINT(find_next_bit(mask, size, 34), 34); + TEST_UINT(find_next_bit(mask, size, 39), 39); + TEST_UINT(find_next_bit(mask, size, 40), size); - TEST(find_next_bit(mask, size, size-1) == size); + TEST_UINT(find_next_bit(mask, size, size-1), size); } static void test_ffs(void) { /* ffs() counts LSB as bit 1 */ - TEST(ffs(0) == 0); - TEST(ffs(1) == 1); - TEST(ffs(2) == 2); - TEST(ffs(3) == 1); - TEST(ffs(0x80000000) == 32); + TEST_UINT(ffs(0), 0); + TEST_UINT(ffs(1), 1); + TEST_UINT(ffs(2), 2); + TEST_UINT(ffs(3), 1); + TEST_UINT(ffs(0x80000000), 32); /* __ffs() counts LSB as bit 0 */ /* __ffs(0) is undefined */ - TEST(__ffs(1) == 0); - TEST(__ffs(2) == 1); - TEST(__ffs(3) == 0); - TEST(__ffs(0x80000000) == 31); + TEST_UINT(__ffs(1), 0); + TEST_UINT(__ffs(2), 1); + TEST_UINT(__ffs(3), 0); + TEST_UINT(__ffs(0x80000000), 31); } void do_tests(void) { + test_csum(); test_div64(); test_swab(); test_atomic_t(); @@ -195,23 +271,31 @@ test_ffs(); } -static int __init apitest_init(void) +static int __init archtest_init(void) { do_tests(); - if (test_failed) { - printk("apitest: at least one test failed\n"); + if (failed) { + printk("archtest: %d test(s) failed\n", failed); } else { - printk("apitest: all tests passed\n"); + printk("archtest: all tests passed\n"); } return 0; } -static void __exit apitest_exit(void) +static void __exit archtest_exit(void) { } -core_initcall(apitest_init); -module_exit(apitest_exit); + +/* + * We use core_initcall() so that we are called as early as possible + * during boot if we are compiled in. If we are compiled as a module, + * core_initcall() gets interpreted same as module_init() + */ +core_initcall(archtest_init); +module_exit(archtest_exit); + +MODULE_AUTHOR("Kenn Humborg <ke...@li...>"); MODULE_LICENSE("GPL"); |