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

Side by Side Diff: tools/android/find_annotated_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: Change after John's comments Created 4 years, 6 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
« no previous file with comments | « build/android/pylib/instrumentation/instrumentation_test_instance.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright 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 annotated 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, 'third_party', 'catapult', 'devil'))
23 from devil.utils import cmd_helper
24
25 sys.path.append(os.path.join(_SRC_DIR, 'build', 'android'))
26 from pylib import constants
27 from pylib.instrumentation import instrumentation_test_instance
28
29
30 _CRBUG_ID_PATTERN = re.compile(r'crbug(?:.com)?/(\d+)')
31 _EXPORT_TIME_FORMAT = '%Y%m%dT%H%M%S'
32 _GIT_LOG_TIME_PATTERN = re.compile(r'\d+')
33 _GIT_LOG_MESSAGE_PATTERN = r'Cr-Commit-Position: refs/heads/master@{#(\d+)}'
34 _GIT_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S'
35 _PLATFORM_VALUE = 'android'
36
37
38 def _GetBugId(test_annotations):
39 """Store annotations in the existing annotation_dict and return bug id"""
40 # TODO(yolandyan): currently the script only support on bug id per method,
jbudorick 2016/06/13 17:35:15 nit: "only support on bug id" -> "only supports on
the real yoland 2016/06/13 19:41:53 Done
41 # add support for multiple bug id
42 for content in test_annotations.itervalues():
43 if content and content.get('message'):
44 search_result = re.search(_CRBUG_ID_PATTERN, content.get('message'))
45 return int(search_result.group(1))
46 else:
47 return None
jbudorick 2016/06/13 17:35:15 This shouldn't return here. It should only return
the real yoland 2016/06/13 19:41:49 Done
48
49
50 def _GetTests(test_apks, apk_output_dir):
51 """Return a list of all annotated tests and total test count"""
52 result = []
53 total_test_count = 0
54 for test_apk in test_apks:
55 logging.info('Current test apk: %s', test_apk)
56 test_jar = os.path.join(
57 apk_output_dir, constants.SDK_BUILD_TEST_JAVALIB_DIR,
58 '%s.jar' % test_apk)
59 all_tests = instrumentation_test_instance.GetAllTests(test_jar=test_jar)
60 for test_class in all_tests:
61 class_path = test_class['class']
62 class_name = test_class['class'].split('.')[-1]
63
64 class_annotations = test_class['annotations']
65 class_bug_id = _GetBugId(class_annotations)
66 for test_method in test_class['methods']:
67 total_test_count += 1
68 # getting annotation of each test case
69 test_annotations = test_method['annotations']
70 test_bug_id = _GetBugId(test_annotations)
71 test_bug_id = test_bug_id if test_bug_id else class_bug_id
72 test_annotations.update(class_annotations)
73 # getting test method name of each test
74 test_name = test_method['method']
75 test_dict = {
76 'bug_id': test_bug_id,
77 'annotations': test_annotations,
78 'test_name': test_name,
79 'test_apk_name': test_apk,
80 'class_name': class_name,
81 'class_path': class_path
82 }
83 result.append(test_dict)
84 logging.info('Total count of tests in all test apks: %d', total_test_count)
jbudorick 2016/06/13 17:35:15 nit: blank line before this one
the real yoland 2016/06/13 19:41:49 Done
85 return result, total_test_count
86
87
88 def _GetReportMeta(utc_script_runtime_string, total_test_count):
89 """Returns a dictionary of the report's metadata"""
90 revision = cmd_helper.GetCmdOutput(['git', 'rev-parse', 'HEAD']).strip()
91 raw_string = cmd_helper.GetCmdOutput(
92 ['git', 'log', '--pretty=format:%at', '--max-count=1', 'HEAD'])
93 time_string_search = re.search(_GIT_LOG_TIME_PATTERN, raw_string)
94 if time_string_search is None:
95 raise Exception('Timestamp format incorrect, expected all digits, got %s'
96 % raw_string)
97
98 raw_string = cmd_helper.GetCmdOutput(
99 ['git', 'log', '--pretty=format:%b', '--max-count=1', 'HEAD'])
100 commit_pos_search = re.search(_GIT_LOG_MESSAGE_PATTERN, raw_string)
101 if commit_pos_search is None:
102 raise Exception('Cr-Commit-Position is not found, potentially running with '
103 'uncommited HEAD')
104 commit_pos = int(commit_pos_search.group(1))
105
106 utc_revision_time = datetime.datetime.utcfromtimestamp(
107 int(time_string_search.group(0)))
108 utc_revision_time = utc_revision_time.strftime(_EXPORT_TIME_FORMAT)
109 logging.info(
110 'revision is %s, revision time is %s', revision, utc_revision_time)
111
112 return {
113 'revision': revision,
114 'commit_pos': commit_pos,
115 'script_runtime': utc_script_runtime_string,
116 'revision_time': utc_revision_time,
117 'platform': _PLATFORM_VALUE,
118 'total_test_count': total_test_count
119 }
120
121
122 def _GetReport(test_apks, script_runtime_string, apk_output_dir):
123 """Generate the dictionary of report data
124
125 Args:
126 test_apks: a list of apks for search for tests
127 script_runtime_string: the time when the script is run at
128 format: '%Y%m%dT%H%M%S'
129 """
130
131 test_data, total_test_count = _GetTests(test_apks, apk_output_dir)
132 report_meta = _GetReportMeta(script_runtime_string, total_test_count)
133 report_data = {
134 'metadata': report_meta,
135 'tests': test_data
136 }
137 return report_data
138
139
140 def main():
141 parser = argparse.ArgumentParser()
142 parser.add_argument('-t', '--test-apks', nargs='+', dest='test_apks',
143 required=True,
144 help='List all test apks file name that the script uses '
145 'to fetch tracked tests from')
146 parser.add_argument('--json-output-dir', required=True,
147 help='JSON file output directory')
148 parser.add_argument('--apk-output-dir', required=True,
149 help='The output directory of test apks')
150 parser.add_argument('-v', '--verbose', action='store_true', default=False,
151 help='INFO verbosity')
152
153 arguments = parser.parse_args(sys.argv[1:])
154 logging.basicConfig(
155 level=logging.INFO if arguments.verbose else logging.WARNING)
156
157 script_runtime = datetime.datetime.utcnow()
jbudorick 2016/06/13 17:35:15 Why are you doing this in main() and not in either
the real yoland 2016/06/13 19:41:51 I know it's not pretty, but I save the json file a
158 script_runtime_string = script_runtime.strftime(_EXPORT_TIME_FORMAT)
159 logging.info('Build time is %s', script_runtime_string)
160 apk_output_dir = os.path.abspath(os.path.join(
161 constants.DIR_SOURCE_ROOT, arguments.apk_output_dir))
162 report_data = _GetReport(
163 arguments.test_apks, script_runtime_string, apk_output_dir)
164
165 temp_output_dir = arguments.json_output_dir
jbudorick 2016/06/13 17:35:15 nit: just use arguments.json_output_dir directly
the real yoland 2016/06/13 19:41:49 Done
166 json_output_path = os.path.join(
167 temp_output_dir, '%s-android-chrome.json' % script_runtime_string)
168 with open(json_output_path, 'w') as f:
169 json.dump(report_data, f, sort_keys=True, separators=(',',': '))
170 logging.info('Saved json output file to %s', json_output_path)
171
jbudorick 2016/06/13 17:35:15 nit: +1 blank line
the real yoland 2016/06/13 19:41:49 Done
172 if __name__ == '__main__':
173 main()
jbudorick 2016/06/13 17:35:15 nit: sys.exit(main())
the real yoland 2016/06/13 19:41:49 Done
OLDNEW
« no previous file with comments | « build/android/pylib/instrumentation/instrumentation_test_instance.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698