diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/.gitignore | 4 | ||||
-rw-r--r-- | tests/Makefile | 150 | ||||
-rw-r--r-- | tests/checkTag.c | 65 | ||||
-rw-r--r-- | tests/fullbench.c | 48 | ||||
-rw-r--r-- | tests/fuzz/zstd_helpers.c | 2 | ||||
-rw-r--r-- | tests/fuzzer.c | 560 | ||||
-rw-r--r-- | tests/legacy.c | 25 | ||||
-rw-r--r-- | tests/namespaceTest.c | 24 | ||||
-rw-r--r-- | tests/paramgrill.c | 12 | ||||
-rwxr-xr-x | tests/playTests.sh | 78 | ||||
-rw-r--r-- | tests/roundTripCrash.c | 2 | ||||
-rw-r--r-- | tests/zstreamtest.c | 258 |
12 files changed, 791 insertions, 437 deletions
diff --git a/tests/.gitignore b/tests/.gitignore index b16e26e3d4902..4911b2d62a568 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -23,6 +23,9 @@ decodecorpus pool poolTests invalidDictionaries +checkTag +zcat +zstdcat # Tmp test directory zstdtest @@ -52,6 +55,7 @@ tmp* *.gz result out +*.zstd # fuzzer afl diff --git a/tests/Makefile b/tests/Makefile index 853f4ee89b195..5b35ad406318d 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -21,7 +21,7 @@ ZSTDDIR = ../lib PRGDIR = ../programs PYTHON ?= python3 -TESTARTEFACT := versionsTest namespaceTest +TESTARTEFACT := versionsTest DEBUGLEVEL ?= 1 DEBUGFLAGS = -g -DZSTD_DEBUG=$(DEBUGLEVEL) @@ -44,6 +44,16 @@ ZSTD_FILES := $(ZSTDDECOMP_FILES) $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) ZBUFF_FILES := $(ZSTDDIR)/deprecated/*.c ZDICT_FILES := $(ZSTDDIR)/dictBuilder/*.c +ZSTD_F1 := $(wildcard $(ZSTD_FILES)) +ZSTD_OBJ1 := $(subst $(ZSTDDIR)/common/,zstdm_,$(ZSTD_F1)) +ZSTD_OBJ2 := $(subst $(ZSTDDIR)/compress/,zstdc_,$(ZSTD_OBJ1)) +ZSTD_OBJ3 := $(subst $(ZSTDDIR)/decompress/,zstdd_,$(ZSTD_OBJ2)) +ZSTD_OBJECTS := $(ZSTD_OBJ3:.c=.o) + +ZSTDMT_OBJ1 := $(subst $(ZSTDDIR)/common/,zstdmt_m_,$(ZSTD_F1)) +ZSTDMT_OBJ2 := $(subst $(ZSTDDIR)/compress/,zstdmt_c_,$(ZSTDMT_OBJ1)) +ZSTDMT_OBJ3 := $(subst $(ZSTDDIR)/decompress/,zstdmt_d_,$(ZSTDMT_OBJ2)) +ZSTDMT_OBJECTS := $(ZSTDMT_OBJ3:.c=.o) # Define *.exe as extension for Windows systems ifneq (,$(filter Windows%,$(OS))) @@ -63,14 +73,17 @@ FUZZERTEST ?= -T200s ZSTDRTTEST = --test-large-data DECODECORPUS_TESTTIME ?= -T30 -.PHONY: default all all32 allnothread dll clean test test32 test-all namespaceTest versionsTest +.PHONY: default all all32 allnothread dll clean test test32 test-all versionsTest default: fullbench + @echo $(ZSTDMT_OBJECTS) -all: fullbench fuzzer zstreamtest paramgrill datagen decodecorpus +all: fullbench fuzzer zstreamtest paramgrill datagen decodecorpus roundTripCrash all32: fullbench32 fuzzer32 zstreamtest32 +allnothread: MULTITHREAD_CPP= +allnothread: MULTITHREAD_LD= allnothread: fullbench fuzzer paramgrill datagen decodecorpus dll: fuzzer-dll zstreamtest-dll @@ -85,37 +98,71 @@ zstd-nolegacy: $(MAKE) -C $(PRGDIR) $@ MOREFLAGS+="$(DEBUGFLAGS)" gzstd: - $(MAKE) -C $(PRGDIR) zstd HAVE_ZLIB=1 MOREFLAGS="$(DEBUGFLAGS)" + $(MAKE) -C $(PRGDIR) zstd HAVE_ZLIB=1 MOREFLAGS+="$(DEBUGFLAGS)" + +.PHONY: zstd-dll +zstd-dll : + $(MAKE) -C $(ZSTDDIR) libzstd + +.PHONY: zstd-staticLib +zstd-staticLib : + $(MAKE) -C $(ZSTDDIR) libzstd.a + +zstdm_%.o : $(ZSTDDIR)/common/%.c + $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ + +zstdc_%.o : $(ZSTDDIR)/compress/%.c + $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ + +zstdd_%.o : $(ZSTDDIR)/decompress/%.c + $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ + +zstdmt%.o : CPPFLAGS += $(MULTITHREAD_CPP) + +zstdmt_m_%.o : $(ZSTDDIR)/common/%.c + $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ + +zstdmt_c_%.o : $(ZSTDDIR)/compress/%.c + $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ + +zstdmt_d_%.o : $(ZSTDDIR)/decompress/%.c + $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ fullbench32: CPPFLAGS += -m32 fullbench fullbench32 : CPPFLAGS += $(MULTITHREAD_CPP) fullbench fullbench32 : LDFLAGS += $(MULTITHREAD_LD) fullbench fullbench32 : DEBUGFLAGS = # turn off assert() for speed measurements -fullbench fullbench32 : $(ZSTD_FILES) $(PRGDIR)/datagen.c fullbench.c +fullbench fullbench32 : $(ZSTD_FILES) +fullbench fullbench32 : $(PRGDIR)/datagen.c fullbench.c $(CC) $(FLAGS) $^ -o $@$(EXT) -fullbench-lib: $(PRGDIR)/datagen.c fullbench.c - $(MAKE) -C $(ZSTDDIR) libzstd.a - $(CC) $(FLAGS) $^ -o $@$(EXT) $(ZSTDDIR)/libzstd.a +fullbench-lib : zstd-staticLib +fullbench-lib : $(PRGDIR)/datagen.c fullbench.c + $(CC) $(FLAGS) $(filter %.c,$^) -o $@$(EXT) $(ZSTDDIR)/libzstd.a +# note : broken : requires unavailable symbols +fullbench-dll : zstd-dll +fullbench-dll : LDFLAGS+= -L$(ZSTDDIR) -lzstd fullbench-dll: $(PRGDIR)/datagen.c fullbench.c - $(MAKE) -C $(ZSTDDIR) libzstd - $(CC) $(FLAGS) $^ -o $@$(EXT) -DZSTD_DLL_IMPORT=1 $(ZSTDDIR)/dll/libzstd.dll +# $(CC) $(FLAGS) $(filter %.c,$^) -o $@$(EXT) -DZSTD_DLL_IMPORT=1 $(ZSTDDIR)/dll/libzstd.dll + $(CC) $(FLAGS) $(filter %.c,$^) -o $@$(EXT) -fuzzer : CPPFLAGS += $(MULTITHREAD_CPP) -fuzzer : LDFLAGS += $(MULTITHREAD_LD) +fuzzer : CPPFLAGS += $(MULTITHREAD_CPP) +fuzzer : LDFLAGS += $(MULTITHREAD_LD) fuzzer32: CFLAGS += -m32 -fuzzer fuzzer32 : $(ZSTD_FILES) $(ZDICT_FILES) $(PRGDIR)/datagen.c fuzzer.c +fuzzer : $(ZSTDMT_OBJECTS) +fuzzer32: $(ZSTD_FILES) +fuzzer fuzzer32 : $(ZDICT_FILES) $(PRGDIR)/datagen.c fuzzer.c $(CC) $(FLAGS) $^ -o $@$(EXT) +fuzzer-dll : zstd-dll fuzzer-dll : LDFLAGS+= -L$(ZSTDDIR) -lzstd fuzzer-dll : $(ZSTDDIR)/common/xxhash.c $(PRGDIR)/datagen.c fuzzer.c - $(MAKE) -C $(ZSTDDIR) libzstd - $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@$(EXT) + $(CC) $(CPPFLAGS) $(CFLAGS) $(filter %.c,$^) $(LDFLAGS) -o $@$(EXT) zbufftest : CPPFLAGS += -I$(ZSTDDIR)/deprecated zbufftest : CFLAGS += -Wno-deprecated-declarations # required to silence deprecation warnings -zbufftest : $(ZSTD_FILES) $(ZBUFF_FILES) $(PRGDIR)/datagen.c zbufftest.c +zbufftest : $(ZSTD_OBJECTS) $(ZBUFF_FILES) $(PRGDIR)/datagen.c zbufftest.c $(CC) $(FLAGS) $^ -o $@$(EXT) zbufftest32 : CPPFLAGS += -I$(ZSTDDIR)/deprecated @@ -123,18 +170,22 @@ zbufftest32 : CFLAGS += -Wno-deprecated-declarations -m32 zbufftest32 : $(ZSTD_FILES) $(ZBUFF_FILES) $(PRGDIR)/datagen.c zbufftest.c $(CC) $(FLAGS) $^ -o $@$(EXT) +zbufftest-dll : zstd-dll zbufftest-dll : CPPFLAGS += -I$(ZSTDDIR)/deprecated zbufftest-dll : CFLAGS += -Wno-deprecated-declarations # required to silence deprecation warnings zbufftest-dll : LDFLAGS+= -L$(ZSTDDIR) -lzstd zbufftest-dll : $(ZSTDDIR)/common/xxhash.c $(PRGDIR)/datagen.c zbufftest.c - $(MAKE) -C $(ZSTDDIR) libzstd - $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@$(EXT) + $(CC) $(CPPFLAGS) $(CFLAGS) $(filter %.c,$^) $(LDFLAGS) -o $@$(EXT) -ZSTREAMFILES := $(ZSTD_FILES) $(ZDICT_FILES) $(PRGDIR)/datagen.c seqgen.c zstreamtest.c +ZSTREAM_LOCAL_FILES := $(PRGDIR)/datagen.c seqgen.c zstreamtest.c +ZSTREAM_PROPER_FILES := $(ZDICT_FILES) $(ZSTREAM_LOCAL_FILES) +ZSTREAMFILES := $(ZSTD_FILES) $(ZSTREAM_PROPER_FILES) zstreamtest32 : CFLAGS += -m32 zstreamtest zstreamtest32 : CPPFLAGS += $(MULTITHREAD_CPP) zstreamtest zstreamtest32 : LDFLAGS += $(MULTITHREAD_LD) -zstreamtest zstreamtest32 : $(ZSTREAMFILES) +zstreamtest : $(ZSTDMT_OBJECTS) $(ZSTREAM_PROPER_FILES) +zstreamtest32 : $(ZSTREAMFILES) +zstreamtest zstreamtest32 : $(CC) $(FLAGS) $^ -o $@$(EXT) zstreamtest_asan : CFLAGS += -fsanitize=address @@ -145,54 +196,53 @@ zstreamtest_tsan : CFLAGS += -fsanitize=thread zstreamtest_tsan : $(ZSTREAMFILES) $(CC) $(FLAGS) $(MULTITHREAD) $^ -o $@$(EXT) +zstreamtest-dll : zstd-dll zstreamtest-dll : LDFLAGS+= -L$(ZSTDDIR) -lzstd -zstreamtest-dll : $(ZSTDDIR)/common/xxhash.c $(PRGDIR)/datagen.c zstreamtest.c - $(MAKE) -C $(ZSTDDIR) libzstd - $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@$(EXT) +zstreamtest-dll : $(ZSTDDIR)/common/xxhash.c # xxh symbols not exposed from dll +zstreamtest-dll : $(ZSTREAM_LOCAL_FILES) + $(CC) $(CPPFLAGS) $(CFLAGS) $(filter %.c,$^) $(LDFLAGS) -o $@$(EXT) -paramgrill : DEBUGFLAGS = +paramgrill : DEBUGFLAGS = # turn off assert() for speed measurements paramgrill : $(ZSTD_FILES) $(PRGDIR)/datagen.c paramgrill.c - $(CC) $(FLAGS) $^ -lm -o $@$(EXT) + $(CC) $(FLAGS) $^ -lm -o $@$(EXT) datagen : $(PRGDIR)/datagen.c datagencli.c - $(CC) $(FLAGS) $^ -o $@$(EXT) + $(CC) $(FLAGS) $^ -o $@$(EXT) -roundTripCrash : $(ZSTD_FILES) roundTripCrash.c - $(CC) $(FLAGS) $(MULTITHREAD) $^ -o $@$(EXT) +roundTripCrash : $(ZSTD_OBJECTS) roundTripCrash.c + $(CC) $(FLAGS) $(MULTITHREAD) $^ -o $@$(EXT) -longmatch : $(ZSTD_FILES) longmatch.c - $(CC) $(FLAGS) $^ -o $@$(EXT) +longmatch : $(ZSTD_OBJECTS) longmatch.c + $(CC) $(FLAGS) $^ -o $@$(EXT) -invalidDictionaries : $(ZSTD_FILES) invalidDictionaries.c - $(CC) $(FLAGS) $^ -o $@$(EXT) +invalidDictionaries : $(ZSTD_OBJECTS) invalidDictionaries.c + $(CC) $(FLAGS) $^ -o $@$(EXT) -legacy : CFLAGS+= -DZSTD_LEGACY_SUPPORT=4 -legacy : CPPFLAGS+= -I$(ZSTDDIR)/legacy +legacy : CPPFLAGS += -I$(ZSTDDIR)/legacy -DZSTD_LEGACY_SUPPORT=4 legacy : $(ZSTD_FILES) $(wildcard $(ZSTDDIR)/legacy/*.c) legacy.c - $(CC) $(FLAGS) $^ -o $@$(EXT) + $(CC) $(FLAGS) $^ -o $@$(EXT) -decodecorpus : $(filter-out $(ZSTDDIR)/compress/zstd_compress.c, $(wildcard $(ZSTD_FILES))) $(ZDICT_FILES) decodecorpus.c - $(CC) $(FLAGS) $^ -o $@$(EXT) -lm +decodecorpus : $(filter-out zstdc_zstd_compress.o, $(ZSTD_OBJECTS)) $(ZDICT_FILES) decodecorpus.c + $(CC) $(FLAGS) $^ -o $@$(EXT) -lm -symbols : symbols.c - $(MAKE) -C $(ZSTDDIR) libzstd +symbols : symbols.c zstd-dll ifneq (,$(filter Windows%,$(OS))) cp $(ZSTDDIR)/dll/libzstd.dll . - $(CC) $(FLAGS) $^ -o $@$(EXT) -DZSTD_DLL_IMPORT=1 libzstd.dll + $(CC) $(FLAGS) $< -o $@$(EXT) -DZSTD_DLL_IMPORT=1 libzstd.dll else - $(CC) $(FLAGS) $^ -o $@$(EXT) -Wl,-rpath=$(ZSTDDIR) $(ZSTDDIR)/libzstd.so + $(CC) $(FLAGS) $< -o $@$(EXT) -Wl,-rpath=$(ZSTDDIR) $(ZSTDDIR)/libzstd.so # broken on Mac endif poolTests : poolTests.c $(ZSTDDIR)/common/pool.c $(ZSTDDIR)/common/threading.c $(ZSTDDIR)/common/zstd_common.c $(ZSTDDIR)/common/error_private.c $(CC) $(FLAGS) $(MULTITHREAD) $^ -o $@$(EXT) -namespaceTest: - if $(CC) namespaceTest.c ../lib/common/xxhash.c -o $@ ; then echo compilation should fail; exit 1 ; fi - $(RM) $@ - +.PHONY: versionsTest versionsTest: clean $(PYTHON) test-zstd-versions.py +checkTag: checkTag.c $(ZSTDDIR)/zstd.h + $(CC) $(FLAGS) $< -o $@$(EXT) + clean: $(MAKE) -C $(ZSTDDIR) clean @$(RM) -fR $(TESTARTEFACT) @@ -205,7 +255,7 @@ clean: zstreamtest$(EXT) zstreamtest32$(EXT) \ datagen$(EXT) paramgrill$(EXT) roundTripCrash$(EXT) longmatch$(EXT) \ symbols$(EXT) invalidDictionaries$(EXT) legacy$(EXT) poolTests$(EXT) \ - decodecorpus$(EXT) + decodecorpus$(EXT) checkTag$(EXT) @echo Cleaning completed @@ -247,15 +297,23 @@ ifneq (,$(filter $(shell uname),SunOS)) DIFF:=gdiff endif +.PHONY: list +list: + @$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' | xargs + +.PHONY: zstd-playTests zstd-playTests: datagen file $(ZSTD) ZSTD="$(QEMU_SYS) $(ZSTD)" ./playTests.sh $(ZSTDRTTEST) +.PHONY: shortest shortest: ZSTDRTTEST= shortest: test-zstd +.PHONY: fuzztest fuzztest: test-fuzzer test-zstream test-decodecorpus +.PHONY: test test: test-zstd test-fullbench test-fuzzer test-zstream test-invalidDictionaries test-legacy test-decodecorpus ifeq ($(QEMU_SYS),) test: test-pool diff --git a/tests/checkTag.c b/tests/checkTag.c new file mode 100644 index 0000000000000..fda3fd1f9df51 --- /dev/null +++ b/tests/checkTag.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* checkTag : validation tool for libzstd + * command : + * $ ./checkTag tag + * checkTag validates tags of following format : v[0-9].[0-9].[0-9]{any} + * The tag is then compared to zstd version number. + * They are compatible if first 3 digits are identical. + * Anything beyond that is free, and doesn't impact validation. + * Example : tag v1.8.1.2 is compatible with version 1.8.1 + * When tag and version are not compatible, program exits with error code 1. + * When they are compatible, it exists with a code 0. + * checkTag is intended to be used in automated testing environment. + */ + +#include <stdio.h> /* printf */ +#include <string.h> /* strlen, strncmp */ +#include "zstd.h" /* ZSTD_VERSION_STRING */ + + +/* validate() : + * @return 1 if tag is compatible, 0 if not. + */ +static int validate(const char* const tag) +{ + size_t const tagLength = strlen(tag); + size_t const verLength = strlen(ZSTD_VERSION_STRING); + + if (tagLength < 2) return 0; + if (tag[0] != 'v') return 0; + if (tagLength <= verLength) return 0; + + if (strncmp(ZSTD_VERSION_STRING, tag+1, verLength)) return 0; + + return 1; +} + +int main(int argc, const char** argv) +{ + const char* const exeName = argv[0]; + const char* const tag = argv[1]; + if (argc!=2) { + printf("incorrect usage : %s tag \n", exeName); + return 2; + } + + printf("Version : %s \n", ZSTD_VERSION_STRING); + printf("Tag : %s \n", tag); + + if (validate(tag)) { + printf("OK : tag is compatible with zstd version \n"); + return 0; + } + + printf("!! error : tag and versions are not compatible !! \n"); + return 1; +} diff --git a/tests/fullbench.c b/tests/fullbench.c index 2ec3ce5554e20..6abdd4da00fa2 100644 --- a/tests/fullbench.c +++ b/tests/fullbench.c @@ -15,6 +15,7 @@ #include "util.h" /* Compiler options, UTIL_GetFileSize */ #include <stdlib.h> /* malloc */ #include <stdio.h> /* fprintf, fopen, ftello64 */ +#include <assert.h> /* assert */ #include "mem.h" /* U32 */ #ifndef ZSTD_DLL_IMPORT @@ -181,7 +182,7 @@ static size_t local_ZSTD_compress_generic_T2_end(void* dst, size_t dstCapacity, ZSTD_inBuffer buffIn; (void)buff2; ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_compressionLevel, 1); - ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_nbThreads, 2); + ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_nbWorkers, 2); buffOut.dst = dst; buffOut.size = dstCapacity; buffOut.pos = 0; @@ -198,7 +199,7 @@ static size_t local_ZSTD_compress_generic_T2_continue(void* dst, size_t dstCapac ZSTD_inBuffer buffIn; (void)buff2; ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_compressionLevel, 1); - ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_nbThreads, 2); + ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_nbWorkers, 2); buffOut.dst = dst; buffOut.size = dstCapacity; buffOut.pos = 0; @@ -413,33 +414,48 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb) break; /* test functions */ - /* by convention, test functions can be added > 100 */ + /* convention: test functions have ID > 100 */ default : ; } - { size_t i; for (i=0; i<dstBuffSize; i++) dstBuff[i]=(BYTE)i; } /* warming up memory */ + /* warming up memory */ + { size_t i; for (i=0; i<dstBuffSize; i++) dstBuff[i]=(BYTE)i; } + /* benchmark loop */ { U32 loopNb; -# define TIME_SEC_MICROSEC (1*1000000ULL) /* 1 second */ - U64 const clockLoop = TIMELOOP_S * TIME_SEC_MICROSEC; + U32 nbRounds = (U32)((50 MB) / (srcSize+1)) + 1; /* initial conservative speed estimate */ +# define TIME_SEC_MICROSEC (1*1000000ULL) /* 1 second */ +# define TIME_SEC_NANOSEC (1*1000000000ULL) /* 1 second */ DISPLAY("%2i- %-30.30s : \r", benchNb, benchName); for (loopNb = 1; loopNb <= g_nbIterations; loopNb++) { UTIL_time_t clockStart; size_t benchResult=0; - U32 nbRounds; + U32 roundNb; - UTIL_sleepMilli(1); /* give processor time to other processes */ + UTIL_sleepMilli(5); /* give processor time to other processes */ UTIL_waitForNextTick(); clockStart = UTIL_getTime(); - for (nbRounds=0; UTIL_clockSpanMicro(clockStart) < clockLoop; nbRounds++) { + for (roundNb=0; roundNb < nbRounds; roundNb++) { benchResult = benchFunction(dstBuff, dstBuffSize, buff2, src, srcSize); - if (ZSTD_isError(benchResult)) { DISPLAY("ERROR ! %s() => %s !! \n", benchName, ZSTD_getErrorName(benchResult)); exit(1); } - } - { U64 const clockSpanMicro = UTIL_clockSpanMicro(clockStart); - double const averageTime = (double)clockSpanMicro / TIME_SEC_MICROSEC / nbRounds; - if (averageTime < bestTime) bestTime = averageTime; - DISPLAY("%2i- %-30.30s : %7.1f MB/s (%9u)\r", loopNb, benchName, (double)srcSize / (1 MB) / bestTime, (U32)benchResult); + if (ZSTD_isError(benchResult)) { + DISPLAY("ERROR ! %s() => %s !! \n", benchName, ZSTD_getErrorName(benchResult)); + exit(1); + } } + { U64 const clockSpanNano = UTIL_clockSpanNano(clockStart); + double const averageTime = (double)clockSpanNano / TIME_SEC_NANOSEC / nbRounds; + if (clockSpanNano > 0) { + if (averageTime < bestTime) bestTime = averageTime; + assert(bestTime > (1./2000000000)); + nbRounds = (U32)(1. / bestTime); /* aim for 1 sec */ + DISPLAY("%2i- %-30.30s : %7.1f MB/s (%9u)\r", + loopNb, benchName, + (double)srcSize / (1 MB) / bestTime, + (U32)benchResult); + } else { + assert(nbRounds < 40000000); /* avoid overflow */ + nbRounds *= 100; + } } } } DISPLAY("%2u\n", benchNb); @@ -573,7 +589,7 @@ int main(int argc, const char** argv) for(i=1; i<argc; i++) { const char* argument = argv[i]; - if(!argument) continue; /* Protection if argument empty */ + assert(argument != NULL); /* Commands (note : aggregated commands are allowed) */ if (argument[0]=='-') { diff --git a/tests/fuzz/zstd_helpers.c b/tests/fuzz/zstd_helpers.c index 602898479bc26..6fc38361b7adc 100644 --- a/tests/fuzz/zstd_helpers.c +++ b/tests/fuzz/zstd_helpers.c @@ -35,7 +35,7 @@ ZSTD_compressionParameters FUZZ_randomCParams(size_t srcSize, uint32_t *state) cParams.searchLength = FUZZ_rand32(state, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX); cParams.targetLength = FUZZ_rand32(state, ZSTD_TARGETLENGTH_MIN, - ZSTD_TARGETLENGTH_MAX); + 512); cParams.strategy = FUZZ_rand32(state, ZSTD_fast, ZSTD_btultra); return ZSTD_adjustCParams(cParams, srcSize, 0); } diff --git a/tests/fuzzer.c b/tests/fuzzer.c index 141bf65484c1e..e97b841e8535c 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -34,7 +34,7 @@ #include "zdict.h" /* ZDICT_trainFromBuffer */ #include "datagen.h" /* RDG_genBuffer */ #include "mem.h" -#define XXH_STATIC_LINKING_ONLY +#define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */ #include "xxhash.h" /* XXH64 */ #include "util.h" @@ -53,7 +53,7 @@ static const U32 nbTestsDefault = 30000; /*-************************************ * Display Macros **************************************/ -#define DISPLAY(...) fprintf(stdout, __VA_ARGS__) +#define DISPLAY(...) fprintf(stderr, __VA_ARGS__) #define DISPLAYLEVEL(l, ...) if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); } static U32 g_displayLevel = 2; @@ -65,11 +65,18 @@ static UTIL_time_t g_displayClock = UTIL_TIME_INITIALIZER; { g_displayClock = UTIL_getTime(); DISPLAY(__VA_ARGS__); \ if (g_displayLevel>=4) fflush(stderr); } } -/*-******************************************************* -* Fuzzer functions -*********************************************************/ + #undef MIN #undef MAX +void FUZ_bug976(void) +{ /* these constants shall not depend on MIN() macro */ + assert(ZSTD_HASHLOG_MAX < 31); + assert(ZSTD_CHAINLOG_MAX < 31); +} + +/*-******************************************************* +* Internal functions +*********************************************************/ #define MIN(a,b) ((a)<(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) @@ -219,7 +226,7 @@ static int FUZ_mallocTests(unsigned seed, double compressibility, unsigned part) ZSTD_outBuffer out = { outBuffer, outSize, 0 }; ZSTD_inBuffer in = { inBuffer, inSize, 0 }; CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_p_compressionLevel, (U32)compressionLevel) ); - CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_p_nbThreads, nbThreads) ); + CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_p_nbWorkers, nbThreads) ); while ( ZSTD_compress_generic(cctx, &out, &in, ZSTD_e_end) ) {} ZSTD_freeCCtx(cctx); DISPLAYLEVEL(3, "compress_generic,-T%u,end level %i : ", @@ -239,7 +246,7 @@ static int FUZ_mallocTests(unsigned seed, double compressibility, unsigned part) ZSTD_outBuffer out = { outBuffer, outSize, 0 }; ZSTD_inBuffer in = { inBuffer, inSize, 0 }; CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_p_compressionLevel, (U32)compressionLevel) ); - CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_p_nbThreads, nbThreads) ); + CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_p_nbWorkers, nbThreads) ); CHECK_Z( ZSTD_compress_generic(cctx, &out, &in, ZSTD_e_continue) ); while ( ZSTD_compress_generic(cctx, &out, &in, ZSTD_e_end) ) {} ZSTD_freeCCtx(cctx); @@ -286,91 +293,91 @@ static int basicUnitTests(U32 seed, double compressibility) RDG_genBuffer(CNBuffer, CNBuffSize, compressibility, 0., seed); /* Basic tests */ - DISPLAYLEVEL(4, "test%3i : ZSTD_getErrorName : ", testNb++); + DISPLAYLEVEL(3, "test%3i : ZSTD_getErrorName : ", testNb++); { const char* errorString = ZSTD_getErrorName(0); - DISPLAYLEVEL(4, "OK : %s \n", errorString); + DISPLAYLEVEL(3, "OK : %s \n", errorString); } - DISPLAYLEVEL(4, "test%3i : ZSTD_getErrorName with wrong value : ", testNb++); + DISPLAYLEVEL(3, "test%3i : ZSTD_getErrorName with wrong value : ", testNb++); { const char* errorString = ZSTD_getErrorName(499); - DISPLAYLEVEL(4, "OK : %s \n", errorString); + DISPLAYLEVEL(3, "OK : %s \n", errorString); } - DISPLAYLEVEL(4, "test%3i : compress %u bytes : ", testNb++, (U32)CNBuffSize); + DISPLAYLEVEL(3, "test%3i : compress %u bytes : ", testNb++, (U32)CNBuffSize); { ZSTD_CCtx* cctx = ZSTD_createCCtx(); if (cctx==NULL) goto _output_error; CHECKPLUS(r, ZSTD_compressCCtx(cctx, compressedBuffer, compressedBufferSize, CNBuffer, CNBuffSize, 1), cSize=r ); - DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); + DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); - DISPLAYLEVEL(4, "test%3i : size of cctx for level 1 : ", testNb++); + DISPLAYLEVEL(3, "test%3i : size of cctx for level 1 : ", testNb++); { size_t const cctxSize = ZSTD_sizeof_CCtx(cctx); - DISPLAYLEVEL(4, "%u bytes \n", (U32)cctxSize); + DISPLAYLEVEL(3, "%u bytes \n", (U32)cctxSize); } ZSTD_freeCCtx(cctx); } - DISPLAYLEVEL(4, "test%3i : ZSTD_getFrameContentSize test : ", testNb++); + DISPLAYLEVEL(3, "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(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : ZSTD_findDecompressedSize test : ", testNb++); + DISPLAYLEVEL(3, "test%3i : ZSTD_findDecompressedSize test : ", testNb++); { unsigned long long const rSize = ZSTD_findDecompressedSize(compressedBuffer, cSize); if (rSize != CNBuffSize) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : decompress %u bytes : ", testNb++, (U32)CNBuffSize); + DISPLAYLEVEL(3, "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(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : check decompressed result : ", testNb++); + DISPLAYLEVEL(3, "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"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : decompress with null dict : ", testNb++); + DISPLAYLEVEL(3, "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; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : decompress with null DDict : ", testNb++); + DISPLAYLEVEL(3, "test%3i : decompress with null DDict : ", testNb++); { size_t const r = ZSTD_decompress_usingDDict(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize, NULL); if (r != CNBuffSize) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : decompress with 1 missing byte : ", testNb++); + DISPLAYLEVEL(3, "test%3i : decompress with 1 missing byte : ", testNb++); { size_t const r = ZSTD_decompress(decodedBuffer, CNBuffSize, compressedBuffer, cSize-1); if (!ZSTD_isError(r)) goto _output_error; if (ZSTD_getErrorCode((size_t)r) != ZSTD_error_srcSize_wrong) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : decompress with 1 too much byte : ", testNb++); + DISPLAYLEVEL(3, "test%3i : decompress with 1 too much byte : ", testNb++); { size_t const r = ZSTD_decompress(decodedBuffer, CNBuffSize, compressedBuffer, cSize+1); if (!ZSTD_isError(r)) goto _output_error; if (ZSTD_getErrorCode(r) != ZSTD_error_srcSize_wrong) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%di : check CCtx size after compressing empty input : ", testNb++); + DISPLAYLEVEL(3, "test%3d : check CCtx size after compressing empty input : ", testNb++); { ZSTD_CCtx* cctx = ZSTD_createCCtx(); size_t const r = ZSTD_compressCCtx(cctx, compressedBuffer, compressedBufferSize, NULL, 0, 19); if (ZSTD_isError(r)) goto _output_error; if (ZSTD_sizeof_CCtx(cctx) > (1U << 20)) goto _output_error; ZSTD_freeCCtx(cctx); } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%di : re-use CCtx with expanding block size : ", testNb++); + DISPLAYLEVEL(3, "test%3d : re-use CCtx with expanding block size : ", testNb++); { ZSTD_CCtx* const cctx = ZSTD_createCCtx(); ZSTD_parameters const params = ZSTD_getParams(1, ZSTD_CONTENTSIZE_UNKNOWN, 0); assert(params.fParams.contentSizeFlag == 1); /* block size will be adapted if pledgedSrcSize is enabled */ @@ -385,11 +392,26 @@ static int basicUnitTests(U32 seed, double compressibility) } ZSTD_freeCCtx(cctx); } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); + + DISPLAYLEVEL(3, "test%3d : large window log smaller data : ", testNb++); + { ZSTD_CCtx* const cctx = ZSTD_createCCtx(); + ZSTD_parameters params = ZSTD_getParams(1, ZSTD_CONTENTSIZE_UNKNOWN, 0); + size_t const nbCompressions = (1U << 31) / CNBuffSize + 1; + size_t i; + params.fParams.contentSizeFlag = 0; + params.cParams.windowLog = ZSTD_WINDOWLOG_MAX; + for (i = 0; i < nbCompressions; ++i) { + CHECK_Z( ZSTD_compressBegin_advanced(cctx, NULL, 0, params, ZSTD_CONTENTSIZE_UNKNOWN) ); /* re-use same parameters */ + CHECK_Z( ZSTD_compressEnd(cctx, compressedBuffer, compressedBufferSize, CNBuffer, CNBuffSize) ); + } + ZSTD_freeCCtx(cctx); + } + DISPLAYLEVEL(3, "OK \n"); /* Static CCtx tests */ #define STATIC_CCTX_LEVEL 3 - DISPLAYLEVEL(4, "test%3i : create static CCtx for level %u :", testNb++, STATIC_CCTX_LEVEL); + DISPLAYLEVEL(3, "test%3i : create static CCtx for level %u :", testNb++, STATIC_CCTX_LEVEL); { size_t const staticCCtxSize = ZSTD_estimateCStreamSize(STATIC_CCTX_LEVEL); void* const staticCCtxBuffer = malloc(staticCCtxSize); size_t const staticDCtxSize = ZSTD_estimateDCtxSize(); @@ -404,57 +426,57 @@ static int basicUnitTests(U32 seed, double compressibility) { ZSTD_CCtx* staticCCtx = ZSTD_initStaticCCtx(staticCCtxBuffer, staticCCtxSize); ZSTD_DCtx* staticDCtx = ZSTD_initStaticDCtx(staticDCtxBuffer, staticDCtxSize); if ((staticCCtx==NULL) || (staticDCtx==NULL)) goto _output_error; - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : init CCtx for level %u : ", testNb++, STATIC_CCTX_LEVEL); + DISPLAYLEVEL(3, "test%3i : init CCtx for level %u : ", testNb++, STATIC_CCTX_LEVEL); { size_t const r = ZSTD_compressBegin(staticCCtx, STATIC_CCTX_LEVEL); if (ZSTD_isError(r)) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : simple compression test with static CCtx : ", testNb++); + DISPLAYLEVEL(3, "test%3i : simple compression test with static CCtx : ", testNb++); CHECKPLUS(r, ZSTD_compressCCtx(staticCCtx, compressedBuffer, compressedBufferSize, CNBuffer, CNBuffSize, STATIC_CCTX_LEVEL), cSize=r ); - DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", + DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); - DISPLAYLEVEL(4, "test%3i : simple decompression test with static DCtx : ", testNb++); + DISPLAYLEVEL(3, "test%3i : simple decompression test with static DCtx : ", testNb++); { size_t const r = ZSTD_decompressDCtx(staticDCtx, decodedBuffer, CNBuffSize, compressedBuffer, cSize); if (r != CNBuffSize) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : check decompressed result : ", testNb++); + DISPLAYLEVEL(3, "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"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : init CCtx for too large level (must fail) : ", testNb++); + DISPLAYLEVEL(3, "test%3i : init CCtx for too large level (must fail) : ", testNb++); { size_t const r = ZSTD_compressBegin(staticCCtx, ZSTD_maxCLevel()); if (!ZSTD_isError(r)) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : init CCtx for small level %u (should work again) : ", testNb++, 1); + DISPLAYLEVEL(3, "test%3i : init CCtx for small level %u (should work again) : ", testNb++, 1); { size_t const r = ZSTD_compressBegin(staticCCtx, 1); if (ZSTD_isError(r)) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : init CStream for small level %u : ", testNb++, 1); + DISPLAYLEVEL(3, "test%3i : init CStream for small level %u : ", testNb++, 1); { size_t const r = ZSTD_initCStream(staticCCtx, 1); if (ZSTD_isError(r)) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : init CStream with dictionary (should fail) : ", testNb++); + DISPLAYLEVEL(3, "test%3i : init CStream with dictionary (should fail) : ", testNb++); { size_t const r = ZSTD_initCStream_usingDict(staticCCtx, CNBuffer, 64 KB, 1); if (!ZSTD_isError(r)) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : init DStream (should fail) : ", testNb++); + DISPLAYLEVEL(3, "test%3i : init DStream (should fail) : ", testNb++); { size_t const r = ZSTD_initDStream(staticDCtx); if (ZSTD_isError(r)) goto _output_error; } { ZSTD_outBuffer output = { decodedBuffer, CNBuffSize, 0 }; @@ -462,53 +484,52 @@ static int basicUnitTests(U32 seed, double compressibility) size_t const r = ZSTD_decompressStream(staticDCtx, &output, &input); if (!ZSTD_isError(r)) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); } free(staticCCtxBuffer); free(staticDCtxBuffer); } - /* ZSTDMT simple MT compression test */ - DISPLAYLEVEL(4, "test%3i : create ZSTDMT CCtx : ", testNb++); + DISPLAYLEVEL(3, "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(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : compress %u bytes with 2 threads : ", testNb++, (U32)CNBuffSize); + DISPLAYLEVEL(3, "test%3i : compress %u bytes with 2 threads : ", testNb++, (U32)CNBuffSize); CHECKPLUS(r, ZSTDMT_compressCCtx(mtctx, compressedBuffer, compressedBufferSize, CNBuffer, CNBuffSize, 1), cSize=r ); - DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); + DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); - DISPLAYLEVEL(4, "test%3i : decompressed size test : ", testNb++); + DISPLAYLEVEL(3, "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(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : decompress %u bytes : ", testNb++, (U32)CNBuffSize); + DISPLAYLEVEL(3, "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(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : check decompressed result : ", testNb++); + DISPLAYLEVEL(3, "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"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : compress -T2 with checksum : ", testNb++); + DISPLAYLEVEL(3, "test%3i : compress -T2 with checksum : ", testNb++); { ZSTD_parameters params = ZSTD_getParams(1, CNBuffSize, 0); params.fParams.checksumFlag = 1; params.fParams.contentSizeFlag = 1; @@ -518,19 +539,19 @@ static int basicUnitTests(U32 seed, double compressibility) NULL, params, 3 /*overlapRLog*/), cSize=r ); } - DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); + DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); - DISPLAYLEVEL(4, "test%3i : decompress %u bytes : ", testNb++, (U32)CNBuffSize); + DISPLAYLEVEL(3, "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(3, "OK \n"); ZSTDMT_freeCCtx(mtctx); } /* Simple API multiframe test */ - DISPLAYLEVEL(4, "test%3i : compress multiple frames : ", testNb++); + DISPLAYLEVEL(3, "test%3i : compress multiple frames : ", testNb++); { size_t off = 0; int i; int const segs = 4; @@ -552,53 +573,53 @@ static int basicUnitTests(U32 seed, double compressibility) } cSize = off; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : get decompressed size of multiple frames : ", testNb++); + DISPLAYLEVEL(3, "test%3i : get decompressed size of multiple frames : ", testNb++); { unsigned long long const r = ZSTD_findDecompressedSize(compressedBuffer, cSize); if (r != CNBuffSize / 2) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : decompress multiple frames : ", testNb++); + DISPLAYLEVEL(3, "test%3i : decompress multiple frames : ", testNb++); { CHECK_V(r, ZSTD_decompress(decodedBuffer, CNBuffSize, compressedBuffer, cSize)); if (r != CNBuffSize / 2) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : check decompressed result : ", testNb++); + DISPLAYLEVEL(3, "test%3i : check decompressed result : ", testNb++); if (memcmp(decodedBuffer, CNBuffer, CNBuffSize / 2) != 0) goto _output_error; - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); /* Dictionary and CCtx Duplication tests */ { ZSTD_CCtx* const ctxOrig = ZSTD_createCCtx(); ZSTD_CCtx* const ctxDuplicated = ZSTD_createCCtx(); static const size_t dictSize = 551; - DISPLAYLEVEL(4, "test%3i : copy context too soon : ", testNb++); + DISPLAYLEVEL(3, "test%3i : copy context too soon : ", testNb++); { size_t const copyResult = ZSTD_copyCCtx(ctxDuplicated, ctxOrig, 0); if (!ZSTD_isError(copyResult)) goto _output_error; } /* error must be detected */ - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : load dictionary into context : ", testNb++); + DISPLAYLEVEL(3, "test%3i : load dictionary into context : ", testNb++); CHECK( ZSTD_compressBegin_usingDict(ctxOrig, CNBuffer, dictSize, 2) ); CHECK( ZSTD_copyCCtx(ctxDuplicated, ctxOrig, 0) ); /* Begin_usingDict implies unknown srcSize, so match that */ - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : compress with flat dictionary : ", testNb++); + DISPLAYLEVEL(3, "test%3i : compress with flat dictionary : ", testNb++); cSize = 0; CHECKPLUS(r, ZSTD_compressEnd(ctxOrig, compressedBuffer, compressedBufferSize, (const char*)CNBuffer + dictSize, CNBuffSize - dictSize), cSize += r); - DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); + DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); - DISPLAYLEVEL(4, "test%3i : frame built with flat dictionary should be decompressible : ", testNb++); + DISPLAYLEVEL(3, "test%3i : frame built with flat dictionary should be decompressible : ", testNb++); CHECKPLUS(r, ZSTD_decompress_usingDict(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize, CNBuffer, dictSize), if (r != CNBuffSize - dictSize) goto _output_error); - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : compress with duplicated context : ", testNb++); + DISPLAYLEVEL(3, "test%3i : compress with duplicated context : ", testNb++); { size_t const cSizeOrig = cSize; cSize = 0; CHECKPLUS(r, ZSTD_compressEnd(ctxDuplicated, compressedBuffer, compressedBufferSize, @@ -606,37 +627,37 @@ static int basicUnitTests(U32 seed, double compressibility) cSize += r); if (cSize != cSizeOrig) goto _output_error; /* should be identical ==> same size */ } - DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); + DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); - DISPLAYLEVEL(4, "test%3i : frame built with duplicated context should be decompressible : ", testNb++); + DISPLAYLEVEL(3, "test%3i : frame built with duplicated context should be decompressible : ", testNb++); CHECKPLUS(r, ZSTD_decompress_usingDict(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize, CNBuffer, dictSize), if (r != CNBuffSize - dictSize) goto _output_error); - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : decompress with DDict : ", testNb++); + DISPLAYLEVEL(3, "test%3i : decompress with DDict : ", testNb++); { ZSTD_DDict* const ddict = ZSTD_createDDict(CNBuffer, dictSize); size_t const r = ZSTD_decompress_usingDDict(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize, ddict); if (r != CNBuffSize - dictSize) goto _output_error; - DISPLAYLEVEL(4, "OK (size of DDict : %u) \n", (U32)ZSTD_sizeof_DDict(ddict)); + DISPLAYLEVEL(3, "OK (size of DDict : %u) \n", (U32)ZSTD_sizeof_DDict(ddict)); ZSTD_freeDDict(ddict); } - DISPLAYLEVEL(4, "test%3i : decompress with static DDict : ", testNb++); + DISPLAYLEVEL(3, "test%3i : decompress with static DDict : ", testNb++); { size_t const ddictBufferSize = ZSTD_estimateDDictSize(dictSize, ZSTD_dlm_byCopy); void* ddictBuffer = malloc(ddictBufferSize); if (ddictBuffer == NULL) goto _output_error; - { ZSTD_DDict* const ddict = ZSTD_initStaticDDict(ddictBuffer, ddictBufferSize, CNBuffer, dictSize, ZSTD_dlm_byCopy); + { const ZSTD_DDict* const ddict = ZSTD_initStaticDDict(ddictBuffer, ddictBufferSize, CNBuffer, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto); size_t const r = ZSTD_decompress_usingDDict(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize, ddict); if (r != CNBuffSize - dictSize) goto _output_error; } free(ddictBuffer); - DISPLAYLEVEL(4, "OK (size of static DDict : %u) \n", (U32)ddictBufferSize); + DISPLAYLEVEL(3, "OK (size of static DDict : %u) \n", (U32)ddictBufferSize); } - DISPLAYLEVEL(4, "test%3i : check content size on duplicated context : ", testNb++); + DISPLAYLEVEL(3, "test%3i : check content size on duplicated context : ", testNb++); { size_t const testSize = CNBuffSize / 3; { ZSTD_parameters p = ZSTD_getParams(2, testSize, dictSize); p.fParams.contentSizeFlag = 1; @@ -651,7 +672,7 @@ static int basicUnitTests(U32 seed, double compressibility) if (ZSTD_getFrameHeader(&zfh, compressedBuffer, cSize)) goto _output_error; if ((zfh.frameContentSize != testSize) && (zfh.frameContentSize != 0)) goto _output_error; } } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); ZSTD_freeCCtx(ctxOrig); ZSTD_freeCCtx(ctxDuplicated); @@ -659,12 +680,13 @@ static int basicUnitTests(U32 seed, double compressibility) /* Dictionary and dictBuilder tests */ { ZSTD_CCtx* const cctx = ZSTD_createCCtx(); - size_t dictSize = 16 KB; - void* dictBuffer = malloc(dictSize); + size_t const dictBufferCapacity = 16 KB; + void* dictBuffer = malloc(dictBufferCapacity); size_t const totalSampleSize = 1 MB; size_t const sampleUnitSize = 8 KB; U32 const nbSamples = (U32)(totalSampleSize / sampleUnitSize); size_t* const samplesSizes = (size_t*) malloc(nbSamples * sizeof(size_t)); + size_t dictSize; U32 dictID; if (dictBuffer==NULL || samplesSizes==NULL) { @@ -673,128 +695,142 @@ static int basicUnitTests(U32 seed, double compressibility) goto _output_error; } - DISPLAYLEVEL(4, "test%3i : dictBuilder : ", testNb++); + DISPLAYLEVEL(3, "test%3i : dictBuilder on cyclic data : ", testNb++); + assert(compressedBufferSize >= totalSampleSize); + { U32 u; for (u=0; u<totalSampleSize; u++) ((BYTE*)decodedBuffer)[u] = (BYTE)u; } { U32 u; for (u=0; u<nbSamples; u++) samplesSizes[u] = sampleUnitSize; } - dictSize = ZDICT_trainFromBuffer(dictBuffer, dictSize, + { size_t const sDictSize = ZDICT_trainFromBuffer(dictBuffer, dictBufferCapacity, + decodedBuffer, samplesSizes, nbSamples); + if (ZDICT_isError(sDictSize)) goto _output_error; + DISPLAYLEVEL(3, "OK, created dictionary of size %u \n", (U32)sDictSize); + } + + DISPLAYLEVEL(3, "test%3i : dictBuilder : ", testNb++); + { U32 u; for (u=0; u<nbSamples; u++) samplesSizes[u] = sampleUnitSize; } + dictSize = ZDICT_trainFromBuffer(dictBuffer, dictBufferCapacity, CNBuffer, samplesSizes, nbSamples); if (ZDICT_isError(dictSize)) goto _output_error; - DISPLAYLEVEL(4, "OK, created dictionary of size %u \n", (U32)dictSize); + DISPLAYLEVEL(3, "OK, created dictionary of size %u \n", (U32)dictSize); - DISPLAYLEVEL(4, "test%3i : check dictID : ", testNb++); + DISPLAYLEVEL(3, "test%3i : check dictID : ", testNb++); dictID = ZDICT_getDictID(dictBuffer, dictSize); if (dictID==0) goto _output_error; - DISPLAYLEVEL(4, "OK : %u \n", dictID); + DISPLAYLEVEL(3, "OK : %u \n", dictID); - DISPLAYLEVEL(4, "test%3i : compress with dictionary : ", testNb++); + DISPLAYLEVEL(3, "test%3i : compress with dictionary : ", testNb++); cSize = ZSTD_compress_usingDict(cctx, compressedBuffer, compressedBufferSize, CNBuffer, CNBuffSize, dictBuffer, dictSize, 4); if (ZSTD_isError(cSize)) goto _output_error; - DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); + DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); - DISPLAYLEVEL(4, "test%3i : retrieve dictID from dictionary : ", testNb++); + DISPLAYLEVEL(3, "test%3i : retrieve dictID from dictionary : ", testNb++); { U32 const did = ZSTD_getDictID_fromDict(dictBuffer, dictSize); if (did != dictID) goto _output_error; /* non-conformant (content-only) dictionary */ } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : retrieve dictID from frame : ", testNb++); + DISPLAYLEVEL(3, "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(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : frame built with dictionary should be decompressible : ", testNb++); + DISPLAYLEVEL(3, "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(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : estimate CDict size : ", testNb++); + DISPLAYLEVEL(3, "test%3i : estimate CDict size : ", testNb++); { ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize); size_t const estimatedSize = ZSTD_estimateCDictSize_advanced(dictSize, cParams, ZSTD_dlm_byRef); - DISPLAYLEVEL(4, "OK : %u \n", (U32)estimatedSize); + DISPLAYLEVEL(3, "OK : %u \n", (U32)estimatedSize); } - DISPLAYLEVEL(4, "test%3i : compress with CDict ", testNb++); + DISPLAYLEVEL(3, "test%3i : compress with CDict ", testNb++); { ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize); ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictSize, - ZSTD_dlm_byRef, ZSTD_dm_auto, + ZSTD_dlm_byRef, ZSTD_dct_auto, cParams, ZSTD_defaultCMem); - DISPLAYLEVEL(4, "(size : %u) : ", (U32)ZSTD_sizeof_CDict(cdict)); + DISPLAYLEVEL(3, "(size : %u) : ", (U32)ZSTD_sizeof_CDict(cdict)); cSize = ZSTD_compress_usingCDict(cctx, compressedBuffer, compressedBufferSize, 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(3, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); - DISPLAYLEVEL(4, "test%3i : retrieve dictID from frame : ", testNb++); + DISPLAYLEVEL(3, "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(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : frame built with dictionary should be decompressible : ", testNb++); + DISPLAYLEVEL(3, "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 : compress with static CDict : ", testNb++); - { ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize); - size_t const cdictSize = ZSTD_estimateCDictSize_advanced(dictSize, cParams, ZSTD_dlm_byCopy); - void* const cdictBuffer = malloc(cdictSize); - if (cdictBuffer==NULL) goto _output_error; - { ZSTD_CDict* const cdict = ZSTD_initStaticCDict(cdictBuffer, cdictSize, - dictBuffer, dictSize, - ZSTD_dlm_byCopy, ZSTD_dm_auto, - cParams); - if (cdict == NULL) { - DISPLAY("ZSTD_initStaticCDict failed "); - goto _output_error; - } - cSize = ZSTD_compress_usingCDict(cctx, - compressedBuffer, compressedBufferSize, - CNBuffer, CNBuffSize, cdict); - if (ZSTD_isError(cSize)) { - DISPLAY("ZSTD_compress_usingCDict failed "); - goto _output_error; - } } - free(cdictBuffer); - } - DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); + DISPLAYLEVEL(3, "OK \n"); + + DISPLAYLEVEL(3, "test%3i : compress with static CDict : ", testNb++); + { int const maxLevel = ZSTD_maxCLevel(); + int level; + for (level = 1; level <= maxLevel; ++level) { + ZSTD_compressionParameters const cParams = ZSTD_getCParams(level, CNBuffSize, dictSize); + size_t const cdictSize = ZSTD_estimateCDictSize_advanced(dictSize, cParams, ZSTD_dlm_byCopy); + void* const cdictBuffer = malloc(cdictSize); + if (cdictBuffer==NULL) goto _output_error; + { const ZSTD_CDict* const cdict = ZSTD_initStaticCDict( + cdictBuffer, cdictSize, + dictBuffer, dictSize, + ZSTD_dlm_byCopy, ZSTD_dct_auto, + cParams); + if (cdict == NULL) { + DISPLAY("ZSTD_initStaticCDict failed "); + goto _output_error; + } + cSize = ZSTD_compress_usingCDict(cctx, + compressedBuffer, compressedBufferSize, + CNBuffer, MIN(10 KB, CNBuffSize), cdict); + if (ZSTD_isError(cSize)) { + DISPLAY("ZSTD_compress_usingCDict failed "); + goto _output_error; + } } + free(cdictBuffer); + } } + DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); - DISPLAYLEVEL(4, "test%3i : ZSTD_compress_usingCDict_advanced, no contentSize, no dictID : ", testNb++); + DISPLAYLEVEL(3, "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_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, ZSTD_dm_auto, cParams, ZSTD_defaultCMem); + ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto, cParams, ZSTD_defaultCMem); cSize = ZSTD_compress_usingCDict_advanced(cctx, compressedBuffer, compressedBufferSize, 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(3, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); - DISPLAYLEVEL(4, "test%3i : try retrieving contentSize from frame : ", testNb++); + DISPLAYLEVEL(3, "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(3, "OK (unknown)\n"); - DISPLAYLEVEL(4, "test%3i : frame built without dictID should be decompressible : ", testNb++); + DISPLAYLEVEL(3, "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(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : ZSTD_compress_advanced, no dictID : ", testNb++); + DISPLAYLEVEL(3, "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, compressedBufferSize, @@ -802,62 +838,62 @@ static int basicUnitTests(U32 seed, double compressibility) dictBuffer, dictSize, p); if (ZSTD_isError(cSize)) goto _output_error; } - DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); + DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); - DISPLAYLEVEL(4, "test%3i : frame built without dictID should be decompressible : ", testNb++); + DISPLAYLEVEL(3, "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(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : dictionary containing only header should return error : ", testNb++); + DISPLAYLEVEL(3, "test%3i : dictionary containing only header should return error : ", testNb++); { const size_t ret = ZSTD_decompress_usingDict( dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize, "\x37\xa4\x30\xec\x11\x22\x33\x44", 8); if (ZSTD_getErrorCode(ret) != ZSTD_error_dictionary_corrupted) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : Building cdict w/ ZSTD_dm_fullDict on a good dictionary : ", testNb++); + DISPLAYLEVEL(3, "test%3i : Building cdict w/ ZSTD_dm_fullDict on a good dictionary : ", testNb++); { ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize); - ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, ZSTD_dm_fullDict, cParams, ZSTD_defaultCMem); + ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, ZSTD_dct_fullDict, cParams, ZSTD_defaultCMem); if (cdict==NULL) goto _output_error; ZSTD_freeCDict(cdict); } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : Building cdict w/ ZSTD_dm_fullDict on a rawContent (must fail) : ", testNb++); + DISPLAYLEVEL(3, "test%3i : Building cdict w/ ZSTD_dm_fullDict on a rawContent (must fail) : ", testNb++); { ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize); - ZSTD_CDict* const cdict = ZSTD_createCDict_advanced((const char*)dictBuffer+1, dictSize-1, ZSTD_dlm_byRef, ZSTD_dm_fullDict, cParams, ZSTD_defaultCMem); + ZSTD_CDict* const cdict = ZSTD_createCDict_advanced((const char*)dictBuffer+1, dictSize-1, ZSTD_dlm_byRef, ZSTD_dct_fullDict, cParams, ZSTD_defaultCMem); if (cdict!=NULL) goto _output_error; ZSTD_freeCDict(cdict); } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : Loading rawContent starting with dict header w/ ZSTD_dm_auto should fail : ", testNb++); + DISPLAYLEVEL(3, "test%3i : Loading rawContent starting with dict header w/ ZSTD_dm_auto should fail : ", testNb++); { size_t ret; MEM_writeLE32((char*)dictBuffer+2, ZSTD_MAGIC_DICTIONARY); ret = ZSTD_CCtx_loadDictionary_advanced( - cctx, (const char*)dictBuffer+2, dictSize-2, ZSTD_dlm_byRef, ZSTD_dm_auto); + cctx, (const char*)dictBuffer+2, dictSize-2, ZSTD_dlm_byRef, ZSTD_dct_auto); if (!ZSTD_isError(ret)) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : Loading rawContent starting with dict header w/ ZSTD_dm_rawContent should pass : ", testNb++); + DISPLAYLEVEL(3, "test%3i : Loading rawContent starting with dict header w/ ZSTD_dm_rawContent should pass : ", testNb++); { size_t ret; MEM_writeLE32((char*)dictBuffer+2, ZSTD_MAGIC_DICTIONARY); ret = ZSTD_CCtx_loadDictionary_advanced( - cctx, (const char*)dictBuffer+2, dictSize-2, ZSTD_dlm_byRef, ZSTD_dm_rawContent); + cctx, (const char*)dictBuffer+2, dictSize-2, ZSTD_dlm_byRef, ZSTD_dct_rawContent); if (ZSTD_isError(ret)) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : Dictionary with non-default repcodes : ", testNb++); + DISPLAYLEVEL(3, "test%3i : Dictionary with non-default repcodes : ", testNb++); { U32 u; for (u=0; u<nbSamples; u++) samplesSizes[u] = sampleUnitSize; } dictSize = ZDICT_trainFromBuffer(dictBuffer, dictSize, CNBuffer, samplesSizes, nbSamples); @@ -888,7 +924,7 @@ static int basicUnitTests(U32 seed, double compressibility) BYTE data[1024]; ZSTD_compressionParameters const cParams = ZSTD_getCParams(19, CNBuffSize, dictSize); ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictSize, - ZSTD_dlm_byRef, ZSTD_dm_auto, + ZSTD_dlm_byRef, ZSTD_dct_auto, cParams, ZSTD_defaultCMem); memset(data, 'x', sizeof(data)); cSize = ZSTD_compress_usingCDict(cctx, compressedBuffer, compressedBufferSize, @@ -899,7 +935,7 @@ static int basicUnitTests(U32 seed, double compressibility) if (ZSTD_isError(dSize)) { DISPLAYLEVEL(5, "Decompression error %s : ", ZSTD_getErrorName(dSize)); goto _output_error; } if (memcmp(data, decodedBuffer, sizeof(data))) { DISPLAYLEVEL(5, "Data corruption : "); goto _output_error; } } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); ZSTD_freeCCtx(cctx); free(dictBuffer); @@ -924,7 +960,7 @@ static int basicUnitTests(U32 seed, double compressibility) goto _output_error; } - DISPLAYLEVEL(4, "test%3i : ZDICT_trainFromBuffer_cover : ", testNb++); + DISPLAYLEVEL(3, "test%3i : ZDICT_trainFromBuffer_cover : ", testNb++); { U32 u; for (u=0; u<nbSamples; u++) samplesSizes[u] = sampleUnitSize; } memset(¶ms, 0, sizeof(params)); params.d = 1 + (FUZ_rand(&seed) % 16); @@ -933,26 +969,26 @@ static int basicUnitTests(U32 seed, double compressibility) CNBuffer, samplesSizes, nbSamples, params); if (ZDICT_isError(dictSize)) goto _output_error; - DISPLAYLEVEL(4, "OK, created dictionary of size %u \n", (U32)dictSize); + DISPLAYLEVEL(3, "OK, created dictionary of size %u \n", (U32)dictSize); - DISPLAYLEVEL(4, "test%3i : check dictID : ", testNb++); + DISPLAYLEVEL(3, "test%3i : check dictID : ", testNb++); dictID = ZDICT_getDictID(dictBuffer, dictSize); if (dictID==0) goto _output_error; - DISPLAYLEVEL(4, "OK : %u \n", dictID); + DISPLAYLEVEL(3, "OK : %u \n", dictID); - DISPLAYLEVEL(4, "test%3i : ZDICT_optimizeTrainFromBuffer_cover : ", testNb++); + DISPLAYLEVEL(3, "test%3i : ZDICT_optimizeTrainFromBuffer_cover : ", testNb++); memset(¶ms, 0, sizeof(params)); params.steps = 4; optDictSize = ZDICT_optimizeTrainFromBuffer_cover(dictBuffer, optDictSize, CNBuffer, samplesSizes, nbSamples / 4, ¶ms); if (ZDICT_isError(optDictSize)) goto _output_error; - DISPLAYLEVEL(4, "OK, created dictionary of size %u \n", (U32)optDictSize); + DISPLAYLEVEL(3, "OK, created dictionary of size %u \n", (U32)optDictSize); - DISPLAYLEVEL(4, "test%3i : check dictID : ", testNb++); + DISPLAYLEVEL(3, "test%3i : check dictID : ", testNb++); dictID = ZDICT_getDictID(dictBuffer, optDictSize); if (dictID==0) goto _output_error; - DISPLAYLEVEL(4, "OK : %u \n", dictID); + DISPLAYLEVEL(3, "OK : %u \n", dictID); ZSTD_freeCCtx(cctx); free(dictBuffer); @@ -960,20 +996,20 @@ static int basicUnitTests(U32 seed, double compressibility) } /* Decompression defense tests */ - DISPLAYLEVEL(4, "test%3i : Check input length for magic number : ", testNb++); + DISPLAYLEVEL(3, "test%3i : Check input length for magic number : ", testNb++); { size_t const r = ZSTD_decompress(decodedBuffer, CNBuffSize, CNBuffer, 3); /* too small input */ if (!ZSTD_isError(r)) goto _output_error; if (ZSTD_getErrorCode(r) != ZSTD_error_srcSize_wrong) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : Check magic Number : ", testNb++); + DISPLAYLEVEL(3, "test%3i : Check magic Number : ", testNb++); ((char*)(CNBuffer))[0] = 1; { size_t const r = ZSTD_decompress(decodedBuffer, CNBuffSize, CNBuffer, 4); if (!ZSTD_isError(r)) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); /* content size verification test */ - DISPLAYLEVEL(4, "test%3i : Content size verification : ", testNb++); + DISPLAYLEVEL(3, "test%3i : Content size verification : ", testNb++); { ZSTD_CCtx* const cctx = ZSTD_createCCtx(); size_t const srcSize = 5000; size_t const wrongSrcSize = (srcSize + 1000); @@ -983,17 +1019,56 @@ static int basicUnitTests(U32 seed, double compressibility) { 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)); + DISPLAYLEVEL(3, "OK : %s \n", ZSTD_getErrorName(result)); } ZSTD_freeCCtx(cctx); } + /* parameters order test */ + { size_t const inputSize = CNBuffSize / 2; + U64 xxh64; + + { ZSTD_CCtx* cctx = ZSTD_createCCtx(); + DISPLAYLEVEL(3, "test%3i : parameters in order : ", testNb++); + CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_p_compressionLevel, 2) ); + CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_p_enableLongDistanceMatching, 1) ); + CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_p_windowLog, 18) ); + { ZSTD_inBuffer in = { CNBuffer, inputSize, 0 }; + ZSTD_outBuffer out = { compressedBuffer, ZSTD_compressBound(inputSize), 0 }; + size_t const result = ZSTD_compress_generic(cctx, &out, &in, ZSTD_e_end); + if (result != 0) goto _output_error; + if (in.pos != in.size) goto _output_error; + cSize = out.pos; + xxh64 = XXH64(out.dst, out.pos, 0); + } + DISPLAYLEVEL(3, "OK (compress : %u -> %u bytes)\n", (U32)inputSize, (U32)cSize); + ZSTD_freeCCtx(cctx); + } + + { ZSTD_CCtx* cctx = ZSTD_createCCtx(); + DISPLAYLEVEL(3, "test%3i : parameters disordered : ", testNb++); + CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_p_windowLog, 18) ); + CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_p_enableLongDistanceMatching, 1) ); + CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_p_compressionLevel, 2) ); + { ZSTD_inBuffer in = { CNBuffer, inputSize, 0 }; + ZSTD_outBuffer out = { compressedBuffer, ZSTD_compressBound(inputSize), 0 }; + size_t const result = ZSTD_compress_generic(cctx, &out, &in, ZSTD_e_end); + if (result != 0) goto _output_error; + if (in.pos != in.size) goto _output_error; + if (out.pos != cSize) goto _output_error; /* must result in same compressed result, hence same size */ + if (XXH64(out.dst, out.pos, 0) != xxh64) goto _output_error; /* must result in exactly same content, hence same hash */ + DISPLAYLEVEL(3, "OK (compress : %u -> %u bytes)\n", (U32)inputSize, (U32)out.pos); + } + ZSTD_freeCCtx(cctx); + } + } + /* custom formats tests */ { ZSTD_CCtx* const cctx = ZSTD_createCCtx(); size_t const inputSize = CNBuffSize / 2; /* won't cause pb with small dict size */ /* basic block compression */ - DISPLAYLEVEL(4, "test%3i : magic-less format test : ", testNb++); + DISPLAYLEVEL(3, "test%3i : magic-less format test : ", testNb++); CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_p_format, ZSTD_f_zstd1_magicless) ); { ZSTD_inBuffer in = { CNBuffer, inputSize, 0 }; ZSTD_outBuffer out = { compressedBuffer, ZSTD_compressBound(inputSize), 0 }; @@ -1002,15 +1077,15 @@ static int basicUnitTests(U32 seed, double compressibility) if (in.pos != in.size) goto _output_error; cSize = out.pos; } - DISPLAYLEVEL(4, "OK (compress : %u -> %u bytes)\n", (U32)inputSize, (U32)cSize); + DISPLAYLEVEL(3, "OK (compress : %u -> %u bytes)\n", (U32)inputSize, (U32)cSize); - DISPLAYLEVEL(4, "test%3i : decompress normally (should fail) : ", testNb++); + DISPLAYLEVEL(3, "test%3i : decompress normally (should fail) : ", testNb++); { size_t const decodeResult = ZSTD_decompressDCtx(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize); if (ZSTD_getErrorCode(decodeResult) != ZSTD_error_prefix_unknown) goto _output_error; - DISPLAYLEVEL(4, "OK : %s \n", ZSTD_getErrorName(decodeResult)); + DISPLAYLEVEL(3, "OK : %s \n", ZSTD_getErrorName(decodeResult)); } - DISPLAYLEVEL(4, "test%3i : decompress with magic-less instruction : ", testNb++); + DISPLAYLEVEL(3, "test%3i : decompress with magic-less instruction : ", testNb++); ZSTD_DCtx_reset(dctx); CHECK( ZSTD_DCtx_setFormat(dctx, ZSTD_f_zstd1_magicless) ); { ZSTD_inBuffer in = { compressedBuffer, cSize, 0 }; @@ -1019,7 +1094,7 @@ static int basicUnitTests(U32 seed, double compressibility) if (result != 0) goto _output_error; if (in.pos != in.size) goto _output_error; if (out.pos != inputSize) goto _output_error; - DISPLAYLEVEL(4, "OK : regenerated %u bytes \n", (U32)out.pos); + DISPLAYLEVEL(3, "OK : regenerated %u bytes \n", (U32)out.pos); } ZSTD_freeCCtx(cctx); @@ -1032,21 +1107,21 @@ static int basicUnitTests(U32 seed, double compressibility) size_t cSize2; /* basic block compression */ - DISPLAYLEVEL(4, "test%3i : Block compression test : ", testNb++); + DISPLAYLEVEL(3, "test%3i : Block compression test : ", testNb++); CHECK( ZSTD_compressBegin(cctx, 5) ); CHECK( ZSTD_getBlockSize(cctx) >= blockSize); cSize = ZSTD_compressBlock(cctx, compressedBuffer, ZSTD_compressBound(blockSize), CNBuffer, blockSize); if (ZSTD_isError(cSize)) goto _output_error; - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : Block decompression test : ", testNb++); + DISPLAYLEVEL(3, "test%3i : Block decompression test : ", testNb++); CHECK( ZSTD_decompressBegin(dctx) ); { CHECK_V(r, ZSTD_decompressBlock(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize) ); if (r != blockSize) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); /* dictionary block compression */ - DISPLAYLEVEL(4, "test%3i : Dictionary Block compression test : ", testNb++); + DISPLAYLEVEL(3, "test%3i : Dictionary Block compression test : ", testNb++); CHECK( ZSTD_compressBegin_usingDict(cctx, CNBuffer, dictSize, 5) ); cSize = ZSTD_compressBlock(cctx, compressedBuffer, ZSTD_compressBound(blockSize), (char*)CNBuffer+dictSize, blockSize); if (ZSTD_isError(cSize)) goto _output_error; @@ -1056,16 +1131,16 @@ static int basicUnitTests(U32 seed, double compressibility) cSize2 = ZSTD_compressBlock(cctx, (char*)compressedBuffer+cSize+blockSize, ZSTD_compressBound(blockSize), (char*)CNBuffer+dictSize+2*blockSize, blockSize); if (ZSTD_isError(cSize2)) goto _output_error; - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : Dictionary Block decompression test : ", testNb++); + DISPLAYLEVEL(3, "test%3i : Dictionary Block decompression test : ", testNb++); CHECK( ZSTD_decompressBegin_usingDict(dctx, CNBuffer, dictSize) ); { CHECK_V( r, ZSTD_decompressBlock(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize) ); if (r != blockSize) goto _output_error; } ZSTD_insertBlock(dctx, (char*)decodedBuffer+blockSize, blockSize); /* insert non-compressed block into dctx history */ { CHECK_V( r, ZSTD_decompressBlock(dctx, (char*)decodedBuffer+2*blockSize, CNBuffSize, (char*)compressedBuffer+cSize+blockSize, cSize2) ); if (r != blockSize) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); ZSTD_freeCCtx(cctx); } @@ -1073,7 +1148,7 @@ static int basicUnitTests(U32 seed, double compressibility) /* long rle test */ { size_t sampleSize = 0; - DISPLAYLEVEL(4, "test%3i : Long RLE test : ", testNb++); + DISPLAYLEVEL(3, "test%3i : Long RLE test : ", testNb++); RDG_genBuffer(CNBuffer, sampleSize, compressibility, 0., seed+1); memset((char*)CNBuffer+sampleSize, 'B', 256 KB - 1); sampleSize += 256 KB - 1; @@ -1083,21 +1158,21 @@ static int basicUnitTests(U32 seed, double compressibility) if (ZSTD_isError(cSize)) goto _output_error; { CHECK_V(regenSize, ZSTD_decompress(decodedBuffer, sampleSize, compressedBuffer, cSize)); if (regenSize!=sampleSize) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); } /* All zeroes test (test bug #137) */ #define ZEROESLENGTH 100 - DISPLAYLEVEL(4, "test%3i : compress %u zeroes : ", testNb++, ZEROESLENGTH); + DISPLAYLEVEL(3, "test%3i : compress %u zeroes : ", testNb++, ZEROESLENGTH); memset(CNBuffer, 0, ZEROESLENGTH); { CHECK_V(r, ZSTD_compress(compressedBuffer, ZSTD_compressBound(ZEROESLENGTH), CNBuffer, ZEROESLENGTH, 1) ); cSize = r; } - DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/ZEROESLENGTH*100); + DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/ZEROESLENGTH*100); - DISPLAYLEVEL(4, "test%3i : decompress %u zeroes : ", testNb++, ZEROESLENGTH); + DISPLAYLEVEL(3, "test%3i : decompress %u zeroes : ", testNb++, ZEROESLENGTH); { CHECK_V(r, ZSTD_decompress(decodedBuffer, ZEROESLENGTH, compressedBuffer, cSize) ); if (r != ZEROESLENGTH) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); /* nbSeq limit test */ #define _3BYTESTESTLENGTH 131000 @@ -1124,18 +1199,18 @@ static int basicUnitTests(U32 seed, double compressibility) ((BYTE*)CNBuffer)[i+1] = _3BytesSeqs[id][1]; ((BYTE*)CNBuffer)[i+2] = _3BytesSeqs[id][2]; } } } - DISPLAYLEVEL(4, "test%3i : compress lots 3-bytes sequences : ", testNb++); + DISPLAYLEVEL(3, "test%3i : compress lots 3-bytes sequences : ", testNb++); { CHECK_V(r, ZSTD_compress(compressedBuffer, ZSTD_compressBound(_3BYTESTESTLENGTH), CNBuffer, _3BYTESTESTLENGTH, 19) ); cSize = r; } - DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/_3BYTESTESTLENGTH*100); + DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/_3BYTESTESTLENGTH*100); - DISPLAYLEVEL(4, "test%3i : decompress lots 3-bytes sequence : ", testNb++); + DISPLAYLEVEL(3, "test%3i : decompress lots 3-bytes sequence : ", testNb++); { CHECK_V(r, ZSTD_decompress(decodedBuffer, _3BYTESTESTLENGTH, compressedBuffer, cSize) ); if (r != _3BYTESTESTLENGTH) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); - DISPLAYLEVEL(4, "test%3i : incompressible data and ill suited dictionary : ", testNb++); + DISPLAYLEVEL(3, "test%3i : incompressible data and ill suited dictionary : ", testNb++); RDG_genBuffer(CNBuffer, CNBuffSize, 0.0, 0.1, seed); { /* Train a dictionary on low characters */ size_t dictSize = 16 KB; @@ -1168,25 +1243,48 @@ static int basicUnitTests(U32 seed, double compressibility) free(dictBuffer); free(samplesSizes); } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); /* findFrameCompressedSize on skippable frames */ - DISPLAYLEVEL(4, "test%3i : frame compressed size of skippable frame : ", testNb++); + DISPLAYLEVEL(3, "test%3i : frame compressed size of skippable frame : ", testNb++); { const char* frame = "\x50\x2a\x4d\x18\x05\x0\x0\0abcde"; size_t const frameSrcSize = 13; if (ZSTD_findFrameCompressedSize(frame, frameSrcSize) != frameSrcSize) goto _output_error; } - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); /* error string tests */ - DISPLAYLEVEL(4, "test%3i : testing ZSTD error code strings : ", testNb++); + DISPLAYLEVEL(3, "test%3i : testing ZSTD error code strings : ", testNb++); if (strcmp("No error detected", ZSTD_getErrorName((ZSTD_ErrorCode)(0-ZSTD_error_no_error))) != 0) goto _output_error; if (strcmp("No error detected", ZSTD_getErrorString(ZSTD_error_no_error)) != 0) goto _output_error; if (strcmp("Unspecified error code", ZSTD_getErrorString((ZSTD_ErrorCode)(0-ZSTD_error_GENERIC))) != 0) goto _output_error; if (strcmp("Error (generic)", ZSTD_getErrorName((size_t)0-ZSTD_error_GENERIC)) != 0) goto _output_error; if (strcmp("Error (generic)", ZSTD_getErrorString(ZSTD_error_GENERIC)) != 0) goto _output_error; if (strcmp("No error detected", ZSTD_getErrorName(ZSTD_error_GENERIC)) != 0) goto _output_error; - DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(3, "OK \n"); + + DISPLAYLEVEL(3, "test%3i : testing ZSTD dictionary sizes : ", testNb++); + RDG_genBuffer(CNBuffer, CNBuffSize, compressibility, 0., seed); + { + size_t const size = MIN(128 KB, CNBuffSize); + ZSTD_CCtx* const cctx = ZSTD_createCCtx(); + ZSTD_CDict* const lgCDict = ZSTD_createCDict(CNBuffer, size, 1); + ZSTD_CDict* const smCDict = ZSTD_createCDict(CNBuffer, 1 KB, 1); + ZSTD_frameHeader lgHeader; + ZSTD_frameHeader smHeader; + + CHECK_Z(ZSTD_compress_usingCDict(cctx, compressedBuffer, compressedBufferSize, CNBuffer, size, lgCDict)); + CHECK_Z(ZSTD_getFrameHeader(&lgHeader, compressedBuffer, compressedBufferSize)); + CHECK_Z(ZSTD_compress_usingCDict(cctx, compressedBuffer, compressedBufferSize, CNBuffer, size, smCDict)); + CHECK_Z(ZSTD_getFrameHeader(&smHeader, compressedBuffer, compressedBufferSize)); + + if (lgHeader.windowSize != smHeader.windowSize) goto _output_error; + + ZSTD_freeCDict(smCDict); + ZSTD_freeCDict(lgCDict); + ZSTD_freeCCtx(cctx); + } + DISPLAYLEVEL(3, "OK \n"); _end: free(CNBuffer); @@ -1338,10 +1436,14 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD crcOrig = XXH64(sampleBuffer, sampleSize, 0); /* compression tests */ - { unsigned const cLevel = + { int const cLevelPositive = ( FUZ_rand(&lseed) % (ZSTD_maxCLevel() - (FUZ_highbit32((U32)sampleSize) / cLevelLimiter)) ) - + 1; + + 1; + int const cLevel = ((FUZ_rand(&lseed) & 15) == 3) ? + - (int)((FUZ_rand(&lseed) & 7) + 1) : /* test negative cLevel */ + cLevelPositive; + DISPLAYLEVEL(5, "fuzzer t%u: Simple compression test (level %i) \n", testNb, cLevel); cSize = ZSTD_compressCCtx(ctx, cBuffer, cBufferSize, sampleBuffer, sampleSize, cLevel); CHECK(ZSTD_isError(cSize), "ZSTD_compressCCtx failed : %s", ZSTD_getErrorName(cSize)); @@ -1369,6 +1471,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD } /* successful decompression test */ + DISPLAYLEVEL(5, "fuzzer t%u: simple decompression test \n", testNb); { size_t const margin = (FUZ_rand(&lseed) & 1) ? 0 : (FUZ_rand(&lseed) & 31) + 1; size_t const dSize = ZSTD_decompress(dstBuffer, sampleSize + margin, cBuffer, cSize); CHECK(dSize != sampleSize, "ZSTD_decompress failed (%s) (srcSize : %u ; cSize : %u)", ZSTD_getErrorName(dSize), (U32)sampleSize, (U32)cSize); @@ -1379,6 +1482,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD free(sampleBuffer); /* no longer useful after this point */ /* truncated src decompression test */ + DISPLAYLEVEL(5, "fuzzer t%u: decompression of truncated source \n", testNb); { size_t const missing = (FUZ_rand(&lseed) % (cSize-2)) + 1; /* no problem, as cSize > 4 (frameHeaderSizer) */ size_t const tooSmallSize = cSize - missing; void* cBufferTooSmall = malloc(tooSmallSize); /* valgrind will catch read overflows */ @@ -1390,6 +1494,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD } /* too small dst decompression test */ + DISPLAYLEVEL(5, "fuzzer t%u: decompress into too small dst buffer \n", testNb); if (sampleSize > 3) { size_t const missing = (FUZ_rand(&lseed) % (sampleSize-2)) + 1; /* no problem, as cSize > 4 (frameHeaderSizer) */ size_t const tooSmallSize = sampleSize - missing; @@ -1412,7 +1517,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD size_t const skipLength = FUZ_rand(&lseed) & mask; pos += skipLength; } - if (pos <= cSize) break; + if (pos >= cSize) break; /* add noise */ { U32 const nbBitsCodes = FUZ_rand(&lseed) % maxNbBits; U32 const nbBits = nbBitsCodes ? nbBitsCodes-1 : 0; @@ -1425,6 +1530,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD } } } /* decompress noisy source */ + DISPLAYLEVEL(5, "fuzzer t%u: decompress noisy source \n", testNb); { U32 const endMark = 0xA9B1C3D6; memcpy(dstBuffer+sampleSize, &endMark, 4); { size_t const decompressResult = ZSTD_decompress(dstBuffer, sampleSize, cBuffer, cSize); @@ -1436,8 +1542,8 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD CHECK(endMark!=endCheck, "ZSTD_decompress on noisy src : dst buffer overflow"); } } } /* noisy src decompression test */ - /*===== Streaming compression test, scattered segments and dictionary =====*/ - + /*===== Bufferless streaming compression test, scattered segments and dictionary =====*/ + DISPLAYLEVEL(5, "fuzzer t%u: Bufferless streaming compression test \n", testNb); { U32 const testLog = FUZ_rand(&lseed) % maxSrcLog; U32 const dictLog = FUZ_rand(&lseed) % maxSrcLog; int const cLevel = (FUZ_rand(&lseed) % @@ -1450,10 +1556,13 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD dictSize = FUZ_rLogLength(&lseed, dictLog); /* needed also for decompression */ dict = srcBuffer + (FUZ_rand(&lseed) % (srcBufferSize - dictSize)); + DISPLAYLEVEL(6, "fuzzer t%u: Compressing up to <=%u bytes at level %i with dictionary size %u \n", + testNb, (U32)maxTestSize, cLevel, (U32)dictSize); + if (FUZ_rand(&lseed) & 0xF) { CHECK_Z ( ZSTD_compressBegin_usingDict(refCtx, dict, dictSize, cLevel) ); } else { - ZSTD_compressionParameters const cPar = ZSTD_getCParams(cLevel, 0, dictSize); + ZSTD_compressionParameters const cPar = ZSTD_getCParams(cLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize); 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 */ @@ -1491,6 +1600,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD } /* streaming decompression test */ + DISPLAYLEVEL(5, "fuzzer t%u: Bufferless streaming decompression test \n", testNb); /* ensure memory requirement is good enough (should always be true) */ { ZSTD_frameHeader zfh; CHECK( ZSTD_getFrameHeader(&zfh, cBuffer, ZSTD_frameHeaderSize_max), @@ -1633,7 +1743,7 @@ int main(int argc, const char** argv) case 'v': argument++; - g_displayLevel = 4; + g_displayLevel++; break; case 'q': diff --git a/tests/legacy.c b/tests/legacy.c index 46a8206c4422e..847e1d25e96b7 100644 --- a/tests/legacy.c +++ b/tests/legacy.c @@ -94,21 +94,19 @@ int testStreamingAPI(void) if (needsInit) { size_t const ret = ZSTD_initDStream(stream); if (ZSTD_isError(ret)) { - DISPLAY("ERROR: %s\n", ZSTD_getErrorName(ret)); + DISPLAY("ERROR: ZSTD_initDStream: %s\n", ZSTD_getErrorName(ret)); return 1; - } - } - { - size_t const ret = ZSTD_decompressStream(stream, &output, &input); + } } + + { size_t const ret = ZSTD_decompressStream(stream, &output, &input); if (ZSTD_isError(ret)) { - DISPLAY("ERROR: %s\n", ZSTD_getErrorName(ret)); + DISPLAY("ERROR: ZSTD_decompressStream: %s\n", ZSTD_getErrorName(ret)); return 1; } if (ret == 0) { needsInit = 1; - } - } + } } if (memcmp(outBuff, EXPECTED + outputPos, output.pos) != 0) { DISPLAY("ERROR: Wrong decoded output produced\n"); @@ -128,15 +126,12 @@ int testStreamingAPI(void) int main(void) { - int ret; - - ret = testSimpleAPI(); - if (ret) return ret; - ret = testStreamingAPI(); - if (ret) return ret; + { int const ret = testSimpleAPI(); + if (ret) return ret; } + { int const ret = testStreamingAPI(); + if (ret) return ret; } DISPLAY("OK\n"); - return 0; } diff --git a/tests/namespaceTest.c b/tests/namespaceTest.c deleted file mode 100644 index 5b7095f67c80a..0000000000000 --- a/tests/namespaceTest.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under both the BSD-style license (found in the - * LICENSE file in the root directory of this source tree) and the GPLv2 (found - * in the COPYING file in the root directory of this source tree). - * You may select, at your option, one of the above-listed licenses. - */ - - - -#include <stddef.h> /* size_t */ -#include <string.h> /* strlen */ - -/* symbol definition */ -extern unsigned XXH32(const void* src, size_t srcSize, unsigned seed); - -int main(int argc, const char** argv) -{ - const char* exename = argv[0]; - unsigned result = XXH32(exename, strlen(exename), argc); - return !result; -} diff --git a/tests/paramgrill.c b/tests/paramgrill.c index ae14aa0748194..13b102b2d042d 100644 --- a/tests/paramgrill.c +++ b/tests/paramgrill.c @@ -547,12 +547,12 @@ static ZSTD_compressionParameters randomParams(void) U32 validated = 0; while (!validated) { /* totally random entry */ - p.chainLog = FUZ_rand(&g_rand) % (ZSTD_CHAINLOG_MAX+1 - ZSTD_CHAINLOG_MIN) + ZSTD_CHAINLOG_MIN; - p.hashLog = FUZ_rand(&g_rand) % (ZSTD_HASHLOG_MAX+1 - ZSTD_HASHLOG_MIN) + ZSTD_HASHLOG_MIN; - p.searchLog = FUZ_rand(&g_rand) % (ZSTD_SEARCHLOG_MAX+1 - ZSTD_SEARCHLOG_MIN) + ZSTD_SEARCHLOG_MIN; - p.windowLog = FUZ_rand(&g_rand) % (ZSTD_WINDOWLOG_MAX+1 - ZSTD_WINDOWLOG_MIN) + ZSTD_WINDOWLOG_MIN; - p.searchLength=FUZ_rand(&g_rand) % (ZSTD_SEARCHLENGTH_MAX+1 - ZSTD_SEARCHLENGTH_MIN) + ZSTD_SEARCHLENGTH_MIN; - p.targetLength=FUZ_rand(&g_rand) % (ZSTD_TARGETLENGTH_MAX+1 - ZSTD_TARGETLENGTH_MIN) + ZSTD_TARGETLENGTH_MIN; + p.chainLog = (FUZ_rand(&g_rand) % (ZSTD_CHAINLOG_MAX+1 - ZSTD_CHAINLOG_MIN)) + ZSTD_CHAINLOG_MIN; + p.hashLog = (FUZ_rand(&g_rand) % (ZSTD_HASHLOG_MAX+1 - ZSTD_HASHLOG_MIN)) + ZSTD_HASHLOG_MIN; + p.searchLog = (FUZ_rand(&g_rand) % (ZSTD_SEARCHLOG_MAX+1 - ZSTD_SEARCHLOG_MIN)) + ZSTD_SEARCHLOG_MIN; + p.windowLog = (FUZ_rand(&g_rand) % (ZSTD_WINDOWLOG_MAX+1 - ZSTD_WINDOWLOG_MIN)) + ZSTD_WINDOWLOG_MIN; + p.searchLength=(FUZ_rand(&g_rand) % (ZSTD_SEARCHLENGTH_MAX+1 - ZSTD_SEARCHLENGTH_MIN)) + ZSTD_SEARCHLENGTH_MIN; + p.targetLength=(FUZ_rand(&g_rand) % (512)) + ZSTD_TARGETLENGTH_MIN; p.strategy = (ZSTD_strategy) (FUZ_rand(&g_rand) % (ZSTD_btultra +1)); validated = !ZSTD_isError(ZSTD_checkCParams(p)); } diff --git a/tests/playTests.sh b/tests/playTests.sh index c93c58fe8d588..41d8263b6a674 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -93,6 +93,7 @@ else hasMT="true" fi + $ECHO "\n===> simple tests " ./datagen > tmp @@ -100,8 +101,12 @@ $ECHO "test : basic compression " $ZSTD -f tmp # trivial compression case, creates tmp.zst $ECHO "test : basic decompression" $ZSTD -df tmp.zst # trivial decompression case (overwrites tmp) -$ECHO "test : too large compression level (must fail)" +$ECHO "test : too large compression level => auto-fix" $ZSTD -99 -f tmp # too large compression level, automatic sized down +$ECHO "test : --fast aka negative compression levels" +$ZSTD --fast -f tmp # == -1 +$ZSTD --fast=3 -f tmp # == -3 +$ZSTD --fast=200000 -f tmp # == no compression $ECHO "test : compress to stdout" $ZSTD tmp -c > tmpCompressed $ZSTD tmp --stdout > tmpCompressed # long command format @@ -190,10 +195,16 @@ $ZSTD -t tmp1.zst tmp2.zst $ZSTD -dc tmp1.zst tmp2.zst $ZSTD tmp1.zst tmp2.zst -o "$INTOVOID" $ZSTD -d tmp1.zst tmp2.zst -o tmp +touch tmpexists +$ZSTD tmp1 tmp2 -f -o tmpexists +$ZSTD tmp1 tmp2 -o tmpexists && die "should have refused to overwrite" +# Bug: PR #972 +if [ "$?" -eq 139 ]; then + die "should not have segfaulted" +fi rm tmp* - $ECHO "\n===> Advanced compression parameters " $ECHO "Hello world!" | $ZSTD --zstd=windowLog=21, - -o tmp.zst && die "wrong parameters not detected!" $ECHO "Hello world!" | $ZSTD --zstd=windowLo=21 - -o tmp.zst && die "wrong parameters not detected!" @@ -203,8 +214,8 @@ roundTripTest -g512K roundTripTest -g512K " --zstd=slen=3,tlen=48,strat=6" roundTripTest -g512K " --zstd=strat=6,wlog=23,clog=23,hlog=22,slog=6" roundTripTest -g512K " --zstd=windowLog=23,chainLog=23,hashLog=22,searchLog=6,searchLength=3,targetLength=48,strategy=6" -roundTripTest -g512K " --long --zstd=ldmHashLog=20,ldmSearchLength=64,ldmBucketSizeLog=1,ldmHashEveryLog=7" -roundTripTest -g512K " --long --zstd=ldmhlog=20,ldmslen=64,ldmblog=1,ldmhevery=7" +roundTripTest -g512K " --single-thread --long --zstd=ldmHashLog=20,ldmSearchLength=64,ldmBucketSizeLog=1,ldmHashEveryLog=7" +roundTripTest -g512K " --single-thread --long --zstd=ldmhlog=20,ldmslen=64,ldmblog=1,ldmhevery=7" roundTripTest -g512K 19 @@ -231,8 +242,18 @@ $ZSTD -c hello.tmp > hello.zstd --no-check $ZSTD -c world.tmp > world.zstd --no-check cat hello.zstd world.zstd > helloworld.zstd $ZSTD -dc helloworld.zstd > result.tmp -cat result.tmp $DIFF helloworld.tmp result.tmp +$ECHO "testing zstdcat symlink" +ln -sf $ZSTD zstdcat +./zstdcat helloworld.zstd > result.tmp +$DIFF helloworld.tmp result.tmp +rm zstdcat +rm result.tmp +$ECHO "testing zcat symlink" +ln -sf $ZSTD zcat +./zcat helloworld.zstd > result.tmp +$DIFF helloworld.tmp result.tmp +rm zcat rm ./*.tmp ./*.zstd $ECHO "frame concatenation tests completed" @@ -322,9 +343,14 @@ $ECHO "- Create first dictionary " TESTFILE=../programs/zstdcli.c $ZSTD --train *.c ../programs/*.c -o tmpDict cp $TESTFILE tmp +$ECHO "- Dictionary compression roundtrip" $ZSTD -f tmp -D tmpDict $ZSTD -d tmp.zst -D tmpDict -fo result $DIFF $TESTFILE result +$ECHO "- Dictionary compression with btlazy2 strategy" +$ZSTD -f tmp -D tmpDict --zstd=strategy=6 +$ZSTD -d tmp.zst -D tmpDict -fo result +$DIFF $TESTFILE result if [ -n "$hasMT" ] then $ECHO "- Test dictionary compression with multithreading " @@ -451,6 +477,8 @@ $ECHO "bench one file" $ZSTD -bi0 tmp1 $ECHO "bench multiple levels" $ZSTD -i0b0e3 tmp1 +$ECHO "bench negative level" +$ZSTD -bi0 --fast tmp1 $ECHO "with recursive and quiet modes" $ZSTD -rqi1b1e2 tmp1 @@ -603,14 +631,15 @@ roundTripTest -g516K 19 # btopt fileRoundTripTest -g500K $ECHO "\n===> zstd long distance matching round-trip tests " -roundTripTest -g0 "2 --long" -roundTripTest -g1000K "1 --long" -roundTripTest -g517K "6 --long" -roundTripTest -g516K "16 --long" -roundTripTest -g518K "19 --long" -fileRoundTripTest -g5M "3 --long" +roundTripTest -g0 "2 --single-thread --long" +roundTripTest -g1000K "1 --single-thread --long" +roundTripTest -g517K "6 --single-thread --long" +roundTripTest -g516K "16 --single-thread --long" +roundTripTest -g518K "19 --single-thread --long" +fileRoundTripTest -g5M "3 --single-thread --long" +roundTripTest -g96K "5 --single-thread" if [ -n "$hasMT" ] then $ECHO "\n===> zstdmt round-trip tests " @@ -620,7 +649,7 @@ then fileRoundTripTest -g4M "19 -T2 -B1M" $ECHO "\n===> zstdmt long distance matching round-trip tests " - roundTripTest -g8M "3 --long -T2" + roundTripTest -g8M "3 --long=24 -T2" else $ECHO "\n===> no multithreading, skipping zstdmt tests " fi @@ -671,13 +700,13 @@ rm tmp* $ECHO "\n===> zstd long distance matching tests " -roundTripTest -g0 " --long" -roundTripTest -g9M "2 --long" +roundTripTest -g0 " --single-thread --long" +roundTripTest -g9M "2 --single-thread --long" # Test parameter parsing -roundTripTest -g1M -P50 "1 --long=29" " --memory=512MB" -roundTripTest -g1M -P50 "1 --long=29 --zstd=wlog=28" " --memory=256MB" -roundTripTest -g1M -P50 "1 --long=29" " --long=28 --memory=512MB" -roundTripTest -g1M -P50 "1 --long=29" " --zstd=wlog=28 --memory=512MB" +roundTripTest -g1M -P50 "1 --single-thread --long=29" " --memory=512MB" +roundTripTest -g1M -P50 "1 --single-thread --long=29 --zstd=wlog=28" " --memory=256MB" +roundTripTest -g1M -P50 "1 --single-thread --long=29" " --long=28 --memory=512MB" +roundTripTest -g1M -P50 "1 --single-thread --long=29" " --zstd=wlog=28 --memory=512MB" if [ "$1" != "--test-large-data" ]; then @@ -712,18 +741,19 @@ roundTripTest -g18000018 -P94 18 roundTripTest -g18000019 -P96 19 roundTripTest -g5000000000 -P99 1 +roundTripTest -g1700000000 -P0 "1 --zstd=strategy=6" # ensure btlazy2 can survive an overflow rescale fileRoundTripTest -g4193M -P99 1 $ECHO "\n===> zstd long, long distance matching round-trip tests " -roundTripTest -g270000000 "1 --long" -roundTripTest -g130000000 -P60 "5 --long" -roundTripTest -g35000000 -P70 "8 --long" -roundTripTest -g18000001 -P80 "18 --long" +roundTripTest -g270000000 "1 --single-thread --long" +roundTripTest -g130000000 -P60 "5 --single-thread --long" +roundTripTest -g35000000 -P70 "8 --single-thread --long" +roundTripTest -g18000001 -P80 "18 --single-thread --long" # Test large window logs -roundTripTest -g700M -P50 "1 --long=29" -roundTripTest -g600M -P50 "1 --long --zstd=wlog=29,clog=28" +roundTripTest -g700M -P50 "1 --single-thread --long=29" +roundTripTest -g600M -P50 "1 --single-thread --long --zstd=wlog=29,clog=28" if [ -n "$hasMT" ] diff --git a/tests/roundTripCrash.c b/tests/roundTripCrash.c index 180fa9b6f6dcd..7d937fceebc01 100644 --- a/tests/roundTripCrash.c +++ b/tests/roundTripCrash.c @@ -94,7 +94,7 @@ static size_t cctxParamRoundTripTest(void* resultBuff, size_t resultBuffCapacity /* Set parameters */ CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_compressionLevel, cLevel) ); - CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_nbThreads, 2) ); + CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_nbWorkers, 2) ); CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_overlapSizeLog, 5) ); diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index 5590c9af15f8e..b94f282f5802c 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -99,7 +99,7 @@ unsigned int FUZ_rand(unsigned int* seedPtr) if (cond) { \ DISPLAY("Error => "); \ DISPLAY(__VA_ARGS__); \ - DISPLAY(" (seed %u, test nb %u, line %u) \n", \ + DISPLAY(" (seed %u, test nb %u, line %u) \n", \ seed, testNb, __LINE__); \ goto _output_error; \ } } @@ -219,6 +219,7 @@ static int basicUnitTests(U32 seed, double compressibility) size_t cSize; int testResult = 0; U32 testNb = 1; + U32 coreSeed = 0; /* this name to conform with CHECK_Z macro display */ ZSTD_CStream* zc = ZSTD_createCStream(); ZSTD_DStream* zd = ZSTD_createDStream(); ZSTDMT_CCtx* mtctx = ZSTDMT_createCCtx(2); @@ -238,7 +239,7 @@ static int basicUnitTests(U32 seed, double compressibility) /* Create dictionary */ DISPLAYLEVEL(3, "creating dictionary for unit tests \n"); - dictionary = FUZ_createDictionary(CNBuffer, CNBufferSize / 2, 8 KB, 40 KB); + dictionary = FUZ_createDictionary(CNBuffer, CNBufferSize / 3, 16 KB, 48 KB); if (!dictionary.start) { DISPLAY("Error creating dictionary, aborting \n"); goto _output_error; @@ -372,7 +373,7 @@ static int basicUnitTests(U32 seed, double compressibility) DISPLAYLEVEL(3, "OK (%u bytes) \n", (U32)s); } - /* Byte-by-byte decompression test */ + /* Decompression by small increment */ DISPLAYLEVEL(3, "test%3i : decompress byte-by-byte : ", testNb++); { /* skippable frame */ size_t r = 1; @@ -382,8 +383,10 @@ static int basicUnitTests(U32 seed, double compressibility) inBuff.pos = 0; outBuff.pos = 0; while (r) { /* skippable frame */ - inBuff.size = inBuff.pos + 1; - outBuff.size = outBuff.pos + 1; + size_t const inSize = FUZ_rand(&coreSeed) & 15; + size_t const outSize = FUZ_rand(&coreSeed) & 15; + inBuff.size = inBuff.pos + inSize; + outBuff.size = outBuff.pos + outSize; r = ZSTD_decompressStream(zd, &outBuff, &inBuff); if (ZSTD_isError(r)) goto _output_error; } @@ -391,8 +394,10 @@ static int basicUnitTests(U32 seed, double compressibility) ZSTD_initDStream_usingDict(zd, CNBuffer, dictSize); r=1; while (r) { - inBuff.size = inBuff.pos + 1; - outBuff.size = outBuff.pos + 1; + size_t const inSize = FUZ_rand(&coreSeed) & 15; + size_t const outSize = FUZ_rand(&coreSeed) & 15; + inBuff.size = inBuff.pos + inSize; + outBuff.size = outBuff.pos + outSize; r = ZSTD_decompressStream(zd, &outBuff, &inBuff); if (ZSTD_isError(r)) goto _output_error; } @@ -427,8 +432,8 @@ static int basicUnitTests(U32 seed, double compressibility) DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/COMPRESSIBLE_NOISE_LENGTH*100); /* wrong _srcSize compression test */ - DISPLAYLEVEL(3, "test%3i : wrong srcSize : %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH-1); - ZSTD_initCStream_srcSize(zc, 1, CNBufferSize-1); + DISPLAYLEVEL(3, "test%3i : too large srcSize : %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH-1); + ZSTD_initCStream_srcSize(zc, 1, CNBufferSize+1); outBuff.dst = (char*)(compressedBuffer); outBuff.size = compressedBufferSize; outBuff.pos = 0; @@ -441,6 +446,20 @@ static int basicUnitTests(U32 seed, double compressibility) if (ZSTD_getErrorCode(r) != ZSTD_error_srcSize_wrong) goto _output_error; /* must fail : wrong srcSize */ DISPLAYLEVEL(3, "OK (error detected : %s) \n", ZSTD_getErrorName(r)); } + /* wrong _srcSize compression test */ + DISPLAYLEVEL(3, "test%3i : too small srcSize : %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH-1); + ZSTD_initCStream_srcSize(zc, 1, CNBufferSize-1); + outBuff.dst = (char*)(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_getErrorCode(r) != ZSTD_error_srcSize_wrong) goto _output_error; /* must fail : wrong srcSize */ + DISPLAYLEVEL(3, "OK (error detected : %s) \n", ZSTD_getErrorName(r)); + } + /* Complex context re-use scenario */ DISPLAYLEVEL(3, "test%3i : context re-use : ", testNb++); ZSTD_freeCStream(zc); @@ -557,11 +576,50 @@ static int basicUnitTests(U32 seed, double compressibility) { size_t const r = ZSTD_decompressStream(zd, &outBuff, &inBuff); if (!ZSTD_isError(r)) goto _output_error; /* must fail : frame requires > 100 bytes */ DISPLAYLEVEL(3, "OK (%s)\n", ZSTD_getErrorName(r)); } + ZSTD_DCtx_reset(zd); /* leave zd in good shape for next tests */ + + DISPLAYLEVEL(3, "test%3i : dictionary source size and level : ", testNb++); + { ZSTD_DCtx* const dctx = ZSTD_createDCtx(); + int const maxLevel = 16; /* first level with zstd_opt */ + int level; + assert(maxLevel < ZSTD_maxCLevel()); + CHECK_Z( ZSTD_DCtx_loadDictionary_byReference(dctx, dictionary.start, dictionary.filled) ); + for (level = 1; level <= maxLevel; ++level) { + ZSTD_CDict* const cdict = ZSTD_createCDict(dictionary.start, dictionary.filled, level); + size_t const maxSize = MIN(1 MB, CNBufferSize); + size_t size; + for (size = 512; size <= maxSize; size <<= 1) { + U64 const crcOrig = XXH64(CNBuffer, size, 0); + ZSTD_CCtx* const cctx = ZSTD_createCCtx(); + outBuff.dst = compressedBuffer; + outBuff.size = compressedBufferSize; + outBuff.pos = 0; + inBuff.src = CNBuffer; + inBuff.size = size; + inBuff.pos = 0; + CHECK_Z(ZSTD_CCtx_refCDict(cctx, cdict)); + CHECK_Z(ZSTD_compress_generic(cctx, &outBuff, &inBuff, ZSTD_e_end)); + if (inBuff.pos != inBuff.size) goto _output_error; + { ZSTD_outBuffer decOut = {decodedBuffer, size, 0}; + ZSTD_inBuffer decIn = {outBuff.dst, outBuff.pos, 0}; + CHECK_Z( ZSTD_decompress_generic(dctx, &decOut, &decIn) ); + if (decIn.pos != decIn.size) goto _output_error; + if (decOut.pos != size) goto _output_error; + { U64 const crcDec = XXH64(decOut.dst, decOut.pos, 0); + if (crcDec != crcOrig) goto _output_error; + } } + ZSTD_freeCCtx(cctx); + } + ZSTD_freeCDict(cdict); + } + ZSTD_freeDCtx(dctx); + } + DISPLAYLEVEL(3, "OK\n"); 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, ZSTD_dlm_byRef, ZSTD_dm_auto, cParams, ZSTD_defaultCMem); + ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictionary.start, dictionary.filled, ZSTD_dlm_byRef, ZSTD_dct_auto, cParams, ZSTD_defaultCMem); size_t const initError = ZSTD_initCStream_usingCDict_advanced(zc, cdict, fParams, CNBufferSize); if (ZSTD_isError(initError)) goto _output_error; cSize = 0; @@ -605,14 +663,18 @@ static int basicUnitTests(U32 seed, double compressibility) cSize = outBuff.pos; DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBufferSize*100); - DISPLAYLEVEL(3, "test%3i : decompress with dictionary : ", testNb++); - { size_t const r = ZSTD_decompress_usingDict(zd, - decodedBuffer, CNBufferSize, - compressedBuffer, cSize, - dictionary.start, dictionary.filled); - if (ZSTD_isError(r)) goto _output_error; /* must fail : dictionary not used */ - DISPLAYLEVEL(3, "OK \n"); - } + DISPLAYLEVEL(3, "test%3i : decompress with ZSTD_DCtx_refPrefix : ", testNb++); + CHECK_Z( ZSTD_DCtx_refPrefix(zd, dictionary.start, dictionary.filled) ); + outBuff.dst = decodedBuffer; + outBuff.size = CNBufferSize; + outBuff.pos = 0; + inBuff.src = compressedBuffer; + inBuff.size = cSize; + inBuff.pos = 0; + CHECK_Z( ZSTD_decompress_generic(zd, &outBuff, &inBuff) ); + if (inBuff.pos != inBuff.size) goto _output_error; /* entire input should be consumed */ + if (outBuff.pos != CNBufferSize) goto _output_error; /* must regenerate whole input */ + DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "test%3i : decompress without dictionary (should fail): ", testNb++); { size_t const r = ZSTD_decompress(decodedBuffer, CNBufferSize, compressedBuffer, cSize); @@ -694,16 +756,19 @@ static int basicUnitTests(U32 seed, double compressibility) inBuff.src = CNBuffer; inBuff.size = CNBufferSize; inBuff.pos = 0; - CHECK_Z( ZSTDMT_compressStream_generic(mtctx, &outBuff, &inBuff, ZSTD_e_end) ); + { size_t const compressResult = ZSTDMT_compressStream_generic(mtctx, &outBuff, &inBuff, ZSTD_e_end); + if (compressResult != 0) goto _output_error; /* compression must be completed in a single round */ + } if (inBuff.pos != inBuff.size) goto _output_error; /* entire input should be consumed */ - { size_t const r = ZSTDMT_endStream(mtctx, &outBuff); - if (r != 0) goto _output_error; } /* error, or some data not flushed */ + { size_t const compressedSize = ZSTD_findFrameCompressedSize(compressedBuffer, outBuff.pos); + if (compressedSize != outBuff.pos) goto _output_error; /* must be a full valid frame */ + } DISPLAYLEVEL(3, "OK \n"); /* Complex multithreading + dictionary test */ - { U32 const nbThreads = 2; + { U32 const nbWorkers = 2; size_t const jobSize = 4 * 1 MB; - size_t const srcSize = jobSize * nbThreads; /* we want each job to have predictable size */ + size_t const srcSize = jobSize * nbWorkers; /* we want each job to have predictable size */ size_t const segLength = 2 KB; size_t const offset = 600 KB; /* must be larger than window defined in cdict */ size_t const start = jobSize + (offset-1); @@ -711,7 +776,7 @@ static int basicUnitTests(U32 seed, double compressibility) BYTE* const dst = (BYTE*)CNBuffer + start - offset; DISPLAYLEVEL(3, "test%3i : compress %u bytes with multiple threads + dictionary : ", testNb++, (U32)srcSize); CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_compressionLevel, 3) ); - CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_nbThreads, 2) ); + CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_nbWorkers, nbWorkers) ); CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_jobSize, jobSize) ); assert(start > offset); assert(start + segLength < COMPRESSIBLE_NOISE_LENGTH); @@ -724,7 +789,7 @@ static int basicUnitTests(U32 seed, double compressibility) inBuff.pos = 0; } { ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, 4 KB, dictionary.filled); /* intentionnally lies on estimatedSrcSize, to push cdict into targeting a small window size */ - ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictionary.start, dictionary.filled, ZSTD_dlm_byRef, ZSTD_dm_fullDict, cParams, ZSTD_defaultCMem); + ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictionary.start, dictionary.filled, ZSTD_dlm_byRef, ZSTD_dct_fullDict, cParams, ZSTD_defaultCMem); DISPLAYLEVEL(5, "cParams.windowLog = %u : ", cParams.windowLog); CHECK_Z( ZSTD_CCtx_refCDict(zc, cdict) ); CHECK_Z( ZSTD_compress_generic(zc, &outBuff, &inBuff, ZSTD_e_end) ); @@ -767,7 +832,7 @@ static int basicUnitTests(U32 seed, double compressibility) XXH64_reset(&xxh, 0); cParams.windowLog = kMaxWindowLog; - cdict = ZSTD_createCDict_advanced(dictionary.start, dictionary.filled, ZSTD_dlm_byRef, ZSTD_dm_fullDict, cParams, ZSTD_defaultCMem); + cdict = ZSTD_createCDict_advanced(dictionary.start, dictionary.filled, ZSTD_dlm_byRef, ZSTD_dct_fullDict, cParams, ZSTD_defaultCMem); ddict = ZSTD_createDDict(dictionary.start, dictionary.filled); if (!cdict || !ddict) goto _output_error; @@ -863,11 +928,21 @@ static size_t findDiff(const void* buf1, const void* buf2, size_t max) for (u=0; u<max; u++) { if (b1[u] != b2[u]) break; } + if (u==max) { + DISPLAY("=> No difference detected within %u bytes \n", (U32)max); + return u; + } DISPLAY("Error at position %u / %u \n", (U32)u, (U32)max); - DISPLAY(" %02X %02X %02X :%02X: %02X %02X %02X %02X %02X \n", - b1[u-3], b1[u-2], b1[u-1], b1[u-0], b1[u+1], b1[u+2], b1[u+3], b1[u+4], b1[u+5]); - DISPLAY(" %02X %02X %02X :%02X: %02X %02X %02X %02X %02X \n", - b2[u-3], b2[u-2], b2[u-1], b2[u-0], b2[u+1], b2[u+2], b2[u+3], b2[u+4], b2[u+5]); + if (u>=3) + DISPLAY(" %02X %02X %02X ", + b1[u-3], b1[u-2], b1[u-1]); + DISPLAY(" :%02X: %02X %02X %02X %02X %02X \n", + b1[u], b1[u+1], b1[u+2], b1[u+3], b1[u+4], b1[u+5]); + if (u>=3) + DISPLAY(" %02X %02X %02X ", + b2[u-3], b2[u-2], b2[u-1]); + DISPLAY(" :%02X: %02X %02X %02X %02X %02X \n", + b2[u], b2[u+1], b2[u+2], b2[u+3], b2[u+4], b2[u+5]); return u; } @@ -948,10 +1023,13 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres size_t maxTestSize; /* init */ - if (nbTests >= testNb) { DISPLAYUPDATE(2, "\r%6u/%6u ", testNb, nbTests); } - else { DISPLAYUPDATE(2, "\r%6u ", testNb); } FUZ_rand(&coreSeed); lseed = coreSeed ^ prime32; + if (nbTests >= testNb) { + DISPLAYUPDATE(2, "\r%6u/%6u ", testNb, nbTests); + } else { + DISPLAYUPDATE(2, "\r%6u ", testNb); + } /* states full reset (deliberately not synchronized) */ /* some issues can only happen when reusing states */ @@ -1161,7 +1239,6 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp UTIL_time_t const startClock = UTIL_getTime(); const BYTE* dict=NULL; /* can keep same dict on 2 consecutive tests */ size_t dictSize = 0; - U32 oldTestLog = 0; int const cLevelMax = bigTests ? (U32)ZSTD_maxCLevel()-1 : g_cLevelMax_smallTests; U32 const nbThreadsMax = bigTests ? 4 : 2; @@ -1183,6 +1260,7 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp RDG_genBuffer(cNoiseBuffer[4], srcBufferSize, 1.00, 0., coreSeed); /* sparse content */ memset(copyBuffer, 0x65, copyBufferSize); /* make copyBuffer considered initialized */ ZSTD_initDStream_usingDict(zd, NULL, 0); /* ensure at least one init */ + DISPLAYLEVEL(6, "Creating initial context with %u threads \n", nbThreads); /* catch up testNb */ for (testNb=1; testNb < startTest; testNb++) @@ -1195,14 +1273,14 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp size_t totalTestSize, totalGenSize, cSize; XXH64_state_t xxhState; U64 crcOrig; - U32 resetAllowed = 1; size_t maxTestSize; - /* init */ - if (testNb < nbTests) { - DISPLAYUPDATE(2, "\r%6u/%6u ", testNb, nbTests); - } else { DISPLAYUPDATE(2, "\r%6u ", testNb); } FUZ_rand(&coreSeed); + if (nbTests >= testNb) { + DISPLAYUPDATE(2, "\r%6u/%6u ", testNb, nbTests); + } else { + DISPLAYUPDATE(2, "\r%6u ", testNb); + } lseed = coreSeed ^ prime32; /* states full reset (deliberately not synchronized) */ @@ -1213,7 +1291,6 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp ZSTDMT_freeCCtx(zc); zc = ZSTDMT_createCCtx(nbThreads); CHECK(zc==NULL, "ZSTDMT_createCCtx allocation error") - resetAllowed=0; } if ((FUZ_rand(&lseed) & 0xFF) == 132) { ZSTD_freeDStream(zd); @@ -1238,15 +1315,7 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp } /* compression init */ - 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; - { int const compressionLevel = (FUZ_rand(&lseed) % 5) + 1; - CHECK_Z( ZSTDMT_initCStream(zc, compressionLevel) ); - } - } else { - U32 const testLog = FUZ_rand(&lseed) % maxSrcLog; + { U32 const testLog = FUZ_rand(&lseed) % maxSrcLog; U32 const dictLog = FUZ_rand(&lseed) % maxSrcLog; int const cLevelCandidate = ( FUZ_rand(&lseed) % (ZSTD_maxCLevel() - (MAX(testLog, dictLog) / 2)) ) @@ -1255,24 +1324,29 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp int const cLevelMin = MAX(cLevelThreadAdjusted, 1); /* no negative cLevel yet */ int const cLevel = MIN(cLevelMin, cLevelMax); maxTestSize = FUZ_rLogLength(&lseed, testLog); - oldTestLog = testLog; - /* random dictionary selection */ - dictSize = ((FUZ_rand(&lseed)&63)==1) ? FUZ_rLogLength(&lseed, dictLog) : 0; - { size_t const dictStart = FUZ_rand(&lseed) % (srcBufferSize - dictSize); - dict = srcBuffer + dictStart; - } - { U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? ZSTD_CONTENTSIZE_UNKNOWN : maxTestSize; - ZSTD_parameters params = ZSTD_getParams(cLevel, pledgedSrcSize, dictSize); - DISPLAYLEVEL(5, "Init with windowLog = %u, pledgedSrcSize = %u, dictSize = %u \n", - params.cParams.windowLog, (U32)pledgedSrcSize, (U32)dictSize); - params.fParams.checksumFlag = FUZ_rand(&lseed) & 1; - params.fParams.noDictIDFlag = FUZ_rand(&lseed) & 1; - params.fParams.contentSizeFlag = FUZ_rand(&lseed) & 1; - DISPLAYLEVEL(5, "checksumFlag : %u \n", params.fParams.checksumFlag); - CHECK_Z( ZSTDMT_setMTCtxParameter(zc, ZSTDMT_p_overlapSectionLog, FUZ_rand(&lseed) % 12) ); - CHECK_Z( ZSTDMT_setMTCtxParameter(zc, ZSTDMT_p_jobSize, FUZ_rand(&lseed) % (2*maxTestSize+1)) ); /* custome job size */ - CHECK_Z( ZSTDMT_initCStream_advanced(zc, dict, dictSize, params, pledgedSrcSize) ); - } } + + if (FUZ_rand(&lseed)&1) { /* simple init */ + int const compressionLevel = (FUZ_rand(&lseed) % 5) + 1; + DISPLAYLEVEL(5, "Init with compression level = %i \n", compressionLevel); + CHECK_Z( ZSTDMT_initCStream(zc, compressionLevel) ); + } else { /* advanced init */ + /* random dictionary selection */ + dictSize = ((FUZ_rand(&lseed)&63)==1) ? FUZ_rLogLength(&lseed, dictLog) : 0; + { size_t const dictStart = FUZ_rand(&lseed) % (srcBufferSize - dictSize); + dict = srcBuffer + dictStart; + } + { U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? ZSTD_CONTENTSIZE_UNKNOWN : maxTestSize; + ZSTD_parameters params = ZSTD_getParams(cLevel, pledgedSrcSize, dictSize); + DISPLAYLEVEL(5, "Init with windowLog = %u, pledgedSrcSize = %u, dictSize = %u \n", + params.cParams.windowLog, (U32)pledgedSrcSize, (U32)dictSize); + params.fParams.checksumFlag = FUZ_rand(&lseed) & 1; + params.fParams.noDictIDFlag = FUZ_rand(&lseed) & 1; + params.fParams.contentSizeFlag = FUZ_rand(&lseed) & 1; + DISPLAYLEVEL(5, "checksumFlag : %u \n", params.fParams.checksumFlag); + CHECK_Z( ZSTDMT_setMTCtxParameter(zc, ZSTDMT_p_overlapSectionLog, FUZ_rand(&lseed) % 12) ); + CHECK_Z( ZSTDMT_setMTCtxParameter(zc, ZSTDMT_p_jobSize, FUZ_rand(&lseed) % (2*maxTestSize+1)) ); /* custome job size */ + CHECK_Z( ZSTDMT_initCStream_advanced(zc, dict, dictSize, params, pledgedSrcSize) ); + } } } /* multi-segments compression test */ XXH64_reset(&xxhState, 0); @@ -1301,9 +1375,12 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp if ((FUZ_rand(&lseed) & 15) == 0) { size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog); size_t const adjustedDstSize = MIN(cBufferSize - cSize, randomDstSize); + size_t const previousPos = outBuff.pos; outBuff.size = outBuff.pos + adjustedDstSize; DISPLAYLEVEL(5, "Flushing into dst buffer of size %u \n", (U32)adjustedDstSize); CHECK_Z( ZSTDMT_flushStream(zc, &outBuff) ); + assert(outBuff.pos >= previousPos); + DISPLAYLEVEL(6, "%u bytes flushed by ZSTDMT_flushStream \n", (U32)(outBuff.pos-previousPos)); } } /* final frame epilogue */ @@ -1311,18 +1388,24 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp while (remainingToFlush) { size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog); size_t const adjustedDstSize = MIN(cBufferSize - cSize, randomDstSize); + size_t const previousPos = outBuff.pos; 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), "ZSTDMT_endStream error : %s", ZSTD_getErrorName(remainingToFlush)); + assert(outBuff.pos >= previousPos); + DISPLAYLEVEL(6, "%u bytes flushed by ZSTDMT_endStream \n", (U32)(outBuff.pos-previousPos)); DISPLAYLEVEL(5, "endStream : remainingToFlush : %u \n", (U32)remainingToFlush); } } crcOrig = XXH64_digest(&xxhState); cSize = outBuff.pos; - DISPLAYLEVEL(5, "Frame completed : %u bytes \n", (U32)cSize); + DISPLAYLEVEL(5, "Frame completed : %u bytes compressed into %u bytes \n", + (U32)totalTestSize, (U32)cSize); } /* multi - fragments decompression test */ + assert(totalTestSize < dstBufferSize); + memset(dstBuffer, 170, totalTestSize); /* init dest area */ if (!dictSize /* don't reset if dictionary : could be different */ && (FUZ_rand(&lseed) & 1)) { CHECK_Z( ZSTD_resetDStream(zd) ); } else { @@ -1337,10 +1420,16 @@ 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 = outBuff.pos + dstBuffSize; - DISPLAYLEVEL(6, "ZSTD_decompressStream input %u bytes \n", (U32)readCSrcSize); + DISPLAYLEVEL(6, "ZSTD_decompressStream input %u bytes into outBuff %u bytes \n", + (U32)readCSrcSize, (U32)dstBuffSize); decompressionResult = ZSTD_decompressStream(zd, &outBuff, &inBuff); + if (ZSTD_isError(decompressionResult)) { + DISPLAY("ZSTD_decompressStream error : %s \n", ZSTD_getErrorName(decompressionResult)); + findDiff(copyBuffer, dstBuffer, totalTestSize); + } CHECK (ZSTD_isError(decompressionResult), "decompression error : %s", ZSTD_getErrorName(decompressionResult)); - DISPLAYLEVEL(6, "inBuff.pos = %u \n", (U32)readCSrcSize); + DISPLAYLEVEL(6, "total ingested (inBuff.pos) = %u and produced (outBuff.pos) = %u \n", + (U32)inBuff.pos, (U32)outBuff.pos); } 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); @@ -1579,7 +1668,11 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double } /* mess with frame parameters */ - if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_checksumFlag, FUZ_rand(&lseed) & 1, useOpaqueAPI) ); + if (FUZ_rand(&lseed) & 1) { + U32 const checksumFlag = FUZ_rand(&lseed) & 1; + DISPLAYLEVEL(5, "t%u: frame checksum : %u \n", testNb, checksumFlag); + CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_checksumFlag, checksumFlag, useOpaqueAPI) ); + } if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_dictIDFlag, FUZ_rand(&lseed) & 1, useOpaqueAPI) ); if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_contentSizeFlag, FUZ_rand(&lseed) & 1, useOpaqueAPI) ); if (FUZ_rand(&lseed) & 1) { @@ -1592,7 +1685,7 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double U32 const nbThreadsAdjusted = (windowLogMalus < nbThreadsCandidate) ? nbThreadsCandidate - windowLogMalus : 1; U32 const nbThreads = MIN(nbThreadsAdjusted, nbThreadsMax); DISPLAYLEVEL(5, "t%u: nbThreads : %u \n", testNb, nbThreads); - CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_nbThreads, nbThreads, useOpaqueAPI) ); + CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_nbWorkers, nbThreads, useOpaqueAPI) ); if (nbThreads > 1) { U32 const jobLog = FUZ_rand(&lseed) % (testLog+1); CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_overlapSizeLog, FUZ_rand(&lseed) % 10, useOpaqueAPI) ); @@ -1644,8 +1737,8 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double outBuff.size = outBuff.pos + dstBuffSize; CHECK_Z( ZSTD_compress_generic(zc, &outBuff, &inBuff, flush) ); - DISPLAYLEVEL(6, "t%u: compress consumed %u bytes (total : %u) \n", - testNb, (U32)inBuff.pos, (U32)(totalTestSize + inBuff.pos)); + DISPLAYLEVEL(6, "t%u: compress consumed %u bytes (total : %u) ; flush: %u (total : %u) \n", + testNb, (U32)inBuff.pos, (U32)(totalTestSize + inBuff.pos), (U32)flush, (U32)outBuff.pos); XXH64_update(&xxhState, srcBuffer+srcStart, inBuff.pos); memcpy(copyBuffer+totalTestSize, srcBuffer+srcStart, inBuff.pos); @@ -1653,14 +1746,15 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double } /* final frame epilogue */ - { size_t remainingToFlush = (size_t)(-1); + { size_t remainingToFlush = 1; while (remainingToFlush) { ZSTD_inBuffer inBuff = { NULL, 0, 0 }; size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog+1); size_t const adjustedDstSize = MIN(cBufferSize - cSize, randomDstSize); outBuff.size = outBuff.pos + adjustedDstSize; - DISPLAYLEVEL(6, "End-flush into dst buffer of size %u \n", (U32)adjustedDstSize); + DISPLAYLEVEL(6, "t%u: End-flush into dst buffer of size %u \n", testNb, (U32)adjustedDstSize); remainingToFlush = ZSTD_compress_generic(zc, &outBuff, &inBuff, ZSTD_e_end); + DISPLAYLEVEL(6, "t%u: Total flushed so far : %u bytes \n", testNb, (U32)outBuff.pos); CHECK( ZSTD_isError(remainingToFlush), "ZSTD_compress_generic w/ ZSTD_e_end error : %s", ZSTD_getErrorName(remainingToFlush) ); @@ -1687,14 +1781,20 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double size_t const dstBuffSize = MIN(dstBufferSize - totalGenSize, randomDstSize); inBuff.size = inBuff.pos + readCSrcSize; outBuff.size = outBuff.pos + dstBuffSize; - DISPLAYLEVEL(6, "ZSTD_decompressStream input %u bytes (pos:%u/%u)\n", - (U32)readCSrcSize, (U32)inBuff.pos, (U32)cSize); + DISPLAYLEVEL(6, "decompression presented %u new bytes (pos:%u/%u)\n", + (U32)readCSrcSize, (U32)inBuff.pos, (U32)cSize); decompressionResult = ZSTD_decompressStream(zd, &outBuff, &inBuff); + DISPLAYLEVEL(6, "so far: consumed = %u, produced = %u \n", + (U32)inBuff.pos, (U32)outBuff.pos); + if (ZSTD_isError(decompressionResult)) { + DISPLAY("ZSTD_decompressStream error : %s \n", ZSTD_getErrorName(decompressionResult)); + findDiff(copyBuffer, dstBuffer, totalTestSize); + } CHECK (ZSTD_isError(decompressionResult), "decompression error : %s", ZSTD_getErrorName(decompressionResult)); - DISPLAYLEVEL(6, "inBuff.pos = %u \n", (U32)readCSrcSize); + CHECK (inBuff.pos > cSize, "ZSTD_decompressStream consumes too much input : %u > %u ", (U32)inBuff.pos, (U32)cSize); } - 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); + CHECK (outBuff.pos != totalTestSize, "decompressed data : wrong size (%u != %u)", (U32)outBuff.pos, (U32)totalTestSize); { U64 const crcDest = XXH64(dstBuffer, totalTestSize, 0); if (crcDest!=crcOrig) findDiff(copyBuffer, dstBuffer, totalTestSize); CHECK (crcDest!=crcOrig, "decompressed data corrupted"); |