Statistics
| Branch: | Tag: | Revision:

root / test / hs / Test / Ganeti / OpCodes.hs @ 3039e2dc

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