# HG changeset patch # User wbell # Date 1272119406 0 # Node ID bfd5fd75d1d664e6375de1ec7c222a00946c09b3 # Parent ab1f18d0e98ca80d23c509314ede565827c95f29 Port of [836] to 0.6.x diff --git a/bitten/master.py b/bitten/master.py --- a/bitten/master.py +++ b/bitten/master.py @@ -281,13 +281,14 @@ db = self.env.get_db_cnx() step = BuildStep(self.env, build=build.id, name=stepname) - try: - step.started = int(_parse_iso_datetime(elem.attr['time'])) - step.stopped = step.started + float(elem.attr['duration']) - except ValueError, e: - self.log.error('Error parsing build step timestamp: %s', e, - exc_info=True) - self._send_error(req, HTTP_BAD_REQUEST, e.args[0]) + + # not a great way to determine the start/stop time of the + # step, but it's a server time, which eliminates a bunch + # of skew issues. + now = int(time.time()) + step.started = now - float(elem.attr['duration']) + step.stopped = now + if elem.attr['status'] == 'failure': self.log.warning('Build %s step %s failed', build.id, stepname) step.status = BuildStep.FAILURE @@ -375,14 +376,3 @@ 'Location': req.abs_href.builds( build.id, 'steps', stepname)}) - -def _parse_iso_datetime(string): - """Minimal parser for ISO date-time strings. - - Return the time as floating point number. Only handles UTC timestamps - without time zone information.""" - try: - string = string.split('.', 1)[0] # strip out microseconds - return calendar.timegm(time.strptime(string, '%Y-%m-%dT%H:%M:%S')) - except ValueError, e: - raise ValueError('Invalid ISO date/time %r' % string) diff --git a/bitten/slave.py b/bitten/slave.py --- a/bitten/slave.py +++ b/bitten/slave.py @@ -325,8 +325,8 @@ def _execute_step(self, build_url, recipe, step): failed = False - started = datetime.utcnow() - xml = xmlio.Element('result', step=step.id, time=started.isoformat()) + started = int(time.time()) + xml = xmlio.Element('result', step=step.id) try: for type, category, generator, output in \ step.execute(recipe.ctxt): @@ -347,7 +347,7 @@ except Exception, e: log.error('Internal error in build step %r', step.id, exc_info=True) failed = True - xml.attr['duration'] = (datetime.utcnow() - started).seconds + xml.attr['duration'] = (time.time() - started) if failed: xml.attr['status'] = 'failure' else: diff --git a/bitten/tests/master.py b/bitten/tests/master.py --- a/bitten/tests/master.py +++ b/bitten/tests/master.py @@ -913,42 +913,6 @@ self.assertEquals(400, outheaders['Status']) self.assertEquals('XML parser error', outbody.getvalue()) - def test_process_build_step_invalid_datetime(self): - recipe = """ - - -""" - BuildConfig(self.env, 'test', path='somepath', active=True, - recipe=recipe).insert() - build = Build(self.env, 'test', '123', 1, slave='hal', rev_time=42, - started=42, status=Build.IN_PROGRESS) - build.slave_info[Build.TOKEN] = '123'; - build.insert() - - inbody = StringIO(""" -""") - outheaders = {} - outbody = StringIO() - req = Mock(method='POST', base_path='', - path_info='/builds/%d/steps/' % build.id, - href=Href('/trac'), remote_addr='127.0.0.1', args={}, - perm=PermissionCache(self.env, 'hal'), - read=inbody.read, - send_response=lambda x: outheaders.setdefault('Status', x), - send_header=lambda x, y: outheaders.setdefault(x, y), - write=outbody.write, - incookie=Cookie('trac_auth=123')) - - module = BuildMaster(self.env) - assert module.match_request(req) - - self.assertRaises(RequestDone, module.process_request, req) - - self.assertEquals(400, outheaders['Status']) - self.assertEquals("Invalid ISO date/time 'sometime tomorrow maybe'", - outbody.getvalue()) def test_process_build_step_no_post(self): BuildConfig(self.env, 'test', path='somepath', active=True,