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

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: Minor change Created 4 years, 8 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
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
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 _DISABLED_TESTS_ANNOTATION_LIST = {'DisabledTest': None, 'FlakyTest': None}
31 _GIT_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S'
32 _EXPORT_TIME_FORMAT = '%Y%m%dT%H%M%S'
33
34 class _JSONKeyName(object):
perezju 2016/04/12 10:29:03 do we really need this?
Yoland Yan(Google) 2016/04/13 01:03:11 hmm, I thought this is good to organize global var
perezju 2016/04/13 09:53:46 I just wouldn't store these as constants at all. I
35 TEST_MASTER_KEY = 'tests'
36 RECORD_MASTER_KEY = 'records'
37 REVISION_KEY = 'revision'
38 STATUS_KEY = 'status'
39 TEST_NAME_KEY = 'name'
40 CRBUG_KEY = 'bug_id'
41 CLASS_PATH_KEY = 'class_path'
42 CLASS_NAME_KEY = 'class_name'
43 TRACKED_TEST_COUNT_KEY = 'tracked_test_count'
44 DISABLED_TEST_COUNT_KEY = 'disabled_test_count'
45 FLAKY_TEST_COUNT_KEY = 'flaky_test_count'
46 TOTAL_TEST_COUNT_KEY = 'total_test_count'
47 UTC_BUILDTIME_KEY = 'utc_buildtime'
48 UTC_REVISIONTIME_KEY = 'utc_revisiontime'
49 PLATFORM_KEY = 'platform'
50 PLATFORM_VALUE = 'android'
51
52 STATUS_DISABLED_TEST_VALUE = 'Disabled Test'
53 STATUS_FLAKY_TEST_VALUE = 'Flaky Test'
54
55 def _SerializeTests(test_apks, annotations):
56 """Use GetFilteredTests to get tests info with wanted annotations"""
57 total_test_count = 0
58 tracked_test_list = []
59 for test_apk in test_apks:
60 logging.info('Current test apk: %s', test_apk)
61 test_jar = os.path.join(
62 constants.GetOutDirectory(), constants.SDK_BUILD_TEST_JAVALIB_DIR,
63 '%s.jar' % test_apk)
64 temp_tracked_test_list = instrumentation_test_instance.GetFilteredTests(
perezju 2016/04/12 10:29:03 could we make getting all tests, and the filtering
Yoland Yan(Google) 2016/04/13 01:03:11 Done
65 test_jar=test_jar,
66 test_filter=None,
67 annotations=annotations,
68 exclude_annotations=None
69 )
70 tracked_test_list.extend(temp_tracked_test_list)
71 total_test_count += instrumentation_test_instance.TotalTestCount(test_jar)
72 logging.info('Total count of tests in all test apks: %d', total_test_count)
73 result = []
74 for test_class in tracked_test_list:
75 class_path = test_class['class']
76 class_name = test_class['class'].split('.')[-1]
77 for test_method in test_class['methods']:
78 # getting annotation of each test case
79 bug_id = None
80 status = []
81 test_annotations = test_method['annotations']
82 assert len(test_annotations) != 0
83 for annotation, content in test_annotations.iteritems():
84 if content is not None:
85 bug_id = content['message']
perezju 2016/04/12 10:29:03 probably a minor thing, but do we worry about mult
Yoland Yan(Google) 2016/04/13 01:03:11 hmm, that's a valid point, on one hand I can add m
perezju 2016/04/25 12:45:07 my main worry was about the bug_id, if there are t
86 status.append(annotation)
87 # getting test method name of each test
88 test_name = test_method['method']
89 test_dict = {
90 _JSONKeyName.CRBUG_KEY: bug_id,
91 _JSONKeyName.STATUS_KEY: status,
92 _JSONKeyName.TEST_NAME_KEY: test_name,
93 _JSONKeyName.CLASS_NAME_KEY: class_name,
94 _JSONKeyName.CLASS_PATH_KEY: class_path
95 }
perezju 2016/04/12 10:29:03 nit: The closing brace should be aligned with test
Yoland Yan(Google) 2016/04/13 01:03:11 Done.
96 result.append(test_dict)
97 return result, total_test_count
98
99 def _DisabledFlakyTestCount(test_list):
100 disabled_test_count = 0
101 flaky_test_count = 0
102 for test in test_list:
103 if _JSONKeyName.STATUS_DISABLED_TEST_VALUE in test.get(
104 _JSONKeyName.STATUS_KEY, ""):
105 disabled_test_count += 1
106 if _JSONKeyName.STATUS_FLAKY_TEST_VALUE in test.get(
107 _JSONKeyName.STATUS_KEY, ""):
108 flaky_test_count += 1
109 return disabled_test_count, flaky_test_count
110
111 def _AddRecord(tracked_test_list, utc_buildtime_string, total_test_count):
112 tracked_flaky_test_count = len(tracked_test_list)
113 disabled_test_count, flaky_test_count = _DisabledFlakyTestCount(
114 tracked_test_list)
115
116 revision = cmd_helper.GetCmdOutput(['git', 'rev-parse', 'HEAD']).strip()
117 raw_string = cmd_helper.GetCmdOutput(
118 ['git', 'log', '--pretty=format:%aI', '--max-count=1', 'HEAD'])
119 time_string_search = re.search(r'\d+-\d+-\d+T\d+:\d+:\d+', raw_string)
120 if time_string_search is None:
121 raise Exception('Time format incorrect')
122
123 raw_string = cmd_helper.GetCmdOutput(
124 ['git', 'log', '--pretty=format:%b', '--max-count=1', 'HEAD'])
125 commit_pos_search = re.search(r'Cr-Commit-Position: (.*)', raw_string)
126 if commit_pos_search is None:
127 raise Exception('Cr commit position is not found, potentially running with '
128 'uncommited HEAD')
129 commit_pos = commit_pos_search.group(1)
130
131 revision_time = time.strptime(time_string_search.group(0), _GIT_TIME_FORMAT)
132 utc_revision_time = datetime.datetime.utcfromtimestamp(
133 time.mktime(revision_time))
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 record_data = [{
139 _JSONKeyName.REVISION_KEY: revision,
140 _JSONKeyName.COMMIT_POS_KEY: commit_pos,
141 _JSONKeyName.UTC_BUILDTIME_KEY: utc_buildtime_string,
142 _JSONKeyName.UTC_REVISIONTIME_KEY: utc_revision_time,
143 _JSONKeyName.PLATFORM_KEY: _JSONKeyName.PLATFORM_VALUE,
144 _JSONKeyName.TRACKED_TEST_COUNT_KEY: tracked_flaky_test_count,
145 _JSONKeyName.DISABLED_TEST_COUNT_KEY: disabled_test_count,
146 _JSONKeyName.FLAKY_TEST_COUNT_KEY: flaky_test_count,
147 _JSONKeyName.TOTAL_TEST_COUNT_KEY: total_test_count
148 }]
149 return record_data
150
151 def main():
152 default_build_type = os.environ.get('BUILDTYPE', 'Debug')
153 parser = argparse.ArgumentParser()
154 parser.add_argument('-t', '--test-apks', action='append', default=[],
155 dest='test_apks', help='List all test apks file name ' +
156 'that the script uses to fetch tracked tests from')
157 parser.add_argument(
158 '--debug', action='store_const', const='Debug', dest='build_type',
159 default=default_build_type,
160 help=('If set, run test suites under out/Debug. '
161 'Default is env var BUILDTYPE or Debug.'))
perezju 2016/04/12 10:29:03 should there be also a --release option?
Yoland Yan(Google) 2016/04/13 01:03:11 Done.
162 parser.add_argument('-o', '--output-path',
163 help='JSON file output to be uploaded on to gcs')
164 parser.add_argument('-a', '--annotations', dest='annotations',
165 action='append', default=['DisabledTest', 'FlakyTest'],
166 help='Disabled tests annotations, seperated by ,' +
perezju 2016/04/12 10:29:04 I would rephrase as: 'Test annotations to track. T
Yoland Yan(Google) 2016/04/13 01:03:11 My bad, done
167 'e.g. --annotation-str=DisabledTest,FlakyTest')
168 parser.add_argument('-v', '--verbose', action='store_true', default=False,
169 help='DEBUG verbosity')
170
171 arguments = parser.parse_args(sys.argv[1:])
172 logging.basicConfig(
173 level=logging.DEBUG if arguments.verbose else logging.WARNING)
174 annotations = dict((x, None) for x in arguments.annotations)
175 constants.SetBuildType(arguments.build_type)
176 logging.info('Use jar from build type: %s', arguments.build_type)
perezju 2016/04/12 10:29:03 nit: Use -> Using
Yoland Yan(Google) 2016/04/13 01:03:11 Done.
177
178 buildtime = datetime.datetime.utcnow()
179 buildtime_string = buildtime.strftime('%Y%m%dT%H%M%S')
perezju 2016/04/12 10:29:03 _EXPORT_TIME_FORMAT
Yoland Yan(Google) 2016/04/13 01:03:11 Done.
180 logging.info('Build time is %s', buildtime_string)
181 test_data, total_test_count = _SerializeTests(arguments.test_apks,
182 annotations)
183 record_data = _AddRecord(test_data, buildtime_string, total_test_count)
perezju 2016/04/12 10:29:03 Instead of _AddRecord, I would have a single metho
Yoland Yan(Google) 2016/04/13 01:03:11 I changed record to report everywhere (will patch
perezju 2016/04/13 09:53:47 metadata? I would suggest: report = { "
Yoland Yan(Google) 2016/04/22 17:50:26 Got it Done
184
185 if arguments.output_path is None:
186 output_path = constants.GetOutDirectory()
187 else:
188 output_path = arguments.output_path
189 json_output_path = os.path.join(output_path,
190 '%s-android-chrome.json' % buildtime_string)
191 export_data = {
192 _JSONKeyName.RECORD_MASTER_KEY: record_data,
193 _JSONKeyName.TEST_MASTER_KEY: test_data
194 }
195 with open(json_output_path, 'w') as f:
196 json.dump(export_data, f, indent=2, sort_keys=True)
perezju 2016/04/12 10:29:03 also add: separators=(': ', ',') otherwise you en
Yoland Yan(Google) 2016/04/13 01:03:11 Woah! Done
197 logging.info('Saved json output file to %s', json_output_path)
198
199 if __name__ == '__main__':
200 main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698