check_test_cases.py (3156B)
1 #!/usr/bin/env python3 2 3 """Sanity checks for test data.""" 4 5 # Copyright The Mbed TLS Contributors 6 # SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 7 8 import argparse 9 import re 10 import sys 11 12 from mbedtls_framework import collect_test_cases 13 14 15 class DescriptionChecker(collect_test_cases.TestDescriptionExplorer): 16 """Check all test case descriptions. 17 18 * Check that each description is valid (length, allowed character set, etc.). 19 * Check that there is no duplicated description inside of one test suite. 20 """ 21 22 def __init__(self, results): 23 self.results = results 24 25 def new_per_file_state(self): 26 """Dictionary mapping descriptions to their line number.""" 27 return {} 28 29 def process_test_case(self, per_file_state, 30 file_name, line_number, description): 31 """Check test case descriptions for errors.""" 32 results = self.results 33 seen = per_file_state 34 if description in seen: 35 results.error(file_name, line_number, 36 'Duplicate description (also line {})', 37 seen[description]) 38 return 39 if re.search(br'[\t;]', description): 40 results.error(file_name, line_number, 41 'Forbidden character \'{}\' in description', 42 re.search(br'[\t;]', description).group(0).decode('ascii')) 43 if re.search(br'[^ -~]', description): 44 results.error(file_name, line_number, 45 'Non-ASCII character in description') 46 if len(description) > 66: 47 results.warning(file_name, line_number, 48 'Test description too long ({} > 66)', 49 len(description)) 50 seen[description] = line_number 51 52 def main(): 53 parser = argparse.ArgumentParser(description=__doc__) 54 parser.add_argument('--list-all', 55 action='store_true', 56 help='List all test cases, without doing checks') 57 parser.add_argument('--quiet', '-q', 58 action='store_true', 59 help='Hide warnings') 60 parser.add_argument('--verbose', '-v', 61 action='store_false', dest='quiet', 62 help='Show warnings (default: on; undoes --quiet)') 63 options = parser.parse_args() 64 if options.list_all: 65 descriptions = collect_test_cases.collect_available_test_cases() 66 sys.stdout.write('\n'.join(descriptions + [''])) 67 return 68 results = collect_test_cases.Results(options) 69 checker = DescriptionChecker(results) 70 try: 71 checker.walk_all() 72 except collect_test_cases.ScriptOutputError as e: 73 results.error(e.script_name, e.idx, 74 '"{}" should be listed as "<suite_name>;<description>"', 75 e.line) 76 if (results.warnings or results.errors) and not options.quiet: 77 sys.stderr.write('{}: {} errors, {} warnings\n' 78 .format(sys.argv[0], results.errors, results.warnings)) 79 sys.exit(1 if results.errors else 0) 80 81 if __name__ == '__main__': 82 main()