Statistics
| Branch: | Tag: | Revision:

root / test / hs / Test / Ganeti / OpCodes.hs @ 06c2fb4a

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