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

Side by Side Diff: net/data/verify_certificate_chain_unittest/rebase-errors.py

Issue 2323223002: Add a script to update the expected errors for (Closed)
Patch Set: Read from stdin if no argument Created 4 years, 3 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 | « net/data/verify_certificate_chain_unittest/generate-violates-pathlen-1-constrained-root.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/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 """Helper script to update the test error expectations based on actual results.
7
8 This is useful for regenerating test expectations after making changes to the
9 error format.
10
11 To use this run the affected tests, and then pass the input to this script
12 (either via stdin, or as the first argument). For instance:
13
14 $ ./out/Release/net_unittests --gtest_filter="*VerifyCertificateChain*" | \
15 net/data/verify_certificate_chain_unittest/rebase-errors.py
16
17 The script will search the unit-test (results.txt in above example) and look
18 for failure lines and the corresponding actual error string.
19
20 It will then go and update the corresponding .pem and .py file.
21 """
22
23 import common
24 import glob
25 import os
26 import sys
27 import re
28
29
30 def read_file_to_string(path):
31 """Reads a file entirely to a string"""
32 with open(path, 'r') as f:
33 return f.read()
34
35
36 def write_string_to_file(data, path):
37 """Writes a string to a file"""
38 print "Writing file %s ..." % (path)
39 with open(path, "w") as f:
40 f.write(data)
41
42
43 def get_file_paths_for_test(test_name):
44 """Returns the file paths (as a tuple) that define a particular unit test.
45 For instance given test name 'IntermediateLacksBasicConstraints' it would
46 return the paths to:
47
48 * intermediate-lacks-basic-constraints.pem,
49 * generate-intermediate-lacks-basic-constraints.py
50 """
51 # The directory that this python script is stored in.
52 base_dir = os.path.dirname(os.path.realpath(__file__))
53
54 # The C++ test name is just a camel case verson of the file name. Rather than
55 # converting directly from camel case to a file name, it is simpler to just
56 # scan the file list and see which matches. (Not efficient but good enough).
57 paths = glob.glob(os.path.join(base_dir, '*.pem'))
58
59 for pem_path in paths:
60 file_name = os.path.basename(pem_path)
61 file_name_no_extension = os.path.splitext(file_name)[0]
62
63 # Strip the hyphens in file name to bring it closer to the camel case.
64 transformed = file_name_no_extension.replace('-', '')
65
66 # Now all that differs is the case.
67 if transformed.lower() == test_name.lower():
68 py_file_name = 'generate-' + file_name_no_extension + '.py'
69 py_path = os.path.join(base_dir, py_file_name)
70 return (pem_path, py_path)
71
72 return None
73
74
75 def replace_string(original, start, end, replacement):
76 """Replaces the specified range of |original| with |replacement|"""
77 return original[0:start] + replacement + original[end:]
78
79
80 def fixup_pem_file(path, actual_errors):
81 """Updates the ERRORS block in the test .pem file"""
82 contents = read_file_to_string(path)
83
84 # This assumes that ERRORS is the last thing in file, and comes after the
85 # VERIFY_RESULT block.
86 kEndVerifyResult = '-----END VERIFY_RESULT-----'
87 contents = contents[0:contents.index(kEndVerifyResult)]
88 contents += kEndVerifyResult
89 contents += '\n'
90 contents += '\n'
91 contents += common.text_data_to_pem('ERRORS', actual_errors)
92
93 # Update the file.
94 write_string_to_file(contents, path)
95
96
97 def fixup_py_file(path, actual_errors):
98 """Replaces the 'errors = XXX' section of the test's python script"""
99 contents = read_file_to_string(path)
100
101 # This assumes that the errors variable uses triple quotes.
102 prog = re.compile(r'^errors = """(.*)"""', re.MULTILINE | re.DOTALL)
103 result = prog.search(contents)
104
105 # Replace the stuff in between the triple quotes with the actual errors.
106 contents = replace_string(contents, result.start(1), result.end(1),
107 actual_errors)
108
109 # Update the file.
110 write_string_to_file(contents, path)
111
112
113 def fixup_test(test_name, actual_errors):
114 """Updates the test files used by |test_name|, setting the expected error to
115 |actual_errors|"""
116
117 # Determine the paths for the corresponding *.pem file and generate-*.py
118 pem_path, py_path = get_file_paths_for_test(test_name)
119
120 fixup_pem_file(pem_path, actual_errors)
121 fixup_py_file(py_path, actual_errors)
122
123
124 kTestNamePattern = (r'^\[ RUN \] VerifyCertificateChain/'
125 'VerifyCertificateChainSingleRootTest/0\.(.*)$')
126 kValueOfLine = 'Value of: errors.ToDebugString()'
127 kActualPattern = '^ Actual: "(.*)"$'
128
129
130 def main():
131 if len(sys.argv) > 2:
132 print 'Usage: %s [path-to-unittest-stdout]' % (sys.argv[0])
133 sys.exit(1)
134
135 # Read the input either from a file, or from stdin.
136 test_stdout = None
137 if len(sys.argv) == 2:
138 test_stdout = read_file_to_string(sys.argv[1])
139 else:
140 print 'Reading input from stdin...'
141 test_stdout = sys.stdin.read()
142
143 lines = test_stdout.split('\n')
144
145 # Iterate over each line of the unit test stdout.
146 for i in range(len(lines) - 3):
147 # Figure out the name of the test.
148 m = re.search(kTestNamePattern, lines[i])
149 if not m:
150 continue
151 test_name = m.group(1)
152
153 # Confirm that it is a failure having to do with the errors.
154 if lines[i + 2] != kValueOfLine:
155 continue
156
157 # Get the actual error text (which in gtest output is escaped).
158 m = re.search(kActualPattern, lines[i + 3])
159 if not m:
160 continue
161 actual = m.group(1)
162 actual = actual.decode('string-escape')
163
164 fixup_test(test_name, actual)
165
166
167 if __name__ == "__main__":
168 main()
OLDNEW
« no previous file with comments | « net/data/verify_certificate_chain_unittest/generate-violates-pathlen-1-constrained-root.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698