OLD | NEW |
---|---|
(Empty) | |
1 #!/usr/bin/env python | |
mikecase (-- gone --)
2016/06/10 20:59:03
as mentioned, rename script to something more gene
the real yoland
2016/06/10 22:20:39
Done
| |
2 # Copyright (c) 2016 The Chromium Authors. All rights reserved. | |
mikecase (-- gone --)
2016/06/10 20:59:02
No (c) in the Copyright notice.
the real yoland
2016/06/10 22:20:40
Done
| |
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 tracked(disabled/flaky) tests from proguard dump""" | |
mikecase (-- gone --)
2016/06/10 20:59:03
offline you said this was for all annotations. Sti
the real yoland
2016/06/10 22:20:40
Done
| |
7 | |
8 import argparse | |
9 import datetime | |
10 import json | |
11 import linecache | |
12 import logging | |
13 import os | |
14 import pprint | |
15 import re | |
16 import sys | |
17 import time | |
18 | |
19 _SRC_DIR = os.path.abspath(os.path.join( | |
20 os.path.dirname(__file__), '..', '..')) | |
21 | |
22 sys.path.append(os.path.join(_SRC_DIR, 'build', 'android')) | |
23 from pylib import constants | |
24 from pylib.instrumentation import instrumentation_test_instance | |
25 | |
26 sys.path.append(os.path.join(_SRC_DIR, 'third_party', 'catapult', 'devil')) | |
27 from devil.utils import cmd_helper | |
28 | |
29 _DEFAULT_APK_OUTPUT_DIR = os.path.join('out', 'Debug') | |
mikecase (-- gone --)
2016/06/10 20:59:03
Use pylib/constants like GetBuildDirectory or some
| |
30 | |
31 _GIT_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S' | |
32 _EXPORT_TIME_FORMAT = '%Y%m%dT%H%M%S' | |
33 | |
34 _GIT_LOG_TIME_PATTERN = re.compile(r'\d+') | |
35 _GIT_LOG_MESSAGE_PATTERN = r'Cr-Commit-Position: refs/heads/master@{#(\d+)}' | |
36 | |
37 _CRBUG_ID_PATTERN = re.compile(r'crbug(?:.com)?/(\d+)') | |
38 | |
39 _TEST_MASTER_KEY = 'tests' | |
40 _REPORT_MASTER_KEY = 'metadata' | |
41 _REVISION_KEY = 'revision' | |
42 _COMMIT_POS_KEY = 'commit_pos' | |
43 _ANNOTATIONS_KEY = 'annotations' | |
44 _TEST_NAME_KEY = 'test_name' | |
45 _TEST_APK_KEY = 'test_apk_name' | |
46 _CRBUG_KEY = 'bug_id' | |
47 _CLASS_PATH_KEY = 'class_path' | |
48 _CLASS_NAME_KEY = 'class_name' | |
49 _TOTAL_TEST_COUNT_KEY = 'total_test_count' | |
50 _UTC_SCRIPT_RUNTIME= 'script_runtime' | |
51 _UTC_REVISIONTIME_KEY = 'revision_time' | |
52 _PLATFORM_KEY = 'platform' | |
53 _PLATFORM_VALUE = 'android' | |
54 | |
55 | |
56 def _GetBugId(message): | |
57 """Validate bug message format and get bug id""" | |
58 result = re.search(_CRBUG_ID_PATTERN, message) | |
59 if result: | |
60 return int(result.group(1)) | |
61 else: | |
62 return None | |
63 | |
64 | |
65 def _GetAnnotations(test_annotations): | |
66 """Store annotations in the existing anntation_dict and return bug id""" | |
67 bug_id = None | |
68 annotations_dict = {} | |
69 for annotation, content in test_annotations.iteritems(): | |
70 if content is not None and content.get('message') is not None: | |
71 bug_id = _GetBugId(content.get('message')) | |
mikecase (-- gone --)
2016/06/10 20:59:02
Ive seen some tests with multiple bugs attached, l
the real yoland
2016/06/10 22:20:40
That would, except I will do some parsing on the s
| |
72 annotations_dict.update({annotation: content}) | |
73 return bug_id, annotations_dict | |
74 | |
75 | |
76 def _GetTests(test_apks, apk_output_dir): | |
77 """Return a list of all annotated tests and total test count""" | |
78 result = [] | |
79 total_test_count = 0 | |
80 for test_apk in test_apks: | |
81 logging.info('Current test apk: %s', test_apk) | |
82 test_jar = os.path.join( | |
83 apk_output_dir, constants.SDK_BUILD_TEST_JAVALIB_DIR, | |
84 '%s.jar' % test_apk) | |
85 all_tests = instrumentation_test_instance.GetAllTests(test_jar=test_jar) | |
86 for test_class in all_tests: | |
87 class_path = test_class['class'] | |
88 class_name = test_class['class'].split('.')[-1] | |
89 | |
90 class_bug_id, class_annotation = _GetAnnotations( | |
91 test_class['annotations']) | |
92 for test_method in test_class['methods']: | |
93 total_test_count += 1 | |
94 # getting annotation of each test case | |
95 test_bug_id, test_annotations = _GetAnnotations( | |
96 test_method['annotations']) | |
97 test_bug_id = test_bug_id if test_bug_id else class_bug_id | |
98 test_annotations.update(class_annotation) | |
99 # getting test method name of each test | |
100 test_name = test_method['method'] | |
101 test_dict = { | |
102 _CRBUG_KEY: test_bug_id, | |
103 _ANNOTATIONS_KEY: test_annotations, | |
104 _TEST_NAME_KEY: test_name, | |
105 _TEST_APK_KEY: test_apk, | |
106 _CLASS_NAME_KEY: class_name, | |
107 _CLASS_PATH_KEY: class_path | |
108 } | |
109 result.append(test_dict) | |
110 logging.info('Total count of tests in all test apks: %d', total_test_count) | |
111 return result, total_test_count | |
112 | |
113 | |
114 def _GetReportMeta(utc_script_runtime_string, total_test_count): | |
115 """Returns a dictionary of the report's metadata""" | |
116 revision = cmd_helper.GetCmdOutput(['git', 'rev-parse', 'HEAD']).strip() | |
117 raw_string = cmd_helper.GetCmdOutput( | |
118 ['git', 'log', '--pretty=format:%at', '--max-count=1', 'HEAD']) | |
119 time_string_search = re.search(_GIT_LOG_TIME_PATTERN, raw_string) | |
120 if time_string_search is None: | |
121 raise Exception('Timestamp format incorrect, expected all digits, got %s' | |
122 % raw_string) | |
123 | |
124 raw_string = cmd_helper.GetCmdOutput( | |
mikecase (-- gone --)
2016/06/10 20:59:02
Should probably explicitly set the cwd arg to some
| |
125 ['git', 'log', '--pretty=format:%b', '--max-count=1', 'HEAD']) | |
126 commit_pos_search = re.search(_GIT_LOG_MESSAGE_PATTERN, raw_string) | |
127 if commit_pos_search is None: | |
128 raise Exception('Cr-Commit-Position is not found, potentially running with ' | |
129 'uncommited HEAD') | |
130 commit_pos = int(commit_pos_search.group(1)) | |
131 | |
132 utc_revision_time = datetime.datetime.utcfromtimestamp( | |
133 int(time_string_search.group(0))) | |
134 utc_revision_time = utc_revision_time.strftime(_EXPORT_TIME_FORMAT) | |
135 logging.info( | |
136 'revision is %s, revision time is %s', revision, utc_revision_time) | |
137 | |
138 return { | |
139 _REVISION_KEY: revision, | |
140 _COMMIT_POS_KEY: commit_pos, | |
141 _UTC_SCRIPT_RUNTIME: utc_script_runtime_string, | |
142 _UTC_REVISIONTIME_KEY: utc_revision_time, | |
143 _PLATFORM_KEY: _PLATFORM_VALUE, | |
144 _TOTAL_TEST_COUNT_KEY: total_test_count | |
145 } | |
146 | |
147 | |
148 def _GetReport(test_apks, script_runtime_string, apk_output_dir): | |
149 """Generate the dictionary of report data | |
150 | |
151 Args: | |
152 test_apks: a list of apks for search for tests | |
153 script_runtime_string: the time when the script is run at | |
154 format: '%Y%m%dT%H%M%S' | |
155 """ | |
156 | |
157 test_data, total_test_count = _GetTests(test_apks, apk_output_dir) | |
158 report_meta = _GetReportMeta(script_runtime_string, total_test_count) | |
159 report_data = { | |
160 _REPORT_MASTER_KEY: report_meta, | |
161 _TEST_MASTER_KEY: test_data} | |
162 return report_data | |
163 | |
164 | |
165 def main(): | |
166 parser = argparse.ArgumentParser() | |
167 parser.add_argument('-t', '--test-apks', nargs='+', dest='test_apks', | |
168 required=True, | |
169 help='List all test apks file name that the script uses ' | |
170 'to fetch tracked tests from') | |
171 parser.add_argument('--json-output-dir', required=True, | |
172 help='JSON file output directory') | |
173 parser.add_argument('--apk-output-dir', default=_DEFAULT_APK_OUTPUT_DIR, | |
174 help='The output directory of test apks') | |
175 parser.add_argument('-v', '--verbose', action='store_true', default=False, | |
176 help='INFO verbosity') | |
177 | |
178 arguments = parser.parse_args(sys.argv[1:]) | |
179 logging.basicConfig( | |
180 level=logging.INFO if arguments.verbose else logging.WARNING) | |
181 | |
182 script_runtime = datetime.datetime.utcnow() | |
183 script_runtime_string = script_runtime.strftime(_EXPORT_TIME_FORMAT) | |
184 logging.info('Build time is %s', script_runtime_string) | |
185 apk_output_dir = os.path.abspath(os.path.join( | |
186 constants.DIR_SOURCE_ROOT, arguments.apk_output_dir)) | |
187 report_data = _GetReport( | |
188 arguments.test_apks, script_runtime_string, apk_output_dir) | |
189 | |
190 temp_output_dir = arguments.json_output_dir | |
191 json_output_path = os.path.join( | |
192 temp_output_dir, '%s-android-chrome.json' % script_runtime_string) | |
193 with open(json_output_path, 'w') as f: | |
194 json.dump(report_data, f, sort_keys=True, separators=(',',': ')) | |
195 logging.info('Saved json output file to %s', json_output_path) | |
196 | |
197 if __name__ == '__main__': | |
198 main() | |
OLD | NEW |