bash_completion: Enable extglob while parsing file
[ganeti-local] / test / ganeti.rapi.testutils_unittest.py
1 #!/usr/bin/python
2 #
3
4 # Copyright (C) 2012 Google Inc.
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 # 02110-1301, USA.
20
21
22 """Script for testing ganeti.rapi.testutils"""
23
24 import unittest
25
26 from ganeti import compat
27 from ganeti import constants
28 from ganeti import errors
29 from ganeti import opcodes
30 from ganeti import luxi
31 from ganeti import rapi
32 from ganeti import utils
33
34 import ganeti.rapi.testutils
35 import ganeti.rapi.client
36
37 import testutils
38
39
40 KNOWN_UNUSED_LUXI = frozenset([
41   luxi.REQ_SUBMIT_MANY_JOBS,
42   luxi.REQ_ARCHIVE_JOB,
43   luxi.REQ_AUTO_ARCHIVE_JOBS,
44   luxi.REQ_QUERY_EXPORTS,
45   luxi.REQ_QUERY_CONFIG_VALUES,
46   luxi.REQ_QUERY_TAGS,
47   luxi.REQ_SET_DRAIN_FLAG,
48   luxi.REQ_SET_WATCHER_PAUSE,
49   ])
50
51
52 # Global variable for storing used LUXI calls
53 _used_luxi_calls = None
54
55
56 class TestHideInternalErrors(unittest.TestCase):
57   def test(self):
58     def inner():
59       raise errors.GenericError("error")
60
61     fn = rapi.testutils._HideInternalErrors(inner)
62
63     self.assertRaises(rapi.testutils.VerificationError, fn)
64
65
66 class TestVerifyOpInput(unittest.TestCase):
67   def testUnknownOpId(self):
68     voi = rapi.testutils.VerifyOpInput
69
70     self.assertRaises(rapi.testutils.VerificationError, voi, "UNK_OP_ID", None)
71
72   def testUnknownParameter(self):
73     voi = rapi.testutils.VerifyOpInput
74
75     self.assertRaises(rapi.testutils.VerificationError, voi,
76       opcodes.OpClusterRename.OP_ID, {
77       "unk": "unk",
78       })
79
80   def testWrongParameterValue(self):
81     voi = rapi.testutils.VerifyOpInput
82     self.assertRaises(rapi.testutils.VerificationError, voi,
83       opcodes.OpClusterRename.OP_ID, {
84       "name": object(),
85       })
86
87   def testSuccess(self):
88     voi = rapi.testutils.VerifyOpInput
89     voi(opcodes.OpClusterRename.OP_ID, {
90       "name": "new-name.example.com",
91       })
92
93
94 class TestVerifyOpResult(unittest.TestCase):
95   def testSuccess(self):
96     vor = rapi.testutils.VerifyOpResult
97
98     vor(opcodes.OpClusterVerify.OP_ID, {
99       constants.JOB_IDS_KEY: [
100         (False, "error message"),
101         ],
102       })
103
104   def testWrongResult(self):
105     vor = rapi.testutils.VerifyOpResult
106
107     self.assertRaises(rapi.testutils.VerificationError, vor,
108       opcodes.OpClusterVerify.OP_ID, [])
109
110   def testNoResultCheck(self):
111     vor = rapi.testutils.VerifyOpResult
112
113     assert opcodes.OpTestDummy.OP_RESULT is None
114
115     vor(opcodes.OpTestDummy.OP_ID, None)
116
117
118 class TestInputTestClient(unittest.TestCase):
119   def setUp(self):
120     self.cl = rapi.testutils.InputTestClient()
121
122   def tearDown(self):
123     _used_luxi_calls.update(self.cl._GetLuxiCalls())
124
125   def testGetInfo(self):
126     self.assertTrue(self.cl.GetInfo() is NotImplemented)
127
128   def testPrepareExport(self):
129     result = self.cl.PrepareExport("inst1.example.com",
130                                    constants.EXPORT_MODE_LOCAL)
131     self.assertTrue(result is NotImplemented)
132     self.assertRaises(rapi.testutils.VerificationError, self.cl.PrepareExport,
133                       "inst1.example.com", "###invalid###")
134
135   def testGetJobs(self):
136     self.assertTrue(self.cl.GetJobs() is NotImplemented)
137
138   def testQuery(self):
139     result = self.cl.Query(constants.QR_NODE, ["name"])
140     self.assertTrue(result is NotImplemented)
141
142   def testQueryFields(self):
143     result = self.cl.QueryFields(constants.QR_INSTANCE)
144     self.assertTrue(result is NotImplemented)
145
146   def testCancelJob(self):
147     self.assertTrue(self.cl.CancelJob("1") is NotImplemented)
148
149   def testGetNodes(self):
150     self.assertTrue(self.cl.GetNodes() is NotImplemented)
151
152   def testGetInstances(self):
153     self.assertTrue(self.cl.GetInstances() is NotImplemented)
154
155   def testGetGroups(self):
156     self.assertTrue(self.cl.GetGroups() is NotImplemented)
157
158   def testWaitForJobChange(self):
159     result = self.cl.WaitForJobChange("1", ["id"], None, None)
160     self.assertTrue(result is NotImplemented)
161
162
163 class CustomTestRunner(unittest.TextTestRunner):
164   def run(self, *args):
165     global _used_luxi_calls
166     assert _used_luxi_calls is None
167
168     diff = (KNOWN_UNUSED_LUXI - luxi.REQ_ALL)
169     assert not diff, "Non-existing LUXI calls listed as unused: %s" % diff
170
171     _used_luxi_calls = set()
172     try:
173       # Run actual tests
174       result = unittest.TextTestRunner.run(self, *args)
175
176       diff = _used_luxi_calls & KNOWN_UNUSED_LUXI
177       if diff:
178         raise AssertionError("LUXI methods marked as unused were called: %s" %
179                              utils.CommaJoin(diff))
180
181       diff = (luxi.REQ_ALL - KNOWN_UNUSED_LUXI - _used_luxi_calls)
182       if diff:
183         raise AssertionError("The following LUXI methods were not used: %s" %
184                              utils.CommaJoin(diff))
185     finally:
186       # Reset global variable
187       _used_luxi_calls = None
188
189     return result
190
191
192 if __name__ == "__main__":
193   testutils.GanetiTestProgram(testRunner=CustomTestRunner)