Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.cli_unittest.py @ 5fa3d337

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