Compress-Stream-Zstd

 view release on metacpan or  search on metacpan

ext/zstd/tests/zstreamtest.c  view on Meta::CPAN

            maxTestSize = FUZ_rLogLength(&lseed, testLog);
            oldTestLog = testLog;
            /* random dictionary selection */
            dictSize  = ((FUZ_rand(&lseed)&7)==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;
                CHECK_Z( ZSTD_CCtx_reset(zc, ZSTD_reset_session_only) );
                CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_c_compressionLevel, cLevel) );
                CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_c_checksumFlag, FUZ_rand(&lseed) & 1) );
                CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_c_contentSizeFlag, FUZ_rand(&lseed) & 1) );
                CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_c_dictIDFlag, FUZ_rand(&lseed) & 1) );
                CHECK_Z( ZSTD_CCtx_setPledgedSrcSize(zc, pledgedSrcSize) );
                CHECK_Z( ZSTD_CCtx_loadDictionary(zc, dict, dictSize) );
        }   }

        /* multi-segments compression test */
        XXH64_reset(&xxhState, 0);
        {   ZSTD_outBuffer outBuff = { cBuffer, cBufferSize, 0 } ;
            cSize=0;
            totalTestSize=0;
            while(totalTestSize < maxTestSize) {
                /* compress random chunks into randomly sized dst buffers */
                {   size_t const randomSrcSize = FUZ_randomLength(&lseed, maxSampleLog);
                    size_t const srcSize = MIN(maxTestSize-totalTestSize, randomSrcSize);
                    size_t const srcStart = FUZ_rand(&lseed) % (srcBufferSize - srcSize);
                    size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
                    size_t const dstBuffSize = MIN(cBufferSize - cSize, randomDstSize);
                    ZSTD_inBuffer inBuff = { srcBuffer+srcStart, srcSize, 0 };
                    outBuff.size = outBuff.pos + dstBuffSize;

                    CHECK_Z( ZSTD_compressStream(zc, &outBuff, &inBuff) );

                    XXH64_update(&xxhState, srcBuffer+srcStart, inBuff.pos);
                    memcpy(copyBuffer+totalTestSize, srcBuffer+srcStart, inBuff.pos);
                    totalTestSize += inBuff.pos;
                }

                /* random flush operation, to mess around */
                if ((FUZ_rand(&lseed) & 15) == 0) {
                    size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
                    size_t const adjustedDstSize = MIN(cBufferSize - cSize, randomDstSize);
                    outBuff.size = outBuff.pos + adjustedDstSize;
                    CHECK_Z( ZSTD_flushStream(zc, &outBuff) );
            }   }

            /* final frame epilogue */
            {   size_t remainingToFlush = (size_t)(-1);
                while (remainingToFlush) {
                    size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
                    size_t const adjustedDstSize = MIN(cBufferSize - cSize, randomDstSize);
                    outBuff.size = outBuff.pos + adjustedDstSize;
                    remainingToFlush = ZSTD_endStream(zc, &outBuff);
                    CHECK (ZSTD_isError(remainingToFlush), "end error : %s", ZSTD_getErrorName(remainingToFlush));
            }   }
            crcOrig = XXH64_digest(&xxhState);
            cSize = outBuff.pos;
        }

        /* multi - fragments decompression test */
        if (!dictSize /* don't reset if dictionary : could be different */ && (FUZ_rand(&lseed) & 1)) {
            CHECK_Z ( ZSTD_resetDStream(zd) );
        } else {
            CHECK_Z ( ZSTD_initDStream_usingDict(zd, dict, dictSize) );
        }
        {   size_t decompressionResult = 1;
            ZSTD_inBuffer  inBuff = { cBuffer, cSize, 0 };
            ZSTD_outBuffer outBuff= { dstBuffer, dstBufferSize, 0 };
            for (totalGenSize = 0 ; decompressionResult ; ) {
                size_t const readCSrcSize = FUZ_randomLength(&lseed, maxSampleLog);
                size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
                size_t const dstBuffSize = MIN(dstBufferSize - totalGenSize, randomDstSize);
                inBuff.size = inBuff.pos + readCSrcSize;
                outBuff.size = outBuff.pos + dstBuffSize;
                decompressionResult = ZSTD_decompressStream(zd, &outBuff, &inBuff);
                if (ZSTD_getErrorCode(decompressionResult) == ZSTD_error_checksum_wrong) {
                    DISPLAY("checksum error : \n");
                    findDiff(copyBuffer, dstBuffer, totalTestSize);
                }
                CHECK( ZSTD_isError(decompressionResult), "decompression error : %s",
                       ZSTD_getErrorName(decompressionResult) );
            }
            CHECK (decompressionResult != 0, "frame not fully decoded");
            CHECK (outBuff.pos != totalTestSize, "decompressed data : wrong size (%u != %u)",
                    (unsigned)outBuff.pos, (unsigned)totalTestSize);
            CHECK (inBuff.pos != cSize, "compressed data should be fully read")
            {   U64 const crcDest = XXH64(dstBuffer, totalTestSize, 0);
                if (crcDest!=crcOrig) findDiff(copyBuffer, dstBuffer, totalTestSize);
                CHECK (crcDest!=crcOrig, "decompressed data corrupted");
        }   }

        /*=====   noisy/erroneous src decompression test   =====*/

        /* add some noise */
        {   U32 const nbNoiseChunks = (FUZ_rand(&lseed) & 7) + 2;
            U32 nn; for (nn=0; nn<nbNoiseChunks; nn++) {
                size_t const randomNoiseSize = FUZ_randomLength(&lseed, maxSampleLog);
                size_t const noiseSize  = MIN((cSize/3) , randomNoiseSize);
                size_t const noiseStart = FUZ_rand(&lseed) % (srcBufferSize - noiseSize);
                size_t const cStart = FUZ_rand(&lseed) % (cSize - noiseSize);
                memcpy(cBuffer+cStart, srcBuffer+noiseStart, noiseSize);
        }   }

        /* try decompression on noisy data */
        CHECK_Z( ZSTD_initDStream(zd_noise) );   /* note : no dictionary */
        {   ZSTD_inBuffer  inBuff = { cBuffer, cSize, 0 };
            ZSTD_outBuffer outBuff= { dstBuffer, dstBufferSize, 0 };
            while (outBuff.pos < dstBufferSize) {
                size_t const randomCSrcSize = FUZ_randomLength(&lseed, maxSampleLog);
                size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
                size_t const adjustedDstSize = MIN(dstBufferSize - outBuff.pos, randomDstSize);
                size_t const adjustedCSrcSize = MIN(cSize - inBuff.pos, randomCSrcSize);
                outBuff.size = outBuff.pos + adjustedDstSize;
                inBuff.size  = inBuff.pos + adjustedCSrcSize;
                {   size_t const decompressError = ZSTD_decompressStream(zd, &outBuff, &inBuff);
                    if (ZSTD_isError(decompressError)) break;   /* error correctly detected */
                    /* No forward progress possible */
                    if (outBuff.pos < outBuff.size && inBuff.pos == cSize) break;
    }   }   }   }
    DISPLAY("\r%u fuzzer tests completed   \n", testNb);

ext/zstd/tests/zstreamtest.c  view on Meta::CPAN

                        /* compress random chunks into randomly sized dst buffers */
                        size_t const randomSrcSize = FUZ_randomLength(&lseed, maxSampleLog);
                        size_t const srcSize = MIN(maxTestSize-totalTestSize, randomSrcSize);
                        size_t const srcStart = FUZ_rand(&lseed) % (srcBufferSize - srcSize);
                        ZSTD_EndDirective const flush = (FUZ_rand(&lseed) & 15) ? ZSTD_e_continue : ZSTD_e_flush;
                        ZSTD_inBuffer inBuff = { srcBuffer+srcStart, srcSize, 0 };
                        int forwardProgress;
                        do {
                            size_t const ipos = inBuff.pos;
                            size_t const opos = outBuff.pos;
                            size_t ret;
                            if (outBuff.pos == outBuff.size) {
                                size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog+1);
                                size_t const dstBuffSize = MIN(cBufferSize - outBuff.pos, randomDstSize);
                                outBuff.size = outBuff.pos + dstBuffSize;
                            }
                            CHECK_Z( ret = ZSTD_compressStream2(zc, &outBuff, &inBuff, flush) );
                            DISPLAYLEVEL(6, "t%u: compress consumed %u bytes (total : %u) ; flush: %u (total : %u) \n",
                                testNb, (unsigned)inBuff.pos, (unsigned)(totalTestSize + inBuff.pos), (unsigned)flush, (unsigned)outBuff.pos);

                            /* We've completed the flush */
                            if (flush == ZSTD_e_flush && ret == 0)
                                break;

                            /* Ensure maximal forward progress for determinism */
                            forwardProgress = (inBuff.pos != ipos) || (outBuff.pos != opos);
                        } while (forwardProgress);
                        assert(inBuff.pos == inBuff.size);

                        XXH64_update(&xxhState, srcBuffer+srcStart, inBuff.pos);
                        memcpy(copyBuffer+totalTestSize, srcBuffer+srcStart, inBuff.pos);
                        totalTestSize += inBuff.pos;
                    }

                    /* final frame epilogue */
                    {   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 - outBuff.pos, randomDstSize);
                            outBuff.size = outBuff.pos + adjustedDstSize;
                            DISPLAYLEVEL(6, "t%u: End-flush into dst buffer of size %u \n", testNb, (unsigned)adjustedDstSize);
                            /* ZSTD_e_end guarantees maximal forward progress */
                            remainingToFlush = ZSTD_compressStream2(zc, &outBuff, &inBuff, ZSTD_e_end);
                            DISPLAYLEVEL(6, "t%u: Total flushed so far : %u bytes \n", testNb, (unsigned)outBuff.pos);
                            CHECK( ZSTD_isError(remainingToFlush),
                                "ZSTD_compressStream2 w/ ZSTD_e_end error : %s",
                                ZSTD_getErrorName(remainingToFlush) );
                    }   }
                    crcOrig = XXH64_digest(&xxhState);
                }
                cSize = outBuff.pos;
                compressedCrcs[iter] = XXH64(cBuffer, cSize, 0);
                DISPLAYLEVEL(5, "Frame completed : %zu bytes \n", cSize);
            }
            CHECK(!(compressedCrcs[0] == compressedCrcs[1]), "Compression is not deterministic!");
        }

        CHECK(badParameters(zc, savedParams), "CCtx params are wrong");

        /* multi - fragments decompression test */
        if (FUZ_rand(&lseed) & 1) {
            CHECK_Z(ZSTD_DCtx_reset(zd, ZSTD_reset_session_and_parameters));
        }
        if (!dictSize /* don't reset if dictionary : could be different */ && (FUZ_rand(&lseed) & 1)) {
            DISPLAYLEVEL(5, "resetting DCtx (dict:%p) \n", (void const*)dict);
            CHECK_Z( ZSTD_resetDStream(zd) );
        } else {
            if (dictSize)
                DISPLAYLEVEL(5, "using dictionary of size %zu \n", dictSize);
            CHECK_Z( ZSTD_initDStream_usingDict(zd, dict, dictSize) );
        }
        if (FUZ_rand(&lseed) & 1) {
            CHECK_Z(ZSTD_DCtx_setParameter(zd, ZSTD_d_disableHuffmanAssembly, FUZ_rand(&lseed) & 1));
        }
        {   size_t decompressionResult = 1;
            ZSTD_inBuffer  inBuff = { cBuffer, cSize, 0 };
            ZSTD_outBuffer outBuff= { dstBuffer, dstBufferSize, 0 };
            for (totalGenSize = 0 ; decompressionResult ; ) {
                size_t const readCSrcSize = FUZ_randomLength(&lseed, maxSampleLog);
                size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
                size_t const dstBuffSize = MIN(dstBufferSize - totalGenSize, randomDstSize);
                inBuff.size = inBuff.pos + readCSrcSize;
                outBuff.size = outBuff.pos + dstBuffSize;
                DISPLAYLEVEL(6, "decompression presented %u new bytes (pos:%u/%u)\n",
                                (unsigned)readCSrcSize, (unsigned)inBuff.pos, (unsigned)cSize);
                decompressionResult = ZSTD_decompressStream(zd, &outBuff, &inBuff);
                DISPLAYLEVEL(6, "so far: consumed = %u, produced = %u \n",
                                (unsigned)inBuff.pos, (unsigned)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));
                CHECK (inBuff.pos > cSize, "ZSTD_decompressStream consumes too much input : %u > %u ", (unsigned)inBuff.pos, (unsigned)cSize);
            }
            CHECK (inBuff.pos != cSize, "compressed data should be fully read (%u != %u)", (unsigned)inBuff.pos, (unsigned)cSize);
            CHECK (outBuff.pos != totalTestSize, "decompressed data : wrong size (%u != %u)", (unsigned)outBuff.pos, (unsigned)totalTestSize);
            {   U64 const crcDest = XXH64(dstBuffer, totalTestSize, 0);
                if (crcDest!=crcOrig) findDiff(copyBuffer, dstBuffer, totalTestSize);
                CHECK (crcDest!=crcOrig, "decompressed data corrupted");
        }   }

        /*=====   noisy/erroneous src decompression test   =====*/

        /* add some noise */
        {   U32 const nbNoiseChunks = (FUZ_rand(&lseed) & 7) + 2;
            U32 nn; for (nn=0; nn<nbNoiseChunks; nn++) {
                size_t const randomNoiseSize = FUZ_randomLength(&lseed, maxSampleLog);
                size_t const noiseSize  = MIN((cSize/3) , randomNoiseSize);
                size_t const noiseStart = FUZ_rand(&lseed) % (srcBufferSize - noiseSize);
                size_t const cStart = FUZ_rand(&lseed) % (cSize - noiseSize);
                memcpy(cBuffer+cStart, srcBuffer+noiseStart, noiseSize);
        }   }

        /* try decompression on noisy data */
        if (FUZ_rand(&lseed) & 1) {
            CHECK_Z(ZSTD_DCtx_reset(zd_noise, ZSTD_reset_session_and_parameters));
        } else {
            CHECK_Z(ZSTD_DCtx_reset(zd_noise, ZSTD_reset_session_only));
        }



( run in 0.839 second using v1.01-cache-2.11-cpan-364913b4093 )