]> git.rkrishnan.org Git - tahoe-lafs/zfec.git/blob - zfec/haskell/test/FECTest.hs
stick a .gitignore file
[tahoe-lafs/zfec.git] / zfec / haskell / test / FECTest.hs
1 module Main where
2
3 import qualified Data.ByteString as B
4 import qualified Codec.FEC as FEC
5 import System.IO (withFile, IOMode(..))
6 import System.Random
7 import Data.List (sortBy)
8
9 import Test.QuickCheck
10
11 -- | Return true if the given @k@ and @n@ values are valid
12 isValidConfig :: Int -> Int -> Bool
13 isValidConfig k n
14   | k >= n = False
15   | k < 1 = False
16   | n < 1 = False
17   | otherwise = True
18
19 randomTake :: Int -> Int -> [a] -> [a]
20 randomTake seed n values = map snd $ take n sortedValues where
21   sortedValues = sortBy (\a b -> compare (fst a) (fst b)) taggedValues
22   taggedValues = zip rnds values
23   rnds :: [Float]
24   rnds = randoms gen
25   gen = mkStdGen seed
26
27 testFEC k n len seed = FEC.decode fec someTaggedBlocks == origBlocks where
28   origBlocks = map (\i -> B.replicate len $ fromIntegral i) [0..(k - 1)]
29   fec = FEC.fec k n
30   secondaryBlocks = FEC.encode fec origBlocks
31   taggedBlocks = zip [0..] (origBlocks ++ secondaryBlocks)
32   someTaggedBlocks = randomTake seed k taggedBlocks
33
34 prop_FEC :: Int -> Int -> Int -> Int -> Property
35 prop_FEC k n len seed =
36   isValidConfig k n && n < 256 && len < 1024 ==> testFEC k n len seed
37
38 checkDivide :: Int -> IO ()
39 checkDivide n = do
40   let input = B.replicate 1024 65
41   parts <- FEC.secureDivide n input
42   if FEC.secureCombine parts == input
43      then return ()
44      else fail "checkDivide failed"
45
46 checkEnFEC :: Int -> IO ()
47 checkEnFEC len = do
48   testdata <- withFile "/dev/urandom" ReadMode (\handle -> B.hGet handle len)
49   let [a, b, c, d, e] = FEC.enFEC 3 5 testdata
50   if FEC.deFEC 3 5 [b, e, d] == testdata
51      then return ()
52      else fail "deFEC failure"
53
54 main = do
55   mapM_ (check (defaultConfig { configMaxTest = 1000, configMaxFail = 10000 })) [prop_FEC]
56   mapM_ checkDivide [1, 2, 3, 4, 10]
57   mapM_ checkEnFEC [1, 2, 3, 4, 5, 1024 * 1024]