Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: tools/android/find_disabled_tests.py

Issue 1851143002: Find annotated tests by exposing API in instrumentation_test_instance (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #!/usr/bin/env python
jbudorick 2016/04/28 14:17:14 Can you move this to a subdirectory of tools/andro
Yoland Yan(Google) 2016/04/29 19:51:43 Will move to tools/android/find_annotated_tests/fi
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 tracked(disabled/flaky) 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 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
jbudorick 2016/04/28 14:17:15 nit: no blank line here
Yoland Yan(Google) 2016/04/29 19:51:42 Done.
24 from pylib import constants
25 from pylib.instrumentation import instrumentation_test_instance
26
27 sys.path.append(os.path.join(_SRC_DIR, 'third_party', 'catapult', 'devil'))
28 from devil.utils import cmd_helper
29
30 _GIT_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S'
31 _EXPORT_TIME_FORMAT = '%Y%m%dT%H%M%S'
32
33 class _JSONKeyName(object):
jbudorick 2016/04/28 14:17:14 I didn't read the earlier reviews, so perhaps this
perezju 2016/04/28 14:33:58 I've been saying the same thing for several review
Yoland Yan(Google) 2016/04/29 19:51:43 wow, what a bunch of bullies lol Done
34 TEST_MASTER_KEY = 'tests'
35 REPORT_MASTER_KEY = 'metadata'
36 REVISION_KEY = 'revision'
37 COMMIT_POS_KEY = 'commit_pos'
38 ANNOTATIONS_KEY = 'annotations'
39 TEST_NAME_KEY = 'test_name'
40 TEST_APK_KEY = 'test_apk_name'
41 CRBUG_KEY = 'bug_id'
42 CLASS_PATH_KEY = 'class_path'
43 CLASS_NAME_KEY = 'class_name'
44 TRACKED_TEST_COUNT_KEY = 'tracked_test_count'
45 DISABLED_TEST_COUNT_KEY = 'disabled_test_count'
46 FLAKY_TEST_COUNT_KEY = 'flaky_test_count'
47 TOTAL_TEST_COUNT_KEY = 'total_test_count'
48 UTC_BUILDTIME_KEY = 'build_time'
49 UTC_REVISIONTIME_KEY = 'revision_time'
50 PLATFORM_KEY = 'platform'
51 PLATFORM_VALUE = 'android'
52
53
54 def _GetBugId(message):
55 """Validate bug message format and get bug id"""
56 result = re.search(r'crbug(?:.com)?/(\d+)', message)
jbudorick 2016/04/28 14:17:15 compile this into a module-scope constant
Yoland Yan(Google) 2016/04/29 19:51:42 Done.
57 if result:
58 return int(result.group(1))
59 else:
60 return None
61
jbudorick 2016/04/28 14:17:14 nit: two lines
Yoland Yan(Google) 2016/04/29 19:51:43 Done.
62 def _GetAnnotations(test_annotations):
63 """Store annotations in the existing anntation_dict and return bug id"""
64 bug_id = None
65 annotations_dict = {}
66 for annotation, content in test_annotations.iteritems():
67 if content is not None and content.get('message') is not None:
68 bug_id = _GetBugId(content.get('message'))
69 annotations_dict.update({annotation: content})
70 return bug_id, annotations_dict
71
72
73 def _GetTests(test_apks):
74 """All the all the tests"""
jbudorick 2016/04/28 14:17:14 nit: "All the all the tests"?
Yoland Yan(Google) 2016/04/29 19:51:43 got it s/All the all the tests/All the all the all
75 result = []
76 total_test_count = 0
77 for test_apk in test_apks:
78 logging.info('Current test apk: %s', test_apk)
79 test_jar = os.path.join(
80 constants.GetOutDirectory(), constants.SDK_BUILD_TEST_JAVALIB_DIR,
81 '%s.jar' % test_apk)
82 all_tests = instrumentation_test_instance.GetAllTests(test_jar=test_jar)
83 for test_class in all_tests:
84 class_path = test_class['class']
85 class_name = test_class['class'].split('.')[-1]
86
87 bug_id, class_annotation = _GetAnnotations(test_class['annotations'])
perezju 2016/04/27 09:29:15 hmm.. looks like you always end up throwing away t
Yoland Yan(Google) 2016/04/29 19:51:43 Done.
Yoland Yan(Google) 2016/04/29 19:51:43 Changed to class_bug_id and test_bug_id for cases
88 for test_method in test_class['methods']:
89 total_test_count += 1
90 # getting annotation of each test case
91 bug_id, test_annotations = _GetAnnotations(test_method['annotations'])
92 test_annotations.update(class_annotation)
93 # getting test method name of each test
94 test_name = test_method['method']
95 test_dict = {
96 _JSONKeyName.CRBUG_KEY: bug_id,
jbudorick 2016/04/28 14:17:15 nit: 2 space indent
Yoland Yan(Google) 2016/04/29 19:51:43 Keep it as 4 after a serious discussion
97 _JSONKeyName.ANNOTATIONS_KEY: test_annotations,
98 _JSONKeyName.TEST_NAME_KEY: test_name,
99 _JSONKeyName.TEST_APK_KEY: test_apk,
100 _JSONKeyName.CLASS_NAME_KEY: class_name,
101 _JSONKeyName.CLASS_PATH_KEY: class_path
102 }
103 result.append(test_dict)
104 logging.info('Total count of tests in all test apks: %d', total_test_count)
105 return result, total_test_count
106
107
108 def _GetReportMeta(utc_buildtime_string, total_test_count):
109 """Returns a dictionary of the report's metadata"""
110 revision = cmd_helper.GetCmdOutput(['git', 'rev-parse', 'HEAD']).strip()
111 raw_string = cmd_helper.GetCmdOutput(
112 ['git', 'log', '--pretty=format:%aI', '--max-count=1', 'HEAD'])
perezju 2016/04/27 09:29:15 hmm, when I run this locally I get: 2016-04-22T
Yoland Yan(Google) 2016/04/29 19:51:42 Done.
113 git_log_time_pattern = r'\d+-\d+-\d+T\d+:\d+:\d+'
perezju 2016/04/27 09:29:15 nit: a module level constant :) you could also pr
jbudorick 2016/04/28 14:17:15 +1.
Yoland Yan(Google) 2016/04/29 19:51:43 Done.
114 time_string_search = re.search(git_log_time_pattern, raw_string)
115 if time_string_search is None:
116 raise Exception('Time format incorrect')
jbudorick 2016/04/28 14:17:15 This error should be a little more verbose -- _why
Yoland Yan(Google) 2016/04/29 19:51:42 Done.
117
118 raw_string = cmd_helper.GetCmdOutput(
119 ['git', 'log', '--pretty=format:%b', '--max-count=1', 'HEAD'])
120 git_log_message_pattern = r'Cr-Commit-Position: (.*)'
perezju 2016/04/27 09:29:15 strip away the "refs/heads/master" blurb, and cast
jbudorick 2016/04/28 14:17:15 note that this should also be compiled into a modu
Yoland Yan(Google) 2016/04/29 19:51:43 Done.
121 commit_pos_search = re.search(git_log_message_pattern, raw_string)
122 if commit_pos_search is None:
123 raise Exception('Cr commit position is not found, potentially running with '
jbudorick 2016/04/28 14:17:14 nit: this should say "Cr-Commit-Position ..." rath
Yoland Yan(Google) 2016/04/29 19:51:42 Done.
124 'uncommited HEAD')
125 commit_pos = commit_pos_search.group(1)
126
127 revision_time = time.strptime(time_string_search.group(0), _GIT_TIME_FORMAT)
128 utc_revision_time = datetime.datetime.utcfromtimestamp(
129 time.mktime(revision_time))
130 utc_revision_time = utc_revision_time.strftime(_EXPORT_TIME_FORMAT)
131 logging.info(
132 'revision is %s, revision time is %s', revision, utc_revision_time)
133
134 return {
135 _JSONKeyName.REVISION_KEY: revision,
jbudorick 2016/04/28 14:17:14 nit: 2 space indent
Yoland Yan(Google) 2016/04/29 19:51:43 Keep as 4 space indent after serious discussion wi
136 _JSONKeyName.COMMIT_POS_KEY: commit_pos,
137 _JSONKeyName.UTC_BUILDTIME_KEY: utc_buildtime_string,
138 _JSONKeyName.UTC_REVISIONTIME_KEY: utc_revision_time,
139 _JSONKeyName.PLATFORM_KEY: _JSONKeyName.PLATFORM_VALUE,
140 _JSONKeyName.TOTAL_TEST_COUNT_KEY: total_test_count}
jbudorick 2016/04/28 14:17:14 nit: drop the trailing } onto the next line
Yoland Yan(Google) 2016/04/29 19:51:43 Done.
141
142
143 def _GetReport(test_apks, buildtime_string):
144 """Generate the dictionary of report data
145
146 Args:
147 test_apks: a list of apks for search for tests
148 buildtime_string: the time when the script is run at
149 format: '%Y%m%dT%H%M%S'
150 """
151
152 test_data, total_test_count = _GetTests(test_apks)
153 report_meta = _GetReportMeta(buildtime_string, total_test_count)
154 report_data = {
155 _JSONKeyName.REPORT_MASTER_KEY: report_meta,
156 _JSONKeyName.TEST_MASTER_KEY: test_data}
157 return report_data
158
159
160 def main():
161 default_build_type = os.environ.get('BUILDTYPE', 'Debug')
jbudorick 2016/04/28 14:17:14 please no
Yoland Yan(Google) 2016/04/29 19:51:43 but...lol (Explain: all this was added when the sc
162 parser = argparse.ArgumentParser()
jbudorick 2016/04/28 14:17:15 Which of these are required?
Yoland Yan(Google) 2016/04/29 19:51:43 --test-apks, --json-output-dir Done
163 parser.add_argument('-t', '--test-apks', nargs='+', dest='test_apks',
jbudorick 2016/04/28 14:17:15 Why should this handle multiple APKs at once? Why
Yoland Yan(Google) 2016/04/29 19:51:42 Because the that would produce multiple JSON file
164 help='List all test apks file name that the script uses '
165 'to fetch tracked tests from')
166 parser.add_argument(
jbudorick 2016/04/28 14:17:14 nix both --debug and --release and instead support
Yoland Yan(Google) 2016/04/29 19:51:42 Done
167 '--debug', action='store_const', const='Debug', dest='build_type',
168 default=default_build_type,
169 help=('If set, run test suites under out/Debug. '
170 'Default is env var BUILDTYPE or Debug.'))
171 parser.add_argument(
172 '--release', action='store_const', const='Release', dest='build_type',
173 help=('If set, run test suites under out/Release. '
174 'Default is env var BUILDTYPE or Debug.'))
175 parser.add_argument('-o', '--output-path',
176 help='JSON file output to be uploaded on to gcs')
jbudorick 2016/04/28 14:17:14 This description is wrong; this is now the output
Yoland Yan(Google) 2016/04/29 19:51:42 Done.
177 parser.add_argument('-v', '--verbose', action='store_true', default=False,
jbudorick 2016/04/28 14:17:14 -v = INFO, -vv = DEBUG plz
Yoland Yan(Google) 2016/04/29 19:51:43 Done.
178 help='DEBUG verbosity')
179
180 arguments = parser.parse_args(sys.argv[1:])
181 logging.basicConfig(
182 level=logging.DEBUG if arguments.verbose else logging.WARNING)
183 constants.SetBuildType(arguments.build_type)
jbudorick 2016/04/28 14:17:14 Get rid of these two lines.
Yoland Yan(Google) 2016/04/29 19:51:43 Done
184 logging.info('Using jar from build type: %s', arguments.build_type)
185
186 buildtime = datetime.datetime.utcnow()
jbudorick 2016/04/28 14:17:15 nit: buildtime is a bad name because this isn't wh
Yoland Yan(Google) 2016/04/29 19:51:42 Changed to script_run_time (I was considering chan
187 buildtime_string = buildtime.strftime(_EXPORT_TIME_FORMAT)
188 logging.info('Build time is %s', buildtime_string)
189 report_data = _GetReport(arguments.test_apks, buildtime_string)
190
191 if arguments.output_path is None:
192 output_path = constants.GetOutDirectory()
193 else:
194 output_path = arguments.output_path
195 json_output_path = os.path.join(output_path,
196 '%s-android-chrome.json' % buildtime_string)
197 with open(json_output_path, 'w') as f:
198 json.dump(report_data, f, indent=2, sort_keys=True, separators=(',',': '))
jbudorick 2016/04/28 14:17:14 This shouldn't be using indent
Yoland Yan(Google) 2016/04/29 19:51:43 Done.
199 logging.info('Saved json output file to %s', json_output_path)
200
201 if __name__ == '__main__':
202 main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698