ceilometer-common 0.2.2 → 0.2.3
raw patch · 5 files changed
+635/−7 lines, 5 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Ceilometer.Types: time :: Lens' (Timed value_atbj) Word64
+ Ceilometer.Types: time :: Lens' (Timed value_atc7) Word64
Files
- ceilometer-common.cabal +9/−4
- lib/Ceilometer/Client.hs +6/−3
- tests/Fold.hs +112/−0
- tests/Prisms.hs +74/−0
- tests/SampleData.hs +434/−0
ceilometer-common.cabal view
@@ -1,7 +1,10 @@ name: ceilometer-common-version: 0.2.2-synopsis: Common Haskell types and encoding for ceilometer-description: Provides a set of common types for use with ceilometer related packages.+version: 0.2.3+synopsis: Common Haskell types and encoding for OpenStack Ceilometer+description: This package defines a library with two interfaces: one + for working with the data producers (e.g. the collector for + OpenStack Ceilometer) and one for the consumers (e.g. the + Borel metering and billing system). homepage: https://github.com/anchor/ceilometer-common license: BSD3 license-file: LICENSE@@ -55,7 +58,9 @@ hs-source-dirs: tests,lib main-is: Main.hs-+ other-modules: Fold+ , Prisms+ , SampleData build-depends: base >=4.7 && < 5 , QuickCheck >= 2.7 , bimap >= 0.2
lib/Ceilometer/Client.hs view
@@ -26,7 +26,10 @@ , decodeFold_ -- * Re-exports- , module C+ , module Ceilometer.Fold + , module Ceilometer.Tags+ , module Ceilometer.Types+ , module Vaultaire.Types ) where import Control.Applicative@@ -37,9 +40,9 @@ import Pipes import qualified Pipes.Prelude as P -import Ceilometer.Fold as C+import Ceilometer.Fold import Ceilometer.Tags-import Ceilometer.Types as C+import Ceilometer.Types import Vaultaire.Types
+ tests/Fold.hs view
@@ -0,0 +1,112 @@+{-# OPTIONS_GHC -fno-warn-missing-signatures #-}+module Fold where++import qualified Control.Foldl as L+import qualified Data.Map as M+import Test.Hspec+import Test.Hspec.QuickCheck+import Test.QuickCheck++import Ceilometer.Fold+import Ceilometer.Types++import SampleData++suite :: Spec+suite = do+ -- "Cumulative Pollster" resources+ describe "Folding points for CUMULATIVE resource: CPU" $ do+ it "ok for monotonically decreasing points"+ $ L.fold foldCPU cpuDecreasing `shouldBe` cumulativeDecreasingResult++ it "ok for monotonically increasing points"+ $ L.fold foldCPU cpuIncreasing `shouldBe` cumulativeIncreasingResult++ it "ok for non-monotonic points"+ $ L.fold foldCPU cpuAny `shouldBe` cumulativeAnyResult++ describe "Folding points for CUMULATIVE resource: NeutronRx" $ do+ it "ok for monotonically decreasing points"+ $ L.fold foldNeutronRx neutronRxDecreasing `shouldBe` cumulativeDecreasingResult++ it "ok for monotonically increasing points"+ $ L.fold foldNeutronRx neutronRxIncreasing `shouldBe` cumulativeIncreasingResult++ it "ok for non-monotonic points"+ $ L.fold foldNeutronRx neutronRxAny `shouldBe` cumulativeAnyResult++ describe "Folding points for CUMULATIVE resource: NeutronTx" $ do+ it "ok for monotonically decreasing points"+ $ L.fold foldNeutronTx neutronTxDecreasing `shouldBe` cumulativeDecreasingResult++ it "ok for monotonically increasing points"+ $ L.fold foldNeutronTx neutronTxIncreasing `shouldBe` cumulativeIncreasingResult++ it "ok for non-monotonic points"+ $ L.fold foldNeutronTx neutronTxAny `shouldBe` cumulativeAnyResult++ describe "Folding points for CUMULATIVE resource: DiskWrite" $ do+ it "ok for monotonically decreasing points"+ $ L.fold foldDiskWrite diskWriteDecreasing `shouldBe` cumulativeDecreasingResult++ it "ok for monotonically increasing points"+ $ L.fold foldDiskWrite diskWriteIncreasing `shouldBe` cumulativeIncreasingResult++ it "ok for non-monotonic points"+ $ L.fold foldDiskWrite diskWriteAny `shouldBe` cumulativeAnyResult++ describe "Folding points for CUMULATIVE resource: DiskRead" $ do+ it "ok for monotonically decreasing points"+ $ L.fold foldDiskRead diskReadDecreasing `shouldBe` cumulativeDecreasingResult++ it "ok for monotonically increasing points"+ $ L.fold foldDiskRead diskReadIncreasing `shouldBe` cumulativeIncreasingResult++ it "ok for non-monotonic points"+ $ L.fold foldDiskRead diskReadAny `shouldBe` cumulativeAnyResult++ -- "Gauge Event" resources+ describe "Folding points for EVENT resource: VOLUME" $+ it "ok for example payload"+ $ L.fold foldVolumeAll volumeTimedPDs `shouldBe` volumeTimedPDsResult++ describe "Folding points for EVENT resource: SSD" $+ it "ok for example payload"+ $ L.fold foldSSDAll ssdTimedPDs `shouldBe` ssdTimedPDsResult++ describe "Folding points for EVENT resource: IMAGE" $+ it "ok for example payload"+ $ L.fold foldImageAll imageTimedPDs `shouldBe` imageTimedPDsResult++ describe "Folding points for EVENT resource: SNAPSHOT" $+ it "ok for example payload"+ $ L.fold foldSnapshotAll snapshotTimedPDs `shouldBe` snapshotTimedPDsResult++ -- "Gauge Pollster" resources+ describe "Folding points for POLLSTER resource: INSTANCE FLAVOR" $+ it "ok for example payload"+ $ L.fold (foldInstanceFlavor $ const True) flavorTimedPDs `shouldBe` M.fromList flavorTimedPDsResult++ describe "Filtering instance statuses" $+ prop "is sane" propSafetyInstance++ describe "Folding points for POLLSTER resource: IMAGE POLLSTER" $+ it "ok for example payload"+ $ L.fold foldImagePollster imagePTimedPDs `shouldBe` imagePTimedPDsResult++{- This test no longer applies since we assume no more event after delete+ + describe "Folding points on edge cases:" $+ prop "discards the rest after VOLUME DELETE" $ property $ do+ vs0 <- listOf volumeNonDelete+ vs1 <- listOf volumeNonDelete+ let bomb = PDVolume VolumeAvailable VolumeDelete Start 10+ let xs0 = zipWith Timed [testS..] $ vs0 ++ [bomb]+ let xs1 = zipWith Timed [testS..] $ vs0 ++ [bomb] ++ vs1+ return $ L.fold foldVolumeAll xs0 == L.fold foldVolumeAll xs1+-}++ where foldVolumeAll = foldVolume (testS, testE)+ foldSSDAll = foldSSD (testS, testE)+ foldImageAll = foldImage (testS, testE)+ foldSnapshotAll = foldSnapshot (testS, testE)
+ tests/Prisms.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE RankNTypes #-}+module Prisms where++import Control.Lens hiding (elements)+import Control.Lens.Properties+import Test.Hspec+import Test.Hspec.QuickCheck+import Test.QuickCheck++import Ceilometer.Types+import SampleData++suite :: Spec+suite = do+ -- Optics for raw payloads aren't required to be proper, since we are+ -- ignoring some bits of the serialised format (Word64), depending on+ -- the raw payload type.+ --+ -- They should still satisfy prism identity since that is concerned with+ -- the RHS of the prism only, but they don't need to satisfy the "suffcient"+ -- law.++ -- does what it says it does+ describe "CHECK: prism for RAW payload: " $ do+ prop "obey the identity prism law" $ prismIdentity prCompoundEvent+ prop "obey the identity prism law" $ prismIdentity prCompoundPollster++ describe "CHECK: prism for DECODED PAYLOAD FIELD: " $ do+ prop "ENDPOINT - is a proper prism" $ isPrism pfEndpoint+ prop "VOLUME STATUS - is a proper prism" $ isPrism pfVolumeStatus+ prop "VOLUME VERB - is a proper prism" $ isPrism pfVolumeVerb+ prop "IMAGE STATUS - is a proper prism" $ isPrism pfImageStatus+ prop "IMAGE VERB - is a proper prism" $ isPrism pfImageVerb+ prop "SNAPSHOT STATUS - is a proper prism" $ isPrism pfSnapshotStatus+ prop "SNAPSHOT VERB - is a proper prism" $ isPrism pfSnapshotVerb+ prop "IP STATUS - is a proper prism" $ isPrism pfIPStatus+ prop "IP VERB - is a proper prism" $ isPrism pfIPVerb++ describe "CHECK: prism for DECODED PAYLOAD: " $ do+ prop "VOLUME - is a proper prism" $ isPrism pdVolume+ prop "SSD - is a proper prism" $ isPrism pdSSD+ prop "CPU - is a proper prism" $ isPrism pdCPU+ prop "VCPU - is a proper prism" $ isPrism pdInstanceVCPU+ prop "RAM - is a proper prism" $ isPrism pdInstanceRAM+ prop "DISK - is a proper prism" $ isPrism pdInstanceDisk+ prop "FLAVOR - is a proper prism" $ isPrism $ pdInstanceFlavor testFlavors+ prop "IMAGE - is a proper prism" $ isPrism pdImage+ prop "SNAPSHOT - is a proper prism" $ isPrism pdSnapshot+ prop "IP - is a proper prism" $ isPrism pdIP++ -- what it does is what we expect+ describe "REFINE: prism:" $ do+ it "parses/prints values correct to spec for: VOLUME" $+ shouldAllBe (preview pdVolume . view prCompoundEvent) volumePRs volumePDs++ it "parses/prints values correct to spec for: SSD" $+ shouldAllBe (preview pdSSD . view prCompoundEvent) ssdPRs ssdPDs++ it "parses/prints values correct to spec for: INSTANCE FLAVOR" $+ shouldAllBe (preview (pdInstanceFlavor testFlavors) . view prCompoundPollster) flavorPRs flavorPDs++ it "parses/prints values correct to spec for: IMAGE" $+ shouldAllBe (preview pdImage . view prCompoundEvent) imagePRs imagePDs++ it "parses/prints values correct to spec for: SNAPSHOT" $+ shouldAllBe (preview pdSnapshot . view prCompoundEvent) snapshotPRs snapshotPDs++ it "parses/prints values correct to spec for: IP" $+ shouldAllBe (preview pdIP . view prCompoundEvent) ipPRs ipPDs+ where shouldAllBe f xs ys = map f xs `shouldBe` map Just ys+++prismIdentity :: Eq b => Prism' a b -> b -> Property+prismIdentity l b = property $ preview l (review l b) == Just b
+ tests/SampleData.hs view
@@ -0,0 +1,434 @@+-- This module defines hard-coded sample data+-- for parsing/printing and folding.+--+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeSynonymInstances #-}++{-# OPTIONS -fno-warn-orphans#-}+{-# OPTIONS -fno-warn-missing-signatures #-}++module SampleData where++import Control.Applicative+import qualified Control.Foldl as L+import Control.Lens hiding (elements)+import Control.Monad+import qualified Data.Bimap as BM+import Data.Binary (Word64)+import Data.Bits+import Data.List.Ordered+import Data.Map (Map)+import qualified Data.Map as M+import Data.Maybe+import Data.Word+import Test.QuickCheck+import Test.QuickCheck.Function++import Ceilometer.Fold+import Ceilometer.Types+import Ceilometer.Types.Image (imageVerb)+import Ceilometer.Types.Instance (siphashID)+import Ceilometer.Types.IP (ipVerb)+import Ceilometer.Types.Snapshot (snapshotVerb)+import Ceilometer.Types.Volume (volumeVerb)+++-- Instances (DO NOT DEFNE NEW ONES IN TESTS) ----------------------------------++instance Function PFEndpoint where function = functionShow+instance Function PFVolumeStatus where function = functionShow+instance Function PFVolumeVerb where function = functionShow+instance Function PFImageStatus where function = functionShow+instance Function PFImageVerb where function = functionShow+instance Function PFSnapshotStatus where function = functionShow+instance Function PFSnapshotVerb where function = functionShow+instance Function PFIPStatus where function = functionShow+instance Function PFIPVerb where function = functionShow+instance Function PDCPU where function = functionShow+instance Function PDVolume where function = functionShow+instance Function PDSSD where function = functionShow+instance Function PDImage where function = functionShow+instance Function PDImagePollster where function = functionShow+instance Function PDIP where function = functionShow+instance Function PDSnapshot where function = functionShow+instance Function PDInstanceVCPU where function = functionShow+instance Function PDInstanceRAM where function = functionShow+instance Function PDInstanceDisk where function = functionShow+instance Function PDInstanceFlavor where function = functionShow++instance Arbitrary a => Arbitrary [Timed a] where+ arbitrary = do+ bigNumber <- choose (1, 10000)+ let ts = [1..bigNumber]+ vs <- replicateM (fromIntegral bigNumber) arbitrary+ return $ zipWith Timed ts vs++instance Arbitrary PRSimple where+ arbitrary = PRSimple <$> arbitrary+instance Arbitrary PRCompoundEvent where+ arbitrary = PRCompoundEvent+ <$> arbitrary+ <*> arbitrary+ <*> arbitrary+ <*> arbitrary+instance Arbitrary PRCompoundPollster where+ arbitrary = PRCompoundPollster+ <$> arbitrary+ <*> arbitrary++instance Arbitrary PFEndpoint where arbitrary = arbitraryBoundedEnum+instance Arbitrary PFVolumeVerb where arbitrary = arbitraryBoundedEnum+instance Arbitrary PFVolumeStatus where arbitrary = arbitraryBoundedEnum+instance Arbitrary PFInstanceStatus where arbitrary = arbitraryBoundedEnum+instance Arbitrary PFImageVerb where arbitrary = arbitraryBoundedEnum+instance Arbitrary PFImageStatus where arbitrary = arbitraryBoundedEnum+instance Arbitrary PFSnapshotVerb where arbitrary = arbitraryBoundedEnum+instance Arbitrary PFSnapshotStatus where arbitrary = arbitraryBoundedEnum+instance Arbitrary PFIPVerb where arbitrary = arbitraryBoundedEnum+instance Arbitrary PFIPStatus where arbitrary = arbitraryBoundedEnum+instance Arbitrary PFIPAlloc where arbitrary = arbitraryBoundedEnum+instance Arbitrary PFValueText where arbitrary = elements $ BM.keys testFlavors++instance Arbitrary PDCPU where arbitrary = PDCPU <$> arbitrary+instance Arbitrary PDVolume where arbitrary = PDVolume+ <$> arbitrary+ <*> arbitrary+ <*> arbitrary+ <*> arbitrary+instance Arbitrary PDSSD where arbitrary = PDSSD+ <$> arbitrary+ <*> arbitrary+ <*> arbitrary+ <*> arbitrary+instance Arbitrary PDInstanceVCPU where arbitrary = PDInstanceVCPU+ <$> arbitrary+ <*> arbitrary+instance Arbitrary PDInstanceRAM where arbitrary = PDInstanceRAM+ <$> arbitrary+ <*> arbitrary+instance Arbitrary PDInstanceDisk where arbitrary = PDInstanceDisk+ <$> arbitrary+ <*> arbitrary+instance Arbitrary PDInstanceFlavor where arbitrary = PDInstanceFlavor+ <$> arbitrary+ <*> arbitrary+instance Arbitrary PDImage where arbitrary = PDImage+ <$> arbitrary+ <*> arbitrary+ <*> arbitrary+ <*> arbitrary+instance Arbitrary PDImagePollster where arbitrary = PDImagePollster <$> arbitrary+instance Arbitrary PDSnapshot where arbitrary = PDSnapshot+ <$> arbitrary+ <*> arbitrary+ <*> arbitrary+ <*> arbitrary+instance Arbitrary PDIP where arbitrary = PDIP+ <$> arbitrary+ <*> arbitrary+ <*> arbitrary+ <*> arbitrary++instance CoArbitrary PFEndpoint where coarbitrary = variant . fromEnum+instance CoArbitrary PFVolumeStatus where coarbitrary = variant . fromEnum+instance CoArbitrary PFVolumeVerb where coarbitrary = variant . fromEnum+instance CoArbitrary PFImageVerb where coarbitrary = variant . fromEnum+instance CoArbitrary PFImageStatus where coarbitrary = variant . fromEnum+instance CoArbitrary PFSnapshotVerb where coarbitrary = variant . fromEnum+instance CoArbitrary PFSnapshotStatus where coarbitrary = variant . fromEnum+instance CoArbitrary PFIPVerb where coarbitrary = variant . fromEnum+instance CoArbitrary PFIPStatus where coarbitrary = variant . fromEnum++instance CoArbitrary PDCPU where+ coarbitrary x = variant $ x ^. re pdCPU . re prSimple+instance CoArbitrary PDVolume where+ coarbitrary x = variant $ x ^. re pdVolume . re prCompoundEvent+instance CoArbitrary PDSSD where+ coarbitrary x = variant $ x ^. re pdSSD . re prCompoundEvent+instance CoArbitrary PDImage where+ coarbitrary x = variant $ x ^. re pdImage . re prCompoundEvent+instance CoArbitrary PDImagePollster where+ coarbitrary x = variant $ x ^. re pdImagePollster . re prSimple+instance CoArbitrary PDSnapshot where+ coarbitrary x = variant $ x ^. re pdSnapshot . re prCompoundEvent+instance CoArbitrary PDIP where+ coarbitrary x = variant $ x ^. re pdIP . re prCompoundEvent+instance CoArbitrary PDInstanceFlavor where+ coarbitrary x = variant $ x ^. re (pdInstanceFlavor testFlavors) . re prCompoundPollster+instance CoArbitrary PDInstanceVCPU where+ coarbitrary x = variant $ x ^. re pdInstanceVCPU . re prCompoundPollster+instance CoArbitrary PDInstanceRAM where+ coarbitrary x = variant $ x ^. re pdInstanceRAM . re prCompoundPollster+instance CoArbitrary PDInstanceDisk where+ coarbitrary x = variant $ x ^. re pdInstanceDisk . re prCompoundPollster+++testS, testE :: Word64+testS = 1300000000000000000+testE = 1400000000000000000+++-- INSTANCES -------------------------------------------------------------------++testFlavors :: FlavorMap+testFlavors = BM.fromList [ (flavorID0, flavorSP0)+ , (flavorID1, flavorSP1)+ , (flavorID2, flavorSP2) ]++flavorID0 = "deadbeef"+flavorSP0 = siphashID flavorID0+flavorID1 = "koolaid"+flavorSP1 = siphashID flavorID1+flavorID2 = "chicken"+flavorSP2 = siphashID flavorID2++flavorPR0, flavorPR1, flavorPR2 :: Word64+flavorPR0 = 1 + (0 `shift` 8) + (0 `shift` 16) + (fromIntegral flavorSP0 `shift` 32)+flavorPR1 = 9 + (0 `shift` 8) + (0 `shift` 16) + (fromIntegral flavorSP1 `shift` 32)+flavorPR2 = 15 + (0 `shift` 8) + (0 `shift` 16) + (fromIntegral flavorSP2 `shift` 32)++flavorPRs = [ flavorPR0, flavorPR1, flavorPR2 ]++flavorPD0 = PDInstanceFlavor InstanceActive flavorID0+flavorPD1 = PDInstanceFlavor InstanceReboot flavorID1+flavorPD2 = PDInstanceFlavor InstancePaused flavorID2++flavorPDs = [ flavorPD0, flavorPD1, flavorPD2 ]++flavorTimedPDs = [ Timed testS flavorPD1+ , Timed (testS + 2) flavorPD1+ , Timed (testS + 7) flavorPD2+ , Timed (testS + 11) flavorPD1+ , Timed (testS + 13) flavorPD1 ]++flavorTimedPDsResult :: [(PFValue PDInstanceFlavor, Word64)]+flavorTimedPDsResult = [ (flavorID1, 9)+ , (flavorID2, 4) ]+++-- | Basic safety properties for filtered folding.+-- The set of keys in the result of the filtered fold should be a subset of+-- the result of the non-filtered fold.+-- For each defined key in the filtered result, the corresponding value+-- should be no larger than in the non-filtered result.+propSafetyInstance :: [Timed PDInstanceFlavor] -> Bool+propSafetyInstance x =+ let testPred (PDInstanceFlavor InstanceActive _) = True+ testPred _ = False+ fullResult = L.fold (foldInstanceFlavor (const True)) x+ filteredResult = L.fold (foldInstanceFlavor testPred ) x+ fullKeys = M.keys fullResult+ filteredKeys = M.keys filteredResult+ in subset filteredKeys fullKeys &&+ all (\k -> isJust $ do+ v <- M.lookup k fullResult+ v' <- M.lookup k filteredResult+ return $ v' <= v) filteredKeys++-- CPU -------------------------------------------------------------------------++cumulativeIncreasing = [30, 40, 50, 60]+cumulativeDecreasing = [40, 30, 20, 10]+cumulativeAny = [20, 30, 10, 20, 30, 40, 10]++cpuIncreasing = map PDCPU cumulativeIncreasing+cpuDecreasing = map PDCPU cumulativeDecreasing+cpuAny = map PDCPU cumulativeAny++neutronRxIncreasing = map PDNeutronRx cumulativeIncreasing+neutronRxDecreasing = map PDNeutronRx cumulativeDecreasing+neutronRxAny = map PDNeutronRx cumulativeAny++neutronTxIncreasing = map PDNeutronTx cumulativeIncreasing+neutronTxDecreasing = map PDNeutronTx cumulativeDecreasing+neutronTxAny = map PDNeutronTx cumulativeAny++diskReadIncreasing = map PDDiskRead cumulativeIncreasing+diskReadDecreasing = map PDDiskRead cumulativeDecreasing+diskReadAny = map PDDiskRead cumulativeAny++diskWriteIncreasing = map PDDiskWrite cumulativeIncreasing+diskWriteDecreasing = map PDDiskWrite cumulativeDecreasing+diskWriteAny = map PDDiskWrite cumulativeAny++cumulativeDecreasingResult, cumulativeIncreasingResult, cumulativeAnyResult :: Word64+cumulativeDecreasingResult = 60+cumulativeIncreasingResult = 30+cumulativeAnyResult = 60+++-- VOLUME ----------------------------------------------------------------------++volumeNonDelete :: Gen PDVolume+volumeNonDelete = (arbitrary :: Gen PDVolume) `suchThat` ((/= VolumeDelete) . view volumeVerb)++-- Raw payloads for volume points+volumePRs = [volumePR0, volumePR1, volumePR2 ]+ssdPRs = volumePRs++volumePR0, volumePR1, volumePR2 :: Word64+volumePR0 = 2 + (1 `shift` 8) + (2 `shift` 16) + (10 `shift` 32)+volumePR1 = 2 + (1 `shift` 8) + (2 `shift` 16) + (30 `shift` 32)+volumePR2 = 4 + (3 `shift` 8) + (2 `shift` 16) + (30 `shift` 32)++-- Decoded payloads for volume points+volumePDs = [volumePD0, volumePD1, volumePD2 ]++volumePD0, volumePD1, volumePD2 :: PDVolume+volumePD0 = PDVolume VolumeCreating VolumeCreate End 10+volumePD1 = PDVolume VolumeCreating VolumeCreate End 30+volumePD2 = PDVolume VolumeDeleting VolumeDelete End 30++ssdPDs = [ssdPD0, ssdPD1, ssdPD2 ]++ssdPD0, ssdPD1, ssdPD2 :: PDSSD+ssdPD0 = PDSSD VolumeCreating VolumeCreate End 10+ssdPD1 = PDSSD VolumeCreating VolumeCreate End 30+ssdPD2 = PDSSD VolumeDeleting VolumeDelete End 30++volumeTimedPDs :: [Timed PDVolume]+volumeTimedPDs = [ Timed testS volumePD0+ , Timed (testS + 2) volumePD1+ , Timed (testS + 7) volumePD1+ , Timed (testS + 11) volumePD0+ , Timed (testS + 21) volumePD2 ]++ssdTimedPDs :: [Timed PDSSD]+ssdTimedPDs = [ Timed testS ssdPD0+ , Timed (testS + 2) ssdPD1+ , Timed (testS + 7) ssdPD1+ , Timed (testS + 11) ssdPD0+ , Timed (testS + 21) ssdPD2 ]++-- Volume events+-- Expected = 2 * 10 + 5 * 30 + 4 * 30 + 10 * 10+-- = (2 + 10) * 10 + (5 + 4) * 30+-- = 12 * 10 + 9 * 30+-- = 390+-- from borel-core+--+volumeTimedPDsResult :: Word64+volumeTimedPDsResult = 390++ssdTimedPDsResult :: Word64+ssdTimedPDsResult = volumeTimedPDsResult++-- IMAGE ----------------------------------------------------------------------++imageNonDelete :: Gen PDImage+imageNonDelete = (arbitrary :: Gen PDImage) `suchThat` ((/= ImageDelete) . view imageVerb)++-- Raw payloads for volume points+imagePRs = [imagePR0, imagePR1, imagePR2 ]++imagePR0, imagePR1, imagePR2 :: Word64+imagePR0 = 1 + (3 `shift` 8) + (0 `shift` 16) + (200000 `shift` 32)+imagePR1 = 1 + (1 `shift` 8) + (0 `shift` 16) + (400000 `shift` 32)+imagePR2 = 3 + (5 `shift` 8) + (0 `shift` 16) + (100000 `shift` 32)++-- Decoded payloads for image points+imagePDs = [imagePD0, imagePD1, imagePD2 ]++imagePD0, imagePD1, imagePD2 :: PDImage+imagePD0 = PDImage ImageActive ImageUpload Instant 200000+imagePD1 = PDImage ImageActive ImageServe Instant 400000+imagePD2 = PDImage ImageDeleted ImageDelete Instant 100000++imageTimedPDs :: [Timed PDImage]+imageTimedPDs = [ Timed testS imagePD0+ , Timed (testS + 5) imagePD1+ , Timed (testS + 12) imagePD1+ , Timed (testS + 21) imagePD0+ , Timed (testS + 32) imagePD2 ]+++-- Image events+-- Expected = 5 * 200000+-- + 7 * 400000+-- + 9 * 400000+-- + 11 * 200000+-- = 16 * 200000+-- + 16 * 400000+-- = 9600000+--+imageTimedPDsResult :: Word64+imageTimedPDsResult = 9600000++imagePPD0, imagePPD1, imagePPD2 :: PDImagePollster+imagePPD0 = PDImagePollster 200000+imagePPD1 = PDImagePollster 400000+imagePPD2 = PDImagePollster 100000++imagePTimedPDs :: [Timed PDImagePollster]+imagePTimedPDs = [ Timed testS imagePPD0+ , Timed (testS + 5) imagePPD1+ , Timed (testS + 12) imagePPD2+ , Timed (testS + 21) imagePPD1+ , Timed (testS + 32) imagePPD2 ]++imagePTimedPDsResult :: Map Word64 Word64+imagePTimedPDsResult = M.fromList [ (200000, 5)+ , (400000, 18)+ , (100000, 9)+ ]++-- SNAPSHOT ----------------------------------------------------------------------++snapshotNonDelete :: Gen PDSnapshot+snapshotNonDelete = (arbitrary :: Gen PDSnapshot) `suchThat` ((/= SnapshotDelete) . view snapshotVerb)++-- Raw payloads for volume points+snapshotPRs = [snapshotPR0, snapshotPR1, snapshotPR2 ]++snapshotPR0, snapshotPR1, snapshotPR2 :: Word64+snapshotPR0 = 1 + (2 `shift` 8) + (2 `shift` 16) + (200 `shift` 32)+snapshotPR1 = 1 + (2 `shift` 8) + (2 `shift` 16) + (300 `shift` 32)+snapshotPR2 = 3 + (3 `shift` 8) + (2 `shift` 16) + (100 `shift` 32)++-- Decoded payloads for snapshot points+snapshotPDs = [snapshotPD0, snapshotPD1, snapshotPD2 ]++snapshotPD0, snapshotPD1, snapshotPD2 :: PDSnapshot+snapshotPD0 = PDSnapshot SnapshotAvailable SnapshotUpdate End 200+snapshotPD1 = PDSnapshot SnapshotAvailable SnapshotUpdate End 300+snapshotPD2 = PDSnapshot SnapshotDeleting SnapshotDelete End 100++snapshotTimedPDs :: [Timed PDSnapshot]+snapshotTimedPDs = [ Timed testS snapshotPD0+ , Timed (testS + 5) snapshotPD1+ , Timed (testS + 12) snapshotPD1+ , Timed (testS + 21) snapshotPD0+ , Timed (testS + 32) snapshotPD2 ]+++-- Snapshot events+-- Expected = 5 * 200+-- + 7 * 300+-- + 9 * 300+-- + 11 * 200+-- = 16 * 200+-- + 16 * 300+-- = 8000+--+snapshotTimedPDsResult :: Word64+snapshotTimedPDsResult = 8000++-- IP ----------------------------------------------------------------------++-- Raw payloads for volume points+ipPRs = [ipPR0, ipPR1, ipPR2 ]++ipPR0, ipPR1, ipPR2 :: Word64+ipPR0 = 1 + (2 `shift` 8) + (2 `shift` 16) + (1 `shift` 32)+ipPR1 = 2 + (2 `shift` 8) + (2 `shift` 16) + (1 `shift` 32)+ipPR2 = 0 + (3 `shift` 8) + (2 `shift` 16) + (1 `shift` 32)++-- Decoded payloads for ip points+ipPDs = [ipPD0, ipPD1, ipPD2 ]++ipPD0, ipPD1, ipPD2 :: PDIP+ipPD0 = PDIP IPActive IPUpdate End IPAlloc+ipPD1 = PDIP IPDown IPUpdate End IPAlloc+ipPD2 = PDIP IPNone IPDelete End IPAlloc