Revision 07eec0fc test/hs/Test/Ganeti/Locking/Allocation.hs
b/test/hs/Test/Ganeti/Locking/Allocation.hs | ||
---|---|---|
80 | 80 |
|
81 | 81 |
{- |
82 | 82 |
|
83 |
All states of a LockAllocation can be obtained by starting from the
|
|
84 |
empty allocation, and sequentially requesting (successfully or not)
|
|
85 |
lock updates. So we first define what arbitrary updates sequences are.
|
|
83 |
All states of a LockAllocation every available outside the
|
|
84 |
Ganeti.Locking.Allocation module must be constructed by starting
|
|
85 |
with emptyAllocation and applying the exported functions.
|
|
86 | 86 |
|
87 | 87 |
-} |
88 | 88 |
|
... | ... | |
92 | 92 |
instance Arbitrary a => Arbitrary (LockRequest a) where |
93 | 93 |
arbitrary = LockRequest <$> arbitrary <*> genMaybe arbitrary |
94 | 94 |
|
95 |
data UpdateRequest a b = UpdateRequest a [LockRequest b] deriving Show |
|
95 |
data UpdateRequest b a = UpdateRequest b [LockRequest a] |
|
96 |
| IntersectRequest b [a] |
|
97 |
| FreeLockRequest b |
|
98 |
deriving Show |
|
96 | 99 |
|
97 | 100 |
instance (Arbitrary a, Arbitrary b) => Arbitrary (UpdateRequest a b) where |
98 |
arbitrary = UpdateRequest <$> arbitrary <*> arbitrary |
|
99 |
|
|
100 |
-- | Fold a sequence of update requests; all allocations can be obtained in |
|
101 |
-- this way, starting from the empty allocation. |
|
101 |
arbitrary = |
|
102 |
frequency [ (4, UpdateRequest <$> arbitrary <*> (choose (1, 4) >>= vector)) |
|
103 |
, (2, IntersectRequest <$> arbitrary |
|
104 |
<*> (choose (1, 4) >>= vector)) |
|
105 |
, (1, FreeLockRequest <$> arbitrary) |
|
106 |
] |
|
107 |
|
|
108 |
-- | Transform an UpdateRequest into the corresponding state transformer. |
|
109 |
asAllocTrans :: (Lock a, Ord b, Show b) |
|
110 |
=> LockAllocation a b -> UpdateRequest b a -> LockAllocation a b |
|
111 |
asAllocTrans state (UpdateRequest owner updates) = |
|
112 |
fst $ updateLocks owner updates state |
|
113 |
asAllocTrans state (IntersectRequest owner locks) = |
|
114 |
intersectLocks owner locks state |
|
115 |
asAllocTrans state (FreeLockRequest owner) = freeLocks state owner |
|
116 |
|
|
117 |
-- | Fold a sequence of requests to transform a lock allocation onto the empty |
|
118 |
-- allocation. As we consider all exported LockAllocation transformers, any |
|
119 |
-- LockAllocation definable is obtained in this way. |
|
102 | 120 |
foldUpdates :: (Lock a, Ord b, Show b) |
103 |
=> LockAllocation a b -> [UpdateRequest b a] -> LockAllocation a b |
|
104 |
foldUpdates = foldl (\s (UpdateRequest owner updates) -> |
|
105 |
fst $ updateLocks owner updates s) |
|
121 |
=> [UpdateRequest b a] -> LockAllocation a b |
|
122 |
foldUpdates = foldl asAllocTrans emptyAllocation |
|
106 | 123 |
|
107 | 124 |
instance (Arbitrary a, Lock a, Arbitrary b, Ord b, Show b) |
108 | 125 |
=> Arbitrary (LockAllocation a b) where |
109 |
arbitrary = foldUpdates emptyAllocation <$> arbitrary
|
|
126 |
arbitrary = foldUpdates <$> (choose (0, 8) >>= vector)
|
|
110 | 127 |
|
111 | 128 |
-- | Basic property of locking: the exclusive locks of one user |
112 | 129 |
-- are disjoint from any locks of any other user. |
Also available in: Unified diff