Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.cli_unittest.py @ 05484a24

History | View | Annotate | Download (31.2 kB)

1 2241e2b9 Iustin Pop
#!/usr/bin/python
2 2241e2b9 Iustin Pop
#
3 2241e2b9 Iustin Pop
4 f0b1bafe Iustin Pop
# Copyright (C) 2008, 2011 Google Inc.
5 2241e2b9 Iustin Pop
#
6 2241e2b9 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 2241e2b9 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 2241e2b9 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 2241e2b9 Iustin Pop
# (at your option) any later version.
10 2241e2b9 Iustin Pop
#
11 2241e2b9 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 2241e2b9 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 2241e2b9 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 2241e2b9 Iustin Pop
# General Public License for more details.
15 2241e2b9 Iustin Pop
#
16 2241e2b9 Iustin Pop
# You should have received a copy of the GNU General Public License
17 2241e2b9 Iustin Pop
# along with this program; if not, write to the Free Software
18 2241e2b9 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 2241e2b9 Iustin Pop
# 02110-1301, USA.
20 2241e2b9 Iustin Pop
21 2241e2b9 Iustin Pop
22 2241e2b9 Iustin Pop
"""Script for unittesting the cli module"""
23 2241e2b9 Iustin Pop
24 2241e2b9 Iustin Pop
import unittest
25 46fbdd04 Iustin Pop
from cStringIO import StringIO
26 2241e2b9 Iustin Pop
27 2241e2b9 Iustin Pop
import ganeti
28 2241e2b9 Iustin Pop
import testutils
29 25231ec5 Michael Hanselmann
30 2241e2b9 Iustin Pop
from ganeti import constants
31 2241e2b9 Iustin Pop
from ganeti import cli
32 4e338533 Michael Hanselmann
from ganeti import errors
33 4e338533 Michael Hanselmann
from ganeti import utils
34 ee3aedff Michael Hanselmann
from ganeti import objects
35 05484a24 Michael Hanselmann
from ganeti import qlang
36 a8469393 Iustin Pop
from ganeti.errors import OpPrereqError, ParameterError
37 2241e2b9 Iustin Pop
38 25231ec5 Michael Hanselmann
39 2241e2b9 Iustin Pop
class TestParseTimespec(unittest.TestCase):
40 2241e2b9 Iustin Pop
  """Testing case for ParseTimespec"""
41 2241e2b9 Iustin Pop
42 2241e2b9 Iustin Pop
  def testValidTimes(self):
43 2241e2b9 Iustin Pop
    """Test valid timespecs"""
44 2241e2b9 Iustin Pop
    test_data = [
45 2241e2b9 Iustin Pop
      ('1s', 1),
46 2241e2b9 Iustin Pop
      ('1', 1),
47 2241e2b9 Iustin Pop
      ('1m', 60),
48 2241e2b9 Iustin Pop
      ('1h', 60 * 60),
49 2241e2b9 Iustin Pop
      ('1d', 60 * 60 * 24),
50 2241e2b9 Iustin Pop
      ('1w', 60 * 60 * 24 * 7),
51 2241e2b9 Iustin Pop
      ('4h', 4 * 60 * 60),
52 2241e2b9 Iustin Pop
      ('61m', 61 * 60),
53 2241e2b9 Iustin Pop
      ]
54 2241e2b9 Iustin Pop
    for value, expected_result in test_data:
55 2241e2b9 Iustin Pop
      self.failUnlessEqual(cli.ParseTimespec(value), expected_result)
56 2241e2b9 Iustin Pop
57 2241e2b9 Iustin Pop
  def testInvalidTime(self):
58 2241e2b9 Iustin Pop
    """Test invalid timespecs"""
59 2241e2b9 Iustin Pop
    test_data = [
60 2241e2b9 Iustin Pop
      '1y',
61 2241e2b9 Iustin Pop
      '',
62 2241e2b9 Iustin Pop
      'aaa',
63 2241e2b9 Iustin Pop
      's',
64 2241e2b9 Iustin Pop
      ]
65 2241e2b9 Iustin Pop
    for value in test_data:
66 2241e2b9 Iustin Pop
      self.failUnlessRaises(OpPrereqError, cli.ParseTimespec, value)
67 2241e2b9 Iustin Pop
68 2241e2b9 Iustin Pop
69 a8469393 Iustin Pop
class TestSplitKeyVal(unittest.TestCase):
70 a8469393 Iustin Pop
  """Testing case for cli._SplitKeyVal"""
71 fcd62d84 Iustin Pop
  DATA = "a=b,c,no_d,-e"
72 fcd62d84 Iustin Pop
  RESULT = {"a": "b", "c": True, "d": False, "e": None}
73 a8469393 Iustin Pop
74 a8469393 Iustin Pop
  def testSplitKeyVal(self):
75 a8469393 Iustin Pop
    """Test splitting"""
76 a8469393 Iustin Pop
    self.failUnlessEqual(cli._SplitKeyVal("option", self.DATA), self.RESULT)
77 a8469393 Iustin Pop
78 a8469393 Iustin Pop
  def testDuplicateParam(self):
79 a8469393 Iustin Pop
    """Test duplicate parameters"""
80 a8469393 Iustin Pop
    for data in ("a=1,a=2", "a,no_a"):
81 a8469393 Iustin Pop
      self.failUnlessRaises(ParameterError, cli._SplitKeyVal,
82 a8469393 Iustin Pop
                            "option", data)
83 a8469393 Iustin Pop
84 4f31882e Guido Trotter
  def testEmptyData(self):
85 4f31882e Guido Trotter
    """Test how we handle splitting an empty string"""
86 4f31882e Guido Trotter
    self.failUnlessEqual(cli._SplitKeyVal("option", ""), {})
87 4f31882e Guido Trotter
88 8b46606c Guido Trotter
class TestIdentKeyVal(unittest.TestCase):
89 8b46606c Guido Trotter
  """Testing case for cli.check_ident_key_val"""
90 8b46606c Guido Trotter
91 8b46606c Guido Trotter
  def testIdentKeyVal(self):
92 8b46606c Guido Trotter
    """Test identkeyval"""
93 8b46606c Guido Trotter
    def cikv(value):
94 8b46606c Guido Trotter
      return cli.check_ident_key_val("option", "opt", value)
95 8b46606c Guido Trotter
96 8b46606c Guido Trotter
    self.assertEqual(cikv("foo:bar"), ("foo", {"bar": True}))
97 8b46606c Guido Trotter
    self.assertEqual(cikv("foo:bar=baz"), ("foo", {"bar": "baz"}))
98 8b46606c Guido Trotter
    self.assertEqual(cikv("bar:b=c,c=a"), ("bar", {"b": "c", "c": "a"}))
99 8b46606c Guido Trotter
    self.assertEqual(cikv("no_bar"), ("bar", False))
100 8b46606c Guido Trotter
    self.assertRaises(ParameterError, cikv, "no_bar:foo")
101 8b46606c Guido Trotter
    self.assertRaises(ParameterError, cikv, "no_bar:foo=baz")
102 8b46606c Guido Trotter
    self.assertEqual(cikv("-foo"), ("foo", None))
103 8b46606c Guido Trotter
    self.assertRaises(ParameterError, cikv, "-foo:a=c")
104 8b46606c Guido Trotter
105 a8469393 Iustin Pop
106 46fbdd04 Iustin Pop
class TestToStream(unittest.TestCase):
107 4e338533 Michael Hanselmann
  """Test the ToStream functions"""
108 46fbdd04 Iustin Pop
109 46fbdd04 Iustin Pop
  def testBasic(self):
110 46fbdd04 Iustin Pop
    for data in ["foo",
111 46fbdd04 Iustin Pop
                 "foo %s",
112 46fbdd04 Iustin Pop
                 "foo %(test)s",
113 46fbdd04 Iustin Pop
                 "foo %s %s",
114 46fbdd04 Iustin Pop
                 "",
115 46fbdd04 Iustin Pop
                 ]:
116 46fbdd04 Iustin Pop
      buf = StringIO()
117 46fbdd04 Iustin Pop
      cli._ToStream(buf, data)
118 46fbdd04 Iustin Pop
      self.failUnlessEqual(buf.getvalue(), data+'\n')
119 46fbdd04 Iustin Pop
120 46fbdd04 Iustin Pop
  def testParams(self):
121 46fbdd04 Iustin Pop
      buf = StringIO()
122 46fbdd04 Iustin Pop
      cli._ToStream(buf, "foo %s", 1)
123 46fbdd04 Iustin Pop
      self.failUnlessEqual(buf.getvalue(), "foo 1\n")
124 46fbdd04 Iustin Pop
      buf = StringIO()
125 46fbdd04 Iustin Pop
      cli._ToStream(buf, "foo %s", (15,16))
126 46fbdd04 Iustin Pop
      self.failUnlessEqual(buf.getvalue(), "foo (15, 16)\n")
127 46fbdd04 Iustin Pop
      buf = StringIO()
128 46fbdd04 Iustin Pop
      cli._ToStream(buf, "foo %s %s", "a", "b")
129 46fbdd04 Iustin Pop
      self.failUnlessEqual(buf.getvalue(), "foo a b\n")
130 46fbdd04 Iustin Pop
131 2ebf1568 Michael Hanselmann
132 2ebf1568 Michael Hanselmann
class TestGenerateTable(unittest.TestCase):
133 2ebf1568 Michael Hanselmann
  HEADERS = dict([("f%s" % i, "Field%s" % i) for i in range(5)])
134 2ebf1568 Michael Hanselmann
135 2ebf1568 Michael Hanselmann
  FIELDS1 = ["f1", "f2"]
136 2ebf1568 Michael Hanselmann
  DATA1 = [
137 2ebf1568 Michael Hanselmann
    ["abc", 1234],
138 2ebf1568 Michael Hanselmann
    ["foobar", 56],
139 2ebf1568 Michael Hanselmann
    ["b", -14],
140 2ebf1568 Michael Hanselmann
    ]
141 2ebf1568 Michael Hanselmann
142 2ebf1568 Michael Hanselmann
  def _test(self, headers, fields, separator, data,
143 2ebf1568 Michael Hanselmann
            numfields, unitfields, units, expected):
144 2ebf1568 Michael Hanselmann
    table = cli.GenerateTable(headers, fields, separator, data,
145 2ebf1568 Michael Hanselmann
                              numfields=numfields, unitfields=unitfields,
146 2ebf1568 Michael Hanselmann
                              units=units)
147 2ebf1568 Michael Hanselmann
    self.assertEqual(table, expected)
148 2ebf1568 Michael Hanselmann
149 2ebf1568 Michael Hanselmann
  def testPlain(self):
150 2ebf1568 Michael Hanselmann
    exp = [
151 2ebf1568 Michael Hanselmann
      "Field1 Field2",
152 2ebf1568 Michael Hanselmann
      "abc    1234",
153 2ebf1568 Michael Hanselmann
      "foobar 56",
154 2ebf1568 Michael Hanselmann
      "b      -14",
155 2ebf1568 Michael Hanselmann
      ]
156 2ebf1568 Michael Hanselmann
    self._test(self.HEADERS, self.FIELDS1, None, self.DATA1,
157 2ebf1568 Michael Hanselmann
               None, None, "m", exp)
158 2ebf1568 Michael Hanselmann
159 2ebf1568 Michael Hanselmann
  def testNoFields(self):
160 2ebf1568 Michael Hanselmann
    self._test(self.HEADERS, [], None, [[], []],
161 2ebf1568 Michael Hanselmann
               None, None, "m", ["", "", ""])
162 2ebf1568 Michael Hanselmann
    self._test(None, [], None, [[], []],
163 2ebf1568 Michael Hanselmann
               None, None, "m", ["", ""])
164 2ebf1568 Michael Hanselmann
165 2ebf1568 Michael Hanselmann
  def testSeparator(self):
166 2ebf1568 Michael Hanselmann
    for sep in ["#", ":", ",", "^", "!", "%", "|", "###", "%%", "!!!", "||"]:
167 2ebf1568 Michael Hanselmann
      exp = [
168 2ebf1568 Michael Hanselmann
        "Field1%sField2" % sep,
169 2ebf1568 Michael Hanselmann
        "abc%s1234" % sep,
170 2ebf1568 Michael Hanselmann
        "foobar%s56" % sep,
171 2ebf1568 Michael Hanselmann
        "b%s-14" % sep,
172 2ebf1568 Michael Hanselmann
        ]
173 2ebf1568 Michael Hanselmann
      self._test(self.HEADERS, self.FIELDS1, sep, self.DATA1,
174 2ebf1568 Michael Hanselmann
                 None, None, "m", exp)
175 2ebf1568 Michael Hanselmann
176 2ebf1568 Michael Hanselmann
  def testNoHeader(self):
177 2ebf1568 Michael Hanselmann
    exp = [
178 2ebf1568 Michael Hanselmann
      "abc    1234",
179 2ebf1568 Michael Hanselmann
      "foobar 56",
180 2ebf1568 Michael Hanselmann
      "b      -14",
181 2ebf1568 Michael Hanselmann
      ]
182 2ebf1568 Michael Hanselmann
    self._test(None, self.FIELDS1, None, self.DATA1,
183 2ebf1568 Michael Hanselmann
               None, None, "m", exp)
184 2ebf1568 Michael Hanselmann
185 2ebf1568 Michael Hanselmann
  def testUnknownField(self):
186 2ebf1568 Michael Hanselmann
    headers = {
187 2ebf1568 Michael Hanselmann
      "f1": "Field1",
188 2ebf1568 Michael Hanselmann
      }
189 2ebf1568 Michael Hanselmann
    exp = [
190 2ebf1568 Michael Hanselmann
      "Field1 UNKNOWN",
191 2ebf1568 Michael Hanselmann
      "abc    1234",
192 2ebf1568 Michael Hanselmann
      "foobar 56",
193 2ebf1568 Michael Hanselmann
      "b      -14",
194 2ebf1568 Michael Hanselmann
      ]
195 2ebf1568 Michael Hanselmann
    self._test(headers, ["f1", "UNKNOWN"], None, self.DATA1,
196 2ebf1568 Michael Hanselmann
               None, None, "m", exp)
197 2ebf1568 Michael Hanselmann
198 2ebf1568 Michael Hanselmann
  def testNumfields(self):
199 2ebf1568 Michael Hanselmann
    fields = ["f1", "f2", "f3"]
200 2ebf1568 Michael Hanselmann
    data = [
201 2ebf1568 Michael Hanselmann
      ["abc", 1234, 0],
202 2ebf1568 Michael Hanselmann
      ["foobar", 56, 3],
203 2ebf1568 Michael Hanselmann
      ["b", -14, "-"],
204 2ebf1568 Michael Hanselmann
      ]
205 2ebf1568 Michael Hanselmann
    exp = [
206 2ebf1568 Michael Hanselmann
      "Field1 Field2 Field3",
207 2ebf1568 Michael Hanselmann
      "abc      1234      0",
208 2ebf1568 Michael Hanselmann
      "foobar     56      3",
209 2ebf1568 Michael Hanselmann
      "b         -14      -",
210 2ebf1568 Michael Hanselmann
      ]
211 2ebf1568 Michael Hanselmann
    self._test(self.HEADERS, fields, None, data,
212 2ebf1568 Michael Hanselmann
               ["f2", "f3"], None, "m", exp)
213 2ebf1568 Michael Hanselmann
214 2ebf1568 Michael Hanselmann
  def testUnitfields(self):
215 2ebf1568 Michael Hanselmann
    expnosep = [
216 2ebf1568 Michael Hanselmann
      "Field1 Field2 Field3",
217 2ebf1568 Michael Hanselmann
      "abc      1234     0M",
218 2ebf1568 Michael Hanselmann
      "foobar     56     3M",
219 2ebf1568 Michael Hanselmann
      "b         -14      -",
220 2ebf1568 Michael Hanselmann
      ]
221 2ebf1568 Michael Hanselmann
222 2ebf1568 Michael Hanselmann
    expsep = [
223 2ebf1568 Michael Hanselmann
      "Field1:Field2:Field3",
224 2ebf1568 Michael Hanselmann
      "abc:1234:0M",
225 2ebf1568 Michael Hanselmann
      "foobar:56:3M",
226 2ebf1568 Michael Hanselmann
      "b:-14:-",
227 2ebf1568 Michael Hanselmann
      ]
228 2ebf1568 Michael Hanselmann
229 2ebf1568 Michael Hanselmann
    for sep, expected in [(None, expnosep), (":", expsep)]:
230 2ebf1568 Michael Hanselmann
      fields = ["f1", "f2", "f3"]
231 2ebf1568 Michael Hanselmann
      data = [
232 2ebf1568 Michael Hanselmann
        ["abc", 1234, 0],
233 2ebf1568 Michael Hanselmann
        ["foobar", 56, 3],
234 2ebf1568 Michael Hanselmann
        ["b", -14, "-"],
235 2ebf1568 Michael Hanselmann
        ]
236 2ebf1568 Michael Hanselmann
      self._test(self.HEADERS, fields, sep, data,
237 2ebf1568 Michael Hanselmann
                 ["f2", "f3"], ["f3"], "h", expected)
238 2ebf1568 Michael Hanselmann
239 2ebf1568 Michael Hanselmann
  def testUnusual(self):
240 2ebf1568 Michael Hanselmann
    data = [
241 2ebf1568 Michael Hanselmann
      ["%", "xyz"],
242 2ebf1568 Michael Hanselmann
      ["%%", "abc"],
243 2ebf1568 Michael Hanselmann
      ]
244 2ebf1568 Michael Hanselmann
    exp = [
245 2ebf1568 Michael Hanselmann
      "Field1 Field2",
246 2ebf1568 Michael Hanselmann
      "%      xyz",
247 2ebf1568 Michael Hanselmann
      "%%     abc",
248 2ebf1568 Michael Hanselmann
      ]
249 2ebf1568 Michael Hanselmann
    self._test(self.HEADERS, ["f1", "f2"], None, data,
250 2ebf1568 Michael Hanselmann
               None, None, "m", exp)
251 2ebf1568 Michael Hanselmann
252 2ebf1568 Michael Hanselmann
253 ee3aedff Michael Hanselmann
class TestFormatQueryResult(unittest.TestCase):
254 ee3aedff Michael Hanselmann
  def test(self):
255 ee3aedff Michael Hanselmann
    fields = [
256 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="name", title="Name",
257 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_TEXT),
258 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="size", title="Size",
259 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_NUMBER),
260 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="act", title="Active",
261 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_BOOL),
262 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="mem", title="Memory",
263 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_UNIT),
264 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="other", title="SomeList",
265 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_OTHER),
266 ee3aedff Michael Hanselmann
      ]
267 ee3aedff Michael Hanselmann
268 ee3aedff Michael Hanselmann
    response = objects.QueryResponse(fields=fields, data=[
269 cfb084ae René Nussbaumer
      [(constants.RS_NORMAL, "nodeA"), (constants.RS_NORMAL, 128),
270 cfb084ae René Nussbaumer
       (constants.RS_NORMAL, False), (constants.RS_NORMAL, 1468006),
271 cfb084ae René Nussbaumer
       (constants.RS_NORMAL, [])],
272 cfb084ae René Nussbaumer
      [(constants.RS_NORMAL, "other"), (constants.RS_NORMAL, 512),
273 cfb084ae René Nussbaumer
       (constants.RS_NORMAL, True), (constants.RS_NORMAL, 16),
274 cfb084ae René Nussbaumer
       (constants.RS_NORMAL, [1, 2, 3])],
275 cfb084ae René Nussbaumer
      [(constants.RS_NORMAL, "xyz"), (constants.RS_NORMAL, 1024),
276 cfb084ae René Nussbaumer
       (constants.RS_NORMAL, True), (constants.RS_NORMAL, 4096),
277 cfb084ae René Nussbaumer
       (constants.RS_NORMAL, [{}, {}])],
278 ee3aedff Michael Hanselmann
      ])
279 ee3aedff Michael Hanselmann
280 ee3aedff Michael Hanselmann
    self.assertEqual(cli.FormatQueryResult(response, unit="h", header=True),
281 ee3aedff Michael Hanselmann
      (cli.QR_NORMAL, [
282 ee3aedff Michael Hanselmann
      "Name  Size Active Memory SomeList",
283 ee3aedff Michael Hanselmann
      "nodeA  128 N        1.4T []",
284 ee3aedff Michael Hanselmann
      "other  512 Y         16M [1, 2, 3]",
285 ee3aedff Michael Hanselmann
      "xyz   1024 Y        4.0G [{}, {}]",
286 ee3aedff Michael Hanselmann
      ]))
287 ee3aedff Michael Hanselmann
288 ee3aedff Michael Hanselmann
  def testTimestampAndUnit(self):
289 ee3aedff Michael Hanselmann
    fields = [
290 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="name", title="Name",
291 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_TEXT),
292 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="size", title="Size",
293 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_UNIT),
294 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="mtime", title="ModTime",
295 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_TIMESTAMP),
296 ee3aedff Michael Hanselmann
      ]
297 ee3aedff Michael Hanselmann
298 ee3aedff Michael Hanselmann
    response = objects.QueryResponse(fields=fields, data=[
299 cfb084ae René Nussbaumer
      [(constants.RS_NORMAL, "a"), (constants.RS_NORMAL, 1024),
300 cfb084ae René Nussbaumer
       (constants.RS_NORMAL, 0)],
301 cfb084ae René Nussbaumer
      [(constants.RS_NORMAL, "b"), (constants.RS_NORMAL, 144996),
302 cfb084ae René Nussbaumer
       (constants.RS_NORMAL, 1291746295)],
303 ee3aedff Michael Hanselmann
      ])
304 ee3aedff Michael Hanselmann
305 ee3aedff Michael Hanselmann
    self.assertEqual(cli.FormatQueryResult(response, unit="m", header=True),
306 ee3aedff Michael Hanselmann
      (cli.QR_NORMAL, [
307 ee3aedff Michael Hanselmann
      "Name   Size ModTime",
308 ee3aedff Michael Hanselmann
      "a      1024 %s" % utils.FormatTime(0),
309 ee3aedff Michael Hanselmann
      "b    144996 %s" % utils.FormatTime(1291746295),
310 ee3aedff Michael Hanselmann
      ]))
311 ee3aedff Michael Hanselmann
312 ee3aedff Michael Hanselmann
  def testOverride(self):
313 ee3aedff Michael Hanselmann
    fields = [
314 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="name", title="Name",
315 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_TEXT),
316 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="cust", title="Custom",
317 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_OTHER),
318 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="xt", title="XTime",
319 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_TIMESTAMP),
320 ee3aedff Michael Hanselmann
      ]
321 ee3aedff Michael Hanselmann
322 ee3aedff Michael Hanselmann
    response = objects.QueryResponse(fields=fields, data=[
323 cfb084ae René Nussbaumer
      [(constants.RS_NORMAL, "x"), (constants.RS_NORMAL, ["a", "b", "c"]),
324 cfb084ae René Nussbaumer
       (constants.RS_NORMAL, 1234)],
325 cfb084ae René Nussbaumer
      [(constants.RS_NORMAL, "y"), (constants.RS_NORMAL, range(10)),
326 cfb084ae René Nussbaumer
       (constants.RS_NORMAL, 1291746295)],
327 ee3aedff Michael Hanselmann
      ])
328 ee3aedff Michael Hanselmann
329 ee3aedff Michael Hanselmann
    override = {
330 ee3aedff Michael Hanselmann
      "cust": (utils.CommaJoin, False),
331 ee3aedff Michael Hanselmann
      "xt": (hex, True),
332 ee3aedff Michael Hanselmann
      }
333 ee3aedff Michael Hanselmann
334 ee3aedff Michael Hanselmann
    self.assertEqual(cli.FormatQueryResult(response, unit="h", header=True,
335 ee3aedff Michael Hanselmann
                                           format_override=override),
336 ee3aedff Michael Hanselmann
      (cli.QR_NORMAL, [
337 ee3aedff Michael Hanselmann
      "Name Custom                            XTime",
338 ee3aedff Michael Hanselmann
      "x    a, b, c                           0x4d2",
339 ee3aedff Michael Hanselmann
      "y    0, 1, 2, 3, 4, 5, 6, 7, 8, 9 0x4cfe7bf7",
340 ee3aedff Michael Hanselmann
      ]))
341 ee3aedff Michael Hanselmann
342 ee3aedff Michael Hanselmann
  def testSeparator(self):
343 ee3aedff Michael Hanselmann
    fields = [
344 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="name", title="Name",
345 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_TEXT),
346 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="count", title="Count",
347 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_NUMBER),
348 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="desc", title="Description",
349 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_TEXT),
350 ee3aedff Michael Hanselmann
      ]
351 ee3aedff Michael Hanselmann
352 ee3aedff Michael Hanselmann
    response = objects.QueryResponse(fields=fields, data=[
353 cfb084ae René Nussbaumer
      [(constants.RS_NORMAL, "instance1.example.com"),
354 cfb084ae René Nussbaumer
       (constants.RS_NORMAL, 21125), (constants.RS_NORMAL, "Hello World!")],
355 cfb084ae René Nussbaumer
      [(constants.RS_NORMAL, "mail.other.net"),
356 cfb084ae René Nussbaumer
       (constants.RS_NORMAL, -9000), (constants.RS_NORMAL, "a,b,c")],
357 ee3aedff Michael Hanselmann
      ])
358 ee3aedff Michael Hanselmann
359 ee3aedff Michael Hanselmann
    for sep in [":", "|", "#", "|||", "###", "@@@", "@#@"]:
360 ee3aedff Michael Hanselmann
      for header in [None, "Name%sCount%sDescription" % (sep, sep)]:
361 ee3aedff Michael Hanselmann
        exp = []
362 ee3aedff Michael Hanselmann
        if header:
363 ee3aedff Michael Hanselmann
          exp.append(header)
364 ee3aedff Michael Hanselmann
        exp.extend([
365 ee3aedff Michael Hanselmann
          "instance1.example.com%s21125%sHello World!" % (sep, sep),
366 ee3aedff Michael Hanselmann
          "mail.other.net%s-9000%sa,b,c" % (sep, sep),
367 ee3aedff Michael Hanselmann
          ])
368 ee3aedff Michael Hanselmann
369 ee3aedff Michael Hanselmann
        self.assertEqual(cli.FormatQueryResult(response, separator=sep,
370 ee3aedff Michael Hanselmann
                                               header=bool(header)),
371 ee3aedff Michael Hanselmann
                         (cli.QR_NORMAL, exp))
372 ee3aedff Michael Hanselmann
373 ee3aedff Michael Hanselmann
  def testStatusWithUnknown(self):
374 ee3aedff Michael Hanselmann
    fields = [
375 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="id", title="ID",
376 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_NUMBER),
377 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="unk", title="unk",
378 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_UNKNOWN),
379 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="unavail", title="Unavail",
380 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_BOOL),
381 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="nodata", title="NoData",
382 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_TEXT),
383 a6070ef7 Michael Hanselmann
      objects.QueryFieldDefinition(name="offline", title="OffLine",
384 a6070ef7 Michael Hanselmann
                                   kind=constants.QFT_TEXT),
385 ee3aedff Michael Hanselmann
      ]
386 ee3aedff Michael Hanselmann
387 ee3aedff Michael Hanselmann
    response = objects.QueryResponse(fields=fields, data=[
388 cfb084ae René Nussbaumer
      [(constants.RS_NORMAL, 1), (constants.RS_UNKNOWN, None),
389 cfb084ae René Nussbaumer
       (constants.RS_NORMAL, False), (constants.RS_NORMAL, ""),
390 cfb084ae René Nussbaumer
       (constants.RS_OFFLINE, None)],
391 cfb084ae René Nussbaumer
      [(constants.RS_NORMAL, 2), (constants.RS_UNKNOWN, None),
392 cfb084ae René Nussbaumer
       (constants.RS_NODATA, None), (constants.RS_NORMAL, "x"),
393 cfb084ae René Nussbaumer
       (constants.RS_OFFLINE, None)],
394 cfb084ae René Nussbaumer
      [(constants.RS_NORMAL, 3), (constants.RS_UNKNOWN, None),
395 cfb084ae René Nussbaumer
       (constants.RS_NORMAL, False), (constants.RS_UNAVAIL, None),
396 cfb084ae René Nussbaumer
       (constants.RS_OFFLINE, None)],
397 ee3aedff Michael Hanselmann
      ])
398 ee3aedff Michael Hanselmann
399 ee3aedff Michael Hanselmann
    self.assertEqual(cli.FormatQueryResult(response, header=True,
400 f0b1bafe Iustin Pop
                                           separator="|", verbose=True),
401 ee3aedff Michael Hanselmann
      (cli.QR_UNKNOWN, [
402 a6070ef7 Michael Hanselmann
      "ID|unk|Unavail|NoData|OffLine",
403 a6070ef7 Michael Hanselmann
      "1|(unknown)|N||(offline)",
404 a6070ef7 Michael Hanselmann
      "2|(unknown)|(nodata)|x|(offline)",
405 a6070ef7 Michael Hanselmann
      "3|(unknown)|N|(unavail)|(offline)",
406 ee3aedff Michael Hanselmann
      ]))
407 f0b1bafe Iustin Pop
    self.assertEqual(cli.FormatQueryResult(response, header=True,
408 f0b1bafe Iustin Pop
                                           separator="|", verbose=False),
409 f0b1bafe Iustin Pop
      (cli.QR_UNKNOWN, [
410 f0b1bafe Iustin Pop
      "ID|unk|Unavail|NoData|OffLine",
411 f0b1bafe Iustin Pop
      "1|??|N||*",
412 f0b1bafe Iustin Pop
      "2|??|?|x|*",
413 f0b1bafe Iustin Pop
      "3|??|N|-|*",
414 f0b1bafe Iustin Pop
      ]))
415 ee3aedff Michael Hanselmann
416 ee3aedff Michael Hanselmann
  def testNoData(self):
417 ee3aedff Michael Hanselmann
    fields = [
418 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="id", title="ID",
419 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_NUMBER),
420 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="name", title="Name",
421 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_TEXT),
422 ee3aedff Michael Hanselmann
      ]
423 ee3aedff Michael Hanselmann
424 ee3aedff Michael Hanselmann
    response = objects.QueryResponse(fields=fields, data=[])
425 ee3aedff Michael Hanselmann
426 ee3aedff Michael Hanselmann
    self.assertEqual(cli.FormatQueryResult(response, header=True),
427 ee3aedff Michael Hanselmann
                     (cli.QR_NORMAL, ["ID Name"]))
428 ee3aedff Michael Hanselmann
429 ee3aedff Michael Hanselmann
  def testNoDataWithUnknown(self):
430 ee3aedff Michael Hanselmann
    fields = [
431 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="id", title="ID",
432 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_NUMBER),
433 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="unk", title="unk",
434 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_UNKNOWN),
435 ee3aedff Michael Hanselmann
      ]
436 ee3aedff Michael Hanselmann
437 ee3aedff Michael Hanselmann
    response = objects.QueryResponse(fields=fields, data=[])
438 ee3aedff Michael Hanselmann
439 ee3aedff Michael Hanselmann
    self.assertEqual(cli.FormatQueryResult(response, header=False),
440 ee3aedff Michael Hanselmann
                     (cli.QR_UNKNOWN, []))
441 ee3aedff Michael Hanselmann
442 ee3aedff Michael Hanselmann
  def testStatus(self):
443 ee3aedff Michael Hanselmann
    fields = [
444 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="id", title="ID",
445 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_NUMBER),
446 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="unavail", title="Unavail",
447 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_BOOL),
448 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="nodata", title="NoData",
449 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_TEXT),
450 a6070ef7 Michael Hanselmann
      objects.QueryFieldDefinition(name="offline", title="OffLine",
451 a6070ef7 Michael Hanselmann
                                   kind=constants.QFT_TEXT),
452 ee3aedff Michael Hanselmann
      ]
453 ee3aedff Michael Hanselmann
454 ee3aedff Michael Hanselmann
    response = objects.QueryResponse(fields=fields, data=[
455 cfb084ae René Nussbaumer
      [(constants.RS_NORMAL, 1), (constants.RS_NORMAL, False),
456 cfb084ae René Nussbaumer
       (constants.RS_NORMAL, ""), (constants.RS_OFFLINE, None)],
457 cfb084ae René Nussbaumer
      [(constants.RS_NORMAL, 2), (constants.RS_NODATA, None),
458 cfb084ae René Nussbaumer
       (constants.RS_NORMAL, "x"), (constants.RS_NORMAL, "abc")],
459 cfb084ae René Nussbaumer
      [(constants.RS_NORMAL, 3), (constants.RS_NORMAL, False),
460 cfb084ae René Nussbaumer
       (constants.RS_UNAVAIL, None), (constants.RS_OFFLINE, None)],
461 ee3aedff Michael Hanselmann
      ])
462 ee3aedff Michael Hanselmann
463 ee3aedff Michael Hanselmann
    self.assertEqual(cli.FormatQueryResult(response, header=False,
464 f0b1bafe Iustin Pop
                                           separator="|", verbose=True),
465 ee3aedff Michael Hanselmann
      (cli.QR_INCOMPLETE, [
466 a6070ef7 Michael Hanselmann
      "1|N||(offline)",
467 a6070ef7 Michael Hanselmann
      "2|(nodata)|x|abc",
468 a6070ef7 Michael Hanselmann
      "3|N|(unavail)|(offline)",
469 ee3aedff Michael Hanselmann
      ]))
470 f0b1bafe Iustin Pop
    self.assertEqual(cli.FormatQueryResult(response, header=False,
471 f0b1bafe Iustin Pop
                                           separator="|", verbose=False),
472 f0b1bafe Iustin Pop
      (cli.QR_INCOMPLETE, [
473 f0b1bafe Iustin Pop
      "1|N||*",
474 f0b1bafe Iustin Pop
      "2|?|x|abc",
475 f0b1bafe Iustin Pop
      "3|N|-|*",
476 f0b1bafe Iustin Pop
      ]))
477 ee3aedff Michael Hanselmann
478 ee3aedff Michael Hanselmann
  def testInvalidFieldType(self):
479 ee3aedff Michael Hanselmann
    fields = [
480 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="x", title="x",
481 ee3aedff Michael Hanselmann
                                   kind="#some#other#type"),
482 ee3aedff Michael Hanselmann
      ]
483 ee3aedff Michael Hanselmann
484 ee3aedff Michael Hanselmann
    response = objects.QueryResponse(fields=fields, data=[])
485 ee3aedff Michael Hanselmann
486 ee3aedff Michael Hanselmann
    self.assertRaises(NotImplementedError, cli.FormatQueryResult, response)
487 ee3aedff Michael Hanselmann
488 ee3aedff Michael Hanselmann
  def testInvalidFieldStatus(self):
489 ee3aedff Michael Hanselmann
    fields = [
490 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="x", title="x",
491 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_TEXT),
492 ee3aedff Michael Hanselmann
      ]
493 ee3aedff Michael Hanselmann
494 ee3aedff Michael Hanselmann
    response = objects.QueryResponse(fields=fields, data=[[(-1, None)]])
495 ee3aedff Michael Hanselmann
    self.assertRaises(NotImplementedError, cli.FormatQueryResult, response)
496 ee3aedff Michael Hanselmann
497 ee3aedff Michael Hanselmann
    response = objects.QueryResponse(fields=fields, data=[[(-1, "x")]])
498 ee3aedff Michael Hanselmann
    self.assertRaises(AssertionError, cli.FormatQueryResult, response)
499 ee3aedff Michael Hanselmann
500 ee3aedff Michael Hanselmann
  def testEmptyFieldTitle(self):
501 ee3aedff Michael Hanselmann
    fields = [
502 ee3aedff Michael Hanselmann
      objects.QueryFieldDefinition(name="x", title="",
503 ee3aedff Michael Hanselmann
                                   kind=constants.QFT_TEXT),
504 ee3aedff Michael Hanselmann
      ]
505 ee3aedff Michael Hanselmann
506 ee3aedff Michael Hanselmann
    response = objects.QueryResponse(fields=fields, data=[])
507 ee3aedff Michael Hanselmann
    self.assertRaises(AssertionError, cli.FormatQueryResult, response)
508 ee3aedff Michael Hanselmann
509 ee3aedff Michael Hanselmann
510 4e338533 Michael Hanselmann
class _MockJobPollCb(cli.JobPollCbBase, cli.JobPollReportCbBase):
511 4e338533 Michael Hanselmann
  def __init__(self, tc, job_id):
512 4e338533 Michael Hanselmann
    self.tc = tc
513 4e338533 Michael Hanselmann
    self.job_id = job_id
514 4e338533 Michael Hanselmann
    self._wfjcr = []
515 4e338533 Michael Hanselmann
    self._jobstatus = []
516 4e338533 Michael Hanselmann
    self._expect_notchanged = False
517 4e338533 Michael Hanselmann
    self._expect_log = []
518 4e338533 Michael Hanselmann
519 4e338533 Michael Hanselmann
  def CheckEmpty(self):
520 4e338533 Michael Hanselmann
    self.tc.assertFalse(self._wfjcr)
521 4e338533 Michael Hanselmann
    self.tc.assertFalse(self._jobstatus)
522 4e338533 Michael Hanselmann
    self.tc.assertFalse(self._expect_notchanged)
523 4e338533 Michael Hanselmann
    self.tc.assertFalse(self._expect_log)
524 4e338533 Michael Hanselmann
525 4e338533 Michael Hanselmann
  def AddWfjcResult(self, *args):
526 4e338533 Michael Hanselmann
    self._wfjcr.append(args)
527 4e338533 Michael Hanselmann
528 4e338533 Michael Hanselmann
  def AddQueryJobsResult(self, *args):
529 4e338533 Michael Hanselmann
    self._jobstatus.append(args)
530 4e338533 Michael Hanselmann
531 4e338533 Michael Hanselmann
  def WaitForJobChangeOnce(self, job_id, fields,
532 4e338533 Michael Hanselmann
                           prev_job_info, prev_log_serial):
533 4e338533 Michael Hanselmann
    self.tc.assertEqual(job_id, self.job_id)
534 4e338533 Michael Hanselmann
    self.tc.assertEqualValues(fields, ["status"])
535 4e338533 Michael Hanselmann
    self.tc.assertFalse(self._expect_notchanged)
536 4e338533 Michael Hanselmann
    self.tc.assertFalse(self._expect_log)
537 4e338533 Michael Hanselmann
538 4e338533 Michael Hanselmann
    (exp_prev_job_info, exp_prev_log_serial, result) = self._wfjcr.pop(0)
539 4e338533 Michael Hanselmann
    self.tc.assertEqualValues(prev_job_info, exp_prev_job_info)
540 4e338533 Michael Hanselmann
    self.tc.assertEqual(prev_log_serial, exp_prev_log_serial)
541 4e338533 Michael Hanselmann
542 4e338533 Michael Hanselmann
    if result == constants.JOB_NOTCHANGED:
543 4e338533 Michael Hanselmann
      self._expect_notchanged = True
544 4e338533 Michael Hanselmann
    elif result:
545 4e338533 Michael Hanselmann
      (_, logmsgs) = result
546 4e338533 Michael Hanselmann
      if logmsgs:
547 4e338533 Michael Hanselmann
        self._expect_log.extend(logmsgs)
548 4e338533 Michael Hanselmann
549 4e338533 Michael Hanselmann
    return result
550 4e338533 Michael Hanselmann
551 4e338533 Michael Hanselmann
  def QueryJobs(self, job_ids, fields):
552 4e338533 Michael Hanselmann
    self.tc.assertEqual(job_ids, [self.job_id])
553 4e338533 Michael Hanselmann
    self.tc.assertEqualValues(fields, ["status", "opstatus", "opresult"])
554 4e338533 Michael Hanselmann
    self.tc.assertFalse(self._expect_notchanged)
555 4e338533 Michael Hanselmann
    self.tc.assertFalse(self._expect_log)
556 4e338533 Michael Hanselmann
557 4e338533 Michael Hanselmann
    result = self._jobstatus.pop(0)
558 4e338533 Michael Hanselmann
    self.tc.assertEqual(len(fields), len(result))
559 4e338533 Michael Hanselmann
    return [result]
560 4e338533 Michael Hanselmann
561 4e338533 Michael Hanselmann
  def ReportLogMessage(self, job_id, serial, timestamp, log_type, log_msg):
562 4e338533 Michael Hanselmann
    self.tc.assertEqual(job_id, self.job_id)
563 4e338533 Michael Hanselmann
    self.tc.assertEqualValues((serial, timestamp, log_type, log_msg),
564 4e338533 Michael Hanselmann
                              self._expect_log.pop(0))
565 4e338533 Michael Hanselmann
566 4e338533 Michael Hanselmann
  def ReportNotChanged(self, job_id, status):
567 4e338533 Michael Hanselmann
    self.tc.assertEqual(job_id, self.job_id)
568 4e338533 Michael Hanselmann
    self.tc.assert_(self._expect_notchanged)
569 4e338533 Michael Hanselmann
    self._expect_notchanged = False
570 4e338533 Michael Hanselmann
571 4e338533 Michael Hanselmann
572 4e338533 Michael Hanselmann
class TestGenericPollJob(testutils.GanetiTestCase):
573 4e338533 Michael Hanselmann
  def testSuccessWithLog(self):
574 4e338533 Michael Hanselmann
    job_id = 29609
575 4e338533 Michael Hanselmann
    cbs = _MockJobPollCb(self, job_id)
576 4e338533 Michael Hanselmann
577 4e338533 Michael Hanselmann
    cbs.AddWfjcResult(None, None, constants.JOB_NOTCHANGED)
578 4e338533 Michael Hanselmann
579 4e338533 Michael Hanselmann
    cbs.AddWfjcResult(None, None,
580 4e338533 Michael Hanselmann
                      ((constants.JOB_STATUS_QUEUED, ), None))
581 4e338533 Michael Hanselmann
582 4e338533 Michael Hanselmann
    cbs.AddWfjcResult((constants.JOB_STATUS_QUEUED, ), None,
583 4e338533 Michael Hanselmann
                      constants.JOB_NOTCHANGED)
584 4e338533 Michael Hanselmann
585 4e338533 Michael Hanselmann
    cbs.AddWfjcResult((constants.JOB_STATUS_QUEUED, ), None,
586 4e338533 Michael Hanselmann
                      ((constants.JOB_STATUS_RUNNING, ),
587 4e338533 Michael Hanselmann
                       [(1, utils.SplitTime(1273491611.0),
588 4e338533 Michael Hanselmann
                         constants.ELOG_MESSAGE, "Step 1"),
589 4e338533 Michael Hanselmann
                        (2, utils.SplitTime(1273491615.9),
590 4e338533 Michael Hanselmann
                         constants.ELOG_MESSAGE, "Step 2"),
591 4e338533 Michael Hanselmann
                        (3, utils.SplitTime(1273491625.02),
592 4e338533 Michael Hanselmann
                         constants.ELOG_MESSAGE, "Step 3"),
593 4e338533 Michael Hanselmann
                        (4, utils.SplitTime(1273491635.05),
594 4e338533 Michael Hanselmann
                         constants.ELOG_MESSAGE, "Step 4"),
595 4e338533 Michael Hanselmann
                        (37, utils.SplitTime(1273491645.0),
596 4e338533 Michael Hanselmann
                         constants.ELOG_MESSAGE, "Step 5"),
597 4e338533 Michael Hanselmann
                        (203, utils.SplitTime(127349155.0),
598 4e338533 Michael Hanselmann
                         constants.ELOG_MESSAGE, "Step 6")]))
599 4e338533 Michael Hanselmann
600 4e338533 Michael Hanselmann
    cbs.AddWfjcResult((constants.JOB_STATUS_RUNNING, ), 203,
601 4e338533 Michael Hanselmann
                      ((constants.JOB_STATUS_RUNNING, ),
602 4e338533 Michael Hanselmann
                       [(300, utils.SplitTime(1273491711.01),
603 4e338533 Michael Hanselmann
                         constants.ELOG_MESSAGE, "Step X"),
604 4e338533 Michael Hanselmann
                        (302, utils.SplitTime(1273491815.8),
605 4e338533 Michael Hanselmann
                         constants.ELOG_MESSAGE, "Step Y"),
606 4e338533 Michael Hanselmann
                        (303, utils.SplitTime(1273491925.32),
607 4e338533 Michael Hanselmann
                         constants.ELOG_MESSAGE, "Step Z")]))
608 4e338533 Michael Hanselmann
609 4e338533 Michael Hanselmann
    cbs.AddWfjcResult((constants.JOB_STATUS_RUNNING, ), 303,
610 4e338533 Michael Hanselmann
                      ((constants.JOB_STATUS_SUCCESS, ), None))
611 4e338533 Michael Hanselmann
612 4e338533 Michael Hanselmann
    cbs.AddQueryJobsResult(constants.JOB_STATUS_SUCCESS,
613 4e338533 Michael Hanselmann
                           [constants.OP_STATUS_SUCCESS,
614 4e338533 Michael Hanselmann
                            constants.OP_STATUS_SUCCESS],
615 4e338533 Michael Hanselmann
                           ["Hello World", "Foo man bar"])
616 4e338533 Michael Hanselmann
617 4e338533 Michael Hanselmann
    self.assertEqual(["Hello World", "Foo man bar"],
618 4e338533 Michael Hanselmann
                     cli.GenericPollJob(job_id, cbs, cbs))
619 4e338533 Michael Hanselmann
    cbs.CheckEmpty()
620 4e338533 Michael Hanselmann
621 4e338533 Michael Hanselmann
  def testJobLost(self):
622 4e338533 Michael Hanselmann
    job_id = 13746
623 4e338533 Michael Hanselmann
624 4e338533 Michael Hanselmann
    cbs = _MockJobPollCb(self, job_id)
625 4e338533 Michael Hanselmann
    cbs.AddWfjcResult(None, None, constants.JOB_NOTCHANGED)
626 4e338533 Michael Hanselmann
    cbs.AddWfjcResult(None, None, None)
627 4e338533 Michael Hanselmann
    self.assertRaises(errors.JobLost, cli.GenericPollJob, job_id, cbs, cbs)
628 4e338533 Michael Hanselmann
    cbs.CheckEmpty()
629 4e338533 Michael Hanselmann
630 4e338533 Michael Hanselmann
  def testError(self):
631 4e338533 Michael Hanselmann
    job_id = 31088
632 4e338533 Michael Hanselmann
633 4e338533 Michael Hanselmann
    cbs = _MockJobPollCb(self, job_id)
634 4e338533 Michael Hanselmann
    cbs.AddWfjcResult(None, None, constants.JOB_NOTCHANGED)
635 4e338533 Michael Hanselmann
    cbs.AddWfjcResult(None, None, ((constants.JOB_STATUS_ERROR, ), None))
636 4e338533 Michael Hanselmann
    cbs.AddQueryJobsResult(constants.JOB_STATUS_ERROR,
637 4e338533 Michael Hanselmann
                           [constants.OP_STATUS_SUCCESS,
638 4e338533 Michael Hanselmann
                            constants.OP_STATUS_ERROR],
639 4e338533 Michael Hanselmann
                           ["Hello World", "Error code 123"])
640 4e338533 Michael Hanselmann
    self.assertRaises(errors.OpExecError, cli.GenericPollJob, job_id, cbs, cbs)
641 4e338533 Michael Hanselmann
    cbs.CheckEmpty()
642 4e338533 Michael Hanselmann
643 4e338533 Michael Hanselmann
  def testError2(self):
644 4e338533 Michael Hanselmann
    job_id = 22235
645 4e338533 Michael Hanselmann
646 4e338533 Michael Hanselmann
    cbs = _MockJobPollCb(self, job_id)
647 4e338533 Michael Hanselmann
    cbs.AddWfjcResult(None, None, ((constants.JOB_STATUS_ERROR, ), None))
648 4e338533 Michael Hanselmann
    encexc = errors.EncodeException(errors.LockError("problem"))
649 4e338533 Michael Hanselmann
    cbs.AddQueryJobsResult(constants.JOB_STATUS_ERROR,
650 4e338533 Michael Hanselmann
                           [constants.OP_STATUS_ERROR], [encexc])
651 4e338533 Michael Hanselmann
    self.assertRaises(errors.LockError, cli.GenericPollJob, job_id, cbs, cbs)
652 4e338533 Michael Hanselmann
    cbs.CheckEmpty()
653 4e338533 Michael Hanselmann
654 4e338533 Michael Hanselmann
  def testWeirdError(self):
655 4e338533 Michael Hanselmann
    job_id = 28847
656 4e338533 Michael Hanselmann
657 4e338533 Michael Hanselmann
    cbs = _MockJobPollCb(self, job_id)
658 4e338533 Michael Hanselmann
    cbs.AddWfjcResult(None, None, ((constants.JOB_STATUS_ERROR, ), None))
659 4e338533 Michael Hanselmann
    cbs.AddQueryJobsResult(constants.JOB_STATUS_ERROR,
660 4e338533 Michael Hanselmann
                           [constants.OP_STATUS_RUNNING,
661 4e338533 Michael Hanselmann
                            constants.OP_STATUS_RUNNING],
662 4e338533 Michael Hanselmann
                           [None, None])
663 4e338533 Michael Hanselmann
    self.assertRaises(errors.OpExecError, cli.GenericPollJob, job_id, cbs, cbs)
664 4e338533 Michael Hanselmann
    cbs.CheckEmpty()
665 4e338533 Michael Hanselmann
666 4e338533 Michael Hanselmann
  def testCancel(self):
667 4e338533 Michael Hanselmann
    job_id = 4275
668 4e338533 Michael Hanselmann
669 4e338533 Michael Hanselmann
    cbs = _MockJobPollCb(self, job_id)
670 4e338533 Michael Hanselmann
    cbs.AddWfjcResult(None, None, constants.JOB_NOTCHANGED)
671 4e338533 Michael Hanselmann
    cbs.AddWfjcResult(None, None, ((constants.JOB_STATUS_CANCELING, ), None))
672 4e338533 Michael Hanselmann
    cbs.AddQueryJobsResult(constants.JOB_STATUS_CANCELING,
673 4e338533 Michael Hanselmann
                           [constants.OP_STATUS_CANCELING,
674 4e338533 Michael Hanselmann
                            constants.OP_STATUS_CANCELING],
675 4e338533 Michael Hanselmann
                           [None, None])
676 4e338533 Michael Hanselmann
    self.assertRaises(errors.OpExecError, cli.GenericPollJob, job_id, cbs, cbs)
677 4e338533 Michael Hanselmann
    cbs.CheckEmpty()
678 4e338533 Michael Hanselmann
679 4e338533 Michael Hanselmann
680 8a7f1c61 Michael Hanselmann
class TestFormatLogMessage(unittest.TestCase):
681 8a7f1c61 Michael Hanselmann
  def test(self):
682 8a7f1c61 Michael Hanselmann
    self.assertEqual(cli.FormatLogMessage(constants.ELOG_MESSAGE,
683 8a7f1c61 Michael Hanselmann
                                          "Hello World"),
684 8a7f1c61 Michael Hanselmann
                     "Hello World")
685 8a7f1c61 Michael Hanselmann
    self.assertRaises(TypeError, cli.FormatLogMessage,
686 8a7f1c61 Michael Hanselmann
                      constants.ELOG_MESSAGE, [1, 2, 3])
687 8a7f1c61 Michael Hanselmann
688 8a7f1c61 Michael Hanselmann
    self.assert_(cli.FormatLogMessage("some other type", (1, 2, 3)))
689 8a7f1c61 Michael Hanselmann
690 8a7f1c61 Michael Hanselmann
691 a4ebd726 Michael Hanselmann
class TestParseFields(unittest.TestCase):
692 a4ebd726 Michael Hanselmann
  def test(self):
693 a4ebd726 Michael Hanselmann
    self.assertEqual(cli.ParseFields(None, []), [])
694 a4ebd726 Michael Hanselmann
    self.assertEqual(cli.ParseFields("name,foo,hello", []),
695 a4ebd726 Michael Hanselmann
                     ["name", "foo", "hello"])
696 a4ebd726 Michael Hanselmann
    self.assertEqual(cli.ParseFields(None, ["def", "ault", "fields", "here"]),
697 a4ebd726 Michael Hanselmann
                     ["def", "ault", "fields", "here"])
698 a4ebd726 Michael Hanselmann
    self.assertEqual(cli.ParseFields("name,foo", ["def", "ault"]),
699 a4ebd726 Michael Hanselmann
                     ["name", "foo"])
700 a4ebd726 Michael Hanselmann
    self.assertEqual(cli.ParseFields("+name,foo", ["def", "ault"]),
701 a4ebd726 Michael Hanselmann
                     ["def", "ault", "name", "foo"])
702 a4ebd726 Michael Hanselmann
703 a4ebd726 Michael Hanselmann
704 84a5b33c Michael Hanselmann
class TestConstants(unittest.TestCase):
705 84a5b33c Michael Hanselmann
  def testPriority(self):
706 84a5b33c Michael Hanselmann
    self.assertEqual(set(cli._PRIONAME_TO_VALUE.values()),
707 84a5b33c Michael Hanselmann
                     set(constants.OP_PRIO_SUBMIT_VALID))
708 84a5b33c Michael Hanselmann
    self.assertEqual(list(value for _, value in cli._PRIORITY_NAMES),
709 84a5b33c Michael Hanselmann
                     sorted(constants.OP_PRIO_SUBMIT_VALID, reverse=True))
710 84a5b33c Michael Hanselmann
711 84a5b33c Michael Hanselmann
712 845c79d8 Michael Hanselmann
class TestParseNicOption(unittest.TestCase):
713 845c79d8 Michael Hanselmann
  def test(self):
714 845c79d8 Michael Hanselmann
    self.assertEqual(cli.ParseNicOption([("0", { "link": "eth0", })]),
715 845c79d8 Michael Hanselmann
                     [{ "link": "eth0", }])
716 845c79d8 Michael Hanselmann
    self.assertEqual(cli.ParseNicOption([("5", { "ip": "192.0.2.7", })]),
717 845c79d8 Michael Hanselmann
                     [{}, {}, {}, {}, {}, { "ip": "192.0.2.7", }])
718 845c79d8 Michael Hanselmann
719 845c79d8 Michael Hanselmann
  def testErrors(self):
720 845c79d8 Michael Hanselmann
    for i in [None, "", "abc", "zero", "Hello World", "\0", []]:
721 845c79d8 Michael Hanselmann
      self.assertRaises(errors.OpPrereqError, cli.ParseNicOption,
722 845c79d8 Michael Hanselmann
                        [(i, { "link": "eth0", })])
723 845c79d8 Michael Hanselmann
      self.assertRaises(errors.OpPrereqError, cli.ParseNicOption,
724 845c79d8 Michael Hanselmann
                        [("0", i)])
725 845c79d8 Michael Hanselmann
726 845c79d8 Michael Hanselmann
    self.assertRaises(errors.TypeEnforcementError, cli.ParseNicOption,
727 845c79d8 Michael Hanselmann
                      [(0, { True: False, })])
728 845c79d8 Michael Hanselmann
729 845c79d8 Michael Hanselmann
    self.assertRaises(errors.TypeEnforcementError, cli.ParseNicOption,
730 845c79d8 Michael Hanselmann
                      [(3, { "mode": [], })])
731 845c79d8 Michael Hanselmann
732 845c79d8 Michael Hanselmann
733 f2c6673d Michael Hanselmann
class TestFormatResultError(unittest.TestCase):
734 f2c6673d Michael Hanselmann
  def testNormal(self):
735 f2c6673d Michael Hanselmann
    for verbose in [False, True]:
736 f2c6673d Michael Hanselmann
      self.assertRaises(AssertionError, cli.FormatResultError,
737 f2c6673d Michael Hanselmann
                        constants.RS_NORMAL, verbose)
738 f2c6673d Michael Hanselmann
739 f2c6673d Michael Hanselmann
  def testUnknown(self):
740 f2c6673d Michael Hanselmann
    for verbose in [False, True]:
741 f2c6673d Michael Hanselmann
      self.assertRaises(NotImplementedError, cli.FormatResultError,
742 f2c6673d Michael Hanselmann
                        "#some!other!status#", verbose)
743 f2c6673d Michael Hanselmann
744 f2c6673d Michael Hanselmann
  def test(self):
745 f2c6673d Michael Hanselmann
    for status in constants.RS_ALL:
746 f2c6673d Michael Hanselmann
      if status == constants.RS_NORMAL:
747 f2c6673d Michael Hanselmann
        continue
748 f2c6673d Michael Hanselmann
749 f2c6673d Michael Hanselmann
      self.assertNotEqual(cli.FormatResultError(status, False),
750 f2c6673d Michael Hanselmann
                          cli.FormatResultError(status, True))
751 f2c6673d Michael Hanselmann
752 f2c6673d Michael Hanselmann
      result = cli.FormatResultError(status, True)
753 f2c6673d Michael Hanselmann
      self.assertTrue(result.startswith("("))
754 f2c6673d Michael Hanselmann
      self.assertTrue(result.endswith(")"))
755 f2c6673d Michael Hanselmann
756 f2c6673d Michael Hanselmann
757 05484a24 Michael Hanselmann
class TestGetOnlineNodes(unittest.TestCase):
758 05484a24 Michael Hanselmann
  class _FakeClient:
759 05484a24 Michael Hanselmann
    def __init__(self):
760 05484a24 Michael Hanselmann
      self._query = []
761 05484a24 Michael Hanselmann
762 05484a24 Michael Hanselmann
    def AddQueryResult(self, *args):
763 05484a24 Michael Hanselmann
      self._query.append(args)
764 05484a24 Michael Hanselmann
765 05484a24 Michael Hanselmann
    def CountPending(self):
766 05484a24 Michael Hanselmann
      return len(self._query)
767 05484a24 Michael Hanselmann
768 05484a24 Michael Hanselmann
    def Query(self, res, fields, filter_):
769 05484a24 Michael Hanselmann
      if res != constants.QR_NODE:
770 05484a24 Michael Hanselmann
        raise Exception("Querying wrong resource")
771 05484a24 Michael Hanselmann
772 05484a24 Michael Hanselmann
      (exp_fields, check_filter, result) = self._query.pop(0)
773 05484a24 Michael Hanselmann
774 05484a24 Michael Hanselmann
      if exp_fields != fields:
775 05484a24 Michael Hanselmann
        raise Exception("Expected fields %s, got %s" % (exp_fields, fields))
776 05484a24 Michael Hanselmann
777 05484a24 Michael Hanselmann
      if not (filter_ is None or check_filter(filter_)):
778 05484a24 Michael Hanselmann
        raise Exception("Filter doesn't match expectations")
779 05484a24 Michael Hanselmann
780 05484a24 Michael Hanselmann
      return objects.QueryResponse(fields=None, data=result)
781 05484a24 Michael Hanselmann
782 05484a24 Michael Hanselmann
  def testEmpty(self):
783 05484a24 Michael Hanselmann
    cl = self._FakeClient()
784 05484a24 Michael Hanselmann
785 05484a24 Michael Hanselmann
    cl.AddQueryResult(["name", "offline", "sip"], None, [])
786 05484a24 Michael Hanselmann
    self.assertEqual(cli.GetOnlineNodes(None, cl=cl), [])
787 05484a24 Michael Hanselmann
    self.assertEqual(cl.CountPending(), 0)
788 05484a24 Michael Hanselmann
789 05484a24 Michael Hanselmann
  def testNoSpecialFilter(self):
790 05484a24 Michael Hanselmann
    cl = self._FakeClient()
791 05484a24 Michael Hanselmann
792 05484a24 Michael Hanselmann
    cl.AddQueryResult(["name", "offline", "sip"], None, [
793 05484a24 Michael Hanselmann
      [(constants.RS_NORMAL, "master.example.com"),
794 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, False),
795 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, "192.0.2.1")],
796 05484a24 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com"),
797 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, False),
798 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, "192.0.2.2")],
799 05484a24 Michael Hanselmann
      ])
800 05484a24 Michael Hanselmann
    self.assertEqual(cli.GetOnlineNodes(None, cl=cl),
801 05484a24 Michael Hanselmann
                     ["master.example.com", "node2.example.com"])
802 05484a24 Michael Hanselmann
    self.assertEqual(cl.CountPending(), 0)
803 05484a24 Michael Hanselmann
804 05484a24 Michael Hanselmann
  def testNoMaster(self):
805 05484a24 Michael Hanselmann
    cl = self._FakeClient()
806 05484a24 Michael Hanselmann
807 05484a24 Michael Hanselmann
    def _CheckFilter(filter_):
808 05484a24 Michael Hanselmann
      self.assertEqual(filter_, [qlang.OP_NOT, [qlang.OP_TRUE, "master"]])
809 05484a24 Michael Hanselmann
      return True
810 05484a24 Michael Hanselmann
811 05484a24 Michael Hanselmann
    cl.AddQueryResult(["name", "offline", "sip"], _CheckFilter, [
812 05484a24 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com"),
813 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, False),
814 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, "192.0.2.2")],
815 05484a24 Michael Hanselmann
      ])
816 05484a24 Michael Hanselmann
    self.assertEqual(cli.GetOnlineNodes(None, cl=cl, filter_master=True),
817 05484a24 Michael Hanselmann
                     ["node2.example.com"])
818 05484a24 Michael Hanselmann
    self.assertEqual(cl.CountPending(), 0)
819 05484a24 Michael Hanselmann
820 05484a24 Michael Hanselmann
  def testSecondaryIpAddress(self):
821 05484a24 Michael Hanselmann
    cl = self._FakeClient()
822 05484a24 Michael Hanselmann
823 05484a24 Michael Hanselmann
    cl.AddQueryResult(["name", "offline", "sip"], None, [
824 05484a24 Michael Hanselmann
      [(constants.RS_NORMAL, "master.example.com"),
825 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, False),
826 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, "192.0.2.1")],
827 05484a24 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com"),
828 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, False),
829 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, "192.0.2.2")],
830 05484a24 Michael Hanselmann
      ])
831 05484a24 Michael Hanselmann
    self.assertEqual(cli.GetOnlineNodes(None, cl=cl, secondary_ips=True),
832 05484a24 Michael Hanselmann
                     ["192.0.2.1", "192.0.2.2"])
833 05484a24 Michael Hanselmann
    self.assertEqual(cl.CountPending(), 0)
834 05484a24 Michael Hanselmann
835 05484a24 Michael Hanselmann
  def testNoMasterFilterNodeName(self):
836 05484a24 Michael Hanselmann
    cl = self._FakeClient()
837 05484a24 Michael Hanselmann
838 05484a24 Michael Hanselmann
    def _CheckFilter(filter_):
839 05484a24 Michael Hanselmann
      self.assertEqual(filter_,
840 05484a24 Michael Hanselmann
        [qlang.OP_AND,
841 05484a24 Michael Hanselmann
         [qlang.OP_OR] + [[qlang.OP_EQUAL, "name", name]
842 05484a24 Michael Hanselmann
                          for name in ["node2", "node3"]],
843 05484a24 Michael Hanselmann
         [qlang.OP_NOT, [qlang.OP_TRUE, "master"]]])
844 05484a24 Michael Hanselmann
      return True
845 05484a24 Michael Hanselmann
846 05484a24 Michael Hanselmann
    cl.AddQueryResult(["name", "offline", "sip"], _CheckFilter, [
847 05484a24 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com"),
848 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, False),
849 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, "192.0.2.12")],
850 05484a24 Michael Hanselmann
      [(constants.RS_NORMAL, "node3.example.com"),
851 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, False),
852 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, "192.0.2.13")],
853 05484a24 Michael Hanselmann
      ])
854 05484a24 Michael Hanselmann
    self.assertEqual(cli.GetOnlineNodes(["node2", "node3"], cl=cl,
855 05484a24 Michael Hanselmann
                                        secondary_ips=True, filter_master=True),
856 05484a24 Michael Hanselmann
                     ["192.0.2.12", "192.0.2.13"])
857 05484a24 Michael Hanselmann
    self.assertEqual(cl.CountPending(), 0)
858 05484a24 Michael Hanselmann
859 05484a24 Michael Hanselmann
  def testOfflineNodes(self):
860 05484a24 Michael Hanselmann
    cl = self._FakeClient()
861 05484a24 Michael Hanselmann
862 05484a24 Michael Hanselmann
    cl.AddQueryResult(["name", "offline", "sip"], None, [
863 05484a24 Michael Hanselmann
      [(constants.RS_NORMAL, "master.example.com"),
864 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, False),
865 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, "192.0.2.1")],
866 05484a24 Michael Hanselmann
      [(constants.RS_NORMAL, "node2.example.com"),
867 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, True),
868 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, "192.0.2.2")],
869 05484a24 Michael Hanselmann
      [(constants.RS_NORMAL, "node3.example.com"),
870 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, True),
871 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, "192.0.2.3")],
872 05484a24 Michael Hanselmann
      ])
873 05484a24 Michael Hanselmann
    self.assertEqual(cli.GetOnlineNodes(None, cl=cl, nowarn=True),
874 05484a24 Michael Hanselmann
                     ["master.example.com"])
875 05484a24 Michael Hanselmann
    self.assertEqual(cl.CountPending(), 0)
876 05484a24 Michael Hanselmann
877 05484a24 Michael Hanselmann
  def testNodeGroup(self):
878 05484a24 Michael Hanselmann
    cl = self._FakeClient()
879 05484a24 Michael Hanselmann
880 05484a24 Michael Hanselmann
    def _CheckFilter(filter_):
881 05484a24 Michael Hanselmann
      self.assertEqual(filter_,
882 05484a24 Michael Hanselmann
        [qlang.OP_OR, [qlang.OP_EQUAL, "group", "foobar"],
883 05484a24 Michael Hanselmann
                      [qlang.OP_EQUAL, "group.uuid", "foobar"]])
884 05484a24 Michael Hanselmann
      return True
885 05484a24 Michael Hanselmann
886 05484a24 Michael Hanselmann
    cl.AddQueryResult(["name", "offline", "sip"], _CheckFilter, [
887 05484a24 Michael Hanselmann
      [(constants.RS_NORMAL, "master.example.com"),
888 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, False),
889 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, "192.0.2.1")],
890 05484a24 Michael Hanselmann
      [(constants.RS_NORMAL, "node3.example.com"),
891 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, False),
892 05484a24 Michael Hanselmann
       (constants.RS_NORMAL, "192.0.2.3")],
893 05484a24 Michael Hanselmann
      ])
894 05484a24 Michael Hanselmann
    self.assertEqual(cli.GetOnlineNodes(None, cl=cl, nodegroup="foobar"),
895 05484a24 Michael Hanselmann
                     ["master.example.com", "node3.example.com"])
896 05484a24 Michael Hanselmann
    self.assertEqual(cl.CountPending(), 0)
897 05484a24 Michael Hanselmann
898 05484a24 Michael Hanselmann
899 2241e2b9 Iustin Pop
if __name__ == '__main__':
900 25231ec5 Michael Hanselmann
  testutils.GanetiTestProgram()