<!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>[174248] 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/174248">174248</a></dd>
<dt>Author</dt> <dd>ap@apple.com</dd>
<dt>Date</dt> <dd>2014-10-02 16:49:30 -0700 (Thu, 02 Oct 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>update-work-items should never delete items
https://bugs.webkit.org/show_bug.cgi?id=137366

Reviewed by Ryosuke Niwa.

As we don't just replace the whole list any more, indicate which items are high
priority, and which are not. Hight priority ones will be prepended to the queue,
others will be appended.

This creates a bit of unfairness in that high priority item queue becomes a LIFO.
But hopefully we will never have many rollouts competing like that.

* QueueStatusServer/app.yaml: Update version.

* QueueStatusServer/handlers/updateworkitems.py: Never remove items. Pass high
priority and regular items separately. Removed some error handling that used to
end up in returning status 500 - an uncaught exception does that automatically.

* QueueStatusServer/main.py: Removed unnecessary regexps from URL matching code.

* QueueStatusServer/model/workitems.py: Added a way to add high priority items.

* QueueStatusServer/templates/updateworkitems.html: Added a field for high
priority items.

* Scripts/webkitpy/common/net/bugzilla/bugzilla.py:
(BugzillaQueries._parse_attachment_ids_request_query): Removed an annoying log
line that complicated testing.

* Scripts/webkitpy/common/net/statusserver.py: Pass high priority items separately.

* Scripts/webkitpy/tool/bot/feeders.py: For commit queue, split high and regular
priority items into separate lists.

* Scripts/webkitpy/common/net/statusserver_mock.py:
* Scripts/webkitpy/tool/bot/feeders_unittest.py:
* Scripts/webkitpy/tool/commands/queues_unittest.py:
Updated tests.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsQueueStatusServerappyaml">trunk/Tools/QueueStatusServer/app.yaml</a></li>
<li><a href="#trunkToolsQueueStatusServerhandlersupdateworkitemspy">trunk/Tools/QueueStatusServer/handlers/updateworkitems.py</a></li>
<li><a href="#trunkToolsQueueStatusServermainpy">trunk/Tools/QueueStatusServer/main.py</a></li>
<li><a href="#trunkToolsQueueStatusServermodelworkitemspy">trunk/Tools/QueueStatusServer/model/workitems.py</a></li>
<li><a href="#trunkToolsQueueStatusServertemplatesupdateworkitemshtml">trunk/Tools/QueueStatusServer/templates/updateworkitems.html</a></li>
<li><a href="#trunkToolsScriptswebkitpycommonnetbugzillabugzillapy">trunk/Tools/Scripts/webkitpy/common/net/bugzilla/bugzilla.py</a></li>
<li><a href="#trunkToolsScriptswebkitpycommonnetstatusserverpy">trunk/Tools/Scripts/webkitpy/common/net/statusserver.py</a></li>
<li><a href="#trunkToolsScriptswebkitpycommonnetstatusserver_mockpy">trunk/Tools/Scripts/webkitpy/common/net/statusserver_mock.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolbotfeederspy">trunk/Tools/Scripts/webkitpy/tool/bot/feeders.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolbotfeeders_unittestpy">trunk/Tools/Scripts/webkitpy/tool/bot/feeders_unittest.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolcommandsqueues_unittestpy">trunk/Tools/Scripts/webkitpy/tool/commands/queues_unittest.py</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (174247 => 174248)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2014-10-02 23:47:38 UTC (rev 174247)
+++ trunk/Tools/ChangeLog        2014-10-02 23:49:30 UTC (rev 174248)
</span><span class="lines">@@ -1,3 +1,44 @@
</span><ins>+2014-10-02  Alexey Proskuryakov  &lt;ap@apple.com&gt;
+
+        update-work-items should never delete items
+        https://bugs.webkit.org/show_bug.cgi?id=137366
+
+        Reviewed by Ryosuke Niwa.
+
+        As we don't just replace the whole list any more, indicate which items are high
+        priority, and which are not. Hight priority ones will be prepended to the queue,
+        others will be appended.
+
+        This creates a bit of unfairness in that high priority item queue becomes a LIFO.
+        But hopefully we will never have many rollouts competing like that.
+
+        * QueueStatusServer/app.yaml: Update version.
+
+        * QueueStatusServer/handlers/updateworkitems.py: Never remove items. Pass high
+        priority and regular items separately. Removed some error handling that used to
+        end up in returning status 500 - an uncaught exception does that automatically.
+
+        * QueueStatusServer/main.py: Removed unnecessary regexps from URL matching code.
+
+        * QueueStatusServer/model/workitems.py: Added a way to add high priority items.
+
+        * QueueStatusServer/templates/updateworkitems.html: Added a field for high
+        priority items.
+
+        * Scripts/webkitpy/common/net/bugzilla/bugzilla.py:
+        (BugzillaQueries._parse_attachment_ids_request_query): Removed an annoying log
+        line that complicated testing.
+
+        * Scripts/webkitpy/common/net/statusserver.py: Pass high priority items separately.
+
+        * Scripts/webkitpy/tool/bot/feeders.py: For commit queue, split high and regular
+        priority items into separate lists.
+
+        * Scripts/webkitpy/common/net/statusserver_mock.py:
+        * Scripts/webkitpy/tool/bot/feeders_unittest.py:
+        * Scripts/webkitpy/tool/commands/queues_unittest.py:
+        Updated tests.
+
</ins><span class="cx"> 2014-10-02  Brendan Long  &lt;b.long@cablelabs.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Annoying build warnings in WTFString API tests
</span></span></pre></div>
<a id="trunkToolsQueueStatusServerappyaml"></a>
<div class="modfile"><h4>Modified: trunk/Tools/QueueStatusServer/app.yaml (174247 => 174248)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/QueueStatusServer/app.yaml        2014-10-02 23:47:38 UTC (rev 174247)
+++ trunk/Tools/QueueStatusServer/app.yaml        2014-10-02 23:49:30 UTC (rev 174248)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> application: webkit-queues
</span><del>-version: 174158 # Bugzilla bug ID of last major change
</del><ins>+version: 174248 # Bugzilla bug ID of last major change
</ins><span class="cx"> runtime: python
</span><span class="cx"> api_version: 1
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsQueueStatusServerhandlersupdateworkitemspy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/QueueStatusServer/handlers/updateworkitems.py (174247 => 174248)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/QueueStatusServer/handlers/updateworkitems.py        2014-10-02 23:47:38 UTC (rev 174247)
+++ trunk/Tools/QueueStatusServer/handlers/updateworkitems.py        2014-10-02 23:49:30 UTC (rev 174248)
</span><span class="lines">@@ -1,4 +1,5 @@
</span><span class="cx"> # Copyright (C) 2013 Google Inc. All rights reserved.
</span><ins>+# Copyright (C) 2014 Apple Inc. All rights reserved.
</ins><span class="cx"> #
</span><span class="cx"> # Redistribution and use in source and binary forms, with or without
</span><span class="cx"> # modification, are permitted provided that the following conditions are
</span><span class="lines">@@ -42,21 +43,15 @@
</span><span class="cx">         self.response.out.write(template.render(&quot;templates/updateworkitems.html&quot;, None))
</span><span class="cx"> 
</span><span class="cx">     def _parse_work_items_string(self, items_string):
</span><del>-        try:
-            item_strings = items_string.split(&quot; &quot;) if items_string else []
-            return map(int, item_strings)
-        except ValueError:
-            return None
</del><ins>+        item_strings = items_string.split(&quot; &quot;) if items_string else []
+        return map(int, item_strings)
</ins><span class="cx"> 
</span><del>-    def _update_work_items_from_request(self, work_items):
</del><ins>+    def _work_items_from_request(self):
+        high_priority_items_string = self.request.get(&quot;high_priority_items&quot;)
</ins><span class="cx">         items_string = self.request.get(&quot;work_items&quot;)
</span><del>-        new_work_items = self._parse_work_items_string(items_string)
-        if new_work_items == None:
-            self.response.out.write(&quot;Failed to parse work items: %s&quot; % items_string)
-            return False
-        work_items.item_ids = new_work_items
-        work_items.date = datetime.utcnow()
-        return True
</del><ins>+        high_priority_work_items = self._parse_work_items_string(high_priority_items_string)
+        work_items = self._parse_work_items_string(items_string)
+        return high_priority_work_items, work_items
</ins><span class="cx"> 
</span><span class="cx">     def _queue_from_request(self):
</span><span class="cx">         queue_name = self.request.get(&quot;queue_name&quot;)
</span><span class="lines">@@ -71,17 +66,12 @@
</span><span class="cx">         if not queue:
</span><span class="cx">             self.response.set_status(500)
</span><span class="cx">             return
</span><del>-        work_items = queue.work_items()
-        old_items = set(work_items.item_ids)
</del><span class="cx"> 
</span><del>-        success = self._update_work_items_from_request(work_items)
-        if not success:
-            self.response.set_status(500)
-            return
-        new_items = set(work_items.item_ids)
-        work_items.put()
</del><ins>+        high_priority_items, items = self._work_items_from_request()
</ins><span class="cx"> 
</span><del>-        for work_item in new_items - old_items:
</del><ins>+        # Add items that are not currently in the work queue. Never remove any items,
+        # as that should be done by the queue, feeder only adds them.
+        added_items = queue.work_items().add_work_items(high_priority_items, items)
+
+        for work_item in added_items:
</ins><span class="cx">             RecordPatchEvent.added(work_item, queue.name())
</span><del>-        for work_item in old_items - new_items:
-            RecordPatchEvent.stopped(work_item, queue.name())
</del></span></pre></div>
<a id="trunkToolsQueueStatusServermainpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/QueueStatusServer/main.py (174247 => 174248)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/QueueStatusServer/main.py        2014-10-02 23:47:38 UTC (rev 174247)
+++ trunk/Tools/QueueStatusServer/main.py        2014-10-02 23:49:30 UTC (rev 174248)
</span><span class="lines">@@ -63,7 +63,7 @@
</span><span class="cx">     ('/sync-queue-logs', SyncQueueLogs),
</span><span class="cx">     (r'/patch-status/(.*)/(.*)', PatchStatus),
</span><span class="cx">     (r'/patch/(.*)', Patch),
</span><del>-    (r'/submit-to-ews', SubmitToEWS),
</del><ins>+    ('/submit-to-ews', SubmitToEWS),
</ins><span class="cx">     (r'/results/(.*)', ShowResults),
</span><span class="cx">     (r'/status-bubble/(.*)', StatusBubble),
</span><span class="cx">     (r'/svn-revision/(.*)', SVNRevision),
</span><span class="lines">@@ -73,8 +73,8 @@
</span><span class="cx">     (r'/queue-status/(.*)', QueueStatus),
</span><span class="cx">     (r'/queue-status-json/(.*)', QueueStatusJSON),
</span><span class="cx">     (r'/next-patch/(.*)', NextPatch),
</span><del>-    (r'/release-patch', ReleasePatch),
-    (r'/release-lock', ReleaseLock),
</del><ins>+    ('/release-patch', ReleasePatch),
+    ('/release-lock', ReleaseLock),
</ins><span class="cx">     ('/update-status', UpdateStatus),
</span><span class="cx">     ('/update-work-items', UpdateWorkItems),
</span><span class="cx">     ('/update-svn-revision', UpdateSVNRevision),
</span></span></pre></div>
<a id="trunkToolsQueueStatusServermodelworkitemspy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/QueueStatusServer/model/workitems.py (174247 => 174248)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/QueueStatusServer/model/workitems.py        2014-10-02 23:47:38 UTC (rev 174247)
+++ trunk/Tools/QueueStatusServer/model/workitems.py        2014-10-02 23:49:30 UTC (rev 174248)
</span><span class="lines">@@ -1,4 +1,5 @@
</span><span class="cx"> # Copyright (C) 2010 Google Inc. All rights reserved.
</span><ins>+# Copyright (C) 2014 Apple Inc. All rights reserved.
</ins><span class="cx"> #
</span><span class="cx"> # Redistribution and use in source and binary forms, with or without
</span><span class="cx"> # modification, are permitted provided that the following conditions are
</span><span class="lines">@@ -53,17 +54,29 @@
</span><span class="cx">         return None
</span><span class="cx"> 
</span><span class="cx">     @staticmethod
</span><del>-    def _unguarded_add(key, attachment_id):
</del><ins>+    def _unguarded_add(key, high_priority_items, items):
</ins><span class="cx">         work_items = db.get(key)
</span><del>-        if attachment_id in work_items.item_ids:
-            return
-        work_items.item_ids.append(attachment_id)
</del><ins>+        added_items = []
+        for item in high_priority_items[::-1]:
+            if item in work_items.item_ids:
+                continue
+            work_items.item_ids.insert(0, item)
+            added_items.insert(0, item)
+        for item in items:
+            if item in work_items.item_ids:
+                continue
+            work_items.item_ids.append(item)
+            added_items.append(item)
</ins><span class="cx">         work_items.put()
</span><ins>+        return added_items
</ins><span class="cx"> 
</span><span class="cx">     # Because this uses .key() self.is_saved() must be True or this will throw NotSavedError.
</span><span class="cx">     def add_work_item(self, attachment_id):
</span><del>-        db.run_in_transaction(self._unguarded_add, self.key(), attachment_id)
</del><ins>+        db.run_in_transaction(self._unguarded_add, self.key(), [], [attachment_id])
</ins><span class="cx"> 
</span><ins>+    def add_work_items(self, high_priority_items, items):
+        return db.run_in_transaction(self._unguarded_add, self.key(), high_priority_items, items)
+
</ins><span class="cx">     @staticmethod
</span><span class="cx">     def _unguarded_remove(key, attachment_id):
</span><span class="cx">         work_items = db.get(key)
</span></span></pre></div>
<a id="trunkToolsQueueStatusServertemplatesupdateworkitemshtml"></a>
<div class="modfile"><h4>Modified: trunk/Tools/QueueStatusServer/templates/updateworkitems.html (174247 => 174248)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/QueueStatusServer/templates/updateworkitems.html        2014-10-02 23:47:38 UTC (rev 174247)
+++ trunk/Tools/QueueStatusServer/templates/updateworkitems.html        2014-10-02 23:49:30 UTC (rev 174248)
</span><span class="lines">@@ -1,8 +1,8 @@
</span><span class="cx"> &lt;form name=&quot;update_work_items&quot; enctype=&quot;multipart/form-data&quot; method=&quot;post&quot;&gt;
</span><span class="cx"> Update work items for a queue: &lt;input name=&quot;queue_name&quot;&gt;
</span><span class="cx">  &lt;div&gt;
</span><del>-     Work Items:
-    &lt;input name=&quot;work_items&quot;&gt;
</del><ins>+     Work items: &lt;input name=&quot;work_items&quot;&gt;
+     High priority work items: &lt;input name=&quot;high_priority_work_items&quot;&gt;
</ins><span class="cx">  &lt;/div&gt;
</span><span class="cx">  &lt;div&gt;&lt;input type=&quot;submit&quot; value=&quot;Update Work Items&quot;&gt;&lt;/div&gt;
</span><span class="cx"> &lt;/form&gt;
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpycommonnetbugzillabugzillapy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/common/net/bugzilla/bugzilla.py (174247 => 174248)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/common/net/bugzilla/bugzilla.py        2014-10-02 23:47:38 UTC (rev 174247)
+++ trunk/Tools/Scripts/webkitpy/common/net/bugzilla/bugzilla.py        2014-10-02 23:49:30 UTC (rev 174248)
</span><span class="lines">@@ -204,7 +204,6 @@
</span><span class="cx">             patch_id = int(digits.search(patch_tag[&quot;href&quot;]).group(0))
</span><span class="cx">             date_tag = row.find(&quot;td&quot;, text=date_format)
</span><span class="cx">             if date_tag and datetime.strptime(date_format.search(date_tag).group(0), &quot;%Y-%m-%d %H:%M&quot;) &lt; since:
</span><del>-                _log.info(&quot;Patch is old: %d (%s)&quot; % (patch_id, date_tag))
</del><span class="cx">                 continue
</span><span class="cx">             patch_ids.append(patch_id)
</span><span class="cx">         return patch_ids
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpycommonnetstatusserverpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/common/net/statusserver.py (174247 => 174248)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/common/net/statusserver.py        2014-10-02 23:47:38 UTC (rev 174247)
+++ trunk/Tools/Scripts/webkitpy/common/net/statusserver.py        2014-10-02 23:49:30 UTC (rev 174248)
</span><span class="lines">@@ -100,13 +100,15 @@
</span><span class="cx">         self._browser[&quot;broken_bot&quot;] = broken_bot
</span><span class="cx">         return self._browser.submit().read()
</span><span class="cx"> 
</span><del>-    def _post_work_items_to_server(self, queue_name, work_items):
</del><ins>+    def _post_work_items_to_server(self, queue_name, high_priority_work_items, work_items):
</ins><span class="cx">         update_work_items_url = &quot;%s/update-work-items&quot; % self.url
</span><span class="cx">         self._browser.open(update_work_items_url)
</span><span class="cx">         self._browser.select_form(name=&quot;update_work_items&quot;)
</span><span class="cx">         self._browser[&quot;queue_name&quot;] = queue_name
</span><span class="cx">         work_items = map(unicode, work_items)  # .join expects strings
</span><span class="cx">         self._browser[&quot;work_items&quot;] = &quot; &quot;.join(work_items)
</span><ins>+        high_priority_work_items = map(unicode, high_priority_work_items)
+        self._browser[&quot;high_priority_work_items&quot;] = &quot; &quot;.join(high_priority_work_items)
</ins><span class="cx">         return self._browser.submit().read()
</span><span class="cx"> 
</span><span class="cx">     def _post_work_item_to_ews(self, attachment_id):
</span><span class="lines">@@ -149,9 +151,9 @@
</span><span class="cx">         _log.info(&quot;Releasing lock for work item %s from %s&quot; % (patch.id(), queue_name))
</span><span class="cx">         return NetworkTransaction(convert_404_to_None=True).run(lambda: self._post_release_lock(queue_name, patch))
</span><span class="cx"> 
</span><del>-    def update_work_items(self, queue_name, work_items):
-        _log.debug(&quot;Recording work items: %s for %s&quot; % (work_items, queue_name))
-        return NetworkTransaction().run(lambda: self._post_work_items_to_server(queue_name, work_items))
</del><ins>+    def update_work_items(self, queue_name, high_priority_work_items, work_items):
+        _log.debug(&quot;Recording work items: %s for %s&quot; % (high_priority_work_items + work_items, queue_name))
+        return NetworkTransaction().run(lambda: self._post_work_items_to_server(queue_name, high_priority_work_items, work_items))
</ins><span class="cx"> 
</span><span class="cx">     def update_status(self, queue_name, status, patch=None, results_file=None):
</span><span class="cx">         _log.info(status)
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpycommonnetstatusserver_mockpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/common/net/statusserver_mock.py (174247 => 174248)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/common/net/statusserver_mock.py        2014-10-02 23:47:38 UTC (rev 174247)
+++ trunk/Tools/Scripts/webkitpy/common/net/statusserver_mock.py        2014-10-02 23:49:30 UTC (rev 174248)
</span><span class="lines">@@ -55,9 +55,9 @@
</span><span class="cx">     def release_lock(self, queue_name, patch):
</span><span class="cx">         _log.info(&quot;MOCK: release_lock: %s %s&quot; % (queue_name, patch.id()))
</span><span class="cx"> 
</span><del>-    def update_work_items(self, queue_name, work_items):
</del><ins>+    def update_work_items(self, queue_name, high_priority_work_items, work_items):
</ins><span class="cx">         self._work_items = work_items
</span><del>-        _log.info(&quot;MOCK: update_work_items: %s %s&quot; % (queue_name, work_items))
</del><ins>+        _log.info(&quot;MOCK: update_work_items: %s %s&quot; % (queue_name, high_priority_work_items + work_items))
</ins><span class="cx"> 
</span><span class="cx">     def submit_to_ews(self, patch_id):
</span><span class="cx">         _log.info(&quot;MOCK: submit_to_ews: %s&quot; % (patch_id))
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolbotfeederspy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/tool/bot/feeders.py (174247 => 174248)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/bot/feeders.py        2014-10-02 23:47:38 UTC (rev 174247)
+++ trunk/Tools/Scripts/webkitpy/tool/bot/feeders.py        2014-10-02 23:49:30 UTC (rev 174248)
</span><span class="lines">@@ -50,19 +50,17 @@
</span><span class="cx">         AbstractFeeder.__init__(self, tool)
</span><span class="cx">         self.committer_validator = CommitterValidator(self._tool)
</span><span class="cx"> 
</span><del>-    def _update_work_items(self, item_ids):
-        # FIXME: This is the last use of update_work_items, the commit-queue
-        # should move to feeding patches one at a time like the EWS does.
-        self._tool.status_server.update_work_items(self.queue_name, item_ids)
-        _log.info(&quot;Feeding %s items %s&quot; % (self.queue_name, item_ids))
-
</del><span class="cx">     def feed(self):
</span><span class="cx">         patches = self._validate_patches()
</span><span class="cx">         patches = self._patches_with_acceptable_review_flag(patches)
</span><span class="cx">         patches = sorted(patches, self._patch_cmp)
</span><del>-        patch_ids = [patch.id() for patch in patches]
-        self._update_work_items(patch_ids)
</del><span class="cx"> 
</span><ins>+        high_priority_item_ids = [patch.id() for patch in patches if patch.is_rollout()]
+        item_ids = [patch.id() for patch in patches if not patch.is_rollout()]
+
+        _log.info(&quot;Feeding %s high priority items %s, regular items %s&quot; % (self.queue_name, high_priority_item_ids, item_ids))
+        self._tool.status_server.update_work_items(self.queue_name, high_priority_item_ids, item_ids)
+
</ins><span class="cx">     def _patches_for_bug(self, bug_id):
</span><span class="cx">         return self._tool.bugs.fetch_bug(bug_id).commit_queued_patches(include_invalid=True)
</span><span class="cx"> 
</span><span class="lines">@@ -77,11 +75,6 @@
</span><span class="cx">         return self.committer_validator.patches_after_rejecting_invalid_commiters_and_reviewers(all_patches)
</span><span class="cx"> 
</span><span class="cx">     def _patch_cmp(self, a, b):
</span><del>-        # Sort first by is_rollout, then by attach_date.
-        # Reversing the order so that is_rollout is first.
-        rollout_cmp = cmp(b.is_rollout(), a.is_rollout())
-        if rollout_cmp != 0:
-            return rollout_cmp
</del><span class="cx">         return cmp(a.attach_date(), b.attach_date())
</span><span class="cx"> 
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolbotfeeders_unittestpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/tool/bot/feeders_unittest.py (174247 => 174248)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/bot/feeders_unittest.py        2014-10-02 23:47:38 UTC (rev 174247)
+++ trunk/Tools/Scripts/webkitpy/tool/bot/feeders_unittest.py        2014-10-02 23:49:30 UTC (rev 174248)
</span><span class="lines">@@ -37,6 +37,7 @@
</span><span class="cx"> 
</span><span class="cx"> class FeedersTest(unittest.TestCase):
</span><span class="cx">     def test_commit_queue_feeder(self):
</span><ins>+        self.maxDiff = None
</ins><span class="cx">         feeder = CommitQueueFeeder(MockTool())
</span><span class="cx">         expected_logs = &quot;&quot;&quot;Warning, attachment 10001 on bug 50000 has invalid committer (non-committer@example.com)
</span><span class="cx"> Warning, attachment 10001 on bug 50000 has invalid committer (non-committer@example.com)
</span><span class="lines">@@ -45,8 +46,8 @@
</span><span class="cx"> - If you do not have committer rights please read http://webkit.org/coding/contributing.html for instructions on how to use bugzilla flags.
</span><span class="cx"> 
</span><span class="cx"> - If you have committer rights please correct the error in Tools/Scripts/webkitpy/common/config/contributors.json by adding yourself to the file (no review needed).  The commit-queue restarts itself every 2 hours.  After restart the commit-queue will correctly respect your committer rights.'
</span><ins>+Feeding commit-queue high priority items [10005], regular items [10000]
</ins><span class="cx"> MOCK: update_work_items: commit-queue [10005, 10000]
</span><del>-Feeding commit-queue items [10005, 10000]
</del><span class="cx"> &quot;&quot;&quot;
</span><span class="cx">         OutputCapture().assert_outputs(self, feeder.feed, expected_logs=expected_logs)
</span><span class="cx"> 
</span><span class="lines">@@ -56,19 +57,6 @@
</span><span class="cx">         attachment.attach_date = lambda: attach_date
</span><span class="cx">         return attachment
</span><span class="cx"> 
</span><del>-    def test_patch_cmp(self):
-        long_ago_date = datetime(1900, 1, 21)
-        recent_date = datetime(2010, 1, 21)
-        attachment1 = self._mock_attachment(is_rollout=False, attach_date=recent_date)
-        attachment2 = self._mock_attachment(is_rollout=False, attach_date=long_ago_date)
-        attachment3 = self._mock_attachment(is_rollout=True, attach_date=recent_date)
-        attachment4 = self._mock_attachment(is_rollout=True, attach_date=long_ago_date)
-        attachments = [attachment1, attachment2, attachment3, attachment4]
-        expected_sort = [attachment4, attachment3, attachment2, attachment1]
-        queue = CommitQueueFeeder(MockTool())
-        attachments.sort(queue._patch_cmp)
-        self.assertEqual(attachments, expected_sort)
-
</del><span class="cx">     def test_patches_with_acceptable_review_flag(self):
</span><span class="cx">         class MockPatch(object):
</span><span class="cx">             def __init__(self, patch_id, review):
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolcommandsqueues_unittestpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/tool/commands/queues_unittest.py (174247 => 174248)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/commands/queues_unittest.py        2014-10-02 23:47:38 UTC (rev 174247)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/queues_unittest.py        2014-10-02 23:49:30 UTC (rev 174248)
</span><span class="lines">@@ -128,6 +128,7 @@
</span><span class="cx"> 
</span><span class="cx"> class FeederQueueTest(QueuesTest):
</span><span class="cx">     def test_feeder_queue(self):
</span><ins>+        self.maxDiff = None
</ins><span class="cx">         queue = TestFeederQueue()
</span><span class="cx">         tool = MockTool(log_executive=True)
</span><span class="cx">         expected_logs = {
</span><span class="lines">@@ -139,8 +140,8 @@
</span><span class="cx"> - If you do not have committer rights please read http://webkit.org/coding/contributing.html for instructions on how to use bugzilla flags.
</span><span class="cx"> 
</span><span class="cx"> - If you have committer rights please correct the error in Tools/Scripts/webkitpy/common/config/contributors.json by adding yourself to the file (no review needed).  The commit-queue restarts itself every 2 hours.  After restart the commit-queue will correctly respect your committer rights.'
</span><ins>+Feeding commit-queue high priority items [10005], regular items [10000]
</ins><span class="cx"> MOCK: update_work_items: commit-queue [10005, 10000]
</span><del>-Feeding commit-queue items [10005, 10000]
</del><span class="cx"> Feeding EWS (1 r? patch, 1 new)
</span><span class="cx"> MOCK: submit_to_ews: 10002
</span><span class="cx"> &quot;&quot;&quot;,
</span></span></pre>
</div>
</div>

</body>
</html>