module Main where import Test.Framework (defaultMain, testGroup, Test) import Test.Framework.Providers.QuickCheck2 (testProperty) import Test.QuickCheck.Monadic (monadicIO, run) import System.Posix.IO import System.Posix.Memory import Control.Monad import Control.Exception (bracket) import Foreign.C.Types import Foreign.Storable import Data.Word psz :: CSize psz = fromIntegral sysconfPageSize -- create an anonymous private mapping of page-size size. withDummyMapping f = do bracket (memoryMap Nothing psz [MemoryProtectionRead,MemoryProtectionWrite] MemoryMapPrivate Nothing 0) (\mem -> memoryUnmap mem psz) f withDevZeroMapping f = withOpenFd "/dev/zero" $ \fd -> bracket (memoryMap Nothing psz [MemoryProtectionRead,MemoryProtectionWrite] MemoryMapPrivate (Just fd) 0) (\mem -> memoryUnmap mem psz) f where withOpenFd filename g = do bracket (openFd filename ReadWrite Nothing defaultFileFlags) closeFd g tests :: [Test] tests = [ testProperty "page-size" $ sysconfPageSize > 0 && sysconfPageSize < (2^(20::Int)) , testGroup "anonymous" $ runTestWithMapping withDummyMapping , testGroup "fd" $ runTestWithMapping withDevZeroMapping ] where runTestWithMapping mapF = [ testProperty "mmap-munmap" $ monadicIO $ run $ mapF $ \_ -> return True , testProperty "madvise" $ monadicIO $ run $ mapF $ \ptr -> memoryAdvise ptr psz MemoryAdviceRandom >> return True , testProperty "msync" $ monadicIO $ run $ mapF $ \ptr -> memorySync ptr psz [MemorySyncAsync] >> return True , testProperty "mlock-munlock" $ monadicIO $ run $ mapF $ \ptr -> do memoryLock ptr psz memoryUnlock ptr psz return True , testProperty "read" $ monadicIO $ run $ mapF $ \ptr -> do res <- forM [0..(sysconfPageSize-1)] $ \off -> do b <- peekElemOff ptr off :: IO Word8 return (b == 0) return $ and res ] main :: IO () main = defaultMain tests