From c22a0e1e1387a9a70b47be4ff5dbc67bbab7da16 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 10 Apr 2015 23:42:17 +0100 Subject: [PATCH] Updated : fuzzer tests can be programmed for a timelength --- Makefile | 2 +- programs/Makefile | 32 +++++++++--------- programs/frametest.c | 50 ++++++++++++++++++++++++---- programs/fuzzer.c | 77 +++++++++++++++++++++++++++++++------------- 4 files changed, 114 insertions(+), 47 deletions(-) diff --git a/Makefile b/Makefile index ca1f525..32f38aa 100644 --- a/Makefile +++ b/Makefile @@ -104,7 +104,7 @@ clangtest: clean $(MAKE) all CC=clang CFLAGS="-O3 -Werror" sanitize: clean - $(MAKE) test CC=clang CFLAGS="-O3 -g -fsanitize=undefined" + $(MAKE) test CC=clang CFLAGS="-O3 -g -fsanitize=undefined" FUZZER_TIME="-T5mn" staticAnalyze: clean scan-build -v $(MAKE) all CFLAGS=-g diff --git a/programs/Makefile b/programs/Makefile index a394d4b..1c9e4b5 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -40,14 +40,11 @@ DESTDIR?= PREFIX ?= /usr/local CFLAGS ?= -O3 CFLAGS += -std=c99 -Wall -Wextra -Wundef -Wshadow -Wcast-align -Wstrict-prototypes -pedantic -DLZ4_VERSION=\"$(RELEASE)\" -FLAGS = -I../lib $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) +FLAGS := -I../lib $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -BINDIR=$(PREFIX)/bin -MANDIR=$(PREFIX)/share/man/man1 -LZ4DIR=../lib - -TEST_FILES = COPYING -TEST_TARGETS=test-native +BINDIR := $(PREFIX)/bin +MANDIR := $(PREFIX)/share/man/man1 +LZ4DIR := ../lib # Define *.exe as extension for Windows systems @@ -61,7 +58,10 @@ endif # Select test target for Travis CI's Build Matrix -TRAVIS_TARGET=$(LZ4_TRAVIS_CI_ENV) +TRAVIS_TARGET:= $(LZ4_TRAVIS_CI_ENV) +TEST_FILES := COPYING +TEST_TARGETS := test-native +FUZZER_TIME ?= -T20mn default: lz4 @@ -220,10 +220,10 @@ test-lz4c32: lz4 lz4c32 datagen ./datagen -g16KB | ./lz4c32 -9 | ./lz4 -t ./datagen | ./lz4c32 | ./lz4c32 -t ./datagen | ./lz4c32 | ./lz4 -t - ./datagen -g256MB | ./lz4c32 -vqB4D | ./lz4c32 -t - ./datagen -g256MB | ./lz4c32 -vqB4D | ./lz4 -t - ./datagen -g6GB | ./lz4c32 -vqB5D | ./lz4c32 -t - ./datagen -g6GB | ./lz4c32 -vq9BD | ./lz4 -t + ./datagen -g256MB | ./lz4c32 -vqB4D | ./lz4c32 -qt + ./datagen -g256MB | ./lz4c32 -vqB4D | ./lz4 -qt + ./datagen -g6GB | ./lz4c32 -vqB5D | ./lz4c32 -qt + ./datagen -g6GB | ./lz4c32 -vq9BD | ./lz4 -qt test-fullbench: fullbench ./fullbench --no-prompt $(TEST_FILES) @@ -232,16 +232,16 @@ test-fullbench32: fullbench32 ./fullbench32 --no-prompt $(TEST_FILES) test-fuzzer: fuzzer - ./fuzzer + ./fuzzer $(FUZZER_TIME) test-fuzzer32: fuzzer32 - ./fuzzer32 + ./fuzzer32 $(FUZZER_TIME) test-frametest: frametest - ./frametest + ./frametest $(FUZZER_TIME) test-frametest32: frametest32 - ./frametest32 + ./frametest32 $(FUZZER_TIME) test-mem: lz4 datagen fuzzer frametest fullbench valgrind --leak-check=yes ./datagen -g50M > $(VOID) diff --git a/programs/frametest.c b/programs/frametest.c index 4beee23..5fccd08 100644 --- a/programs/frametest.c +++ b/programs/frametest.c @@ -537,7 +537,7 @@ static void locateBuffDiff(const void* buff1, const void* buff2, size_t size, un static const U32 srcDataLength = 9 MB; /* needs to be > 2x4MB to test large blocks */ -int fuzzerTests(U32 seed, unsigned nbTests, unsigned startTest, double compressibility) +int fuzzerTests(U32 seed, unsigned nbTests, unsigned startTest, double compressibility, U32 duration) { unsigned testResult = 0; unsigned testNb = 0; @@ -548,10 +548,15 @@ int fuzzerTests(U32 seed, unsigned nbTests, unsigned startTest, double compressi LZ4F_decompressionContext_t dCtx = NULL; LZ4F_compressionContext_t cCtx = NULL; size_t result; + const U32 startTime = FUZ_GetMilliStart(); XXH64_state_t xxh64; # define CHECK(cond, ...) if (cond) { DISPLAY("Error => "); DISPLAY(__VA_ARGS__); \ DISPLAY(" (seed %u, test nb %u) \n", seed, testNb); goto _output_error; } + + /* Init */ + duration *= 1000; + /* Create buffers */ result = LZ4F_createDecompressionContext(&dCtx, LZ4F_VERSION); CHECK(LZ4F_isError(result), "Allocation failed (error %i)", (int)result); @@ -566,10 +571,10 @@ int fuzzerTests(U32 seed, unsigned nbTests, unsigned startTest, double compressi FUZ_fillCompressibleNoiseBuffer(srcBuffer, srcDataLength, compressibility, &coreRand); /* jump to requested testNb */ - for (testNb =0; testNb < startTest; testNb++) (void)FUZ_rand(&coreRand); // sync randomizer + for (testNb =0; (testNb < startTest); testNb++) (void)FUZ_rand(&coreRand); // sync randomizer /* main fuzzer test loop */ - for ( ; testNb < nbTests; testNb++) + for ( ; (testNb < nbTests) || (duration > FUZ_GetMilliSpan(startTime)) ; testNb++) { U32 randState = coreRand ^ prime1; unsigned BSId = 4 + (FUZ_rand(&randState) & 3); @@ -721,6 +726,7 @@ int FUZ_usage(void) DISPLAY( "\n"); DISPLAY( "Arguments :\n"); DISPLAY( " -i# : Nb of tests (default:%u) \n", nbTestsDefault); + DISPLAY( " -T# : Duration of tests (default: use Nb of tests) \n"); DISPLAY( " -s# : Select seed (default:prompt user)\n"); DISPLAY( " -t# : Select starting test number (default:0)\n"); DISPLAY( " -p# : Select compressibility in %% (default:%i%%)\n", FUZ_COMPRESSIBILITY_DEFAULT); @@ -739,6 +745,7 @@ int main(int argc, char** argv) int testNb = 0; int proba = FUZ_COMPRESSIBILITY_DEFAULT; int result=0; + U32 duration=0; /* Check command line */ programName = argv[0]; @@ -746,9 +753,9 @@ int main(int argc, char** argv) { char* argument = argv[argNb]; - if(!argument) continue; // Protection if argument empty + if(!argument) continue; /* Protection if argument empty */ - // Decode command (note : aggregated commands are allowed) + /* Decode command (note : aggregated commands are allowed) */ if (argument[0]=='-') { if (!strcmp(argument, "--no-prompt")) @@ -781,7 +788,7 @@ int main(int argc, char** argv) case 'i': argument++; - nbTests=0; + nbTests=0; duration=0; while ((*argument>='0') && (*argument<='9')) { nbTests *= 10; @@ -789,6 +796,35 @@ int main(int argc, char** argv) argument++; } break; + + case 'T': + argument++; + nbTests = 0; duration = 0; + + for (;;) + { + if (argument[0]=='m') + { + duration *= 60; + argument++; + continue; + } + if (argument[0]=='n') + { + argument++; + continue; + } + if ((*argument>='0') && (*argument<='9')) + { + duration *= 10; + duration += *argument - '0'; + argument++; + continue; + } + break; + } + break; + case 's': argument++; seed=0; @@ -841,5 +877,5 @@ int main(int argc, char** argv) if (testNb==0) result = basicTests(seed, ((double)proba) / 100); if (result) return 1; - return fuzzerTests(seed, nbTests, testNb, ((double)proba) / 100); + return fuzzerTests(seed, nbTests, testNb, ((double)proba) / 100, duration); } diff --git a/programs/fuzzer.c b/programs/fuzzer.c index 3d3cf8e..9e2ce1e 100644 --- a/programs/fuzzer.c +++ b/programs/fuzzer.c @@ -19,7 +19,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. You can contact the author at : - - LZ4 source repository : http://code.google.com/p/lz4 - LZ4 source mirror : https://github.com/Cyan4973/lz4 - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c */ @@ -210,7 +209,7 @@ static int FUZ_AddressOverflow(void) printf("Overflow tests : "); - // Only possible in 32-bits + /* Only possible in 32-bits */ if (sizeof(void*)==8) { printf("64 bits mode : no overflow \n"); @@ -300,7 +299,7 @@ static void FUZ_displayUpdate(unsigned testNb) } -static int FUZ_test(U32 seed, const U32 nbCycles, const U32 startCycle, const double compressibility) +static int FUZ_test(U32 seed, U32 nbCycles, const U32 startCycle, const double compressibility, U32 duration) { unsigned long long bytes = 0; unsigned long long cbytes = 0; @@ -313,7 +312,7 @@ static int FUZ_test(U32 seed, const U32 nbCycles, const U32 startCycle, const do int ret; unsigned cycleNb; # define FUZ_CHECKTEST(cond, ...) if (cond) { printf("Test %u : ", testNb); printf(__VA_ARGS__); \ - printf(" (seed %u, cycle %u) \n", seed, cycleNb); goto _output_error; } + printf(" (seed %u, cycle %u) \n", seed, cycleNb); goto _output_error; } # define FUZ_DISPLAYTEST { testNb++; g_displayLevel<3 ? 0 : printf("%2u\b\b", testNb); if (g_displayLevel==4) fflush(stdout); } void* stateLZ4 = malloc(LZ4_sizeofState()); void* stateLZ4HC = malloc(LZ4_sizeofStateHC()); @@ -324,23 +323,25 @@ static int FUZ_test(U32 seed, const U32 nbCycles, const U32 startCycle, const do U32 coreRandState = seed; U32 randState = coreRandState ^ PRIME3; int result = 0; + const U32 startTime = FUZ_GetMilliStart(); - // init + /* init */ memset(&LZ4dict, 0, sizeof(LZ4dict)); + duration *= 1000; - // Create compressible test buffer + /* Create compressible test buffer */ CNBuffer = malloc(COMPRESSIBLE_NOISE_LENGTH); FUZ_fillCompressibleNoiseBuffer(CNBuffer, COMPRESSIBLE_NOISE_LENGTH, compressibility, &randState); compressedBuffer = (char*)malloc(LZ4_compressBound(FUZ_MAX_BLOCK_SIZE)); decodedBuffer = (char*)malloc(FUZ_MAX_DICT_SIZE + FUZ_MAX_BLOCK_SIZE); - // move to startCycle + /* move to startCycle */ for (cycleNb = 0; cycleNb < startCycle; cycleNb++) { (void)FUZ_rand(&coreRandState); - if (0) // some problems related to dictionary re-use; in this case, enable this loop + if (0) /* some problems are related to dictionary re-use; in this case, enable this loop */ { int dictSize, blockSize, blockStart; char* dict; @@ -362,8 +363,8 @@ static int FUZ_test(U32 seed, const U32 nbCycles, const U32 startCycle, const do } } - // Test loop - for (cycleNb = startCycle; cycleNb < nbCycles; cycleNb++) + /* Main test loop */ + for (cycleNb = startCycle; (cycleNb < nbCycles) || (FUZ_GetMilliSpan(startTime) < duration) ; cycleNb++) { U32 testNb = 0; char* dict; @@ -375,7 +376,7 @@ static int FUZ_test(U32 seed, const U32 nbCycles, const U32 startCycle, const do (void)FUZ_rand(&coreRandState); randState = coreRandState ^ PRIME3; - // Select block to test + /* Select block to test */ blockSize = FUZ_rand(&randState) % FUZ_MAX_BLOCK_SIZE; blockStart = FUZ_rand(&randState) % (COMPRESSIBLE_NOISE_LENGTH - blockSize); dictSize = FUZ_rand(&randState) % FUZ_MAX_DICT_SIZE; @@ -385,7 +386,7 @@ static int FUZ_test(U32 seed, const U32 nbCycles, const U32 startCycle, const do /* Compression tests */ - // Test compression HC + /* Test compression HC */ FUZ_DISPLAYTEST; ret = LZ4_compressHC(block, compressedBuffer, blockSize); FUZ_CHECKTEST(ret==0, "LZ4_compressHC() failed"); @@ -673,21 +674,22 @@ static int FUZ_test(U32 seed, const U32 nbCycles, const U32 startCycle, const do FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe_usingDict corrupted decoded data"); - // ***** End of tests *** // - // Fill stats + /* ***** End of tests *** */ + /* Fill stats */ bytes += blockSize; cbytes += compressedSize; hcbytes += HCcompressedSize; ccbytes += blockContinueCompressedSize; } + if (nbCycles<=1) nbCycles = cycleNb; printf("\r%7u /%7u - ", cycleNb, nbCycles); printf("all tests completed successfully \n"); printf("compression ratio: %0.3f%%\n", (double)cbytes/bytes*100); printf("HC compression ratio: %0.3f%%\n", (double)hcbytes/bytes*100); printf("ratio with dict: %0.3f%%\n", (double)ccbytes/bytes*100); - // unalloc + /* release memory */ { _exit: free(CNBuffer); @@ -831,7 +833,7 @@ static void FUZ_unitTests(void) crcNew = XXH64(testVerify, testCompressedSize, 0); FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe() simple dictionary decompression test : corruption"); - // multiple HC compression test with dictionary + /* multiple HC compression test with dictionary */ { int result1, result2; int segSize = testCompressedSize / 2; @@ -863,7 +865,7 @@ static void FUZ_unitTests(void) crcNew = XXH64(testVerify, testCompressedSize, 0); FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe_usingDict() decompression corruption"); - // multiple HC compression with ext. dictionary + /* multiple HC compression with ext. dictionary */ { XXH64_state_t crcOrigState; XXH64_state_t crcNewState; @@ -912,7 +914,7 @@ static void FUZ_unitTests(void) } } - // ring buffer test + /* ring buffer test */ { XXH64_state_t xxhOrig; XXH64_state_t xxhNew; @@ -956,7 +958,7 @@ static void FUZ_unitTests(void) } } - // small decoder-side ring buffer test + /* small decoder-side ring buffer test */ { XXH64_state_t xxhOrig; XXH64_state_t xxhNew; @@ -1013,6 +1015,7 @@ static int FUZ_usage(char* programName) DISPLAY( "\n"); DISPLAY( "Arguments :\n"); DISPLAY( " -i# : Nb of tests (default:%i) \n", NB_ATTEMPTS); + DISPLAY( " -T# : Duration of tests (default: use Nb of tests) \n"); DISPLAY( " -s# : Select seed (default:prompt user)\n"); DISPLAY( " -t# : Select starting test number (default:0)\n"); DISPLAY( " -P# : Select compressibility in %% (default:%i%%)\n", FUZ_COMPRESSIBILITY_DEFAULT); @@ -1033,8 +1036,9 @@ int main(int argc, char** argv) int proba = FUZ_COMPRESSIBILITY_DEFAULT; int pause = 0; char* programName = argv[0]; + U32 duration = 0; - // Check command line + /* Check command line */ for(argNb=1; argNb='0') && (*argument<='9')) { nbTests *= 10; @@ -1075,6 +1079,34 @@ int main(int argc, char** argv) } break; + case 'T': + argument++; + nbTests = 0; duration = 0; + + for (;;) + { + if (argument[0]=='m') + { + duration *= 60; + argument++; + continue; + } + if (argument[0]=='n') + { + argument++; + continue; + } + if ((*argument>='0') && (*argument<='9')) + { + duration *= 10; + duration += *argument - '0'; + argument++; + continue; + } + break; + } + break; + case 's': argument++; seed=0; seedset=1; @@ -1115,7 +1147,6 @@ int main(int argc, char** argv) } } - // Get Seed printf("Starting LZ4 fuzzer (%i-bits, %s)\n", (int)(sizeof(size_t)*8), LZ4_VERSION); if (!seedset) seed = FUZ_GetMilliStart() % 10000; @@ -1127,7 +1158,7 @@ int main(int argc, char** argv) if (nbTests<=0) nbTests=1; { - int result = FUZ_test(seed, nbTests, testNb, ((double)proba) / 100); + int result = FUZ_test(seed, nbTests, testNb, ((double)proba) / 100, duration); if (pause) { DISPLAY("press enter ... \n");