Migration and failover: add iallocator and target_node slots
[ganeti-local] / test / ganeti.luxi_unittest.py
1 #!/usr/bin/python
2 #
3
4 # Copyright (C) 2010 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 unittesting the luxi module"""
23
24
25 import unittest
26
27 from ganeti import constants
28 from ganeti import errors
29 from ganeti import luxi
30 from ganeti import serializer
31
32 import testutils
33
34
35 class TestLuxiParsing(testutils.GanetiTestCase):
36   def testParseRequest(self):
37     msg = serializer.DumpJson({
38       luxi.KEY_METHOD: "foo",
39       luxi.KEY_ARGS: ("bar", "baz", 123),
40       })
41
42     self.assertEqualValues(luxi.ParseRequest(msg),
43                            ("foo", ["bar", "baz", 123], None))
44
45     self.assertRaises(luxi.ProtocolError, luxi.ParseRequest,
46                       "this\"is {invalid, ]json data")
47
48     # No dict
49     self.assertRaises(luxi.ProtocolError, luxi.ParseRequest,
50                       serializer.DumpJson(123))
51
52     # Empty dict
53     self.assertRaises(luxi.ProtocolError, luxi.ParseRequest,
54                       serializer.DumpJson({ }))
55
56     # No arguments
57     self.assertRaises(luxi.ProtocolError, luxi.ParseRequest,
58                       serializer.DumpJson({ luxi.KEY_METHOD: "foo", }))
59
60     # No method
61     self.assertRaises(luxi.ProtocolError, luxi.ParseRequest,
62                       serializer.DumpJson({ luxi.KEY_ARGS: [], }))
63
64     # No method or arguments
65     self.assertRaises(luxi.ProtocolError, luxi.ParseRequest,
66                       serializer.DumpJson({ luxi.KEY_VERSION: 1, }))
67
68   def testParseRequestWithVersion(self):
69     msg = serializer.DumpJson({
70       luxi.KEY_METHOD: "version",
71       luxi.KEY_ARGS: (["some"], "args", 0, "here"),
72       luxi.KEY_VERSION: 20100101,
73       })
74
75     self.assertEqualValues(luxi.ParseRequest(msg),
76                            ("version", [["some"], "args", 0, "here"], 20100101))
77
78   def testParseResponse(self):
79     msg = serializer.DumpJson({
80       luxi.KEY_SUCCESS: True,
81       luxi.KEY_RESULT: None,
82       })
83
84     self.assertEqual(luxi.ParseResponse(msg), (True, None, None))
85
86     self.assertRaises(luxi.ProtocolError, luxi.ParseResponse,
87                       "this\"is {invalid, ]json data")
88
89     # No dict
90     self.assertRaises(luxi.ProtocolError, luxi.ParseResponse,
91                       serializer.DumpJson(123))
92
93     # Empty dict
94     self.assertRaises(luxi.ProtocolError, luxi.ParseResponse,
95                       serializer.DumpJson({ }))
96
97     # No success
98     self.assertRaises(luxi.ProtocolError, luxi.ParseResponse,
99                       serializer.DumpJson({ luxi.KEY_RESULT: True, }))
100
101     # No result
102     self.assertRaises(luxi.ProtocolError, luxi.ParseResponse,
103                       serializer.DumpJson({ luxi.KEY_SUCCESS: True, }))
104
105     # No result or success
106     self.assertRaises(luxi.ProtocolError, luxi.ParseResponse,
107                       serializer.DumpJson({ luxi.KEY_VERSION: 123, }))
108
109   def testParseResponseWithVersion(self):
110     msg = serializer.DumpJson({
111       luxi.KEY_SUCCESS: True,
112       luxi.KEY_RESULT: "Hello World",
113       luxi.KEY_VERSION: 19991234,
114       })
115
116     self.assertEqual(luxi.ParseResponse(msg), (True, "Hello World", 19991234))
117
118   def testFormatResponse(self):
119     for success, result in [(False, "error"), (True, "abc"),
120                             (True, { "a": 123, "b": None, })]:
121       msg = luxi.FormatResponse(success, result)
122       msgdata = serializer.LoadJson(msg)
123       self.assert_(luxi.KEY_SUCCESS in msgdata)
124       self.assert_(luxi.KEY_RESULT in msgdata)
125       self.assert_(luxi.KEY_VERSION not in msgdata)
126       self.assertEqualValues(msgdata,
127                              { luxi.KEY_SUCCESS: success,
128                                luxi.KEY_RESULT: result,
129                              })
130
131   def testFormatResponseWithVersion(self):
132     for success, result, version in [(False, "error", 123), (True, "abc", 999),
133                                      (True, { "a": 123, "b": None, }, 2010)]:
134       msg = luxi.FormatResponse(success, result, version=version)
135       msgdata = serializer.LoadJson(msg)
136       self.assert_(luxi.KEY_SUCCESS in msgdata)
137       self.assert_(luxi.KEY_RESULT in msgdata)
138       self.assert_(luxi.KEY_VERSION in msgdata)
139       self.assertEqualValues(msgdata,
140                              { luxi.KEY_SUCCESS: success,
141                                luxi.KEY_RESULT: result,
142                                luxi.KEY_VERSION: version,
143                              })
144
145   def testFormatRequest(self):
146     for method, args in [("a", []), ("b", [1, 2, 3])]:
147       msg = luxi.FormatRequest(method, args)
148       msgdata = serializer.LoadJson(msg)
149       self.assert_(luxi.KEY_METHOD in msgdata)
150       self.assert_(luxi.KEY_ARGS in msgdata)
151       self.assert_(luxi.KEY_VERSION not in msgdata)
152       self.assertEqualValues(msgdata,
153                              { luxi.KEY_METHOD: method,
154                                luxi.KEY_ARGS: args,
155                              })
156
157   def testFormatRequestWithVersion(self):
158     for method, args, version in [("fn1", [], 123), ("fn2", [1, 2, 3], 999)]:
159       msg = luxi.FormatRequest(method, args, version=version)
160       msgdata = serializer.LoadJson(msg)
161       self.assert_(luxi.KEY_METHOD in msgdata)
162       self.assert_(luxi.KEY_ARGS in msgdata)
163       self.assert_(luxi.KEY_VERSION in msgdata)
164       self.assertEqualValues(msgdata,
165                              { luxi.KEY_METHOD: method,
166                                luxi.KEY_ARGS: args,
167                                luxi.KEY_VERSION: version,
168                              })
169
170
171 class TestCallLuxiMethod(unittest.TestCase):
172   MY_LUXI_VERSION = 1234
173   assert constants.LUXI_VERSION != MY_LUXI_VERSION
174
175   def testSuccessNoVersion(self):
176     def _Cb(msg):
177       (method, args, version) = luxi.ParseRequest(msg)
178       self.assertEqual(method, "fn1")
179       self.assertEqual(args, "Hello World")
180       return luxi.FormatResponse(True, "x")
181
182     result = luxi.CallLuxiMethod(_Cb, "fn1", "Hello World")
183
184   def testServerVersionOnly(self):
185     def _Cb(msg):
186       (method, args, version) = luxi.ParseRequest(msg)
187       self.assertEqual(method, "fn1")
188       self.assertEqual(args, "Hello World")
189       return luxi.FormatResponse(True, "x", version=self.MY_LUXI_VERSION)
190
191     self.assertRaises(errors.LuxiError, luxi.CallLuxiMethod,
192                       _Cb, "fn1", "Hello World")
193
194   def testWithVersion(self):
195     def _Cb(msg):
196       (method, args, version) = luxi.ParseRequest(msg)
197       self.assertEqual(method, "fn99")
198       self.assertEqual(args, "xyz")
199       return luxi.FormatResponse(True, "y", version=self.MY_LUXI_VERSION)
200
201     self.assertEqual("y", luxi.CallLuxiMethod(_Cb, "fn99", "xyz",
202                                               version=self.MY_LUXI_VERSION))
203
204   def testVersionMismatch(self):
205     def _Cb(msg):
206       (method, args, version) = luxi.ParseRequest(msg)
207       self.assertEqual(method, "fn5")
208       self.assertEqual(args, "xyz")
209       return luxi.FormatResponse(True, "F", version=self.MY_LUXI_VERSION * 2)
210
211     self.assertRaises(errors.LuxiError, luxi.CallLuxiMethod,
212                       _Cb, "fn5", "xyz", version=self.MY_LUXI_VERSION)
213
214   def testError(self):
215     def _Cb(msg):
216       (method, args, version) = luxi.ParseRequest(msg)
217       self.assertEqual(method, "fnErr")
218       self.assertEqual(args, [])
219       err = errors.OpPrereqError("Test")
220       return luxi.FormatResponse(False, errors.EncodeException(err))
221
222     self.assertRaises(errors.OpPrereqError, luxi.CallLuxiMethod,
223                       _Cb, "fnErr", [])
224
225   def testErrorWithVersionMismatch(self):
226     def _Cb(msg):
227       (method, args, version) = luxi.ParseRequest(msg)
228       self.assertEqual(method, "fnErr")
229       self.assertEqual(args, [])
230       err = errors.OpPrereqError("TestVer")
231       return luxi.FormatResponse(False, errors.EncodeException(err),
232                                  version=self.MY_LUXI_VERSION * 2)
233
234     self.assertRaises(errors.LuxiError, luxi.CallLuxiMethod,
235                       _Cb, "fnErr", [],
236                       version=self.MY_LUXI_VERSION)
237
238   def testErrorWithVersion(self):
239     def _Cb(msg):
240       (method, args, version) = luxi.ParseRequest(msg)
241       self.assertEqual(method, "fn9")
242       self.assertEqual(args, [])
243       err = errors.OpPrereqError("TestVer")
244       return luxi.FormatResponse(False, errors.EncodeException(err),
245                                  version=self.MY_LUXI_VERSION)
246
247     self.assertRaises(errors.OpPrereqError, luxi.CallLuxiMethod,
248                       _Cb, "fn9", [],
249                       version=self.MY_LUXI_VERSION)
250
251
252 if __name__ == "__main__":
253   testutils.GanetiTestProgram()