Title: [239650] trunk/Tools
Revision
239650
Author
aakash_j...@apple.com
Date
2019-01-04 18:30:03 -0800 (Fri, 04 Jan 2019)

Log Message

[ews-build] Add build step to validate the patch before processing it
https://bugs.webkit.org/show_bug.cgi?id=193140

Reviewed by Lucas Forschler.

* BuildSlaveSupport/ews-build/factories.py:
(Factory.__init__): Added ValidatePatch step.
* BuildSlaveSupport/ews-build/steps.py:
(ValidatePatch):
(ValidatePatch.fetch_data_from_url): Fetch data from a url.
(ValidatePatch.get_patch_json): Get patch json data.
(ValidatePatch.get_bug_json): Get bug json data.
(ValidatePatch.get_bug_id_from_patch): Get bug id from a patch id.
(ValidatePatch._is_patch_obsolete): Check if the patch is obsolete.
(ValidatePatch._is_patch_review_denied): Check if the patch is marked r-.
(ValidatePatch._is_bug_closed): Check if the bug is already closed.
(ValidatePatch.skip_build): Skip the build.
(ValidatePatch.start):

Modified Paths

Diff

Modified: trunk/Tools/BuildSlaveSupport/ews-build/factories.py (239649 => 239650)


--- trunk/Tools/BuildSlaveSupport/ews-build/factories.py	2019-01-05 01:23:52 UTC (rev 239649)
+++ trunk/Tools/BuildSlaveSupport/ews-build/factories.py	2019-01-05 02:30:03 UTC (rev 239650)
@@ -35,6 +35,7 @@
         self.addStep(ConfigureBuild(platform, configuration, architectures, buildOnly, additionalArguments))
         if checkRelevance:
             self.addStep(CheckPatchRelevance())
+        self.addStep(ValidatePatch())
         self.addStep(CheckOutSource())
         self.addStep(ApplyPatch())
 

Modified: trunk/Tools/BuildSlaveSupport/ews-build/steps.py (239649 => 239650)


--- trunk/Tools/BuildSlaveSupport/ews-build/steps.py	2019-01-05 01:23:52 UTC (rev 239649)
+++ trunk/Tools/BuildSlaveSupport/ews-build/steps.py	2019-01-05 02:30:03 UTC (rev 239650)
@@ -28,6 +28,7 @@
 from twisted.internet import defer
 
 import re
+import requests
 
 BUG_SERVER_URL = 'https://bugs.webkit.org/'
 EWS_URL = 'http://ews-build.webkit-uat.org/'
@@ -221,6 +222,137 @@
         return None
 
 
+class ValidatePatch(buildstep.BuildStep):
+    name = 'validate-patch'
+    description = ['validate-patch running']
+    descriptionDone = ['validate-patch']
+    flunkOnFailure = True
+    haltOnFailure = True
+    bug_open_statuses = ["UNCONFIRMED", "NEW", "ASSIGNED", "REOPENED"]
+    bug_closed_statuses = ["RESOLVED", "VERIFIED", "CLOSED"]
+
+    @defer.inlineCallbacks
+    def _addToLog(self, logName, message):
+        try:
+            log = self.getLog(logName)
+        except KeyError:
+            log = yield self.addLog(logName)
+        log.addStdout(message)
+
+    def fetch_data_from_url(self, url):
+        response = None
+        try:
+            response = requests.get(url)
+        except Exception as e:
+            if response:
+                self._addToLog('stdio', 'Failed to access {url} with status code {status_code}.\n'.format(url="" status_code=response.status_code))
+            else:
+                self._addToLog('stdio', 'Failed to access {url} with exception: {exception}\n'.format(url="" exception=e))
+            return None
+        if response.status_code != 200:
+            self._addToLog('stdio', 'Accessed {url} with unexpected status code {status_code}.\n'.format(url="" status_code=response.status_code))
+            return None
+        return response
+
+    def get_patch_json(self, patch_id):
+        patch_url = '{}rest/bug/attachment/{}'.format(BUG_SERVER_URL, patch_id)
+        patch = self.fetch_data_from_url(patch_url)
+        if not patch:
+            return None
+        patch_json = patch.json().get('attachments')
+        if not patch_json or len(patch_json) == 0:
+            return None
+        return patch_json.get(str(patch_id))
+
+    def get_bug_json(self, bug_id):
+        bug_url = '{}rest/bug/{}'.format(BUG_SERVER_URL, bug_id)
+        bug = self.fetch_data_from_url(bug_url)
+        if not bug:
+            return None
+        bugs_json = bug.json().get('bugs')
+        if not bugs_json or len(bugs_json) == 0:
+            return None
+        return bugs_json[0]
+
+    def get_bug_id_from_patch(self, patch_id):
+        patch_json = self.get_patch_json(patch_id)
+        if not patch_json:
+            self._addToLog('stdio', 'Unable to fetch patch {}.\n'.format(patch_id))
+            return -1
+        return patch_json.get('bug_id')
+
+    def _is_patch_obsolete(self, patch_id):
+        patch_json = self.get_patch_json(patch_id)
+        if not patch_json:
+            self._addToLog('stdio', 'Unable to fetch patch {}.\n'.format(patch_id))
+            return -1
+
+        if patch_json.get('id') != self.getProperty('patch_id', ''):
+            self._addToLog('stdio', 'Fetched patch id {} does not match with requested patch id {}. Unable to validate.\n'.format(patch_json.get('id'), self.getProperty('patch_id', '')))
+            return -1
+
+        return patch_json.get('is_obsolete')
+
+    def _is_patch_review_denied(self, patch_id):
+        patch_json = self.get_patch_json(patch_id)
+        if not patch_json:
+            self._addToLog('stdio', 'Unable to fetch patch {}.\n'.format(patch_id))
+            return -1
+
+        for flag in patch_json.get('flags', []):
+            if flag.get('name') == 'review' and flag.get('status') == '-':
+                return 1
+        return 0
+
+    def _is_bug_closed(self, bug_id):
+        bug_json = self.get_bug_json(bug_id)
+        if not bug_json or not bug_json.get('status'):
+            self._addToLog('stdio', 'Unable to fetch bug {}.\n'.format(bug_id))
+            return -1
+
+        if bug_json.get('status') in self.bug_closed_statuses:
+            return 1
+        return 0
+
+    def skip_build(self, reason):
+        self._addToLog('stdio', reason)
+        self.finished(FAILURE)
+        self.build.results = SKIPPED
+        self.build.buildFinished([reason], SKIPPED)
+
+    def start(self):
+        patch_id = self.getProperty('patch_id', '')
+        if not patch_id:
+            self._addToLog('stdio', 'No patch_id found. Unable to proceed without patch_id.\n')
+            self.finished(FAILURE)
+            return None
+
+        bug_id = self.getProperty('bug_id', self.get_bug_id_from_patch(patch_id))
+
+        bug_closed = self._is_bug_closed(bug_id)
+        if bug_closed == 1:
+            self.skip_build('Bug {} is already closed'.format(bug_id))
+            return None
+
+        obsolete = self._is_patch_obsolete(patch_id)
+        if obsolete == 1:
+            self.skip_build('Patch {} is obsolete'.format(patch_id))
+            return None
+
+        review_denied = self._is_patch_review_denied(patch_id)
+        if review_denied == 1:
+            self.skip_build('Patch {} is marked r-'.format(patch_id))
+            return None
+
+        if obsolete == -1 or review_denied == -1 or bug_closed == -1:
+            self.finished(WARNINGS)
+            return None
+
+        self._addToLog('stdio', 'Bug is open.\nPatch is not obsolete.\nPatch is not marked r-.\n')
+        self.finished(SUCCESS)
+        return None
+
+
 class UnApplyPatchIfRequired(CheckOutSource):
     name = 'unapply-patch'
 

Modified: trunk/Tools/ChangeLog (239649 => 239650)


--- trunk/Tools/ChangeLog	2019-01-05 01:23:52 UTC (rev 239649)
+++ trunk/Tools/ChangeLog	2019-01-05 02:30:03 UTC (rev 239650)
@@ -1,3 +1,24 @@
+2019-01-04  Aakash Jain  <aakash_j...@apple.com>
+
+        [ews-build] Add build step to validate the patch before processing it
+        https://bugs.webkit.org/show_bug.cgi?id=193140
+
+        Reviewed by Lucas Forschler.
+
+        * BuildSlaveSupport/ews-build/factories.py:
+        (Factory.__init__): Added ValidatePatch step.
+        * BuildSlaveSupport/ews-build/steps.py:
+        (ValidatePatch):
+        (ValidatePatch.fetch_data_from_url): Fetch data from a url.
+        (ValidatePatch.get_patch_json): Get patch json data.
+        (ValidatePatch.get_bug_json): Get bug json data.
+        (ValidatePatch.get_bug_id_from_patch): Get bug id from a patch id.
+        (ValidatePatch._is_patch_obsolete): Check if the patch is obsolete.
+        (ValidatePatch._is_patch_review_denied): Check if the patch is marked r-.
+        (ValidatePatch._is_bug_closed): Check if the bug is already closed.
+        (ValidatePatch.skip_build): Skip the build.
+        (ValidatePatch.start):
+
 2019-01-04  Alex Christensen  <achristen...@webkit.org>
 
         Progress towards fixing Mac CMake build
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to