Statistics
| Branch: | Tag: | Revision:

root / test / hs / Test / Ganeti / OpCodes.hs @ 66af5ec5

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