1 # Copyright (C) 2011 Google Inc. All rights reserved.
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are
7 # 1. Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer.
9 # 2. Redistributions in binary form must reproduce the above copyright
10 # notice, this list of conditions and the following disclaimer in the
11 # documentation and/or other materials provided with the distribution.
13 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
14 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
15 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
16 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
17 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 from webkitpy.common.memoized import memoized
35 from webkitpy.tool.servers.reflectionhandler import ReflectionHandler
36 from webkitpy.layout_tests.port import builders
39 _log = logging.getLogger(__name__)
42 class GardeningHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
43 def __init__(self, httpd_port, config):
45 self.tool = config['tool']
46 self.options = config['options']
47 BaseHTTPServer.HTTPServer.__init__(self, (server_name, httpd_port), GardeningHTTPRequestHandler)
49 def url(self, args=None):
50 # We can't use urllib.encode() here because that encodes spaces as plus signs and the buildbots don't decode those properly.
51 arg_string = ('?' + '&'.join("%s=%s" % (key, urllib.quote(value)) for (key, value) in args.items())) if args else ''
52 return 'http://localhost:8127/garden-o-matic.html' + arg_string
55 class GardeningHTTPRequestHandler(ReflectionHandler):
57 BLINK_SVN_URL = 'http://src.chromium.org/blink/trunk'
58 CHROMIUM_SVN_DEPS_URL = 'http://src.chromium.org/chrome/trunk/src/DEPS'
59 # "webkit_revision": "149598",
60 BLINK_REVISION_REGEXP = re.compile(r'^ "webkit_revision": "(?P<revision>\d+)",$', re.MULTILINE);
62 STATIC_FILE_NAMES = frozenset()
64 STATIC_FILE_EXTENSIONS = ('.js', '.css', '.html', '.gif', '.png', '.ico')
66 STATIC_FILE_DIRECTORY = os.path.join(
67 os.path.dirname(__file__),
74 allow_cross_origin_requests = True
78 self._serve_text('pong')
80 def _run_webkit_patch(self, command, input_string):
81 PIPE = self.server.tool.executive.PIPE
82 process = self.server.tool.executive.popen([self.server.tool.path()] + command, cwd=self.server.tool.scm().checkout_root, stdin=PIPE, stdout=PIPE, stderr=PIPE)
83 process.stdin.write(input_string)
84 output, error = process.communicate()
85 return (process.returncode, output, error)
88 self._serve_xml(self.server.tool.executive.run_command(['svn', 'log', '--xml', '--limit', self.REVISION_LIMIT, self.BLINK_SVN_URL]))
91 deps_contents = self.server.tool.executive.run_command(['svn', 'cat', self.CHROMIUM_SVN_DEPS_URL])
92 match = re.search(self.BLINK_REVISION_REGEXP, deps_contents)
94 _log.error("Unable to produce last Blink roll revision")
98 revision_line = match.group()
99 revision = match.group("revision")
100 self._serve_text(revision)
102 def rebaselineall(self):
103 command = ['rebaseline-json']
104 if self.server.options.results_directory:
105 command.extend(['--results-directory', self.server.options.results_directory])
106 if not self.server.options.optimize:
107 command.append('--no-optimize')
108 if self.server.options.verbose:
109 command.append('--verbose')
110 json_input = self.read_entity_body()
112 _log.debug("calling %s, input='%s'", command, json_input)
113 return_code, output, error = self._run_webkit_patch(command, json_input)
114 print >> sys.stderr, error
115 json_result = {"return_code": return_code}
117 _log.error("rebaseline-json failed: %d, output='%s'" % (return_code, output))
118 json_result["output"] = output
120 _log.debug("rebaseline-json succeeded")
122 self._serve_text(json.dumps(json_result))
124 def localresult(self):
125 path = self.query['path'][0]
126 filesystem = self.server.tool.filesystem
128 # Ensure that we're only serving files from inside the results directory.
129 if not filesystem.isabs(path) and self.server.options.results_directory:
130 fullpath = filesystem.abspath(filesystem.join(self.server.options.results_directory, path))
131 if fullpath.startswith(filesystem.abspath(self.server.options.results_directory)):
132 self._serve_file(fullpath, headers_only=(self.command == 'HEAD'))
135 self.send_response(403)