tizen beta release
[profile/ivi/webkit-efl.git] / 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 os
27
28 from webkitpy.common.memoized import memoized
29 from webkitpy.tool.servers.reflectionhandler import ReflectionHandler
30 from webkitpy.layout_tests.controllers.test_expectations_editor import BugManager, TestExpectationsEditor
31 from webkitpy.layout_tests.models.test_expectations import TestExpectationParser, TestExpectations, TestExpectationSerializer
32 from webkitpy.layout_tests.models.test_configuration import TestConfigurationConverter
33 from webkitpy.layout_tests.port import builders
34
35
36 class BuildCoverageExtrapolator(object):
37     def __init__(self, test_configuration_converter):
38         self._test_configuration_converter = test_configuration_converter
39
40     @memoized
41     def _covered_test_configurations_for_builder_name(self):
42         coverage = {}
43         for builder_name in builders.all_builder_names():
44             coverage[builder_name] = self._test_configuration_converter.to_config_set(builders.coverage_specifiers_for_builder_name(builder_name))
45         return coverage
46
47     def extrapolate_test_configurations(self, builder_name):
48         return self._covered_test_configurations_for_builder_name()[builder_name]
49
50
51 class GardeningExpectationsUpdater(BugManager):
52     def __init__(self, tool, port):
53         self._converter = TestConfigurationConverter(port.all_test_configurations(), port.configuration_specifier_macros())
54         self._extrapolator = BuildCoverageExtrapolator(self._converter)
55         self._parser = TestExpectationParser(port, [], allow_rebaseline_modifier=False)
56         self._path_to_test_expectations_file = port.path_to_test_expectations_file()
57         self._tool = tool
58
59     def close_bug(self, bug_id, reference_bug_id=None):
60         # FIXME: Implement this properly.
61         pass
62
63     def create_bug(self):
64         return "BUG_NEW"
65
66     def update_expectations(self, failure_info_list):
67         expectation_lines = TestExpectationParser.tokenize_list(self._tool.filesystem.read_text_file(self._path_to_test_expectations_file))
68         for expectation_line in expectation_lines:
69             self._parser.parse(expectation_line)
70         editor = TestExpectationsEditor(expectation_lines, self)
71         updated_expectation_lines = []
72         # FIXME: Group failures by testName+failureTypeList.
73         for failure_info in failure_info_list:
74             expectation_set = set(filter(lambda expectation: expectation is not None,
75                                          map(TestExpectations.expectation_from_string, failure_info['failureTypeList'])))
76             assert(expectation_set)
77             test_name = failure_info['testName']
78             assert(test_name)
79             builder_name = failure_info['builderName']
80             affected_test_configuration_set = self._extrapolator.extrapolate_test_configurations(builder_name)
81             updated_expectation_lines.extend(editor.update_expectation(test_name, affected_test_configuration_set, expectation_set))
82         self._tool.filesystem.write_text_file(self._path_to_test_expectations_file, TestExpectationSerializer.list_to_string(expectation_lines, self._converter, reconstitute_only_these=updated_expectation_lines))
83
84
85 class GardeningHTTPServer(BaseHTTPServer.HTTPServer):
86     def __init__(self, httpd_port, config):
87         server_name = ''
88         self.tool = config['tool']
89         BaseHTTPServer.HTTPServer.__init__(self, (server_name, httpd_port), GardeningHTTPRequestHandler)
90
91     def url(self):
92         return 'file://' + os.path.join(GardeningHTTPRequestHandler.STATIC_FILE_DIRECTORY, 'garden-o-matic.html')
93
94
95 class GardeningHTTPRequestHandler(ReflectionHandler):
96     STATIC_FILE_NAMES = frozenset()
97
98     STATIC_FILE_DIRECTORY = os.path.join(
99         os.path.dirname(__file__),
100         '..',
101         '..',
102         '..',
103         '..',
104         'BuildSlaveSupport',
105         'build.webkit.org-config',
106         'public_html',
107         'TestFailures')
108
109     allow_cross_origin_requests = True
110
111     def _run_webkit_patch(self, args):
112         return self.server.tool.executive.run_command([self.server.tool.path()] + args, cwd=self.server.tool.scm().checkout_root)
113
114     @memoized
115     def _expectations_updater(self):
116         # FIXME: Should split failure_info_list into lists per port, then edit each expectations file separately.
117         # For now, assume Chromium port.
118         port = self.server.tool.get("chromium-win-win7")
119         return GardeningExpectationsUpdater(self.server.tool, port)
120
121     def rollout(self):
122         revision = self.query['revision'][0]
123         reason = self.query['reason'][0]
124         self._run_webkit_patch([
125             'rollout',
126             '--force-clean',
127             '--non-interactive',
128             revision,
129             reason,
130         ])
131         self._serve_text('success')
132
133     def ping(self):
134         self._serve_text('pong')
135
136     def updateexpectations(self):
137         self._expectations_updater().update_expectations(self._read_entity_body_as_json())
138         self._serve_text('success')
139
140     def rebaseline(self):
141         builder = self.query['builder'][0]
142         test = self.query['test'][0]
143         self._run_webkit_patch([
144             'rebaseline-test',
145             builder,
146             test,
147         ])
148         self._serve_text('success')
149
150     def optimizebaselines(self):
151         test = self.query['test'][0]
152         self._run_webkit_patch([
153             'optimize-baselines',
154             test,
155         ])
156         self._serve_text('success')