| # Copyright (C) 2019 Apple Inc. All rights reserved. |
| # |
| # Redistribution and use in source and binary forms, with or without |
| # modification, are permitted provided that the following conditions |
| # are met: |
| # 1. Redistributions of source code must retain the above copyright |
| # notice, this list of conditions and the following disclaimer. |
| # 2. Redistributions in binary form must reproduce the above copyright |
| # notice, this list of conditions and the following disclaimer in the |
| # documentation and/or other materials provided with the distribution. |
| # |
| # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND |
| # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR |
| # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| import json |
| |
| |
| class LayoutTestFailures(object): |
| _JSON_PREFIX = "ADD_RESULTS(" |
| _JSON_SUFFIX = ");" |
| |
| def __init__(self, failing_tests, did_exceed_test_failure_limit): |
| self.failing_tests = failing_tests |
| self.did_exceed_test_failure_limit = did_exceed_test_failure_limit |
| |
| @classmethod |
| def has_json_wrapper(cls, string): |
| return string.startswith(cls._JSON_PREFIX) and string.endswith(cls._JSON_SUFFIX) |
| |
| @classmethod |
| def strip_json_wrapper(cls, json_content): |
| if cls.has_json_wrapper(json_content): |
| return json_content[len(cls._JSON_PREFIX):len(json_content) - len(cls._JSON_SUFFIX)] |
| return json_content |
| |
| @classmethod |
| def results_from_string(cls, string): |
| if not string: |
| return None |
| |
| string = string.strip() |
| if not cls.has_json_wrapper(string): |
| return None |
| |
| content_string = cls.strip_json_wrapper(string) |
| # Workaround for https://github.com/buildbot/buildbot/issues/4906 |
| content_string = ''.join(content_string.splitlines()) |
| json_dict = json.loads(content_string) |
| |
| failing_tests = [] |
| |
| def get_failing_tests(test, result): |
| if result.get('report') in ['REGRESSION', 'MISSING']: |
| failing_tests.append(test) |
| |
| cls.parse_full_results_json(json_dict['tests'], get_failing_tests) |
| return cls(failing_tests, json_dict.get('interrupted', False)) |
| |
| @classmethod |
| def parse_full_results_json(cls, tree, handler, prefix=''): |
| for key in tree: |
| new_prefix = (prefix + '/' + key) if prefix else key |
| if 'actual' not in tree[key]: |
| cls.parse_full_results_json(tree[key], handler, new_prefix) |
| else: |
| handler(new_prefix, tree[key]) |