Statistics
| Branch: | Tag: | Revision:

root / test / hs / Test / Ganeti / OpCodes.hs @ 5b0ec494

History | View | Annotate | Download (24.3 kB)

1 aed2325f Iustin Pop
{-# LANGUAGE TemplateHaskell #-}
2 aed2325f Iustin Pop
{-# OPTIONS_GHC -fno-warn-orphans #-}
3 aed2325f Iustin Pop
4 aed2325f Iustin Pop
{-| Unittests for ganeti-htools.
5 aed2325f Iustin Pop
6 aed2325f Iustin Pop
-}
7 aed2325f Iustin Pop
8 aed2325f Iustin Pop
{-
9 aed2325f Iustin Pop
10 72747d91 Iustin Pop
Copyright (C) 2009, 2010, 2011, 2012, 2013 Google Inc.
11 aed2325f Iustin Pop
12 aed2325f Iustin Pop
This program is free software; you can redistribute it and/or modify
13 aed2325f Iustin Pop
it under the terms of the GNU General Public License as published by
14 aed2325f Iustin Pop
the Free Software Foundation; either version 2 of the License, or
15 aed2325f Iustin Pop
(at your option) any later version.
16 aed2325f Iustin Pop
17 aed2325f Iustin Pop
This program is distributed in the hope that it will be useful, but
18 aed2325f Iustin Pop
WITHOUT ANY WARRANTY; without even the implied warranty of
19 aed2325f Iustin Pop
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20 aed2325f Iustin Pop
General Public License for more details.
21 aed2325f Iustin Pop
22 aed2325f Iustin Pop
You should have received a copy of the GNU General Public License
23 aed2325f Iustin Pop
along with this program; if not, write to the Free Software
24 aed2325f Iustin Pop
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 aed2325f Iustin Pop
02110-1301, USA.
26 aed2325f Iustin Pop
27 aed2325f Iustin Pop
-}
28 aed2325f Iustin Pop
29 aed2325f Iustin Pop
module Test.Ganeti.OpCodes
30 aed2325f Iustin Pop
  ( testOpCodes
31 aed2325f Iustin Pop
  , OpCodes.OpCode(..)
32 aed2325f Iustin Pop
  ) where
33 aed2325f Iustin Pop
34 f56013fd Iustin Pop
import Test.HUnit as HUnit
35 f56013fd Iustin Pop
import Test.QuickCheck as QuickCheck
36 aed2325f Iustin Pop
37 aed2325f Iustin Pop
import Control.Applicative
38 dc4b5c42 Iustin Pop
import Control.Monad
39 dc4b5c42 Iustin Pop
import Data.Char
40 aed2325f Iustin Pop
import Data.List
41 c66f09f5 Iustin Pop
import qualified Data.Map as Map
42 aed2325f Iustin Pop
import qualified Text.JSON as J
43 8d239fa4 Iustin Pop
import Text.Printf (printf)
44 aed2325f Iustin Pop
45 aed2325f Iustin Pop
import Test.Ganeti.TestHelper
46 aed2325f Iustin Pop
import Test.Ganeti.TestCommon
47 c7d249d0 Iustin Pop
import Test.Ganeti.Types ()
48 c66f09f5 Iustin Pop
import Test.Ganeti.Query.Language
49 aed2325f Iustin Pop
50 f56013fd Iustin Pop
import Ganeti.BasicTypes
51 aed2325f Iustin Pop
import qualified Ganeti.Constants as C
52 aed2325f Iustin Pop
import qualified Ganeti.OpCodes as OpCodes
53 c7d249d0 Iustin Pop
import Ganeti.Types
54 c7d249d0 Iustin Pop
import Ganeti.OpParams
55 c66f09f5 Iustin Pop
import Ganeti.JSON
56 aed2325f Iustin Pop
57 5b11f8db Iustin Pop
{-# ANN module "HLint: ignore Use camelCase" #-}
58 5b11f8db Iustin Pop
59 aed2325f Iustin Pop
-- * Arbitrary instances
60 aed2325f Iustin Pop
61 d8e7c45e Iustin Pop
instance Arbitrary OpCodes.TagObject where
62 5006418e Iustin Pop
  arbitrary = oneof [ OpCodes.TagInstance <$> genFQDN
63 5006418e Iustin Pop
                    , OpCodes.TagNode     <$> genFQDN
64 5006418e Iustin Pop
                    , OpCodes.TagGroup    <$> genFQDN
65 d8e7c45e Iustin Pop
                    , pure OpCodes.TagCluster
66 d8e7c45e Iustin Pop
                    ]
67 367c4241 Dato Simó
68 7022db83 Iustin Pop
$(genArbitrary ''OpCodes.ReplaceDisksMode)
69 aed2325f Iustin Pop
70 6d558717 Iustin Pop
$(genArbitrary ''DiskAccess)
71 6d558717 Iustin Pop
72 aed2325f Iustin Pop
instance Arbitrary OpCodes.DiskIndex where
73 aed2325f Iustin Pop
  arbitrary = choose (0, C.maxDisks - 1) >>= OpCodes.mkDiskIndex
74 aed2325f Iustin Pop
75 5ef4fbb1 Iustin Pop
instance Arbitrary INicParams where
76 5006418e Iustin Pop
  arbitrary = INicParams <$> genMaybe genNameNE <*> genMaybe genName <*>
77 4e4433e8 Christos Stavrakakis
              genMaybe genNameNE <*> genMaybe genNameNE <*> genMaybe genNameNE
78 c66f09f5 Iustin Pop
79 6d558717 Iustin Pop
instance Arbitrary IDiskParams where
80 6d558717 Iustin Pop
  arbitrary = IDiskParams <$> arbitrary <*> arbitrary <*>
81 5006418e Iustin Pop
              genMaybe genNameNE <*> genMaybe genNameNE <*>
82 4e4433e8 Christos Stavrakakis
              genMaybe genNameNE <*> genMaybe genNameNE
83 6d558717 Iustin Pop
84 c2d3219b Iustin Pop
instance Arbitrary RecreateDisksInfo where
85 c2d3219b Iustin Pop
  arbitrary = oneof [ pure RecreateDisksAll
86 c2d3219b Iustin Pop
                    , RecreateDisksIndices <$> arbitrary
87 c2d3219b Iustin Pop
                    , RecreateDisksParams <$> arbitrary
88 c2d3219b Iustin Pop
                    ]
89 c2d3219b Iustin Pop
90 c2d3219b Iustin Pop
instance Arbitrary DdmOldChanges where
91 c2d3219b Iustin Pop
  arbitrary = oneof [ DdmOldIndex <$> arbitrary
92 c2d3219b Iustin Pop
                    , DdmOldMod   <$> arbitrary
93 c2d3219b Iustin Pop
                    ]
94 c2d3219b Iustin Pop
95 c2d3219b Iustin Pop
instance (Arbitrary a) => Arbitrary (SetParamsMods a) where
96 c2d3219b Iustin Pop
  arbitrary = oneof [ pure SetParamsEmpty
97 c2d3219b Iustin Pop
                    , SetParamsDeprecated <$> arbitrary
98 c2d3219b Iustin Pop
                    , SetParamsNew        <$> arbitrary
99 c2d3219b Iustin Pop
                    ]
100 c2d3219b Iustin Pop
101 398e9066 Iustin Pop
instance Arbitrary ExportTarget where
102 398e9066 Iustin Pop
  arbitrary = oneof [ ExportTargetLocal <$> genNodeNameNE
103 398e9066 Iustin Pop
                    , ExportTargetRemote <$> pure []
104 398e9066 Iustin Pop
                    ]
105 398e9066 Iustin Pop
106 aed2325f Iustin Pop
instance Arbitrary OpCodes.OpCode where
107 aed2325f Iustin Pop
  arbitrary = do
108 aed2325f Iustin Pop
    op_id <- elements OpCodes.allOpIDs
109 aed2325f Iustin Pop
    case op_id of
110 aed2325f Iustin Pop
      "OP_TEST_DELAY" ->
111 7d421386 Iustin Pop
        OpCodes.OpTestDelay <$> arbitrary <*> arbitrary <*>
112 7d421386 Iustin Pop
          genNodeNamesNE <*> arbitrary
113 aed2325f Iustin Pop
      "OP_INSTANCE_REPLACE_DISKS" ->
114 3d7e87b8 Iustin Pop
        OpCodes.OpInstanceReplaceDisks <$> genFQDN <*> arbitrary <*>
115 3d7e87b8 Iustin Pop
          arbitrary <*> arbitrary <*> genDiskIndices <*>
116 3d7e87b8 Iustin Pop
          genMaybe genNodeNameNE <*> genMaybe genNameNE
117 aed2325f Iustin Pop
      "OP_INSTANCE_FAILOVER" ->
118 3d7e87b8 Iustin Pop
        OpCodes.OpInstanceFailover <$> genFQDN <*> arbitrary <*> arbitrary <*>
119 aa7a5c90 Michele Tartara
          genMaybe genNodeNameNE <*> arbitrary <*> genMaybe genNameNE <*>
120 aa7a5c90 Michele Tartara
          arbitrary
121 aed2325f Iustin Pop
      "OP_INSTANCE_MIGRATE" ->
122 3d7e87b8 Iustin Pop
        OpCodes.OpInstanceMigrate <$> genFQDN <*> arbitrary <*> arbitrary <*>
123 3d7e87b8 Iustin Pop
          genMaybe genNodeNameNE <*> arbitrary <*>
124 3d7e87b8 Iustin Pop
          arbitrary <*> arbitrary <*> genMaybe genNameNE <*> arbitrary
125 a451dae2 Iustin Pop
      "OP_TAGS_GET" ->
126 a451dae2 Iustin Pop
        OpCodes.OpTagsGet <$> arbitrary <*> arbitrary
127 a451dae2 Iustin Pop
      "OP_TAGS_SEARCH" ->
128 a451dae2 Iustin Pop
        OpCodes.OpTagsSearch <$> genNameNE
129 3bebda52 Dato Simó
      "OP_TAGS_SET" ->
130 d8e7c45e Iustin Pop
        OpCodes.OpTagsSet <$> arbitrary <*> genTags
131 3bebda52 Dato Simó
      "OP_TAGS_DEL" ->
132 d8e7c45e Iustin Pop
        OpCodes.OpTagsSet <$> arbitrary <*> genTags
133 c66f09f5 Iustin Pop
      "OP_CLUSTER_POST_INIT" -> pure OpCodes.OpClusterPostInit
134 c66f09f5 Iustin Pop
      "OP_CLUSTER_DESTROY" -> pure OpCodes.OpClusterDestroy
135 c66f09f5 Iustin Pop
      "OP_CLUSTER_QUERY" -> pure OpCodes.OpClusterQuery
136 c66f09f5 Iustin Pop
      "OP_CLUSTER_VERIFY" ->
137 c66f09f5 Iustin Pop
        OpCodes.OpClusterVerify <$> arbitrary <*> arbitrary <*>
138 5ef4fbb1 Iustin Pop
          genSet Nothing <*> genSet Nothing <*> arbitrary <*>
139 5006418e Iustin Pop
          genMaybe genNameNE
140 c66f09f5 Iustin Pop
      "OP_CLUSTER_VERIFY_CONFIG" ->
141 c66f09f5 Iustin Pop
        OpCodes.OpClusterVerifyConfig <$> arbitrary <*> arbitrary <*>
142 c66f09f5 Iustin Pop
          genSet Nothing <*> arbitrary
143 c66f09f5 Iustin Pop
      "OP_CLUSTER_VERIFY_GROUP" ->
144 5ef4fbb1 Iustin Pop
        OpCodes.OpClusterVerifyGroup <$> genNameNE <*> arbitrary <*>
145 c66f09f5 Iustin Pop
          arbitrary <*> genSet Nothing <*> genSet Nothing <*> arbitrary
146 c66f09f5 Iustin Pop
      "OP_CLUSTER_VERIFY_DISKS" -> pure OpCodes.OpClusterVerifyDisks
147 c66f09f5 Iustin Pop
      "OP_GROUP_VERIFY_DISKS" ->
148 5ef4fbb1 Iustin Pop
        OpCodes.OpGroupVerifyDisks <$> genNameNE
149 c66f09f5 Iustin Pop
      "OP_CLUSTER_REPAIR_DISK_SIZES" ->
150 5006418e Iustin Pop
        OpCodes.OpClusterRepairDiskSizes <$> genNodeNamesNE
151 c66f09f5 Iustin Pop
      "OP_CLUSTER_CONFIG_QUERY" ->
152 5ef4fbb1 Iustin Pop
        OpCodes.OpClusterConfigQuery <$> genFieldsNE
153 c66f09f5 Iustin Pop
      "OP_CLUSTER_RENAME" ->
154 5006418e Iustin Pop
        OpCodes.OpClusterRename <$> genNameNE
155 c66f09f5 Iustin Pop
      "OP_CLUSTER_SET_PARAMS" ->
156 e5c92cfb Klaus Aehlig
        OpCodes.OpClusterSetParams <$> arbitrary <*> emptyMUD <*> emptyMUD <*>
157 5006418e Iustin Pop
          arbitrary <*> genMaybe (listOf1 arbitrary >>= mkNonEmpty) <*>
158 5006418e Iustin Pop
          genMaybe genEmptyContainer <*> emptyMUD <*>
159 5006418e Iustin Pop
          genMaybe genEmptyContainer <*> genMaybe genEmptyContainer <*>
160 5006418e Iustin Pop
          genMaybe genEmptyContainer <*> genMaybe arbitrary <*>
161 c66f09f5 Iustin Pop
          arbitrary <*> arbitrary <*> arbitrary <*>
162 c66f09f5 Iustin Pop
          arbitrary <*> arbitrary <*> arbitrary <*>
163 c66f09f5 Iustin Pop
          emptyMUD <*> emptyMUD <*> arbitrary <*>
164 67fc4de7 Iustin Pop
          arbitrary <*> arbitrary <*> arbitrary <*> arbitrary <*>
165 75f2ff7d Michele Tartara
          arbitrary <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
166 c66f09f5 Iustin Pop
      "OP_CLUSTER_REDIST_CONF" -> pure OpCodes.OpClusterRedistConf
167 c66f09f5 Iustin Pop
      "OP_CLUSTER_ACTIVATE_MASTER_IP" ->
168 c66f09f5 Iustin Pop
        pure OpCodes.OpClusterActivateMasterIp
169 c66f09f5 Iustin Pop
      "OP_CLUSTER_DEACTIVATE_MASTER_IP" ->
170 c66f09f5 Iustin Pop
        pure OpCodes.OpClusterDeactivateMasterIp
171 c66f09f5 Iustin Pop
      "OP_QUERY" ->
172 c66f09f5 Iustin Pop
        OpCodes.OpQuery <$> arbitrary <*> arbitrary <*> arbitrary <*> genFilter
173 c66f09f5 Iustin Pop
      "OP_QUERY_FIELDS" ->
174 c66f09f5 Iustin Pop
        OpCodes.OpQueryFields <$> arbitrary <*> arbitrary
175 c66f09f5 Iustin Pop
      "OP_OOB_COMMAND" ->
176 c66f09f5 Iustin Pop
        OpCodes.OpOobCommand <$> genNodeNamesNE <*> arbitrary <*>
177 c66f09f5 Iustin Pop
          arbitrary <*> arbitrary <*> (arbitrary `suchThat` (>0))
178 5006418e Iustin Pop
      "OP_NODE_REMOVE" -> OpCodes.OpNodeRemove <$> genNodeNameNE
179 c66f09f5 Iustin Pop
      "OP_NODE_ADD" ->
180 5ef4fbb1 Iustin Pop
        OpCodes.OpNodeAdd <$> genNodeNameNE <*> emptyMUD <*> emptyMUD <*>
181 5006418e Iustin Pop
          genMaybe genName <*> genMaybe genNameNE <*> arbitrary <*>
182 5006418e Iustin Pop
          genMaybe genNameNE <*> arbitrary <*> arbitrary <*> emptyMUD
183 c66f09f5 Iustin Pop
      "OP_NODE_QUERY" ->
184 3131adc7 Iustin Pop
        OpCodes.OpNodeQuery <$> genFieldsNE <*> genNamesNE <*> arbitrary
185 c66f09f5 Iustin Pop
      "OP_NODE_QUERYVOLS" ->
186 c66f09f5 Iustin Pop
        OpCodes.OpNodeQueryvols <$> arbitrary <*> genNodeNamesNE
187 c66f09f5 Iustin Pop
      "OP_NODE_QUERY_STORAGE" ->
188 c66f09f5 Iustin Pop
        OpCodes.OpNodeQueryStorage <$> arbitrary <*> arbitrary <*>
189 5ef4fbb1 Iustin Pop
          genNodeNamesNE <*> genNameNE
190 c66f09f5 Iustin Pop
      "OP_NODE_MODIFY_STORAGE" ->
191 c66f09f5 Iustin Pop
        OpCodes.OpNodeModifyStorage <$> genNodeNameNE <*> arbitrary <*>
192 5ef4fbb1 Iustin Pop
          genNameNE <*> pure emptyJSObject
193 c66f09f5 Iustin Pop
      "OP_REPAIR_NODE_STORAGE" ->
194 c66f09f5 Iustin Pop
        OpCodes.OpRepairNodeStorage <$> genNodeNameNE <*> arbitrary <*>
195 5ef4fbb1 Iustin Pop
          genNameNE <*> arbitrary
196 c66f09f5 Iustin Pop
      "OP_NODE_SET_PARAMS" ->
197 c66f09f5 Iustin Pop
        OpCodes.OpNodeSetParams <$> genNodeNameNE <*> arbitrary <*>
198 c66f09f5 Iustin Pop
          emptyMUD <*> emptyMUD <*> arbitrary <*> arbitrary <*> arbitrary <*>
199 5006418e Iustin Pop
          arbitrary <*> arbitrary <*> arbitrary <*> genMaybe genNameNE <*>
200 67fc4de7 Iustin Pop
          emptyMUD <*> arbitrary
201 c66f09f5 Iustin Pop
      "OP_NODE_POWERCYCLE" ->
202 c66f09f5 Iustin Pop
        OpCodes.OpNodePowercycle <$> genNodeNameNE <*> arbitrary
203 c66f09f5 Iustin Pop
      "OP_NODE_MIGRATE" ->
204 c66f09f5 Iustin Pop
        OpCodes.OpNodeMigrate <$> genNodeNameNE <*> arbitrary <*>
205 5006418e Iustin Pop
          arbitrary <*> genMaybe genNodeNameNE <*> arbitrary <*>
206 5006418e Iustin Pop
          arbitrary <*> genMaybe genNameNE
207 c66f09f5 Iustin Pop
      "OP_NODE_EVACUATE" ->
208 c66f09f5 Iustin Pop
        OpCodes.OpNodeEvacuate <$> arbitrary <*> genNodeNameNE <*>
209 5006418e Iustin Pop
          genMaybe genNodeNameNE <*> genMaybe genNameNE <*> arbitrary
210 6d558717 Iustin Pop
      "OP_INSTANCE_CREATE" ->
211 5006418e Iustin Pop
        OpCodes.OpInstanceCreate <$> genFQDN <*> arbitrary <*>
212 6d558717 Iustin Pop
          arbitrary <*> arbitrary <*> arbitrary <*> pure emptyJSObject <*>
213 5006418e Iustin Pop
          arbitrary <*> arbitrary <*> arbitrary <*> genMaybe genNameNE <*>
214 5006418e Iustin Pop
          pure emptyJSObject <*> arbitrary <*> genMaybe genNameNE <*>
215 6d558717 Iustin Pop
          arbitrary <*> arbitrary <*> arbitrary <*> arbitrary <*>
216 6d558717 Iustin Pop
          arbitrary <*> arbitrary <*> pure emptyJSObject <*>
217 5006418e Iustin Pop
          genMaybe genNameNE <*>
218 5006418e Iustin Pop
          genMaybe genNodeNameNE <*> genMaybe genNodeNameNE <*>
219 5006418e Iustin Pop
          genMaybe (pure []) <*> genMaybe genNodeNameNE <*>
220 5006418e Iustin Pop
          arbitrary <*> genMaybe genNodeNameNE <*>
221 5006418e Iustin Pop
          genMaybe genNodeNameNE <*> genMaybe genNameNE <*>
222 1f1188c3 Michael Hanselmann
          arbitrary <*> arbitrary <*> (genTags >>= mapM mkNonEmpty)
223 c2d3219b Iustin Pop
      "OP_INSTANCE_MULTI_ALLOC" ->
224 c298ed02 Michael Hanselmann
        OpCodes.OpInstanceMultiAlloc <$> genMaybe genNameNE <*> pure [] <*>
225 c298ed02 Michael Hanselmann
          arbitrary
226 c2d3219b Iustin Pop
      "OP_INSTANCE_REINSTALL" ->
227 5006418e Iustin Pop
        OpCodes.OpInstanceReinstall <$> genFQDN <*> arbitrary <*>
228 5006418e Iustin Pop
          genMaybe genNameNE <*> genMaybe (pure emptyJSObject)
229 c2d3219b Iustin Pop
      "OP_INSTANCE_REMOVE" ->
230 5006418e Iustin Pop
        OpCodes.OpInstanceRemove <$> genFQDN <*> arbitrary <*> arbitrary
231 c2d3219b Iustin Pop
      "OP_INSTANCE_RENAME" ->
232 5006418e Iustin Pop
        OpCodes.OpInstanceRename <$> genFQDN <*> genNodeNameNE <*>
233 c2d3219b Iustin Pop
          arbitrary <*> arbitrary
234 c2d3219b Iustin Pop
      "OP_INSTANCE_STARTUP" ->
235 5006418e Iustin Pop
        OpCodes.OpInstanceStartup <$> genFQDN <*> arbitrary <*> arbitrary <*>
236 c2d3219b Iustin Pop
          pure emptyJSObject <*> pure emptyJSObject <*>
237 c2d3219b Iustin Pop
          arbitrary <*> arbitrary
238 c2d3219b Iustin Pop
      "OP_INSTANCE_SHUTDOWN" ->
239 0d57ce24 Guido Trotter
        OpCodes.OpInstanceShutdown <$> genFQDN <*> arbitrary <*> arbitrary <*>
240 c2d3219b Iustin Pop
          arbitrary <*> arbitrary
241 c2d3219b Iustin Pop
      "OP_INSTANCE_REBOOT" ->
242 5006418e Iustin Pop
        OpCodes.OpInstanceReboot <$> genFQDN <*> arbitrary <*>
243 aa922d64 Michele Tartara
          arbitrary <*> arbitrary
244 c2d3219b Iustin Pop
      "OP_INSTANCE_MOVE" ->
245 5006418e Iustin Pop
        OpCodes.OpInstanceMove <$> genFQDN <*> arbitrary <*> arbitrary <*>
246 c2d3219b Iustin Pop
          genNodeNameNE <*> arbitrary
247 5006418e Iustin Pop
      "OP_INSTANCE_CONSOLE" -> OpCodes.OpInstanceConsole <$> genFQDN
248 c2d3219b Iustin Pop
      "OP_INSTANCE_ACTIVATE_DISKS" ->
249 5006418e Iustin Pop
        OpCodes.OpInstanceActivateDisks <$> genFQDN <*>
250 c2d3219b Iustin Pop
          arbitrary <*> arbitrary
251 c2d3219b Iustin Pop
      "OP_INSTANCE_DEACTIVATE_DISKS" ->
252 5006418e Iustin Pop
        OpCodes.OpInstanceDeactivateDisks <$> genFQDN <*> arbitrary
253 c2d3219b Iustin Pop
      "OP_INSTANCE_RECREATE_DISKS" ->
254 5006418e Iustin Pop
        OpCodes.OpInstanceRecreateDisks <$> genFQDN <*> arbitrary <*>
255 5006418e Iustin Pop
          genNodeNamesNE <*> genMaybe genNameNE
256 1cd563e2 Iustin Pop
      "OP_INSTANCE_QUERY" ->
257 1cd563e2 Iustin Pop
        OpCodes.OpInstanceQuery <$> genFieldsNE <*> genNamesNE <*> arbitrary
258 c2d3219b Iustin Pop
      "OP_INSTANCE_QUERY_DATA" ->
259 c2d3219b Iustin Pop
        OpCodes.OpInstanceQueryData <$> arbitrary <*>
260 c2d3219b Iustin Pop
          genNodeNamesNE <*> arbitrary
261 c2d3219b Iustin Pop
      "OP_INSTANCE_SET_PARAMS" ->
262 5006418e Iustin Pop
        OpCodes.OpInstanceSetParams <$> genFQDN <*> arbitrary <*>
263 c2d3219b Iustin Pop
          arbitrary <*> arbitrary <*> arbitrary <*> arbitrary <*>
264 c2d3219b Iustin Pop
          pure emptyJSObject <*> arbitrary <*> pure emptyJSObject <*>
265 d2204b1a Klaus Aehlig
          arbitrary <*> genMaybe genNodeNameNE <*> genMaybe genNodeNameNE <*>
266 d2204b1a Klaus Aehlig
          genMaybe genNameNE <*> pure emptyJSObject <*> arbitrary <*>
267 5b0ec494 Dimitris Aragiorgis
          arbitrary <*> arbitrary <*> arbitrary
268 c2d3219b Iustin Pop
      "OP_INSTANCE_GROW_DISK" ->
269 5006418e Iustin Pop
        OpCodes.OpInstanceGrowDisk <$> genFQDN <*> arbitrary <*>
270 c2d3219b Iustin Pop
          arbitrary <*> arbitrary <*> arbitrary
271 c2d3219b Iustin Pop
      "OP_INSTANCE_CHANGE_GROUP" ->
272 5006418e Iustin Pop
        OpCodes.OpInstanceChangeGroup <$> genFQDN <*> arbitrary <*>
273 5006418e Iustin Pop
          genMaybe genNameNE <*> genMaybe (resize maxNodes (listOf genNameNE))
274 398e9066 Iustin Pop
      "OP_GROUP_ADD" ->
275 398e9066 Iustin Pop
        OpCodes.OpGroupAdd <$> genNameNE <*> arbitrary <*>
276 5006418e Iustin Pop
          emptyMUD <*> genMaybe genEmptyContainer <*>
277 398e9066 Iustin Pop
          emptyMUD <*> emptyMUD <*> emptyMUD
278 398e9066 Iustin Pop
      "OP_GROUP_ASSIGN_NODES" ->
279 398e9066 Iustin Pop
        OpCodes.OpGroupAssignNodes <$> genNameNE <*> arbitrary <*>
280 398e9066 Iustin Pop
          genNodeNamesNE
281 398e9066 Iustin Pop
      "OP_GROUP_QUERY" ->
282 398e9066 Iustin Pop
        OpCodes.OpGroupQuery <$> genFieldsNE <*> genNamesNE
283 398e9066 Iustin Pop
      "OP_GROUP_SET_PARAMS" ->
284 398e9066 Iustin Pop
        OpCodes.OpGroupSetParams <$> genNameNE <*> arbitrary <*>
285 5006418e Iustin Pop
          emptyMUD <*> genMaybe genEmptyContainer <*>
286 398e9066 Iustin Pop
          emptyMUD <*> emptyMUD <*> emptyMUD
287 398e9066 Iustin Pop
      "OP_GROUP_REMOVE" ->
288 398e9066 Iustin Pop
        OpCodes.OpGroupRemove <$> genNameNE
289 398e9066 Iustin Pop
      "OP_GROUP_RENAME" ->
290 398e9066 Iustin Pop
        OpCodes.OpGroupRename <$> genNameNE <*> genNameNE
291 398e9066 Iustin Pop
      "OP_GROUP_EVACUATE" ->
292 398e9066 Iustin Pop
        OpCodes.OpGroupEvacuate <$> genNameNE <*> arbitrary <*>
293 5006418e Iustin Pop
          genMaybe genNameNE <*> genMaybe genNamesNE
294 398e9066 Iustin Pop
      "OP_OS_DIAGNOSE" ->
295 398e9066 Iustin Pop
        OpCodes.OpOsDiagnose <$> genFieldsNE <*> genNamesNE
296 b954f097 Constantinos Venetsanopoulos
      "OP_EXT_STORAGE_DIAGNOSE" ->
297 b954f097 Constantinos Venetsanopoulos
        OpCodes.OpOsDiagnose <$> genFieldsNE <*> genNamesNE
298 398e9066 Iustin Pop
      "OP_BACKUP_QUERY" ->
299 398e9066 Iustin Pop
        OpCodes.OpBackupQuery <$> arbitrary <*> genNodeNamesNE
300 398e9066 Iustin Pop
      "OP_BACKUP_PREPARE" ->
301 5006418e Iustin Pop
        OpCodes.OpBackupPrepare <$> genFQDN <*> arbitrary
302 398e9066 Iustin Pop
      "OP_BACKUP_EXPORT" ->
303 5006418e Iustin Pop
        OpCodes.OpBackupExport <$> genFQDN <*> arbitrary <*>
304 398e9066 Iustin Pop
          arbitrary <*> arbitrary <*> arbitrary <*> arbitrary <*>
305 67fc4de7 Iustin Pop
          arbitrary <*> genMaybe (pure []) <*> genMaybe genNameNE
306 398e9066 Iustin Pop
      "OP_BACKUP_REMOVE" ->
307 5006418e Iustin Pop
        OpCodes.OpBackupRemove <$> genFQDN
308 a3f02317 Iustin Pop
      "OP_TEST_ALLOCATOR" ->
309 a3f02317 Iustin Pop
        OpCodes.OpTestAllocator <$> arbitrary <*> arbitrary <*>
310 a3f02317 Iustin Pop
          genNameNE <*> pure [] <*> pure [] <*>
311 5006418e Iustin Pop
          arbitrary <*> genMaybe genNameNE <*>
312 a3f02317 Iustin Pop
          (genTags >>= mapM mkNonEmpty) <*>
313 5006418e Iustin Pop
          arbitrary <*> arbitrary <*> genMaybe genNameNE <*>
314 5006418e Iustin Pop
          arbitrary <*> genMaybe genNodeNamesNE <*> arbitrary <*>
315 5006418e Iustin Pop
          genMaybe genNamesNE <*> arbitrary <*> arbitrary
316 a3f02317 Iustin Pop
      "OP_TEST_JQUEUE" ->
317 a3f02317 Iustin Pop
        OpCodes.OpTestJqueue <$> arbitrary <*> arbitrary <*>
318 5006418e Iustin Pop
          resize 20 (listOf genFQDN) <*> arbitrary
319 a3f02317 Iustin Pop
      "OP_TEST_DUMMY" ->
320 a3f02317 Iustin Pop
        OpCodes.OpTestDummy <$> pure J.JSNull <*> pure J.JSNull <*>
321 a3f02317 Iustin Pop
          pure J.JSNull <*> pure J.JSNull
322 8d239fa4 Iustin Pop
      "OP_NETWORK_ADD" ->
323 5cfa6c37 Dimitris Aragiorgis
        OpCodes.OpNetworkAdd <$> genNameNE <*> genIp4Net <*>
324 5006418e Iustin Pop
          genMaybe genIp4Addr <*> pure Nothing <*> pure Nothing <*>
325 5006418e Iustin Pop
          genMaybe genMacPrefix <*> genMaybe (listOf genIp4Addr) <*>
326 1dbceab9 Iustin Pop
          arbitrary <*> (genTags >>= mapM mkNonEmpty)
327 8d239fa4 Iustin Pop
      "OP_NETWORK_REMOVE" ->
328 8d239fa4 Iustin Pop
        OpCodes.OpNetworkRemove <$> genNameNE <*> arbitrary
329 8d239fa4 Iustin Pop
      "OP_NETWORK_SET_PARAMS" ->
330 5cfa6c37 Dimitris Aragiorgis
        OpCodes.OpNetworkSetParams <$> genNameNE <*>
331 5006418e Iustin Pop
          genMaybe genIp4Addr <*> pure Nothing <*> pure Nothing <*>
332 5006418e Iustin Pop
          genMaybe genMacPrefix <*> genMaybe (listOf genIp4Addr) <*>
333 5006418e Iustin Pop
          genMaybe (listOf genIp4Addr)
334 8d239fa4 Iustin Pop
      "OP_NETWORK_CONNECT" ->
335 8d239fa4 Iustin Pop
        OpCodes.OpNetworkConnect <$> genNameNE <*> genNameNE <*>
336 8d239fa4 Iustin Pop
          arbitrary <*> genNameNE <*> arbitrary
337 8d239fa4 Iustin Pop
      "OP_NETWORK_DISCONNECT" ->
338 0ae4b355 Helga Velroyen
        OpCodes.OpNetworkDisconnect <$> genNameNE <*> genNameNE
339 8d239fa4 Iustin Pop
      "OP_NETWORK_QUERY" ->
340 8d459129 Michael Hanselmann
        OpCodes.OpNetworkQuery <$> genFieldsNE <*> genNamesNE <*> arbitrary
341 1cd563e2 Iustin Pop
      "OP_RESTRICTED_COMMAND" ->
342 1cd563e2 Iustin Pop
        OpCodes.OpRestrictedCommand <$> arbitrary <*> genNodeNamesNE <*>
343 1cd563e2 Iustin Pop
          genNameNE
344 c66f09f5 Iustin Pop
      _ -> fail $ "Undefined arbitrary for opcode " ++ op_id
345 aed2325f Iustin Pop
346 516a0e94 Michele Tartara
-- | Generates one element of a reason trail
347 516a0e94 Michele Tartara
genReasonElem :: Gen ReasonElem
348 516a0e94 Michele Tartara
genReasonElem = (,,) <$> genFQDN <*> genFQDN <*> arbitrary
349 516a0e94 Michele Tartara
350 516a0e94 Michele Tartara
-- | Generates a reason trail
351 516a0e94 Michele Tartara
genReasonTrail :: Gen ReasonTrail
352 516a0e94 Michele Tartara
genReasonTrail = do
353 516a0e94 Michele Tartara
  size <- choose (0, 10)
354 516a0e94 Michele Tartara
  vectorOf size genReasonElem
355 516a0e94 Michele Tartara
356 4a826364 Iustin Pop
instance Arbitrary OpCodes.CommonOpParams where
357 4a826364 Iustin Pop
  arbitrary = OpCodes.CommonOpParams <$> arbitrary <*> arbitrary <*>
358 516a0e94 Michele Tartara
                arbitrary <*> resize 5 arbitrary <*> genMaybe genName <*>
359 516a0e94 Michele Tartara
                genReasonTrail
360 4a826364 Iustin Pop
361 c7d249d0 Iustin Pop
-- * Helper functions
362 c7d249d0 Iustin Pop
363 c66f09f5 Iustin Pop
-- | Empty JSObject.
364 c66f09f5 Iustin Pop
emptyJSObject :: J.JSObject J.JSValue
365 c66f09f5 Iustin Pop
emptyJSObject = J.toJSObject []
366 c66f09f5 Iustin Pop
367 c66f09f5 Iustin Pop
-- | Empty maybe unchecked dictionary.
368 c66f09f5 Iustin Pop
emptyMUD :: Gen (Maybe (J.JSObject J.JSValue))
369 5006418e Iustin Pop
emptyMUD = genMaybe $ pure emptyJSObject
370 c66f09f5 Iustin Pop
371 c66f09f5 Iustin Pop
-- | Generates an empty container.
372 c66f09f5 Iustin Pop
genEmptyContainer :: (Ord a) => Gen (GenericContainer a b)
373 c66f09f5 Iustin Pop
genEmptyContainer = pure . GenericContainer $ Map.fromList []
374 c66f09f5 Iustin Pop
375 c7d249d0 Iustin Pop
-- | Generates list of disk indices.
376 c7d249d0 Iustin Pop
genDiskIndices :: Gen [DiskIndex]
377 c7d249d0 Iustin Pop
genDiskIndices = do
378 c7d249d0 Iustin Pop
  cnt <- choose (0, C.maxDisks)
379 df8578fb Iustin Pop
  genUniquesList cnt arbitrary
380 c7d249d0 Iustin Pop
381 c7d249d0 Iustin Pop
-- | Generates a list of node names.
382 c7d249d0 Iustin Pop
genNodeNames :: Gen [String]
383 5006418e Iustin Pop
genNodeNames = resize maxNodes (listOf genFQDN)
384 c7d249d0 Iustin Pop
385 c66f09f5 Iustin Pop
-- | Generates a list of node names in non-empty string type.
386 c66f09f5 Iustin Pop
genNodeNamesNE :: Gen [NonEmptyString]
387 417ab39c Iustin Pop
genNodeNamesNE = genNodeNames >>= mapM mkNonEmpty
388 c66f09f5 Iustin Pop
389 c7d249d0 Iustin Pop
-- | Gets a node name in non-empty type.
390 c7d249d0 Iustin Pop
genNodeNameNE :: Gen NonEmptyString
391 5006418e Iustin Pop
genNodeNameNE = genFQDN >>= mkNonEmpty
392 c7d249d0 Iustin Pop
393 5ef4fbb1 Iustin Pop
-- | Gets a name (non-fqdn) in non-empty type.
394 5ef4fbb1 Iustin Pop
genNameNE :: Gen NonEmptyString
395 5006418e Iustin Pop
genNameNE = genName >>= mkNonEmpty
396 5ef4fbb1 Iustin Pop
397 398e9066 Iustin Pop
-- | Gets a list of names (non-fqdn) in non-empty type.
398 398e9066 Iustin Pop
genNamesNE :: Gen [NonEmptyString]
399 398e9066 Iustin Pop
genNamesNE = resize maxNodes (listOf genNameNE)
400 398e9066 Iustin Pop
401 5ef4fbb1 Iustin Pop
-- | Returns a list of non-empty fields.
402 5ef4fbb1 Iustin Pop
genFieldsNE :: Gen [NonEmptyString]
403 5006418e Iustin Pop
genFieldsNE = genFields >>= mapM mkNonEmpty
404 5ef4fbb1 Iustin Pop
405 8d239fa4 Iustin Pop
-- | Generate a 3-byte MAC prefix.
406 8d239fa4 Iustin Pop
genMacPrefix :: Gen NonEmptyString
407 8d239fa4 Iustin Pop
genMacPrefix = do
408 8d239fa4 Iustin Pop
  octets <- vectorOf 3 $ choose (0::Int, 255)
409 8d239fa4 Iustin Pop
  mkNonEmpty . intercalate ":" $ map (printf "%02x") octets
410 8d239fa4 Iustin Pop
411 4a826364 Iustin Pop
-- | Arbitrary instance for MetaOpCode, defined here due to TH ordering.
412 4a826364 Iustin Pop
$(genArbitrary ''OpCodes.MetaOpCode)
413 4a826364 Iustin Pop
414 f56013fd Iustin Pop
-- | Small helper to check for a failed JSON deserialisation
415 f56013fd Iustin Pop
isJsonError :: J.Result a -> Bool
416 f56013fd Iustin Pop
isJsonError (J.Error _) = True
417 f56013fd Iustin Pop
isJsonError _           = False
418 f56013fd Iustin Pop
419 aed2325f Iustin Pop
-- * Test cases
420 aed2325f Iustin Pop
421 aed2325f Iustin Pop
-- | Check that opcode serialization is idempotent.
422 20bc5360 Iustin Pop
prop_serialization :: OpCodes.OpCode -> Property
423 63b068c1 Iustin Pop
prop_serialization = testSerialisation
424 aed2325f Iustin Pop
425 aed2325f Iustin Pop
-- | Check that Python and Haskell defined the same opcode list.
426 20bc5360 Iustin Pop
case_AllDefined :: HUnit.Assertion
427 20bc5360 Iustin Pop
case_AllDefined = do
428 9b773665 Iustin Pop
  let py_ops = sort C.opcodesOpIds
429 9b773665 Iustin Pop
      hs_ops = sort OpCodes.allOpIDs
430 9b773665 Iustin Pop
      extra_py = py_ops \\ hs_ops
431 aed2325f Iustin Pop
      extra_hs = hs_ops \\ py_ops
432 9b773665 Iustin Pop
  HUnit.assertBool ("Missing OpCodes from the Haskell code:\n" ++
433 9b773665 Iustin Pop
                    unlines extra_py) (null extra_py)
434 aed2325f Iustin Pop
  HUnit.assertBool ("Extra OpCodes in the Haskell code code:\n" ++
435 aed2325f Iustin Pop
                    unlines extra_hs) (null extra_hs)
436 aed2325f Iustin Pop
437 aed2325f Iustin Pop
-- | Custom HUnit test case that forks a Python process and checks
438 aed2325f Iustin Pop
-- correspondence between Haskell-generated OpCodes and their Python
439 aed2325f Iustin Pop
-- decoded, validated and re-encoded version.
440 aed2325f Iustin Pop
--
441 aed2325f Iustin Pop
-- Note that we have a strange beast here: since launching Python is
442 aed2325f Iustin Pop
-- expensive, we don't do this via a usual QuickProperty, since that's
443 aed2325f Iustin Pop
-- slow (I've tested it, and it's indeed quite slow). Rather, we use a
444 aed2325f Iustin Pop
-- single HUnit assertion, and in it we manually use QuickCheck to
445 aed2325f Iustin Pop
-- generate 500 opcodes times the number of defined opcodes, which
446 aed2325f Iustin Pop
-- then we pass in bulk to Python. The drawbacks to this method are
447 aed2325f Iustin Pop
-- two fold: we cannot control the number of generated opcodes, since
448 aed2325f Iustin Pop
-- HUnit assertions don't get access to the test options, and for the
449 aed2325f Iustin Pop
-- same reason we can't run a repeatable seed. We should probably find
450 aed2325f Iustin Pop
-- a better way to do this, for example by having a
451 aed2325f Iustin Pop
-- separately-launched Python process (if not running the tests would
452 aed2325f Iustin Pop
-- be skipped).
453 d1ac695f Iustin Pop
case_py_compat_types :: HUnit.Assertion
454 d1ac695f Iustin Pop
case_py_compat_types = do
455 086ad4cf Iustin Pop
  let num_opcodes = length OpCodes.allOpIDs * 100
456 72747d91 Iustin Pop
  opcodes <- genSample (vectorOf num_opcodes
457 72747d91 Iustin Pop
                                   (arbitrary::Gen OpCodes.MetaOpCode))
458 72747d91 Iustin Pop
  let with_sum = map (\o -> (OpCodes.opSummary $
459 ad1c1e41 Iustin Pop
                             OpCodes.metaOpCode o, o)) opcodes
460 aed2325f Iustin Pop
      serialized = J.encode opcodes
461 dc4b5c42 Iustin Pop
  -- check for non-ASCII fields, usually due to 'arbitrary :: String'
462 dc4b5c42 Iustin Pop
  mapM_ (\op -> when (any (not . isAscii) (J.encode op)) .
463 dc4b5c42 Iustin Pop
                HUnit.assertFailure $
464 dc4b5c42 Iustin Pop
                  "OpCode has non-ASCII fields: " ++ show op
465 dc4b5c42 Iustin Pop
        ) opcodes
466 aed2325f Iustin Pop
  py_stdout <-
467 aed2325f Iustin Pop
     runPython "from ganeti import opcodes\n\
468 aed2325f Iustin Pop
               \import sys\n\
469 aed2325f Iustin Pop
               \from ganeti import serializer\n\
470 aed2325f Iustin Pop
               \op_data = serializer.Load(sys.stdin.read())\n\
471 aed2325f Iustin Pop
               \decoded = [opcodes.OpCode.LoadOpCode(o) for o in op_data]\n\
472 aed2325f Iustin Pop
               \for op in decoded:\n\
473 aed2325f Iustin Pop
               \  op.Validate(True)\n\
474 ad1c1e41 Iustin Pop
               \encoded = [(op.Summary(), op.__getstate__())\n\
475 ad1c1e41 Iustin Pop
               \           for op in decoded]\n\
476 aed2325f Iustin Pop
               \print serializer.Dump(encoded)" serialized
477 aed2325f Iustin Pop
     >>= checkPythonResult
478 ad1c1e41 Iustin Pop
  let deserialised =
479 ad1c1e41 Iustin Pop
        J.decode py_stdout::J.Result [(String, OpCodes.MetaOpCode)]
480 aed2325f Iustin Pop
  decoded <- case deserialised of
481 aed2325f Iustin Pop
               J.Ok ops -> return ops
482 aed2325f Iustin Pop
               J.Error msg ->
483 aed2325f Iustin Pop
                 HUnit.assertFailure ("Unable to decode opcodes: " ++ msg)
484 aed2325f Iustin Pop
                 -- this already raised an expection, but we need it
485 aed2325f Iustin Pop
                 -- for proper types
486 aed2325f Iustin Pop
                 >> fail "Unable to decode opcodes"
487 aed2325f Iustin Pop
  HUnit.assertEqual "Mismatch in number of returned opcodes"
488 ad1c1e41 Iustin Pop
    (length decoded) (length with_sum)
489 aed2325f Iustin Pop
  mapM_ (uncurry (HUnit.assertEqual "Different result after encoding/decoding")
490 ad1c1e41 Iustin Pop
        ) $ zip decoded with_sum
491 aed2325f Iustin Pop
492 d1ac695f Iustin Pop
-- | Custom HUnit test case that forks a Python process and checks
493 d1ac695f Iustin Pop
-- correspondence between Haskell OpCodes fields and their Python
494 d1ac695f Iustin Pop
-- equivalent.
495 d1ac695f Iustin Pop
case_py_compat_fields :: HUnit.Assertion
496 d1ac695f Iustin Pop
case_py_compat_fields = do
497 d1ac695f Iustin Pop
  let hs_fields = sort $ map (\op_id -> (op_id, OpCodes.allOpFields op_id))
498 d1ac695f Iustin Pop
                         OpCodes.allOpIDs
499 d1ac695f Iustin Pop
  py_stdout <-
500 d1ac695f Iustin Pop
     runPython "from ganeti import opcodes\n\
501 d1ac695f Iustin Pop
               \import sys\n\
502 d1ac695f Iustin Pop
               \from ganeti import serializer\n\
503 d1ac695f Iustin Pop
               \fields = [(k, sorted([p[0] for p in v.OP_PARAMS]))\n\
504 d1ac695f Iustin Pop
               \           for k, v in opcodes.OP_MAPPING.items()]\n\
505 d1ac695f Iustin Pop
               \print serializer.Dump(fields)" ""
506 d1ac695f Iustin Pop
     >>= checkPythonResult
507 d1ac695f Iustin Pop
  let deserialised = J.decode py_stdout::J.Result [(String, [String])]
508 d1ac695f Iustin Pop
  py_fields <- case deserialised of
509 d1ac695f Iustin Pop
                 J.Ok v -> return $ sort v
510 d1ac695f Iustin Pop
                 J.Error msg ->
511 d1ac695f Iustin Pop
                   HUnit.assertFailure ("Unable to decode op fields: " ++ msg)
512 d1ac695f Iustin Pop
                   -- this already raised an expection, but we need it
513 d1ac695f Iustin Pop
                   -- for proper types
514 d1ac695f Iustin Pop
                   >> fail "Unable to decode op fields"
515 d1ac695f Iustin Pop
  HUnit.assertEqual "Mismatch in number of returned opcodes"
516 d1ac695f Iustin Pop
    (length hs_fields) (length py_fields)
517 d1ac695f Iustin Pop
  HUnit.assertEqual "Mismatch in defined OP_IDs"
518 d1ac695f Iustin Pop
    (map fst hs_fields) (map fst py_fields)
519 d1ac695f Iustin Pop
  mapM_ (\((py_id, py_flds), (hs_id, hs_flds)) -> do
520 d1ac695f Iustin Pop
           HUnit.assertEqual "Mismatch in OP_ID" py_id hs_id
521 d1ac695f Iustin Pop
           HUnit.assertEqual ("Mismatch in fields for " ++ hs_id)
522 d1ac695f Iustin Pop
             py_flds hs_flds
523 d1ac695f Iustin Pop
        ) $ zip py_fields hs_fields
524 d1ac695f Iustin Pop
525 4a826364 Iustin Pop
-- | Checks that setOpComment works correctly.
526 4a826364 Iustin Pop
prop_setOpComment :: OpCodes.MetaOpCode -> String -> Property
527 4a826364 Iustin Pop
prop_setOpComment op comment =
528 4a826364 Iustin Pop
  let (OpCodes.MetaOpCode common _) = OpCodes.setOpComment comment op
529 4a826364 Iustin Pop
  in OpCodes.opComment common ==? Just comment
530 4a826364 Iustin Pop
531 f56013fd Iustin Pop
-- | Tests wrong tag object building (cluster takes only jsnull, the
532 f56013fd Iustin Pop
-- other take a string, so we test the opposites).
533 f56013fd Iustin Pop
case_TagObject_fail :: Assertion
534 f56013fd Iustin Pop
case_TagObject_fail =
535 f56013fd Iustin Pop
  mapM_ (\(t, j) -> assertEqual (show t ++ "/" ++ J.encode j) Nothing $
536 f56013fd Iustin Pop
                    tagObjectFrom t j)
537 f56013fd Iustin Pop
    [ (TagTypeCluster,  J.showJSON "abc")
538 f56013fd Iustin Pop
    , (TagTypeInstance, J.JSNull)
539 f56013fd Iustin Pop
    , (TagTypeNode,     J.JSNull)
540 f56013fd Iustin Pop
    , (TagTypeGroup,    J.JSNull)
541 f56013fd Iustin Pop
    ]
542 f56013fd Iustin Pop
543 f56013fd Iustin Pop
-- | Tests wrong (negative) disk index.
544 f56013fd Iustin Pop
prop_mkDiskIndex_fail :: QuickCheck.Positive Int -> Property
545 f56013fd Iustin Pop
prop_mkDiskIndex_fail (Positive i) =
546 f56013fd Iustin Pop
  case mkDiskIndex (negate i) of
547 f56013fd Iustin Pop
    Bad msg -> printTestCase "error message " $
548 f56013fd Iustin Pop
               "Invalid value" `isPrefixOf` msg
549 f56013fd Iustin Pop
    Ok v -> failTest $ "Succeeded to build disk index '" ++ show v ++
550 f56013fd Iustin Pop
                       "' from negative value " ++ show (negate i)
551 f56013fd Iustin Pop
552 f56013fd Iustin Pop
-- | Tests a few invalid 'readRecreateDisks' cases.
553 f56013fd Iustin Pop
case_readRecreateDisks_fail :: Assertion
554 f56013fd Iustin Pop
case_readRecreateDisks_fail = do
555 f56013fd Iustin Pop
  assertBool "null" $
556 f56013fd Iustin Pop
    isJsonError (J.readJSON J.JSNull::J.Result RecreateDisksInfo)
557 f56013fd Iustin Pop
  assertBool "string" $
558 f56013fd Iustin Pop
    isJsonError (J.readJSON (J.showJSON "abc")::J.Result RecreateDisksInfo)
559 f56013fd Iustin Pop
560 f56013fd Iustin Pop
-- | Tests a few invalid 'readDdmOldChanges' cases.
561 f56013fd Iustin Pop
case_readDdmOldChanges_fail :: Assertion
562 f56013fd Iustin Pop
case_readDdmOldChanges_fail = do
563 f56013fd Iustin Pop
  assertBool "null" $
564 f56013fd Iustin Pop
    isJsonError (J.readJSON J.JSNull::J.Result DdmOldChanges)
565 f56013fd Iustin Pop
  assertBool "string" $
566 f56013fd Iustin Pop
    isJsonError (J.readJSON (J.showJSON "abc")::J.Result DdmOldChanges)
567 f56013fd Iustin Pop
568 f56013fd Iustin Pop
-- | Tests a few invalid 'readExportTarget' cases.
569 f56013fd Iustin Pop
case_readExportTarget_fail :: Assertion
570 f56013fd Iustin Pop
case_readExportTarget_fail = do
571 f56013fd Iustin Pop
  assertBool "null" $
572 f56013fd Iustin Pop
    isJsonError (J.readJSON J.JSNull::J.Result ExportTarget)
573 f56013fd Iustin Pop
  assertBool "int" $
574 f56013fd Iustin Pop
    isJsonError (J.readJSON (J.showJSON (5::Int))::J.Result ExportTarget)
575 f56013fd Iustin Pop
576 aed2325f Iustin Pop
testSuite "OpCodes"
577 20bc5360 Iustin Pop
            [ 'prop_serialization
578 20bc5360 Iustin Pop
            , 'case_AllDefined
579 d1ac695f Iustin Pop
            , 'case_py_compat_types
580 d1ac695f Iustin Pop
            , 'case_py_compat_fields
581 4a826364 Iustin Pop
            , 'prop_setOpComment
582 f56013fd Iustin Pop
            , 'case_TagObject_fail
583 f56013fd Iustin Pop
            , 'prop_mkDiskIndex_fail
584 f56013fd Iustin Pop
            , 'case_readRecreateDisks_fail
585 f56013fd Iustin Pop
            , 'case_readDdmOldChanges_fail
586 f56013fd Iustin Pop
            , 'case_readExportTarget_fail
587 aed2325f Iustin Pop
            ]