Updated : fuzzer tests can be programmed for a timelength

This commit is contained in:
Yann Collet 2015-04-10 23:42:17 +01:00
parent a2864fd49d
commit c22a0e1e13
4 changed files with 114 additions and 47 deletions

View File

@ -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

View File

@ -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)

View File

@ -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);
}

View File

@ -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<argc; argNb++)
{
char* argument = argv[argNb];
@ -1066,7 +1070,7 @@ int main(int argc, char** argv)
case 'i':
argument++;
nbTests=0;
nbTests = 0; duration = 0;
while ((*argument>='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");