From 95dadd3d84caa42df3c7e47800dc79c951b2f930 Mon Sep 17 00:00:00 2001 From: "Dustin J. Mitchell" Date: Tue, 15 Jul 2014 09:19:35 -0400 Subject: [PATCH] Use dateutil.tz.gettz to handle P4Poller's `server_tz`. --- master/buildbot/changes/p4poller.py | 5 ++-- master/buildbot/schedulers/timed.py | 10 +------ .../test/unit/test_changes_p4poller.py | 29 +++++++++++++++++++ master/buildbot/test/unit/test_util.py | 2 +- master/buildbot/util/__init__.py | 26 ++++++----------- master/docs/manual/cfg-changesources.rst | 3 +- master/docs/relnotes/index.rst | 7 +++++ 7 files changed, 50 insertions(+), 32 deletions(-) diff --git a/master/buildbot/changes/p4poller.py b/master/buildbot/changes/p4poller.py index 1db6d2319b8..b1d9d1c6d89 100644 --- a/master/buildbot/changes/p4poller.py +++ b/master/buildbot/changes/p4poller.py @@ -18,7 +18,7 @@ # Many thanks to Dave Peticolas for contributing this module import datetime -import dateutil +import dateutil.tz import exceptions import os import os.path @@ -148,7 +148,7 @@ def __init__(self, p4port=None, p4user=None, p4passwd=None, self.project = util.ascii2unicode(project) self.use_tickets = use_tickets self.ticket_login_interval = ticket_login_interval - self.server_tz = server_tz + self.server_tz = dateutil.tz.gettz(server_tz) if server_tz else None self._ticket_passwd = None self._ticket_login_counter = 0 @@ -272,7 +272,6 @@ def _poll(self): if self.server_tz: # Convert from the server's timezone to the local timezone. when = when.replace(tzinfo=self.server_tz) - when = when.astimezone(dateutil.tz.tzlocal()) when = util.datetime2epoch(when) comments = '' while not lines[0].startswith('Affected files'): diff --git a/master/buildbot/schedulers/timed.py b/master/buildbot/schedulers/timed.py index 3f82c6ff0ec..20d11d804cd 100644 --- a/master/buildbot/schedulers/timed.py +++ b/master/buildbot/schedulers/timed.py @@ -22,18 +22,10 @@ from buildbot.process import buildstep from buildbot.process import properties from buildbot.schedulers import base +from buildbot.util import croniter from twisted.internet import defer from twisted.internet import reactor from twisted.python import log -# Import croniter if available. -# This is only required for Nightly schedulers, -# so fail gracefully if it isn't present. -try: - from buildbot.util import croniter -except ImportError: - # Pyflakes doesn't like a redefinition here - # Instead, we check if croniter is defined when we need it - pass class Timed(base.BaseScheduler): diff --git a/master/buildbot/test/unit/test_changes_p4poller.py b/master/buildbot/test/unit/test_changes_p4poller.py index 0f2b90e55d5..7d90f4c27ff 100644 --- a/master/buildbot/test/unit/test_changes_p4poller.py +++ b/master/buildbot/test/unit/test_changes_p4poller.py @@ -14,6 +14,7 @@ # Copyright Buildbot Team Members import datetime +import dateutil.tz from buildbot.changes.p4poller import P4PollerError from buildbot.changes.p4poller import P4Source @@ -347,6 +348,34 @@ def check(res): d.addCallback(check) return d + def test_server_tz(self): + """Verify that the server_tz parameter is handled correctly""" + self.attachChangeSource( + P4Source(p4port=None, p4user=None, + p4base='//depot/myproject/', + split_file=get_simple_split, + server_tz="Europe/Berlin")) + self.expectCommands( + gpo.Expect('p4', 'changes', '//depot/myproject/...@51,now').stdout(third_p4changes), + ) + self.add_p4_describe_result(5, p4change[5]) + + self.changesource.last_change = 50 + d = self.changesource.poll() + + def check(res): + # when_timestamp is converted from 21:55:39 Berlin time to UTC + when_berlin = self.makeTime("2006/04/13 21:55:39") + when_berlin = when_berlin.replace(tzinfo=dateutil.tz.gettz('Europe/Berlin')) + when = datetime2epoch(when_berlin) + + self.assertEqual([ch['when_timestamp'] + for ch in self.master.data.updates.changesAdded], + [when, when]) + self.assertAllCommandsRan() + d.addCallback(check) + return d + class TestSplit(unittest.TestCase): diff --git a/master/buildbot/test/unit/test_util.py b/master/buildbot/test/unit/test_util.py index dcdae889662..212db97296c 100644 --- a/master/buildbot/test/unit/test_util.py +++ b/master/buildbot/test/unit/test_util.py @@ -124,7 +124,7 @@ def test_UTC(self): datetime.timedelta(0)) self.assertEqual(util.UTC.dst(datetime.datetime.now()), datetime.timedelta(0)) - self.assertEqual(util.UTC.tzname(), "UTC") + self.assertEqual(util.UTC.tzname(datetime.datetime.utcnow()), "UTC") def test_epoch2datetime(self): self.assertEqual(util.epoch2datetime(0), diff --git a/master/buildbot/util/__init__.py b/master/buildbot/util/__init__.py index a3d40737d5a..0b85e05b7b9 100644 --- a/master/buildbot/util/__init__.py +++ b/master/buildbot/util/__init__.py @@ -16,6 +16,7 @@ import calendar import datetime +import dateutil.tz import locale import re import string @@ -88,7 +89,8 @@ class _None: def __hash__(self): compare_attrs = [] - reflect.accumulateClassList(self.__class__, 'compare_attrs', compare_attrs) + reflect.accumulateClassList( + self.__class__, 'compare_attrs', compare_attrs) alist = [self.__class__] + \ [getattr(self, name, self._None) for name in compare_attrs] @@ -104,7 +106,8 @@ def __cmp__(self, them): return result compare_attrs = [] - reflect.accumulateClassList(self.__class__, 'compare_attrs', compare_attrs) + reflect.accumulateClassList( + self.__class__, 'compare_attrs', compare_attrs) self_list = [getattr(self, name, self._None) for name in compare_attrs] @@ -114,7 +117,8 @@ def __cmp__(self, them): def getConfigDict(self): compare_attrs = [] - reflect.accumulateClassList(self.__class__, 'compare_attrs', compare_attrs) + reflect.accumulateClassList( + self.__class__, 'compare_attrs', compare_attrs) return dict([(k, getattr(self, k)) for k in compare_attrs if hasattr(self, k) and k not in ("passwd", "password")]) @@ -182,20 +186,8 @@ def __nonzero__(self): # time-handling methods - -class UTC(datetime.tzinfo): - - """Simple definition of UTC timezone""" - - def utcoffset(self, dt): - return datetime.timedelta(0) - - def dst(self, dt): - return datetime.timedelta(0) - - def tzname(self): - return "UTC" -UTC = UTC() +# this used to be a custom class; now it's just an instance of dateutil's class +UTC = dateutil.tz.tzutc() def epoch2datetime(epoch): diff --git a/master/docs/manual/cfg-changesources.rst b/master/docs/manual/cfg-changesources.rst index e05f6c44423..8e651051393 100644 --- a/master/docs/manual/cfg-changesources.rst +++ b/master/docs/manual/cfg-changesources.rst @@ -618,8 +618,7 @@ depot for changes. It accepts the following arguments: ``server_tz`` The timezone of the Perforce server, using the usual timezone format - (e.g: ``Europe/Stockholm``) in case it's in a different timezone than the - buildbot master. + (e.g: ``"Europe/Stockholm"``) in case it's not in UTC. ``use_tickets`` Set to ``True`` to use ticket-based authentication, instead of passwords (but diff --git a/master/docs/relnotes/index.rst b/master/docs/relnotes/index.rst index c6e5f5520d5..c8d244d4814 100644 --- a/master/docs/relnotes/index.rst +++ b/master/docs/relnotes/index.rst @@ -51,6 +51,11 @@ But the devil is in the details: * If you want multiple masters, you'll need an external message broker of some sort. Messaging is based on `Kombu `_, and supports the backends that Kombu supports. +Minor Python Packages +..................... + +* Buildbot requires at least Twisted-11.0.0. + Features ~~~~~~~~ @@ -105,6 +110,8 @@ Fixes More detailed information is available in :bb:status:`GerritStatusPush` section. +* :bb:chsrc:`P4Poller`'s ``server_tz`` parameter now works correctly. + Deprecations, Removals, and Non-Compatible Changes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~