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

Side by Side Diff: tools/traffic_annotation/auditor/traffic_annotation_auditor.py

Issue 2905263002: Filter added to prune files before applying network annotation extractor. (Closed)
Patch Set: run_tool.py reverted. Created 3 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 | « no previous file | tools/traffic_annotation/auditor/traffic_annotation_file_filter.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2017 The Chromium Authors. All rights reserved. 2 # Copyright 2017 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """This script is used to extract network traffic annotations from Chrome. 6 """This script is used to extract network traffic annotations from Chrome.
7 Please refer to README.md for running steps.""" 7 Please refer to README.md for running steps."""
8 8
9 import argparse 9 import argparse
10 import datetime
10 import os 11 import os
11 import subprocess 12 import subprocess
12 import sys 13 import sys
14 import tempfile
15
16 from traffic_annotation_file_filter import TrafficAnnotationFileFilter
17
13 18
14 # These two lines are required to import protobuf from third_party directory 19 # These two lines are required to import protobuf from third_party directory
15 # instead of the one installed with python. 20 # instead of the one installed with python.
16 from prepare_protobuf import PrepareProtobuf 21 from prepare_protobuf import PrepareProtobuf
17 PrepareProtobuf() 22 PrepareProtobuf()
18 23
19 from google.protobuf import text_format 24 from google.protobuf import text_format
20 import traffic_annotation_pb2 25 import traffic_annotation_pb2
21 26
22 27
(...skipping 10 matching lines...) Expand all
33 'net/traffic_annotation/network_traffic_annotation.h'. 38 'net/traffic_annotation/network_traffic_annotation.h'.
34 args: 39 args:
35 unique_id: str The string to be converted to hash code. 40 unique_id: str The string to be converted to hash code.
36 41
37 Returns: 42 Returns:
38 unsigned int Hash code of the input string 43 unsigned int Hash code of the input string
39 """ 44 """
40 return _RecursiveHash(unique_id) if len(unique_id) else -1 45 return _RecursiveHash(unique_id) if len(unique_id) else -1
41 46
42 47
43 def _RunClangTool(src_dir, build_dir, path_filters): 48 def _RunClangTool(src_dir, build_dir, path_filters, prefilter_files):
44 """Executes the clang tool to extract annotations. 49 """Executes the clang tool to extract annotations.
45 Args: 50 Args:
46 src_dir: str Path to the src directory of Chrome. 51 src_dir: str Path to the src directory of Chrome.
47 build_dir: str Path to the build directory. 52 build_dir: str Path to the build directory.
48 path_filters: list of str List of paths to source directories for 53 path_filters: list of str List of paths to source directories for
49 extraction. 54 extraction.
55 prefilter_files: bool Flag stating if source files should be first filtered
56 using annotation related keywords and then given to clang tool.
50 57
51 Returns: 58 Returns:
52 raw_annotations: str Output of clang tool (extracted content and metadata of 59 str Output of clang tool (extracted content and metadata of annotations).
53 annotations).
54 """ 60 """
55 raw_annotations = "" 61 args = [
56 for path in path_filters:
57 args = [
58 src_dir + "/tools/clang/scripts/run_tool.py", 62 src_dir + "/tools/clang/scripts/run_tool.py",
59 "--generate-compdb", 63 "--generate-compdb",
60 "--tool=traffic_annotation_extractor", 64 "--tool=traffic_annotation_extractor",
61 "-p", build_dir, 65 "-p=" + build_dir]
62 path] 66 if sys.platform == "win32":
63 if sys.platform == "win32":
64 args.insert(0, "python") 67 args.insert(0, "python")
65 command = subprocess.Popen(args, stdout=subprocess.PIPE, 68
66 stderr=subprocess.PIPE) 69 if prefilter_files:
67 stdout_text, stderr_text = command.communicate() 70 file_filter = TrafficAnnotationFileFilter(False)
68 raw_annotations += stdout_text 71 for path in path_filters:
69 if stderr_text: 72 args += file_filter.GetFilteredFilesList(path)
70 print stderr_text 73 else:
71 return raw_annotations 74 args += path_filters
75
76 command = subprocess.Popen(args, stdout=subprocess.PIPE,
77 stderr=subprocess.PIPE)
78 stdout_text, stderr_text = command.communicate()
79 if stderr_text:
80 print stderr_text
81 return stdout_text
72 82
73 83
74 def _ParsRawAnnotations(raw_annotations): 84 def _ParsRawAnnotations(raw_annotations):
75 """Parses raw annotations texts which are received from the clang tool. 85 """Parses raw annotations texts which are received from the clang tool.
76 Args: 86 Args:
77 raw_annotations: str Serialization of annotations and metadata. Each 87 raw_annotations: str Serialization of annotations and metadata. Each
78 annotation should have either of the following lines: 88 annotation should have either of the following lines:
79 1- "==== NEW ANNOTATION ====" 89 1- "==== NEW ANNOTATION ===="
80 2- File path. 90 2- File path.
81 3- Name of the function including this position. 91 3- Name of the function including this position.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 raise Exception( 126 raise Exception(
117 "Not enough header lines at line %i." % current) 127 "Not enough header lines at line %i." % current)
118 128
119 # Extract header lines. 129 # Extract header lines.
120 source = traffic_annotation_pb2.NetworkTrafficAnnotation.TrafficSource() 130 source = traffic_annotation_pb2.NetworkTrafficAnnotation.TrafficSource()
121 source.file = lines[current + 1] 131 source.file = lines[current + 1]
122 source.function = lines[current + 2] 132 source.function = lines[current + 2]
123 source.line = int(lines[current + 3]) 133 source.line = int(lines[current + 3])
124 unique_id = lines[current + 5] 134 unique_id = lines[current + 5]
125 135
126 new_metadata = {'function_type': lines[current + 4], 136 new_metadata = {"function_type": lines[current + 4],
127 'extra_id': lines[current + 6], 137 "extra_id": lines[current + 6],
128 'unique_id_hash': _ComputeStringHash(unique_id)} 138 "unique_id_hash": _ComputeStringHash(unique_id)}
129 # Extract serialized proto. 139 # Extract serialized proto.
130 current += 7 140 current += 7
131 annotation_text = "" 141 annotation_text = ""
132 142
133 while current < len(lines): 143 while current < len(lines):
134 if lines[current] == "==== ANNOTATION ENDS ====": 144 if lines[current] == "==== ANNOTATION ENDS ====":
135 break 145 break
136 else: 146 else:
137 annotation_text += lines[current] 147 annotation_text += lines[current]
138 current += 1 148 current += 1
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 def _WriteSummaryFile(annotations, metadata, errors, file_path): 198 def _WriteSummaryFile(annotations, metadata, errors, file_path):
189 """Writes extracted annotations and errors into a simple text file. 199 """Writes extracted annotations and errors into a simple text file.
190 args: 200 args:
191 annotations: ExtractedNetworkTrafficAnnotation A protobuf including all 201 annotations: ExtractedNetworkTrafficAnnotation A protobuf including all
192 extracted annotations. 202 extracted annotations.
193 metadata: list of dict Metadata for annotations, as specified in the outputs 203 metadata: list of dict Metadata for annotations, as specified in the outputs
194 of _ParsRawAnnotations function. 204 of _ParsRawAnnotations function.
195 errors: list of str List of all extraction errors. 205 errors: list of str List of all extraction errors.
196 file_path: str File path to the brief summary file. 206 file_path: str File path to the brief summary file.
197 """ 207 """
198 with open(file_path, 'w') as summary_file: 208 with open(file_path, "w") as summary_file:
199 if errors: 209 if errors:
200 summary_file.write("Errors:\n%s\n\n" % "\n".join(errors)) 210 summary_file.write("Errors:\n%s\n\n" % "\n".join(errors))
201 if len(annotations.network_traffic_annotation): 211 if len(annotations.network_traffic_annotation):
202 summary_file.write("Annotations:\n") 212 summary_file.write("Annotations:\n")
203 for annotation, meta in zip(annotations.network_traffic_annotation, 213 for annotation, meta in zip(annotations.network_traffic_annotation,
204 metadata): 214 metadata):
205 summary_file.write( 215 summary_file.write(
206 "%s\n+MetaData:%s\n---\n" % (str(annotation), str(meta))) 216 "%s\n+MetaData:%s\n---\n" % (str(annotation), str(meta)))
207 217
208 218
209 def _WriteHashCodesFile(annotations, metadata, file_path): 219 def _WriteHashCodesFile(annotations, metadata, file_path):
210 """Writes unique ids and hash codes of annotations into a simple text file. 220 """Writes unique ids and hash codes of annotations into a simple text file.
211 args: 221 args:
212 annotations: ExtractedNetworkTrafficAnnotation A protobuf including all 222 annotations: ExtractedNetworkTrafficAnnotation A protobuf including all
213 extracted annotations. 223 extracted annotations.
214 metadata: list of dict Metadata for annotations, as specified in the outputs 224 metadata: list of dict Metadata for annotations, as specified in the outputs
215 of _ParsRawAnnotations function. 225 of _ParsRawAnnotations function.
216 file_path: str File path to the brief summary file. 226 file_path: str File path to the brief summary file.
217 """ 227 """
218 with open(file_path, 'w') as summary_file: 228 hash_list = []
219 for annotation, meta in zip(annotations.network_traffic_annotation, 229 for annotation, meta in zip(annotations.network_traffic_annotation, metadata):
220 metadata): 230 hash_list += ["%s,%s" % (annotation.unique_id, meta["unique_id_hash"])]
221 summary_file.write( 231 for keyword in ("test", "test_partial", "undefined", "missing"):
222 "%s,%s\n" % (annotation.unique_id, meta['unique_id_hash'])) 232 hash_list += ["%s,%s" % (keyword, _ComputeStringHash(keyword))]
223 for keyword in ("test", "test_partial", "undefined", "missing"): 233 open(file_path, "w").write("\n".join(sorted(hash_list)))
224 summary_file.write(
225 "%s,%s\n" % (keyword, _ComputeStringHash(keyword)))
226 234
227 235
228 def main(): 236 def main():
229 parser = argparse.ArgumentParser(description='Traffic Annotation Auditor.') 237 parser = argparse.ArgumentParser(description="Traffic Annotation Auditor.")
230 parser.add_argument('--build-dir', 238 parser.add_argument("--build-dir",
231 help='Path to the build directory.') 239 help="Path to the build directory.")
232 parser.add_argument('--extractor-output', 240 parser.add_argument("--extractor-output",
233 help='Optional path to the temporary file that extracted ' 241 help="Optional path to the temporary file that extracted "
234 'annotations will be stored into.') 242 "annotations will be stored into.")
235 parser.add_argument('--extractor-input', 243 parser.add_argument("--extractor-input",
236 help='Optional path to the file that temporary extracted ' 244 help="Optional path to the file that temporary extracted "
237 'annotations are already stored in. If this is ' 245 "annotations are already stored in. If this is "
238 'provided, clang tool is not run and this is used ' 246 "provided, clang tool is not run and this is used "
239 'as input.') 247 "as input.")
240 parser.add_argument('--summary-file', 248 parser.add_argument("--summary-file",
241 help='Path to the output file with all annotations.') 249 help="Path to the output file with all annotations.")
242 parser.add_argument('--hash-codes-file', 250 parser.add_argument("--hash-codes-file",
243 help='Path to the output file with the list of unique ' 251 help="Path to the output file with the list of unique "
244 'ids and their hash codes.') 252 "ids and their hash codes.")
245 parser.add_argument('path_filters', 253 parser.add_argument("path_filters",
246 nargs='*', 254 nargs="*",
247 help='Optional paths to filter what files the tool is ' 255 help="Optional paths to filter what files the tool is "
248 'run on.') 256 "run on.",
257 default=[""])
258 parser.add_argument("--prefilter-files", action="store_true",
259 help="Checks source files for patterns of annotations "
260 "and network functions that may require annotation "
261 "and limits running clang tool only on them.")
249 args = parser.parse_args() 262 args = parser.parse_args()
250 263
251 if not args.summary_file and not args.hash_codes_file: 264 if not args.summary_file and not args.hash_codes_file:
252 print "Warning: Output file not specified." 265 print "Warning: Output file not specified."
253 266
254 # If a pre-extracted input file is provided, load it. 267 # If a pre-extracted input file is provided, load it.
255 if args.extractor_input: 268 if args.extractor_input:
256 with open(args.extractor_input, 'r') as raw_file: 269 with open(args.extractor_input, "r") as raw_file:
257 raw_annotations = raw_file.read() 270 raw_annotations = raw_file.read()
258 else: 271 else:
259 # Either extacted input file or build directory should be provided. 272 # Either extacted input file or build directory should be provided.
260 if not args.build_dir: 273 if not args.build_dir:
261 print "You must either specify the build directory to run the clang " \ 274 print "You must either specify the build directory to run the clang " \
262 "tool and extract annotations, or specify the input directory " \ 275 "tool and extract annotations, or specify the input directory " \
263 "where extracted annotation files already exist.\n" 276 "where extracted annotation files already exist.\n"
264 return 1 277 return 1
265 278
266 # Get Chrome source directory with relative path from this file. 279 # Get Chrome source directory with relative path from this file.
267 chrome_source = os.path.abspath(os.path.join(os.path.dirname( 280 chrome_source = os.path.abspath(os.path.join(os.path.dirname(
268 os.path.realpath(__file__)), "..", "..", "..")) 281 os.path.realpath(__file__)), "..", "..", ".."))
269 raw_annotations = _RunClangTool(chrome_source, args.build_dir, 282 raw_annotations = _RunClangTool(chrome_source, args.build_dir,
270 args.path_filters if args.path_filters else ["./"]) 283 args.path_filters, args.prefilter_files)
271 284
272 if args.extractor_output: 285 if args.extractor_output:
273 with open(args.extractor_output, 'w') as raw_file: 286 with open(args.extractor_output, "w") as raw_file:
274 raw_file.write(raw_annotations) 287 raw_file.write(raw_annotations)
275 288
276 annotations, metadata, errors = _ParsRawAnnotations(raw_annotations) 289 annotations, metadata, errors = _ParsRawAnnotations(raw_annotations)
277 290
278 if not annotations: 291 if not annotations:
279 print "Could not extract any annotation." 292 print "Could not extract any annotation."
280 if errors: 293 if errors:
281 print "Errors:\n%s" % "\n".join(errors) 294 print "Errors:\n%s" % "\n".join(errors)
282 return 1 295 return 1
283 296
284 if args.summary_file: 297 if args.summary_file:
285 _WriteSummaryFile(annotations, metadata, errors, args.summary_file) 298 _WriteSummaryFile(annotations, metadata, errors, args.summary_file)
286 299
287 if args.hash_codes_file: 300 if args.hash_codes_file:
288 _WriteHashCodesFile(annotations, metadata, args.hash_codes_file) 301 _WriteHashCodesFile(annotations, metadata, args.hash_codes_file)
289 302
290 return 0 303 return 0
291 304
292 305
293 if __name__ == '__main__': 306 if __name__ == "__main__":
294 sys.exit(main()) 307 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | tools/traffic_annotation/auditor/traffic_annotation_file_filter.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698