diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/Makefile | 22 | ||||
| -rw-r--r-- | tests/decodecorpus.c | 60 | ||||
| -rw-r--r-- | tests/fullbench.c | 4 | ||||
| -rw-r--r-- | tests/fuzzer.c | 264 | ||||
| -rw-r--r-- | tests/paramgrill.c | 82 | ||||
| -rwxr-xr-x | tests/playTests.sh | 168 | ||||
| -rwxr-xr-x | tests/test-zstd-speed.py | 18 | ||||
| -rw-r--r-- | tests/zbufftest.c | 2 | ||||
| -rw-r--r-- | tests/zstreamtest.c | 112 | 
9 files changed, 564 insertions, 168 deletions
| diff --git a/tests/Makefile b/tests/Makefile index 9382fe80ddc2..ea58c0fe5119 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -26,9 +26,12 @@ PYTHON ?= python3  TESTARTEFACT := versionsTest namespaceTest -CPPFLAGS+= -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress -I$(ZSTDDIR)/dictBuilder -I$(ZSTDDIR)/deprecated -I$(PRGDIR) +DEBUGFLAGS=-g -DZSTD_DEBUG=1 +CPPFLAGS+= -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \ +           -I$(ZSTDDIR)/dictBuilder -I$(ZSTDDIR)/deprecated -I$(PRGDIR) \ +           $(DEBUGFLAG)  CFLAGS  ?= -O3 -CFLAGS  += -g -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ +CFLAGS  += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \             -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \             -Wstrict-prototypes -Wundef -Wformat-security  CFLAGS  += $(MOREFLAGS) @@ -65,14 +68,16 @@ FUZZERTEST ?= -T5mn  ZSTDRTTEST = --test-large-data  DECODECORPUS_TESTTIME ?= -T30 -.PHONY: default all all32 dll clean test test32 test-all namespaceTest versionsTest +.PHONY: default all all32 allnothread dll clean test test32 test-all namespaceTest versionsTest  default: fullbench -all: fullbench fuzzer zstreamtest paramgrill datagen zbufftest +all: fullbench fuzzer zstreamtest paramgrill datagen zbufftest decodecorpus  all32: fullbench32 fuzzer32 zstreamtest32 zbufftest32 +allnothread: fullbench fuzzer paramgrill datagen zbufftest decodecorpus +  dll: fuzzer-dll zstreamtest-dll zbufftest-dll  zstd: @@ -152,6 +157,7 @@ zstreamtest-dll : $(ZSTDDIR)/common/xxhash.c $(PRGDIR)/datagen.c zstreamtest.c  	$(MAKE) -C $(ZSTDDIR) libzstd  	$(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@$(EXT) +paramgrill : DEBUGFLAG =  paramgrill : $(ZSTD_FILES) $(PRGDIR)/datagen.c paramgrill.c  	$(CC)      $(FLAGS) $^ -lm -o $@$(EXT) @@ -300,10 +306,10 @@ test-fullbench32: fullbench32 datagen  	$(QEMU_SYS) ./fullbench32 -i1 -P0  test-fuzzer: fuzzer -	$(QEMU_SYS) ./fuzzer $(FUZZERTEST) +	$(QEMU_SYS) ./fuzzer $(FUZZERTEST) $(FUZZER_FLAGS)  test-fuzzer32: fuzzer32 -	$(QEMU_SYS) ./fuzzer32 $(FUZZERTEST) +	$(QEMU_SYS) ./fuzzer32 $(FUZZERTEST) $(FUZZER_FLAGS)  test-zbuff: zbufftest  	$(QEMU_SYS) ./zbufftest $(ZSTREAM_TESTTIME) @@ -312,10 +318,10 @@ test-zbuff32: zbufftest32  	$(QEMU_SYS) ./zbufftest32 $(ZSTREAM_TESTTIME)  test-zstream: zstreamtest -	$(QEMU_SYS) ./zstreamtest $(ZSTREAM_TESTTIME) +	$(QEMU_SYS) ./zstreamtest $(ZSTREAM_TESTTIME) $(FUZZER_FLAGS)  test-zstream32: zstreamtest32 -	$(QEMU_SYS) ./zstreamtest32 $(ZSTREAM_TESTTIME) +	$(QEMU_SYS) ./zstreamtest32 $(ZSTREAM_TESTTIME) $(FUZZER_FLAGS)  test-longmatch: longmatch  	$(QEMU_SYS) ./longmatch diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 183d20f749e6..f7b3c854fdb2 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -98,7 +98,7 @@ static void RAND_bufferMaxSymb(U32* seed, void* ptr, size_t size, int maxSymb)      BYTE* op = ptr;      for (i = 0; i < size; i++) { -        op[i] = RAND(seed) % (maxSymb + 1); +        op[i] = (BYTE) (RAND(seed) % (maxSymb + 1));      }  } @@ -134,8 +134,8 @@ static void RAND_genDist(U32* seed, BYTE* dist, double weight)  {      size_t i = 0;      size_t statesLeft = DISTSIZE; -    BYTE symb = RAND(seed) % 256; -    BYTE step = (RAND(seed) % 256) | 1; /* force it to be odd so it's relatively prime to 256 */ +    BYTE symb = (BYTE) (RAND(seed) % 256); +    BYTE step = (BYTE) ((RAND(seed) % 256) | 1); /* force it to be odd so it's relatively prime to 256 */      while (i < DISTSIZE) {          size_t states = ((size_t)(weight * statesLeft)) + 1; @@ -259,7 +259,7 @@ static void writeFrameHeader(U32* seed, frame_t* frame)          /* Follow window algorithm from specification */          int const exponent = RAND(seed) % (MAX_WINDOW_LOG - 10);          int const mantissa = RAND(seed) % 8; -        windowByte = (exponent << 3) | mantissa; +        windowByte = (BYTE) ((exponent << 3) | mantissa);          fh.windowSize = (1U << (exponent + 10));          fh.windowSize += fh.windowSize / 8 * mantissa;      } @@ -284,7 +284,7 @@ static void writeFrameHeader(U32* seed, frame_t* frame)          if (contentSizeFlag && (fh.contentSize == 0 || !(RAND(seed) & 7))) {              /* do single segment sometimes */ -            fh.windowSize = fh.contentSize; +            fh.windowSize = (U32) fh.contentSize;              singleSegment = 1;          }      } @@ -307,7 +307,7 @@ static void writeFrameHeader(U32* seed, frame_t* frame)      {          BYTE const frameHeaderDescriptor = -                (fcsCode << 6) | (singleSegment << 5) | (1 << 2); +                (BYTE) ((fcsCode << 6) | (singleSegment << 5) | (1 << 2));          op[pos++] = frameHeaderDescriptor;      } @@ -318,14 +318,14 @@ static void writeFrameHeader(U32* seed, frame_t* frame)      if (contentSizeFlag) {          switch (fcsCode) {          default: /* Impossible */ -        case 0: op[pos++] = fh.contentSize; break; -        case 1: MEM_writeLE16(op + pos, fh.contentSize - 256); pos += 2; break; -        case 2: MEM_writeLE32(op + pos, fh.contentSize); pos += 4; break; -        case 3: MEM_writeLE64(op + pos, fh.contentSize); pos += 8; break; +        case 0: op[pos++] = (BYTE) fh.contentSize; break; +        case 1: MEM_writeLE16(op + pos, (U16) (fh.contentSize - 256)); pos += 2; break; +        case 2: MEM_writeLE32(op + pos, (U32) fh.contentSize); pos += 4; break; +        case 3: MEM_writeLE64(op + pos, (U64) fh.contentSize); pos += 8; break;          }      } -    DISPLAYLEVEL(2, " frame content size:\t%zu\n", fh.contentSize); +    DISPLAYLEVEL(2, " frame content size:\t%u\n", (U32)fh.contentSize);      DISPLAYLEVEL(2, " frame window size:\t%u\n", fh.windowSize);      DISPLAYLEVEL(2, " content size flag:\t%d\n", contentSizeFlag);      DISPLAYLEVEL(2, " single segment flag:\t%d\n", singleSegment); @@ -385,7 +385,7 @@ static size_t writeLiteralsBlockSimple(U32* seed, frame_t* frame, size_t content          op += litSize;      } else {          /* RLE literals */ -        BYTE const symb = RAND(seed) % 256; +        BYTE const symb = (BYTE) (RAND(seed) % 256);          DISPLAYLEVEL(4, "   rle literals: 0x%02x\n", (U32)symb); @@ -542,8 +542,8 @@ static size_t writeLiteralsBlockCompressed(U32* seed, frame_t* frame, size_t con          op += compressedSize;          compressedSize += hufHeaderSize; -        DISPLAYLEVEL(5, "    regenerated size: %zu\n", litSize); -        DISPLAYLEVEL(5, "    compressed size: %zu\n", compressedSize); +        DISPLAYLEVEL(5, "    regenerated size: %u\n", (U32)litSize); +        DISPLAYLEVEL(5, "    compressed size: %u\n", (U32)compressedSize);          if (compressedSize >= litSize) {              DISPLAYLEVEL(5, "     trying again\n");              /* if we have to try again, reset the stats so we don't accidentally @@ -611,7 +611,7 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,      size_t const remainingMatch = contentSize - literalsSize;      size_t excessMatch = 0;      U32 numSequences = 0; -   +      U32 i; @@ -628,7 +628,7 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,          excessMatch = remainingMatch - numSequences * MIN_SEQ_LEN;      } -    DISPLAYLEVEL(5, "    total match lengths: %zu\n", remainingMatch); +    DISPLAYLEVEL(5, "    total match lengths: %u\n", (U32)remainingMatch);      for (i = 0; i < numSequences; i++) {          /* Generate match and literal lengths by exponential distribution to @@ -647,10 +647,10 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,          U32 offset, offsetCode, repIndex;          /* bounds checks */ -        matchLen = MIN(matchLen, excessMatch + MIN_SEQ_LEN); -        literalLen = MIN(literalLen, literalsSize); +        matchLen = (U32) MIN(matchLen, excessMatch + MIN_SEQ_LEN); +        literalLen = MIN(literalLen, (U32) literalsSize);          if (i == 0 && srcPtr == frame->srcStart && literalLen == 0) literalLen = 1; -        if (i + 1 == numSequences) matchLen = MIN_SEQ_LEN + excessMatch; +        if (i + 1 == numSequences) matchLen = MIN_SEQ_LEN + (U32) excessMatch;          memcpy(srcPtr, literals, literalLen);          srcPtr += literalLen; @@ -694,8 +694,8 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,          }          DISPLAYLEVEL(6, "      LL: %5u OF: %5u ML: %5u", literalLen, offset, matchLen); -        DISPLAYLEVEL(7, " srcPos: %8tu seqNb: %3u", -                     (BYTE*)srcPtr - (BYTE*)frame->srcStart, i); +        DISPLAYLEVEL(7, " srcPos: %8u seqNb: %3u", +                     (U32)((BYTE*)srcPtr - (BYTE*)frame->srcStart), i);          DISPLAYLEVEL(6, "\n");          if (offsetCode < 3) {              DISPLAYLEVEL(7, "        repeat offset: %d\n", repIndex); @@ -711,8 +711,8 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,      memcpy(srcPtr, literals, literalsSize);      srcPtr += literalsSize; -    DISPLAYLEVEL(6, "      excess literals: %5zu", literalsSize); -    DISPLAYLEVEL(7, " srcPos: %8tu", (BYTE*)srcPtr - (BYTE*)frame->srcStart); +    DISPLAYLEVEL(6, "      excess literals: %5u", (U32)literalsSize); +    DISPLAYLEVEL(7, " srcPos: %8u", (U32)((BYTE*)srcPtr - (BYTE*)frame->srcStart));      DISPLAYLEVEL(6, "\n");      return numSequences; @@ -957,11 +957,11 @@ static size_t writeCompressedBlock(U32* seed, frame_t* frame, size_t contentSize      literalsSize = writeLiteralsBlock(seed, frame, contentSize); -    DISPLAYLEVEL(4, "   literals size: %zu\n", literalsSize); +    DISPLAYLEVEL(4, "   literals size: %u\n", (U32)literalsSize);      nbSeq = writeSequencesBlock(seed, frame, contentSize, literalsSize); -    DISPLAYLEVEL(4, "   number of sequences: %zu\n", nbSeq); +    DISPLAYLEVEL(4, "   number of sequences: %u\n", (U32)nbSeq);      return (BYTE*)frame->data - blockStart;  } @@ -977,7 +977,7 @@ static void writeBlock(U32* seed, frame_t* frame, size_t contentSize,      BYTE *op = header + 3;      DISPLAYLEVEL(3, " block:\n"); -    DISPLAYLEVEL(3, "  block content size: %zu\n", contentSize); +    DISPLAYLEVEL(3, "  block content size: %u\n", (U32)contentSize);      DISPLAYLEVEL(3, "  last block: %s\n", lastBlock ? "yes" : "no");      if (blockTypeDesc == 0) { @@ -1025,10 +1025,10 @@ static void writeBlock(U32* seed, frame_t* frame, size_t contentSize,      frame->src = (BYTE*)frame->src + contentSize;      DISPLAYLEVEL(3, "  block type: %s\n", BLOCK_TYPES[blockType]); -    DISPLAYLEVEL(3, "  block size field: %zu\n", blockSize); +    DISPLAYLEVEL(3, "  block size field: %u\n", (U32)blockSize); -    header[0] = (lastBlock | (blockType << 1) | (blockSize << 3)) & 0xff; -    MEM_writeLE16(header + 1, blockSize >> 5); +    header[0] = (BYTE) ((lastBlock | (blockType << 1) | (blockSize << 3)) & 0xff); +    MEM_writeLE16(header + 1, (U16) (blockSize >> 5));      frame->data = op;  } @@ -1300,7 +1300,7 @@ static int generateCorpus(U32 seed, unsigned numFiles, const char* const path,  *********************************************************/  static U32 makeSeed(void)  { -    U32 t = time(NULL); +    U32 t = (U32) time(NULL);      return XXH32(&t, sizeof(t), 0) % 65536;  } diff --git a/tests/fullbench.c b/tests/fullbench.c index 940d315a7cd4..38cf22fa7ebc 100644 --- a/tests/fullbench.c +++ b/tests/fullbench.c @@ -251,14 +251,14 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb)      case 13:          benchFunction = local_ZSTD_decompressContinue; benchName = "ZSTD_decompressContinue";          break; -	case 31: +    case 31:          benchFunction = local_ZSTD_decodeLiteralsBlock; benchName = "ZSTD_decodeLiteralsBlock";          break;      case 32:          benchFunction = local_ZSTD_decodeSeqHeaders; benchName = "ZSTD_decodeSeqHeaders";          break;  #endif -	case 41: +    case 41:          benchFunction = local_ZSTD_compressStream; benchName = "ZSTD_compressStream";          break;      case 42: diff --git a/tests/fuzzer.c b/tests/fuzzer.c index def7542b5f0b..a9dcf12e0702 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -28,6 +28,7 @@  #define ZSTD_STATIC_LINKING_ONLY   /* ZSTD_compressContinue, ZSTD_compressBlock */  #include "zstd.h"         /* ZSTD_VERSION_STRING */  #include "zstd_errors.h"  /* ZSTD_getErrorCode */ +#include "zstdmt_compress.h"  #define ZDICT_STATIC_LINKING_ONLY  #include "zdict.h"        /* ZDICT_trainFromBuffer */  #include "datagen.h"      /* RDG_genBuffer */ @@ -57,7 +58,7 @@ static U32 g_displayLevel = 2;  #define DISPLAYUPDATE(l, ...) if (g_displayLevel>=l) { \              if ((FUZ_clockSpan(g_displayClock) > g_refreshRate) || (g_displayLevel>=4)) \              { g_displayClock = clock(); DISPLAY(__VA_ARGS__); \ -            if (g_displayLevel>=4) fflush(stdout); } } +            if (g_displayLevel>=4) fflush(stderr); } }  static const clock_t g_refreshRate = CLOCKS_PER_SEC / 6;  static clock_t g_displayClock = 0; @@ -133,13 +134,21 @@ static int basicUnitTests(U32 seed, double compressibility)          DISPLAYLEVEL(4, "OK : %s \n", errorString);      } +      DISPLAYLEVEL(4, "test%3i : compress %u bytes : ", testNb++, (U32)CNBuffSize);      CHECKPLUS(r, ZSTD_compress(compressedBuffer, ZSTD_compressBound(CNBuffSize),                                 CNBuffer, CNBuffSize, 1),                cSize=r );      DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); -    DISPLAYLEVEL(4, "test%3i : decompressed size test : ", testNb++); + +    DISPLAYLEVEL(4, "test%3i : ZSTD_getFrameContentSize test : ", testNb++); +    {   unsigned long long const rSize = ZSTD_getFrameContentSize(compressedBuffer, cSize); +        if (rSize != CNBuffSize) goto _output_error; +    } +    DISPLAYLEVEL(4, "OK \n"); + +    DISPLAYLEVEL(4, "test%3i : ZSTD_findDecompressedSize test : ", testNb++);      {   unsigned long long const rSize = ZSTD_findDecompressedSize(compressedBuffer, cSize);          if (rSize != CNBuffSize) goto _output_error;      } @@ -157,6 +166,7 @@ static int basicUnitTests(U32 seed, double compressibility)      }   }      DISPLAYLEVEL(4, "OK \n"); +      DISPLAYLEVEL(4, "test%3i : decompress with null dict : ", testNb++);      { size_t const r = ZSTD_decompress_usingDict(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize, NULL, 0);        if (r != CNBuffSize) goto _output_error; } @@ -179,6 +189,49 @@ static int basicUnitTests(U32 seed, double compressibility)        if (ZSTD_getErrorCode(r) != ZSTD_error_srcSize_wrong) goto _output_error; }      DISPLAYLEVEL(4, "OK \n"); + +    /* ZSTDMT simple MT compression test */ +    DISPLAYLEVEL(4, "test%3i : create ZSTDMT CCtx : ", testNb++); +    {   ZSTDMT_CCtx* mtctx = ZSTDMT_createCCtx(2); +        if (mtctx==NULL) { +            DISPLAY("mtctx : mot enough memory, aborting \n"); +            testResult = 1; +            goto _end; +        } +        DISPLAYLEVEL(4, "OK \n"); + +        DISPLAYLEVEL(4, "test%3i : compress %u bytes with 2 threads : ", testNb++, (U32)CNBuffSize); +        CHECKPLUS(r, ZSTDMT_compressCCtx(mtctx, +                                compressedBuffer, ZSTD_compressBound(CNBuffSize), +                                CNBuffer, CNBuffSize, +                                1), +                  cSize=r ); +        DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); + +        DISPLAYLEVEL(4, "test%3i : decompressed size test : ", testNb++); +        {   unsigned long long const rSize = ZSTD_getFrameContentSize(compressedBuffer, cSize); +            if (rSize != CNBuffSize)  { +                DISPLAY("ZSTD_getFrameContentSize incorrect : %u != %u \n", (U32)rSize, (U32)CNBuffSize); +                goto _output_error; +        }   } +        DISPLAYLEVEL(4, "OK \n"); + +        DISPLAYLEVEL(4, "test%3i : decompress %u bytes : ", testNb++, (U32)CNBuffSize); +        { size_t const r = ZSTD_decompress(decodedBuffer, CNBuffSize, compressedBuffer, cSize); +          if (r != CNBuffSize) goto _output_error; } +        DISPLAYLEVEL(4, "OK \n"); + +        DISPLAYLEVEL(4, "test%3i : check decompressed result : ", testNb++); +        {   size_t u; +            for (u=0; u<CNBuffSize; u++) { +                if (((BYTE*)decodedBuffer)[u] != ((BYTE*)CNBuffer)[u]) goto _output_error;; +        }   } +        DISPLAYLEVEL(4, "OK \n"); + +        ZSTDMT_freeCCtx(mtctx); +    } + +      /* Simple API multiframe test */      DISPLAYLEVEL(4, "test%3i : compress multiple frames : ", testNb++);      {   size_t off = 0; @@ -351,7 +404,58 @@ static int basicUnitTests(U32 seed, double compressibility)                    if (r != CNBuffSize) goto _output_error);          DISPLAYLEVEL(4, "OK \n"); -        DISPLAYLEVEL(4, "test%3i : compress without dictID : ", testNb++); +        DISPLAYLEVEL(4, "test%3i : compress with preprocessed dictionary : ", testNb++); +        {   ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize); +            ZSTD_customMem customMem = { NULL, NULL, NULL }; +            ZSTD_CDict* cdict = ZSTD_createCDict_advanced(dictBuffer, dictSize, 1, cParams, customMem); +            cSize = ZSTD_compress_usingCDict(cctx, compressedBuffer, ZSTD_compressBound(CNBuffSize), +                                                 CNBuffer, CNBuffSize, cdict); +            ZSTD_freeCDict(cdict); +            if (ZSTD_isError(cSize)) goto _output_error; +        } +        DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); + +        DISPLAYLEVEL(4, "test%3i : retrieve dictID from frame : ", testNb++); +        {   U32 const did = ZSTD_getDictID_fromFrame(compressedBuffer, cSize); +            if (did != dictID) goto _output_error;   /* non-conformant (content-only) dictionary */ +        } +        DISPLAYLEVEL(4, "OK \n"); + +        DISPLAYLEVEL(4, "test%3i : frame built with dictionary should be decompressible : ", testNb++); +        CHECKPLUS(r, ZSTD_decompress_usingDict(dctx, +                                       decodedBuffer, CNBuffSize, +                                       compressedBuffer, cSize, +                                       dictBuffer, dictSize), +                  if (r != CNBuffSize) goto _output_error); +        DISPLAYLEVEL(4, "OK \n"); + +        DISPLAYLEVEL(4, "test%3i : ZSTD_compress_usingCDict_advanced, no contentSize, no dictID : ", testNb++); +        {   ZSTD_frameParameters const fParams = { 0 /* frameSize */, 1 /* checksum */, 1 /* noDictID*/ }; +            ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize); +            ZSTD_customMem const customMem = { NULL, NULL, NULL }; +            ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictSize, 1, cParams, customMem); +            cSize = ZSTD_compress_usingCDict_advanced(cctx, compressedBuffer, ZSTD_compressBound(CNBuffSize), +                                                 CNBuffer, CNBuffSize, cdict, fParams); +            ZSTD_freeCDict(cdict); +            if (ZSTD_isError(cSize)) goto _output_error; +        } +        DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); + +        DISPLAYLEVEL(4, "test%3i : try retrieving contentSize from frame : ", testNb++); +        {   U64 const contentSize = ZSTD_getFrameContentSize(compressedBuffer, cSize); +            if (contentSize != ZSTD_CONTENTSIZE_UNKNOWN) goto _output_error; +        } +        DISPLAYLEVEL(4, "OK (unknown)\n"); + +        DISPLAYLEVEL(4, "test%3i : frame built without dictID should be decompressible : ", testNb++); +        CHECKPLUS(r, ZSTD_decompress_usingDict(dctx, +                                       decodedBuffer, CNBuffSize, +                                       compressedBuffer, cSize, +                                       dictBuffer, dictSize), +                  if (r != CNBuffSize) goto _output_error); +        DISPLAYLEVEL(4, "OK \n"); + +        DISPLAYLEVEL(4, "test%3i : ZSTD_compress_advanced, no dictID : ", testNb++);          {   ZSTD_parameters p = ZSTD_getParams(3, CNBuffSize, dictSize);              p.fParams.noDictIDFlag = 1;              cSize = ZSTD_compress_advanced(cctx, compressedBuffer, ZSTD_compressBound(CNBuffSize), @@ -438,9 +542,9 @@ static int basicUnitTests(U32 seed, double compressibility)      /* Decompression defense tests */      DISPLAYLEVEL(4, "test%3i : Check input length for magic number : ", testNb++); -    { size_t const r = ZSTD_decompress(decodedBuffer, CNBuffSize, CNBuffer, 3); +    { size_t const r = ZSTD_decompress(decodedBuffer, CNBuffSize, CNBuffer, 3);   /* too small input */        if (!ZSTD_isError(r)) goto _output_error; -      if (r != (size_t)-ZSTD_error_srcSize_wrong) goto _output_error; } +      if (ZSTD_getErrorCode(r) != ZSTD_error_srcSize_wrong) goto _output_error; }      DISPLAYLEVEL(4, "OK \n");      DISPLAYLEVEL(4, "test%3i : Check magic Number : ", testNb++); @@ -449,6 +553,24 @@ static int basicUnitTests(U32 seed, double compressibility)        if (!ZSTD_isError(r)) goto _output_error; }      DISPLAYLEVEL(4, "OK \n"); +    /* content size verification test */ +    DISPLAYLEVEL(4, "test%3i : Content size verification : ", testNb++); +    {   ZSTD_CCtx* const cctx = ZSTD_createCCtx(); +        size_t const srcSize = 5000; +        size_t const wrongSrcSize = (srcSize + 1000); +        ZSTD_parameters params = ZSTD_getParams(1, wrongSrcSize, 0); +        params.fParams.contentSizeFlag = 1; +        {   size_t const result = ZSTD_compressBegin_advanced(cctx, NULL, 0, params, wrongSrcSize); +            if (ZSTD_isError(result)) goto _output_error; +        } +        {   size_t const result = ZSTD_compressEnd(cctx, decodedBuffer, CNBuffSize, CNBuffer, srcSize); +            if (!ZSTD_isError(result)) goto _output_error; +            if (ZSTD_getErrorCode(result) != ZSTD_error_srcSize_wrong) goto _output_error; +            DISPLAYLEVEL(4, "OK : %s \n", ZSTD_getErrorName(result)); +        } +        ZSTD_freeCCtx(cctx); +    } +      /* block API tests */      {   ZSTD_CCtx* const cctx = ZSTD_createCCtx();          static const size_t dictSize = 65 KB; @@ -600,6 +722,14 @@ static size_t findDiff(const void* buf1, const void* buf2, size_t max)  } +static ZSTD_parameters FUZ_makeParams(ZSTD_compressionParameters cParams, ZSTD_frameParameters fParams) +{ +    ZSTD_parameters params; +    params.cParams = cParams; +    params.fParams = fParams; +    return params; +} +  static size_t FUZ_rLogLength(U32* seed, U32 logLength)  {      size_t const lengthMask = ((size_t)1 << logLength) - 1; @@ -616,7 +746,7 @@ static size_t FUZ_randomLength(U32* seed, U32 maxLog)  #define CHECK(cond, ...) if (cond) { DISPLAY("Error => "); DISPLAY(__VA_ARGS__); \                           DISPLAY(" (seed %u, test nb %u)  \n", seed, testNb); goto _output_error; } -static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxDurationS, double compressibility) +static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxDurationS, double compressibility, int bigTests)  {      static const U32 maxSrcLog = 23;      static const U32 maxSampleLog = 22; @@ -636,6 +766,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD      U32 coreSeed = seed, lseed = 0;      clock_t const startClock = clock();      clock_t const maxClockSpan = maxDurationS * CLOCKS_PER_SEC; +    int const cLevelLimiter = bigTests ? 3 : 2;      /* allocation */      cNoiseBuffer[0] = (BYTE*)malloc (srcBufferSize); @@ -662,7 +793,6 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD      for ( ; (testNb <= nbTests) || (FUZ_clockSpan(startClock) < maxClockSpan); testNb++ ) {          size_t sampleSize, maxTestSize, totalTestSize;          size_t cSize, totalCSize, totalGenSize; -        XXH64_state_t xxhState;          U64 crcOrig;          BYTE* sampleBuffer;          const BYTE* dict; @@ -701,7 +831,10 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD          crcOrig = XXH64(sampleBuffer, sampleSize, 0);          /* compression tests */ -        {   unsigned const cLevel = (FUZ_rand(&lseed) % (ZSTD_maxCLevel() - (FUZ_highbit32((U32)sampleSize)/3))) + 1; +        {   unsigned const cLevel = +                    ( FUZ_rand(&lseed) % +                     (ZSTD_maxCLevel() - (FUZ_highbit32((U32)sampleSize) / cLevelLimiter)) ) +                     + 1;              cSize = ZSTD_compressCCtx(ctx, cBuffer, cBufferSize, sampleBuffer, sampleSize, cLevel);              CHECK(ZSTD_isError(cSize), "ZSTD_compressCCtx failed : %s", ZSTD_getErrorName(cSize)); @@ -801,7 +934,10 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD          {   U32 const testLog = FUZ_rand(&lseed) % maxSrcLog;              U32 const dictLog = FUZ_rand(&lseed) % maxSrcLog; -            int const cLevel = (FUZ_rand(&lseed) % (ZSTD_maxCLevel() - (MAX(testLog, dictLog)/3))) + 1; +            int const cLevel = (FUZ_rand(&lseed) % +                                (ZSTD_maxCLevel() - +                                 (MAX(testLog, dictLog) / cLevelLimiter))) + +                               1;              maxTestSize = FUZ_rLogLength(&lseed, testLog);              if (maxTestSize >= dstBufferSize) maxTestSize = dstBufferSize-1; @@ -813,22 +949,22 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD                  CHECK (ZSTD_isError(errorCode), "ZSTD_compressBegin_usingDict error : %s", ZSTD_getErrorName(errorCode));              } else {                  ZSTD_compressionParameters const cPar = ZSTD_getCParams(cLevel, 0, dictSize); -                ZSTD_frameParameters const fpar = { FUZ_rand(&lseed)&1 /* contentSizeFlag */, +                ZSTD_frameParameters const fPar = { FUZ_rand(&lseed)&1 /* contentSizeFlag */,                                                      !(FUZ_rand(&lseed)&3) /* contentChecksumFlag*/,                                                      0 /*NodictID*/ };   /* note : since dictionary is fake, dictIDflag has no impact */ -                ZSTD_parameters p; -                size_t errorCode; -                p.cParams = cPar; p.fParams = fpar; -                errorCode = ZSTD_compressBegin_advanced(refCtx, dict, dictSize, p, 0); +                ZSTD_parameters const p = FUZ_makeParams(cPar, fPar); +                size_t const errorCode = ZSTD_compressBegin_advanced(refCtx, dict, dictSize, p, 0);                  CHECK (ZSTD_isError(errorCode), "ZSTD_compressBegin_advanced error : %s", ZSTD_getErrorName(errorCode));              }              {   size_t const errorCode = ZSTD_copyCCtx(ctx, refCtx, 0);                  CHECK (ZSTD_isError(errorCode), "ZSTD_copyCCtx error : %s", ZSTD_getErrorName(errorCode));          }   } -        XXH64_reset(&xxhState, 0);          ZSTD_setCCtxParameter(ctx, ZSTD_p_forceWindow, FUZ_rand(&lseed) & 1); +          {   U32 const nbChunks = (FUZ_rand(&lseed) & 127) + 2;              U32 n; +            XXH64_state_t xxhState; +            XXH64_reset(&xxhState, 0);              for (totalTestSize=0, cSize=0, n=0 ; n<nbChunks ; n++) {                  size_t const segmentSize = FUZ_randomLength(&lseed, maxSampleLog);                  size_t const segmentStart = FUZ_rand(&lseed) % (srcBufferSize - segmentSize); @@ -843,13 +979,14 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD                  XXH64_update(&xxhState, srcBuffer+segmentStart, segmentSize);                  memcpy(mirrorBuffer + totalTestSize, srcBuffer+segmentStart, segmentSize);                  totalTestSize += segmentSize; -        }   } +            } -        {   size_t const flushResult = ZSTD_compressEnd(ctx, cBuffer+cSize, cBufferSize-cSize, NULL, 0); -            CHECK (ZSTD_isError(flushResult), "multi-segments epilogue error : %s", ZSTD_getErrorName(flushResult)); -            cSize += flushResult; +            {   size_t const flushResult = ZSTD_compressEnd(ctx, cBuffer+cSize, cBufferSize-cSize, NULL, 0); +                CHECK (ZSTD_isError(flushResult), "multi-segments epilogue error : %s", ZSTD_getErrorName(flushResult)); +                cSize += flushResult; +            } +            crcOrig = XXH64_digest(&xxhState);          } -        crcOrig = XXH64_digest(&xxhState);          /* streaming decompression test */          if (dictSize<8) dictSize=0, dict=NULL;   /* disable dictionary */ @@ -899,7 +1036,7 @@ _output_error:  /*_*******************************************************  *  Command line  *********************************************************/ -int FUZ_usage(const char* programName) +static int FUZ_usage(const char* programName)  {      DISPLAY( "Usage :\n");      DISPLAY( "      %s [args]\n", programName); @@ -915,19 +1052,39 @@ int FUZ_usage(const char* programName)      return 0;  } +/*! readU32FromChar() : +    @return : unsigned integer value read from input in `char` format +    allows and interprets K, KB, KiB, M, MB and MiB suffix. +    Will also modify `*stringPtr`, advancing it to position where it stopped reading. +    Note : function result can overflow if digit string > MAX_UINT */ +static unsigned readU32FromChar(const char** stringPtr) +{ +    unsigned result = 0; +    while ((**stringPtr >='0') && (**stringPtr <='9')) +        result *= 10, result += **stringPtr - '0', (*stringPtr)++ ; +    if ((**stringPtr=='K') || (**stringPtr=='M')) { +        result <<= 10; +        if (**stringPtr=='M') result <<= 10; +        (*stringPtr)++ ; +        if (**stringPtr=='i') (*stringPtr)++; +        if (**stringPtr=='B') (*stringPtr)++; +    } +    return result; +}  int main(int argc, const char** argv)  { -    U32 seed=0; -    int seedset=0; +    U32 seed = 0; +    int seedset = 0;      int argNb;      int nbTests = nbTestsDefault;      int testNb = 0;      U32 proba = FUZ_compressibility_default; -    int result=0; +    int result = 0;      U32 mainPause = 0;      U32 maxDuration = 0; -    const char* programName = argv[0]; +    int bigTests = 1; +    const char* const programName = argv[0];      /* Check command line */      for (argNb=1; argNb<argc; argNb++) { @@ -936,81 +1093,64 @@ int main(int argc, const char** argv)          /* Handle commands. Aggregated commands are allowed */          if (argument[0]=='-') { + +            if (!strcmp(argument, "--no-big-tests")) { bigTests=0; continue; } +              argument++;              while (*argument!=0) {                  switch(*argument)                  {                  case 'h':                      return FUZ_usage(programName); +                  case 'v':                      argument++; -                    g_displayLevel=4; +                    g_displayLevel = 4;                      break; +                  case 'q':                      argument++;                      g_displayLevel--;                      break; +                  case 'p': /* pause at the end */                      argument++;                      mainPause = 1;                      break;                  case 'i': -                    argument++; maxDuration=0; -                    nbTests=0; -                    while ((*argument>='0') && (*argument<='9')) { -                        nbTests *= 10; -                        nbTests += *argument - '0'; -                        argument++; -                    } +                    argument++; maxDuration = 0; +                    nbTests = readU32FromChar(&argument);                      break;                  case 'T':                      argument++; -                    nbTests=0; maxDuration=0; -                    while ((*argument>='0') && (*argument<='9')) { -                        maxDuration *= 10; -                        maxDuration += *argument - '0'; -                        argument++; -                    } -                    if (*argument=='m') maxDuration *=60, argument++; +                    nbTests = 0; +                    maxDuration = readU32FromChar(&argument); +                    if (*argument=='s') argument++;   /* seconds */ +                    if (*argument=='m') maxDuration *= 60, argument++;   /* minutes */                      if (*argument=='n') argument++;                      break;                  case 's':                      argument++; -                    seed=0; -                    seedset=1; -                    while ((*argument>='0') && (*argument<='9')) { -                        seed *= 10; -                        seed += *argument - '0'; -                        argument++; -                    } +                    seedset = 1; +                    seed = readU32FromChar(&argument);                      break;                  case 't':                      argument++; -                    testNb=0; -                    while ((*argument>='0') && (*argument<='9')) { -                        testNb *= 10; -                        testNb += *argument - '0'; -                        argument++; -                    } +                    testNb = readU32FromChar(&argument);                      break;                  case 'P':   /* compressibility % */                      argument++; -                    proba=0; -                    while ((*argument>='0') && (*argument<='9')) { -                        proba *= 10; -                        proba += *argument - '0'; -                        argument++; -                    } -                    if (proba>100) proba=100; +                    proba = readU32FromChar(&argument); +                    if (proba>100) proba = 100;                      break;                  default: -                    return FUZ_usage(programName); +                    return (FUZ_usage(programName), 1);      }   }   }   }   /* for (argNb=1; argNb<argc; argNb++) */      /* Get Seed */ @@ -1030,7 +1170,7 @@ int main(int argc, const char** argv)      if (testNb==0)          result = basicUnitTests(0, ((double)proba) / 100);  /* constant seed for predictability */      if (!result) -        result = fuzzerTests(seed, nbTests, testNb, maxDuration, ((double)proba) / 100); +        result = fuzzerTests(seed, nbTests, testNb, maxDuration, ((double)proba) / 100, bigTests);      if (mainPause) {          int unused;          DISPLAY("Press Enter \n"); diff --git a/tests/paramgrill.c b/tests/paramgrill.c index 5eabcba2b60b..1913b54d0a54 100644 --- a/tests/paramgrill.c +++ b/tests/paramgrill.c @@ -58,6 +58,11 @@ static const int g_maxNbVariations = 64;  **************************************/  #define DISPLAY(...)  fprintf(stderr, __VA_ARGS__) +#undef MIN +#undef MAX +#define MIN(a,b)   ( (a) < (b) ? (a) : (b) ) +#define MAX(a,b)   ( (a) > (b) ? (a) : (b) ) +  /*-************************************  *  Benchmark Parameters @@ -106,7 +111,11 @@ static size_t BMK_findMaxMem(U64 requiredMem)  } -#  define FUZ_rotl32(x,r) ((x << r) | (x >> (32 - r))) +static U32 FUZ_rotl32(U32 x, U32 r) +{ +    return ((x << r) | (x >> (32 - r))); +} +  U32 FUZ_rand(U32* src)  {      const U32 prime1 = 2654435761U; @@ -125,7 +134,7 @@ U32 FUZ_rand(U32* src)  *********************************************************/  typedef struct {      size_t cSize; -    double cSpeed; +    double cSpeed;   /* bytes / sec */      double dSpeed;  } BMK_result_t; @@ -141,8 +150,6 @@ typedef struct  } blockParam_t; -#define MIN(a,b)  ( (a) < (b) ? (a) : (b) ) -  static size_t BMK_benchParam(BMK_result_t* resultPtr,                               const void* srcBuffer, size_t srcSize,                               ZSTD_CCtx* ctx, @@ -165,6 +172,11 @@ static size_t BMK_benchParam(BMK_result_t* resultPtr,      char name[30] = { 0 };      U64 crcOrig; +    /* init result for early exit */ +    resultPtr->cSize = srcSize; +    resultPtr->cSpeed = 0.; +    resultPtr->dSpeed = 0.; +      /* Memory allocation & restrictions */      snprintf(name, 30, "Sw%02uc%02uh%02us%02ul%1ut%03uS%1u", Wlog, Clog, Hlog, Slog, Slength, Tlength, strat);      if (!compressedBuffer || !resultBuffer || !blockTable) { @@ -206,7 +218,6 @@ static size_t BMK_benchParam(BMK_result_t* resultPtr,          size_t cSize = 0;          double fastestC = 100000000., fastestD = 100000000.;          double ratio = 0.; -        U64 crcCheck = 0;          clock_t const benchStart = clock();          DISPLAY("\r%79s\r", ""); @@ -242,8 +253,8 @@ static size_t BMK_benchParam(BMK_result_t* resultPtr,              cSize = 0;              for (blockNb=0; blockNb<nbBlocks; blockNb++)                  cSize += blockTable[blockNb].cSize; -            if ((double)roundClock < fastestC * CLOCKS_PER_SEC * nbLoops) fastestC = ((double)roundClock / CLOCKS_PER_SEC) / nbLoops;              ratio = (double)srcSize / (double)cSize; +            if ((double)roundClock < fastestC * CLOCKS_PER_SEC * nbLoops) fastestC = ((double)roundClock / CLOCKS_PER_SEC) / nbLoops;              DISPLAY("\r");              DISPLAY("%1u-%s : %9u ->", loopNb, name, (U32)srcSize);              DISPLAY(" %9u (%4.3f),%7.1f MB/s", (U32)cSize, ratio, (double)srcSize / fastestC / 1000000.); @@ -273,18 +284,18 @@ static size_t BMK_benchParam(BMK_result_t* resultPtr,              resultPtr->dSpeed = (double)srcSize / fastestD;              /* CRC Checking */ -            crcCheck = XXH64(resultBuffer, srcSize, 0); -            if (crcOrig!=crcCheck) { -                unsigned u; -                unsigned eBlockSize = (unsigned)(MIN(65536*2, blockSize)); -                DISPLAY("\n!!! WARNING !!! Invalid Checksum : %x != %x\n", (unsigned)crcOrig, (unsigned)crcCheck); -                for (u=0; u<srcSize; u++) { -                    if (((const BYTE*)srcBuffer)[u] != ((BYTE*)resultBuffer)[u]) { -                        printf("Decoding error at pos %u (block %u, pos %u) \n", u, u / eBlockSize, u % eBlockSize); -                        break; -                }   } -                break; -            } +            {   U64 const crcCheck = XXH64(resultBuffer, srcSize, 0); +                if (crcOrig!=crcCheck) { +                    unsigned u; +                    unsigned eBlockSize = (unsigned)(MIN(65536*2, blockSize)); +                    DISPLAY("\n!!! WARNING !!! Invalid Checksum : %x != %x\n", (unsigned)crcOrig, (unsigned)crcCheck); +                    for (u=0; u<srcSize; u++) { +                        if (((const BYTE*)srcBuffer)[u] != ((BYTE*)resultBuffer)[u]) { +                            printf("Decoding error at pos %u (block %u, pos %u) \n", u, u / eBlockSize, u % eBlockSize); +                            break; +                    }   } +                    break; +            }   }  #endif      }   } @@ -505,8 +516,6 @@ static BYTE g_alreadyTested[PARAMTABLESIZE] = {0};   /* init to zero */      g_alreadyTested[(XXH64(sanitizeParams(p), sizeof(p), 0) >> 3) & PARAMTABLEMASK] -#define MAX(a,b)   ( (a) > (b) ? (a) : (b) ) -  static void playAround(FILE* f, winnerInfo_t* winners,                         ZSTD_compressionParameters params,                         const void* srcBuffer, size_t srcSize, @@ -711,6 +720,14 @@ int benchFiles(const char** fileNamesTable, int nbFiles)  } +static void BMK_translateAdvancedParams(ZSTD_compressionParameters params) +{ +    DISPLAY("--zstd=windowLog=%u,chainLog=%u,hashLog=%u,searchLog=%u,searchLength=%u,targetLength=%u,strategy=%u \n", +             params.windowLog, params.chainLog, params.hashLog, params.searchLog, params.searchLength, params.targetLength, (U32)(params.strategy)); +} + +/* optimizeForSize(): + * targetSpeed : expressed in MB/s */  int optimizeForSize(const char* inFileName, U32 targetSpeed)  {      FILE* const inFile = fopen( inFileName, "rb" ); @@ -723,8 +740,11 @@ int optimizeForSize(const char* inFileName, U32 targetSpeed)      /* Memory allocation & restrictions */      if ((U64)benchedSize > inFileSize) benchedSize = (size_t)inFileSize; -    if (benchedSize < inFileSize) -        DISPLAY("Not enough memory for '%s' full size; testing %i MB only...\n", inFileName, (int)(benchedSize>>20)); +    if (benchedSize < inFileSize) { +        DISPLAY("Not enough memory for '%s' \n", inFileName); +        fclose(inFile); +        return 11; +    }      /* Alloc */      origBuff = malloc(benchedSize); @@ -747,10 +767,9 @@ int optimizeForSize(const char* inFileName, U32 targetSpeed)      /* bench */      DISPLAY("\r%79s\r", "");      DISPLAY("optimizing for %s - limit speed %u MB/s \n", inFileName, targetSpeed); -    targetSpeed *= 1000; +    targetSpeed *= 1000000;      {   ZSTD_CCtx* const ctx = ZSTD_createCCtx(); -        ZSTD_compressionParameters params;          winnerInfo_t winner;          BMK_result_t candidate;          const size_t blockSize = g_blockSize ? g_blockSize : benchedSize; @@ -764,26 +783,28 @@ int optimizeForSize(const char* inFileName, U32 targetSpeed)          {   const int maxSeeds = g_noSeed ? 1 : ZSTD_maxCLevel();              int i;              for (i=1; i<=maxSeeds; i++) { -                params = ZSTD_getCParams(i, blockSize, 0); -                BMK_benchParam(&candidate, origBuff, benchedSize, ctx, params); +                ZSTD_compressionParameters const CParams = ZSTD_getCParams(i, blockSize, 0); +                BMK_benchParam(&candidate, origBuff, benchedSize, ctx, CParams);                  if (candidate.cSpeed < targetSpeed)                      break;                  if ( (candidate.cSize < winner.result.cSize)                     | ((candidate.cSize == winner.result.cSize) & (candidate.cSpeed > winner.result.cSpeed)) )                  { -                    winner.params = params; +                    winner.params = CParams;                      winner.result = candidate;                      BMK_printWinner(stdout, i, winner.result, winner.params, benchedSize);              }   }          }          BMK_printWinner(stdout, 99, winner.result, winner.params, benchedSize); +        BMK_translateAdvancedParams(winner.params);          /* start tests */          {   time_t const grillStart = time(NULL);              do { -                params = winner.params; +                ZSTD_compressionParameters params = winner.params;                  paramVariation(¶ms); -                if ((FUZ_rand(&g_rand) & 15) == 3) params = randomParams(); +                if ((FUZ_rand(&g_rand) & 31) == 3) params = randomParams();  /* totally random config to improve search space */ +                params = ZSTD_adjustCParams(params, blockSize, 0);                  /* exclude faster if already played set of params */                  if (FUZ_rand(&g_rand) & ((1 << NB_TESTS_PLAYED(params))-1)) continue; @@ -800,6 +821,7 @@ int optimizeForSize(const char* inFileName, U32 targetSpeed)                      winner.params = params;                      winner.result = candidate;                      BMK_printWinner(stdout, 99, winner.result, winner.params, benchedSize); +                    BMK_translateAdvancedParams(winner.params);                  }              } while (BMK_timeSpan(grillStart) < g_grillDuration_s);          } @@ -833,7 +855,7 @@ static int usage_advanced(void)      DISPLAY( " -T#    : set level 1 speed objective \n");      DISPLAY( " -B#    : cut input into blocks of size # (default : single block) \n");      DISPLAY( " -i#    : iteration loops [1-9](default : %i) \n", NBLOOPS); -    DISPLAY( " -O#    : find Optimized parameters for # target speed (default : 0) \n"); +    DISPLAY( " -O#    : find Optimized parameters for # MB/s compression speed (default : 0) \n");      DISPLAY( " -S     : Single run \n");      DISPLAY( " -P#    : generated sample compressibility (default : %.1f%%) \n", COMPRESSIBILITY_DEFAULT * 100);      return 0; diff --git a/tests/playTests.sh b/tests/playTests.sh index c493fed55358..021fd59fe2af 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -11,6 +11,7 @@ roundTripTest() {          local_p="$2"      else          local_c="$2" +        local_p=""      fi      rm -f tmp1 tmp2 @@ -20,13 +21,36 @@ roundTripTest() {      $DIFF -q tmp1 tmp2  } +fileRoundTripTest() { +    if [ -n "$3" ]; then +        local_c="$3" +        local_p="$2" +    else +        local_c="$2" +        local_p="" +    fi + +    rm -f tmp.zstd tmp.md5.1 tmp.md5.2 +    $ECHO "fileRoundTripTest: ./datagen $1 $local_p > tmp && $ZSTD -v$local_c -c tmp | $ZSTD -d" +    ./datagen $1 $local_p > tmp +    cat tmp | $MD5SUM > tmp.md5.1 +    $ZSTD --ultra -v$local_c -c tmp | $ZSTD -d | $MD5SUM > tmp.md5.2 +    $DIFF -q tmp.md5.1 tmp.md5.2 +} + +isTerminal=false +if [ -t 0 ] && [ -t 1 ] +then +    isTerminal=true +fi +  isWindows=false -ECHO="echo" +ECHO="echo -e"  INTOVOID="/dev/null"  case "$OS" in    Windows*)      isWindows=true -    ECHO="echo -e" +    INTOVOID="NUL"      ;;  esac @@ -42,11 +66,17 @@ case "$UNAME" in    SunOS) DIFF="gdiff" ;;  esac -  $ECHO "\nStarting playTests.sh isWindows=$isWindows ZSTD='$ZSTD'"  [ -n "$ZSTD" ] || die "ZSTD variable must be defined!" +if [ -n "$(echo hello | $ZSTD -v -T2 2>&1 > $INTOVOID | grep 'multi-threading is disabled')" ] +then +    hasMT="" +else +    hasMT="true" +fi +  $ECHO "\n**** simple tests **** "  ./datagen > tmp @@ -72,6 +102,12 @@ cp tmp tmp2  $ZSTD tmp2 -fo && die "-o must be followed by filename "  $ECHO "test : implied stdout when input is stdin"  $ECHO bob | $ZSTD | $ZSTD -d +if [ "$isTerminal" = true ]; then +$ECHO "test : compressed data to terminal" +$ECHO bob | $ZSTD && die "should have refused : compressed data to terminal" +$ECHO "test : compressed data from terminal (a hang here is a test fail, zstd is wrongly waiting on data from terminal)" +$ZSTD -d > $INTOVOID && die "should have refused : compressed data from terminal" +fi  $ECHO "test : null-length file roundtrip"  $ECHO -n '' | $ZSTD - --stdout | $ZSTD -d --stdout  $ECHO "test : decompress file with wrong suffix (must fail)" @@ -96,6 +132,14 @@ $ZSTD -q tmp && die "overwrite check failed!"  $ECHO "test : force overwrite"  $ZSTD -q -f tmp  $ZSTD -q --force tmp +$ECHO "test : overwrite readonly file" +rm -f tmpro tmpro.zst +$ECHO foo > tmpro.zst +$ECHO foo > tmpro +chmod 400 tmpro.zst +$ZSTD -q tmpro && die "should have refused to overwrite read-only file" +$ZSTD -q -f tmpro +rm -f tmpro tmpro.zst  $ECHO "test : file removal"  $ZSTD -f --rm tmp  ls tmp && die "tmp should no longer be present" @@ -156,6 +200,19 @@ $ECHO "$ECHO foo | $ZSTD > /dev/full"  $ECHO foo | $ZSTD > /dev/full && die "write error not detected!"  $ECHO "$ECHO foo | $ZSTD | $ZSTD -d > /dev/full"  $ECHO foo | $ZSTD | $ZSTD -d > /dev/full && die "write error not detected!" + +$ECHO "\n**** symbolic link test **** " + +rm -f hello.tmp world.tmp hello.tmp.zst world.tmp.zst +$ECHO "hello world" > hello.tmp +ln -s hello.tmp world.tmp +$ZSTD world.tmp hello.tmp +ls hello.tmp.zst || die "regular file should have been compressed!" +ls world.tmp.zst && die "symbolic link should not have been compressed!" +$ZSTD world.tmp hello.tmp -f +ls world.tmp.zst || die "symbol link should have been compressed with --force" +rm -f hello.tmp world.tmp hello.tmp.zst world.tmp.zst +  fi @@ -227,12 +284,12 @@ $ECHO "- Create second (different) dictionary "  $ZSTD --train *.c ../programs/*.c ../programs/*.h -o tmpDictC  $ZSTD -d tmp.zst -D tmpDictC -fo result && die "wrong dictionary not detected!"  $ECHO "- Create dictionary with short dictID" -$ZSTD --train *.c ../programs/*.c --dictID 1 -o tmpDict1 +$ZSTD --train *.c ../programs/*.c --dictID=1 -o tmpDict1  cmp tmpDict tmpDict1 && die "dictionaries should have different ID !"  $ECHO "- Create dictionary with wrong dictID parameter order (must fail)"  $ZSTD --train *.c ../programs/*.c --dictID -o 1 tmpDict1 && die "wrong order : --dictID must be followed by argument "  $ECHO "- Create dictionary with size limit" -$ZSTD --train *.c ../programs/*.c -o tmpDict2 --maxdict 4K -v +$ZSTD --train *.c ../programs/*.c -o tmpDict2 --maxdict=4K -v  $ECHO "- Create dictionary with wrong parameter order (must fail)"  $ZSTD --train *.c ../programs/*.c -o tmpDict2 --maxdict -v 4K && die "wrong order : --maxdict must be followed by argument "  $ECHO "- Compress without dictID" @@ -240,7 +297,7 @@ $ZSTD -f tmp -D tmpDict1 --no-dictID  $ZSTD -d tmp.zst -D tmpDict -fo result  $DIFF $TESTFILE result  $ECHO "- Compress with wrong argument order (must fail)" -$ZSTD tmp -Df tmpDict1 -c > /dev/null && die "-D must be followed by dictionary name " +$ZSTD tmp -Df tmpDict1 -c > $INTOVOID && die "-D must be followed by dictionary name "  $ECHO "- Compress multiple files with dictionary"  rm -rf dirTestDict  mkdir dirTestDict @@ -255,6 +312,11 @@ case "$UNAME" in    *) $MD5SUM -c tmph1 ;;  esac  rm -rf dirTestDict +$ECHO "- dictionary builder on bogus input" +$ECHO "Hello World" > tmp +$ZSTD --train-legacy -q tmp && die "Dictionary training should fail : not enough input source" +./datagen -P0 -g10M > tmp +$ZSTD --train-legacy -q tmp && die "Dictionary training should fail : source is pure noise"  rm tmp* @@ -263,19 +325,39 @@ $ECHO "\n**** cover dictionary tests **** "  TESTFILE=../programs/zstdcli.c  ./datagen > tmpDict  $ECHO "- Create first dictionary" -$ZSTD --train --cover=k=46,d=8 *.c ../programs/*.c -o tmpDict +$ZSTD --train-cover=k=46,d=8 *.c ../programs/*.c -o tmpDict  cp $TESTFILE tmp  $ZSTD -f tmp -D tmpDict  $ZSTD -d tmp.zst -D tmpDict -fo result  $DIFF $TESTFILE result  $ECHO "- Create second (different) dictionary" -$ZSTD --train --cover=k=56,d=8 *.c ../programs/*.c ../programs/*.h -o tmpDictC +$ZSTD --train-cover=k=56,d=8 *.c ../programs/*.c ../programs/*.h -o tmpDictC  $ZSTD -d tmp.zst -D tmpDictC -fo result && die "wrong dictionary not detected!"  $ECHO "- Create dictionary with short dictID" -$ZSTD --train --cover=k=46,d=8 *.c ../programs/*.c --dictID 1 -o tmpDict1 +$ZSTD --train-cover=k=46,d=8 *.c ../programs/*.c --dictID=1 -o tmpDict1  cmp tmpDict tmpDict1 && die "dictionaries should have different ID !"  $ECHO "- Create dictionary with size limit" -$ZSTD --train --optimize-cover=steps=8 *.c ../programs/*.c -o tmpDict2 --maxdict 4K +$ZSTD --train-cover=steps=8 *.c ../programs/*.c -o tmpDict2 --maxdict=4K +rm tmp* + +$ECHO "\n**** legacy dictionary tests **** " + +TESTFILE=../programs/zstdcli.c +./datagen > tmpDict +$ECHO "- Create first dictionary" +$ZSTD --train-legacy=selectivity=8 *.c ../programs/*.c -o tmpDict +cp $TESTFILE tmp +$ZSTD -f tmp -D tmpDict +$ZSTD -d tmp.zst -D tmpDict -fo result +$DIFF $TESTFILE result +$ECHO "- Create second (different) dictionary" +$ZSTD --train-legacy=s=5 *.c ../programs/*.c ../programs/*.h -o tmpDictC +$ZSTD -d tmp.zst -D tmpDictC -fo result && die "wrong dictionary not detected!" +$ECHO "- Create dictionary with short dictID" +$ZSTD --train-legacy -s5 *.c ../programs/*.c --dictID=1 -o tmpDict1 +cmp tmpDict tmpDict1 && die "dictionaries should have different ID !" +$ECHO "- Create dictionary with size limit" +$ZSTD --train-legacy -s9 *.c ../programs/*.c -o tmpDict2 --maxdict=4K  rm tmp* @@ -341,7 +423,7 @@ if [ $GZIPMODE -eq 1 ]; then      $ZSTD -f --format=gzip tmp      $ZSTD -f tmp      cat tmp.gz tmp.zst tmp.gz tmp.zst | $ZSTD -d -f -o tmp -    head -c -1 tmp.gz | $ZSTD -t && die "incomplete frame not detected !" +    head -c -1 tmp.gz | $ZSTD -t > $INTOVOID && die "incomplete frame not detected !"      rm tmp*  else      $ECHO "gzip mode not supported" @@ -383,13 +465,48 @@ if [ $LZMAMODE -eq 1 ]; then      $ZSTD -f --format=lzma tmp      $ZSTD -f tmp      cat tmp.xz tmp.lzma tmp.zst tmp.lzma tmp.xz tmp.zst | $ZSTD -d -f -o tmp -    head -c -1 tmp.xz | $ZSTD -t && die "incomplete frame not detected !" -    head -c -1 tmp.lzma | $ZSTD -t && die "incomplete frame not detected !" +    head -c -1 tmp.xz | $ZSTD -t > $INTOVOID && die "incomplete frame not detected !" +    head -c -1 tmp.lzma | $ZSTD -t > $INTOVOID && die "incomplete frame not detected !"      rm tmp*  else      $ECHO "xz mode not supported"  fi +$ECHO "\n**** lz4 compatibility tests **** " + +LZ4MODE=1 +$ZSTD --format=lz4 -V || LZ4MODE=0 +if [ $LZ4MODE -eq 1 ]; then +    $ECHO "lz4 support detected" +    LZ4EXE=1 +    lz4 -V || LZ4EXE=0 +    if [ $LZ4EXE -eq 1 ]; then +        ./datagen > tmp +        $ZSTD --format=lz4 -f tmp +        lz4 -t -v tmp.lz4 +        lz4 -f tmp +        $ZSTD -d -f -v tmp.lz4 +        rm tmp* +    else +        $ECHO "lz4 binary not detected" +    fi +else +    $ECHO "lz4 mode not supported" +fi + + +$ECHO "\n**** lz4 frame tests **** " + +if [ $LZ4MODE -eq 1 ]; then +    ./datagen > tmp +    $ZSTD -f --format=lz4 tmp +    $ZSTD -f tmp +    cat tmp.lz4 tmp.zst tmp.lz4 tmp.zst | $ZSTD -d -f -o tmp +    head -c -1 tmp.lz4 | $ZSTD -t > $INTOVOID && die "incomplete frame not detected !" +    rm tmp* +else +    $ECHO "lz4 mode not supported" +fi  $ECHO "\n**** zstd round-trip tests **** " @@ -402,6 +519,19 @@ roundTripTest -g519K 6    # greedy, hash chain  roundTripTest -g517K 16   # btlazy2  roundTripTest -g516K 19   # btopt +fileRoundTripTest -g500K + +if [ -n "$hasMT" ] +then +    $ECHO "\n**** zstdmt round-trip tests **** " +    roundTripTest -g4M "1 -T0" +    roundTripTest -g8M "3 -T2" +    roundTripTest -g8000K "2 --threads=2" +    fileRoundTripTest -g4M "19 -T2 -B1M" +else +    $ECHO "\n**** no multithreading, skipping zstdmt tests **** " +fi +  rm tmp*  if [ "$1" != "--test-large-data" ]; then @@ -437,4 +567,16 @@ roundTripTest -g50000000 -P94 19  roundTripTest -g99000000 -P99 20  roundTripTest -g6000000000 -P99 1 +fileRoundTripTest -g4193M -P99 1 + +if [ -n "$hasMT" ] +then +    $ECHO "\n**** zstdmt long round-trip tests **** " +    roundTripTest -g99000000 -P99 "20 -T2" +    roundTripTest -g6000000000 -P99 "1 -T2" +    fileRoundTripTest -g4193M -P98 " -T0" +else +    $ECHO "\n**** no multithreading, skipping zstdmt tests **** " +fi +  rm tmp* diff --git a/tests/test-zstd-speed.py b/tests/test-zstd-speed.py index 23d4f477c7f3..56108a5cae4c 100755 --- a/tests/test-zstd-speed.py +++ b/tests/test-zstd-speed.py @@ -14,14 +14,15 @@  # - dir1/zstd and dir2/zstd will be merged in a single results file  import argparse -import os +import os           # getloadavg  import string  import subprocess -import time +import time         # strftime  import traceback  import hashlib +import platform     # system -script_version = 'v1.1.1 (2016-10-28)' +script_version = 'v1.1.2 (2017-03-26)'  default_repo_url = 'https://github.com/facebook/zstd.git'  working_dir_name = 'speedTest'  working_path = os.getcwd() + '/' + working_dir_name     # /path/to/zstd/tests/speedTest @@ -152,10 +153,15 @@ def benchmark_and_compare(branch, commit, last_commit, args, executableName, md5              % (os.getloadavg()[0], args.maxLoadAvg, sleepTime))          time.sleep(sleepTime)      start_load = str(os.getloadavg()) +    osType = platform.system() +    if osType == 'Linux': +        cpuSelector = "taskset --cpu-list 0" +    else: +        cpuSelector = ""      if args.dictionary: -        result = execute('programs/%s -rqi5b1e%s -D %s %s' % (executableName, args.lastCLevel, args.dictionary, testFilePath), print_output=True) +        result = execute('%s programs/%s -rqi5b1e%s -D %s %s' % (cpuSelector, executableName, args.lastCLevel, args.dictionary, testFilePath), print_output=True)      else: -        result = execute('programs/%s -rqi5b1e%s %s' % (executableName, args.lastCLevel, testFilePath), print_output=True)    +        result = execute('%s programs/%s -rqi5b1e%s %s' % (cpuSelector, executableName, args.lastCLevel, testFilePath), print_output=True)      end_load = str(os.getloadavg())      linesExpected = args.lastCLevel + 1      if len(result) != linesExpected: @@ -291,7 +297,7 @@ if __name__ == '__main__':          log("ERROR: e-mail senders 'mail' or 'mutt' not found")          exit(1) -    clang_version = execute("clang -v 2>&1 | grep 'clang version' | sed -e 's:.*version \\([0-9.]*\\).*:\\1:' -e 's:\\.\\([0-9][0-9]\\):\\1:g'", verbose)[0]; +    clang_version = execute("clang -v 2>&1 | grep ' version ' | sed -e 's:.*version \\([0-9.]*\\).*:\\1:' -e 's:\\.\\([0-9][0-9]\\):\\1:g'", verbose)[0];      gcc_version = execute("gcc -dumpversion", verbose)[0];      if verbose: diff --git a/tests/zbufftest.c b/tests/zbufftest.c index 14b73923311d..601aa808d027 100644 --- a/tests/zbufftest.c +++ b/tests/zbufftest.c @@ -60,7 +60,7 @@ static U32 g_displayLevel = 2;  #define DISPLAYUPDATE(l, ...) if (g_displayLevel>=l) { \              if ((FUZ_GetClockSpan(g_displayClock) > g_refreshRate) || (g_displayLevel>=4)) \              { g_displayClock = clock(); DISPLAY(__VA_ARGS__); \ -            if (g_displayLevel>=4) fflush(stdout); } } +            if (g_displayLevel>=4) fflush(stderr); } }  static const clock_t g_refreshRate = CLOCKS_PER_SEC * 15 / 100;  static clock_t g_displayClock = 0; diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index aa7367bcfd31..0e09e185642b 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -59,7 +59,7 @@ static U32 g_displayLevel = 2;  #define DISPLAYUPDATE(l, ...) if (g_displayLevel>=l) { \              if ((FUZ_GetClockSpan(g_displayClock) > g_refreshRate) || (g_displayLevel>=4)) \              { g_displayClock = clock(); DISPLAY(__VA_ARGS__); \ -            if (g_displayLevel>=4) fflush(stdout); } } +            if (g_displayLevel>=4) fflush(stderr); } }  static const clock_t g_refreshRate = CLOCKS_PER_SEC / 6;  static clock_t g_displayClock = 0; @@ -131,7 +131,7 @@ static buffer_t FUZ_createDictionary(const void* src, size_t srcSize, size_t blo      }      {   size_t const dictSize = ZDICT_trainFromBuffer(dict.start, requestedDictSize, src, blockSizes, (unsigned)nbBlocks);          free(blockSizes); -        if (ZDICT_isError(dictSize)) { free(dict.start); return (buffer_t){ NULL, 0, 0 }; } +        if (ZDICT_isError(dictSize)) { free(dict.start); return g_nullBuffer; }          dict.size = requestedDictSize;          dict.filled = dictSize;          return dict;   /* how to return dictSize ? */ @@ -207,6 +207,16 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo        DISPLAYLEVEL(3, "OK (%u bytes) \n", (U32)s);      } +    /* Attempt bad compression parameters */ +    DISPLAYLEVEL(3, "test%3i : use bad compression parameters : ", testNb++); +    {   size_t r; +        ZSTD_parameters params = ZSTD_getParams(1, 0, 0); +        params.cParams.searchLength = 2; +        r = ZSTD_initCStream_advanced(zc, NULL, 0, params, 0); +        if (!ZSTD_isError(r)) goto _output_error; +        DISPLAYLEVEL(3, "init error : %s \n", ZSTD_getErrorName(r)); +    } +      /* skippable frame test */      DISPLAYLEVEL(3, "test%3i : decompress skippable frame : ", testNb++);      ZSTD_initDStream_usingDict(zd, CNBuffer, 128 KB); @@ -438,11 +448,64 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo        if (!ZSTD_isError(r)) goto _output_error;  /* must fail : frame requires > 100 bytes */        DISPLAYLEVEL(3, "OK (%s)\n", ZSTD_getErrorName(r)); } -    /* Unknown srcSize */ +    DISPLAYLEVEL(3, "test%3i : ZSTD_initCStream_usingCDict_advanced with masked dictID : ", testNb++); +    {   ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBufferSize, dictionary.filled); +        ZSTD_frameParameters const fParams = { 1 /* contentSize */, 1 /* checksum */, 1 /* noDictID */}; +        ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictionary.start, dictionary.filled, 1 /* byReference */, cParams, customMem); +        size_t const initError = ZSTD_initCStream_usingCDict_advanced(zc, cdict, CNBufferSize, fParams); +        if (ZSTD_isError(initError)) goto _output_error; +        cSize = 0; +        outBuff.dst = compressedBuffer; +        outBuff.size = compressedBufferSize; +        outBuff.pos = 0; +        inBuff.src = CNBuffer; +        inBuff.size = CNBufferSize; +        inBuff.pos = 0; +        { size_t const r = ZSTD_compressStream(zc, &outBuff, &inBuff); +          if (ZSTD_isError(r)) goto _output_error; } +        if (inBuff.pos != inBuff.size) goto _output_error;   /* entire input should be consumed */ +        { size_t const r = ZSTD_endStream(zc, &outBuff); +          if (r != 0) goto _output_error; }  /* error, or some data not flushed */ +        cSize = outBuff.pos; +        ZSTD_freeCDict(cdict); +        DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBufferSize*100); +    } + +    DISPLAYLEVEL(3, "test%3i : try retrieving dictID from frame : ", testNb++); +    {   U32 const did = ZSTD_getDictID_fromFrame(compressedBuffer, cSize); +        if (did != 0) goto _output_error; +    } +    DISPLAYLEVEL(3, "OK (not detected) \n"); + +    DISPLAYLEVEL(3, "test%3i : decompress without dictionary : ", testNb++); +    {   size_t const r = ZSTD_decompress(decodedBuffer, CNBufferSize, compressedBuffer, cSize); +        if (!ZSTD_isError(r)) goto _output_error;  /* must fail : dictionary not used */ +        DISPLAYLEVEL(3, "OK (%s)\n", ZSTD_getErrorName(r)); +    } + +    /* Empty srcSize */ +    DISPLAYLEVEL(3, "test%3i : ZSTD_initCStream_advanced with pledgedSrcSize=0 and dict : ", testNb++); +    {   ZSTD_parameters params = ZSTD_getParams(5, 0, 0); +        params.fParams.contentSizeFlag = 1; +        ZSTD_initCStream_advanced(zc, dictionary.start, dictionary.filled, params, 0); +    } /* cstream advanced shall write content size = 0 */ +    inBuff.src = CNBuffer; +    inBuff.size = 0; +    inBuff.pos = 0; +    outBuff.dst = compressedBuffer; +    outBuff.size = compressedBufferSize; +    outBuff.pos = 0; +    if (ZSTD_isError(ZSTD_compressStream(zc, &outBuff, &inBuff))) goto _output_error; +    if (ZSTD_endStream(zc, &outBuff) != 0) goto _output_error; +    cSize = outBuff.pos; +    if (ZSTD_findDecompressedSize(compressedBuffer, cSize) != 0) goto _output_error; +    DISPLAYLEVEL(3, "OK \n"); +      DISPLAYLEVEL(3, "test%3i : pledgedSrcSize == 0 behaves properly : ", testNb++);      {   ZSTD_parameters params = ZSTD_getParams(5, 0, 0);          params.fParams.contentSizeFlag = 1; -        ZSTD_initCStream_advanced(zc, NULL, 0, params, 0); } /* cstream advanced should write the 0 size field */ +        ZSTD_initCStream_advanced(zc, NULL, 0, params, 0); +    } /* cstream advanced shall write content size = 0 */      inBuff.src = CNBuffer;      inBuff.size = 0;      inBuff.pos = 0; @@ -552,7 +615,7 @@ static size_t FUZ_randomLength(U32* seed, U32 maxLog)  #define CHECK(cond, ...) if (cond) { DISPLAY("Error => "); DISPLAY(__VA_ARGS__); \                           DISPLAY(" (seed %u, test nb %u)  \n", seed, testNb); goto _output_error; } -static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibility) +static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibility, int bigTests)  {      static const U32 maxSrcLog = 24;      static const U32 maxSampleLog = 19; @@ -574,6 +637,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres      const BYTE* dict=NULL;   /* can keep same dict on 2 consecutive tests */      size_t dictSize = 0;      U32 oldTestLog = 0; +    int const cLevelLimiter = bigTests ? 3 : 2;      /* allocations */      cNoiseBuffer[0] = (BYTE*)malloc (srcBufferSize); @@ -638,7 +702,8 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres          if ((FUZ_rand(&lseed)&1) /* at beginning, to keep same nb of rand */              && oldTestLog /* at least one test happened */ && resetAllowed) {              maxTestSize = FUZ_randomLength(&lseed, oldTestLog+2); -            if (maxTestSize >= srcBufferSize) maxTestSize = srcBufferSize-1; +            if (maxTestSize >= srcBufferSize) +                maxTestSize = srcBufferSize-1;              {   U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? 0 : maxTestSize;                  size_t const resetError = ZSTD_resetCStream(zc, pledgedSrcSize);                  CHECK(ZSTD_isError(resetError), "ZSTD_resetCStream error : %s", ZSTD_getErrorName(resetError)); @@ -646,11 +711,14 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres          } else {              U32 const testLog = FUZ_rand(&lseed) % maxSrcLog;              U32 const dictLog = FUZ_rand(&lseed) % maxSrcLog; -            U32 const cLevel = (FUZ_rand(&lseed) % (ZSTD_maxCLevel() - (MAX(testLog, dictLog)/3))) + 1; +            U32 const cLevel = ( FUZ_rand(&lseed) % +                                (ZSTD_maxCLevel() - +                                (MAX(testLog, dictLog) / cLevelLimiter))) +                                 + 1;              maxTestSize = FUZ_rLogLength(&lseed, testLog);              oldTestLog = testLog;              /* random dictionary selection */ -            dictSize  = ((FUZ_rand(&lseed)&63)==1) ? FUZ_rLogLength(&lseed, dictLog) : 0; +            dictSize  = ((FUZ_rand(&lseed)&1)==1) ? FUZ_rLogLength(&lseed, dictLog) : 0;              {   size_t const dictStart = FUZ_rand(&lseed) % (srcBufferSize - dictSize);                  dict = srcBuffer + dictStart;              } @@ -785,7 +853,7 @@ _output_error:  /* Multi-threading version of fuzzer Tests */ -static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double compressibility) +static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double compressibility, int bigTests)  {      static const U32 maxSrcLog = 24;      static const U32 maxSampleLog = 19; @@ -807,6 +875,7 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp      const BYTE* dict=NULL;   /* can keep same dict on 2 consecutive tests */      size_t dictSize = 0;      U32 oldTestLog = 0; +    int const cLevelLimiter = bigTests ? 3 : 2;      /* allocations */      cNoiseBuffer[0] = (BYTE*)malloc (srcBufferSize); @@ -851,6 +920,7 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp          /* some issues can only happen when reusing states */          if ((FUZ_rand(&lseed) & 0xFF) == 131) {              U32 const nbThreads = (FUZ_rand(&lseed) % 6) + 1; +            DISPLAYLEVEL(5, "Creating new context with %u threads \n", nbThreads);              ZSTDMT_freeCCtx(zc);              zc = ZSTDMT_createCCtx(nbThreads);              resetAllowed=0; @@ -888,7 +958,10 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp          } else {              U32 const testLog = FUZ_rand(&lseed) % maxSrcLog;              U32 const dictLog = FUZ_rand(&lseed) % maxSrcLog; -            U32 const cLevel = (FUZ_rand(&lseed) % (ZSTD_maxCLevel() - (MAX(testLog, dictLog)/3))) + 1; +            U32 const cLevel = (FUZ_rand(&lseed) % +                                (ZSTD_maxCLevel() - +                                 (MAX(testLog, dictLog) / cLevelLimiter))) + +                               1;              maxTestSize = FUZ_rLogLength(&lseed, testLog);              oldTestLog = testLog;              /* random dictionary selection */ @@ -898,9 +971,12 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp              }              {   U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? 0 : maxTestSize;                  ZSTD_parameters params = ZSTD_getParams(cLevel, pledgedSrcSize, dictSize); -                DISPLAYLEVEL(5, "Init with windowLog = %u \n", params.cParams.windowLog); +                DISPLAYLEVEL(5, "Init with windowLog = %u and pledgedSrcSize = %u \n", +                    params.cParams.windowLog, (U32)pledgedSrcSize);                  params.fParams.checksumFlag = FUZ_rand(&lseed) & 1;                  params.fParams.noDictIDFlag = FUZ_rand(&lseed) & 1; +                params.fParams.contentSizeFlag = pledgedSrcSize>0; +                DISPLAYLEVEL(5, "checksumFlag : %u \n", params.fParams.checksumFlag);                  { size_t const initError = ZSTDMT_initCStream_advanced(zc, dict, dictSize, params, pledgedSrcSize);                    CHECK (ZSTD_isError(initError),"ZSTDMT_initCStream_advanced error : %s", ZSTD_getErrorName(initError)); }                  ZSTDMT_setMTCtxParameter(zc, ZSTDMT_p_overlapSectionLog, FUZ_rand(&lseed) % 12); @@ -938,7 +1014,7 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp                      outBuff.size = outBuff.pos + adjustedDstSize;                      DISPLAYLEVEL(5, "Flushing into dst buffer of size %u \n", (U32)adjustedDstSize);                      {   size_t const flushError = ZSTDMT_flushStream(zc, &outBuff); -                        CHECK (ZSTD_isError(flushError), "flush error : %s", ZSTD_getErrorName(flushError)); +                        CHECK (ZSTD_isError(flushError), "ZSTDMT_flushStream error : %s", ZSTD_getErrorName(flushError));              }   }   }              /* final frame epilogue */ @@ -949,12 +1025,12 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp                      outBuff.size = outBuff.pos + adjustedDstSize;                      DISPLAYLEVEL(5, "Ending into dst buffer of size %u \n", (U32)adjustedDstSize);                      remainingToFlush = ZSTDMT_endStream(zc, &outBuff); -                    CHECK (ZSTD_isError(remainingToFlush), "flush error : %s", ZSTD_getErrorName(remainingToFlush)); +                    CHECK (ZSTD_isError(remainingToFlush), "ZSTDMT_endStream error : %s", ZSTD_getErrorName(remainingToFlush));                      DISPLAYLEVEL(5, "endStream : remainingToFlush : %u \n", (U32)remainingToFlush);              }   } -            DISPLAYLEVEL(5, "Frame completed \n");              crcOrig = XXH64_digest(&xxhState);              cSize = outBuff.pos; +            DISPLAYLEVEL(5, "Frame completed : %u bytes \n", (U32)cSize);          }          /* multi - fragments decompression test */ @@ -972,8 +1048,10 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp                  size_t const dstBuffSize = MIN(dstBufferSize - totalGenSize, randomDstSize);                  inBuff.size = inBuff.pos + readCSrcSize;                  outBuff.size = inBuff.pos + dstBuffSize; +                DISPLAYLEVEL(5, "ZSTD_decompressStream input %u bytes \n", (U32)readCSrcSize);                  decompressionResult = ZSTD_decompressStream(zd, &outBuff, &inBuff);                  CHECK (ZSTD_isError(decompressionResult), "decompression error : %s", ZSTD_getErrorName(decompressionResult)); +                DISPLAYLEVEL(5, "inBuff.pos = %u \n", (U32)readCSrcSize);              }              CHECK (outBuff.pos != totalTestSize, "decompressed data : wrong size (%u != %u)", (U32)outBuff.pos, (U32)totalTestSize);              CHECK (inBuff.pos != cSize, "compressed data should be fully read (%u != %u)", (U32)inBuff.pos, (U32)cSize); @@ -1063,6 +1141,7 @@ int main(int argc, const char** argv)      int result=0;      int mainPause = 0;      int mtOnly = 0; +    int bigTests = 1;      const char* const programName = argv[0];      ZSTD_customMem const customMem = { allocFunction, freeFunction, NULL };      ZSTD_customMem const customNULL = { NULL, NULL, NULL }; @@ -1076,6 +1155,7 @@ int main(int argc, const char** argv)          if (argument[0]=='-') {              if (!strcmp(argument, "--mt")) { mtOnly=1; continue; } +            if (!strcmp(argument, "--no-big-tests")) { bigTests=0; continue; }              argument++;              while (*argument!=0) { @@ -1181,8 +1261,8 @@ int main(int argc, const char** argv)              result = basicUnitTests(0, ((double)proba) / 100, customMem);  /* use custom memory allocation functions */      }   } -    if (!result && !mtOnly) result = fuzzerTests(seed, nbTests, testNb, ((double)proba) / 100); -    if (!result) result = fuzzerTests_MT(seed, nbTests, testNb, ((double)proba) / 100); +    if (!result && !mtOnly) result = fuzzerTests(seed, nbTests, testNb, ((double)proba) / 100, bigTests); +    if (!result) result = fuzzerTests_MT(seed, nbTests, testNb, ((double)proba) / 100, bigTests);      if (mainPause) {          int unused; | 
