Updated unsynchronized buffers tests
authorYann Collet <yann.collet.73@gmail.com>
Tue, 4 Nov 2014 09:04:37 +0000 (10:04 +0100)
committerYann Collet <yann.collet.73@gmail.com>
Tue, 4 Nov 2014 09:04:37 +0000 (10:04 +0100)
examples/HCStreaming_ringBuffer.c
examples/blockStreaming_ringBuffer.c
programs/fuzzer.c

index afe77ae..dfa2670 100644 (file)
@@ -30,7 +30,7 @@
 enum {
     MESSAGE_MAX_BYTES   = 1024,
     RING_BUFFER_BYTES   = 1024 * 8 + MESSAGE_MAX_BYTES,
-    DEC_BUFFER_BYTES    = RING_BUFFER_BYTES + MESSAGE_MAX_BYTES
+    DEC_BUFFER_BYTES    = RING_BUFFER_BYTES + MESSAGE_MAX_BYTES   // Intentionally larger to test unsynchronized ring buffers
 };
 
 
index eda721f..beb5e66 100644 (file)
@@ -27,7 +27,7 @@
 enum {
     MESSAGE_MAX_BYTES   = 1024,
     RING_BUFFER_BYTES   = 1024 * 8 + MESSAGE_MAX_BYTES,
-    DICT_BYTES          = 65536,
+    DECODE_RING_BUFFER  = RING_BUFFER_BYTES + MESSAGE_MAX_BYTES   // Intentionally larger, to test unsynchronized ring buffers
 };
 
 
@@ -83,7 +83,7 @@ void test_compress(FILE* outFp, FILE* inpFp)
 
 void test_decompress(FILE* outFp, FILE* inpFp)
 {
-    static char decBuf[RING_BUFFER_BYTES];
+    static char decBuf[DECODE_RING_BUFFER];
     int   decOffset    = 0;
     LZ4_streamDecode_t lz4StreamDecode_body = { 0 };
     LZ4_streamDecode_t* lz4StreamDecode = &lz4StreamDecode_body;
@@ -109,7 +109,7 @@ void test_decompress(FILE* outFp, FILE* inpFp)
             write_bin(outFp, decPtr, decBytes);
 
             // Wraparound the ringbuffer offset
-            if(decOffset >= RING_BUFFER_BYTES - MESSAGE_MAX_BYTES) decOffset = 0;
+            if(decOffset >= DECODE_RING_BUFFER - MESSAGE_MAX_BYTES) decOffset = 0;
         }
     }
 }
index 3a2ec34..17f7c43 100644 (file)
@@ -663,8 +663,8 @@ _output_error:
 }
 
 
-#define testInputSize (128 KB)
-#define testCompressedSize (64 KB)
+#define testInputSize (192 KB)
+#define testCompressedSize (128 KB)
 #define ringBufferSize (8 KB)
 
 static void FUZ_unitTests(void)
@@ -786,15 +786,15 @@ static void FUZ_unitTests(void)
         FUZ_CHECKTEST(result==0, "LZ4_compressHC_limitedOutput_continue() dictionary compression failed : result = %i", result);
 
         result = LZ4_decompress_safe_usingDict(testCompressed, testVerify, result, testCompressedSize, testInput, 64 KB);
-        FUZ_CHECKTEST(result!=(int)testCompressedSize, "LZ4_decompress_safe() dictionary decompression failed");
+        FUZ_CHECKTEST(result!=(int)testCompressedSize, "LZ4_decompress_safe() simple dictionary decompression test failed");
         crcNew = XXH64(testVerify, testCompressedSize, 0);
-        FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe() dictionary decompression corruption");
+        FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe() simple dictionary decompression test : corruption");
 
         // multiple HC compression test with dictionary
         {
             int result1, result2;
             int segSize = testCompressedSize / 2;
-            crcOrig = XXH64(testInput + segSize, 64 KB, 0);
+            crcOrig = XXH64(testInput + segSize, testCompressedSize, 0);
             LZ4_resetStreamHC(&sHC, 0);
             LZ4_loadDictHC(&sHC, testInput, segSize);
             result1 = LZ4_compressHC_limitedOutput_continue(&sHC, testInput + segSize, testCompressed, segSize, segSize -1);
@@ -915,6 +915,48 @@ static void FUZ_unitTests(void)
             }
         }
 
+        // small decoder-side ring buffer test
+        {
+            XXH64_state_t xxhOrig;
+            XXH64_state_t xxhNew;
+            LZ4_streamDecode_t decodeState;
+            const U32 maxMessageSizeLog = 10;
+            const U32 maxMessageSizeMask = (1<<maxMessageSizeLog) - 1;
+            U32 messageSize = (FUZ_rand(&randState) & maxMessageSizeMask) + 1;
+            U32 totalMessageSize = 0;
+            U32 iNext = 0;
+            U32 dNext = 0;
+            const U32 dBufferSize = 64 KB + maxMessageSizeMask;
+
+            XXH64_reset(&xxhOrig, 0);
+            XXH64_reset(&xxhNew, 0);
+            LZ4_resetStreamHC(&sHC, 0);
+            LZ4_setStreamDecode(&decodeState, NULL, 0);
+
+            while (totalMessageSize < 9 MB)
+            {
+                XXH64_update(&xxhOrig, testInput + iNext, messageSize);
+                crcOrig = XXH64_digest(&xxhOrig);
+
+                result = LZ4_compressHC_limitedOutput_continue(&sHC, testInput + iNext, testCompressed, messageSize, testCompressedSize-ringBufferSize);
+                FUZ_CHECKTEST(result==0, "LZ4_compressHC_limitedOutput_continue() compression failed");
+
+                result = LZ4_decompress_safe_continue(&decodeState, testCompressed, testVerify + dNext, result, messageSize);
+                FUZ_CHECKTEST(result!=(int)messageSize, "ringBuffer : LZ4_decompress_safe() test failed");
+
+                XXH64_update(&xxhNew, testVerify + dNext, messageSize);
+                crcNew = crcOrig = XXH64_digest(&xxhNew);
+                FUZ_CHECKTEST(crcOrig!=crcNew, "LZ4_decompress_safe() decompression corruption");
+
+                // prepare next message
+                dNext += messageSize;
+                totalMessageSize += messageSize;
+                messageSize = (FUZ_rand(&randState) & maxMessageSizeMask) + 1;
+                iNext = (FUZ_rand(&randState) & 65535);
+                if (dNext + messageSize > dBufferSize) dNext = 0;
+            }
+        }
+
         // long stream test ; Warning : very long test !
         if (1)
         {
@@ -939,6 +981,9 @@ static void FUZ_unitTests(void)
 
                 FUZ_displayUpdate((U32)(totalTestDone >> 20));
 
+                if (testStart == oldStart + oldSize)   // Corner case not covered by this test (LZ4_decompress_safe_usingDict() limitation)
+                    testStart++;
+
                 XXH64_update(&crcOrigState, testInput + testStart, testSize);
                 crcOrig = XXH64_digest(&crcOrigState);