<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[283363] trunk/Tools</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/283363">283363</a></dd>
<dt>Author</dt> <dd>gsnedders@apple.com</dd>
<dt>Date</dt> <dd>2021-10-01 06:12:44 -0700 (Fri, 01 Oct 2021)</dd>
</dl>
<h3>Log Message</h3>
<pre>Remove most deprecated webkit-patch commands
https://bugs.webkit.org/show_bug.cgi?id=231032
Reviewed by Jonathan Bedard.
This removes all currently deprecated commands except for
rebaseline-server (to be decided about) and land-cowhand (see
https://bugs.webkit.org/show_bug.cgi?id=227980).
This undoubtedly leaves dead code elsewhere in webkitpy, but tidying that is a task for the
future (due to dynamic typing, determining what is or is not dead is non-trivial).
* Scripts/webkitpy/tool/bot/retrylogic_unittest.py:
(MockJSCEarlyWarningSystem):
Rewrite to directly be a EarlyWarningSystemTaskDelegate subclass.
(MockJSCEarlyWarningSystem.__init__):
(MockJSCEarlyWarningSystem.group):
* Scripts/webkitpy/tool/commands/__init__.py:
* Scripts/webkitpy/tool/commands/adduserstogroups.py: Removed.
* Scripts/webkitpy/tool/commands/analyzechangelog.py: Removed.
* Scripts/webkitpy/tool/commands/analyzechangelog_unittest.py: Removed.
* Scripts/webkitpy/tool/commands/applywatchlistlocal.py:
* Scripts/webkitpy/tool/commands/bugfortest.py: Removed.
* Scripts/webkitpy/tool/commands/bugsearch.py: Removed.
* Scripts/webkitpy/tool/commands/download.py:
(Update): Deleted.
(Build): Deleted.
(Build._prepare_state): Deleted.
(CheckPatchRelevance): Deleted.
(LandCowboy): Deleted.
(LandCowboy._prepare_state): Deleted.
(BuildAttachment): Deleted.
(ApplyWatchList): Deleted.
(LandFromURL): Deleted.
(PrepareRollout): Deleted.
(PrepareRollout._prepare_state): Deleted.
(CreateRollout): Deleted.
(CreateRollout._prepare_state): Deleted.
(Rollout): Deleted.
(Rollout._prepare_state): Deleted.
* Scripts/webkitpy/tool/commands/download_unittest.py:
(DownloadCommandsTest.test_build): Deleted.
(DownloadCommandsTest.test_apply_watch_list): Deleted.
(test_land): Deleted.
(test_build_attachment): Deleted.
(test_land_from_url): Deleted.
(test_prepare_revert): Deleted.
* Scripts/webkitpy/tool/commands/earlywarningsystem.py: Removed.
* Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py: Removed.
* Scripts/webkitpy/tool/commands/findusers.py: Removed.
* Scripts/webkitpy/tool/commands/gardenomatic.py: Removed.
* Scripts/webkitpy/tool/commands/openbugs.py: Removed.
* Scripts/webkitpy/tool/commands/openbugs_unittest.py: Removed.
* Scripts/webkitpy/tool/commands/queries.py:
(BugsToCommit): Deleted.
(BugsToCommit.execute): Deleted.
(PatchesInCommitQueue): Deleted.
(PatchesInCommitQueue.execute): Deleted.
(PatchesToCommitQueue): Deleted.
(PatchesToCommitQueue.__init__): Deleted.
(PatchesToCommitQueue._needs_commit_queue): Deleted.
(PatchesToCommitQueue.execute): Deleted.
(PatchesToReview): Deleted.
(PatchesToReview.__init__): Deleted.
(PatchesToReview._print_report): Deleted.
(PatchesToReview._generate_report): Deleted.
(PatchesToReview.execute): Deleted.
(WhatBroke): Deleted.
(WhatBroke._print_builder_line): Deleted.
(WhatBroke._print_blame_information_for_builder): Deleted.
(WhatBroke.execute): Deleted.
(ResultsFor): Deleted.
(ResultsFor._print_layout_test_results): Deleted.
(ResultsFor.execute): Deleted.
(FailureReason): Deleted.
(FailureReason._blame_line_for_revision): Deleted.
(FailureReason._print_blame_information_for_transition): Deleted.
(FailureReason._explain_failures_for_builder): Deleted.
(FailureReason._builder_to_explain): Deleted.
(FailureReason._done_explaining): Deleted.
(FailureReason.execute): Deleted.
(FindFlakyTests): Deleted.
(FindFlakyTests._find_failures): Deleted.
(FindFlakyTests._increment_statistics): Deleted.
(FindFlakyTests._print_statistics): Deleted.
(FindFlakyTests._walk_backwards_from): Deleted.
(FindFlakyTests._builder_to_analyze): Deleted.
(FindFlakyTests.execute): Deleted.
(TreeStatus): Deleted.
(execute): Deleted.
(CrashLog): Deleted.
(PrintExpectations): Deleted.
(PrintExpectations.__init__): Deleted.
(PrintExpectations.execute): Deleted.
(PrintExpectations._filter_tests): Deleted.
(PrintExpectations._format_lines): Deleted.
(PrintExpectations._model): Deleted.
(PrintBaselines): Deleted.
(PrintBaselines.__init__): Deleted.
(PrintBaselines.execute): Deleted.
(PrintBaselines._print_baselines): Deleted.
(PrintBaselines._platform_for_path): Deleted.
(FindResolvedBugs): Deleted.
(FindResolvedBugs.execute): Deleted.
* Scripts/webkitpy/tool/commands/queries_unittest.py: Removed.
* Scripts/webkitpy/tool/commands/rebaseline.py: Removed.
* Scripts/webkitpy/tool/commands/rebaseline_unittest.py: Removed.
* Scripts/webkitpy/tool/commands/upload.py:
(CommitMessageForCurrentDiff): Deleted.
(CommitMessageForCurrentDiff.__init__): Deleted.
(CommitMessageForCurrentDiff.execute): Deleted.
(CleanPendingCommit): Deleted.
(CleanPendingCommit._flags_to_clear_on_patch): Deleted.
(CleanPendingCommit.execute): Deleted.
(CleanReviewQueue): Deleted.
(CleanReviewQueue.execute): Deleted.
(AssignToCommitter): Deleted.
(AssignToCommitter._patches_have_commiters): Deleted.
(AssignToCommitter._assign_bug_to_last_patch_attacher): Deleted.
(AssignToCommitter.execute): Deleted.
(ObsoleteAttachments): Deleted.
(ObsoleteAttachments._prepare_state): Deleted.
(AttachToBug): Deleted.
(AttachToBug._prepare_state): Deleted.
(HasLanded): Deleted.
(PostCommits): Deleted.
(PostCommits.__init__): Deleted.
(PostCommits._comment_text_for_commit): Deleted.
(PostCommits.execute): Deleted.
(CreateBug): Deleted.
(CreateBug.__init__): Deleted.
(CreateBug.create_bug_from_commit): Deleted.
(CreateBug.create_bug_from_patch): Deleted.
(CreateBug.prompt_for_bug_title_and_comment): Deleted.
(CreateBug.execute): Deleted.
(WPTChangeExport): Deleted.
(WPTChangeExport._prepare_state): Deleted.
* Scripts/webkitpy/tool/commands/upload_unittest.py:
(UploadCommandsTest.test_commit_message_for_current_diff): Deleted.
(UploadCommandsTest.test_clean_pending_commit): Deleted.
(UploadCommandsTest.test_assign_to_committer): Deleted.
(test_obsolete_attachments): Deleted.
(test_post): Deleted.
(test_attach_to_bug): Deleted.
(test_attach_to_bug_no_description_or_comment): Deleted.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolbotretrylogic_unittestpy">trunk/Tools/Scripts/webkitpy/tool/bot/retrylogic_unittest.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolcommands__init__py">trunk/Tools/Scripts/webkitpy/tool/commands/__init__.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolcommandsapplywatchlistlocalpy">trunk/Tools/Scripts/webkitpy/tool/commands/applywatchlistlocal.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolcommandsdownloadpy">trunk/Tools/Scripts/webkitpy/tool/commands/download.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolcommandsdownload_unittestpy">trunk/Tools/Scripts/webkitpy/tool/commands/download_unittest.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolcommandsqueriespy">trunk/Tools/Scripts/webkitpy/tool/commands/queries.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolcommandsuploadpy">trunk/Tools/Scripts/webkitpy/tool/commands/upload.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolcommandsupload_unittestpy">trunk/Tools/Scripts/webkitpy/tool/commands/upload_unittest.py</a></li>
</ul>
<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkToolsScriptswebkitpytoolcommandsadduserstogroupspy">trunk/Tools/Scripts/webkitpy/tool/commands/adduserstogroups.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolcommandsanalyzechangelogpy">trunk/Tools/Scripts/webkitpy/tool/commands/analyzechangelog.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolcommandsanalyzechangelog_unittestpy">trunk/Tools/Scripts/webkitpy/tool/commands/analyzechangelog_unittest.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolcommandsbugfortestpy">trunk/Tools/Scripts/webkitpy/tool/commands/bugfortest.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolcommandsbugsearchpy">trunk/Tools/Scripts/webkitpy/tool/commands/bugsearch.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolcommandsearlywarningsystempy">trunk/Tools/Scripts/webkitpy/tool/commands/earlywarningsystem.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolcommandsearlywarningsystem_unittestpy">trunk/Tools/Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolcommandsfinduserspy">trunk/Tools/Scripts/webkitpy/tool/commands/findusers.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolcommandsgardenomaticpy">trunk/Tools/Scripts/webkitpy/tool/commands/gardenomatic.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolcommandsopenbugspy">trunk/Tools/Scripts/webkitpy/tool/commands/openbugs.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolcommandsopenbugs_unittestpy">trunk/Tools/Scripts/webkitpy/tool/commands/openbugs_unittest.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolcommandsqueries_unittestpy">trunk/Tools/Scripts/webkitpy/tool/commands/queries_unittest.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolcommandsrebaselinepy">trunk/Tools/Scripts/webkitpy/tool/commands/rebaseline.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolcommandsrebaseline_unittestpy">trunk/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/ChangeLog 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -1,3 +1,151 @@
</span><ins>+2021-10-01 Sam Sneddon <gsnedders@apple.com>
+
+ Remove most deprecated webkit-patch commands
+ https://bugs.webkit.org/show_bug.cgi?id=231032
+
+ Reviewed by Jonathan Bedard.
+
+ This removes all currently deprecated commands except for
+ rebaseline-server (to be decided about) and land-cowhand (see
+ https://bugs.webkit.org/show_bug.cgi?id=227980).
+
+ This undoubtedly leaves dead code elsewhere in webkitpy, but tidying that is a task for the
+ future (due to dynamic typing, determining what is or is not dead is non-trivial).
+
+ * Scripts/webkitpy/tool/bot/retrylogic_unittest.py:
+ (MockJSCEarlyWarningSystem):
+ Rewrite to directly be a EarlyWarningSystemTaskDelegate subclass.
+ (MockJSCEarlyWarningSystem.__init__):
+ (MockJSCEarlyWarningSystem.group):
+ * Scripts/webkitpy/tool/commands/__init__.py:
+ * Scripts/webkitpy/tool/commands/adduserstogroups.py: Removed.
+ * Scripts/webkitpy/tool/commands/analyzechangelog.py: Removed.
+ * Scripts/webkitpy/tool/commands/analyzechangelog_unittest.py: Removed.
+ * Scripts/webkitpy/tool/commands/applywatchlistlocal.py:
+ * Scripts/webkitpy/tool/commands/bugfortest.py: Removed.
+ * Scripts/webkitpy/tool/commands/bugsearch.py: Removed.
+ * Scripts/webkitpy/tool/commands/download.py:
+ (Update): Deleted.
+ (Build): Deleted.
+ (Build._prepare_state): Deleted.
+ (CheckPatchRelevance): Deleted.
+ (LandCowboy): Deleted.
+ (LandCowboy._prepare_state): Deleted.
+ (BuildAttachment): Deleted.
+ (ApplyWatchList): Deleted.
+ (LandFromURL): Deleted.
+ (PrepareRollout): Deleted.
+ (PrepareRollout._prepare_state): Deleted.
+ (CreateRollout): Deleted.
+ (CreateRollout._prepare_state): Deleted.
+ (Rollout): Deleted.
+ (Rollout._prepare_state): Deleted.
+ * Scripts/webkitpy/tool/commands/download_unittest.py:
+ (DownloadCommandsTest.test_build): Deleted.
+ (DownloadCommandsTest.test_apply_watch_list): Deleted.
+ (test_land): Deleted.
+ (test_build_attachment): Deleted.
+ (test_land_from_url): Deleted.
+ (test_prepare_revert): Deleted.
+ * Scripts/webkitpy/tool/commands/earlywarningsystem.py: Removed.
+ * Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py: Removed.
+ * Scripts/webkitpy/tool/commands/findusers.py: Removed.
+ * Scripts/webkitpy/tool/commands/gardenomatic.py: Removed.
+ * Scripts/webkitpy/tool/commands/openbugs.py: Removed.
+ * Scripts/webkitpy/tool/commands/openbugs_unittest.py: Removed.
+ * Scripts/webkitpy/tool/commands/queries.py:
+ (BugsToCommit): Deleted.
+ (BugsToCommit.execute): Deleted.
+ (PatchesInCommitQueue): Deleted.
+ (PatchesInCommitQueue.execute): Deleted.
+ (PatchesToCommitQueue): Deleted.
+ (PatchesToCommitQueue.__init__): Deleted.
+ (PatchesToCommitQueue._needs_commit_queue): Deleted.
+ (PatchesToCommitQueue.execute): Deleted.
+ (PatchesToReview): Deleted.
+ (PatchesToReview.__init__): Deleted.
+ (PatchesToReview._print_report): Deleted.
+ (PatchesToReview._generate_report): Deleted.
+ (PatchesToReview.execute): Deleted.
+ (WhatBroke): Deleted.
+ (WhatBroke._print_builder_line): Deleted.
+ (WhatBroke._print_blame_information_for_builder): Deleted.
+ (WhatBroke.execute): Deleted.
+ (ResultsFor): Deleted.
+ (ResultsFor._print_layout_test_results): Deleted.
+ (ResultsFor.execute): Deleted.
+ (FailureReason): Deleted.
+ (FailureReason._blame_line_for_revision): Deleted.
+ (FailureReason._print_blame_information_for_transition): Deleted.
+ (FailureReason._explain_failures_for_builder): Deleted.
+ (FailureReason._builder_to_explain): Deleted.
+ (FailureReason._done_explaining): Deleted.
+ (FailureReason.execute): Deleted.
+ (FindFlakyTests): Deleted.
+ (FindFlakyTests._find_failures): Deleted.
+ (FindFlakyTests._increment_statistics): Deleted.
+ (FindFlakyTests._print_statistics): Deleted.
+ (FindFlakyTests._walk_backwards_from): Deleted.
+ (FindFlakyTests._builder_to_analyze): Deleted.
+ (FindFlakyTests.execute): Deleted.
+ (TreeStatus): Deleted.
+ (execute): Deleted.
+ (CrashLog): Deleted.
+ (PrintExpectations): Deleted.
+ (PrintExpectations.__init__): Deleted.
+ (PrintExpectations.execute): Deleted.
+ (PrintExpectations._filter_tests): Deleted.
+ (PrintExpectations._format_lines): Deleted.
+ (PrintExpectations._model): Deleted.
+ (PrintBaselines): Deleted.
+ (PrintBaselines.__init__): Deleted.
+ (PrintBaselines.execute): Deleted.
+ (PrintBaselines._print_baselines): Deleted.
+ (PrintBaselines._platform_for_path): Deleted.
+ (FindResolvedBugs): Deleted.
+ (FindResolvedBugs.execute): Deleted.
+ * Scripts/webkitpy/tool/commands/queries_unittest.py: Removed.
+ * Scripts/webkitpy/tool/commands/rebaseline.py: Removed.
+ * Scripts/webkitpy/tool/commands/rebaseline_unittest.py: Removed.
+ * Scripts/webkitpy/tool/commands/upload.py:
+ (CommitMessageForCurrentDiff): Deleted.
+ (CommitMessageForCurrentDiff.__init__): Deleted.
+ (CommitMessageForCurrentDiff.execute): Deleted.
+ (CleanPendingCommit): Deleted.
+ (CleanPendingCommit._flags_to_clear_on_patch): Deleted.
+ (CleanPendingCommit.execute): Deleted.
+ (CleanReviewQueue): Deleted.
+ (CleanReviewQueue.execute): Deleted.
+ (AssignToCommitter): Deleted.
+ (AssignToCommitter._patches_have_commiters): Deleted.
+ (AssignToCommitter._assign_bug_to_last_patch_attacher): Deleted.
+ (AssignToCommitter.execute): Deleted.
+ (ObsoleteAttachments): Deleted.
+ (ObsoleteAttachments._prepare_state): Deleted.
+ (AttachToBug): Deleted.
+ (AttachToBug._prepare_state): Deleted.
+ (HasLanded): Deleted.
+ (PostCommits): Deleted.
+ (PostCommits.__init__): Deleted.
+ (PostCommits._comment_text_for_commit): Deleted.
+ (PostCommits.execute): Deleted.
+ (CreateBug): Deleted.
+ (CreateBug.__init__): Deleted.
+ (CreateBug.create_bug_from_commit): Deleted.
+ (CreateBug.create_bug_from_patch): Deleted.
+ (CreateBug.prompt_for_bug_title_and_comment): Deleted.
+ (CreateBug.execute): Deleted.
+ (WPTChangeExport): Deleted.
+ (WPTChangeExport._prepare_state): Deleted.
+ * Scripts/webkitpy/tool/commands/upload_unittest.py:
+ (UploadCommandsTest.test_commit_message_for_current_diff): Deleted.
+ (UploadCommandsTest.test_clean_pending_commit): Deleted.
+ (UploadCommandsTest.test_assign_to_committer): Deleted.
+ (test_obsolete_attachments): Deleted.
+ (test_post): Deleted.
+ (test_attach_to_bug): Deleted.
+ (test_attach_to_bug_no_description_or_comment): Deleted.
+
</ins><span class="cx"> 2021-10-01 Carlos Garcia Campos <cgarcia@igalia.com>
</span><span class="cx">
</span><span class="cx"> [GTK][a11y] Add initial implementation of accessible interface when building with ATSPI
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolbotretrylogic_unittestpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/tool/bot/retrylogic_unittest.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/bot/retrylogic_unittest.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/bot/retrylogic_unittest.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -24,7 +24,7 @@
</span><span class="cx"> import unittest
</span><span class="cx">
</span><span class="cx"> from webkitpy.tool.bot.patchanalysistask import *
</span><del>-from webkitpy.tool.commands.earlywarningsystem import AbstractEarlyWarningSystem
</del><ins>+from webkitpy.tool.bot.earlywarningsystemtask import EarlyWarningSystemTaskDelegate
</ins><span class="cx"> from webkitpy.tool.mocktool import MockTool
</span><span class="cx">
</span><span class="cx"> _log = logging.getLogger(__name__)
</span><span class="lines">@@ -62,12 +62,15 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx"> # This is the delegate to be used with MockPatchAnalysisTask, above.
</span><del>-class MockJSCEarlyWarningSystem(AbstractEarlyWarningSystem):
</del><ins>+class MockJSCEarlyWarningSystem(EarlyWarningSystemTaskDelegate):
</ins><span class="cx"> def __init__(self, first_test_results, second_test_results, clean_test_results):
</span><del>- AbstractEarlyWarningSystem.__init__(self)
</del><ins>+ super(MockJSCEarlyWarningSystem, self).__init__()
</ins><span class="cx"> self._group = 'jsc'
</span><span class="cx"> self._results_in_order = [clean_test_results, second_test_results, first_test_results]
</span><span class="cx">
</span><ins>+ def group(self):
+ return self._group
+
</ins><span class="cx"> def test_results(self):
</span><span class="cx"> return self._results_in_order.pop()
</span><span class="cx">
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommands__init__py"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/tool/commands/__init__.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/__init__.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/__init__.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -1,22 +1,11 @@
</span><span class="cx"> # Required for Python to search this directory for module files
</span><span class="cx">
</span><del>-from webkitpy.tool.commands.adduserstogroups import AddUsersToGroups
-from webkitpy.tool.commands.analyzechangelog import AnalyzeChangeLog
</del><span class="cx"> from webkitpy.tool.commands.applywatchlistlocal import ApplyWatchListLocal
</span><del>-from webkitpy.tool.commands.bugfortest import BugForTest
-from webkitpy.tool.commands.bugsearch import BugSearch
</del><span class="cx"> from webkitpy.tool.commands.download import *
</span><del>-from webkitpy.tool.commands.earlywarningsystem import AbstractEarlyWarningSystem
-from webkitpy.tool.commands.findusers import FindUsers
-from webkitpy.tool.commands.gardenomatic import GardenOMatic
-from webkitpy.tool.commands.openbugs import OpenBugs
</del><span class="cx"> from webkitpy.tool.commands.prettydiff import PrettyDiff
</span><span class="cx"> from webkitpy.tool.commands.queries import *
</span><span class="cx"> from webkitpy.tool.commands.queues import *
</span><del>-from webkitpy.tool.commands.rebaseline import Rebaseline
</del><span class="cx"> from webkitpy.tool.commands.rebaselineserver import RebaselineServer
</span><span class="cx"> from webkitpy.tool.commands.setupgitclone import SetupGitClone
</span><span class="cx"> from webkitpy.tool.commands.upload import *
</span><span class="cx"> from webkitpy.tool.commands.suggestnominations import *
</span><del>-
-classes = AbstractEarlyWarningSystem.load_ews_classes()
</del></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommandsadduserstogroupspy"></a>
<div class="delfile"><h4>Deleted: trunk/Tools/Scripts/webkitpy/tool/commands/adduserstogroups.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/adduserstogroups.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/adduserstogroups.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -1,67 +0,0 @@
</span><del>-# Copyright (c) 2011 Google 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:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * 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.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-# OWNER OR 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.
-
-from webkitpy.tool.commands.deprecatedcommand import DeprecatedCommand
-from webkitpy.tool.multicommandtool import Command
-
-
-@DeprecatedCommand
-class AddUsersToGroups(Command):
- name = "add-users-to-groups"
- help_text = "Add users matching subtring to specified groups"
-
- # This probably belongs in bugzilla.py
- known_groups = ['canconfirm', 'editbugs']
-
- def execute(self, options, args, tool):
- search_string = args[0]
- # FIXME: We could allow users to specify groups on the command line.
- list_title = 'Add users matching "%s" which groups?' % search_string
- # FIXME: Need a way to specify that "none" is not allowed.
- # FIXME: We could lookup what groups the current user is able to grant from bugzilla.
- groups = tool.user.prompt_with_list(list_title, self.known_groups, can_choose_multiple=True)
- if not groups:
- print("No groups specified.")
- return
-
- login_userid_pairs = tool.bugs.queries.fetch_login_userid_pairs_matching_substring(search_string)
- if not login_userid_pairs:
- print("No users found matching '%s'" % search_string)
- return
-
- print("Found %s users matching %s:" % (len(login_userid_pairs), search_string))
- for (login, user_id) in login_userid_pairs:
- print("%s (%s)" % (login, user_id))
-
- confirm_message = "Are you sure you want add %s users to groups %s? (This action cannot be undone using webkit-patch.)" % (len(login_userid_pairs), groups)
- if not tool.user.confirm(confirm_message):
- return
-
- for (login, user_id) in login_userid_pairs:
- print("Adding %s to %s" % (login, groups))
- tool.bugs.add_user_to_groups(user_id, groups)
</del></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommandsanalyzechangelogpy"></a>
<div class="delfile"><h4>Deleted: trunk/Tools/Scripts/webkitpy/tool/commands/analyzechangelog.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/analyzechangelog.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/analyzechangelog.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -1,208 +0,0 @@
</span><del>-# Copyright (c) 2011 Google 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:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * 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.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-# OWNER OR 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.
-
-from __future__ import print_function
-import json
-import re
-import time
-
-from webkitpy.common.checkout.changelog import ChangeLog
-from webkitpy.common.checkout.scm.detection import SCMDetector
-from webkitpy.common.config.contributionareas import ContributionAreas
-from webkitpy.common.system.filesystem import FileSystem
-from webkitpy.tool import steps
-from webkitpy.tool.commands.deprecatedcommand import DeprecatedCommand
-from webkitpy.tool.multicommandtool import Command
-
-
-@DeprecatedCommand
-class AnalyzeChangeLog(Command):
- name = "analyze-changelog"
- help_text = "Experimental command for analyzing change logs."
- long_help = "This command parses changelogs in a specified directory and summarizes the result as JSON files."
-
- def __init__(self):
- options = [
- steps.Options.changelog_count,
- ]
- Command.__init__(self, options=options)
-
- @staticmethod
- def _enumerate_changelogs(filesystem, dirname, changelog_count):
- changelogs = [filesystem.join(dirname, filename) for filename in filesystem.listdir(dirname) if re.match(r'^ChangeLog(-(\d{4}-\d{2}-\d{2}))?$', filename)]
- # Make sure ChangeLog shows up before ChangeLog-2011-01-01
- changelogs = sorted(changelogs, key=lambda filename: filename + 'X', reverse=True)
- return changelogs[:changelog_count]
-
- @staticmethod
- def _generate_jsons(filesystem, jsons, output_dir):
- for filename in jsons:
- print(' Generating', filename)
- filesystem.write_text_file(filesystem.join(output_dir, filename), json.dumps(jsons[filename], indent=2))
-
- def execute(self, options, args, tool):
- filesystem = self._tool.filesystem
- if len(args) < 1 or not filesystem.exists(args[0]):
- print("Need the directory name to look for changelog as the first argument")
- return
- changelog_dir = filesystem.abspath(args[0])
-
- if len(args) < 2 or not filesystem.exists(args[1]):
- print("Need the output directory name as the second argument")
- return
- output_dir = args[1]
-
- startTime = time.time()
-
- print('Enumerating ChangeLog files...')
- changelogs = AnalyzeChangeLog._enumerate_changelogs(filesystem, changelog_dir, options.changelog_count)
-
- analyzer = ChangeLogAnalyzer(tool, changelogs)
- analyzer.analyze()
-
- print('Generating json files...')
- json_files = {
- 'summary.json': analyzer.summary(),
- 'contributors.json': analyzer.contributors_statistics(),
- 'areas.json': analyzer.areas_statistics(),
- }
- AnalyzeChangeLog._generate_jsons(filesystem, json_files, output_dir)
- commands_dir = filesystem.dirname(filesystem.path_to_module(self.__module__))
- print(commands_dir)
- filesystem.copyfile(filesystem.join(commands_dir, 'data/summary.html'), filesystem.join(output_dir, 'summary.html'))
-
- tick = time.time() - startTime
- print('Finished in %02dm:%02ds' % (int(tick / 60), int(tick % 60)))
-
-
-class ChangeLogAnalyzer(object):
- def __init__(self, host, changelog_paths):
- self._changelog_paths = changelog_paths
- self._filesystem = host.filesystem
- self._contribution_areas = ContributionAreas(host.filesystem)
- self._scm = host.scm()
- self._parsed_revisions = {}
-
- self._contributors_statistics = {}
- self._areas_statistics = dict([(area, {'reviewed': 0, 'unreviewed': 0, 'contributors': {}}) for area in self._contribution_areas.names()])
- self._summary = {'reviewed': 0, 'unreviewed': 0}
-
- self._longest_filename = max([len(path) - len(self._scm.checkout_root) for path in changelog_paths])
- self._filename = ''
- self._length_of_previous_output = 0
-
- def contributors_statistics(self):
- return self._contributors_statistics
-
- def areas_statistics(self):
- return self._areas_statistics
-
- def summary(self):
- return self._summary
-
- def _print_status(self, status):
- if self._length_of_previous_output:
- print("\r" + " " * self._length_of_previous_output, end=' ')
- new_output = ('%' + str(self._longest_filename) + 's: %s') % (self._filename, status)
- print("\r" + new_output, end=' ')
- self._length_of_previous_output = len(new_output)
-
- def _set_filename(self, filename):
- if self._filename:
- print()
- self._filename = filename
-
- def analyze(self):
- for path in self._changelog_paths:
- self._set_filename(self._filesystem.relpath(path, self._scm.checkout_root))
- with self._filesystem.open_text_file_for_reading(path) as changelog:
- self._print_status('Parsing entries...')
- number_of_parsed_entries = self._analyze_entries(ChangeLog.parse_entries_from_file(changelog), path)
- self._print_status('Done (%d entries)' % number_of_parsed_entries)
- print()
- self._summary['contributors'] = len(self._contributors_statistics)
- self._summary['contributors_with_reviews'] = sum([1 for contributor in self._contributors_statistics.values() if contributor['reviews']['total']])
- self._summary['contributors_without_reviews'] = self._summary['contributors'] - self._summary['contributors_with_reviews']
-
- def _collect_statistics_for_contributor_area(self, area, contributor, contribution_type, reviewed):
- area_contributors = self._areas_statistics[area]['contributors']
- if contributor not in area_contributors:
- area_contributors[contributor] = {'reviews': 0, 'reviewed': 0, 'unreviewed': 0}
- if contribution_type == 'patches':
- contribution_type = 'reviewed' if reviewed else 'unreviewed'
- area_contributors[contributor][contribution_type] += 1
-
- def _collect_statistics_for_contributor(self, contributor, contribution_type, areas, touched_files, reviewed):
- if contributor not in self._contributors_statistics:
- self._contributors_statistics[contributor] = {
- 'reviews': {'total': 0, 'areas': {}, 'files': {}},
- 'patches': {'reviewed': 0, 'unreviewed': 0, 'areas': {}, 'files': {}}}
- statistics = self._contributors_statistics[contributor][contribution_type]
-
- if contribution_type == 'reviews':
- statistics['total'] += 1
- elif reviewed:
- statistics['reviewed'] += 1
- else:
- statistics['unreviewed'] += 1
-
- for area in areas:
- self._increment_dictionary_value(statistics['areas'], area)
- self._collect_statistics_for_contributor_area(area, contributor, contribution_type, reviewed)
- for touchedfile in touched_files:
- self._increment_dictionary_value(statistics['files'], touchedfile)
-
- def _increment_dictionary_value(self, dictionary, key):
- dictionary[key] = dictionary.get(key, 0) + 1
-
- def _analyze_entries(self, entries, changelog_path):
- dirname = self._filesystem.dirname(changelog_path)
- i = 0
- for i, entry in enumerate(entries):
- self._print_status('(%s) entries' % i)
- assert(entry.authors())
-
- touchedfiles_for_entry = [self._filesystem.relpath(self._filesystem.join(dirname, name), self._scm.checkout_root) for name in entry.touched_files()]
- areas_for_entry = self._contribution_areas.areas_for_touched_files(touchedfiles_for_entry)
- authors_for_entry = entry.authors()
- reviewers_for_entry = entry.reviewers()
-
- for reviewer in reviewers_for_entry:
- self._collect_statistics_for_contributor(reviewer.full_name, 'reviews', areas_for_entry, touchedfiles_for_entry, reviewed=True)
-
- for author in authors_for_entry:
- self._collect_statistics_for_contributor(author['name'], 'patches', areas_for_entry, touchedfiles_for_entry,
- reviewed=bool(reviewers_for_entry))
-
- for area in areas_for_entry:
- self._areas_statistics[area]['reviewed' if reviewers_for_entry else 'unreviewed'] += 1
-
- self._summary['reviewed' if reviewers_for_entry else 'unreviewed'] += 1
-
- self._print_status('(%s) entries' % i)
- return i
</del></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommandsanalyzechangelog_unittestpy"></a>
<div class="delfile"><h4>Deleted: trunk/Tools/Scripts/webkitpy/tool/commands/analyzechangelog_unittest.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/analyzechangelog_unittest.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/analyzechangelog_unittest.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -1,180 +0,0 @@
</span><del>-# Copyright (c) 2011 Google Inc. All rights reserved.
-# Copyright (C) 2020 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:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * 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.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-# OWNER OR 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 json
-import sys
-from webkitpy.common.config.contributionareas import ContributionAreas
-from webkitpy.common.host_mock import MockHost
-from webkitpy.common.system.filesystem_mock import MockFileSystem
-from webkitpy.tool.commands.analyzechangelog import AnalyzeChangeLog
-from webkitpy.tool.commands.analyzechangelog import ChangeLogAnalyzer
-from webkitpy.tool.commands.commandtest import CommandsTest
-from webkitpy.tool.multicommandtool import Command
-
-from webkitcorepy import OutputCapture
-
-
-class AnalyzeChangeLogTest(CommandsTest):
- def test_enumerate_enumerate_changelogs(self):
- filesystem = MockFileSystem({
- 'foo/ChangeLog': '',
- 'foo/ChangeLog-2010-06-23': '',
- 'foo/ChangeLog-2010-12-31': '',
- 'foo/ChangeLog-x': '',
- 'foo/ChangeLog-2011-01-01': '',
- })
- changelogs = AnalyzeChangeLog._enumerate_changelogs(filesystem, 'foo/', None)
- self.assertEqual(changelogs, ['foo/ChangeLog', 'foo/ChangeLog-2011-01-01', 'foo/ChangeLog-2010-12-31', 'foo/ChangeLog-2010-06-23'])
-
- changelogs = AnalyzeChangeLog._enumerate_changelogs(filesystem, 'foo/', 2)
- self.assertEqual(changelogs, ['foo/ChangeLog', 'foo/ChangeLog-2011-01-01'])
-
- def test_generate_jsons(self):
- filesystem = MockFileSystem()
- test_json = {'array.json': [1, 2, 3, {'key': 'value'}], 'dictionary.json': {'somekey': 'somevalue', 'array': [4, 5]}}
-
- with OutputCapture():
- AnalyzeChangeLog._generate_jsons(filesystem, test_json, 'bar')
- self.assertEqual(set(filesystem.files.keys()), {'bar/array.json', 'bar/dictionary.json'})
-
- self.assertEqual(json.loads(filesystem.files['bar/array.json']), test_json['array.json'])
- self.assertEqual(json.loads(filesystem.files['bar/dictionary.json']), test_json['dictionary.json'])
-
-
-class ChangeLogAnalyzerTest(CommandsTest):
- def test_analyze_one_changelog(self):
- host = MockHost()
- host.filesystem.files['mock-checkout/foo/ChangeLog'] = u"""2011-11-17 Mark Rowe <mrowe@apple.com>
-
- <http://webkit.org/b/72646> Disable deprecation warnings around code where we cannot easily
- switch away from the deprecated APIs.
-
- Reviewed by Sam Weinig.
-
- * platform/mac/WebCoreNSStringExtras.mm:
- * platform/network/cf/SocketStreamHandleCFNet.cpp:
- (WebCore::SocketStreamHandle::reportErrorToClient):
-
-2011-11-19 Kevin Ollivier <kevino@theolliviers.com>
-
- [wx] C++ bindings build fix for move of array classes to WTF.
-
- * bindings/scripts/CodeGeneratorCPP.pm:
- (GetCPPTypeGetter):
- (GetNamespaceForClass):
- (GenerateHeader):
- (GenerateImplementation):
-
-2011-10-27 Philippe Normand <pnormand@igalia.com> and Zan Dobersek <zandobersek@gmail.com>
-
- [GStreamer] WebAudio AudioFileReader implementation
- https://bugs.webkit.org/show_bug.cgi?id=69834
-
- Reviewed by Martin Robinson.
-
- Basic FileReader implementation, supporting one or 2 audio
- channels. An empty AudioDestination is also provided, its complete
- implementation is handled in bug 69835.
-
- * GNUmakefile.am:
- * GNUmakefile.list.am:
- * platform/audio/gstreamer/AudioDestinationGStreamer.cpp: Added.
- (WebCore::AudioDestination::create):
- (WebCore::AudioDestination::hardwareSampleRate):
- (WebCore::AudioDestinationGStreamer::AudioDestinationGStreamer):
- (WebCore::AudioDestinationGStreamer::~AudioDestinationGStreamer):
- (WebCore::AudioDestinationGStreamer::start):
- (WebCore::AudioDestinationGStreamer::stop):
- * platform/audio/gstreamer/AudioDestinationGStreamer.h: Added.
- (WebCore::AudioDestinationGStreamer::isPlaying):
- (WebCore::AudioDestinationGStreamer::sampleRate):
- (WebCore::AudioDestinationGStreamer::sourceProvider):
- * platform/audio/gstreamer/AudioFileReaderGStreamer.cpp: Added.
- (WebCore::getGStreamerAudioCaps):
- (WebCore::getFloatFromByteReader):
- (WebCore::copyGstreamerBuffersToAudioChannel):
- (WebCore::onAppsinkNewBufferCallback):
- (WebCore::messageCallback):
- (WebCore::onGStreamerDeinterleavePadAddedCallback):
- (WebCore::onGStreamerDeinterleaveReadyCallback):
- (WebCore::onGStreamerDecodebinPadAddedCallback):
- (WebCore::AudioFileReader::AudioFileReader):
- (WebCore::AudioFileReader::~AudioFileReader):
- (WebCore::AudioFileReader::handleBuffer):
- (WebCore::AudioFileReader::handleMessage):
- (WebCore::AudioFileReader::handleNewDeinterleavePad):
- (WebCore::AudioFileReader::deinterleavePadsConfigured):
- (WebCore::AudioFileReader::plugDeinterleave):
- (WebCore::AudioFileReader::createBus):
- (WebCore::createBusFromAudioFile):
- (WebCore::createBusFromInMemoryAudioFile):
- * platform/audio/gtk/AudioBusGtk.cpp: Added.
- (WebCore::AudioBus::loadPlatformResource):
-"""
-
- with OutputCapture():
- analyzer = ChangeLogAnalyzer(host, ['mock-checkout/foo/ChangeLog'])
- analyzer.analyze()
-
- self.assertEqual(analyzer.summary(),
- {'reviewed': 2, 'unreviewed': 1, 'contributors': 6, 'contributors_with_reviews': 2, 'contributors_without_reviews': 4})
-
- self.assertEqual(
- set(analyzer.contributors_statistics().keys()),
- {'Sam Weinig', u'Mark Rowe', u'Kevin Ollivier', 'Martin Robinson', u'Philippe Normand', u'Zan Dobersek'},
- )
-
- self.assertEqual(analyzer.contributors_statistics()['Sam Weinig'],
- {'reviews': {'files': {u'foo/platform/mac/WebCoreNSStringExtras.mm': 1, u'foo/platform/network/cf/SocketStreamHandleCFNet.cpp': 1},
- 'total': 1, 'areas': {'Network': 1}}, 'patches': {'files': {}, 'areas': {}, 'unreviewed': 0, 'reviewed': 0}})
- self.assertEqual(analyzer.contributors_statistics()[u'Mark Rowe'],
- {'reviews': {'files': {}, 'total': 0, 'areas': {}}, 'patches': {'files': {u'foo/platform/mac/WebCoreNSStringExtras.mm': 1,
- u'foo/platform/network/cf/SocketStreamHandleCFNet.cpp': 1}, 'areas': {'Network': 1}, 'unreviewed': 0, 'reviewed': 1}})
- self.assertEqual(analyzer.contributors_statistics()[u'Kevin Ollivier'],
- {'reviews': {'files': {}, 'total': 0, 'areas': {}}, 'patches': {'files': {u'foo/bindings/scripts/CodeGeneratorCPP.pm': 1},
- 'areas': {'Bindings': 1}, 'unreviewed': 1, 'reviewed': 0}})
-
- files_for_audio_patch = {u'foo/GNUmakefile.am': 1, u'foo/GNUmakefile.list.am': 1, 'foo/platform/audio/gstreamer/AudioDestinationGStreamer.cpp': 1,
- 'foo/platform/audio/gstreamer/AudioDestinationGStreamer.h': 1, 'foo/platform/audio/gstreamer/AudioFileReaderGStreamer.cpp': 1,
- 'foo/platform/audio/gtk/AudioBusGtk.cpp': 1}
- author_expectation_for_audio_patch = {'reviews': {'files': {}, 'total': 0, 'areas': {}},
- 'patches': {'files': files_for_audio_patch, 'areas': {'The WebKitGTK Port': 1}, 'unreviewed': 0, 'reviewed': 1}}
- self.assertEqual(analyzer.contributors_statistics()[u'Martin Robinson'],
- {'reviews': {'files': files_for_audio_patch, 'total': 1, 'areas': {'The WebKitGTK Port': 1}},
- 'patches': {'files': {}, 'areas': {}, 'unreviewed': 0, 'reviewed': 0}})
- self.assertEqual(analyzer.contributors_statistics()[u'Philippe Normand'], author_expectation_for_audio_patch)
- self.assertEqual(analyzer.contributors_statistics()[u'Zan Dobersek'], author_expectation_for_audio_patch)
-
- areas_statistics = analyzer.areas_statistics()
- areas_with_patches = [area for area in areas_statistics if areas_statistics[area]['reviewed'] or areas_statistics[area]['unreviewed']]
- self.assertEqual(set(areas_with_patches), set(['Bindings', 'Network', 'The WebKitGTK Port']))
- self.assertEqual(areas_statistics['Bindings'], {'unreviewed': 1, 'reviewed': 0, 'contributors':
- {u'Kevin Ollivier': {'reviews': 0, 'unreviewed': 1, 'reviewed': 0}}})
- self.assertEqual(areas_statistics['Network'], {'unreviewed': 0, 'reviewed': 1, 'contributors':
- {'Sam Weinig': {'reviews': 1, 'unreviewed': 0, 'reviewed': 0}, u'Mark Rowe': {'reviews': 0, 'unreviewed': 0, 'reviewed': 1}}})
</del></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommandsapplywatchlistlocalpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/tool/commands/applywatchlistlocal.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/applywatchlistlocal.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/applywatchlistlocal.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -28,7 +28,6 @@
</span><span class="cx">
</span><span class="cx"> from webkitpy.tool import steps
</span><span class="cx"> from webkitpy.tool.commands.abstractsequencedcommand import AbstractSequencedCommand
</span><del>-from webkitpy.tool.commands.deprecatedcommand import DeprecatedCommand
</del><span class="cx">
</span><span class="cx">
</span><span class="cx"> class ApplyWatchListLocal(AbstractSequencedCommand):
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommandsbugfortestpy"></a>
<div class="delfile"><h4>Deleted: trunk/Tools/Scripts/webkitpy/tool/commands/bugfortest.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/bugfortest.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/bugfortest.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -1,50 +0,0 @@
</span><del>-# Copyright (c) 2010 Google 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:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * 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.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-# OWNER OR 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.
-
-from webkitpy.tool.bot.flakytestreporter import FlakyTestReporter
-from webkitpy.tool.commands.deprecatedcommand import DeprecatedCommand
-from webkitpy.tool.multicommandtool import Command
-
-
-# This is mostly a command for testing FlakyTestReporter, however
-# it could be easily expanded to auto-create bugs, etc. if another
-# command outside of webkitpy wanted to use it.
-@DeprecatedCommand
-class BugForTest(Command):
- name = "bug-for-test"
- help_text = "Finds the bugzilla bug for a given test"
-
- def execute(self, options, args, tool):
- reporter = FlakyTestReporter(tool, "webkitpy")
- search_string = args[0]
- bug = reporter._lookup_bug_for_flaky_test(search_string)
- if bug:
- bug = reporter._follow_duplicate_chain(bug)
- print("%5s %s" % (bug.id(), bug.title()))
- else:
- print("No bugs found matching '%s'" % search_string)
</del></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommandsbugsearchpy"></a>
<div class="delfile"><h4>Deleted: trunk/Tools/Scripts/webkitpy/tool/commands/bugsearch.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/bugsearch.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/bugsearch.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -1,51 +0,0 @@
</span><del>-# Copyright (c) 2010 Google 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:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * 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.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-# OWNER OR 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.
-
-from webkitpy.tool.commands.deprecatedcommand import DeprecatedCommand
-from webkitpy.tool.multicommandtool import Command
-
-
-@DeprecatedCommand
-class BugSearch(Command):
- name = "bug-search"
- help_text = "List bugs matching a query"
- argument_names = "QUERY"
- long_help = \
-"""Runs the bugzilla quicksearch QUERY on bugs.webkit.org, and lists all bugs
-returned. QUERY can be as simple as a bug number or a comma delimited list of
-bug numbers.
-See https://bugzilla.mozilla.org/page.cgi?id=quicksearch.html for full
-documentation on the query format."""
-
- def execute(self, options, args, tool):
- search_string = args[0]
- bugs = tool.bugs.queries.fetch_bugs_matching_quicksearch(search_string)
- for bug in bugs:
- print("%5s %s" % (bug.id(), bug.title()))
- if not bugs:
- print("No bugs found matching '%s'" % search_string)
</del></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommandsdownloadpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/tool/commands/download.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/download.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/download.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -57,39 +57,6 @@
</span><span class="cx"> options.force_clean = True
</span><span class="cx">
</span><span class="cx">
</span><del>-@DeprecatedCommand
-class Update(AbstractSequencedCommand):
- name = "update"
- help_text = "Update working copy (used internally)"
- steps = [
- steps.DiscardLocalChanges,
- steps.Update,
- ]
-
-
-@DeprecatedCommand
-class Build(AbstractSequencedCommand):
- name = "build"
- help_text = "Update working copy and build"
- steps = [
- steps.DiscardLocalChanges,
- steps.Update,
- steps.Build,
- ]
-
- def _prepare_state(self, options, args, tool):
- options.build = True
-
-
-@DeprecatedCommand
-class CheckPatchRelevance(AbstractSequencedCommand):
- name = "check-patch-relevance"
- help_text = "Check if this patch needs to be tested"
- steps = [
- steps.CheckPatchRelevance,
- ]
-
-
</del><span class="cx"> class Land(AbstractSequencedCommand):
</span><span class="cx"> name = "land"
</span><span class="cx"> help_text = "Land the current working directory diff and updates the associated bug if any"
</span><span class="lines">@@ -136,15 +103,6 @@
</span><span class="cx"> options.check_style_filter = "-changelog"
</span><span class="cx">
</span><span class="cx">
</span><del>-@DeprecatedCommand
-class LandCowboy(LandCowhand):
- name = "land-cowboy"
-
- def _prepare_state(self, options, args, tool):
- _log.warning("land-cowboy is deprecated, use land-cowhand instead.")
- LandCowhand._prepare_state(self, options, args, tool)
-
-
</del><span class="cx"> class CheckStyleLocal(AbstractSequencedCommand):
</span><span class="cx"> name = "check-style-local"
</span><span class="cx"> help_text = "Run check-webkit-style on the current working directory diff"
</span><span class="lines">@@ -259,19 +217,6 @@
</span><span class="cx"> ]
</span><span class="cx">
</span><span class="cx">
</span><del>-@DeprecatedCommand
-class BuildAttachment(AbstractPatchSequencingCommand, ProcessAttachmentsMixin):
- name = "build-attachment"
- help_text = "Apply and build patches from bugzilla"
- argument_names = "ATTACHMENT_ID [ATTACHMENT_IDS]"
- main_steps = [
- steps.DiscardLocalChanges,
- steps.Update,
- steps.ApplyPatch,
- steps.Build,
- ]
-
-
</del><span class="cx"> class AbstractPatchApplyingCommand(AbstractPatchSequencingCommand):
</span><span class="cx"> prepare_steps = [
</span><span class="cx"> steps.EnsureLocalCommitIfNeeded,
</span><span class="lines">@@ -299,21 +244,6 @@
</span><span class="cx"> show_in_main_help = True
</span><span class="cx">
</span><span class="cx">
</span><del>-@DeprecatedCommand
-class ApplyWatchList(AbstractPatchSequencingCommand, ProcessAttachmentsMixin):
- name = "apply-watchlist"
- help_text = "Applies the watchlist to the specified attachments"
- argument_names = "ATTACHMENT_ID [ATTACHMENT_IDS]"
- main_steps = [
- steps.DiscardLocalChanges,
- steps.Update,
- steps.ApplyPatch,
- steps.ApplyWatchList,
- ]
- long_help = """"Applies the watchlist to the specified attachments.
-Downloads the attachment, applies it locally, runs the watchlist against it, and updates the bug with the result."""
-
-
</del><span class="cx"> class AbstractPatchLandingCommand(AbstractPatchSequencingCommand):
</span><span class="cx"> main_steps = [
</span><span class="cx"> steps.DiscardLocalChanges,
</span><span class="lines">@@ -350,13 +280,6 @@
</span><span class="cx"> show_in_main_help = True
</span><span class="cx">
</span><span class="cx">
</span><del>-@DeprecatedCommand
-class LandFromURL(AbstractPatchLandingCommand, ProcessURLsMixin):
- name = "land-from-url"
- help_text = "Land all patches on the given URLs, optionally building and testing them first"
- argument_names = "URL [URLS]"
-
-
</del><span class="cx"> class ValidateChangelog(AbstractSequencedCommand):
</span><span class="cx"> name = "validate-changelog"
</span><span class="cx"> help_text = "Validate that the ChangeLogs and reviewers look reasonable"
</span><span class="lines">@@ -438,15 +361,6 @@
</span><span class="cx"> ]
</span><span class="cx">
</span><span class="cx">
</span><del>-@DeprecatedCommand
-class PrepareRollout(PrepareRevert):
- name = "prepare-rollout"
-
- def _prepare_state(self, options, args, tool):
- _log.warning("prepare-rollout is deprecated, use prepare-revert instead.")
- return PrepareRevert._prepare_state(self, options, args, tool)
-
-
</del><span class="cx"> class CreateRevert(AbstractRevertPrepCommand):
</span><span class="cx"> name = "create-revert"
</span><span class="cx"> help_text = "Creates a bug to track the broken SVN revision(s) and uploads a revert patch."
</span><span class="lines">@@ -476,15 +390,6 @@
</span><span class="cx"> return state
</span><span class="cx">
</span><span class="cx">
</span><del>-@DeprecatedCommand
-class CreateRollout(CreateRevert):
- name = "create-rollout"
-
- def _prepare_state(self, options, args, tool):
- _log.warning("create-rollout is deprecated, use create-revert instead.")
- return CreateRevert._prepare_state(self, options, args, tool)
-
-
</del><span class="cx"> class Revert(AbstractRevertPrepCommand):
</span><span class="cx"> name = "revert"
</span><span class="cx"> show_in_main_help = True
</span><span class="lines">@@ -506,13 +411,3 @@
</span><span class="cx"> steps.Commit,
</span><span class="cx"> steps.ReopenBugAfterRevert,
</span><span class="cx"> ]
</span><del>-
-
-@DeprecatedCommand
-class Rollout(Revert):
- name = "rollout"
- show_in_main_help = False
-
- def _prepare_state(self, options, args, tool):
- _log.warning("rollout is deprecated, use revert instead.")
- return Revert._prepare_state(self, options, args, tool)
</del></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommandsdownload_unittestpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/tool/commands/download_unittest.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/download_unittest.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/download_unittest.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -106,10 +106,6 @@
</span><span class="cx"> )),
</span><span class="cx"> })
</span><span class="cx">
</span><del>- def test_build(self):
- expected_logs = "Updating working directory\nBuilding WebKit\n"
- self.assert_execute_outputs(Build(), [], options=self._default_options(), expected_logs=expected_logs)
-
</del><span class="cx"> def test_apply_attachment(self):
</span><span class="cx"> options = self._default_options()
</span><span class="cx"> options.update = True
</span><span class="lines">@@ -128,19 +124,6 @@
</span><span class="cx"> expected_logs = "Updating working directory\n2 reviewed patches found on bug 50000.\nProcessing 2 patches from 1 bug.\nProcessing patch 10000 from bug 50000.\nProcessing patch 10001 from bug 50000.\n"
</span><span class="cx"> self.assert_execute_outputs(ApplyFromBug(), [50000], options=options, expected_logs=expected_logs)
</span><span class="cx">
</span><del>- def test_apply_watch_list(self):
- expected_logs = """Processing 1 patch from 1 bug.
-Updating working directory
-MOCK run_and_throw_if_fail: ['mock-update-webkit'], cwd=/mock-checkout
-Processing patch 10000 from bug 50000.
-MockWatchList: determine_cc_and_messages
-No bug was updated because no id was given.
-Result of watchlist: cc "abarth@webkit.org, eric@webkit.org, levin@chromium.org" messages "Message1.
-
-Message2."
-"""
- self.assert_execute_outputs(ApplyWatchList(), [10000], options=self._default_options(), expected_logs=expected_logs, tool=MockTool(log_executive=True))
-
</del><span class="cx"> def test_land(self):
</span><span class="cx"> expected_logs = """Building WebKit
</span><span class="cx"> Committed r49824: <https://commits.webkit.org/r49824>
</span><span class="lines">@@ -171,9 +154,6 @@
</span><span class="cx"> mock_tool = MockTool(log_executive=True)
</span><span class="cx"> self.assert_execute_outputs(LandCowhand(), [50000], options=self._default_options(), expected_logs=expected_logs, tool=mock_tool)
</span><span class="cx">
</span><del>- expected_logs = "land-cowboy is deprecated, use land-cowhand instead.\n" + expected_logs
- self.assert_execute_outputs(LandCowboy(), [50000], options=self._default_options(), expected_logs=expected_logs, tool=mock_tool)
-
</del><span class="cx"> def test_land_red_builders(self):
</span><span class="cx"> expected_logs = """Building WebKit
</span><span class="cx"> Committed r49824: <https://commits.webkit.org/r49824>
</span><span class="lines">@@ -193,10 +173,6 @@
</span><span class="cx"> """
</span><span class="cx"> self.assert_execute_outputs(CheckStyle(), [10000], options=self._default_options(), expected_logs=expected_logs, tool=MockTool(log_executive=True))
</span><span class="cx">
</span><del>- def test_build_attachment(self):
- expected_logs = "Processing 1 patch from 1 bug.\nUpdating working directory\nProcessing patch 10000 from bug 50000.\nBuilding WebKit\n"
- self.assert_execute_outputs(BuildAttachment(), [10000], options=self._default_options(), expected_logs=expected_logs)
-
</del><span class="cx"> def test_land_attachment(self):
</span><span class="cx"> # FIXME: This expected result is imperfect, notice how it's seeing the same patch as still there after it thought it would have cleared the flags.
</span><span class="cx"> expected_logs = """Processing 1 patch from 1 bug.
</span><span class="lines">@@ -227,24 +203,6 @@
</span><span class="cx"> with self.mock_svn_remote():
</span><span class="cx"> self.assert_execute_outputs(LandFromBug(), [50000], options=self._default_options(), expected_logs=expected_logs)
</span><span class="cx">
</span><del>- def test_land_from_url(self):
- # FIXME: This expected result is imperfect, notice how it's seeing the same patch as still there after it thought it would have cleared the flags.
- expected_logs = """2 patches found on bug 50000.
-Processing 2 patches from 1 bug.
-Updating working directory
-Processing patch 10000 from bug 50000.
-Building WebKit
-Committed r49824: <https://commits.webkit.org/r49824>
-Not closing bug 50000 as attachment 10000 has review=+. Assuming there are more patches to land from this bug.
-Updating working directory
-Processing patch 10001 from bug 50000.
-Building WebKit
-Committed r49824: <https://commits.webkit.org/r49824>
-Not closing bug 50000 as attachment 10000 has review=+. Assuming there are more patches to land from this bug.
-"""
- with self.mock_svn_remote():
- self.assert_execute_outputs(LandFromURL(), ["https://bugs.webkit.org/show_bug.cgi?id=50000"], options=self._default_options(), expected_logs=expected_logs)
-
</del><span class="cx"> def test_land_no_comment(self):
</span><span class="cx"> expected_logs = """Building WebKit
</span><span class="cx"> Committed r49824: <https://commits.webkit.org/r49824>
</span><span class="lines">@@ -281,13 +239,6 @@
</span><span class="cx"> options.close_bug = False
</span><span class="cx"> self.assert_execute_outputs(Land(), [50000], options=options, expected_logs=expected_logs)
</span><span class="cx">
</span><del>- def test_prepare_revert(self):
- expected_logs = "Preparing revert for bug 50000.\nUpdating working directory\n"
- self.assert_execute_outputs(PrepareRevert(), [852, "Reason"], options=self._default_options(), expected_logs=expected_logs)
-
- expected_logs = "prepare-rollout is deprecated, use prepare-revert instead.\n" + expected_logs
- self.assert_execute_outputs(PrepareRollout(), [852, "Reason"], options=self._default_options(), expected_logs=expected_logs)
-
</del><span class="cx"> def test_create_revert(self):
</span><span class="cx"> expected_logs = """Preparing revert for bug 50000.
</span><span class="cx"> Updating working directory
</span><span class="lines">@@ -311,9 +262,6 @@
</span><span class="cx"> """
</span><span class="cx"> self.assert_execute_outputs(CreateRevert(), [852, "Reason"], options=self._default_options(), expected_logs=expected_logs)
</span><span class="cx">
</span><del>- expected_logs = "create-rollout is deprecated, use create-revert instead.\n" + expected_logs
- self.assert_execute_outputs(CreateRollout(), [852, "Reason"], options=self._default_options(), expected_logs=expected_logs)
-
</del><span class="cx"> def test_create_revert_multiple_revision(self):
</span><span class="cx"> expected_logs = """Preparing revert for bug 50000.
</span><span class="cx"> Preparing revert for bug 50000.
</span><span class="lines">@@ -433,9 +381,6 @@
</span><span class="cx"> with self.mock_svn_remote():
</span><span class="cx"> self.assert_execute_outputs(Revert(), [852, "Reason", "Description"], options=self._default_options(), expected_logs=expected_logs)
</span><span class="cx">
</span><del>- expected_logs = "rollout is deprecated, use revert instead.\n" + expected_logs
- self.assert_execute_outputs(Rollout(), [852, "Reason", "Description"], options=self._default_options(), expected_logs=expected_logs)
-
</del><span class="cx"> def test_revert_two_revisions(self):
</span><span class="cx"> expected_logs = """Preparing revert for bug 50000.
</span><span class="cx"> Preparing revert for bug 50005.
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommandsearlywarningsystempy"></a>
<div class="delfile"><h4>Deleted: trunk/Tools/Scripts/webkitpy/tool/commands/earlywarningsystem.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/earlywarningsystem.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/earlywarningsystem.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -1,172 +0,0 @@
</span><del>-# Copyright (c) 2009 Google Inc. All rights reserved.
-# Copyright (c) 2017 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:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * 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.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-# OWNER OR 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 json
-import logging
-from optparse import make_option
-import sys
-
-from webkitcorepy import string_utils
-
-from webkitpy.common.system.executive import ScriptError
-from webkitpy.common.system.filesystem import FileSystem
-from webkitpy.tool.bot.earlywarningsystemtask import EarlyWarningSystemTask, EarlyWarningSystemTaskDelegate
-from webkitpy.tool.bot.jsctestresultsreader import JSCTestResultsReader
-from webkitpy.tool.bot.layouttestresultsreader import LayoutTestResultsReader
-from webkitpy.tool.bot.patchanalysistask import UnableToApplyPatch, PatchIsNotValid, PatchIsNotApplicable
-from webkitpy.tool.commands.deprecatedcommand import DeprecatedCommand
-from webkitpy.tool.commands.queues import AbstractReviewQueue
-
-_log = logging.getLogger(__name__)
-
-
-@DeprecatedCommand
-class AbstractEarlyWarningSystem(AbstractReviewQueue, EarlyWarningSystemTaskDelegate):
- # FIXME: Switch _default_run_tests from opt-in to opt-out once more bots are ready to run tests.
- run_tests = False
-
- def __init__(self):
- options = [make_option("--run-tests", action="store_true", dest="run_tests", default=self.run_tests, help="Run the Layout tests for each patch")]
- AbstractReviewQueue.__init__(self, options=options)
-
- def begin_work_queue(self):
- AbstractReviewQueue.begin_work_queue(self)
-
- if self.group() == "jsc":
- self._test_results_reader = JSCTestResultsReader(self._tool, self._port.jsc_results_directory())
- else:
- self._test_results_reader = LayoutTestResultsReader(self._tool, self._port.results_directory(), self._log_directory())
-
- def _failing_tests_message(self, task, patch):
- results = task.results_from_patch_test_run(patch)
-
- if not results:
- return None
-
- if results.did_exceed_test_failure_limit():
- return "Number of test failures exceeded the failure limit."
- return "New failing tests:\n%s" % "\n".join(results.failing_tests())
-
- def _post_reject_message_on_bug(self, tool, patch, status_id, extra_message_text=None):
- if not extra_message_text:
- return # Don't comment on Bugzilla if we don't have failing tests.
-
- message = "Attachment %s did not pass %s (%s)" % (patch.id(), self.name, self.port_name)
- if extra_message_text:
- message += "\n\n%s" % extra_message_text
- # FIXME: We might want to add some text about rejecting from the commit-queue in
- # the case where patch.commit_queue() isn't already set to '-'.
- if not self._can_access_bug(patch.bug_id()):
- return
- if self.watchers:
- tool.bugs.add_cc_to_bug(patch.bug_id(), self.watchers)
- tool.bugs.set_flag_on_attachment(patch.id(), "commit-queue", "-", message)
-
- # This exists for mocking
- def _create_task(self, patch):
- return EarlyWarningSystemTask(self, patch, should_run_tests=self._options.run_tests, should_build=self.should_build)
-
- def review_patch(self, patch):
- task = self._create_task(patch)
- try:
- succeeded = task.run()
- return succeeded
- except PatchIsNotValid:
- return False
- except UnableToApplyPatch:
- return False
- except PatchIsNotApplicable:
- return False
- except ScriptError as e:
- self._post_reject_message_on_bug(self._tool, patch, task.failure_status_id, self._failing_tests_message(task, patch))
- results_archive = task.results_archive_from_patch_test_run(patch)
- if results_archive:
- self._upload_results_archive_for_patch(patch, results_archive)
- raise e
-
- # EarlyWarningSystemDelegate methods
-
- def parent_command(self):
- return self.name
-
- def run_command(self, command):
- self.run_webkit_patch(command + [self._deprecated_port.flag()] + (['--architecture=%s' % self._port.architecture()] if self._port.architecture() != self._port.DEFAULT_ARCHITECTURE else []))
-
- def test_results(self):
- return self._test_results_reader.results()
-
- def archive_last_test_results(self, patch):
- return self._test_results_reader.archive(patch)
-
- def build_style(self):
- return self._build_style
-
- def group(self):
- return self._group
-
- def refetch_patch(self, patch):
- return self._tool.bugs.fetch_attachment(patch.id())
-
- def report_flaky_tests(self, patch, flaky_test_results, results_archive):
- pass
-
- # StepSequenceErrorHandler methods
-
- @classmethod
- def handle_script_error(cls, tool, state, script_error):
- # FIXME: Why does this not exit(1) like the superclass does?
- _log.error(script_error.message_with_output(output_limit=5000))
-
- @classmethod
- def load_ews_classes(cls):
- filesystem = FileSystem()
- json_path = filesystem.join(filesystem.dirname(filesystem.path_to_module('webkitpy.common.config')), 'ews.json')
- try:
- ewses = json.loads(filesystem.read_text_file(json_path))
- except ValueError:
- return None
-
- classes = []
- for name, config in ewses.items():
- if sys.version_info > (3, 0):
- translated = string_utils.encode(name, target_type=str).translate(' -')
- else:
- translated = string_utils.encode(name, target_type=str).translate(None, ' -')
-
- classes.append(type(translated, (cls,), {
- 'name': config.get('name', config['port'] + '-ews'),
- 'port_name': config['port'],
- 'architecture': config.get('architecture', None),
- '_build_style': config.get('style', "release"),
- 'watchers': config.get('watchers', []),
- 'run_tests': config.get('runTests', cls.run_tests),
- '_group': config.get('group', None),
- 'should_build': config.get('shouldBuild', True),
- }))
- return classes
</del></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommandsearlywarningsystem_unittestpy"></a>
<div class="delfile"><h4>Deleted: trunk/Tools/Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -1,186 +0,0 @@
</span><del>-# Copyright (C) 2009 Google Inc. All rights reserved.
-# Copyright (C) 2017, 2020 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:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * 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.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-# OWNER OR 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.
-
-from webkitpy.thirdparty.mock import Mock
-from webkitpy.common.host import Host
-from webkitpy.common.host_mock import MockHost
-from webkitpy.common.net.jsctestresults import JSCTestResults
-from webkitpy.common.net.layouttestresults import LayoutTestResults
-from webkitpy.layout_tests.models import test_results
-from webkitpy.layout_tests.models import test_failures
-from webkitpy.port.factory import PortFactory
-from webkitpy.tool.bot.queueengine import QueueEngine
-from webkitpy.tool.commands.earlywarningsystem import *
-from webkitpy.tool.commands.queues import PatchProcessingQueue
-from webkitpy.tool.commands.queuestest import QueuesTest
-from webkitpy.tool.mocktool import MockTool, MockOptions
-
-from webkitcorepy import OutputCapture
-
-
-# Needed to define port_name, used in AbstractEarlyWarningSystem.__init__
-class TestEWS(AbstractEarlyWarningSystem):
- port_name = "win" # Needs to be a port which port/factory understands.
- _build_style = None
- _group = None
-
-
-class TestJSCEWS(AbstractEarlyWarningSystem):
- port_name = "mac" # Needs to be a port which port/factory understands.
- _build_style = None
- _group = "jsc"
-
-
-class AbstractEarlyWarningSystemTest(QueuesTest):
- def _test_message(self, ews, results, message):
- ews.bind_to_tool(MockTool())
- ews.host = MockHost()
- ews._options = MockOptions(port=None, confirm=False)
-
- with OutputCapture(level=logging.INFO) as captured:
- ews.begin_work_queue()
- self.assertEqual(captured.root.log.getvalue(), self._default_begin_work_queue_logs(ews.name))
-
- task = Mock()
- task.results_from_patch_test_run = results
- patch = ews._tool.bugs.fetch_attachment(10000)
- self.assertMultiLineEqual(ews._failing_tests_message(task, patch), message)
-
- def test_failing_tests_message(self):
- ews = TestEWS()
- results = lambda a: LayoutTestResults([test_results.TestResult("foo.html", failures=[test_failures.FailureTextMismatch()]),
- test_results.TestResult("bar.html", failures=[test_failures.FailureTextMismatch()])],
- did_exceed_test_failure_limit=False)
- message = "New failing tests:\nfoo.html\nbar.html"
- self._test_message(ews, results, message)
-
- def test_failing_jsc_tests_message(self):
- ews = TestJSCEWS()
- results = lambda a: JSCTestResults(False, ["es6.yaml/es6/typed_arrays_Int8Array.js.default", "es6.yaml/es6/typed_arrays_Uint8Array.js.default"])
- message = "New failing tests:\nes6.yaml/es6/typed_arrays_Int8Array.js.default\nes6.yaml/es6/typed_arrays_Uint8Array.js.default\napiTests"
- self._test_message(ews, results, message)
-
-
-class MockEarlyWarningSystemTaskForInconclusiveJSCResults(EarlyWarningSystemTask):
- def _test_patch(self):
- self._test()
- results = self._delegate.test_results()
- return bool(results)
-
-
-class MockAbstractEarlyWarningSystemForInconclusiveJSCResults(AbstractEarlyWarningSystem):
- def _create_task(self, patch):
- task = MockEarlyWarningSystemTaskForInconclusiveJSCResults(self, patch, self._options.run_tests)
- return task
-
-
-class EarlyWarningSystemTest(QueuesTest):
- def _default_expected_logs(self, ews, conclusive):
- string_replacements = {
- "name": ews.name,
- "port": ews.port_name,
- "architecture": " --architecture=%s" % ews.architecture if ews.architecture else "",
- "build_style": ews.build_style(),
- "group": ews.group(),
- }
-
- if ews.should_build:
- build_line = "Running: webkit-patch build --no-clean --no-update --build-style=%(build_style)s --group=%(group)s --port=%(port)s%(architecture)s\n" % string_replacements
- else:
- build_line = ""
- string_replacements['build_line'] = build_line
-
- if ews.run_tests:
- run_tests_line = "Running: webkit-patch build-and-test --no-clean --no-update --test --non-interactive --build-style=%(build_style)s --group=%(group)s --port=%(port)s%(architecture)s\n" % string_replacements
- else:
- run_tests_line = ""
- string_replacements['run_tests_line'] = run_tests_line
-
- string_replacements['result_lines'] = ""
-
- expected_logs = {
- "begin_work_queue": self._default_begin_work_queue_logs(ews.name),
- "process_work_item": """Running: webkit-patch clean --port=%(port)s%(architecture)s
-Running: webkit-patch update --port=%(port)s%(architecture)s
-Running: webkit-patch apply-attachment --no-update --non-interactive 10000 --port=%(port)s%(architecture)s
-Running: webkit-patch check-patch-relevance --quiet --group=%(group)s --port=%(port)s%(architecture)s
-%(build_line)s%(run_tests_line)s%(result_lines)s""" % string_replacements,
- "handle_unexpected_error": "Mock error message\n",
- "handle_script_error": "ScriptError error message\n\nMOCK output\n",
- }
- return expected_logs
-
- def _test_ews(self, ews, results_are_conclusive=True):
- ews.bind_to_tool(MockTool())
- ews.host = MockHost()
- options = Mock()
- options.port = None
- options.run_tests = ews.run_tests
- self.assert_queue_outputs(ews, expected_logs=self._default_expected_logs(ews, results_are_conclusive), options=options)
-
- def test_ewses(self):
- classes = AbstractEarlyWarningSystem.load_ews_classes()
- self.assertTrue(classes)
- self.maxDiff = None
- for ews_class in classes:
- self._test_ews(ews_class())
-
- def test_inconclusive_jsc_test_results(self):
- classes = MockAbstractEarlyWarningSystemForInconclusiveJSCResults.load_ews_classes()
- self.assertTrue(classes)
- self.maxDiff = None
- test_classes = filter(lambda x: x.run_tests and x.group == "jsc", classes)
- for ews_class in test_classes:
- self._test_ews(ews_class(), False)
-
- def test_ews_name(self):
- # These are the names EWS's infrastructure expects, check that they work
- expected_names = {
- 'gtk-wk2-ews',
- 'ios-ews',
- 'ios-sim-ews',
- 'jsc-ews',
- 'jsc-i386-ews',
- 'jsc-mips-ews',
- 'jsc-armv7-ews',
- 'mac-debug-ews',
- 'mac-ews',
- 'mac-wk2-ews',
- 'win-ews',
- 'wpe-ews',
- 'wincairo-ews',
- }
- classes = AbstractEarlyWarningSystem.load_ews_classes()
- names = {cls.name for cls in classes}
- missing_names = expected_names - names
- unexpected_names = names - expected_names
- if missing_names:
- raise AssertionError("'{}' is not a valid EWS command but is used by EWS's infrastructure".format(missing_names.pop()))
- if unexpected_names:
- raise AssertionError("'{}' is a valid EWS command but is not used by EWS's infrastructure".format(unexpected_names.pop()))
</del></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommandsfinduserspy"></a>
<div class="delfile"><h4>Deleted: trunk/Tools/Scripts/webkitpy/tool/commands/findusers.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/findusers.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/findusers.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -1,44 +0,0 @@
</span><del>-# Copyright (c) 2011 Google Inc. All rights reserved.
-# Copyright (c) 2014 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:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * 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.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-# OWNER OR 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.
-
-from webkitpy.common.config.committers import CommitterList
-from webkitpy.tool.commands.deprecatedcommand import DeprecatedCommand
-from webkitpy.tool.multicommandtool import Command
-
-
-@DeprecatedCommand
-class FindUsers(Command):
- name = "find-users"
- help_text = "Find users matching substring"
-
- def execute(self, options, args, tool):
- search_string = args[0]
- users = CommitterList().contributors_by_search_string(search_string)
- for user in users:
- print(user)
</del></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommandsgardenomaticpy"></a>
<div class="delfile"><h4>Deleted: trunk/Tools/Scripts/webkitpy/tool/commands/gardenomatic.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/gardenomatic.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/gardenomatic.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -1,66 +0,0 @@
</span><del>-# Copyright (C) 2011 Google 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-# OWNER OR 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.
-
-from webkitpy.port import builders
-from webkitpy.port import factory
-from webkitpy.tool.commands.deprecatedcommand import DeprecatedCommand
-from webkitpy.tool.commands.rebaseline import AbstractRebaseliningCommand
-from webkitpy.tool.servers.gardeningserver import GardeningHTTPServer
-
-
-@DeprecatedCommand
-class GardenOMatic(AbstractRebaseliningCommand):
- name = "garden-o-matic"
- help_text = "Command for gardening the WebKit tree."
-
- # REVIEW: Reset the option here because globbing isn't useful for us, but apparently
- # it's useful for other rebaselining commands because use_globs=True is set in parent.
- platform_options = factory.platform_options()
-
- def __init__(self):
- super(GardenOMatic, self).__init__(options=(self.platform_options + [
- self.move_overwritten_baselines_option,
- self.results_directory_option,
- self.no_optimize_option,
- ]))
-
- def execute(self, options, args, tool):
- print("This command runs a local HTTP server that changes your working copy")
- print("based on the actions you take in the web-based UI.")
-
- args = {}
- if options.platform:
- # FIXME: This assumes that the port implementation (chromium-, gtk-, etc.) is the first part of options.platform.
- args['platform'] = options.platform.split('-')[0]
- builder = builders.builder_name_for_port_name(options.platform)
- if builder:
- args['builder'] = builder
- if options.results_directory:
- args['useLocalResults'] = "true"
-
- httpd = GardeningHTTPServer(httpd_port=8127, config={'tool': tool, 'options': options})
- self._tool.user.open_url(httpd.url(args))
-
- print("Local HTTP server started.")
- httpd.serve_forever()
</del></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommandsopenbugspy"></a>
<div class="delfile"><h4>Deleted: trunk/Tools/Scripts/webkitpy/tool/commands/openbugs.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/openbugs.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/openbugs.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -1,67 +0,0 @@
</span><del>-# Copyright (c) 2010 Google 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:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * 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.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-# OWNER OR 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 re
-import sys
-
-from webkitpy.tool.multicommandtool import Command
-from webkitpy.tool.commands.deprecatedcommand import DeprecatedCommand
-
-_log = logging.getLogger(__name__)
-
-
-@DeprecatedCommand
-class OpenBugs(Command):
- name = "open-bugs"
- help_text = "Finds all bug numbers passed in arguments (or stdin if no args provided) and opens them in a web browser"
-
- bug_number_regexp = re.compile(r"\b\d{4,6}\b")
-
- def _open_bugs(self, bug_ids):
- for bug_id in bug_ids:
- bug_url = self._tool.bugs.bug_url_for_bug_id(bug_id)
- self._tool.user.open_url(bug_url)
-
- # _find_bugs_in_string mostly exists for easy unit testing.
- def _find_bugs_in_string(self, string):
- return self.bug_number_regexp.findall(string)
-
- def _find_bugs_in_iterable(self, iterable):
- return sum([self._find_bugs_in_string(string) for string in iterable], [])
-
- def execute(self, options, args, tool):
- if args:
- bug_ids = self._find_bugs_in_iterable(args)
- else:
- # This won't open bugs until stdin is closed but could be made to easily. That would just make unit testing slightly harder.
- bug_ids = self._find_bugs_in_iterable(sys.stdin)
-
- _log.info("%s bugs found in input." % len(bug_ids))
-
- self._open_bugs(bug_ids)
</del></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommandsopenbugs_unittestpy"></a>
<div class="delfile"><h4>Deleted: trunk/Tools/Scripts/webkitpy/tool/commands/openbugs_unittest.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/openbugs_unittest.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/openbugs_unittest.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -1,51 +0,0 @@
</span><del>-# Copyright (C) 2009 Google 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:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * 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.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-# OWNER OR 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.
-
-from webkitpy.tool.commands.commandtest import CommandsTest
-from webkitpy.tool.commands.openbugs import OpenBugs
-
-
-class OpenBugsTest(CommandsTest):
-
- find_bugs_in_string_expectations = [
- ["123", []],
- ["1234", ["1234"]],
- ["12345", ["12345"]],
- ["123456", ["123456"]],
- ["1234567", []],
- [" 123456 234567", ["123456", "234567"]],
- ]
-
- def test_find_bugs_in_string(self):
- openbugs = OpenBugs()
- for expectation in self.find_bugs_in_string_expectations:
- self.assertEqual(openbugs._find_bugs_in_string(expectation[0]), expectation[1])
-
- def test_args_parsing(self):
- expected_logs = "2 bugs found in input.\nMOCK: user.open_url: http://example.com/12345\nMOCK: user.open_url: http://example.com/23456\n"
- self.assert_execute_outputs(OpenBugs(), ["12345\n23456"], expected_logs=expected_logs)
</del></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommandsqueriespy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/tool/commands/queries.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/queries.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/queries.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -53,7 +53,6 @@
</span><span class="cx"> from webkitpy.layout_tests.models.test_expectations import TestExpectations
</span><span class="cx"> from webkitpy.port import platform_options, configuration_options
</span><span class="cx"> from webkitpy.tool.commands.abstractsequencedcommand import AbstractSequencedCommand
</span><del>-from webkitpy.tool.commands.deprecatedcommand import DeprecatedCommand
</del><span class="cx"> from webkitpy.tool.multicommandtool import Command
</span><span class="cx">
</span><span class="cx"> _log = logging.getLogger(__name__)
</span><span class="lines">@@ -68,561 +67,3 @@
</span><span class="cx">
</span><span class="cx"> def _prepare_state(self, options, args, tool):
</span><span class="cx"> options.suggest_reviewers = True
</span><del>-
-
-@DeprecatedCommand
-class BugsToCommit(Command):
- name = "bugs-to-commit"
- help_text = "List bugs in the commit-queue"
-
- def execute(self, options, args, tool):
- # FIXME: This command is poorly named. It's fetching the commit-queue list here. The name implies it's fetching pending-commit (all r+'d patches).
- bug_ids = tool.bugs.queries.fetch_bug_ids_from_commit_queue()
- for bug_id in bug_ids:
- print("%s" % bug_id)
-
-
-@DeprecatedCommand
-class PatchesInCommitQueue(Command):
- name = "patches-in-commit-queue"
- help_text = "List patches in the commit-queue"
-
- def execute(self, options, args, tool):
- patches = tool.bugs.queries.fetch_patches_from_commit_queue()
- _log.info("Patches in commit queue:")
- for patch in patches:
- print(patch.url())
-
-
-@DeprecatedCommand
-class PatchesToCommitQueue(Command):
- name = "patches-to-commit-queue"
- help_text = "Patches which should be added to the commit queue"
-
- def __init__(self):
- options = [
- make_option("--bugs", action="store_true", dest="bugs", help="Output bug links instead of patch links"),
- ]
- Command.__init__(self, options=options)
-
- @staticmethod
- def _needs_commit_queue(patch):
- if patch.commit_queue() == "+": # If it's already cq+, ignore the patch.
- _log.info("%s already has cq=%s" % (patch.id(), patch.commit_queue()))
- return False
-
- # We only need to worry about patches from contributers who are not yet committers.
- committer_record = CommitterList().committer_by_email(patch.attacher_email())
- if committer_record:
- _log.info("%s committer = %s" % (patch.id(), committer_record))
- return not committer_record
-
- def execute(self, options, args, tool):
- patches = tool.bugs.queries.fetch_patches_from_pending_commit_list()
- patches_needing_cq = filter(self._needs_commit_queue, patches)
- if options.bugs:
- bugs_needing_cq = map(lambda patch: patch.bug_id(), patches_needing_cq)
- bugs_needing_cq = sorted(set(bugs_needing_cq))
- for bug_id in bugs_needing_cq:
- print("%s" % tool.bugs.bug_url_for_bug_id(bug_id))
- else:
- for patch in patches_needing_cq:
- print("%s" % tool.bugs.attachment_url_for_id(patch.id(), action="edit"))
-
-
-@DeprecatedCommand
-class PatchesToReview(Command):
- name = "patches-to-review"
- help_text = "List bugs which have attachments pending review"
-
- def __init__(self):
- options = [
- make_option("--all", action="store_true",
- help="Show all bugs regardless of who is on CC (it might take a while)"),
- make_option("--include-cq-denied", action="store_true",
- help="By default, r? patches with cq- are omitted unless this option is set"),
- make_option("--cc-email",
- help="Specifies the email on the CC field (defaults to your bugzilla login email)"),
- ]
- Command.__init__(self, options=options)
-
- def _print_report(self, report, cc_email, print_all):
- if print_all:
- print("Bugs with attachments pending review:")
- else:
- print("Bugs with attachments pending review that has %s in the CC list:" % cc_email)
-
- print("http://webkit.org/b/bugid Description (age in days)")
- for row in report:
- print("%s (%d)" % (row[1], row[0]))
-
- print("Total: %d" % len(report))
-
- def _generate_report(self, bugs, include_cq_denied):
- report = []
-
- for bug in bugs:
- patch = bug.unreviewed_patches()[-1]
-
- if not include_cq_denied and patch.commit_queue() == "-":
- continue
-
- age_in_days = (datetime.today() - patch.attach_date()).days
- report.append((age_in_days, "http://webkit.org/b/%-7s %s" % (bug.id(), bug.title())))
-
- report.sort()
- return report
-
- def execute(self, options, args, tool):
- tool.bugs.authenticate()
-
- cc_email = options.cc_email
- if not cc_email and not options.all:
- cc_email = tool.bugs.username
-
- bugs = tool.bugs.queries.fetch_bugs_from_review_queue(cc_email=cc_email)
- report = self._generate_report(bugs, options.include_cq_denied)
- self._print_report(report, cc_email, options.all)
-
-
-@DeprecatedCommand
-class WhatBroke(Command):
- name = "what-broke"
- help_text = "Print failing buildbots (%s) and what revisions broke them" % config_urls.buildbot_url
-
- def _print_builder_line(self, builder_name, max_name_width, status_message):
- print("%s : %s" % (builder_name.ljust(max_name_width), status_message))
-
- def _print_blame_information_for_builder(self, builder_status, name_width, avoid_flakey_tests=True):
- builder = self._tool.buildbot.builder_with_name(builder_status["name"])
- red_build = builder.build(builder_status["build_number"])
- regression_window = builder.find_regression_window(red_build)
- if not regression_window.failing_build():
- self._print_builder_line(builder.name(), name_width, "FAIL (error loading build information)")
- return
- if not regression_window.build_before_failure():
- self._print_builder_line(builder.name(), name_width, "FAIL (blame-list: sometime before %s?)" % regression_window.failing_build().revision())
- return
-
- revisions = regression_window.revisions()
- first_failure_message = ""
- if (regression_window.failing_build() == builder.build(builder_status["build_number"])):
- first_failure_message = " FIRST FAILURE, possibly a flaky test"
- self._print_builder_line(builder.name(), name_width, "FAIL (blame-list: %s%s)" % (revisions, first_failure_message))
- for revision in revisions:
- commit_info = self._tool.checkout().commit_info_for_revision(revision)
- if commit_info:
- print(commit_info.blame_string(self._tool.bugs))
- else:
- print("FAILED to fetch CommitInfo for r%s, likely missing ChangeLog" % revision)
-
- def execute(self, options, args, tool):
- builder_statuses = tool.buildbot.builder_statuses()
- longest_builder_name = max(map(len, map(lambda builder: builder["name"], builder_statuses)))
- failing_builders = 0
- for builder_status in builder_statuses:
- # If the builder is green, print OK, exit.
- if builder_status["is_green"]:
- continue
- self._print_blame_information_for_builder(builder_status, name_width=longest_builder_name)
- failing_builders += 1
- if failing_builders:
- print("%s of %s are failing" % (failing_builders, pluralize(len(builder_statuses), "builder")))
- else:
- print("All builders are passing!")
-
-
-@DeprecatedCommand
-class ResultsFor(Command):
- name = "results-for"
- help_text = "Print a list of failures for the passed revision from bots on %s" % config_urls.buildbot_url
- argument_names = "REVISION"
-
- def _print_layout_test_results(self, results):
- if not results:
- print(" No results.")
- return
- for title, files in results.parsed_results().items():
- print(" %s" % title)
- for filename in files:
- print(" %s" % filename)
-
- def execute(self, options, args, tool):
- builders = self._tool.buildbot.builders()
- for builder in builders:
- print("%s:" % builder.name())
- build = builder.build_for_revision(args[0], allow_failed_lookups=True)
- self._print_layout_test_results(build.layout_test_results())
-
-
-@DeprecatedCommand
-class FailureReason(Command):
- name = "failure-reason"
- help_text = "Lists revisions where individual test failures started at %s" % config_urls.buildbot_url
- arguments_names = "[LAYOUT_TESTS]"
-
- def _blame_line_for_revision(self, revision):
- try:
- commit_info = self._tool.checkout().commit_info_for_revision(revision)
- except Exception as e:
- return "FAILED to fetch CommitInfo for r%s, exception: %s" % (revision, e)
- if not commit_info:
- return "FAILED to fetch CommitInfo for r%s, likely missing ChangeLog" % revision
- return commit_info.blame_string(self._tool.bugs)
-
- def _print_blame_information_for_transition(self, regression_window, failing_tests):
- red_build = regression_window.failing_build()
- print("SUCCESS: Build %s (r%s) was the first to show failures: %s" % (red_build._number, red_build.revision(), failing_tests))
- print("Suspect revisions:")
- for revision in regression_window.revisions():
- print(self._blame_line_for_revision(revision))
-
- def _explain_failures_for_builder(self, builder, start_revision):
- print("Examining failures for \"%s\", starting at r%s" % (builder.name(), start_revision))
- revision_to_test = start_revision
- build = builder.build_for_revision(revision_to_test, allow_failed_lookups=True)
- layout_test_results = build.layout_test_results()
- if not layout_test_results:
- # FIXME: This could be made more user friendly.
- print("Failed to load layout test results from %s; can't continue. (start revision = r%s)" % (build.results_url(), start_revision))
- return 1
-
- results_to_explain = set(layout_test_results.failing_tests())
- last_build_with_results = build
- print("Starting at %s" % revision_to_test)
- while results_to_explain and not self._done_explaining():
- revision_to_test -= 1
- new_build = builder.build_for_revision(revision_to_test, allow_failed_lookups=True)
- if not new_build:
- print("No build for %s" % revision_to_test)
- continue
- build = new_build
- latest_results = build.layout_test_results()
- if not latest_results:
- print("No results build %s (r%s)" % (build._number, build.revision()))
- continue
- failures = set(latest_results.failing_tests())
- if len(failures) >= 500:
- # FIXME: We may need to move this logic into the LayoutTestResults class.
- # The buildbot stops runs after 500 failures so we don't have full results to work with here.
- print("Too many failures in build %s (r%s), ignoring." % (build._number, build.revision()))
- continue
- fixed_results = results_to_explain - failures
- if not fixed_results:
- print("No change in build %s (r%s), %s unexplained failures (%s in this build)" % (build._number, build.revision(), len(results_to_explain), len(failures)))
- last_build_with_results = build
- continue
- self.explained_failures.update(fixed_results)
- regression_window = RegressionWindow(build, last_build_with_results)
- self._print_blame_information_for_transition(regression_window, fixed_results)
- last_build_with_results = build
- results_to_explain -= fixed_results
- if results_to_explain:
- print("Failed to explain failures: %s" % results_to_explain)
- return 1
- print("Explained all results for %s" % builder.name())
- return 0
-
- def _builder_to_explain(self):
- builder_statuses = self._tool.buildbot.builder_statuses()
- red_statuses = [status for status in builder_statuses if not status["is_green"]]
- print("%s failing" % (pluralize(len(red_statuses), "builder")))
- builder_choices = [status["name"] for status in red_statuses]
- # We could offer an "All" choice here.
- chosen_name = self._tool.user.prompt_with_list("Which builder to diagnose:", builder_choices)
- # FIXME: prompt_with_list should really take a set of objects and a set of names and then return the object.
- for status in red_statuses:
- if status["name"] == chosen_name:
- return (self._tool.buildbot.builder_with_name(chosen_name), status["built_revision"])
-
- def _done_explaining(self):
- if not self.failures_to_explain:
- return False
-
- return self.explained_failures.issuperset(self.failures_to_explain)
-
- def execute(self, options, args, tool):
- (builder, latest_revision) = self._builder_to_explain()
- start_revision = self._tool.user.prompt("Revision to walk backwards from? [%s] " % latest_revision) or latest_revision
- self.failures_to_explain = args
- self.explained_failures = set()
- if not start_revision:
- print("Revision required.")
- return 1
- return self._explain_failures_for_builder(builder, start_revision=int(start_revision))
-
-
-@DeprecatedCommand
-class FindFlakyTests(Command):
- name = "find-flaky-tests"
- help_text = "Lists tests that often fail for a single build at %s" % config_urls.buildbot_url
-
- def _find_failures(self, builder, revision):
- build = builder.build_for_revision(revision, allow_failed_lookups=True)
- if not build:
- print("No build for %s" % revision)
- return (None, None)
- results = build.layout_test_results()
- if not results:
- print("No results build %s (r%s)" % (build._number, build.revision()))
- return (None, None)
- failures = set(results.failing_tests())
- if len(failures) >= 20:
- # FIXME: We may need to move this logic into the LayoutTestResults class.
- # The buildbot stops runs after 20 failures so we don't have full results to work with here.
- print("Too many failures in build %s (r%s), ignoring." % (build._number, build.revision()))
- return (None, None)
- return (build, failures)
-
- def _increment_statistics(self, flaky_tests, flaky_test_statistics):
- for test in flaky_tests:
- count = flaky_test_statistics.get(test, 0)
- flaky_test_statistics[test] = count + 1
-
- def _print_statistics(self, statistics):
- print("=== Results ===")
- print("Occurrences Test name")
- for value, key in sorted([(value, key) for key, value in statistics.items()]):
- print("%10d %s" % (value, key))
-
- def _walk_backwards_from(self, builder, start_revision, limit):
- flaky_test_statistics = {}
- all_previous_failures = set([])
- one_time_previous_failures = set([])
- previous_build = None
- for i in range(limit):
- revision = start_revision - i
- print("Analyzing %s ... " % revision, end=' ')
- (build, failures) = self._find_failures(builder, revision)
- if failures == None:
- # Notice that we don't loop on the empty set!
- continue
- print("has %s failures" % len(failures))
- flaky_tests = one_time_previous_failures - failures
- if flaky_tests:
- print("Flaky tests: %s %s" % (sorted(flaky_tests),
- previous_build.results_url()))
- self._increment_statistics(flaky_tests, flaky_test_statistics)
- one_time_previous_failures = failures - all_previous_failures
- all_previous_failures = failures
- previous_build = build
- self._print_statistics(flaky_test_statistics)
-
- def _builder_to_analyze(self):
- statuses = self._tool.buildbot.builder_statuses()
- choices = [status["name"] for status in statuses]
- chosen_name = self._tool.user.prompt_with_list("Which builder to analyze:", choices)
- for status in statuses:
- if status["name"] == chosen_name:
- return (self._tool.buildbot.builder_with_name(chosen_name), status["built_revision"])
-
- def execute(self, options, args, tool):
- (builder, latest_revision) = self._builder_to_analyze()
- limit = self._tool.user.prompt("How many revisions to look through? [10000] ") or 10000
- return self._walk_backwards_from(builder, latest_revision, limit=int(limit))
-
-
-@DeprecatedCommand
-class TreeStatus(Command):
- name = "tree-status"
- help_text = "Print the status of the %s buildbots" % config_urls.buildbot_url
- long_help = """Fetches build status from https://build.webkit.org/one_box_per_builder
-and displayes the status of each builder."""
-
- def execute(self, options, args, tool):
- for builder in tool.buildbot.builder_statuses():
- status_string = "ok" if builder["is_green"] else "FAIL"
- print("%s : %s" % (status_string.ljust(4), builder["name"]))
-
-
-@DeprecatedCommand
-class CrashLog(Command):
- name = "crash-log"
- help_text = "Print the newest crash log for the given process"
- long_help = """Finds the newest crash log matching the given process name
-and PID and prints it to stdout."""
- argument_names = "PROCESS_NAME [PID]"
-
- def execute(self, options, args, tool):
- default_port = tool.port_factory.get()
- crash_logs = CrashLogs(tool, default_port.path_to_crash_logs())
- pid = None
- if len(args) > 1:
- pid = int(args[1])
- print(crash_logs.find_newest_log(args[0], pid))
-
-
-@DeprecatedCommand
-class PrintExpectations(Command):
- name = 'print-expectations'
- help_text = 'Print the expected result for the given test(s) on the given port(s)'
-
- def __init__(self):
- options = [
- make_option('--all', action='store_true', default=False,
- help='display the expectations for *all* tests'),
- make_option('-x', '--exclude-keyword', action='append', default=[],
- help='limit to tests not matching the given keyword (for example, "skip", "slow", or "crash". May specify multiple times'),
- make_option('-i', '--include-keyword', action='append', default=[],
- help='limit to tests with the given keyword (for example, "skip", "slow", or "crash". May specify multiple times'),
- make_option('-f', '--full', action='store_true', default=False,
- help='Print a full TestExpectations-style line for every match'),
- make_option('--paths', action='store_true', default=False,
- help='display the paths for all applicable expectation files'),
- ] + platform_options(use_globs=True)
-
- Command.__init__(self, options=options)
- self._expectation_models = {}
-
- def execute(self, options, args, tool):
- if not options.paths and not args and not options.all:
- print("You must either specify one or more test paths or --all.")
- return
-
- if options.platform:
- port_names = fnmatch.filter(tool.port_factory.all_port_names(), options.platform)
- if not port_names:
- default_port = tool.port_factory.get(options.platform)
- if default_port:
- port_names = [default_port.name()]
- else:
- print("No port names match '%s'" % options.platform)
- return
- else:
- default_port = tool.port_factory.get(port_names[0])
- else:
- default_port = tool.port_factory.get(options=options)
- port_names = [default_port.name()]
-
- if options.paths:
- files = default_port.expectations_files()
- layout_tests_dir = default_port.layout_tests_dir()
- for file in files:
- if file.startswith(layout_tests_dir):
- file = file.replace(layout_tests_dir, 'LayoutTests')
- print(file)
- return
-
- finder = LayoutTestFinder(default_port, None)
- tests = finder.find_tests_by_path(args)
- test_files = {test.test_path for test in tests}
- for port_name in port_names:
- model = self._model(options, port_name, test_files)
- tests_to_print = self._filter_tests(options, model, test_files)
- lines = [model.get_expectation_line(test) for test in sorted(tests_to_print)]
- if port_name != port_names[0]:
- print()
- print('\n'.join(self._format_lines(options, port_name, lines)))
-
- def _filter_tests(self, options, model, tests):
- filtered_tests = set()
- if options.include_keyword:
- for keyword in options.include_keyword:
- filtered_tests.update(model.get_test_set_for_keyword(keyword))
- else:
- filtered_tests = tests
-
- for keyword in options.exclude_keyword:
- filtered_tests.difference_update(model.get_test_set_for_keyword(keyword))
- return filtered_tests
-
- def _format_lines(self, options, port_name, lines):
- output = []
- if lines:
- include_modifiers = options.full
- include_expectations = options.full or len(options.include_keyword) != 1 or len(options.exclude_keyword)
- output.append("// For %s" % port_name)
- for line in lines:
- output.append("%s" % line.to_string(None, include_modifiers, include_expectations, include_comment=False))
- return output
-
- def _model(self, options, port_name, tests):
- port = self._tool.port_factory.get(port_name, options)
- expectations = TestExpectations(port, tests)
- expectations.parse_all_expectations()
- return expectations.model()
-
-
-@DeprecatedCommand
-class PrintBaselines(Command):
- name = 'print-baselines'
- help_text = 'Prints the baseline locations for given test(s) on the given port(s)'
-
- def __init__(self):
- options = [
- make_option('--all', action='store_true', default=False,
- help='display the baselines for *all* tests'),
- ] + platform_options(use_globs=True)
- Command.__init__(self, options=options)
- self._platform_regexp = re.compile(r'platform/([^\/]+)/(.+)')
-
- def execute(self, options, args, tool):
- if not args and not options.all:
- print("You must either specify one or more test paths or --all.")
- return
-
- default_port = tool.port_factory.get()
- if options.platform:
- port_names = fnmatch.filter(tool.port_factory.all_port_names(), options.platform)
- if not port_names:
- print("No port names match '%s'" % options.platform)
- else:
- port_names = [default_port.name()]
-
- # FIXME: make real_tests() a public method.
- finder = LayoutTestFinder(default_port, None)
- tests = sorted(finder._real_tests(args))
-
- for port_name in port_names:
- if port_name != port_names[0]:
- print()
- print("// For %s" % port_name)
- port = tool.port_factory.get(port_name)
- for test_name in tests:
- self._print_baselines(options, port_name, test_name, port.expected_baselines_by_extension(test_name))
-
- def _print_baselines(self, options, port_name, test_name, baselines):
- for extension in sorted(baselines.keys()):
- baseline_location = baselines[extension]
- if baseline_location:
- print(baseline_location)
-
- def _platform_for_path(self, relpath):
- platform_matchobj = self._platform_regexp.match(relpath)
- if platform_matchobj:
- return platform_matchobj.group(1)
- return None
-
-
-@DeprecatedCommand
-class FindResolvedBugs(Command):
- name = "find-resolved-bugs"
- help_text = "Collect the RESOLVED bugs in the given TestExpectations file"
- argument_names = "TEST_EXPECTATIONS_FILE"
-
- def execute(self, options, args, tool):
- filename = args[0]
- if not tool.filesystem.isfile(filename):
- print("The given path is not a file, please pass a valid path.")
- return
-
- ids = set()
- inputfile = tool.filesystem.open_text_file_for_reading(filename)
- for line in inputfile:
- result = re.search(r"(https://bugs\.webkit\.org/show_bug\.cgi\?id=|webkit\.org/b/)([0-9]+)", line)
- if result:
- ids.add(result.group(2))
- inputfile.close()
-
- resolved_ids = set()
- num_of_bugs = len(ids)
- bugzilla = Bugzilla()
- for i, bugid in enumerate(ids, start=1):
- bug = bugzilla.fetch_bug(bugid)
- print("Checking bug %s \t [%d/%d]" % (bugid, i, num_of_bugs))
- if not bug.is_open():
- resolved_ids.add(bugid)
-
- print("Resolved bugs in %s :" % (filename))
- for bugid in resolved_ids:
- print("https://bugs.webkit.org/show_bug.cgi?id=%s" % (bugid))
</del></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommandsqueries_unittestpy"></a>
<div class="delfile"><h4>Deleted: trunk/Tools/Scripts/webkitpy/tool/commands/queries_unittest.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/queries_unittest.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/queries_unittest.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -1,265 +0,0 @@
</span><del>-# Copyright (C) 2009 Google Inc. All rights reserved.
-# Copyright (C) 2012 Intel Corporation. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * 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.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-# OWNER OR 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 unittest
-
-from webkitpy.common.net.bugzilla import Bugzilla
-from webkitpy.thirdparty.mock import Mock
-from webkitpy.port.test import TestPort
-from webkitpy.tool.commands.commandtest import CommandsTest
-from webkitpy.tool.commands.queries import *
-from webkitpy.tool.mocktool import MockTool, MockOptions
-
-from webkitcorepy import OutputCapture
-
-
-class MockTestPort1(object):
- def skips_layout_test(self, test_name):
- return test_name in ["media/foo/bar.html", "foo"]
-
-
-class MockTestPort2(object):
- def skips_layout_test(self, test_name):
- return test_name == "media/foo/bar.html"
-
-
-class MockPortFactory(object):
- def __init__(self):
- self._all_ports = {
- "test_port1": MockTestPort1(),
- "test_port2": MockTestPort2(),
- }
-
- def all_port_names(self, options=None):
- return self._all_ports.keys()
-
- def get(self, port_name):
- return self._all_ports.get(port_name)
-
-
-class QueryCommandsTest(CommandsTest):
- def test_bugs_to_commit(self):
- expected_logs = "Warning, attachment 10001 on bug 50000 has invalid committer (non-committer@example.com)\n"
- self.assert_execute_outputs(BugsToCommit(), None, "50000\n50003\n", expected_logs=expected_logs)
-
- def test_patches_in_commit_queue(self):
- expected_stdout = "http://example.com/10000\nhttp://example.com/10002\n"
- expected_logs = "Warning, attachment 10001 on bug 50000 has invalid committer (non-committer@example.com)\nPatches in commit queue:\n"
- self.assert_execute_outputs(PatchesInCommitQueue(), None, expected_stdout, expected_logs=expected_logs)
-
- def test_patches_to_commit_queue(self):
- expected_stdout = "http://example.com/10003&action=edit\n"
- expected_logs = "10000 already has cq=+\n10001 already has cq=+\n10004 committer = \"Alexey Proskuryakov\" <ap@webkit.org>\n"
- options = Mock()
- options.bugs = False
- self.assert_execute_outputs(PatchesToCommitQueue(), None, expected_stdout, expected_logs=expected_logs, options=options)
-
- expected_stdout = "http://example.com/50003\n"
- options.bugs = True
- self.assert_execute_outputs(PatchesToCommitQueue(), None, expected_stdout, expected_logs=expected_logs, options=options)
-
- def test_patches_to_review(self):
- options = Mock()
-
- # When no cc_email is provided, we use the Bugzilla username by default.
- # The MockBugzilla will fake the authentication using username@webkit.org
- # as login and it should match the username at the report header.
- options.cc_email = None
- options.include_cq_denied = False
- options.all = False
- expected_stdout = \
- "Bugs with attachments pending review that has username@webkit.org in the CC list:\n" \
- "http://webkit.org/b/bugid Description (age in days)\n" \
- "Total: 0\n"
- expected_stderr = ""
- self.assert_execute_outputs(PatchesToReview(), None, expected_stdout, expected_stderr, options=options)
-
- options.cc_email = "abarth@webkit.org"
- options.include_cq_denied = True
- options.all = False
- expected_stdout = \
- "Bugs with attachments pending review that has abarth@webkit.org in the CC list:\n" \
- "http://webkit.org/b/bugid Description (age in days)\n" \
- "http://webkit.org/b/50001 Bug with a patch needing review. (0)\n" \
- "Total: 1\n"
- expected_stderr = ""
- self.assert_execute_outputs(PatchesToReview(), None, expected_stdout, expected_stderr, options=options)
-
- options.cc_email = None
- options.include_cq_denied = True
- options.all = True
- expected_stdout = \
- "Bugs with attachments pending review:\n" \
- "http://webkit.org/b/bugid Description (age in days)\n" \
- "http://webkit.org/b/50001 Bug with a patch needing review. (0)\n" \
- "Total: 1\n"
- self.assert_execute_outputs(PatchesToReview(), None, expected_stdout, expected_stderr, options=options)
-
- options.cc_email = None
- options.include_cq_denied = False
- options.all = True
- expected_stdout = \
- "Bugs with attachments pending review:\n" \
- "http://webkit.org/b/bugid Description (age in days)\n" \
- "Total: 0\n"
- self.assert_execute_outputs(PatchesToReview(), None, expected_stdout, expected_stderr, options=options)
-
- options.cc_email = "invalid_email@example.com"
- options.all = False
- options.include_cq_denied = True
- expected_stdout = \
- "Bugs with attachments pending review that has invalid_email@example.com in the CC list:\n" \
- "http://webkit.org/b/bugid Description (age in days)\n" \
- "Total: 0\n"
- self.assert_execute_outputs(PatchesToReview(), None, expected_stdout, expected_stderr, options=options)
-
- def test_tree_status(self):
- expected_stdout = "ok : Builder1\nok : Builder2\n"
- self.assert_execute_outputs(TreeStatus(), None, expected_stdout)
-
-
-class FailureReasonTest(unittest.TestCase):
- def test_blame_line_for_revision(self):
- tool = MockTool()
- command = FailureReason()
- command.bind_to_tool(tool)
- # This is an artificial example, mostly to test the CommitInfo lookup failure case.
- self.assertEqual(command._blame_line_for_revision(0), "FAILED to fetch CommitInfo for r0, likely missing ChangeLog")
-
- def raising_mock(self):
- raise Exception("MESSAGE")
- tool.checkout().commit_info_for_revision = raising_mock
- self.assertEqual(command._blame_line_for_revision(0), "FAILED to fetch CommitInfo for r0, exception: MESSAGE")
-
-
-class PrintExpectationsTest(unittest.TestCase):
- def run_test(self, tests, expected_stdout, platform='test-win-xp', **args):
- options = MockOptions(all=False, full=False, platform=platform,
- include_keyword=[], exclude_keyword=[], paths=False).update(**args)
- tool = MockTool()
- tool.port_factory.all_port_names = lambda: TestPort.ALL_BASELINE_VARIANTS
- command = PrintExpectations()
- command.bind_to_tool(tool)
-
- with OutputCapture() as captured:
- command.execute(options, tests, tool)
- self.assertMultiLineEqual(captured.stdout.getvalue(), expected_stdout)
-
- def test_basic(self):
- self.run_test(['failures/expected/text.html', 'failures/expected/image.html'],
- ('// For test-win-xp\n'
- 'failures/expected/image.html [ ImageOnlyFailure ]\n'
- 'failures/expected/text.html [ Failure ]\n'))
-
- def test_multiple(self):
- self.run_test(['failures/expected/text.html', 'failures/expected/image.html'],
- ('// For test-win-vista\n'
- 'failures/expected/image.html [ ImageOnlyFailure ]\n'
- 'failures/expected/text.html [ Failure ]\n'
- '\n'
- '// For test-win-7sp0\n'
- 'failures/expected/image.html [ ImageOnlyFailure ]\n'
- 'failures/expected/text.html [ Failure ]\n'
- '\n'
- '// For test-win-xp\n'
- 'failures/expected/image.html [ ImageOnlyFailure ]\n'
- 'failures/expected/text.html [ Failure ]\n'),
- platform='test-win-*')
-
- def test_full(self):
- self.run_test(['failures/expected/text.html', 'failures/expected/image.html'],
- ('// For test-win-xp\n'
- 'Bug(test) failures/expected/image.html [ ImageOnlyFailure ]\n'
- 'Bug(test) failures/expected/text.html [ Failure ]\n'),
- full=True)
-
- def test_exclude(self):
- self.run_test(['failures/expected/text.html', 'failures/expected/image.html'],
- ('// For test-win-xp\n'
- 'failures/expected/text.html [ Failure ]\n'),
- exclude_keyword=['image'])
-
- def test_include(self):
- self.run_test(['failures/expected/text.html', 'failures/expected/image.html'],
- ('// For test-win-xp\n'
- 'failures/expected/image.html\n'),
- include_keyword=['image'])
-
- def test_paths(self):
- self.run_test([],
- ('LayoutTests/TestExpectations\n'
- 'LayoutTests/platform/test/TestExpectations\n'
- 'LayoutTests/platform/test-win-xp/TestExpectations\n'),
- paths=True)
-
- def test_platform(self):
- self.run_test(['platform/test-mac-leopard/http/test.html'],
- ('// For test-mac-snowleopard\n'
- 'platform/test-mac-leopard [ Pass Skip WontFix ]\n' # Note that this is the expectation (from being skipped internally), not the test name
- '\n'
- '// For test-mac-leopard\n'
- 'platform/test-mac-leopard/http/test.html [ Pass ]\n'),
- platform='test-mac-*')
-
-
-class PrintBaselinesTest(unittest.TestCase):
- def setUp(self):
- self.oc = None
- self.tool = MockTool()
- self.test_port = self.tool.port_factory.get('test-win-xp')
- self.tool.port_factory.get = lambda port_name=None: self.test_port
- self.tool.port_factory.all_port_names = lambda: TestPort.ALL_BASELINE_VARIANTS
-
- def test_basic(self):
- command = PrintBaselines()
- command.bind_to_tool(self.tool)
- with OutputCapture() as captured:
- command.execute(MockOptions(all=False, platform=None), ['passes/text.html'], self.tool)
- self.assertMultiLineEqual(captured.stdout.getvalue(),
- ('// For test-win-xp\n'
- 'passes/text-expected.png\n'
- 'passes/text-expected.txt\n'))
-
- def test_multiple(self):
- command = PrintBaselines()
- command.bind_to_tool(self.tool)
- with OutputCapture() as captured:
- command.execute(MockOptions(all=False, platform='test-win-*'), ['passes/text.html'], self.tool)
- self.assertMultiLineEqual(captured.stdout.getvalue(),
- ('// For test-win-vista\n'
- 'passes/text-expected.png\n'
- 'passes/text-expected.txt\n'
- '\n'
- '// For test-win-7sp0\n'
- 'passes/text-expected.png\n'
- 'passes/text-expected.txt\n'
- '\n'
- '// For test-win-xp\n'
- 'passes/text-expected.png\n'
- 'passes/text-expected.txt\n'))
</del></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommandsrebaselinepy"></a>
<div class="delfile"><h4>Deleted: trunk/Tools/Scripts/webkitpy/tool/commands/rebaseline.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/rebaseline.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/rebaseline.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -1,432 +0,0 @@
</span><del>-# Copyright (c) 2010 Google 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:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * 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.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-# OWNER OR 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.
-
-from __future__ import print_function
-import json
-import logging
-import optparse
-import sys
-
-from webkitpy.common.system.executive import ScriptError
-from webkitpy.layout_tests.controllers.test_result_writer import TestResultWriter
-from webkitpy.layout_tests.models import test_failures
-from webkitpy.layout_tests.models.test_expectations import TestExpectations, BASELINE_SUFFIX_LIST
-from webkitpy.port import builders
-from webkitpy.port import factory
-from webkitpy.tool.commands.deprecatedcommand import DeprecatedCommand
-from webkitpy.tool.multicommandtool import Command
-
-
-_log = logging.getLogger(__name__)
-
-
-# FIXME: Should TestResultWriter know how to compute this string?
-def _baseline_name(fs, test_name, suffix):
- return fs.splitext(test_name)[0] + TestResultWriter.FILENAME_SUFFIX_EXPECTED + "." + suffix
-
-
-class AbstractRebaseliningCommand(Command):
- # not overriding execute() - pylint: disable=W0223
-
- move_overwritten_baselines_option = optparse.make_option("--move-overwritten-baselines", action="store_true", default=False,
- help="Move overwritten baselines elsewhere in the baseline path. This is for bringing up new ports.")
-
- no_optimize_option = optparse.make_option('--no-optimize', dest='optimize', action='store_false', default=True,
- help=('Do not optimize/de-dup the expectations after rebaselining (default is to de-dup automatically). '
- 'You can use "webkit-patch optimize-baselines" to optimize separately.'))
-
- update_expectations_option = optparse.make_option('--update-expectations', dest='update_expectations', action='store_true',
- default=False, help=('Update test expectations.'))
-
- platform_options = factory.platform_options(use_globs=True)
-
- results_directory_option = optparse.make_option("--results-directory", help="Local results directory to use")
-
- suffixes_option = optparse.make_option("--suffixes", default=','.join(BASELINE_SUFFIX_LIST), action="store",
- help="Comma-separated-list of file types to rebaseline")
-
- def __init__(self, options=None):
- super(AbstractRebaseliningCommand, self).__init__(options=options)
- self._baseline_suffix_list = BASELINE_SUFFIX_LIST
-
-
-@DeprecatedCommand
-class RebaselineTest(AbstractRebaseliningCommand):
- name = "rebaseline-test-internal"
- help_text = "Rebaseline a single test from a buildbot. Only intended for use by other webkit-patch commands."
-
- def __init__(self):
- super(RebaselineTest, self).__init__(options=[
- self.no_optimize_option,
- self.results_directory_option,
- self.suffixes_option,
- self.update_expectations_option,
- optparse.make_option("--builder", help="Builder to pull new baselines from"),
- optparse.make_option("--move-overwritten-baselines-to", action="append", default=[],
- help="Platform to move existing baselines to before rebaselining. This is for bringing up new ports."),
- optparse.make_option("--test", help="Test to rebaseline"),
- ])
- self._scm_changes = {'add': []}
-
- def _results_url(self, builder_name):
- return self._tool.buildbot.builder_with_name(builder_name).latest_layout_test_results_url()
-
- def _baseline_directory(self, builder_name):
- port = self._tool.port_factory.get_from_builder_name(builder_name)
- override_dir = builders.rebaseline_override_dir(builder_name)
- if override_dir:
- return self._tool.filesystem.join(port.layout_tests_dir(), 'platform', override_dir)
- return port.baseline_version_dir()
-
- def _copy_existing_baseline(self, move_overwritten_baselines_to, test_name, suffix):
- old_baselines = []
- new_baselines = []
-
- # Need to gather all the baseline paths before modifying the filesystem since
- # the modifications can affect the results of port.expected_filename.
- for platform in move_overwritten_baselines_to:
- port = self._tool.port_factory.get(platform)
- old_baseline = port.expected_filename(test_name, "." + suffix)
- if not self._tool.filesystem.exists(old_baseline):
- _log.debug("No existing baseline for %s." % test_name)
- continue
-
- new_baseline = self._tool.filesystem.join(port.baseline_path(), self._file_name_for_expected_result(test_name, suffix))
- if self._tool.filesystem.exists(new_baseline):
- _log.debug("Existing baseline at %s, not copying over it." % new_baseline)
- continue
-
- old_baselines.append(old_baseline)
- new_baselines.append(new_baseline)
-
- for i in range(len(old_baselines)):
- old_baseline = old_baselines[i]
- new_baseline = new_baselines[i]
-
- _log.debug("Copying baseline from %s to %s." % (old_baseline, new_baseline))
- self._tool.filesystem.maybe_make_directory(self._tool.filesystem.dirname(new_baseline))
- self._tool.filesystem.copyfile(old_baseline, new_baseline)
- if not self._tool.scm().exists(new_baseline):
- self._add_to_scm(new_baseline)
-
- def _save_baseline(self, data, target_baseline):
- if not data:
- return
- filesystem = self._tool.filesystem
- filesystem.maybe_make_directory(filesystem.dirname(target_baseline))
- filesystem.write_binary_file(target_baseline, data)
- if not self._tool.scm().exists(target_baseline):
- self._add_to_scm(target_baseline)
-
- def _add_to_scm(self, path):
- self._scm_changes['add'].append(path)
-
- def _update_expectations_file(self, builder_name, test_name):
- port = self._tool.port_factory.get_from_builder_name(builder_name)
-
- # Since rebaseline-test-internal can be called multiple times in parallel,
- # we need to ensure that we're not trying to update the expectations file
- # concurrently as well.
- # FIXME: We should rework the code to not need this; maybe just download
- # the files in parallel and rebaseline local files serially?
- path = port.path_to_test_expectations_file()
- with self._tool.make_file_lock(path + '.lock') as lock:
- if not lock.acquired:
- raise OSError('Failed to aquire rebaseline lock for {}'.format(path))
-
- expectations = TestExpectations(port, include_generic=False, include_overrides=False)
- expectations.parse_all_expectations()
- for test_configuration in port.all_test_configurations():
- if test_configuration.version == port.test_configuration().version:
- expectationsString = expectations.remove_configuration_from_test(test_name, test_configuration)
-
- self._tool.filesystem.write_text_file(path, expectationsString)
-
- def _test_root(self, test_name):
- return self._tool.filesystem.splitext(test_name)[0]
-
- def _file_name_for_actual_result(self, test_name, suffix):
- return "%s-actual.%s" % (self._test_root(test_name), suffix)
-
- def _file_name_for_expected_result(self, test_name, suffix):
- return "%s-expected.%s" % (self._test_root(test_name), suffix)
-
- def _rebaseline_test(self, builder_name, test_name, move_overwritten_baselines_to, suffix, results_url):
- baseline_directory = self._baseline_directory(builder_name)
-
- source_baseline = "%s/%s" % (results_url, self._file_name_for_actual_result(test_name, suffix))
- target_baseline = self._tool.filesystem.join(baseline_directory, self._file_name_for_expected_result(test_name, suffix))
-
- if move_overwritten_baselines_to:
- self._copy_existing_baseline(move_overwritten_baselines_to, test_name, suffix)
-
- _log.debug("Retrieving %s." % source_baseline)
- self._save_baseline(self._tool.web.get_binary(source_baseline, convert_404_to_None=True), target_baseline)
-
- def _rebaseline_tests(self, options):
- if options.results_directory:
- results_url = 'file://' + options.results_directory
- else:
- results_url = self._results_url(options.builder)
- self._baseline_suffix_list = options.suffixes.split(',')
- for suffix in self._baseline_suffix_list:
- self._rebaseline_test(options.builder, options.test, options.move_overwritten_baselines_to, suffix, results_url)
-
- def execute(self, options, args, tool):
- self._rebaseline_tests(options)
- if options.update_expectations:
- self._update_expectations_file(options.builder, options.test)
- print(json.dumps(self._scm_changes))
-
-
-class AbstractParallelRebaselineCommand(AbstractRebaseliningCommand):
- # not overriding execute() - pylint: disable=W0223
-
- def _run_webkit_patch(self, args, verbose):
- try:
- verbose_args = ['--verbose'] if verbose else []
- stderr = self._tool.executive.run_command([self._tool.path()] + verbose_args + args, cwd=self._tool.scm().checkout_root, return_stderr=True)
- for line in stderr.splitlines():
- print(line, file=sys.stderr)
- except ScriptError as e:
- _log.error(e)
-
- def _builders_to_fetch_from(self, builders_to_check):
- # This routine returns the subset of builders that will cover all of the baseline search paths
- # used in the input list. In particular, if the input list contains both Release and Debug
- # versions of a configuration, we *only* return the Release version (since we don't save
- # debug versions of baselines).
- release_builders = set()
- debug_builders = set()
- builders_to_fallback_paths = {}
- for builder in builders_to_check:
- port = self._tool.port_factory.get_from_builder_name(builder)
- if port.test_configuration().build_type == 'Release':
- release_builders.add(builder)
- else:
- debug_builders.add(builder)
- for builder in list(release_builders) + list(debug_builders):
- port = self._tool.port_factory.get_from_builder_name(builder)
- fallback_path = port.baseline_search_path()
- if fallback_path not in builders_to_fallback_paths.values():
- builders_to_fallback_paths[builder] = fallback_path
- return builders_to_fallback_paths.keys()
-
- def _rebaseline_commands(self, test_list, options):
-
- path_to_webkit_patch = self._tool.path()
- cwd = self._tool.scm().checkout_root
- commands = []
- for test in test_list:
- for builder in self._builders_to_fetch_from(test_list[test]):
- suffixes = ','.join(test_list[test][builder])
- cmd_line = [path_to_webkit_patch, 'rebaseline-test-internal', '--suffixes', suffixes, '--builder', builder, '--test', test]
- if options.move_overwritten_baselines:
- move_overwritten_baselines_to = builders.move_overwritten_baselines_to(builder)
- for platform in move_overwritten_baselines_to:
- cmd_line.extend(['--move-overwritten-baselines-to', platform])
- if options.results_directory:
- cmd_line.extend(['--results-directory', options.results_directory])
- if options.update_expectations:
- cmd_line.extend(['--update-expectations', options.update_expectations and 'True' or 'False'])
- if options.verbose:
- cmd_line.append('--verbose')
- commands.append(tuple([cmd_line, cwd]))
- return commands
-
- def _files_to_add(self, command_results):
- files_to_add = set()
- for output in [result[1].split('\n') for result in command_results]:
- file_added = False
- for line in output:
- try:
- if line:
- files_to_add.update(json.loads(line)['add'])
- file_added = True
- except ValueError:
- _log.debug('"%s" is not a JSON object, ignoring' % line)
-
- if not file_added:
- _log.debug('Could not add file based off output "%s"' % output)
-
- return list(files_to_add)
-
- def _rebaseline(self, options, test_list):
- for test, builders_to_check in sorted(test_list.items()):
- _log.info("Rebaselining %s" % test)
- for builder, suffixes in sorted(builders_to_check.items()):
- _log.debug(" %s: %s" % (builder, ",".join(suffixes)))
-
- commands = self._rebaseline_commands(test_list, options)
- command_results = self._tool.executive.run_in_parallel(commands)
-
- log_output = '\n'.join(result[2] for result in command_results).replace('\n\n', '\n')
- for line in log_output.split('\n'):
- if line:
- print(line, file=sys.stderr) # FIXME: Figure out how to log properly.
-
- files_to_add = self._files_to_add(command_results)
- if files_to_add:
- self._tool.scm().add_list(list(files_to_add))
-
-
-@DeprecatedCommand
-class RebaselineJson(AbstractParallelRebaselineCommand):
- name = "rebaseline-json"
- help_text = "Rebaseline based off JSON passed to stdin. Intended to only be called from other scripts."
-
- def __init__(self,):
- super(RebaselineJson, self).__init__(options=[
- self.move_overwritten_baselines_option,
- self.no_optimize_option,
- self.results_directory_option,
- ])
-
- def execute(self, options, args, tool):
- self._rebaseline(options, json.loads(sys.stdin.read()))
-
-
-@DeprecatedCommand
-class RebaselineExpectations(AbstractParallelRebaselineCommand):
- name = "rebaseline-expectations"
- help_text = "Rebaselines the tests indicated in TestExpectations."
-
- def __init__(self):
- super(RebaselineExpectations, self).__init__(options=[
- self.move_overwritten_baselines_option,
- self.no_optimize_option,
- self.update_expectations_option,
- ] + self.platform_options)
- self._test_list = None
-
- def _update_expectations_files(self, port_name):
- port = self._tool.port_factory.get(port_name)
-
- expectations = TestExpectations(port)
- expectations.parse_all_expectations()
- for path in port.expectations_dict():
- if self._tool.filesystem.exists(path):
- self._tool.filesystem.write_text_file(path, expectations.remove_rebaselined_tests(expectations.get_rebaselining_failures(), path))
-
- def _tests_to_rebaseline(self, port):
- tests_to_rebaseline = {}
- expectations = TestExpectations(port, include_overrides=True)
- expectations.parse_all_expectations()
- for test in expectations.get_rebaselining_failures():
- tests_to_rebaseline[test] = TestExpectations.suffixes_for_expectations(expectations.model().get_expectations(test))
- return tests_to_rebaseline
-
- def _add_tests_to_rebaseline_for_port(self, port_name):
- builder_name = builders.builder_name_for_port_name(port_name)
- if not builder_name:
- return
- tests = self._tests_to_rebaseline(self._tool.port_factory.get(port_name)).items()
-
- if tests:
- _log.info("Retrieving results for %s from %s." % (port_name, builder_name))
-
- for test_name, suffixes in tests:
- _log.info(" %s (%s)" % (test_name, ','.join(suffixes)))
- if test_name not in self._test_list:
- self._test_list[test_name] = {}
- self._test_list[test_name][builder_name] = suffixes
-
- def execute(self, options, args, tool):
- options.results_directory = None
- self._test_list = {}
- port_names = tool.port_factory.all_port_names(options.platform)
- for port_name in port_names:
- self._add_tests_to_rebaseline_for_port(port_name)
- if not self._test_list:
- _log.warning("Did not find any tests marked Rebaseline.")
- return
-
- self._rebaseline(options, self._test_list)
-
- if options.update_expectations:
- for port_name in port_names:
- self._update_expectations_files(port_name)
-
-
-@DeprecatedCommand
-class Rebaseline(AbstractParallelRebaselineCommand):
- name = "rebaseline"
- help_text = "Rebaseline tests with results from the build bots. Shows the list of failing tests on the builders if no test names are provided."
- argument_names = "[TEST_NAMES]"
-
- def __init__(self):
- super(Rebaseline, self).__init__(options=[
- self.move_overwritten_baselines_option,
- self.no_optimize_option,
- self.update_expectations_option,
- # FIXME: should we support the platform options in addition to (or instead of) --builders?
- self.suffixes_option,
- optparse.make_option("--builders", default=None, action="append", help="Comma-separated-list of builders to pull new baselines from (can also be provided multiple times)"),
- ])
-
- def _builders_to_pull_from(self):
- webkit_buildbot_builder_names = []
- for name in builders.all_builder_names():
- webkit_buildbot_builder_names.append(name)
-
- titles = ["build.webkit.org bots"]
- lists = [webkit_buildbot_builder_names]
-
- chosen_names = self._tool.user.prompt_with_multiple_lists("Which builder to pull results from:", titles, lists, can_choose_multiple=True)
- return [self._builder_with_name(name) for name in chosen_names]
-
- def _builder_with_name(self, name):
- return self._tool.buildbot.builder_with_name(name)
-
- def _tests_to_update(self, builder):
- failing_tests = builder.latest_layout_test_results().tests_matching_failure_types([test_failures.FailureTextMismatch])
- return self._tool.user.prompt_with_list("Which test(s) to rebaseline for %s:" % builder.name(), failing_tests, can_choose_multiple=True)
-
- def execute(self, options, args, tool):
- options.results_directory = None
- if options.builders:
- builders_to_check = []
- for builder_names in options.builders:
- builders_to_check += [self._builder_with_name(name) for name in builder_names.split(",")]
- else:
- builders_to_check = self._builders_to_pull_from()
-
- test_list = {}
- suffixes_to_update = options.suffixes.split(",")
-
- for builder in builders_to_check:
- tests = args or self._tests_to_update(builder)
- for test in tests:
- if test not in test_list:
- test_list[test] = {}
- test_list[test][builder.name()] = suffixes_to_update
-
- if options.verbose:
- _log.debug("rebaseline-json: " + str(test_list))
-
- self._rebaseline(options, test_list)
</del></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommandsrebaseline_unittestpy"></a>
<div class="delfile"><h4>Deleted: trunk/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -1,347 +0,0 @@
</span><del>-# Copyright (C) 2010 Google Inc. All rights reserved.
-# Copyright (C) 2013 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:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * 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.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-# OWNER OR 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 unittest
-
-from webkitpy.common.net.buildbot.buildbot_mock import MockBuilder
-from webkitpy.common.system.executive_mock import MockExecutive2
-from webkitpy.thirdparty.mock import Mock
-from webkitpy.tool.commands.rebaseline import *
-from webkitpy.tool.mocktool import MockTool, MockOptions
-
-from webkitcorepy import OutputCapture
-
-
-class _BaseTestCase(unittest.TestCase):
- MOCK_WEB_RESULT = 'MOCK Web result, convert 404 to None=True'
- WEB_PREFIX = 'http://example.com/f/builders/Apple Lion Release WK1 (Tests)/results/layout-test-results'
-
- command_constructor = None
-
- def setUp(self):
- self.tool = MockTool()
- self.command = self.command_constructor() # lint warns that command_constructor might not be set, but this is intentional; pylint: disable=E1102
- self.command.bind_to_tool(self.tool)
- self.lion_port = self.tool.port_factory.get_from_builder_name("Apple Lion Release WK1 (Tests)")
- self.lion_expectations_path = self.lion_port.path_to_test_expectations_file()
-
- # FIXME: we should override builders._exact_matches here to point to a set
- # of test ports and restore the value in tearDown(), and that way the
- # individual tests wouldn't have to worry about it.
-
- def _expand(self, path):
- if self.tool.filesystem.isabs(path):
- return path
- return self.tool.filesystem.join(self.lion_port.layout_tests_dir(), path)
-
- def _read(self, path):
- return self.tool.filesystem.read_text_file(self._expand(path))
-
- def _write(self, path, contents):
- self.tool.filesystem.write_text_file(self._expand(path), contents)
-
- def _zero_out_test_expectations(self):
- for port_name in self.tool.port_factory.all_port_names():
- port = self.tool.port_factory.get(port_name)
- for path in port.expectations_files():
- self._write(path, '')
- self.tool.filesystem.written_files = {}
-
-
-class TestRebaselineTest(_BaseTestCase):
- command_constructor = RebaselineTest # AKA webkit-patch rebaseline-test-internal
-
- def setUp(self):
- super(TestRebaselineTest, self).setUp()
- self.options = MockOptions(builder="Apple Lion Release WK1 (Tests)", test="userscripts/another-test.html", suffixes="txt",
- move_overwritten_baselines_to=None, results_directory=None, update_expectations=True)
-
- def test_baseline_directory(self):
- command = self.command
- self.assertMultiLineEqual(command._baseline_directory("Apple Win XP Debug (Tests)"), "/mock-checkout/LayoutTests/platform/win-xp")
- self.assertMultiLineEqual(command._baseline_directory("Apple Win 7 Release (Tests)"), "/mock-checkout/LayoutTests/platform/win")
- self.assertMultiLineEqual(command._baseline_directory("Apple Lion Release WK1 (Tests)"), "/mock-checkout/LayoutTests/platform/mac-lion-wk1")
- self.assertMultiLineEqual(command._baseline_directory("Apple Lion Release WK2 (Tests)"), "/mock-checkout/LayoutTests/platform/mac-lion-wk2")
- self.assertMultiLineEqual(command._baseline_directory("Apple MountainLion Release WK1 (Tests)"), "/mock-checkout/LayoutTests/platform/mac-mountainlion-wk1")
- self.assertMultiLineEqual(command._baseline_directory("Apple MountainLion Release WK2 (Tests)"), "/mock-checkout/LayoutTests/platform/mac-mountainlion-wk2")
- self.assertMultiLineEqual(command._baseline_directory("Apple Mavericks Release WK1 (Tests)"), "/mock-checkout/LayoutTests/platform/mac-mavericks-wk1")
- self.assertMultiLineEqual(command._baseline_directory("Apple Mavericks Release WK2 (Tests)"), "/mock-checkout/LayoutTests/platform/mac-mavericks-wk2")
- self.assertMultiLineEqual(command._baseline_directory("Apple Yosemite Release WK1 (Tests)"), "/mock-checkout/LayoutTests/platform/mac-yosemite-wk1")
- self.assertMultiLineEqual(command._baseline_directory("Apple Yosemite Release WK2 (Tests)"), "/mock-checkout/LayoutTests/platform/mac-yosemite-wk2")
- self.assertMultiLineEqual(command._baseline_directory("GTK Linux 64-bit Debug (Tests)"), "/mock-checkout/LayoutTests/platform/gtk")
- self.assertMultiLineEqual(command._baseline_directory("GTK Linux 64-bit Release (Tests)"), "/mock-checkout/LayoutTests/platform/gtk")
-
- def test_rebaseline_updates_expectations_file_noop(self):
- self._zero_out_test_expectations()
- self._write(self.lion_expectations_path, """Bug(B) [ Mac Linux XP Debug ] fast/dom/Window/window-postmessage-clone-really-deep-array.html [ Pass ]
-Bug(A) [ Debug ] : fast/css/large-list-of-rules-crash.html [ Failure ]
-""")
- self._write("fast/dom/Window/window-postmessage-clone-really-deep-array.html", "Dummy test contents")
- self._write("fast/css/large-list-of-rules-crash.html", "Dummy test contents")
- self._write("userscripts/another-test.html", "Dummy test contents")
-
- self.options.suffixes = "png,wav,txt"
- self.command._rebaseline_tests(self.options)
-
- self.assertEquals(
- sorted(self.tool.web.urls_fetched), [
- self.WEB_PREFIX + '/userscripts/another-test-actual.png',
- self.WEB_PREFIX + '/userscripts/another-test-actual.txt',
- self.WEB_PREFIX + '/userscripts/another-test-actual.wav',
- ])
- new_expectations = self._read(self.lion_expectations_path)
- self.assertMultiLineEqual(new_expectations, """Bug(B) [ Mac Linux XP Debug ] fast/dom/Window/window-postmessage-clone-really-deep-array.html [ Pass ]
-Bug(A) [ Debug ] : fast/css/large-list-of-rules-crash.html [ Failure ]
-""")
-
- def test_rebaseline_updates_expectations_file(self):
- self._write(self.lion_expectations_path, "Bug(x) [ Mac ] userscripts/another-test.html [ ImageOnlyFailure ]\nbug(z) [ Linux ] userscripts/another-test.html [ ImageOnlyFailure ]\n")
- self._write("userscripts/another-test.html", "Dummy test contents")
-
- self.options.suffixes = 'png,wav,txt'
- self.command._rebaseline_tests(self.options)
-
- self.assertEquals(
- sorted(self.tool.web.urls_fetched), [
- self.WEB_PREFIX + '/userscripts/another-test-actual.png',
- self.WEB_PREFIX + '/userscripts/another-test-actual.txt',
- self.WEB_PREFIX + '/userscripts/another-test-actual.wav',
- ])
- new_expectations = self._read(self.lion_expectations_path)
- self.assertMultiLineEqual(new_expectations, "Bug(x) [ Mac ] userscripts/another-test.html [ ImageOnlyFailure ]\nbug(z) [ Linux ] userscripts/another-test.html [ ImageOnlyFailure ]\n")
-
- def test_rebaseline_does_not_include_overrides(self):
- self._write(self.lion_expectations_path, "Bug(x) [ Mac ] userscripts/another-test.html [ ImageOnlyFailure ]\nBug(z) [ Linux ] userscripts/another-test.html [ ImageOnlyFailure ]\n")
- self._write("userscripts/another-test.html", "Dummy test contents")
-
- self.options.suffixes = 'png,wav,txt'
- self.command._rebaseline_tests(self.options)
-
- self.assertEquals(
- sorted(self.tool.web.urls_fetched), [
- self.WEB_PREFIX + '/userscripts/another-test-actual.png',
- self.WEB_PREFIX + '/userscripts/another-test-actual.txt',
- self.WEB_PREFIX + '/userscripts/another-test-actual.wav',
- ])
-
- new_expectations = self._read(self.lion_expectations_path)
- self.assertMultiLineEqual(new_expectations, "Bug(x) [ Mac ] userscripts/another-test.html [ ImageOnlyFailure ]\nBug(z) [ Linux ] userscripts/another-test.html [ ImageOnlyFailure ]\n")
-
- def test_rebaseline_test(self):
- self.command._rebaseline_test("Apple Lion Release WK1 (Tests)", "userscripts/another-test.html", None, "txt", self.WEB_PREFIX)
- self.assertEquals(self.tool.web.urls_fetched, [self.WEB_PREFIX + '/userscripts/another-test-actual.txt'])
-
- def test_rebaseline_test_with_results_directory(self):
- self._write(self.lion_expectations_path, "Bug(x) [ Mac ] userscripts/another-test.html [ ImageOnlyFailure ]\nbug(z) [ Linux ] userscripts/another-test.html [ ImageOnlyFailure ]\n")
- self.options.results_directory = '/tmp'
- self.command._rebaseline_tests(self.options)
- self.assertEquals(self.tool.web.urls_fetched, ['file:///tmp/userscripts/another-test-actual.txt'])
-
- def test_rebaseline_test_and_print_scm_changes(self):
- self.command._print_scm_changes = True
- self.command._scm_changes = {'add': [], 'delete': []}
- self.tool._scm.exists = lambda x: False
-
- self.command._rebaseline_test("Apple Lion Release WK1 (Tests)", "userscripts/another-test.html", None, "txt", None)
-
- self.assertDictEqual(self.command._scm_changes, {'add': ['/mock-checkout/LayoutTests/platform/mac-lion-wk1/userscripts/another-test-expected.txt'], 'delete': []})
-
- def test_rebaseline_and_copy_test(self):
- self._write("userscripts/another-test-expected.txt", "generic result")
-
- self.command._rebaseline_test("Apple Lion Release WK1 (Tests)", "userscripts/another-test.html", ["mac-lion-wk2"], "txt", None)
-
- self.assertMultiLineEqual(self._read('platform/mac-lion-wk1/userscripts/another-test-expected.txt'), self.MOCK_WEB_RESULT)
- self.assertMultiLineEqual(self._read('platform/mac-lion-wk2/userscripts/another-test-expected.txt'), 'generic result')
-
- def test_rebaseline_and_copy_test_no_existing_result(self):
- self.command._rebaseline_test("Apple Lion Release WK1 (Tests)", "userscripts/another-test.html", ["mac-lion-wk2"], "txt", None)
-
- self.assertMultiLineEqual(self._read('platform/mac-lion-wk1/userscripts/another-test-expected.txt'), self.MOCK_WEB_RESULT)
- self.assertFalse(self.tool.filesystem.exists(self._expand('platform/mac-lion-wk2/userscripts/another-test-expected.txt')))
-
- def test_rebaseline_and_copy_test_with_lion_result(self):
- self._write("platform/mac-lion/userscripts/another-test-expected.txt", "original lion result")
-
- self.command._rebaseline_test("Apple Lion Release WK1 (Tests)", "userscripts/another-test.html", ["mac-lion-wk2"], "txt", self.WEB_PREFIX)
-
- self.assertEquals(self.tool.web.urls_fetched, [self.WEB_PREFIX + '/userscripts/another-test-actual.txt'])
- self.assertMultiLineEqual(self._read("platform/mac-lion-wk2/userscripts/another-test-expected.txt"), "original lion result")
- self.assertMultiLineEqual(self._read("platform/mac-lion-wk1/userscripts/another-test-expected.txt"), self.MOCK_WEB_RESULT)
-
- def test_rebaseline_and_copy_no_overwrite_test(self):
- self._write("platform/mac-lion/userscripts/another-test-expected.txt", "original lion result")
- self._write("platform/mac-lion-wk2/userscripts/another-test-expected.txt", "original lion wk2 result")
-
- self.command._rebaseline_test("Apple Lion Release WK1 (Tests)", "userscripts/another-test.html", ["mac-lion-wk2"], "txt", None)
-
- self.assertMultiLineEqual(self._read("platform/mac-lion-wk2/userscripts/another-test-expected.txt"), "original lion wk2 result")
- self.assertMultiLineEqual(self._read("platform/mac-lion-wk1/userscripts/another-test-expected.txt"), self.MOCK_WEB_RESULT)
-
- def test_rebaseline_test_internal_with_move_overwritten_baselines_to(self):
- self.tool.executive = MockExecutive2()
-
- # FIXME: it's confusing that this is the test- port, and not the regular lion port. Really all of the tests should be using the test ports.
- port = self.tool.port_factory.get('test-mac-snowleopard')
- self._write(port._filesystem.join(port.layout_tests_dir(), 'platform/test-mac-snowleopard/failures/expected/image-expected.txt'), 'original snowleopard result')
-
- old_exact_matches = builders._exact_matches
- with OutputCapture() as captured:
- builders._exact_matches = {
- "MOCK Leopard": {"port_name": "test-mac-leopard", "specifiers": {"mock-specifier"}},
- "MOCK SnowLeopard": {"port_name": "test-mac-snowleopard", "specifiers": {"mock-specifier"}},
- }
-
- options = MockOptions(optimize=True, builder="MOCK SnowLeopard", suffixes="txt", move_overwritten_baselines_to=["test-mac-leopard"],
- verbose=True, test="failures/expected/image.html", results_directory=None, update_expectations=True)
-
- self.command.execute(options, [], self.tool)
-
- builders._exact_matches = old_exact_matches
-
- self.assertMultiLineEqual(self._read(self.tool.filesystem.join(port.layout_tests_dir(), 'platform/test-mac-leopard/failures/expected/image-expected.txt')), 'original snowleopard result')
- self.assertMultiLineEqual(captured.stdout.getvalue(), '{"add": []}\n')
-
-
-class TestRebaselineJson(_BaseTestCase):
- command_constructor = RebaselineJson
-
- def setUp(self):
- super(TestRebaselineJson, self).setUp()
- self.tool.executive = MockExecutive2()
- self.old_exact_matches = builders._exact_matches
- builders._exact_matches = {
- "MOCK builder": {"port_name": "test-mac-snowleopard", "specifiers": set(["mock-specifier"]),
- "move_overwritten_baselines_to": ["test-mac-leopard"]},
- "MOCK builder (Debug)": {"port_name": "test-mac-snowleopard", "specifiers": set(["mock-specifier", "debug"])},
- }
-
- def tearDown(self):
- builders._exact_matches = self.old_exact_matches
- super(TestRebaselineJson, self).tearDown()
-
- def test_rebaseline_all(self):
- options = MockOptions(optimize=True, verbose=True, move_overwritten_baselines=False, results_directory=None, update_expectations=True)
- self.command._rebaseline(options, {"user-scripts/another-test.html": {"MOCK builder": ["txt", "png"]}})
-
- def test_rebaseline_debug(self):
- options = MockOptions(optimize=True, verbose=True, move_overwritten_baselines=False, results_directory=None, update_expectations=True)
- self.command._rebaseline(options, {"user-scripts/another-test.html": {"MOCK builder (Debug)": ["txt", "png"]}})
-
- def test_no_optimize(self):
- options = MockOptions(optimize=False, verbose=True, move_overwritten_baselines=False, results_directory=None, update_expectations=True)
- self.command._rebaseline(options, {"user-scripts/another-test.html": {"MOCK builder (Debug)": ["txt", "png"]}})
-
- # Note that we have only one run_in_parallel() call
- self.assertEqual(self.tool.executive.calls, [[['echo', 'rebaseline-test-internal', '--suffixes', 'txt,png', '--builder', 'MOCK builder (Debug)',
- '--test', 'user-scripts/another-test.html', '--update-expectations', 'True', '--verbose']]])
-
- def test_results_directory(self):
- options = MockOptions(optimize=False, verbose=True, move_overwritten_baselines=False, results_directory='/tmp', update_expectations=True)
- self.command._rebaseline(options, {"user-scripts/another-test.html": {"MOCK builder": ["txt", "png"]}})
-
- # Note that we have only one run_in_parallel() call
- self.assertEqual(self.tool.executive.calls, [[['echo', 'rebaseline-test-internal', '--suffixes', 'txt,png', '--builder', 'MOCK builder',
- '--test', 'user-scripts/another-test.html', '--results-directory', '/tmp', '--update-expectations', 'True', '--verbose']]])
-
-
-class TestRebaseline(_BaseTestCase):
- # This command shares most of its logic with RebaselineJson, so these tests just test what is different.
-
- command_constructor = Rebaseline # AKA webkit-patch rebaseline
-
- def test_tests_to_update(self):
- build = Mock()
- with OutputCapture():
- self.command._tests_to_update(build)
-
- def test_rebaseline(self):
- self.command._builders_to_pull_from = lambda: [MockBuilder('MOCK builder')]
- self.command._tests_to_update = lambda builder: ['mock/path/to/test.html']
-
- self._zero_out_test_expectations()
-
- old_exact_matches = builders._exact_matches
- with OutputCapture() as captured:
- builders._exact_matches = {
- "MOCK builder": {"port_name": "test-mac-leopard", "specifiers": {"mock-specifier"}},
- }
- self.command.execute(MockOptions(optimize=False, builders=None, suffixes="txt,png", verbose=True, move_overwritten_baselines=False, update_expectations=True), [], self.tool)
-
- builders._exact_matches = old_exact_matches
-
- calls = list(filter(lambda x: x[0] not in ['perl', '/usr/bin/xcrun', '/usr/bin/ulimit'], self.tool.executive.calls))
- self.assertEqual(calls, [[['echo', 'rebaseline-test-internal', '--suffixes', 'txt,png', '--builder', 'MOCK builder',
- '--test', 'mock/path/to/test.html', '--update-expectations', 'True', '--verbose']]])
-
-
-class TestRebaselineExpectations(_BaseTestCase):
- command_constructor = RebaselineExpectations
-
- def setUp(self):
- super(TestRebaselineExpectations, self).setUp()
- self.options = MockOptions(optimize=False, builders=None, suffixes=['txt'], verbose=False, platform=None,
- move_overwritten_baselines=False, results_directory=None, update_expectations=True)
-
- def test_rebaseline_expectations(self):
- self._zero_out_test_expectations()
-
- self.tool.executive = MockExecutive2()
-
- self.command._tests_to_rebaseline = lambda port: {'userscripts/another-test.html': set(['txt']), 'userscripts/images.svg': set(['png'])}
- self.command.execute(self.options, [], self.tool)
-
- # FIXME: change this to use the test- ports.
- calls = list(filter(lambda x: x[0] not in ['perl', '/usr/bin/xcrun', '/usr/bin/ulimit'], self.tool.executive.calls))
- self.assertEqual(len(calls), 1)
- self.assertEqual(len(calls[0]), 24)
-
- def test_rebaseline_expectations_noop(self):
- self._zero_out_test_expectations()
-
- with OutputCapture() as captured:
- self.command.execute(self.options, [], self.tool)
-
- self.assertEqual(self.tool.filesystem.written_files, {})
- self.assertEqual(captured.root.log.getvalue(), "The 'rebaseline-expectations' command is currently deprecated due to believed non-use; if it forms part of your workflow, please comment on https://bugs.webkit.org/show_bug.cgi?id=221991 and please include the command you ran, even if others have already mentioned it\nDid not find any tests marked Rebaseline.\n")
-
- def disabled_test_overrides_are_included_correctly(self):
- # This tests that the any tests marked as REBASELINE in the overrides are found, but
- # that the overrides do not get written into the main file.
- self._zero_out_test_expectations()
-
- self._write(self.lion_expectations_path, '')
- self.lion_port.expectations_dict = lambda: {
- self.lion_expectations_path: '',
- 'overrides': ('Bug(x) userscripts/another-test.html [ Failure Rebaseline ]\n'
- 'Bug(y) userscripts/test.html [ Crash ]\n')}
- self._write('/userscripts/another-test.html', '')
-
- self.assertDictEqual(self.command._tests_to_rebaseline(self.lion_port), {'userscripts/another-test.html': set(['png', 'txt', 'wav'])})
- self.assertEqual(self._read(self.lion_expectations_path), '')
</del></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommandsuploadpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/tool/commands/upload.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/upload.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/upload.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -42,7 +42,6 @@
</span><span class="cx"> from webkitpy.common.config.committers import CommitterList
</span><span class="cx"> from webkitpy.common.system.user import User
</span><span class="cx"> from webkitpy.tool.commands.abstractsequencedcommand import AbstractSequencedCommand
</span><del>-from webkitpy.tool.commands.deprecatedcommand import DeprecatedCommand
</del><span class="cx"> from webkitpy.tool.comments import bug_comment_from_svn_revision
</span><span class="cx"> from webkitpy.tool.multicommandtool import Command
</span><span class="cx">
</span><span class="lines">@@ -49,152 +48,8 @@
</span><span class="cx"> _log = logging.getLogger(__name__)
</span><span class="cx">
</span><span class="cx">
</span><del>-@DeprecatedCommand
-class CommitMessageForCurrentDiff(Command):
- name = "commit-message"
- help_text = "Print a commit message suitable for the uncommitted changes"
</del><span class="cx">
</span><del>- def __init__(self):
- options = [
- steps.Options.git_commit,
- ]
- Command.__init__(self, options=options)
</del><span class="cx">
</span><del>- def execute(self, options, args, tool):
- # This command is a useful test to make sure commit_message_for_this_commit
- # always returns the right value regardless of the current working directory.
- print("%s" % tool.checkout().commit_message_for_this_commit(options.git_commit).message())
-
-
-@DeprecatedCommand
-class CleanPendingCommit(Command):
- name = "clean-pending-commit"
- help_text = "Clear r+ on obsolete patches so they do not appear in the pending-commit list."
-
- # NOTE: This was designed to be generic, but right now we're only processing patches from the pending-commit list, so only r+ matters.
- def _flags_to_clear_on_patch(self, patch):
- if not patch.is_obsolete():
- return None
- what_was_cleared = []
- if patch.review() == "+":
- if patch.reviewer():
- what_was_cleared.append(u"%s's review+" % patch.reviewer().full_name)
- else:
- what_was_cleared.append("review+")
- return string_utils.join(what_was_cleared)
-
- def execute(self, options, args, tool):
- for bug_id in tool.bugs.queries.fetch_bug_ids_from_pending_commit_list():
- bug = self._tool.bugs.fetch_bug(bug_id)
- patches = bug.patches(include_obsolete=True)
- for patch in patches:
- flags_to_clear = self._flags_to_clear_on_patch(patch)
- if not flags_to_clear:
- continue
- message = u"Cleared %s from obsolete attachment %s so that this bug does not appear in http://webkit.org/pending-commit." % (flags_to_clear, patch.id())
- self._tool.bugs.obsolete_attachment(patch.id(), message)
-
-
-# FIXME: This should be share more logic with AssignToCommitter and CleanPendingCommit
-@DeprecatedCommand
-class CleanReviewQueue(Command):
- name = "clean-review-queue"
- help_text = "Clear r? on obsolete patches so they do not appear in the pending-review list."
-
- def execute(self, options, args, tool):
- queue_url = "http://webkit.org/pending-review"
- # We do this inefficient dance to be more like webkit.org/pending-review
- # bugs.queries.fetch_bug_ids_from_review_queue() doesn't return
- # closed bugs, but folks using /pending-review will see them. :(
- for patch_id in tool.bugs.queries.fetch_attachment_ids_from_review_queue():
- patch = self._tool.bugs.fetch_attachment(patch_id)
- if not patch.review() == "?":
- continue
- attachment_obsolete_modifier = ""
- if patch.is_obsolete():
- attachment_obsolete_modifier = "obsolete "
- elif patch.bug().is_closed():
- bug_closed_explanation = " If you would like this patch reviewed, please attach it to a new bug (or re-open this bug before marking it for review again)."
- else:
- # Neither the patch was obsolete or the bug was closed, next patch...
- continue
- message = "Cleared review? from %sattachment %s so that this bug does not appear in %s.%s" % (attachment_obsolete_modifier, patch.id(), queue_url, bug_closed_explanation)
- self._tool.bugs.obsolete_attachment(patch.id(), message)
-
-
-@DeprecatedCommand
-class AssignToCommitter(Command):
- name = "assign-to-committer"
- help_text = "Assign bug to whoever attached the most recent r+'d patch"
-
- def _patches_have_commiters(self, reviewed_patches):
- for patch in reviewed_patches:
- if not patch.committer():
- return False
- return True
-
- def _assign_bug_to_last_patch_attacher(self, bug_id):
- committers = CommitterList()
- bug = self._tool.bugs.fetch_bug(bug_id)
- if not bug.is_unassigned():
- assigned_to_email = bug.assigned_to_email()
- _log.info(u"Bug %s is already assigned to %s (%s)." % (bug_id, assigned_to_email, committers.committer_by_email(assigned_to_email)))
- return
-
- reviewed_patches = bug.reviewed_patches()
- if not reviewed_patches:
- _log.info("Bug %s has no non-obsolete patches, ignoring." % bug_id)
- return
-
- # We only need to do anything with this bug if one of the r+'d patches does not have a valid committer (cq+ set).
- if self._patches_have_commiters(reviewed_patches):
- _log.info("All reviewed patches on bug %s already have commit-queue+, ignoring." % bug_id)
- return
-
- latest_patch = reviewed_patches[-1]
- attacher_email = latest_patch.attacher_email()
- committer = committers.committer_by_email(attacher_email)
- if not committer:
- _log.info("Attacher %s is not a committer. Bug %s likely needs commit-queue+." % (attacher_email, bug_id))
- return
-
- reassign_message = u"Attachment %s was posted by a committer and has review+, assigning to %s for commit." % (latest_patch.id(), committer.full_name)
- self._tool.bugs.reassign_bug(bug_id, committer.bugzilla_email(), reassign_message)
-
- def execute(self, options, args, tool):
- for bug_id in tool.bugs.queries.fetch_bug_ids_from_pending_commit_list():
- self._assign_bug_to_last_patch_attacher(bug_id)
-
-
-@DeprecatedCommand
-class ObsoleteAttachments(AbstractSequencedCommand):
- name = "obsolete-attachments"
- help_text = "Mark all attachments on a bug as obsolete"
- argument_names = "BUGID"
- steps = [
- steps.ObsoletePatches,
- ]
-
- def _prepare_state(self, options, args, tool):
- return { "bug_id" : args[0] }
-
-
-@DeprecatedCommand
-class AttachToBug(AbstractSequencedCommand):
- name = "attach-to-bug"
- help_text = "Attach the file to the bug"
- argument_names = "BUGID FILEPATH"
- steps = [
- steps.AttachToBug,
- ]
-
- def _prepare_state(self, options, args, tool):
- state = {}
- state["bug_id"] = args[0]
- state["filepath"] = args[1]
- return state
-
-
</del><span class="cx"> class AbstractPatchUploadingCommand(AbstractSequencedCommand):
</span><span class="cx"> def _bug_id(self, options, args, tool, state):
</span><span class="cx"> # Perfer a bug id passed as an argument over a bug url in the diff (i.e. ChangeLogs).
</span><span class="lines">@@ -248,16 +103,6 @@
</span><span class="cx"> ]
</span><span class="cx">
</span><span class="cx">
</span><del>-@DeprecatedCommand
-class HasLanded(AbstractPatchUploadingCommand):
- name = "has-landed"
- help_text = "Check that the current code was successfully landed and no changes remain."
- argument_names = "[BUGID]"
- steps = [
- steps.HasLanded,
- ]
-
-
</del><span class="cx"> class Prepare(AbstractSequencedCommand):
</span><span class="cx"> name = "prepare"
</span><span class="cx"> help_text = "Creates a bug (or prompts for an existing bug) and prepares the ChangeLogs"
</span><span class="lines">@@ -319,65 +164,7 @@
</span><span class="cx"> ]
</span><span class="cx">
</span><span class="cx">
</span><del>-@DeprecatedCommand
-class PostCommits(Command):
- name = "post-commits"
- help_text = "Attach a range of local commits to bugs as patch files"
- argument_names = "COMMITISH"
</del><span class="cx">
</span><del>- def __init__(self):
- options = [
- make_option("-b", "--bug-id", action="store", type="string", dest="bug_id", help="Specify bug id if no URL is provided in the commit log."),
- make_option("--add-log-as-comment", action="store_true", dest="add_log_as_comment", default=False, help="Add commit log message as a comment when uploading the patch."),
- make_option("-m", "--description", action="store", type="string", dest="description", help="Description string for the attachment (default: description from commit message)"),
- steps.Options.obsolete_patches,
- steps.Options.review,
- steps.Options.request_commit,
- steps.Options.ews,
- ]
- Command.__init__(self, options=options, requires_local_commits=True)
-
- def _comment_text_for_commit(self, options, commit_message, tool, commit_id):
- comment_text = None
- if (options.add_log_as_comment):
- comment_text = commit_message.body(lstrip=True)
- comment_text += "---\n"
- comment_text += tool.scm().files_changed_summary_for_commit(commit_id)
- return comment_text
-
- def execute(self, options, args, tool):
- commit_ids = tool.scm().commit_ids_from_commitish_arguments(args)
- if len(commit_ids) > 10: # We could lower this limit, 10 is too many for one bug as-is.
- _log.error("webkit-patch does not support attaching %s at once. Are you sure you passed the right commit range?" % (string_utils.pluralize(len(commit_ids), 'patch', plural='patches')))
- sys.exit(1)
-
- have_obsoleted_patches = set()
- for commit_id in commit_ids:
- commit_message = tool.scm().commit_message_for_local_commit(commit_id)
-
- # Prefer --bug-id=, then a bug url in the commit message, then a bug url in the entire commit diff (i.e. ChangeLogs).
- bug_id = options.bug_id or parse_bug_id_from_changelog(commit_message.message()) or parse_bug_id_from_changelog(tool.scm().create_patch(git_commit=commit_id))
- if not bug_id:
- _log.info("Skipping %s: No bug id found in commit or specified with --bug-id." % commit_id)
- continue
-
- if options.obsolete_patches and bug_id not in have_obsoleted_patches:
- state = { "bug_id": bug_id }
- steps.ObsoletePatches(tool, options).run(state)
- have_obsoleted_patches.add(bug_id)
-
- diff = tool.scm().create_patch(git_commit=commit_id)
- description = options.description or commit_message.description(lstrip=True, strip_url=True)
- comment_text = self._comment_text_for_commit(options, commit_message, tool, commit_id)
- attachment_id = tool.bugs.add_patch_to_bug(bug_id, diff, description, comment_text, mark_for_review=options.review, mark_for_commit_queue=options.request_commit)
-
- # We only need to submit --no-review patches to EWS as patches posted for review are
- # automatically submitted to EWS by EWSFeeder.
- if not options.review and options.ews:
- state = {'attachment_ids': [attachment_id]}
- steps.SubmitToEWS(tool, options).run(state)
-
-
</del><span class="cx"> # FIXME: This command needs to be brought into the modern age with steps and CommitInfo.
</span><span class="cx"> class MarkBugFixed(Command):
</span><span class="cx"> name = "mark-bug-fixed"
</span><span class="lines">@@ -458,112 +245,3 @@
</span><span class="cx"> else:
</span><span class="cx"> _log.info("Adding comment to Bug %s and marking as Resolved/Fixed." % bug_id)
</span><span class="cx"> tool.bugs.close_bug_as_fixed(bug_id, bug_comment)
</span><del>-
-
-# FIXME: Requires unit test. Blocking issue: too complex for now.
-@DeprecatedCommand
-class CreateBug(Command):
- name = "create-bug"
- help_text = "Create a bug from local changes or local commits"
- argument_names = "[COMMITISH]"
-
- def __init__(self):
- options = [
- steps.Options.cc,
- steps.Options.cc_radar,
- steps.Options.component,
- make_option("--no-prompt", action="store_false", dest="prompt", default=True, help="Do not prompt for bug title and comment; use commit log instead."),
- make_option("--no-review", action="store_false", dest="review", default=True, help="Do not mark the patch for review."),
- make_option("--request-commit", action="store_true", dest="request_commit", default=False, help="Mark the patch as needing auto-commit after review."),
- ]
- Command.__init__(self, options=options)
-
- def create_bug_from_commit(self, options, args, tool):
- commit_ids = tool.scm().commit_ids_from_commitish_arguments(args)
- if len(commit_ids) > 3:
- _log.error("Are you sure you want to create one bug with %s patches?" % len(commit_ids))
- sys.exit(1)
-
- commit_id = commit_ids[0]
-
- if options.prompt:
- (bug_title, comment_text) = self.prompt_for_bug_title_and_comment()
- else:
- commit_message = tool.scm().commit_message_for_local_commit(commit_id)
- bug_title = commit_message.description(lstrip=True, strip_url=True)
- comment_text = commit_message.body(lstrip=True)
- comment_text += "---\n"
- comment_text += tool.scm().files_changed_summary_for_commit(commit_id)
-
- diff = tool.scm().create_patch(git_commit=commit_id)
- bug_id = tool.bugs.create_bug(bug_title, comment_text, options.component, diff, "Patch", cc=options.cc, mark_for_review=options.review, mark_for_commit_queue=options.request_commit)
-
- if bug_id and len(commit_ids) > 1:
- options.bug_id = bug_id
- options.obsolete_patches = False
- # FIXME: We should pass through --no-comment switch as well.
- PostCommits.execute(self, options, commit_ids[1:], tool)
-
- def create_bug_from_patch(self, options, args, tool):
- if options.prompt:
- (bug_title, comment_text) = self.prompt_for_bug_title_and_comment()
- else:
- commit_message = tool.checkout().commit_message_for_this_commit(options.git_commit)
- bug_title = commit_message.description(lstrip=True, strip_url=True)
- comment_text = commit_message.body(lstrip=True)
-
- diff = tool.scm().create_patch(options.git_commit)
- tool.bugs.create_bug(bug_title, comment_text, options.component, diff, "Patch", cc=options.cc, mark_for_review=options.review, mark_for_commit_queue=options.request_commit)
-
- def prompt_for_bug_title_and_comment(self):
- bug_title = User.prompt("Bug title: ")
- # FIXME: User should provide a function for doing this multi-line prompt.
- print("Bug comment (hit ^D on blank line to end):")
- lines = sys.stdin.readlines()
- try:
- sys.stdin.seek(0, os.SEEK_END)
- except IOError:
- # Cygwin raises an Illegal Seek (errno 29) exception when the above
- # seek() call is made. Ignoring it seems to cause no harm.
- # FIXME: Figure out a way to get avoid the exception in the first
- # place.
- pass
- comment_text = "".join(lines)
- return (bug_title, comment_text)
-
- def execute(self, options, args, tool):
- if options.cc_radar:
- if options.cc:
- options.cc = "webkit-bug-importer@group.apple.com,%s" % options.cc
- else:
- options.cc = "webkit-bug-importer@group.apple.com"
- if len(args):
- if (not tool.scm().supports_local_commits()):
- _log.error("Extra arguments not supported; patch is taken from working directory.")
- sys.exit(1)
- self.create_bug_from_commit(options, args, tool)
- else:
- self.create_bug_from_patch(options, args, tool)
-
-
-@DeprecatedCommand
-class WPTChangeExport(AbstractPatchUploadingCommand):
- name = "wpt-change-export"
- help_text = "Opens a pull request to synchronize any changes in the LayoutTests/imported/w3c/web-platform-tests directory"
- argument_names = "[BUGID]"
- steps = [
- steps.WPTChangeExport,
- ]
-
- long_help = """Opens a pull request to the w3c/web-platform-tests
- github repo for any changes in the
- LayoutTests/imported/w3c/web-platform-tests directory. This step
- will noop if there are no changes in the web-platform-tests directory.
- The user will be prompted to provide a github username and OAuth token
- the first time this is run.
- """
-
- def _prepare_state(self, options, args, tool):
- state = {}
- state["bug_id"] = self._bug_id(options, args, tool, state)
- return state
</del></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommandsupload_unittestpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/tool/commands/upload_unittest.py (283362 => 283363)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/upload_unittest.py 2021-10-01 12:53:49 UTC (rev 283362)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/upload_unittest.py 2021-10-01 13:12:44 UTC (rev 283363)
</span><span class="lines">@@ -36,30 +36,6 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx"> class UploadCommandsTest(CommandsTest):
</span><del>- def test_commit_message_for_current_diff(self):
- tool = MockTool()
- expected_stdout = "This is a fake commit message that is at least 50 characters.\n"
- self.assert_execute_outputs(CommitMessageForCurrentDiff(), [], expected_stdout=expected_stdout, tool=tool)
-
- def test_clean_pending_commit(self):
- self.assert_execute_outputs(CleanPendingCommit(), [])
-
- def test_assign_to_committer(self):
- tool = MockTool()
- expected_logs = """Warning, attachment 10001 on bug 50000 has invalid committer (non-committer@example.com)
-MOCK reassign_bug: bug_id=50000, assignee=ap@webkit.org
--- Begin comment --
-Attachment 10001 was posted by a committer and has review+, assigning to Alexey Proskuryakov for commit.
--- End comment --
-Bug 50003 is already assigned to foo@foo.com (None).
-Bug 50002 has no non-obsolete patches, ignoring.
-"""
- self.assert_execute_outputs(AssignToCommitter(), [], expected_logs=expected_logs, tool=tool)
-
- def test_obsolete_attachments(self):
- expected_logs = "Obsoleting 2 old patches on bug 50000\n"
- self.assert_execute_outputs(ObsoleteAttachments(), [50000], expected_logs=expected_logs)
-
</del><span class="cx"> def test_post(self):
</span><span class="cx"> options = MockOptions()
</span><span class="cx"> options.cc = None
</span><span class="lines">@@ -81,24 +57,6 @@
</span><span class="cx"> """
</span><span class="cx"> self.assert_execute_outputs(Post(), [50000], options=options, expected_logs=expected_logs)
</span><span class="cx">
</span><del>- def test_attach_to_bug(self):
- options = MockOptions()
- options.comment = "extra comment"
- options.description = "file description"
- expected_logs = """MOCK add_attachment_to_bug: bug_id=50000, description=file description filename=None mimetype=None
--- Begin comment --
-extra comment
--- End comment --
-"""
- self.assert_execute_outputs(AttachToBug(), [50000, "path/to/file.txt", "file description"], options=options, expected_logs=expected_logs)
-
- def test_attach_to_bug_no_description_or_comment(self):
- options = MockOptions()
- options.comment = None
- options.description = None
- expected_logs = "MOCK add_attachment_to_bug: bug_id=50000, description=file.txt filename=None mimetype=None\n"
- self.assert_execute_outputs(AttachToBug(), [50000, "path/to/file.txt"], options=options, expected_logs=expected_logs)
-
</del><span class="cx"> def test_land_safely(self):
</span><span class="cx"> expected_logs = """Obsoleting 2 old patches on bug 50000
</span><span class="cx"> MOCK reassign_bug: bug_id=50000, assignee=None
</span></span></pre>
</div>
</div>
</body>
</html>