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