Changeset 52145 in webkit


Ignore:
Timestamp:
Dec 15, 2009 2:07:17 AM (14 years ago)
Author:
eric@webkit.org
Message:

2009-12-15 Eric Seidel <eric@webkit.org>

Reviewed by Adam Barth.

queue sub-commands need --status-host so they can report status
https://bugs.webkit.org/show_bug.cgi?id=32313

Make --status-bot a global option and make
run_bugzilla_tool pass --status-bot to sub-commands.

  • Scripts/bugzilla-tool:
    • Rename _status to status_bot and make it non-lazy.
  • Scripts/modules/commands/queues.py:
    • Move status updates out of WorkQueue and into individual queues.
  • Scripts/modules/commands/queues_unittest.py:
    • Test that --status-host is passed to bugzilla-tool when run as subcommand.
  • Scripts/modules/mock_bugzillatool.py:
    • Add a MockStatusBot
  • Scripts/modules/workqueue.py:
    • Remove status_host and work_work_logs_directory callbacks.
    • Add new work_item_log_path callback so that WorkQueue doesn't need to know about patches!
  • Scripts/modules/workqueue_unittest.py:
    • Update unit tests to reflect new callbacks.
Location:
trunk/WebKitTools
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebKitTools/ChangeLog

    r52142 r52145  
     12009-12-15  Eric Seidel  <eric@webkit.org>
     2
     3        Reviewed by Adam Barth.
     4
     5        queue sub-commands need --status-host so they can report status
     6        https://bugs.webkit.org/show_bug.cgi?id=32313
     7
     8        Make --status-bot a global option and make
     9        run_bugzilla_tool pass --status-bot to sub-commands.
     10
     11        * Scripts/bugzilla-tool:
     12         - Rename _status to status_bot and make it non-lazy.
     13        * Scripts/modules/commands/queues.py:
     14         - Move status updates out of WorkQueue and into individual queues.
     15        * Scripts/modules/commands/queues_unittest.py:
     16         - Test that --status-host is passed to bugzilla-tool when run as subcommand.
     17        * Scripts/modules/mock_bugzillatool.py:
     18         - Add a MockStatusBot
     19        * Scripts/modules/workqueue.py:
     20         - Remove status_host and work_work_logs_directory callbacks.
     21         - Add new work_item_log_path callback so that WorkQueue doesn't need to know about patches!
     22        * Scripts/modules/workqueue_unittest.py:
     23         - Update unit tests to reflect new callbacks.
     24
    1252009-12-15  Adam Barth  <abarth@webkit.org>
    226
  • trunk/WebKitTools/Scripts/bugzilla-tool

    r52131 r52145  
    4949        MultiCommandTool.__init__(self)
    5050        self.global_option_parser.add_option("--dry-run", action="callback", help="do not touch remote servers", callback=self.dry_run_callback)
     51        self.global_option_parser.add_option("--status-host", action="callback", type="string", nargs=1, help="Hostname (e.g. localhost or commit.webkit.org) where status updates should be posted.", callback=self.status_host_callback)
    5152
    5253        self.bugs = Bugzilla()
     
    5455        self.executive = Executive()
    5556        self._scm = None
    56         self._status = None
     57        self.status_bot = StatusBot()
    5758
    5859    def dry_run_callback(self, option, opt, value, parser):
    5960        self.scm().dryrun = True
    6061        self.bugs.dryrun = True
     62
     63    def status_host_callback(self, option, opt, value, parser):
     64        self.status_bot.set_host(value)
    6165
    6266    def scm(self):
     
    7680
    7781        return self._scm
    78 
    79     def status(self):
    80         if not self._status:
    81             self._status = StatusBot()
    82         return self._status
    8382
    8483    def path(self):
  • trunk/WebKitTools/Scripts/modules/commands/queues.py

    r52129 r52145  
    2929# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    3030
     31import os
    3132import re
    3233
    3334from datetime import datetime
    3435from optparse import make_option
     36from StringIO import StringIO
    3537
    3638from modules.executive import ScriptError
     
    4951        options_list = (options or []) + [
    5052            make_option("--no-confirm", action="store_false", dest="confirm", default=True, help="Do not ask the user for confirmation before running the queue.  Dangerous!"),
    51             make_option("--status-host", action="store", type="string", dest="status_host", default=StatusBot.default_host, help="Hostname (e.g. localhost or commit.webkit.org) where status updates should be posted."),
    5253        ]
    5354        Command.__init__(self, "Run the %s" % self.name, options=options_list)
     
    5960            log("Failed to CC watchers: %s." % e)
    6061
     62    def _updates_status(self, message, patch, results_file=None):
     63        self.tool.status_bot.update_status(self.name, message, patch, results_file)
     64
    6165    def queue_log_path(self):
    6266        return "%s.log" % self.name
    6367
    64     def work_logs_directory(self):
    65         return "%s-logs" % self.name
    66 
    67     def status_host(self):
    68         return self.options.status_host
     68    def work_item_log_path(self, patch):
     69        return os.path.join("%s-logs" % self.name, "%s.log" % patch["bug_id"])
    6970
    7071    def begin_work_queue(self):
     
    9293
    9394    def run_bugzilla_tool(self, args):
    94         bugzilla_tool_args = [self.tool.path()] + map(str, args)
     95        bugzilla_tool_args = [self.tool.path()]
     96        # FIXME: This is a hack, we should have a more general way to pass global options.
     97        bugzilla_tool_args += ["--status-host=%s" % self.tool.status_bot.statusbot_host]
     98        bugzilla_tool_args += map(str, args)
    9599        self.tool.executive.run_and_throw_if_fail(bugzilla_tool_args)
    96100
     
    118122        patches = self.tool.bugs.fetch_patches_from_commit_queue(reject_invalid_patches=True)
    119123        if not patches:
     124            self._updates_status("Empty queue.", None)
    120125            return None
    121126        # Only bother logging if we have patches in the queue.
     
    127132        if red_builders_names:
    128133            red_builders_names = map(lambda name: "\"%s\"" % name, red_builders_names) # Add quotes around the names.
    129             return (False, "Builders [%s] are red. See http://build.webkit.org." % ", ".join(red_builders_names), None)
    130         return (True, "Landing patch %s from bug %s." % (patch["id"], patch["bug_id"]), patch)
     134            self._updates_status("Builders [%s] are red. See http://build.webkit.org." % ", ".join(red_builders_names), None)
     135            return False
     136        self._updates_status("Landing patch %s from bug %s." % (patch["id"], patch["bug_id"]), patch)
     137        return True
    131138
    132139    def process_work_item(self, patch):
     
    163170    def begin_work_queue(self):
    164171        AbstractQueue.begin_work_queue(self)
    165         self.tool.status().set_host(self.options.status_host)
    166172        self._patches = PersistentPatchCollection(self)
    167173
     
    193199
    194200    def should_proceed_with_work_item(self, patch):
    195         return (True, "Checking style for patch %s on bug %s." % (patch["id"], patch["bug_id"]), patch)
     201        self._update_status("Checking style for patch %s on bug %s." % (patch["id"], patch["bug_id"]), patch)
     202        return True
    196203
    197204    def process_work_item(self, patch):
  • trunk/WebKitTools/Scripts/modules/commands/queues_unittest.py

    r51889 r52145  
    5656        self._assert_log_progress_output([1], "1 patch in test-queue [1]\n")
    5757
    58     def _assert_run_bugzilla_tool_output(self, run_args, tool_output):
     58    def _assert_run_bugzilla_tool(self, run_args):
    5959        queue = TestQueue()
    60         queue.bind_to_tool(MockBugzillaTool())
    61         # MockBugzillaTool.path() is "echo"
    62         self._assert_output(queue.run_bugzilla_tool, [run_args], expected_stdout=tool_output)
     60        tool = MockBugzillaTool()
     61        queue.bind_to_tool(tool)
     62
     63        queue.run_bugzilla_tool(run_args)
     64        expected_run_args = ["echo", "--status-host=example.com"] + map(str, run_args)
     65        tool.executive.run_and_throw_if_fail.assert_called_with(expected_run_args)
    6366
    6467    def test_run_bugzilla_tool(self):
    65         self._assert_run_bugzilla_tool_output([1], "")
    66         self._assert_run_bugzilla_tool_output(["one", 2], "")
     68        self._assert_run_bugzilla_tool([1])
     69        self._assert_run_bugzilla_tool(["one", 2])
  • trunk/WebKitTools/Scripts/modules/mock_bugzillatool.py

    r52130 r52145  
    143143
    144144
     145class MockStatusBot(object):
     146    def __init__(self):
     147        self.statusbot_host = "example.com"
     148
     149
    145150class MockBugzillaTool():
    146151    def __init__(self):
     
    149154        self.executive = Mock()
    150155        self._scm = MockSCM()
     156        self.status_bot = MockStatusBot()
    151157
    152158    def scm(self):
  • trunk/WebKitTools/Scripts/modules/statusbot.py

    r51753 r52145  
    2828#
    2929# WebKit's Python module for interacting with the Commit Queue status page.
     30
     31from modules.logging import log
    3032
    3133# WebKit includes a built copy of BeautifulSoup in Scripts/modules
     
    6668            return
    6769
     70        log(status)
    6871        update_status_url = "%s/update-status" % self.statusbot_server_url
    6972        self.browser.open(update_status_url)
  • trunk/WebKitTools/Scripts/modules/workqueue.py

    r51903 r52145  
    4646        raise NotImplementedError, "subclasses must implement"
    4747
    48     def work_logs_directory(self):
    49         raise NotImplementedError, "subclasses must implement"
    50 
    51     def status_host(self):
     48    def work_item_log_path(self, work_item):
    5249        raise NotImplementedError, "subclasses must implement"
    5350
     
    9188    def run(self):
    9289        self._begin_logging()
    93         self.status_bot = StatusBot(host=self._delegate.status_host())
    9490
    9591        self._delegate.begin_work_queue()
     
    9995                work_item = self._delegate.next_work_item()
    10096                if not work_item:
    101                     self._update_status_and_sleep("Empty queue.")
     97                    self._sleep("No work item.")
    10298                    continue
    103                 (safe_to_proceed, waiting_message, patch) = self._delegate.should_proceed_with_work_item(work_item)
    104                 if not safe_to_proceed:
    105                     self._update_status_and_sleep(waiting_message)
     99                if not self._delegate.should_proceed_with_work_item(work_item):
     100                    self._sleep("Not proceeding with work item.")
    106101                    continue
    107                 self.status_bot.update_status(self._name, waiting_message, patch)
    108102            except KeyboardInterrupt, e:
    109103                log("\nUser terminated queue.")
     
    116110
    117111            # FIXME: Work logs should not depend on bug_id specificaly.
    118             self._open_work_log(patch["bug_id"])
     112            self._open_work_log(work_item)
    119113            try:
    120114                self._delegate.process_work_item(work_item)
     
    133127        self._work_log = None
    134128
    135     def _open_work_log(self, bug_id):
    136         work_log_path = os.path.join(self._delegate.work_logs_directory(), "%s.log" % bug_id)
    137         self._work_log = self._output_tee.add_log(work_log_path)
     129    def _open_work_log(self, work_item):
     130        work_item_log_path = self._delegate.work_item_log_path(work_item)
     131        self._work_log = self._output_tee.add_log(work_item_log_path)
    138132
    139133    def _ensure_work_log_closed(self):
     
    152146        log(cls._sleep_message(message))
    153147        time.sleep(cls.seconds_to_sleep)
    154 
    155     def _update_status_and_sleep(self, message):
    156         status_message = self._sleep_message(message)
    157         self.status_bot.update_status(self._name, status_message)
    158         log(status_message)
    159         time.sleep(self.seconds_to_sleep)
  • trunk/WebKitTools/Scripts/modules/workqueue_unittest.py

    r51972 r52145  
    4444    expected_callbacks = [
    4545        'queue_log_path',
    46         'status_host',
    4746        'begin_work_queue',
    4847        'should_continue_work_queue',
    4948        'next_work_item',
    5049        'should_proceed_with_work_item',
    51         'work_logs_directory',
     50        'work_item_log_path',
    5251        'process_work_item',
    5352        'should_continue_work_queue'
     
    6160        return os.path.join(self._test.temp_dir, "queue_log_path")
    6261
    63     def work_logs_directory(self):
    64         self.record("work_logs_directory")
    65         return os.path.join(self._test.temp_dir, "work_log_path")
    66 
    67     def status_host(self):
    68         self.record("status_host")
    69         return None
     62    def work_item_log_path(self, work_item):
     63        self.record("work_item_log_path")
     64        return os.path.join(self._test.temp_dir, "work_log_path", "%s.log" % work_item)
    7065
    7166    def begin_work_queue(self):
     
    112107        self.record("should_proceed_with_work_item")
    113108        self._test.assertEquals(work_item, "work_item")
    114         fake_patch = { 'bug_id' : 42 }
    115         return (False, "waiting_message", fake_patch)
     109        return False
    116110
    117111
     
    123117    seconds_to_sleep = 0
    124118
    125     def _update_status_and_sleep(self, message):
     119    def _sleep(self, message):
    126120        pass
    127121
     
    133127        work_queue.run()
    134128        self.assertEquals(delegate._callbacks, LoggingDelegate.expected_callbacks)
    135         self.assertTrue(os.path.exists(delegate.queue_log_path()))
    136         self.assertTrue(os.path.exists(os.path.join(delegate.work_logs_directory(), "42.log")))
     129        self.assertTrue(os.path.exists(os.path.join(self.temp_dir, "queue_log_path")))
     130        self.assertTrue(os.path.exists(os.path.join(self.temp_dir, "work_log_path", "work_item.log")))
    137131
    138132    def test_unexpected_error(self):
Note: See TracChangeset for help on using the changeset viewer.