OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2016 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. |
| 5 |
| 6 """Finds all the disabled tests from proguard dump""" |
| 7 |
| 8 import argparse |
| 9 import datetime |
| 10 import json |
| 11 import linecache |
| 12 import logging |
| 13 import os |
| 14 import re |
| 15 import sys |
| 16 import time |
| 17 import pprint |
| 18 |
| 19 |
| 20 _SRC_DIR = os.path.abspath(os.path.join( |
| 21 os.path.dirname(__file__), '..', '..')) |
| 22 |
| 23 sys.path.append(os.path.join(_SRC_DIR, 'build', 'android')) |
| 24 |
| 25 from pylib import constants |
| 26 from pylib.instrumentation import instrumentation_test_instance |
| 27 |
| 28 sys.path.append(os.path.join(_SRC_DIR, 'third_party', 'catapult', 'devil')) |
| 29 from devil.utils import cmd_helper |
| 30 |
| 31 _DISABLED_TESTS_ANNOTATION_LIST = {'DisabledTest': None, 'FlakyTest': None} |
| 32 _GIT_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S' |
| 33 _EXPORT_TIME_FORMAT = '%Y%m%dT%H%M%S' |
| 34 |
| 35 class JSONKeyName(object): |
| 36 TEST_MASTER_KEY = 'tests' |
| 37 RECORD_MASTER_KEY = 'records' |
| 38 REVISION_KEY = 'revision' |
| 39 STATUS_KEY = 'status' |
| 40 TEST_NAME_KEY = 'name' |
| 41 CRBUG_KEY = 'bug_id' |
| 42 CLASS_PATH_KEY = 'class_path' |
| 43 CLASS_NAME_KEY = 'class_name' |
| 44 DF_TEST_AMOUNT_KEY = 'df_test_amount' |
| 45 TOTAL_TEST_AMOUNT_KEY = 'total_test_amount' |
| 46 UTC_BUILDTIME_KEY = 'utc_buildtime' |
| 47 UTC_REVISIONTIME_KEY = 'utc_revisiontime' |
| 48 PLATFORM_KEY = 'platform' |
| 49 PLATFORM_VALUE = 'android' |
| 50 |
| 51 def _SerializeTests(arguments): |
| 52 """Create instrumentation test instance and extract disabled tests info""" |
| 53 total_test_amount = 0 |
| 54 disabled_test_list = [] |
| 55 for test_apk in arguments.test_apks: |
| 56 arguments.test_apk = test_apk |
| 57 test_jar = os.path.join( |
| 58 constants.GetOutDirectory(), constants.SDK_BUILD_TEST_JAVALIB_DIR, |
| 59 '%s.jar' % arguments.test_apk) |
| 60 temp_disabled_test_list = instrumentation_test_instance.GetFilteredTests( |
| 61 test_jar=test_jar, |
| 62 test_filter=None, |
| 63 annotations=arguments.annotations, |
| 64 exclude_annotations=None |
| 65 ) |
| 66 disabled_test_list.extend(temp_disabled_test_list) |
| 67 total_test_amount += instrumentation_test_instance.TotalTestAmount(test_jar) |
| 68 result = [] |
| 69 for test_class in disabled_test_list: |
| 70 class_path = test_class['class'] |
| 71 class_name = test_class['class'].split('.')[-1] |
| 72 for test_method in test_class['methods']: |
| 73 # getting annotation of each test case |
| 74 bug_id = None |
| 75 status = [] |
| 76 test_annotations = test_method['annotations'] |
| 77 assert len(test_annotations) != 0 |
| 78 for annotation, content in test_annotations.iteritems(): |
| 79 if content is not None: |
| 80 bug_id = content['message'] |
| 81 status.append(annotation) |
| 82 # getting test method name of each test |
| 83 test_name = test_method['method'] |
| 84 test_dict = { |
| 85 JSONKeyName.CRBUG_KEY: bug_id, |
| 86 JSONKeyName.STATUS_KEY: status, |
| 87 JSONKeyName.TEST_NAME_KEY: test_name, |
| 88 JSONKeyName.CLASS_NAME_KEY: class_name, |
| 89 JSONKeyName.CLASS_PATH_KEY: class_path |
| 90 } |
| 91 result.append(test_dict) |
| 92 return result, total_test_amount |
| 93 |
| 94 def _AddRecord(disabled_test_list, utc_buildtime_string, total_test_amount): |
| 95 disabled_test_number = len(disabled_test_list) |
| 96 |
| 97 revision = cmd_helper.GetCmdOutput(['git', 'rev-parse', 'HEAD']).strip() |
| 98 raw_time_string = cmd_helper.GetCmdOutput( |
| 99 ['git', 'log', '--pretty=format:%aI', '--max-count=1', 'HEAD']) |
| 100 time_string_search = re.search(r'\d+-\d+-\d+T\d+:\d+:\d+', raw_time_string) |
| 101 if time_string_search is None: |
| 102 raise Exception('Time format incorrect') |
| 103 |
| 104 revision_time = time.strptime(time_string_search.group(0), _GIT_TIME_FORMAT) |
| 105 utc_revision_time = datetime.datetime.utcfromtimestamp( |
| 106 time.mktime(revision_time)) |
| 107 utc_revision_time = utc_revision_time.strftime(_EXPORT_TIME_FORMAT) |
| 108 |
| 109 record_data = [{ |
| 110 JSONKeyName.REVISION_KEY: revision, |
| 111 JSONKeyName.UTC_BUILDTIME_KEY: utc_buildtime_string, |
| 112 JSONKeyName.UTC_REVISIONTIME_KEY: utc_revision_time, |
| 113 JSONKeyName.PLATFORM_KEY: JSONKeyName.PLATFORM_VALUE, |
| 114 JSONKeyName.DF_TEST_AMOUNT_KEY: disabled_test_number, |
| 115 JSONKeyName.TOTAL_TEST_AMOUNT_KEY: total_test_amount |
| 116 }] |
| 117 return record_data |
| 118 |
| 119 def main(): |
| 120 default_build_type = os.environ.get('BUILDTYPE', 'Debug') |
| 121 parser = argparse.ArgumentParser() |
| 122 parser.add_argument('-t', '--test-apks', action='append', default=[], |
| 123 dest='test_apks', help='List all test apks file name ' + |
| 124 'that the script uses to fetch disabled tests from') |
| 125 # TODO(yolandyan): if builder uses incremental script, jar path changes |
| 126 parser.add_argument('--test_apk_incremental_install_script') |
| 127 parser.add_argument( |
| 128 '--debug', action='store_const', const='Debug', dest='build_type', |
| 129 default=default_build_type, |
| 130 help=('If set, run test suites under out/Debug. ' |
| 131 'Default is env var BUILDTYPE or Debug.')) |
| 132 parser.add_argument('-o', '--output-path', |
| 133 help='JSON file output to be uploaded on to gcs') |
| 134 parser.add_argument('-a', '--annotations', dest='annotations', |
| 135 action='append', default=['DisabledTest', 'FlakyTest'], |
| 136 help='Disabled tests annotations, seperated by ,' + |
| 137 'e.g. --annotation-str=DisabledTest,FlakyTest') |
| 138 |
| 139 arguments = parser.parse_args(sys.argv[1:]) |
| 140 arguments.annotations = dict((x, None) for x in arguments.annotations) |
| 141 constants.SetBuildType(arguments.build_type) |
| 142 |
| 143 buildtime = datetime.datetime.utcnow() |
| 144 buildtime_string = buildtime.strftime('%Y%m%dT%H%M%S') |
| 145 test_data, total_test_amount = _SerializeTests(arguments) |
| 146 record_data = _AddRecord(test_data, buildtime_string, total_test_amount) |
| 147 |
| 148 if arguments.output_path is None: |
| 149 output_path = constants.GetOutDirectory() |
| 150 else: |
| 151 output_path = arguments.output_path |
| 152 json_output_path = os.path.join(output_path, |
| 153 '%s-android-chrome.json' % buildtime_string) |
| 154 export_data = { |
| 155 JSONKeyName.RECORD_MASTER_KEY: record_data, |
| 156 JSONKeyName.TEST_MASTER_KEY: test_data |
| 157 } |
| 158 with open(json_output_path, 'w') as f: |
| 159 json.dump(export_data, f, indent=2, sort_keys=True) |
| 160 |
| 161 if __name__ == "__main__": |
| 162 main() |
OLD | NEW |