Statistics
| Branch: | Tag: | Revision:

root / test / hs / Test / Ganeti / Luxi.hs @ 93f1e606

History | View | Annotate | Download (5.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 aed2325f Iustin Pop
Copyright (C) 2009, 2010, 2011, 2012 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.Luxi (testLuxi) where
30 aed2325f Iustin Pop
31 471b6c46 Iustin Pop
import Test.HUnit
32 aed2325f Iustin Pop
import Test.QuickCheck
33 aed2325f Iustin Pop
import Test.QuickCheck.Monadic (monadicIO, run, stop)
34 aed2325f Iustin Pop
35 471b6c46 Iustin Pop
import Data.List
36 aed2325f Iustin Pop
import Control.Applicative
37 aed2325f Iustin Pop
import Control.Concurrent (forkIO)
38 aed2325f Iustin Pop
import Control.Exception (bracket)
39 aed2325f Iustin Pop
import qualified Text.JSON as J
40 aed2325f Iustin Pop
41 aed2325f Iustin Pop
import Test.Ganeti.TestHelper
42 aed2325f Iustin Pop
import Test.Ganeti.TestCommon
43 aed2325f Iustin Pop
import Test.Ganeti.Query.Language (genFilter)
44 aed2325f Iustin Pop
import Test.Ganeti.OpCodes ()
45 aed2325f Iustin Pop
46 aed2325f Iustin Pop
import Ganeti.BasicTypes
47 aed2325f Iustin Pop
import qualified Ganeti.Luxi as Luxi
48 d79a6502 Petr Pudlak
import qualified Ganeti.UDSServer as US
49 aed2325f Iustin Pop
50 67e4fcf4 Iustin Pop
{-# ANN module "HLint: ignore Use camelCase" #-}
51 67e4fcf4 Iustin Pop
52 aed2325f Iustin Pop
-- * Luxi tests
53 aed2325f Iustin Pop
54 7022db83 Iustin Pop
$(genArbitrary ''Luxi.LuxiReq)
55 aed2325f Iustin Pop
56 aed2325f Iustin Pop
instance Arbitrary Luxi.LuxiOp where
57 aed2325f Iustin Pop
  arbitrary = do
58 aed2325f Iustin Pop
    lreq <- arbitrary
59 aed2325f Iustin Pop
    case lreq of
60 5006418e Iustin Pop
      Luxi.ReqQuery -> Luxi.Query <$> arbitrary <*> genFields <*> genFilter
61 5006418e Iustin Pop
      Luxi.ReqQueryFields -> Luxi.QueryFields <$> arbitrary <*> genFields
62 5006418e Iustin Pop
      Luxi.ReqQueryNodes -> Luxi.QueryNodes <$> listOf genFQDN <*>
63 5006418e Iustin Pop
                            genFields <*> arbitrary
64 aed2325f Iustin Pop
      Luxi.ReqQueryGroups -> Luxi.QueryGroups <$> arbitrary <*>
65 aed2325f Iustin Pop
                             arbitrary <*> arbitrary
66 795d035d Klaus Aehlig
      Luxi.ReqQueryNetworks -> Luxi.QueryNetworks <$> arbitrary <*>
67 795d035d Klaus Aehlig
                             arbitrary <*> arbitrary
68 5006418e Iustin Pop
      Luxi.ReqQueryInstances -> Luxi.QueryInstances <$> listOf genFQDN <*>
69 5006418e Iustin Pop
                                genFields <*> arbitrary
70 5006418e Iustin Pop
      Luxi.ReqQueryJobs -> Luxi.QueryJobs <$> arbitrary <*> genFields
71 aed2325f Iustin Pop
      Luxi.ReqQueryExports -> Luxi.QueryExports <$>
72 5006418e Iustin Pop
                              listOf genFQDN <*> arbitrary
73 5006418e Iustin Pop
      Luxi.ReqQueryConfigValues -> Luxi.QueryConfigValues <$> genFields
74 aed2325f Iustin Pop
      Luxi.ReqQueryClusterInfo -> pure Luxi.QueryClusterInfo
75 6e94b75c Jose A. Lopes
      Luxi.ReqQueryTags -> do
76 6e94b75c Jose A. Lopes
        kind <- arbitrary
77 6e94b75c Jose A. Lopes
        Luxi.QueryTags kind <$> genLuxiTagName kind
78 5b11f8db Iustin Pop
      Luxi.ReqSubmitJob -> Luxi.SubmitJob <$> resize maxOpCodes arbitrary
79 346c3037 Klaus Aehlig
      Luxi.ReqSubmitJobToDrainedQueue -> Luxi.SubmitJobToDrainedQueue <$>
80 346c3037 Klaus Aehlig
                                         resize maxOpCodes arbitrary
81 aed2325f Iustin Pop
      Luxi.ReqSubmitManyJobs -> Luxi.SubmitManyJobs <$>
82 5b11f8db Iustin Pop
                                resize maxOpCodes arbitrary
83 aed2325f Iustin Pop
      Luxi.ReqWaitForJobChange -> Luxi.WaitForJobChange <$> arbitrary <*>
84 5006418e Iustin Pop
                                  genFields <*> pure J.JSNull <*>
85 aed2325f Iustin Pop
                                  pure J.JSNull <*> arbitrary
86 d9d1e541 Klaus Aehlig
      Luxi.ReqPickupJob -> Luxi.PickupJob <$> arbitrary
87 aed2325f Iustin Pop
      Luxi.ReqArchiveJob -> Luxi.ArchiveJob <$> arbitrary
88 aed2325f Iustin Pop
      Luxi.ReqAutoArchiveJobs -> Luxi.AutoArchiveJobs <$> arbitrary <*>
89 aed2325f Iustin Pop
                                 arbitrary
90 aed2325f Iustin Pop
      Luxi.ReqCancelJob -> Luxi.CancelJob <$> arbitrary
91 f63ffb37 Michael Hanselmann
      Luxi.ReqChangeJobPriority -> Luxi.ChangeJobPriority <$> arbitrary <*>
92 f63ffb37 Michael Hanselmann
                                   arbitrary
93 aed2325f Iustin Pop
      Luxi.ReqSetDrainFlag -> Luxi.SetDrainFlag <$> arbitrary
94 aed2325f Iustin Pop
      Luxi.ReqSetWatcherPause -> Luxi.SetWatcherPause <$> arbitrary
95 aed2325f Iustin Pop
96 aed2325f Iustin Pop
-- | Simple check that encoding/decoding of LuxiOp works.
97 20bc5360 Iustin Pop
prop_CallEncoding :: Luxi.LuxiOp -> Property
98 20bc5360 Iustin Pop
prop_CallEncoding op =
99 d79a6502 Petr Pudlak
  (US.parseCall (Luxi.buildCall op) >>= uncurry Luxi.decodeLuxiCall) ==? Ok op
100 aed2325f Iustin Pop
101 aed2325f Iustin Pop
-- | Server ping-pong helper.
102 aed2325f Iustin Pop
luxiServerPong :: Luxi.Client -> IO ()
103 aed2325f Iustin Pop
luxiServerPong c = do
104 aed2325f Iustin Pop
  msg <- Luxi.recvMsgExt c
105 aed2325f Iustin Pop
  case msg of
106 aed2325f Iustin Pop
    Luxi.RecvOk m -> Luxi.sendMsg c m >> luxiServerPong c
107 aed2325f Iustin Pop
    _ -> return ()
108 aed2325f Iustin Pop
109 aed2325f Iustin Pop
-- | Client ping-pong helper.
110 aed2325f Iustin Pop
luxiClientPong :: Luxi.Client -> [String] -> IO [String]
111 aed2325f Iustin Pop
luxiClientPong c =
112 aed2325f Iustin Pop
  mapM (\m -> Luxi.sendMsg c m >> Luxi.recvMsg c)
113 aed2325f Iustin Pop
114 aed2325f Iustin Pop
-- | Monadic check that, given a server socket, we can connect via a
115 aed2325f Iustin Pop
-- client to it, and that we can send a list of arbitrary messages and
116 aed2325f Iustin Pop
-- get back what we sent.
117 20bc5360 Iustin Pop
prop_ClientServer :: [[DNSChar]] -> Property
118 20bc5360 Iustin Pop
prop_ClientServer dnschars = monadicIO $ do
119 aed2325f Iustin Pop
  let msgs = map (map dnsGetChar) dnschars
120 588d0ee4 Jose A. Lopes
  fpath <- run $ getTempFileName "luxitest"
121 aed2325f Iustin Pop
  -- we need to create the server first, otherwise (if we do it in the
122 aed2325f Iustin Pop
  -- forked thread) the client could try to connect to it before it's
123 aed2325f Iustin Pop
  -- ready
124 d605e261 Petr Pudlak
  server <- run $ Luxi.getLuxiServer False fpath
125 aed2325f Iustin Pop
  -- fork the server responder
126 aed2325f Iustin Pop
  _ <- run . forkIO $
127 aed2325f Iustin Pop
    bracket
128 aed2325f Iustin Pop
      (Luxi.acceptClient server)
129 5e671e0e Petr Pudlak
      (\c -> Luxi.closeClient c >> Luxi.closeServer server)
130 aed2325f Iustin Pop
      luxiServerPong
131 aed2325f Iustin Pop
  replies <- run $
132 aed2325f Iustin Pop
    bracket
133 d605e261 Petr Pudlak
      (Luxi.getLuxiClient fpath)
134 aed2325f Iustin Pop
      Luxi.closeClient
135 5b11f8db Iustin Pop
      (`luxiClientPong` msgs)
136 aed2325f Iustin Pop
  stop $ replies ==? msgs
137 aed2325f Iustin Pop
138 471b6c46 Iustin Pop
-- | Check that Python and Haskell define the same Luxi requests list.
139 471b6c46 Iustin Pop
case_AllDefined :: Assertion
140 471b6c46 Iustin Pop
case_AllDefined = do
141 471b6c46 Iustin Pop
  py_stdout <- runPython "from ganeti import luxi\n\
142 471b6c46 Iustin Pop
                         \print '\\n'.join(luxi.REQ_ALL)" "" >>=
143 471b6c46 Iustin Pop
               checkPythonResult
144 471b6c46 Iustin Pop
  let py_ops = sort $ lines py_stdout
145 471b6c46 Iustin Pop
      hs_ops = Luxi.allLuxiCalls
146 471b6c46 Iustin Pop
      extra_py = py_ops \\ hs_ops
147 471b6c46 Iustin Pop
      extra_hs = hs_ops \\ py_ops
148 471b6c46 Iustin Pop
  assertBool ("Luxi calls missing from Haskell code:\n" ++
149 471b6c46 Iustin Pop
              unlines extra_py) (null extra_py)
150 471b6c46 Iustin Pop
  assertBool ("Extra Luxi calls in the Haskell code code:\n" ++
151 471b6c46 Iustin Pop
              unlines extra_hs) (null extra_hs)
152 471b6c46 Iustin Pop
153 471b6c46 Iustin Pop
154 aed2325f Iustin Pop
testSuite "Luxi"
155 20bc5360 Iustin Pop
          [ 'prop_CallEncoding
156 20bc5360 Iustin Pop
          , 'prop_ClientServer
157 471b6c46 Iustin Pop
          , 'case_AllDefined
158 aed2325f Iustin Pop
          ]