summaryrefslogtreecommitdiff
path: root/testsuite/tests/ghc-regress/lib/Concurrent/SampleVar001.hs
blob: def86c5d54ddd0aafc0e4472f5cef84363d4f87d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
-------------------------------------------------------------------------------
-- Module      :  SampleVarTest
-------------------------------------------------------------------------------

import Debug.QuickCheck
import System.IO.Unsafe
import Control.Concurrent
import Control.Concurrent.SampleVar
import Control.Monad


data Action = NewEmptySampleVar | NewSampleVar Int | EmptySampleVar 
	    | ReadSampleVar | WriteSampleVar Int | IsEmptySampleVar 
	    | ReturnInt Int | ReturnBool Bool
  deriving (Eq,Show)


main = do 
  t <- myThreadId
  forkIO (threadDelay 1000000 >> killThread t)
	-- just in case we deadlock
  testSampleVar

testSampleVar :: IO ()
testSampleVar = do
  quickCheck prop_NewEIs_NewERet
  quickCheck prop_NewIs_NewRet
  quickCheck prop_NewRead_NewRet
  quickCheck prop_NewEWriteRead_NewERet
  quickCheck prop_WriteEmpty_Empty
  quickCheck prop_WriteRead_Ret



perform :: [Action] -> IO ([Bool],[Int])
perform [] = return ([],[])

perform (a:as) =
  case a of
    ReturnInt v	      -> liftM (\(b,l) -> (b,v:l)) (perform as)
    ReturnBool v      -> liftM (\(b,l) -> (v:b,l)) (perform as)
    NewEmptySampleVar -> newEmptySampleVar >>= \sv -> perform' sv as
    NewSampleVar n    -> newSampleVar n >>= \sv -> perform' sv as    


perform' :: SampleVar Int -> [Action] -> IO ([Bool],[Int])
perform' _ [] = return ([],[])

perform' sv (a:as) =
  case a of
    ReturnInt v	      -> liftM (\(b,l) -> (b,v:l)) (perform' sv as)
    ReturnBool v      -> liftM (\(b,l) -> (v:b,l)) (perform' sv as)
    EmptySampleVar    -> emptySampleVar sv >> perform' sv as
    ReadSampleVar     -> liftM2 (\v (b,l) -> (b,v:l)) (readSampleVar sv) 
			        (perform' sv as)
    WriteSampleVar n  -> writeSampleVar sv n >> perform' sv as
    IsEmptySampleVar  -> liftM2 (\v (b,l) -> (v:b,l)) (isEmptySampleVar sv)
				(perform' sv as)


actions :: Gen [Action]
actions = do
  oneof [liftM (NewEmptySampleVar:) (actions' True),
	 liftM2 (:) (liftM NewSampleVar arbitrary) (actions' False)] 


actions' :: Bool -> Gen [Action]
actions' empty =
  oneof ([return [],
	  liftM (IsEmptySampleVar:) (actions' empty),
	  liftM (EmptySampleVar:) (actions' True),
	  liftM2 (:) (liftM WriteSampleVar arbitrary) (actions' False)] ++
	  if empty
	     then []
	     else [liftM (ReadSampleVar:) (actions' True)])  


(=^) :: [Action] -> [Action] -> Property
c =^ c' =
  forAll (actions' (delta True c))
	 (\suff -> observe c suff == observe c' suff)
  where observe x suff = unsafePerformIO (perform (x++suff))


(^=^) :: [Action] -> [Action] -> Property
c ^=^ c' =
  forAll actions
	 (\pref -> forAll (actions' (delta True (pref++c)))
			  (\suff -> observe c pref suff == 
				      observe c' pref suff))
  where observe x pref suff = unsafePerformIO (perform (pref++x++suff))


delta :: Bool -> [Action] -> Bool
delta b [] = b

delta b (ReturnInt _:as) = delta b as

delta b (ReturnBool _:as) = delta b as

delta _ (NewEmptySampleVar:as) = delta True as

delta _ (NewSampleVar _:as) = delta False as

delta _ (EmptySampleVar:as) = delta True as

delta b (ReadSampleVar:as) = delta (if b
				       then error "read on empty SampleVar"
				       else True) as 
delta _ (WriteSampleVar _:as) = delta False as

delta b (IsEmptySampleVar:as) = delta b as


prop_NewEIs_NewERet = 
  [NewEmptySampleVar,IsEmptySampleVar] =^ [NewEmptySampleVar,ReturnBool True]

prop_NewIs_NewRet n = 
  [NewSampleVar n,IsEmptySampleVar] =^ [NewSampleVar n,ReturnBool False]

prop_NewRead_NewRet n =
  [NewSampleVar n,ReadSampleVar] =^ [NewEmptySampleVar,ReturnInt n]

prop_NewEWriteRead_NewERet n = 
  [NewEmptySampleVar,WriteSampleVar n,ReadSampleVar] =^ 
    [NewEmptySampleVar,ReturnInt n]

prop_WriteEmpty_Empty n = 
  [WriteSampleVar n,EmptySampleVar] ^=^ [EmptySampleVar]

prop_WriteRead_Ret n = 
  [WriteSampleVar n,ReadSampleVar] ^=^ [EmptySampleVar,ReturnInt n]