Skip to content

Commit 77b8771

Browse files
committed
Add tests for the concatenated gzip streams
1 parent a13fa9b commit 77b8771

File tree

2 files changed

+76
-5
lines changed

2 files changed

+76
-5
lines changed

test/Test.hs

Lines changed: 75 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,16 @@ import Prelude hiding (catch)
2828
#endif
2929

3030

31-
3231
main :: IO ()
3332
main = defaultMain $
3433
testGroup "zlib tests" [
3534
testGroup "property tests" [
3635
testProperty "decompress . compress = id (standard)" prop_decompress_after_compress,
3736
testProperty "decompress . compress = id (Zlib -> GZipOrZLib)" prop_gziporzlib1,
3837
testProperty "decompress . compress = id (GZip -> GZipOrZlib)" prop_gziporzlib2,
38+
testProperty "concatenated gzip members" prop_gzip_concat,
39+
testProperty "multiple gzip members, boundaries (all 2-chunks)" prop_multiple_members_boundary2,
40+
testProperty "multiple gzip members, boundaries (all 3-chunks)" prop_multiple_members_boundary3,
3941
testProperty "prefixes of valid stream detected as truncated" prop_truncated
4042
],
4143
testGroup "unit tests" [
@@ -46,6 +48,7 @@ main = defaultMain $
4648
testCase "dectect inflate with wrong dict" test_wrong_dictionary,
4749
testCase "dectect inflate with right dict" test_right_dictionary,
4850
testCase "handle trailing data" test_trailing_data,
51+
testCase "multiple gzip members" test_multiple_members,
4952
testCase "check small input chunks" test_small_chunks,
5053
testCase "check exception raised" test_exception
5154
]
@@ -83,6 +86,42 @@ prop_gziporzlib2 cp dp =
8386
decompressBufferSize dp > 0 && compressBufferSize cp > 0 ==>
8487
liftM2 (==) (decompress gzipOrZlibFormat dp . compress gzipFormat cp) id
8588

89+
prop_gzip_concat :: CompressParams
90+
-> DecompressParams
91+
-> BL.ByteString
92+
-> Property
93+
prop_gzip_concat cp dp input =
94+
decompressWindowBits dp >= compressWindowBits cp &&
95+
decompressBufferSize dp > 0 && compressBufferSize cp > 0 ==>
96+
let catComp = BL.concat (replicate 5 (compress gzipFormat cp input))
97+
compCat = compress gzipFormat cp (BL.concat (replicate 5 input))
98+
99+
in decompress gzipFormat dp { decompressAllMembers = True } catComp
100+
== decompress gzipFormat dp { decompressAllMembers = True } compCat
101+
102+
prop_multiple_members_boundary2 :: Property
103+
prop_multiple_members_boundary2 =
104+
forAll shortStrings $ \bs ->
105+
all (\c -> decomp c == BL.append bs bs)
106+
(twoChunkSplits (comp bs `BL.append` comp bs))
107+
where
108+
comp = compress gzipFormat defaultCompressParams
109+
decomp = decompress gzipFormat defaultDecompressParams
110+
111+
shortStrings = fmap BL.pack $ listOf arbitrary
112+
113+
prop_multiple_members_boundary3 :: Property
114+
prop_multiple_members_boundary3 =
115+
forAll shortStrings $ \bs ->
116+
all (\c -> decomp c == BL.append bs bs)
117+
(threeChunkSplits (comp bs `BL.append` comp bs))
118+
where
119+
comp = compress gzipFormat defaultCompressParams
120+
decomp = decompress gzipFormat defaultDecompressParams
121+
122+
shortStrings = sized $ \sz -> resize (sz `div` 10) $
123+
fmap BL.pack $ listOf arbitrary
124+
86125
prop_truncated :: Format -> Property
87126
prop_truncated format =
88127
forAll shortStrings $ \bs ->
@@ -170,12 +209,27 @@ test_right_dictionary = do
170209
test_trailing_data :: Assertion
171210
test_trailing_data =
172211
withSampleData "two-files.gz" $ \hnd -> do
173-
let decomp = decompressIO gzipFormat defaultDecompressParams
212+
let decomp = decompressIO gzipFormat defaultDecompressParams {
213+
decompressAllMembers = False
214+
}
174215
chunks <- assertDecompressOkChunks hnd decomp
175216
case chunks of
176217
[chunk] -> chunk @?= BS.Char8.pack "Test 1"
177218
_ -> assertFailure "expected single chunk"
178219

220+
test_multiple_members :: Assertion
221+
test_multiple_members =
222+
withSampleData "two-files.gz" $ \hnd -> do
223+
let decomp = decompressIO gzipFormat defaultDecompressParams {
224+
decompressAllMembers = True
225+
}
226+
chunks <- assertDecompressOkChunks hnd decomp
227+
case chunks of
228+
[chunk1,
229+
chunk2] -> do chunk1 @?= BS.Char8.pack "Test 1"
230+
chunk2 @?= BS.Char8.pack "Test 2"
231+
_ -> assertFailure "expected two chunks"
232+
179233
test_small_chunks :: Assertion
180234
test_small_chunks = do
181235
uncompressedFile <- readSampleData "not-gzip"
@@ -190,9 +244,6 @@ test_small_chunks = do
190244
compressedFile <- readSampleData "hello.gz"
191245
(GZip.decompress . smallChunks) compressedFile @?= GZip.decompress compressedFile
192246

193-
where
194-
smallChunks :: BL.ByteString -> BL.ByteString
195-
smallChunks = BL.fromChunks . map (\c -> BS.pack [c]) . BL.unpack
196247

197248
test_exception :: Assertion
198249
test_exception =
@@ -212,6 +263,25 @@ toStrict = BL.toStrict
212263
toStrict = BS.concat . BL.toChunks
213264
#endif
214265

266+
-----------------------
267+
-- Chunk boundary utils
268+
269+
smallChunks :: BL.ByteString -> BL.ByteString
270+
smallChunks = BL.fromChunks . map (\c -> BS.pack [c]) . BL.unpack
271+
272+
twoChunkSplits :: BL.ByteString -> [BL.ByteString]
273+
twoChunkSplits bs = zipWith (\a b -> BL.fromChunks [a,b]) (BS.inits sbs) (BS.tails sbs)
274+
where
275+
sbs = toStrict bs
276+
277+
threeChunkSplits :: BL.ByteString -> [BL.ByteString]
278+
threeChunkSplits bs =
279+
[ BL.fromChunks [a,b,c]
280+
| (a,x) <- zip (BS.inits sbs) (BS.tails sbs)
281+
, (b,c) <- zip (BS.inits x) (BS.tails x) ]
282+
where
283+
sbs = toStrict bs
284+
215285
--------------
216286
-- HUnit Utils
217287

test/Test/Codec/Compression/Zlib/Internal.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,5 @@ instance Arbitrary DecompressParams where
3333
arbitrary = return DecompressParams `ap` arbitrary
3434
`ap` arbitraryBufferSize
3535
`ap` return Nothing
36+
`ap` arbitrary
3637

0 commit comments

Comments
 (0)