Upstream version 9.37.197.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Tools / Scripts / webkitpy / tool / servers / gardeningserver.py
1 # Copyright (C) 2011 Google Inc. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are
5 # met:
6 #
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.
12 #
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.
24
25 import BaseHTTPServer
26 import SocketServer
27 import logging
28 import json
29 import os
30 import re
31 import sys
32 import urllib
33
34 from webkitpy.common.memoized import memoized
35 from webkitpy.tool.servers.reflectionhandler import ReflectionHandler
36 from webkitpy.layout_tests.port import builders
37
38
39 _log = logging.getLogger(__name__)
40
41
42 class GardeningHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
43     def __init__(self, httpd_port, config):
44         server_name = ''
45         self.tool = config['tool']
46         self.options = config['options']
47         BaseHTTPServer.HTTPServer.__init__(self, (server_name, httpd_port), GardeningHTTPRequestHandler)
48
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
53
54
55 class GardeningHTTPRequestHandler(ReflectionHandler):
56     REVISION_LIMIT = 100
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);
61
62     STATIC_FILE_NAMES = frozenset()
63
64     STATIC_FILE_EXTENSIONS = ('.js', '.css', '.html', '.gif', '.png', '.ico')
65
66     STATIC_FILE_DIRECTORY = os.path.join(
67         os.path.dirname(__file__),
68         '..',
69         '..',
70         '..',
71         '..',
72         'GardeningServer')
73
74     allow_cross_origin_requests = True
75     debug_output = ''
76
77     def ping(self):
78         self._serve_text('pong')
79
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)
86
87     def svnlog(self):
88         self._serve_xml(self.server.tool.executive.run_command(['svn', 'log', '--xml', '--limit', self.REVISION_LIMIT, self.BLINK_SVN_URL]))
89
90     def lastroll(self):
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)
93         if not match:
94             _log.error("Unable to produce last Blink roll revision")
95             self._serve_text("0")
96             return
97
98         revision_line = match.group()
99         revision = match.group("revision")
100         self._serve_text(revision)
101
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()
111
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}
116         if return_code:
117             _log.error("rebaseline-json failed: %d, output='%s'" % (return_code, output))
118             json_result["output"] = output
119         else:
120             _log.debug("rebaseline-json succeeded")
121
122         self._serve_text(json.dumps(json_result))
123
124     def localresult(self):
125         path = self.query['path'][0]
126         filesystem = self.server.tool.filesystem
127
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'))
133                 return
134
135         self.send_response(403)