2019-04-10 19:45:58 +03:00
|
|
|
-- Copyright (c) 2014-present, Facebook, Inc.
|
|
|
|
-- All rights reserved.
|
|
|
|
--
|
|
|
|
-- This source code is distributed under the terms of a BSD license,
|
|
|
|
-- found in the LICENSE file.
|
|
|
|
|
2020-01-10 12:31:35 +03:00
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
2019-04-10 19:45:58 +03:00
|
|
|
module WriteTests (tests) where
|
|
|
|
|
|
|
|
import Test.HUnit
|
|
|
|
|
|
|
|
import Data.Foldable
|
|
|
|
|
|
|
|
import Haxl.Core
|
|
|
|
import Haxl.Prelude as Haxl
|
|
|
|
|
|
|
|
newtype SimpleWrite = SimpleWrite Text
|
|
|
|
deriving (Eq, Show)
|
|
|
|
|
2019-10-08 21:08:34 +03:00
|
|
|
doInnerWrite :: GenHaxl u SimpleWrite Int
|
|
|
|
doInnerWrite = do
|
2019-04-10 19:45:58 +03:00
|
|
|
tellWrite $ SimpleWrite "inner"
|
|
|
|
return 0
|
|
|
|
|
|
|
|
doOuterWrite :: GenHaxl u SimpleWrite Int
|
|
|
|
doOuterWrite = do
|
|
|
|
tellWrite $ SimpleWrite "outer1"
|
|
|
|
|
2019-10-08 21:08:34 +03:00
|
|
|
doWriteMemo <- newMemoWith doInnerWrite
|
2019-04-10 19:45:58 +03:00
|
|
|
let doMemoizedWrite = runMemo doWriteMemo
|
|
|
|
_ <- doMemoizedWrite
|
|
|
|
_ <- doMemoizedWrite
|
|
|
|
|
|
|
|
tellWrite $ SimpleWrite "outer2"
|
|
|
|
|
|
|
|
return 1
|
|
|
|
|
2019-10-08 21:08:34 +03:00
|
|
|
doNonMemoWrites :: GenHaxl u SimpleWrite Int
|
|
|
|
doNonMemoWrites = do
|
|
|
|
tellWrite $ SimpleWrite "inner"
|
|
|
|
tellWriteNoMemo $ SimpleWrite "inner not memo"
|
|
|
|
return 0
|
|
|
|
|
2019-04-10 19:45:58 +03:00
|
|
|
writeSoundness :: Test
|
|
|
|
writeSoundness = TestCase $ do
|
|
|
|
let numReps = 4
|
|
|
|
|
|
|
|
-- do writes without memoization
|
|
|
|
env1 <- emptyEnv ()
|
|
|
|
(allRes, allWrites) <- runHaxlWithWrites env1 $
|
2019-10-08 21:08:34 +03:00
|
|
|
Haxl.sequence (replicate numReps doInnerWrite)
|
2019-04-10 19:45:58 +03:00
|
|
|
|
|
|
|
assertBool "Write Soundness 1" $
|
|
|
|
allWrites == replicate numReps (SimpleWrite "inner")
|
|
|
|
assertBool "Write Soundness 2" $ allRes == replicate numReps 0
|
|
|
|
|
|
|
|
-- do writes with memoization
|
|
|
|
env2 <- emptyEnv ()
|
|
|
|
|
|
|
|
(memoRes, memoWrites) <- runHaxlWithWrites env2 $ do
|
2019-10-08 21:08:34 +03:00
|
|
|
doWriteMemo <- newMemoWith doInnerWrite
|
2019-04-10 19:45:58 +03:00
|
|
|
let memoizedWrite = runMemo doWriteMemo
|
|
|
|
|
|
|
|
Haxl.sequence (replicate numReps memoizedWrite)
|
|
|
|
|
|
|
|
assertBool "Write Soundness 3" $
|
|
|
|
memoWrites == replicate numReps (SimpleWrite "inner")
|
|
|
|
assertBool "Write Soundness 4" $ memoRes == replicate numReps 0
|
|
|
|
|
|
|
|
-- do writes with interleaved memo
|
|
|
|
env3 <- emptyEnv ()
|
|
|
|
|
|
|
|
(ilRes, ilWrites) <- runHaxlWithWrites env3 $ do
|
2019-10-08 21:08:34 +03:00
|
|
|
doWriteMemo <- newMemoWith doInnerWrite
|
2019-04-10 19:45:58 +03:00
|
|
|
let memoizedWrite = runMemo doWriteMemo
|
|
|
|
|
2019-10-08 21:08:34 +03:00
|
|
|
Haxl.sequence $ replicate numReps (doInnerWrite *> memoizedWrite)
|
2019-04-10 19:45:58 +03:00
|
|
|
|
|
|
|
assertBool "Write Soundness 5" $
|
|
|
|
ilWrites == replicate (2*numReps) (SimpleWrite "inner")
|
|
|
|
assertBool "Write Soundness 6" $ ilRes == replicate numReps 0
|
|
|
|
|
|
|
|
-- do writes with nested memo
|
|
|
|
env4 <- emptyEnv ()
|
|
|
|
|
|
|
|
(nestRes, nestWrites) <- runHaxlWithWrites env4 $ do
|
|
|
|
doWriteMemo' <- newMemoWith doOuterWrite
|
|
|
|
let memoizedWrite' = runMemo doWriteMemo'
|
|
|
|
|
|
|
|
Haxl.sequence (replicate numReps memoizedWrite')
|
|
|
|
|
|
|
|
let expWrites =
|
|
|
|
[ SimpleWrite "outer1"
|
|
|
|
, SimpleWrite "inner"
|
|
|
|
, SimpleWrite "inner"
|
|
|
|
, SimpleWrite "outer2"
|
|
|
|
]
|
|
|
|
assertBool "Write Soundness 7" $
|
|
|
|
nestWrites == fold (replicate numReps expWrites)
|
|
|
|
assertBool "Write Soundness 8" $ nestRes == replicate numReps 1
|
|
|
|
|
2019-10-08 21:08:34 +03:00
|
|
|
-- do both kinds of writes without memoization
|
|
|
|
env5 <- emptyEnv ()
|
|
|
|
(allRes, allWrites) <- runHaxlWithWrites env5 $
|
|
|
|
Haxl.sequence (replicate numReps doNonMemoWrites)
|
|
|
|
|
|
|
|
assertBool "Write Soundness 9" $
|
|
|
|
allWrites == replicate numReps (SimpleWrite "inner") ++
|
|
|
|
replicate numReps (SimpleWrite "inner not memo")
|
|
|
|
assertBool "Write Soundness 10" $ allRes == replicate numReps 0
|
|
|
|
|
|
|
|
-- do both kinds of writes with memoization
|
|
|
|
env6 <- emptyEnv ()
|
|
|
|
|
|
|
|
(memoRes, memoWrites) <- runHaxlWithWrites env6 $ do
|
|
|
|
doWriteMemo <- newMemoWith doNonMemoWrites
|
|
|
|
let memoizedWrite = runMemo doWriteMemo
|
|
|
|
|
|
|
|
Haxl.sequence (replicate numReps memoizedWrite)
|
|
|
|
|
|
|
|
-- "inner not memo" only appears once in this test
|
|
|
|
assertBool "Write Soundness 11" $
|
|
|
|
memoWrites == replicate numReps (SimpleWrite "inner") ++
|
|
|
|
[SimpleWrite "inner not memo"]
|
|
|
|
assertBool "Write Soundness 12" $ memoRes == replicate numReps 0
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-04-10 19:45:58 +03:00
|
|
|
tests = TestList [TestLabel "Write Soundness" writeSoundness]
|