Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2017 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 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 os | 10 import os |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 67 stdout_text, stderr_text = command.communicate() | 67 stdout_text, stderr_text = command.communicate() |
| 68 raw_annotations += stdout_text | 68 raw_annotations += stdout_text |
| 69 if stderr_text: | 69 if stderr_text: |
| 70 print stderr_text | 70 print stderr_text |
| 71 return raw_annotations | 71 return raw_annotations |
| 72 | 72 |
| 73 | 73 |
| 74 def _ParsRawAnnotations(raw_annotations): | 74 def _ParsRawAnnotations(raw_annotations): |
| 75 """Parses raw annotations texts which are received from the clang tool. | 75 """Parses raw annotations texts which are received from the clang tool. |
| 76 Args: | 76 Args: |
| 77 raw_annotations: str Serialization of annotations and metadata. Each | 77 raw_annotations: str Serialization of annotations and metadata. Each |
|
msramek
2017/05/29 21:03:37
Please update the function doc to mention calls as
Ramin Halavati
2017/05/30 04:40:37
Done.
| |
| 78 annotation should have the following lines: | 78 annotation should have the following lines: |
| 79 1- "==== NEW ANNOTATION ====" | 79 1- "==== NEW ANNOTATION ====" |
| 80 2- File path. | 80 2- File path. |
| 81 3- Name of the function including this position. | 81 3- Name of the function including this position. |
| 82 4- Line number. | 82 4- Line number. |
| 83 5- Function Type. | 83 5- Function Type. |
| 84 6- Unique id of annotation. | 84 6- Unique id of annotation. |
| 85 7- Completing id or group id, when applicable, empty otherwise. | 85 7- Completing id or group id, when applicable, empty otherwise. |
| 86 8- Serialization of annotation text (several lines) | 86 8- Serialization of annotation text (several lines) |
| 87 n- "==== ANNOTATION ENDS ====" | 87 n- "==== ANNOTATION ENDS ====" |
| 88 | 88 |
| 89 Returns: | 89 Returns: |
| 90 annotations: ExtractedNetworkTrafficAnnotation A protobuf including all | 90 annotations: ExtractedNetworkTrafficAnnotation A protobuf including all |
| 91 extracted annotations. | 91 extracted annotations. |
| 92 metadata: list of dict List of metadata for each annotation. Each item | 92 metadata: list of dict List of metadata for each annotation. Each item |
| 93 includes the following fields: | 93 includes the following fields: |
| 94 function_type: str Type of the function that defines the annotation. | 94 function_type: str Type of the function that defines the annotation. |
| 95 extra_id: str Possible prefix for annotation completion. | 95 extra_id: str Possible prefix for annotation completion. |
| 96 errors: list of str List of errors. | 96 errors: list of str List of errors. |
| 97 """ | 97 """ |
| 98 annotations = traffic_annotation_pb2.ExtractedNetworkTrafficAnnotation() | 98 annotations = traffic_annotation_pb2.ExtractedNetworkTrafficAnnotation() |
| 99 errors = [] | 99 errors = [] |
| 100 metadata = [] | 100 metadata = [] |
| 101 | 101 |
| 102 lines = [line.strip("\r\n") for line in raw_annotations.split("\n")] | 102 lines = [line.strip("\r\n") for line in raw_annotations.split("\n")] |
| 103 current = 0 | 103 current = 0 |
| 104 | 104 |
| 105 try: | 105 try: |
| 106 while current < len(lines) - 1: | 106 while current < len(lines) - 1: |
|
msramek
2017/05/29 21:03:37
Not necessarily in this CL, but this logic looks l
Ramin Halavati
2017/05/30 04:40:37
Acknowledged.
| |
| 107 if lines[current] != "==== NEW ANNOTATION ====": | 107 if lines[current] == "==== NEW ANNOTATION ====": |
| 108 if current + 5 >= len(lines): | |
|
msramek
2017/05/29 21:03:36
+5 is not enough, since you're accessing +6 at lin
Ramin Halavati
2017/05/30 04:40:37
Done.
| |
| 109 raise Exception( | |
| 110 "Not enough header lines at line %i." % current) | |
| 111 | |
| 112 # Extract header lines. | |
| 113 source = traffic_annotation_pb2.NetworkTrafficAnnotation.TrafficSource() | |
| 114 source.file = lines[current + 1] | |
| 115 source.function = lines[current + 2] | |
| 116 source.line = int(lines[current + 3]) | |
| 117 unique_id = lines[current + 5] | |
| 118 | |
| 119 new_metadata = {'function_type': lines[current + 4], | |
| 120 'extra_id': lines[current + 6], | |
| 121 'unique_id_hash': _ComputeStringHash(unique_id)} | |
| 122 # Extract serialized proto. | |
| 123 current += 7 | |
| 124 annotation_text = "" | |
| 125 | |
| 126 while current < len(lines): | |
| 127 current += 1 | |
|
msramek
2017/05/29 21:03:37
optional: Consider moving this current += 1 at the
Ramin Halavati
2017/05/30 04:40:36
Done.
| |
| 128 if lines[current - 1] == "==== ANNOTATION ENDS ====": | |
| 129 break | |
| 130 else: | |
| 131 annotation_text += lines[current - 1] | |
| 132 else: | |
| 133 raise Exception( | |
| 134 "Error at line %i, expected annotation end tag." % current) | |
| 135 | |
|
msramek
2017/05/29 21:03:37
Should we handle an empty |annotation_text| here?
Ramin Halavati
2017/05/30 04:40:36
It would be checked later when proto is deserializ
| |
| 136 # Process unittests and undefined tags. | |
| 137 if unique_id in ("test", "test_partial"): | |
| 138 continue | |
| 139 if unique_id in ("undefined", "missing"): | |
| 140 errors.append("Annotation is not defined for file '%s', line %i." % | |
| 141 (source.file, source.line)) | |
| 142 continue | |
| 143 | |
| 144 # Decode serialized proto. | |
| 145 annotation_proto = traffic_annotation_pb2.NetworkTrafficAnnotation() | |
| 146 try: | |
| 147 text_format.Parse(annotation_text, annotation_proto) | |
| 148 except Exception as error: | |
| 149 errors.append("Annotation in file '%s', line %i, has error: %s" % | |
|
msramek
2017/05/29 21:03:37
nit: an error
Ramin Halavati
2017/05/30 04:40:36
Done.
| |
| 150 (source.file, source.line, error)) | |
| 151 | |
| 152 # Add new proto. | |
| 153 annotation_proto.unique_id = unique_id | |
| 154 annotation_proto.source.CopyFrom(source) | |
| 155 annotations.network_traffic_annotation.add().CopyFrom(annotation_proto) | |
| 156 metadata.append(new_metadata) | |
| 157 elif lines[current] == "==== NEW CALL ====": | |
| 158 # Ignore calls for now. | |
| 159 while current < len(lines): | |
| 160 current += 1 | |
| 161 if lines[current - 1] == "==== CALL ENDS ====": | |
| 162 break | |
| 163 else: | |
| 164 raise Exception( | |
| 165 "Error at line %i, expected call end tag." % current) | |
| 166 else: # The line is neither new annotation nor new call. | |
| 108 raise Exception( | 167 raise Exception( |
| 109 "Error at line %i, expected starting new annotaion." % current) | 168 "Error at line %i, expected starting new annotation or call." % |
| 110 if current + 5 >= len(lines): | 169 current) |
| 111 raise Exception( | |
| 112 "Not enough header lines at line %i." % current) | |
| 113 | |
| 114 # Extract header lines. | |
| 115 source = traffic_annotation_pb2.NetworkTrafficAnnotation.TrafficSource() | |
| 116 source.file = lines[current + 1] | |
| 117 source.function = lines[current + 2] | |
| 118 source.line = int(lines[current + 3]) | |
| 119 unique_id = lines[current + 5] | |
| 120 | |
| 121 new_metadata = {'function_type': lines[current + 4], | |
| 122 'extra_id': lines[current + 6], | |
| 123 'unique_id_hash': _ComputeStringHash(unique_id)} | |
| 124 # Extract serialized proto. | |
| 125 current += 7 | |
| 126 annotation_text = "" | |
| 127 | |
| 128 while current < len(lines): | |
| 129 current += 1 | |
| 130 if lines[current - 1] == "==== ANNOTATION ENDS ====": | |
| 131 break | |
| 132 else: | |
| 133 annotation_text += lines[current - 1] | |
| 134 else: | |
| 135 raise Exception( | |
| 136 "Error at line %i, expected annotation end tag." % current) | |
| 137 | |
| 138 # Process unittests and undefined tags. | |
| 139 if unique_id in ("test", "test_partial"): | |
| 140 continue | |
| 141 if unique_id in ("undefined", "missing"): | |
| 142 errors.append("Annotation is not defined for file '%s', line %i." % | |
| 143 (source.file, source.line)) | |
| 144 continue | |
| 145 | |
| 146 # Decode serialized proto. | |
| 147 annotation_proto = traffic_annotation_pb2.NetworkTrafficAnnotation() | |
| 148 try: | |
| 149 text_format.Parse(annotation_text, annotation_proto) | |
| 150 except Exception as error: | |
| 151 errors.append("Annotation in file '%s', line %i, has error: %s" % | |
| 152 (source.file, source.line, error)) | |
| 153 | |
| 154 # Add new proto. | |
| 155 annotation_proto.unique_id = unique_id | |
| 156 annotation_proto.source.CopyFrom(source) | |
| 157 annotations.network_traffic_annotation.add().CopyFrom(annotation_proto) | |
| 158 metadata.append(new_metadata) | |
| 159 | 170 |
| 160 except Exception as error: | 171 except Exception as error: |
| 161 errors.append(str(error)) | 172 errors.append(str(error)) |
| 162 | 173 |
| 163 print "Extracted %i annotations with %i errors." % \ | 174 print "Extracted %i annotations with %i errors." % \ |
| 164 (len(annotations.network_traffic_annotation), len(errors)) | 175 (len(annotations.network_traffic_annotation), len(errors)) |
| 165 return annotations, metadata, errors | 176 return annotations, metadata, errors |
| 166 | 177 |
| 167 | 178 |
| 168 def _WriteSummaryFile(annotations, metadata, errors, file_path): | 179 def _WriteSummaryFile(annotations, metadata, errors, file_path): |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 265 _WriteSummaryFile(annotations, metadata, errors, args.summary_file) | 276 _WriteSummaryFile(annotations, metadata, errors, args.summary_file) |
| 266 | 277 |
| 267 if args.hash_codes_file: | 278 if args.hash_codes_file: |
| 268 _WriteHashCodesFile(annotations, metadata, args.hash_codes_file) | 279 _WriteHashCodesFile(annotations, metadata, args.hash_codes_file) |
| 269 | 280 |
| 270 return 0 | 281 return 0 |
| 271 | 282 |
| 272 | 283 |
| 273 if __name__ == '__main__': | 284 if __name__ == '__main__': |
| 274 sys.exit(main()) | 285 sys.exit(main()) |
| OLD | NEW |