Statistics
| Branch: | Tag: | Revision:

root / htest / Test / Ganeti / Query / Language.hs @ e09c1fa0

History | View | Annotate | Download (3.3 kB)

1
{-# LANGUAGE TemplateHaskell #-}
2
{-# OPTIONS_GHC -fno-warn-orphans #-}
3

    
4
{-| Unittests for ganeti-htools.
5

    
6
-}
7

    
8
{-
9

    
10
Copyright (C) 2009, 2010, 2011, 2012 Google Inc.
11

    
12
This program is free software; you can redistribute it and/or modify
13
it under the terms of the GNU General Public License as published by
14
the Free Software Foundation; either version 2 of the License, or
15
(at your option) any later version.
16

    
17
This program is distributed in the hope that it will be useful, but
18
WITHOUT ANY WARRANTY; without even the implied warranty of
19
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20
General Public License for more details.
21

    
22
You should have received a copy of the GNU General Public License
23
along with this program; if not, write to the Free Software
24
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25
02110-1301, USA.
26

    
27
-}
28

    
29
module Test.Ganeti.Query.Language
30
  ( testQuery_Language
31
  , genFilter
32
  ) where
33

    
34
import Test.QuickCheck
35

    
36
import Control.Applicative
37
import qualified Text.JSON as J
38

    
39
import Test.Ganeti.TestHelper
40
import Test.Ganeti.TestCommon
41

    
42
import qualified Ganeti.Query.Language as Qlang
43

    
44
-- | Custom 'Qlang.Filter' generator (top-level), which enforces a
45
-- (sane) limit on the depth of the generated filters.
46
genFilter :: Gen (Qlang.Filter Qlang.FilterField)
47
genFilter = choose (0, 10) >>= genFilter'
48

    
49
-- | Custom generator for filters that correctly halves the state of
50
-- the generators at each recursive step, per the QuickCheck
51
-- documentation, in order not to run out of memory.
52
genFilter' :: Int -> Gen (Qlang.Filter Qlang.FilterField)
53
genFilter' 0 =
54
  oneof [ return Qlang.EmptyFilter
55
        , Qlang.TrueFilter     <$> getName
56
        , Qlang.EQFilter       <$> getName <*> value
57
        , Qlang.LTFilter       <$> getName <*> value
58
        , Qlang.GTFilter       <$> getName <*> value
59
        , Qlang.LEFilter       <$> getName <*> value
60
        , Qlang.GEFilter       <$> getName <*> value
61
        , Qlang.RegexpFilter   <$> getName <*> arbitrary
62
        , Qlang.ContainsFilter <$> getName <*> value
63
        ]
64
    where value = oneof [ Qlang.QuotedString <$> getName
65
                        , Qlang.NumericValue <$> arbitrary
66
                        ]
67
genFilter' n = do
68
  oneof [ Qlang.AndFilter  <$> vectorOf n'' (genFilter' n')
69
        , Qlang.OrFilter   <$> vectorOf n'' (genFilter' n')
70
        , Qlang.NotFilter  <$> genFilter' n'
71
        ]
72
  where n' = n `div` 2 -- sub-filter generator size
73
        n'' = max n' 2 -- but we don't want empty or 1-element lists,
74
                       -- so use this for and/or filter list length
75

    
76
instance Arbitrary Qlang.ItemType where
77
  arbitrary = elements [minBound..maxBound]
78

    
79
instance Arbitrary Qlang.FilterRegex where
80
  arbitrary = getName >>= Qlang.mkRegex -- a name should be a good regex
81

    
82
-- | Tests that serialisation/deserialisation of filters is
83
-- idempotent.
84
prop_Serialisation :: Property
85
prop_Serialisation =
86
  forAll genFilter $ \flt ->
87
  J.readJSON (J.showJSON flt) ==? J.Ok flt
88

    
89
prop_FilterRegex_instances :: Qlang.FilterRegex -> Property
90
prop_FilterRegex_instances rex =
91
  printTestCase "failed JSON encoding"
92
    (J.readJSON (J.showJSON rex) ==? J.Ok rex) .&&.
93
  printTestCase "failed read/show instances" (read (show rex) ==? rex)
94

    
95
testSuite "Query/Language"
96
  [ 'prop_Serialisation
97
  , 'prop_FilterRegex_instances
98
  ]