Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.cli_unittest.py @ 560ef132

History | View | Annotate | Download (58.3 kB)

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

1207 65978cb7 Bernardo Dal Seno
  These tests rely on cli._SerializeGenericInfo (tested elsewhere).
1208 65978cb7 Bernardo Dal Seno

1209 65978cb7 Bernardo Dal Seno
  """
1210 65978cb7 Bernardo Dal Seno
  def setUp(self):
1211 65978cb7 Bernardo Dal Seno
    # Policies are big, and we want to see the difference in case of an error
1212 65978cb7 Bernardo Dal Seno
    self.maxDiff = None
1213 65978cb7 Bernardo Dal Seno
1214 65978cb7 Bernardo Dal Seno
  def _RenameDictItem(self, parsed, old, new):
1215 65978cb7 Bernardo Dal Seno
    self.assertTrue(old in parsed)
1216 65978cb7 Bernardo Dal Seno
    self.assertTrue(new not in parsed)
1217 65978cb7 Bernardo Dal Seno
    parsed[new] = parsed[old]
1218 65978cb7 Bernardo Dal Seno
    del parsed[old]
1219 65978cb7 Bernardo Dal Seno
1220 65978cb7 Bernardo Dal Seno
  def _TranslateParsedNames(self, parsed):
1221 65978cb7 Bernardo Dal Seno
    for (pretty, raw) in [
1222 65978cb7 Bernardo Dal Seno
      ("bounds specs", constants.ISPECS_MINMAX),
1223 9db0b351 Bernardo Dal Seno
      ("allowed disk templates", constants.IPOLICY_DTS)
1224 65978cb7 Bernardo Dal Seno
      ]:
1225 65978cb7 Bernardo Dal Seno
      self._RenameDictItem(parsed, pretty, raw)
1226 65978cb7 Bernardo Dal Seno
    for minmax in parsed[constants.ISPECS_MINMAX]:
1227 65978cb7 Bernardo Dal Seno
      for key in minmax:
1228 65978cb7 Bernardo Dal Seno
        keyparts = key.split("/", 1)
1229 65978cb7 Bernardo Dal Seno
        if len(keyparts) > 1:
1230 65978cb7 Bernardo Dal Seno
          self._RenameDictItem(minmax, key, keyparts[0])
1231 65978cb7 Bernardo Dal Seno
    self.assertTrue(constants.IPOLICY_DTS in parsed)
1232 65978cb7 Bernardo Dal Seno
    parsed[constants.IPOLICY_DTS] = yaml.load("[%s]" %
1233 65978cb7 Bernardo Dal Seno
                                              parsed[constants.IPOLICY_DTS])
1234 65978cb7 Bernardo Dal Seno
1235 65978cb7 Bernardo Dal Seno
  @staticmethod
1236 65978cb7 Bernardo Dal Seno
  def _PrintAndParsePolicy(custom, effective, iscluster):
1237 65978cb7 Bernardo Dal Seno
    formatted = cli.FormatPolicyInfo(custom, effective, iscluster)
1238 65978cb7 Bernardo Dal Seno
    buf = StringIO()
1239 65978cb7 Bernardo Dal Seno
    cli._SerializeGenericInfo(buf, formatted, 0)
1240 65978cb7 Bernardo Dal Seno
    return yaml.load(buf.getvalue())
1241 65978cb7 Bernardo Dal Seno
1242 65978cb7 Bernardo Dal Seno
  def _PrintAndCheckParsed(self, policy):
1243 65978cb7 Bernardo Dal Seno
    parsed = self._PrintAndParsePolicy(policy, NotImplemented, True)
1244 65978cb7 Bernardo Dal Seno
    self._TranslateParsedNames(parsed)
1245 65978cb7 Bernardo Dal Seno
    self.assertEqual(parsed, policy)
1246 65978cb7 Bernardo Dal Seno
1247 65978cb7 Bernardo Dal Seno
  def _CompareClusterGroupItems(self, cluster, group, skip=None):
1248 65978cb7 Bernardo Dal Seno
    if isinstance(group, dict):
1249 65978cb7 Bernardo Dal Seno
      self.assertTrue(isinstance(cluster, dict))
1250 65978cb7 Bernardo Dal Seno
      if skip is None:
1251 65978cb7 Bernardo Dal Seno
        skip = frozenset()
1252 65978cb7 Bernardo Dal Seno
      self.assertEqual(frozenset(cluster.keys()).difference(skip),
1253 65978cb7 Bernardo Dal Seno
                       frozenset(group.keys()))
1254 65978cb7 Bernardo Dal Seno
      for key in group:
1255 65978cb7 Bernardo Dal Seno
        self._CompareClusterGroupItems(cluster[key], group[key])
1256 65978cb7 Bernardo Dal Seno
    elif isinstance(group, list):
1257 65978cb7 Bernardo Dal Seno
      self.assertTrue(isinstance(cluster, list))
1258 65978cb7 Bernardo Dal Seno
      self.assertEqual(len(cluster), len(group))
1259 65978cb7 Bernardo Dal Seno
      for (cval, gval) in zip(cluster, group):
1260 65978cb7 Bernardo Dal Seno
        self._CompareClusterGroupItems(cval, gval)
1261 65978cb7 Bernardo Dal Seno
    else:
1262 65978cb7 Bernardo Dal Seno
      self.assertTrue(isinstance(group, basestring))
1263 65978cb7 Bernardo Dal Seno
      self.assertEqual("default (%s)" % cluster, group)
1264 65978cb7 Bernardo Dal Seno
1265 65978cb7 Bernardo Dal Seno
  def _TestClusterVsGroup(self, policy):
1266 65978cb7 Bernardo Dal Seno
    cluster = self._PrintAndParsePolicy(policy, NotImplemented, True)
1267 65978cb7 Bernardo Dal Seno
    group = self._PrintAndParsePolicy({}, policy, False)
1268 65978cb7 Bernardo Dal Seno
    self._CompareClusterGroupItems(cluster, group, ["std"])
1269 65978cb7 Bernardo Dal Seno
1270 65978cb7 Bernardo Dal Seno
  def testWithDefaults(self):
1271 65978cb7 Bernardo Dal Seno
    self._PrintAndCheckParsed(constants.IPOLICY_DEFAULTS)
1272 65978cb7 Bernardo Dal Seno
    self._TestClusterVsGroup(constants.IPOLICY_DEFAULTS)
1273 65978cb7 Bernardo Dal Seno
1274 65978cb7 Bernardo Dal Seno
1275 a6fdce9e Bernardo Dal Seno
class TestCreateIPolicyFromOpts(unittest.TestCase):
1276 a6fdce9e Bernardo Dal Seno
  """Test case for cli.CreateIPolicyFromOpts."""
1277 919db916 Bernardo Dal Seno
  def setUp(self):
1278 919db916 Bernardo Dal Seno
    # Policies are big, and we want to see the difference in case of an error
1279 919db916 Bernardo Dal Seno
    self.maxDiff = None
1280 919db916 Bernardo Dal Seno
1281 41044e04 Bernardo Dal Seno
  def _RecursiveCheckMergedDicts(self, default_pol, diff_pol, merged_pol,
1282 41044e04 Bernardo Dal Seno
                                 merge_minmax=False):
1283 a6fdce9e Bernardo Dal Seno
    self.assertTrue(type(default_pol) is dict)
1284 a6fdce9e Bernardo Dal Seno
    self.assertTrue(type(diff_pol) is dict)
1285 a6fdce9e Bernardo Dal Seno
    self.assertTrue(type(merged_pol) is dict)
1286 a6fdce9e Bernardo Dal Seno
    self.assertEqual(frozenset(default_pol.keys()),
1287 a6fdce9e Bernardo Dal Seno
                     frozenset(merged_pol.keys()))
1288 a6fdce9e Bernardo Dal Seno
    for (key, val) in merged_pol.items():
1289 a6fdce9e Bernardo Dal Seno
      if key in diff_pol:
1290 a6fdce9e Bernardo Dal Seno
        if type(val) is dict:
1291 a6fdce9e Bernardo Dal Seno
          self._RecursiveCheckMergedDicts(default_pol[key], diff_pol[key], val)
1292 41044e04 Bernardo Dal Seno
        elif (merge_minmax and key == "minmax" and type(val) is list and
1293 41044e04 Bernardo Dal Seno
              len(val) == 1):
1294 41044e04 Bernardo Dal Seno
          self.assertEqual(len(default_pol[key]), 1)
1295 41044e04 Bernardo Dal Seno
          self.assertEqual(len(diff_pol[key]), 1)
1296 41044e04 Bernardo Dal Seno
          self._RecursiveCheckMergedDicts(default_pol[key][0],
1297 41044e04 Bernardo Dal Seno
                                          diff_pol[key][0], val[0])
1298 a6fdce9e Bernardo Dal Seno
        else:
1299 a6fdce9e Bernardo Dal Seno
          self.assertEqual(val, diff_pol[key])
1300 a6fdce9e Bernardo Dal Seno
      else:
1301 a6fdce9e Bernardo Dal Seno
        self.assertEqual(val, default_pol[key])
1302 a6fdce9e Bernardo Dal Seno
1303 a6fdce9e Bernardo Dal Seno
  def testClusterPolicy(self):
1304 919db916 Bernardo Dal Seno
    pol0 = cli.CreateIPolicyFromOpts(
1305 919db916 Bernardo Dal Seno
      ispecs_mem_size={},
1306 919db916 Bernardo Dal Seno
      ispecs_cpu_count={},
1307 919db916 Bernardo Dal Seno
      ispecs_disk_count={},
1308 919db916 Bernardo Dal Seno
      ispecs_disk_size={},
1309 919db916 Bernardo Dal Seno
      ispecs_nic_count={},
1310 919db916 Bernardo Dal Seno
      ipolicy_disk_templates=None,
1311 919db916 Bernardo Dal Seno
      ipolicy_vcpu_ratio=None,
1312 919db916 Bernardo Dal Seno
      ipolicy_spindle_ratio=None,
1313 919db916 Bernardo Dal Seno
      fill_all=True
1314 919db916 Bernardo Dal Seno
      )
1315 919db916 Bernardo Dal Seno
    self.assertEqual(pol0, constants.IPOLICY_DEFAULTS)
1316 919db916 Bernardo Dal Seno
1317 a6fdce9e Bernardo Dal Seno
    exp_pol1 = {
1318 41044e04 Bernardo Dal Seno
      constants.ISPECS_MINMAX: [
1319 41044e04 Bernardo Dal Seno
        {
1320 41044e04 Bernardo Dal Seno
          constants.ISPECS_MIN: {
1321 41044e04 Bernardo Dal Seno
            constants.ISPEC_CPU_COUNT: 2,
1322 41044e04 Bernardo Dal Seno
            constants.ISPEC_DISK_COUNT: 1,
1323 41044e04 Bernardo Dal Seno
            },
1324 41044e04 Bernardo Dal Seno
          constants.ISPECS_MAX: {
1325 41044e04 Bernardo Dal Seno
            constants.ISPEC_MEM_SIZE: 12*1024,
1326 41044e04 Bernardo Dal Seno
            constants.ISPEC_DISK_COUNT: 2,
1327 41044e04 Bernardo Dal Seno
            },
1328 da5f09ef Bernardo Dal Seno
          },
1329 41044e04 Bernardo Dal Seno
        ],
1330 a6fdce9e Bernardo Dal Seno
      constants.ISPECS_STD: {
1331 a6fdce9e Bernardo Dal Seno
        constants.ISPEC_CPU_COUNT: 2,
1332 a6fdce9e Bernardo Dal Seno
        constants.ISPEC_DISK_COUNT: 2,
1333 a6fdce9e Bernardo Dal Seno
        },
1334 a6fdce9e Bernardo Dal Seno
      constants.IPOLICY_VCPU_RATIO: 3.1,
1335 a6fdce9e Bernardo Dal Seno
      }
1336 919db916 Bernardo Dal Seno
    pol1 = cli.CreateIPolicyFromOpts(
1337 919db916 Bernardo Dal Seno
      ispecs_mem_size={"max": "12g"},
1338 919db916 Bernardo Dal Seno
      ispecs_cpu_count={"min": 2, "std": 2},
1339 919db916 Bernardo Dal Seno
      ispecs_disk_count={"min": 1, "max": 2, "std": 2},
1340 919db916 Bernardo Dal Seno
      ispecs_disk_size={},
1341 919db916 Bernardo Dal Seno
      ispecs_nic_count={},
1342 919db916 Bernardo Dal Seno
      ipolicy_disk_templates=None,
1343 919db916 Bernardo Dal Seno
      ipolicy_vcpu_ratio=3.1,
1344 919db916 Bernardo Dal Seno
      ipolicy_spindle_ratio=None,
1345 919db916 Bernardo Dal Seno
      fill_all=True
1346 919db916 Bernardo Dal Seno
      )
1347 919db916 Bernardo Dal Seno
    self._RecursiveCheckMergedDicts(constants.IPOLICY_DEFAULTS,
1348 41044e04 Bernardo Dal Seno
                                    exp_pol1, pol1, merge_minmax=True)
1349 919db916 Bernardo Dal Seno
1350 a6fdce9e Bernardo Dal Seno
    exp_pol2 = {
1351 41044e04 Bernardo Dal Seno
      constants.ISPECS_MINMAX: [
1352 41044e04 Bernardo Dal Seno
        {
1353 41044e04 Bernardo Dal Seno
          constants.ISPECS_MIN: {
1354 41044e04 Bernardo Dal Seno
            constants.ISPEC_DISK_SIZE: 512,
1355 41044e04 Bernardo Dal Seno
            constants.ISPEC_NIC_COUNT: 2,
1356 41044e04 Bernardo Dal Seno
            },
1357 41044e04 Bernardo Dal Seno
          constants.ISPECS_MAX: {
1358 41044e04 Bernardo Dal Seno
            constants.ISPEC_NIC_COUNT: 3,
1359 41044e04 Bernardo Dal Seno
            },
1360 da5f09ef Bernardo Dal Seno
          },
1361 41044e04 Bernardo Dal Seno
        ],
1362 a6fdce9e Bernardo Dal Seno
      constants.ISPECS_STD: {
1363 a6fdce9e Bernardo Dal Seno
        constants.ISPEC_CPU_COUNT: 2,
1364 a6fdce9e Bernardo Dal Seno
        constants.ISPEC_NIC_COUNT: 3,
1365 a6fdce9e Bernardo Dal Seno
        },
1366 a6fdce9e Bernardo Dal Seno
      constants.IPOLICY_SPINDLE_RATIO: 1.3,
1367 a6fdce9e Bernardo Dal Seno
      constants.IPOLICY_DTS: ["templates"],
1368 a6fdce9e Bernardo Dal Seno
      }
1369 919db916 Bernardo Dal Seno
    pol2 = cli.CreateIPolicyFromOpts(
1370 919db916 Bernardo Dal Seno
      ispecs_mem_size={},
1371 919db916 Bernardo Dal Seno
      ispecs_cpu_count={"std": 2},
1372 919db916 Bernardo Dal Seno
      ispecs_disk_count={},
1373 919db916 Bernardo Dal Seno
      ispecs_disk_size={"min": "0.5g"},
1374 919db916 Bernardo Dal Seno
      ispecs_nic_count={"min": 2, "max": 3, "std": 3},
1375 919db916 Bernardo Dal Seno
      ipolicy_disk_templates=["templates"],
1376 919db916 Bernardo Dal Seno
      ipolicy_vcpu_ratio=None,
1377 919db916 Bernardo Dal Seno
      ipolicy_spindle_ratio=1.3,
1378 919db916 Bernardo Dal Seno
      fill_all=True
1379 919db916 Bernardo Dal Seno
      )
1380 919db916 Bernardo Dal Seno
    self._RecursiveCheckMergedDicts(constants.IPOLICY_DEFAULTS,
1381 41044e04 Bernardo Dal Seno
                                      exp_pol2, pol2, merge_minmax=True)
1382 919db916 Bernardo Dal Seno
1383 919db916 Bernardo Dal Seno
    for fill_all in [False, True]:
1384 919db916 Bernardo Dal Seno
      exp_pol3 = {
1385 919db916 Bernardo Dal Seno
        constants.ISPECS_STD: {
1386 919db916 Bernardo Dal Seno
          constants.ISPEC_CPU_COUNT: 2,
1387 919db916 Bernardo Dal Seno
          constants.ISPEC_NIC_COUNT: 3,
1388 919db916 Bernardo Dal Seno
          },
1389 919db916 Bernardo Dal Seno
        }
1390 919db916 Bernardo Dal Seno
      pol3 = cli.CreateIPolicyFromOpts(
1391 919db916 Bernardo Dal Seno
        std_ispecs={
1392 919db916 Bernardo Dal Seno
          constants.ISPEC_CPU_COUNT: "2",
1393 919db916 Bernardo Dal Seno
          constants.ISPEC_NIC_COUNT: "3",
1394 919db916 Bernardo Dal Seno
          },
1395 a6fdce9e Bernardo Dal Seno
        ipolicy_disk_templates=None,
1396 a6fdce9e Bernardo Dal Seno
        ipolicy_vcpu_ratio=None,
1397 a6fdce9e Bernardo Dal Seno
        ipolicy_spindle_ratio=None,
1398 919db916 Bernardo Dal Seno
        fill_all=fill_all
1399 a6fdce9e Bernardo Dal Seno
        )
1400 919db916 Bernardo Dal Seno
      if fill_all:
1401 a6fdce9e Bernardo Dal Seno
        self._RecursiveCheckMergedDicts(constants.IPOLICY_DEFAULTS,
1402 41044e04 Bernardo Dal Seno
                                        exp_pol3, pol3, merge_minmax=True)
1403 a6fdce9e Bernardo Dal Seno
      else:
1404 919db916 Bernardo Dal Seno
        self.assertEqual(pol3, exp_pol3)
1405 919db916 Bernardo Dal Seno
1406 919db916 Bernardo Dal Seno
  def testPartialPolicy(self):
1407 919db916 Bernardo Dal Seno
    exp_pol0 = objects.MakeEmptyIPolicy()
1408 919db916 Bernardo Dal Seno
    pol0 = cli.CreateIPolicyFromOpts(
1409 919db916 Bernardo Dal Seno
      minmax_ispecs=None,
1410 919db916 Bernardo Dal Seno
      std_ispecs=None,
1411 919db916 Bernardo Dal Seno
      ipolicy_disk_templates=None,
1412 919db916 Bernardo Dal Seno
      ipolicy_vcpu_ratio=None,
1413 919db916 Bernardo Dal Seno
      ipolicy_spindle_ratio=None,
1414 919db916 Bernardo Dal Seno
      fill_all=False
1415 919db916 Bernardo Dal Seno
      )
1416 919db916 Bernardo Dal Seno
    self.assertEqual(pol0, exp_pol0)
1417 919db916 Bernardo Dal Seno
1418 919db916 Bernardo Dal Seno
    exp_pol1 = {
1419 919db916 Bernardo Dal Seno
      constants.IPOLICY_VCPU_RATIO: 3.1,
1420 919db916 Bernardo Dal Seno
      }
1421 919db916 Bernardo Dal Seno
    pol1 = cli.CreateIPolicyFromOpts(
1422 919db916 Bernardo Dal Seno
      minmax_ispecs=None,
1423 919db916 Bernardo Dal Seno
      std_ispecs=None,
1424 919db916 Bernardo Dal Seno
      ipolicy_disk_templates=None,
1425 919db916 Bernardo Dal Seno
      ipolicy_vcpu_ratio=3.1,
1426 919db916 Bernardo Dal Seno
      ipolicy_spindle_ratio=None,
1427 919db916 Bernardo Dal Seno
      fill_all=False
1428 919db916 Bernardo Dal Seno
      )
1429 919db916 Bernardo Dal Seno
    self.assertEqual(pol1, exp_pol1)
1430 919db916 Bernardo Dal Seno
1431 919db916 Bernardo Dal Seno
    exp_pol2 = {
1432 919db916 Bernardo Dal Seno
      constants.IPOLICY_SPINDLE_RATIO: 1.3,
1433 919db916 Bernardo Dal Seno
      constants.IPOLICY_DTS: ["templates"],
1434 919db916 Bernardo Dal Seno
      }
1435 919db916 Bernardo Dal Seno
    pol2 = cli.CreateIPolicyFromOpts(
1436 919db916 Bernardo Dal Seno
      minmax_ispecs=None,
1437 919db916 Bernardo Dal Seno
      std_ispecs=None,
1438 919db916 Bernardo Dal Seno
      ipolicy_disk_templates=["templates"],
1439 919db916 Bernardo Dal Seno
      ipolicy_vcpu_ratio=None,
1440 919db916 Bernardo Dal Seno
      ipolicy_spindle_ratio=1.3,
1441 919db916 Bernardo Dal Seno
      fill_all=False
1442 919db916 Bernardo Dal Seno
      )
1443 919db916 Bernardo Dal Seno
    self.assertEqual(pol2, exp_pol2)
1444 919db916 Bernardo Dal Seno
1445 919db916 Bernardo Dal Seno
  def _TestInvalidISpecs(self, minmax_ispecs, std_ispecs, fail=True):
1446 919db916 Bernardo Dal Seno
    for fill_all in [False, True]:
1447 919db916 Bernardo Dal Seno
      if fail:
1448 919db916 Bernardo Dal Seno
        self.assertRaises((errors.OpPrereqError,
1449 919db916 Bernardo Dal Seno
                           errors.UnitParseError,
1450 919db916 Bernardo Dal Seno
                           errors.TypeEnforcementError),
1451 919db916 Bernardo Dal Seno
                          cli.CreateIPolicyFromOpts,
1452 919db916 Bernardo Dal Seno
                          minmax_ispecs=minmax_ispecs,
1453 919db916 Bernardo Dal Seno
                          std_ispecs=std_ispecs,
1454 919db916 Bernardo Dal Seno
                          fill_all=fill_all)
1455 a6fdce9e Bernardo Dal Seno
      else:
1456 919db916 Bernardo Dal Seno
        cli.CreateIPolicyFromOpts(minmax_ispecs=minmax_ispecs,
1457 919db916 Bernardo Dal Seno
                                  std_ispecs=std_ispecs,
1458 919db916 Bernardo Dal Seno
                                  fill_all=fill_all)
1459 a6fdce9e Bernardo Dal Seno
1460 a6fdce9e Bernardo Dal Seno
  def testInvalidPolicies(self):
1461 919db916 Bernardo Dal Seno
    self.assertRaises(AssertionError, cli.CreateIPolicyFromOpts,
1462 919db916 Bernardo Dal Seno
                      std_ispecs={constants.ISPEC_MEM_SIZE: 1024},
1463 919db916 Bernardo Dal Seno
                      ipolicy_disk_templates=None, ipolicy_vcpu_ratio=None,
1464 919db916 Bernardo Dal Seno
                      ipolicy_spindle_ratio=None, group_ipolicy=True)
1465 a6fdce9e Bernardo Dal Seno
    self.assertRaises(errors.OpPrereqError, cli.CreateIPolicyFromOpts,
1466 a6fdce9e Bernardo Dal Seno
                      ispecs_mem_size={"wrong": "x"}, ispecs_cpu_count={},
1467 a6fdce9e Bernardo Dal Seno
                      ispecs_disk_count={}, ispecs_disk_size={},
1468 a6fdce9e Bernardo Dal Seno
                      ispecs_nic_count={}, ipolicy_disk_templates=None,
1469 919db916 Bernardo Dal Seno
                      ipolicy_vcpu_ratio=None, ipolicy_spindle_ratio=None,
1470 919db916 Bernardo Dal Seno
                      fill_all=True)
1471 a6fdce9e Bernardo Dal Seno
    self.assertRaises(errors.TypeEnforcementError, cli.CreateIPolicyFromOpts,
1472 a6fdce9e Bernardo Dal Seno
                      ispecs_mem_size={}, ispecs_cpu_count={"min": "default"},
1473 a6fdce9e Bernardo Dal Seno
                      ispecs_disk_count={}, ispecs_disk_size={},
1474 a6fdce9e Bernardo Dal Seno
                      ispecs_nic_count={}, ipolicy_disk_templates=None,
1475 919db916 Bernardo Dal Seno
                      ipolicy_vcpu_ratio=None, ipolicy_spindle_ratio=None,
1476 919db916 Bernardo Dal Seno
                      fill_all=True)
1477 919db916 Bernardo Dal Seno
1478 ef99e3e8 Bernardo Dal Seno
    good_mmspecs = [
1479 ef99e3e8 Bernardo Dal Seno
      constants.ISPECS_MINMAX_DEFAULTS,
1480 ef99e3e8 Bernardo Dal Seno
      constants.ISPECS_MINMAX_DEFAULTS,
1481 ef99e3e8 Bernardo Dal Seno
      ]
1482 919db916 Bernardo Dal Seno
    self._TestInvalidISpecs(good_mmspecs, None, fail=False)
1483 919db916 Bernardo Dal Seno
    broken_mmspecs = copy.deepcopy(good_mmspecs)
1484 ef99e3e8 Bernardo Dal Seno
    for minmaxpair in broken_mmspecs:
1485 ef99e3e8 Bernardo Dal Seno
      for key in constants.ISPECS_MINMAX_KEYS:
1486 ef99e3e8 Bernardo Dal Seno
        for par in constants.ISPECS_PARAMETERS:
1487 ef99e3e8 Bernardo Dal Seno
          old = minmaxpair[key][par]
1488 ef99e3e8 Bernardo Dal Seno
          del minmaxpair[key][par]
1489 ef99e3e8 Bernardo Dal Seno
          self._TestInvalidISpecs(broken_mmspecs, None)
1490 ef99e3e8 Bernardo Dal Seno
          minmaxpair[key][par] = "invalid"
1491 ef99e3e8 Bernardo Dal Seno
          self._TestInvalidISpecs(broken_mmspecs, None)
1492 ef99e3e8 Bernardo Dal Seno
          minmaxpair[key][par] = old
1493 ef99e3e8 Bernardo Dal Seno
        minmaxpair[key]["invalid_key"] = None
1494 919db916 Bernardo Dal Seno
        self._TestInvalidISpecs(broken_mmspecs, None)
1495 ef99e3e8 Bernardo Dal Seno
        del minmaxpair[key]["invalid_key"]
1496 ef99e3e8 Bernardo Dal Seno
      minmaxpair["invalid_key"] = None
1497 919db916 Bernardo Dal Seno
      self._TestInvalidISpecs(broken_mmspecs, None)
1498 ef99e3e8 Bernardo Dal Seno
      del minmaxpair["invalid_key"]
1499 ef99e3e8 Bernardo Dal Seno
      assert broken_mmspecs == good_mmspecs
1500 919db916 Bernardo Dal Seno
1501 919db916 Bernardo Dal Seno
    good_stdspecs = constants.IPOLICY_DEFAULTS[constants.ISPECS_STD]
1502 919db916 Bernardo Dal Seno
    self._TestInvalidISpecs(None, good_stdspecs, fail=False)
1503 919db916 Bernardo Dal Seno
    broken_stdspecs = copy.deepcopy(good_stdspecs)
1504 919db916 Bernardo Dal Seno
    for par in constants.ISPECS_PARAMETERS:
1505 919db916 Bernardo Dal Seno
      old = broken_stdspecs[par]
1506 919db916 Bernardo Dal Seno
      broken_stdspecs[par] = "invalid"
1507 919db916 Bernardo Dal Seno
      self._TestInvalidISpecs(None, broken_stdspecs)
1508 919db916 Bernardo Dal Seno
      broken_stdspecs[par] = old
1509 919db916 Bernardo Dal Seno
    broken_stdspecs["invalid_key"] = None
1510 919db916 Bernardo Dal Seno
    self._TestInvalidISpecs(None, broken_stdspecs)
1511 919db916 Bernardo Dal Seno
    del broken_stdspecs["invalid_key"]
1512 919db916 Bernardo Dal Seno
    assert broken_stdspecs == good_stdspecs
1513 a6fdce9e Bernardo Dal Seno
1514 a6fdce9e Bernardo Dal Seno
  def testAllowedValues(self):
1515 a6fdce9e Bernardo Dal Seno
    allowedv = "blah"
1516 a6fdce9e Bernardo Dal Seno
    exp_pol1 = {
1517 919db916 Bernardo Dal Seno
      constants.ISPECS_MINMAX: allowedv,
1518 f824ae42 Bernardo Dal Seno
      constants.IPOLICY_DTS: allowedv,
1519 f824ae42 Bernardo Dal Seno
      constants.IPOLICY_VCPU_RATIO: allowedv,
1520 f824ae42 Bernardo Dal Seno
      constants.IPOLICY_SPINDLE_RATIO: allowedv,
1521 a6fdce9e Bernardo Dal Seno
      }
1522 ef99e3e8 Bernardo Dal Seno
    pol1 = cli.CreateIPolicyFromOpts(minmax_ispecs=[{allowedv: {}}],
1523 919db916 Bernardo Dal Seno
                                     std_ispecs=None,
1524 f824ae42 Bernardo Dal Seno
                                     ipolicy_disk_templates=allowedv,
1525 f824ae42 Bernardo Dal Seno
                                     ipolicy_vcpu_ratio=allowedv,
1526 f824ae42 Bernardo Dal Seno
                                     ipolicy_spindle_ratio=allowedv,
1527 a6fdce9e Bernardo Dal Seno
                                     allowed_values=[allowedv])
1528 a6fdce9e Bernardo Dal Seno
    self.assertEqual(pol1, exp_pol1)
1529 a6fdce9e Bernardo Dal Seno
1530 d2d3935a Bernardo Dal Seno
  @staticmethod
1531 d2d3935a Bernardo Dal Seno
  def _ConvertSpecToStrings(spec):
1532 d2d3935a Bernardo Dal Seno
    ret = {}
1533 d2d3935a Bernardo Dal Seno
    for (par, val) in spec.items():
1534 d2d3935a Bernardo Dal Seno
      ret[par] = str(val)
1535 d2d3935a Bernardo Dal Seno
    return ret
1536 d2d3935a Bernardo Dal Seno
1537 d2d3935a Bernardo Dal Seno
  def _CheckNewStyleSpecsCall(self, exp_ipolicy, minmax_ispecs, std_ispecs,
1538 d2d3935a Bernardo Dal Seno
                              group_ipolicy, fill_all):
1539 d2d3935a Bernardo Dal Seno
    ipolicy = cli.CreateIPolicyFromOpts(minmax_ispecs=minmax_ispecs,
1540 d2d3935a Bernardo Dal Seno
                                        std_ispecs=std_ispecs,
1541 d2d3935a Bernardo Dal Seno
                                        group_ipolicy=group_ipolicy,
1542 d2d3935a Bernardo Dal Seno
                                        fill_all=fill_all)
1543 d2d3935a Bernardo Dal Seno
    self.assertEqual(ipolicy, exp_ipolicy)
1544 d2d3935a Bernardo Dal Seno
1545 d2d3935a Bernardo Dal Seno
  def _TestFullISpecsInner(self, skel_exp_ipol, exp_minmax, exp_std,
1546 d2d3935a Bernardo Dal Seno
                           group_ipolicy, fill_all):
1547 d2d3935a Bernardo Dal Seno
    exp_ipol = skel_exp_ipol.copy()
1548 d2d3935a Bernardo Dal Seno
    if exp_minmax is not None:
1549 ef99e3e8 Bernardo Dal Seno
      minmax_ispecs = []
1550 ef99e3e8 Bernardo Dal Seno
      for exp_mm_pair in exp_minmax:
1551 ef99e3e8 Bernardo Dal Seno
        mmpair = {}
1552 ef99e3e8 Bernardo Dal Seno
        for (key, spec) in exp_mm_pair.items():
1553 ef99e3e8 Bernardo Dal Seno
          mmpair[key] = self._ConvertSpecToStrings(spec)
1554 ef99e3e8 Bernardo Dal Seno
        minmax_ispecs.append(mmpair)
1555 ef99e3e8 Bernardo Dal Seno
      exp_ipol[constants.ISPECS_MINMAX] = exp_minmax
1556 d2d3935a Bernardo Dal Seno
    else:
1557 d2d3935a Bernardo Dal Seno
      minmax_ispecs = None
1558 d2d3935a Bernardo Dal Seno
    if exp_std is not None:
1559 d2d3935a Bernardo Dal Seno
      std_ispecs = self._ConvertSpecToStrings(exp_std)
1560 d2d3935a Bernardo Dal Seno
      exp_ipol[constants.ISPECS_STD] = exp_std
1561 d2d3935a Bernardo Dal Seno
    else:
1562 d2d3935a Bernardo Dal Seno
      std_ispecs = None
1563 d2d3935a Bernardo Dal Seno
1564 d2d3935a Bernardo Dal Seno
    self._CheckNewStyleSpecsCall(exp_ipol, minmax_ispecs, std_ispecs,
1565 d2d3935a Bernardo Dal Seno
                                 group_ipolicy, fill_all)
1566 d2d3935a Bernardo Dal Seno
    if minmax_ispecs:
1567 ef99e3e8 Bernardo Dal Seno
      for mmpair in minmax_ispecs:
1568 ef99e3e8 Bernardo Dal Seno
        for (key, spec) in mmpair.items():
1569 ef99e3e8 Bernardo Dal Seno
          for par in [constants.ISPEC_MEM_SIZE, constants.ISPEC_DISK_SIZE]:
1570 ef99e3e8 Bernardo Dal Seno
            if par in spec:
1571 ef99e3e8 Bernardo Dal Seno
              spec[par] += "m"
1572 ef99e3e8 Bernardo Dal Seno
              self._CheckNewStyleSpecsCall(exp_ipol, minmax_ispecs, std_ispecs,
1573 ef99e3e8 Bernardo Dal Seno
                                           group_ipolicy, fill_all)
1574 d2d3935a Bernardo Dal Seno
    if std_ispecs:
1575 d2d3935a Bernardo Dal Seno
      for par in [constants.ISPEC_MEM_SIZE, constants.ISPEC_DISK_SIZE]:
1576 d2d3935a Bernardo Dal Seno
        if par in std_ispecs:
1577 d2d3935a Bernardo Dal Seno
          std_ispecs[par] += "m"
1578 d2d3935a Bernardo Dal Seno
          self._CheckNewStyleSpecsCall(exp_ipol, minmax_ispecs, std_ispecs,
1579 d2d3935a Bernardo Dal Seno
                                       group_ipolicy, fill_all)
1580 d2d3935a Bernardo Dal Seno
1581 d2d3935a Bernardo Dal Seno
  def testFullISpecs(self):
1582 ef99e3e8 Bernardo Dal Seno
    exp_minmax1 = [
1583 ef99e3e8 Bernardo Dal Seno
      {
1584 ef99e3e8 Bernardo Dal Seno
        constants.ISPECS_MIN: {
1585 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_MEM_SIZE: 512,
1586 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_CPU_COUNT: 2,
1587 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_DISK_COUNT: 2,
1588 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_DISK_SIZE: 512,
1589 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_NIC_COUNT: 2,
1590 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_SPINDLE_USE: 2,
1591 ef99e3e8 Bernardo Dal Seno
          },
1592 ef99e3e8 Bernardo Dal Seno
        constants.ISPECS_MAX: {
1593 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_MEM_SIZE: 768*1024,
1594 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_CPU_COUNT: 7,
1595 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_DISK_COUNT: 6,
1596 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_DISK_SIZE: 2048*1024,
1597 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_NIC_COUNT: 3,
1598 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_SPINDLE_USE: 3,
1599 ef99e3e8 Bernardo Dal Seno
          },
1600 d2d3935a Bernardo Dal Seno
        },
1601 ef99e3e8 Bernardo Dal Seno
      ]
1602 ef99e3e8 Bernardo Dal Seno
    exp_minmax2 = [
1603 ef99e3e8 Bernardo Dal Seno
      {
1604 ef99e3e8 Bernardo Dal Seno
        constants.ISPECS_MIN: {
1605 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_MEM_SIZE: 512,
1606 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_CPU_COUNT: 2,
1607 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_DISK_COUNT: 2,
1608 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_DISK_SIZE: 512,
1609 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_NIC_COUNT: 2,
1610 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_SPINDLE_USE: 2,
1611 ef99e3e8 Bernardo Dal Seno
          },
1612 ef99e3e8 Bernardo Dal Seno
        constants.ISPECS_MAX: {
1613 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_MEM_SIZE: 768*1024,
1614 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_CPU_COUNT: 7,
1615 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_DISK_COUNT: 6,
1616 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_DISK_SIZE: 2048*1024,
1617 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_NIC_COUNT: 3,
1618 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_SPINDLE_USE: 3,
1619 ef99e3e8 Bernardo Dal Seno
          },
1620 d2d3935a Bernardo Dal Seno
        },
1621 ef99e3e8 Bernardo Dal Seno
      {
1622 ef99e3e8 Bernardo Dal Seno
        constants.ISPECS_MIN: {
1623 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_MEM_SIZE: 1024*1024,
1624 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_CPU_COUNT: 3,
1625 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_DISK_COUNT: 3,
1626 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_DISK_SIZE: 256,
1627 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_NIC_COUNT: 4,
1628 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_SPINDLE_USE: 5,
1629 ef99e3e8 Bernardo Dal Seno
          },
1630 ef99e3e8 Bernardo Dal Seno
        constants.ISPECS_MAX: {
1631 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_MEM_SIZE: 2048*1024,
1632 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_CPU_COUNT: 5,
1633 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_DISK_COUNT: 5,
1634 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_DISK_SIZE: 1024*1024,
1635 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_NIC_COUNT: 5,
1636 ef99e3e8 Bernardo Dal Seno
          constants.ISPEC_SPINDLE_USE: 7,
1637 ef99e3e8 Bernardo Dal Seno
          },
1638 ef99e3e8 Bernardo Dal Seno
        },
1639 ef99e3e8 Bernardo Dal Seno
      ]
1640 d2d3935a Bernardo Dal Seno
    exp_std1 = {
1641 d2d3935a Bernardo Dal Seno
      constants.ISPEC_MEM_SIZE: 768*1024,
1642 d2d3935a Bernardo Dal Seno
      constants.ISPEC_CPU_COUNT: 7,
1643 d2d3935a Bernardo Dal Seno
      constants.ISPEC_DISK_COUNT: 6,
1644 d2d3935a Bernardo Dal Seno
      constants.ISPEC_DISK_SIZE: 2048*1024,
1645 d2d3935a Bernardo Dal Seno
      constants.ISPEC_NIC_COUNT: 3,
1646 d2d3935a Bernardo Dal Seno
      constants.ISPEC_SPINDLE_USE: 1,
1647 d2d3935a Bernardo Dal Seno
      }
1648 d2d3935a Bernardo Dal Seno
    for fill_all in [False, True]:
1649 d2d3935a Bernardo Dal Seno
      if fill_all:
1650 d2d3935a Bernardo Dal Seno
        skel_ipolicy = constants.IPOLICY_DEFAULTS
1651 d2d3935a Bernardo Dal Seno
      else:
1652 d2d3935a Bernardo Dal Seno
        skel_ipolicy = {}
1653 d2d3935a Bernardo Dal Seno
      self._TestFullISpecsInner(skel_ipolicy, None, exp_std1,
1654 d2d3935a Bernardo Dal Seno
                                False, fill_all)
1655 ef99e3e8 Bernardo Dal Seno
      for exp_minmax in [exp_minmax1, exp_minmax2]:
1656 ef99e3e8 Bernardo Dal Seno
        self._TestFullISpecsInner(skel_ipolicy, exp_minmax, exp_std1,
1657 ef99e3e8 Bernardo Dal Seno
                                  False, fill_all)
1658 ef99e3e8 Bernardo Dal Seno
        self._TestFullISpecsInner(skel_ipolicy, exp_minmax, None,
1659 ef99e3e8 Bernardo Dal Seno
                                  False, fill_all)
1660 a6fdce9e Bernardo Dal Seno
1661 ea9d3b40 Bernardo Dal Seno
1662 ea9d3b40 Bernardo Dal Seno
class TestPrintIPolicyCommand(unittest.TestCase):
1663 ea9d3b40 Bernardo Dal Seno
  """Test case for cli.PrintIPolicyCommand"""
1664 ea9d3b40 Bernardo Dal Seno
  _SPECS1 = {
1665 ea9d3b40 Bernardo Dal Seno
    "par1": 42,
1666 ea9d3b40 Bernardo Dal Seno
    "par2": "xyz",
1667 ea9d3b40 Bernardo Dal Seno
    }
1668 ea9d3b40 Bernardo Dal Seno
  _SPECS1_STR = "par1=42,par2=xyz"
1669 ea9d3b40 Bernardo Dal Seno
  _SPECS2 = {
1670 ea9d3b40 Bernardo Dal Seno
    "param": 10,
1671 ea9d3b40 Bernardo Dal Seno
    "another_param": 101,
1672 ea9d3b40 Bernardo Dal Seno
    }
1673 ea9d3b40 Bernardo Dal Seno
  _SPECS2_STR = "another_param=101,param=10"
1674 ef99e3e8 Bernardo Dal Seno
  _SPECS3 = {
1675 ef99e3e8 Bernardo Dal Seno
    "par1": 1024,
1676 ef99e3e8 Bernardo Dal Seno
    "param": "abc",
1677 ef99e3e8 Bernardo Dal Seno
    }
1678 ef99e3e8 Bernardo Dal Seno
  _SPECS3_STR = "par1=1024,param=abc"
1679 ea9d3b40 Bernardo Dal Seno
1680 ea9d3b40 Bernardo Dal Seno
  def _CheckPrintIPolicyCommand(self, ipolicy, isgroup, expected):
1681 ea9d3b40 Bernardo Dal Seno
    buf = StringIO()
1682 ea9d3b40 Bernardo Dal Seno
    cli.PrintIPolicyCommand(buf, ipolicy, isgroup)
1683 ea9d3b40 Bernardo Dal Seno
    self.assertEqual(buf.getvalue(), expected)
1684 ea9d3b40 Bernardo Dal Seno
1685 ea9d3b40 Bernardo Dal Seno
  def testIgnoreStdForGroup(self):
1686 ea9d3b40 Bernardo Dal Seno
    self._CheckPrintIPolicyCommand({"std": self._SPECS1}, True, "")
1687 ea9d3b40 Bernardo Dal Seno
1688 ea9d3b40 Bernardo Dal Seno
  def testIgnoreEmpty(self):
1689 ea9d3b40 Bernardo Dal Seno
    policies = [
1690 ea9d3b40 Bernardo Dal Seno
      {},
1691 ea9d3b40 Bernardo Dal Seno
      {"std": {}},
1692 41044e04 Bernardo Dal Seno
      {"minmax": []},
1693 41044e04 Bernardo Dal Seno
      {"minmax": [{}]},
1694 41044e04 Bernardo Dal Seno
      {"minmax": [{
1695 ea9d3b40 Bernardo Dal Seno
        "min": {},
1696 ea9d3b40 Bernardo Dal Seno
        "max": {},
1697 41044e04 Bernardo Dal Seno
        }]},
1698 41044e04 Bernardo Dal Seno
      {"minmax": [{
1699 ea9d3b40 Bernardo Dal Seno
        "min": self._SPECS1,
1700 ea9d3b40 Bernardo Dal Seno
        "max": {},
1701 41044e04 Bernardo Dal Seno
        }]},
1702 ea9d3b40 Bernardo Dal Seno
      ]
1703 ea9d3b40 Bernardo Dal Seno
    for pol in policies:
1704 ea9d3b40 Bernardo Dal Seno
      self._CheckPrintIPolicyCommand(pol, False, "")
1705 ea9d3b40 Bernardo Dal Seno
1706 ea9d3b40 Bernardo Dal Seno
  def testFullPolicies(self):
1707 ea9d3b40 Bernardo Dal Seno
    cases = [
1708 ea9d3b40 Bernardo Dal Seno
      ({"std": self._SPECS1},
1709 ea9d3b40 Bernardo Dal Seno
       " %s %s" % (cli.IPOLICY_STD_SPECS_STR, self._SPECS1_STR)),
1710 41044e04 Bernardo Dal Seno
      ({"minmax": [{
1711 ea9d3b40 Bernardo Dal Seno
        "min": self._SPECS1,
1712 ea9d3b40 Bernardo Dal Seno
        "max": self._SPECS2,
1713 41044e04 Bernardo Dal Seno
        }]},
1714 ea9d3b40 Bernardo Dal Seno
       " %s min:%s/max:%s" % (cli.IPOLICY_BOUNDS_SPECS_STR,
1715 ea9d3b40 Bernardo Dal Seno
                              self._SPECS1_STR, self._SPECS2_STR)),
1716 ef99e3e8 Bernardo Dal Seno
      ({"minmax": [
1717 ef99e3e8 Bernardo Dal Seno
        {
1718 ef99e3e8 Bernardo Dal Seno
          "min": self._SPECS1,
1719 ef99e3e8 Bernardo Dal Seno
          "max": self._SPECS2,
1720 ef99e3e8 Bernardo Dal Seno
          },
1721 ef99e3e8 Bernardo Dal Seno
        {
1722 ef99e3e8 Bernardo Dal Seno
          "min": self._SPECS2,
1723 ef99e3e8 Bernardo Dal Seno
          "max": self._SPECS3,
1724 ef99e3e8 Bernardo Dal Seno
          },
1725 ef99e3e8 Bernardo Dal Seno
        ]},
1726 ef99e3e8 Bernardo Dal Seno
       " %s min:%s/max:%s//min:%s/max:%s" %
1727 ef99e3e8 Bernardo Dal Seno
       (cli.IPOLICY_BOUNDS_SPECS_STR, self._SPECS1_STR, self._SPECS2_STR,
1728 ef99e3e8 Bernardo Dal Seno
        self._SPECS2_STR, self._SPECS3_STR)),
1729 ea9d3b40 Bernardo Dal Seno
      ]
1730 ea9d3b40 Bernardo Dal Seno
    for (pol, exp) in cases:
1731 ea9d3b40 Bernardo Dal Seno
      self._CheckPrintIPolicyCommand(pol, False, exp)
1732 ea9d3b40 Bernardo Dal Seno
1733 ea9d3b40 Bernardo Dal Seno
1734 d971402f Michael Hanselmann
if __name__ == "__main__":
1735 25231ec5 Michael Hanselmann
  testutils.GanetiTestProgram()