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

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: Rebase Created 4 years, 5 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_test.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
36
37 def _GetBugId(test_annotations):
38 """Find and return the test bug id from its annoation message elements"""
39 # TODO(yolandyan): currently the script only supports on bug id per method,
40 # add support for multiple bug id
41 for content in test_annotations.itervalues():
42 if content and content.get('message'):
43 search_result = re.search(_CRBUG_ID_PATTERN, content.get('message'))
44 if search_result is not None:
45 return int(search_result.group(1))
46 return None
47
48
49 def _GetTests(test_apks, apk_output_dir):
50 """Return a list of all annotated tests and total test count"""
51 result = []
52 total_test_count = 0
53 for test_apk in test_apks:
54 logging.info('Current test apk: %s', test_apk)
55 test_jar = os.path.join(
56 apk_output_dir, constants.SDK_BUILD_TEST_JAVALIB_DIR,
57 '%s.jar' % test_apk)
58 all_tests = instrumentation_test_instance.GetAllTests(test_jar=test_jar)
59 for test_class in all_tests:
60 class_path = test_class['class']
61 class_name = test_class['class'].split('.')[-1]
62
63 class_annotations = test_class['annotations']
64 class_bug_id = _GetBugId(class_annotations)
65 for test_method in test_class['methods']:
66 total_test_count += 1
67 # getting annotation of each test case
68 test_annotations = test_method['annotations']
69 test_bug_id = _GetBugId(test_annotations)
70 test_bug_id = test_bug_id if test_bug_id else class_bug_id
71 test_annotations.update(class_annotations)
72 # getting test method name of each test
73 test_name = test_method['method']
74 test_dict = {
75 'bug_id': test_bug_id,
76 'annotations': test_annotations,
77 'test_name': test_name,
78 'test_apk_name': test_apk,
79 'class_name': class_name,
80 'class_path': class_path
81 }
82 result.append(test_dict)
83
84 logging.info('Total count of tests in all test apks: %d', total_test_count)
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': 'android',
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 dir')
148 parser.add_argument('--apk-output-dir', required=True,
149 help='The output directory of test apks')
150 parser.add_argument('--timestamp-string',
151 help='The time when this script is run, passed in by the '
152 'recipe that runs this script so both the recipe '
153 'and this script use it to format output json name')
154 parser.add_argument('-v', '--verbose', action='store_true', default=False,
155 help='INFO verbosity')
156
157 arguments = parser.parse_args(sys.argv[1:])
158 logging.basicConfig(
159 level=logging.INFO if arguments.verbose else logging.WARNING)
160
161 if arguments.timestamp_string is None:
162 script_runtime = datetime.datetime.utcnow()
163 script_runtime_string = script_runtime.strftime(_EXPORT_TIME_FORMAT)
164 else:
165 script_runtime = arguments.timestamp_string
166 logging.info('Build time is %s', script_runtime_string)
167 apk_output_dir = os.path.abspath(os.path.join(
168 constants.DIR_SOURCE_ROOT, arguments.apk_output_dir))
169 report_data = _GetReport(
170 arguments.test_apks, script_runtime_string, apk_output_dir)
171
172 json_output_path = os.path.join(
173 arguments.json_output_dir,
174 '%s-android-chrome.json' % script_runtime_string)
175 with open(json_output_path, 'w') as f:
176 json.dump(report_data, f, sort_keys=True, separators=(',',': '))
177 logging.info('Saved json output file to %s', json_output_path)
178
179
180 if __name__ == '__main__':
181 sys.exit(main())
OLDNEW
« no previous file with comments | « build/android/pylib/instrumentation/instrumentation_test_instance_test.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698