diff --git a/Makefile.am b/Makefile.am index cbc9ac7bd8fbef3491da0aa4142ce591bd2b6e32..dd5ad12db9a26690d3a9eb88a5387ceb2db8038d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -202,7 +202,8 @@ dist_TESTS = \ test/ganeti.workerpool_unittest.py \ test/ganeti.rapi.resources_unittest.py \ test/ganeti.http_unittest.py \ - test/ganeti.constants_unittest.py + test/ganeti.constants_unittest.py \ + test/ganeti.cli_unittest.py nodist_TESTS = diff --git a/lib/cli.py b/lib/cli.py index 71a99530708126aaec0c826b01a16c5acf04d861..a2843912358c52eedbf907944311aa02f662169b 100644 --- a/lib/cli.py +++ b/lib/cli.py @@ -707,3 +707,45 @@ def FormatTimestamp(ts): return '?' sec, usec = ts return time.strftime("%F %T", time.localtime(sec)) + ".%06d" % usec + + +def ParseTimespec(value): + """Parse a time specification. + + The following suffixed will be recognized: + + - s: seconds + - m: minutes + - h: hours + - d: day + - w: weeks + + Without any suffix, the value will be taken to be in seconds. + + """ + value = str(value) + if not value: + raise errors.OpPrereqError("Empty time specification passed") + suffix_map = { + 's': 1, + 'm': 60, + 'h': 3600, + 'd': 86400, + 'w': 604800, + } + if value[-1] not in suffix_map: + try: + value = int(value) + except ValueError: + raise errors.OpPrereqError("Invalid time specification '%s'" % value) + else: + multiplier = suffix_map[value[-1]] + value = value[:-1] + if not value: # no data left after stripping the suffix + raise errors.OpPrereqError("Invalid time specification (only" + " suffix passed)") + try: + value = int(value) * multiplier + except ValueError: + raise errors.OpPrereqError("Invalid time specification '%s'" % value) + return value diff --git a/test/ganeti.cli_unittest.py b/test/ganeti.cli_unittest.py new file mode 100755 index 0000000000000000000000000000000000000000..fb0d8201f660bdb8f64d863dd981455c9f25017a --- /dev/null +++ b/test/ganeti.cli_unittest.py @@ -0,0 +1,63 @@ +#!/usr/bin/python +# + +# Copyright (C) 2008 Google Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + + +"""Script for unittesting the cli module""" + +import unittest + +import ganeti +import testutils +from ganeti import constants +from ganeti import cli +from ganeti.errors import OpPrereqError + +class TestParseTimespec(unittest.TestCase): + """Testing case for ParseTimespec""" + + def testValidTimes(self): + """Test valid timespecs""" + test_data = [ + ('1s', 1), + ('1', 1), + ('1m', 60), + ('1h', 60 * 60), + ('1d', 60 * 60 * 24), + ('1w', 60 * 60 * 24 * 7), + ('4h', 4 * 60 * 60), + ('61m', 61 * 60), + ] + for value, expected_result in test_data: + self.failUnlessEqual(cli.ParseTimespec(value), expected_result) + + def testInvalidTime(self): + """Test invalid timespecs""" + test_data = [ + '1y', + '', + 'aaa', + 's', + ] + for value in test_data: + self.failUnlessRaises(OpPrereqError, cli.ParseTimespec, value) + + +if __name__ == '__main__': + unittest.main()