From b22ce4abb50360bda0e7a7ae9bfa95e1af38853c Mon Sep 17 00:00:00 2001 From: "debing.sun" Date: Tue, 31 Mar 2026 16:05:35 +0800 Subject: [PATCH] Fix sds unit test and improve unittest output formatting (#14927) ### Summary 1. Fix sdsResize() unit tests Before this PR, we forgot to call test_report() after the test ended, resulting in that even if there were failures, we couldn't detect them. In this PR, the test_report() call has been fixed, and the missed test failures in sds.c have been resolved. Since only the allocated size of jemalloc is deterministic, the allocation size related sds unittests are only run with Jemalloc. 2. Improve the unit test framework output Add ANSI color highlighting to test_cond (green PASSED / red FAILED) and test_report, and refactor the test summary in server.c to show per-group pass/total counts with a formatted summary table. --- src/sds.c | 23 +++++++++++++++++++---- src/server.c | 41 +++++++++++++++++++++++++---------------- src/testhelp.h | 11 +++++++---- 3 files changed, 51 insertions(+), 24 deletions(-) diff --git a/src/sds.c b/src/sds.c index 06f16cf80..0a940e13d 100644 --- a/src/sds.c +++ b/src/sds.c @@ -1507,27 +1507,42 @@ int sdsTest(int argc, char **argv, int flags) { x = sdsResize(x, 200, 1); test_cond("sdsresize() expand len", sdslen(x) == 40); test_cond("sdsresize() expand strlen", strlen(x) == 40); - test_cond("sdsresize() expand alloc", sdsalloc(x) == 200); +#if defined(USE_JEMALLOC) + /* 224 - hdrlen(3) - 1(\0) */ + test_cond("sdsresize() expand alloc", sdsalloc(x) == 220); +#endif /* Test sdsresize - trim free space */ x = sdsResize(x, 80, 1); test_cond("sdsresize() shrink len", sdslen(x) == 40); test_cond("sdsresize() shrink strlen", strlen(x) == 40); - test_cond("sdsresize() shrink alloc", sdsalloc(x) == 80); +#if defined(USE_JEMALLOC) + /* 96 - hdrlen(3) - 1(\0) */ + test_cond("sdsresize() shrink alloc", sdsalloc(x) == 92); +#endif /* Test sdsresize - crop used space */ x = sdsResize(x, 30, 1); test_cond("sdsresize() crop len", sdslen(x) == 30); test_cond("sdsresize() crop strlen", strlen(x) == 30); - test_cond("sdsresize() crop alloc", sdsalloc(x) == 30); +#if defined(USE_JEMALLOC) + /* 40 - hdrlen(3) - 1(\0) */ + test_cond("sdsresize() crop alloc", sdsalloc(x) == 36); +#endif /* Test sdsresize - extend to different class */ x = sdsResize(x, 400, 1); test_cond("sdsresize() expand len", sdslen(x) == 30); test_cond("sdsresize() expand strlen", strlen(x) == 30); - test_cond("sdsresize() expand alloc", sdsalloc(x) == 400); +#if defined(USE_JEMALLOC) + /* 448 - hdrlen(5) - 1(\0) */ + test_cond("sdsresize() expand alloc", sdsalloc(x) == 442); +#endif /* Test sdsresize - shrink to different class */ x = sdsResize(x, 4, 1); test_cond("sdsresize() crop len", sdslen(x) == 4); test_cond("sdsresize() crop strlen", strlen(x) == 4); +#if defined(USE_JEMALLOC) + /* 8 - hdrlen(3) - 1(\0) */ test_cond("sdsresize() crop alloc", sdsalloc(x) == 4); +#endif sdsfree(x); { /* Test adjustTypeIfNeeded() */ diff --git a/src/server.c b/src/server.c index 3e216568b..b8a5e14cf 100644 --- a/src/server.c +++ b/src/server.c @@ -7783,7 +7783,8 @@ int zsetTest(int argc, char **argv, int flags); struct redisTest { char *name; redisTestProc *proc; - int failed; + int test_count; + int passed_count; } redisTests[] = { {"ziplist", ziplistTest}, {"quicklist", quicklistTest}, @@ -7837,32 +7838,40 @@ int main(int argc, char **argv) { if (!strcasecmp(argv[2], "all")) { int numtests = sizeof(redisTests)/sizeof(struct redisTest); - for (j = 0; j < numtests; j++) { - redisTests[j].failed = (redisTests[j].proc(argc,argv,flags) != 0); - } - - /* Report tests result */ int failed_num = 0; for (j = 0; j < numtests; j++) { - if (redisTests[j].failed) { + int before_total = __test_num; + int before_failed = __failed_tests; + redisTests[j].proc(argc,argv,flags); + redisTests[j].test_count = __test_num - before_total; + redisTests[j].passed_count = redisTests[j].test_count - (__failed_tests - before_failed); + if (redisTests[j].passed_count < redisTests[j].test_count) failed_num++; - printf("[failed] Test - %s\n", redisTests[j].name); - } else { - printf("[ok] Test - %s\n", redisTests[j].name); - } } - printf("%d tests, %d passed, %d failed\n", numtests, - numtests-failed_num, failed_num); + printf("\n========== Test Suite Summary ==========\n\n"); + for (j = 0; j < numtests; j++) { + int failed = redisTests[j].passed_count < redisTests[j].test_count; + printf(" %s %-15s (%d/%d passed)%s\n", + failed ? "\033[31m[failed]" : "\033[32m[ok] \033[0m", + redisTests[j].name, + redisTests[j].passed_count, redisTests[j].test_count, + failed ? "\033[0m" : ""); + } - return failed_num == 0 ? 0 : 1; + printf("\n Test Groups: %s%d passed\033[0m, %s%d failed\033[0m, %d total\n", + failed_num ? "" : "\033[32m", numtests-failed_num, + failed_num ? "\033[31m" : "", failed_num, numtests); + + test_report(); } else { redisTestProc *proc = getTestProcByName(argv[2]); if (!proc) return -1; /* test not found */ - return proc(argc,argv,flags); + proc(argc,argv,flags); + test_report(); } - return 0; + return __failed_tests ? 1 : 0; } #endif diff --git a/src/testhelp.h b/src/testhelp.h index aeae372dd..58fe2f8fa 100644 --- a/src/testhelp.h +++ b/src/testhelp.h @@ -30,14 +30,17 @@ extern int __test_num; #define test_cond(descr,_c) do { \ __test_num++; printf("%d - %s: ", __test_num, descr); \ - if(_c) printf("PASSED\n"); else {printf("FAILED\n"); __failed_tests++;} \ + if(_c) printf("\033[32mPASSED\033[0m\n"); else {printf("\033[31mFAILED\033[0m\n"); __failed_tests++;} \ } while(0) #define test_report() do { \ - printf("%d tests, %d passed, %d failed\n", __test_num, \ - __test_num-__failed_tests, __failed_tests); \ if (__failed_tests) { \ - printf("=== WARNING === We have failed tests here...\n"); \ + printf(" Tests: %d passed, \033[31m%d failed\033[0m, %d total\n", \ + __test_num-__failed_tests, __failed_tests, __test_num); \ + printf("\033[31m=== WARNING === We have failed tests here...\033[0m\n"); \ exit(1); \ + } else { \ + printf(" Tests: \033[32m%d passed\033[0m, %d failed, %d total\n", \ + __test_num-__failed_tests, __failed_tests, __test_num); \ } \ } while(0)