Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.cli_unittest.py @ 1a2eb2dc

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