Merge branch 'devel-2.1'
[ganeti-local] / test / ganeti.cli_unittest.py
1 #!/usr/bin/python
2 #
3
4 # Copyright (C) 2008 Google Inc.
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 # 02110-1301, USA.
20
21
22 """Script for unittesting the cli module"""
23
24 import unittest
25 from cStringIO import StringIO
26
27 import ganeti
28 import testutils
29
30 from ganeti import constants
31 from ganeti import cli
32 from ganeti.errors import OpPrereqError, ParameterError
33
34
35 class TestParseTimespec(unittest.TestCase):
36   """Testing case for ParseTimespec"""
37
38   def testValidTimes(self):
39     """Test valid timespecs"""
40     test_data = [
41       ('1s', 1),
42       ('1', 1),
43       ('1m', 60),
44       ('1h', 60 * 60),
45       ('1d', 60 * 60 * 24),
46       ('1w', 60 * 60 * 24 * 7),
47       ('4h', 4 * 60 * 60),
48       ('61m', 61 * 60),
49       ]
50     for value, expected_result in test_data:
51       self.failUnlessEqual(cli.ParseTimespec(value), expected_result)
52
53   def testInvalidTime(self):
54     """Test invalid timespecs"""
55     test_data = [
56       '1y',
57       '',
58       'aaa',
59       's',
60       ]
61     for value in test_data:
62       self.failUnlessRaises(OpPrereqError, cli.ParseTimespec, value)
63
64
65 class TestSplitKeyVal(unittest.TestCase):
66   """Testing case for cli._SplitKeyVal"""
67   DATA = "a=b,c,no_d,-e"
68   RESULT = {"a": "b", "c": True, "d": False, "e": None}
69
70   def testSplitKeyVal(self):
71     """Test splitting"""
72     self.failUnlessEqual(cli._SplitKeyVal("option", self.DATA), self.RESULT)
73
74   def testDuplicateParam(self):
75     """Test duplicate parameters"""
76     for data in ("a=1,a=2", "a,no_a"):
77       self.failUnlessRaises(ParameterError, cli._SplitKeyVal,
78                             "option", data)
79
80   def testEmptyData(self):
81     """Test how we handle splitting an empty string"""
82     self.failUnlessEqual(cli._SplitKeyVal("option", ""), {})
83
84 class TestIdentKeyVal(unittest.TestCase):
85   """Testing case for cli.check_ident_key_val"""
86
87   def testIdentKeyVal(self):
88     """Test identkeyval"""
89     def cikv(value):
90       return cli.check_ident_key_val("option", "opt", value)
91
92     self.assertEqual(cikv("foo:bar"), ("foo", {"bar": True}))
93     self.assertEqual(cikv("foo:bar=baz"), ("foo", {"bar": "baz"}))
94     self.assertEqual(cikv("bar:b=c,c=a"), ("bar", {"b": "c", "c": "a"}))
95     self.assertEqual(cikv("no_bar"), ("bar", False))
96     self.assertRaises(ParameterError, cikv, "no_bar:foo")
97     self.assertRaises(ParameterError, cikv, "no_bar:foo=baz")
98     self.assertEqual(cikv("-foo"), ("foo", None))
99     self.assertRaises(ParameterError, cikv, "-foo:a=c")
100
101
102 class TestToStream(unittest.TestCase):
103   """Thes the ToStream functions"""
104
105   def testBasic(self):
106     for data in ["foo",
107                  "foo %s",
108                  "foo %(test)s",
109                  "foo %s %s",
110                  "",
111                  ]:
112       buf = StringIO()
113       cli._ToStream(buf, data)
114       self.failUnlessEqual(buf.getvalue(), data+'\n')
115
116   def testParams(self):
117       buf = StringIO()
118       cli._ToStream(buf, "foo %s", 1)
119       self.failUnlessEqual(buf.getvalue(), "foo 1\n")
120       buf = StringIO()
121       cli._ToStream(buf, "foo %s", (15,16))
122       self.failUnlessEqual(buf.getvalue(), "foo (15, 16)\n")
123       buf = StringIO()
124       cli._ToStream(buf, "foo %s %s", "a", "b")
125       self.failUnlessEqual(buf.getvalue(), "foo a b\n")
126
127
128 class TestGenerateTable(unittest.TestCase):
129   HEADERS = dict([("f%s" % i, "Field%s" % i) for i in range(5)])
130
131   FIELDS1 = ["f1", "f2"]
132   DATA1 = [
133     ["abc", 1234],
134     ["foobar", 56],
135     ["b", -14],
136     ]
137
138   def _test(self, headers, fields, separator, data,
139             numfields, unitfields, units, expected):
140     table = cli.GenerateTable(headers, fields, separator, data,
141                               numfields=numfields, unitfields=unitfields,
142                               units=units)
143     self.assertEqual(table, expected)
144
145   def testPlain(self):
146     exp = [
147       "Field1 Field2",
148       "abc    1234",
149       "foobar 56",
150       "b      -14",
151       ]
152     self._test(self.HEADERS, self.FIELDS1, None, self.DATA1,
153                None, None, "m", exp)
154
155   def testNoFields(self):
156     self._test(self.HEADERS, [], None, [[], []],
157                None, None, "m", ["", "", ""])
158     self._test(None, [], None, [[], []],
159                None, None, "m", ["", ""])
160
161   def testSeparator(self):
162     for sep in ["#", ":", ",", "^", "!", "%", "|", "###", "%%", "!!!", "||"]:
163       exp = [
164         "Field1%sField2" % sep,
165         "abc%s1234" % sep,
166         "foobar%s56" % sep,
167         "b%s-14" % sep,
168         ]
169       self._test(self.HEADERS, self.FIELDS1, sep, self.DATA1,
170                  None, None, "m", exp)
171
172   def testNoHeader(self):
173     exp = [
174       "abc    1234",
175       "foobar 56",
176       "b      -14",
177       ]
178     self._test(None, self.FIELDS1, None, self.DATA1,
179                None, None, "m", exp)
180
181   def testUnknownField(self):
182     headers = {
183       "f1": "Field1",
184       }
185     exp = [
186       "Field1 UNKNOWN",
187       "abc    1234",
188       "foobar 56",
189       "b      -14",
190       ]
191     self._test(headers, ["f1", "UNKNOWN"], None, self.DATA1,
192                None, None, "m", exp)
193
194   def testNumfields(self):
195     fields = ["f1", "f2", "f3"]
196     data = [
197       ["abc", 1234, 0],
198       ["foobar", 56, 3],
199       ["b", -14, "-"],
200       ]
201     exp = [
202       "Field1 Field2 Field3",
203       "abc      1234      0",
204       "foobar     56      3",
205       "b         -14      -",
206       ]
207     self._test(self.HEADERS, fields, None, data,
208                ["f2", "f3"], None, "m", exp)
209
210   def testUnitfields(self):
211     expnosep = [
212       "Field1 Field2 Field3",
213       "abc      1234     0M",
214       "foobar     56     3M",
215       "b         -14      -",
216       ]
217
218     expsep = [
219       "Field1:Field2:Field3",
220       "abc:1234:0M",
221       "foobar:56:3M",
222       "b:-14:-",
223       ]
224
225     for sep, expected in [(None, expnosep), (":", expsep)]:
226       fields = ["f1", "f2", "f3"]
227       data = [
228         ["abc", 1234, 0],
229         ["foobar", 56, 3],
230         ["b", -14, "-"],
231         ]
232       self._test(self.HEADERS, fields, sep, data,
233                  ["f2", "f3"], ["f3"], "h", expected)
234
235   def testUnusual(self):
236     data = [
237       ["%", "xyz"],
238       ["%%", "abc"],
239       ]
240     exp = [
241       "Field1 Field2",
242       "%      xyz",
243       "%%     abc",
244       ]
245     self._test(self.HEADERS, ["f1", "f2"], None, data,
246                None, None, "m", exp)
247
248
249 if __name__ == '__main__':
250   testutils.GanetiTestProgram()