blob: c6aef2d802dd62616a77b90f84aa609ff8e39462 [file] [log] [blame]
# Copyright (C) 2018-2019 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import logging
import threading
import time
from ews.common.bugzilla import Bugzilla
from ews.common.buildbot import Buildbot
from ews.models.patch import Patch
_log = logging.getLogger(__name__)
class FetchLoop():
def __init__(self, interval=30):
self.interval = interval
thread = threading.Thread(target=self.run, args=())
thread.daemon = True
thread.start()
def run(self):
while True:
Buildbot.update_icons_for_queues_mapping()
try:
BugzillaPatchFetcher().fetch()
except Exception as e:
_log.error('Exception in BugzillaPatchFetcher: {}'.format(e))
time.sleep(self.interval)
class BugzillaPatchFetcher():
def fetch(self, patch_ids=None):
if patch_ids and type(patch_ids) != list:
_log.error('Error: patch_ids should be a list, found: {}'.format(type(patch_ids)))
return -1
if not patch_ids:
patch_ids = Bugzilla.get_list_of_patches_needing_reviews()
patch_ids = BugzillaPatchFetcher.filter_valid_patches(patch_ids)
_log.debug('r? patches: {}'.format(patch_ids))
Patch.save_patches(patch_ids)
patches_to_send = self.patches_to_send_to_buildbot(patch_ids)
_log.info('{} r? patches, {} patches need to be sent to Buildbot: {}'.format(len(patch_ids), len(patches_to_send), patches_to_send))
for patch_id in patches_to_send:
bz_patch = Bugzilla.retrieve_attachment(patch_id)
if not bz_patch or bz_patch['id'] != patch_id:
_log.error('Unable to retrive patch "{}"'.format(patch_id))
continue
if bz_patch.get('is_obsolete'):
_log.warn('Patch is obsolete, skipping')
Patch.set_obsolete(patch_id)
continue
if Patch.is_patch_sent_to_buildbot(patch_id):
_log.error('Patch {} is already sent to buildbot.'.format(patch_id))
continue
Patch.set_sent_to_buildbot(patch_id, True)
rc = Buildbot.send_patch_to_buildbot(bz_patch['path'],
properties=['patch_id={}'.format(patch_id), 'bug_id={}'.format(bz_patch['bug_id']), 'owner={}'.format(bz_patch.get('creator', ''))])
if rc == 0:
Patch.set_bug_id(patch_id, bz_patch['bug_id'])
else:
_log.error('Failed to send patch to buildbot.')
Patch.set_sent_to_buildbot(patch_id, False)
#FIXME: send an email for this failure
return patch_ids
def patches_to_send_to_buildbot(self, patch_ids):
return [patch_id for patch_id in patch_ids if not Patch.is_patch_sent_to_buildbot(patch_id)]
@classmethod
def filter_valid_patches(cls, patch_ids):
return list(filter(lambda p: Patch.is_valid_patch_id(p), patch_ids))