# HG changeset patch # User cmlenz # Date 1186147745 0 # Node ID a10942252ebcbca6a6320abe27eaaa87ce8a0a17 # Parent d039348592bb6b8f99212d93650f1977eb89cd1b Use POST for submitting step results, instead of PUT. diff --git a/bitten/master.py b/bitten/master.py --- a/bitten/master.py +++ b/bitten/master.py @@ -57,7 +57,7 @@ # IRequestHandler methods def match_request(self, req): - match = re.match(r'/builds(?:/(\d+)(?:/(\w+)/([^/]+))?)?$', + match = re.match(r'/builds(?:/(\d+)(?:/(\w+)/([^/]+)?)?)?$', req.path_info) if match: if match.group(1): @@ -82,12 +82,11 @@ if not req.args['collection']: return self._process_build_initiation(req, config, build) - if req.method != 'PUT': + if req.method != 'POST': raise HTTPMethodNotAllowed('Method not allowed') if req.args['collection'] == 'steps': - return self._process_build_step(req, config, build, - req.args['member']) + return self._process_build_step(req, config, build) else: raise HTTPNotFound('No such collection') @@ -149,7 +148,13 @@ req.write(body) raise RequestDone - def _process_build_step(self, req, config, build, stepname): + def _process_build_step(self, req, config, build): + try: + elem = xmlio.parse(req.read()) + except xmlio.ParseError, e: + raise HTTPBadRequest('XML parser error') + stepname = elem.attr['step'] + step = BuildStep.fetch(self.env, build=build.id, name=stepname) if step: raise HTTPConflict('Build step already exists') @@ -165,11 +170,6 @@ raise HTTPForbidden('No such build step') last_step = index == num - try: - elem = xmlio.parse(req.read()) - except xmlio.ParseError, e: - raise HTTPBadRequest('XML parser error') - self.log.debug('Slave %s completed step %d (%s) with status %s', build.slave, index, stepname, elem.attr['status']) @@ -191,7 +191,7 @@ # Collect log messages from the request body for idx, log_elem in enumerate(elem.children('log')): - build_log = BuildLog(self.env, build=build.id, step=step.name, + build_log = BuildLog(self.env, build=build.id, step=stepname, generator=log_elem.attr.get('generator'), orderno=idx) for message_elem in log_elem.children('message'): @@ -201,7 +201,7 @@ # Collect report data from the request body for report_elem in elem.children('report'): - report = Report(self.env, build=build.id, step=step.name, + report = Report(self.env, build=build.id, step=stepname, category=report_elem.attr.get('category'), generator=report_elem.attr.get('generator')) for item_elem in report_elem.children(): diff --git a/bitten/slave.py b/bitten/slave.py --- a/bitten/slave.py +++ b/bitten/slave.py @@ -163,7 +163,7 @@ def _execute_step(self, build_url, recipe, step): failed = False started = datetime.utcnow() - xml = xmlio.Element('result', time=started.isoformat()) + xml = xmlio.Element('result', step=step.id, time=started.isoformat()) try: for type, category, generator, output in \ step.execute(recipe.ctxt): @@ -187,10 +187,10 @@ xml.attr['status'] = 'success' log.info('Build step %s completed successfully', step.id) - resp = self.request('PUT', build_url + '/steps/' + step.id, str(xml), { + resp = self.request('POST', build_url + '/steps/', str(xml), { 'Content-Type': 'application/x-bitten+xml' }) - if resp.status != 200: + if resp.status != 201: log.error('Unexpected response (%d): %s', resp.status, resp.reason) return not failed or step.onerror != 'fail' diff --git a/bitten/tests/master.py b/bitten/tests/master.py --- a/bitten/tests/master.py +++ b/bitten/tests/master.py @@ -213,8 +213,8 @@ build = Build(self.env, 'test', '123', 1, slave='hal', rev_time=42) build.insert() - req = Mock(method='PUT', base_path='', - path_info='/builds/%d/files/abc.zip' % build.id, + req = Mock(method='POST', base_path='', + path_info='/builds/%d/files/' % build.id, href=Href('/trac'), remote_addr='127.0.0.1', args={}, perm=PermissionCache(self.env, 'hal')) @@ -237,14 +237,14 @@ started=42) build.insert() - inbody = StringIO(""" """) outheaders = {} outbody = StringIO() - req = Mock(method='PUT', base_path='', - path_info='/builds/%d/steps/foo' % build.id, + 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, @@ -283,7 +283,7 @@ started=42) build.insert() - inbody = StringIO(""" @@ -293,8 +293,8 @@ """) outheaders = {} outbody = StringIO() - req = Mock(method='PUT', base_path='', - path_info='/builds/%d/steps/foo' % build.id, + 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, @@ -341,7 +341,7 @@ started=42) build.insert() - inbody = StringIO(""" """) outheaders = {} outbody = StringIO() - req = Mock(method='PUT', base_path='', - path_info='/builds/%d/steps/foo' % build.id, + 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, @@ -406,14 +406,14 @@ started=42) build.insert() - inbody = StringIO(""" """) outheaders = {} outbody = StringIO() - req = Mock(method='PUT', base_path='', - path_info='/builds/%d/steps/foo' % build.id, + 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, @@ -452,14 +452,14 @@ started=42) build.insert() - inbody = StringIO(""" """) outheaders = {} outbody = StringIO() - req = Mock(method='PUT', base_path='', - path_info='/builds/%d/steps/foo' % build.id, + 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, @@ -499,8 +499,8 @@ build.insert() inbody = StringIO("""""") - req = Mock(method='PUT', base_path='', - path_info='/builds/%d/steps/foo' % build.id, + 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) @@ -524,12 +524,12 @@ started=42) build.insert() - inbody = StringIO(""" """) - req = Mock(method='PUT', base_path='', - path_info='/builds/%d/steps/foo' % build.id, + 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) @@ -543,15 +543,15 @@ self.assertEqual("Invalid ISO date/time 'sometime tomorrow maybe'", e.detail) - def test_process_build_step_no_put(self): + def test_process_build_step_no_post(self): BuildConfig(self.env, 'test', path='somepath', active=True, recipe='').insert() build = Build(self.env, 'test', '123', 1, slave='hal', rev_time=42, started=42) build.insert() - req = Mock(method='POST', base_path='', - path_info='/builds/%d/steps/foo' % build.id, + req = Mock(method='GET', base_path='', + path_info='/builds/%d/steps/' % build.id, href=Href('/trac'), remote_addr='127.0.0.1', args={}, perm=PermissionCache(self.env, 'hal'))