From 9f37f689ce4e3aa2a300ba5d86d9d17f3abbcdf5 Mon Sep 17 00:00:00 2001 From: Michael Hanselmann <hansmi@google.com> Date: Fri, 17 Dec 2010 18:38:40 +0100 Subject: [PATCH] utils: Timezone fixes and tests - Update docstrings to explicitely mention Epoch - Fix timezone bug in FormatTimestampWithTZ, where it would use GMT/UTC when it should use the local timezone - Add unittests for time formatting functions Signed-off-by: Michael Hanselmann <hansmi@google.com> Reviewed-by: Iustin Pop <iustin@google.com> --- lib/utils.py | 12 ++++++++---- test/ganeti.utils_unittest.py | 36 +++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/lib/utils.py b/lib/utils.py index bef80576d..7c7808f26 100644 --- a/lib/utils.py +++ b/lib/utils.py @@ -1680,8 +1680,8 @@ def RemoveHostFromEtcHosts(hostname): def TimestampForFilename(): """Returns the current time formatted for filenames. - The format doesn't contain colons as some shells and applications them as - separators. + The format doesn't contain colons as some shells and applications treat them + as separators. Uses the local timezone. """ return time.strftime("%Y-%m-%d_%H_%M_%S") @@ -2838,8 +2838,11 @@ def TailFile(fname, lines=20): def FormatTimestampWithTZ(secs): """Formats a Unix timestamp with the local timezone. + @type secs: number + @param secs: Seconds since the Epoch (1970-01-01 00:00:00 UTC) + """ - return time.strftime("%F %T %Z", time.gmtime(secs)) + return time.strftime("%F %T %Z", time.localtime(secs)) def _ParseAsn1Generalizedtime(value): @@ -3366,7 +3369,8 @@ def FormatTime(val): """Formats a time value. @type val: float or None - @param val: the timestamp as returned by time.time() + @param val: Timestamp as returned by time.time() (seconds since Epoch, + 1970-01-01 00:00:00 UTC) @return: a string value or N/A if we don't have a valid timestamp """ diff --git a/test/ganeti.utils_unittest.py b/test/ganeti.utils_unittest.py index eaa183929..1f80e6b10 100755 --- a/test/ganeti.utils_unittest.py +++ b/test/ganeti.utils_unittest.py @@ -1682,6 +1682,23 @@ class TestSafeEncode(unittest.TestCase): class TestFormatTime(unittest.TestCase): """Testing case for FormatTime""" + @staticmethod + def _TestInProcess(tz, timestamp, expected): + os.environ["TZ"] = tz + time.tzset() + return utils.FormatTime(timestamp) == expected + + def _Test(self, *args): + # Need to use separate process as we want to change TZ + self.assert_(utils.RunInSeparateProcess(self._TestInProcess, *args)) + + def test(self): + self._Test("UTC", 0, "1970-01-01 00:00:00") + self._Test("America/Sao_Paulo", 1292606926, "2010-12-17 15:28:46") + self._Test("Europe/London", 1292606926, "2010-12-17 17:28:46") + self._Test("Europe/Zurich", 1292606926, "2010-12-17 18:28:46") + self._Test("Australia/Sydney", 1292606926, "2010-12-18 04:28:46") + def testNone(self): self.failUnlessEqual(FormatTime(None), "N/A") @@ -1695,6 +1712,25 @@ class TestFormatTime(unittest.TestCase): FormatTime(int(time.time())) +class TestFormatTimestampWithTZ(unittest.TestCase): + @staticmethod + def _TestInProcess(tz, timestamp, expected): + os.environ["TZ"] = tz + time.tzset() + return utils.FormatTimestampWithTZ(timestamp) == expected + + def _Test(self, *args): + # Need to use separate process as we want to change TZ + self.assert_(utils.RunInSeparateProcess(self._TestInProcess, *args)) + + def test(self): + self._Test("UTC", 0, "1970-01-01 00:00:00 UTC") + self._Test("America/Sao_Paulo", 1292606926, "2010-12-17 15:28:46 BRST") + self._Test("Europe/London", 1292606926, "2010-12-17 17:28:46 GMT") + self._Test("Europe/Zurich", 1292606926, "2010-12-17 18:28:46 CET") + self._Test("Australia/Sydney", 1292606926, "2010-12-18 04:28:46 EST") + + class RunInSeparateProcess(unittest.TestCase): def test(self): for exp in [True, False]: -- GitLab