1a5f9918aSopenharmony_ci 2a5f9918aSopenharmony_ciimport sys, os, os.path, types, traceback, pprint 3a5f9918aSopenharmony_ci 4a5f9918aSopenharmony_ciDATA = 'tests/data' 5a5f9918aSopenharmony_ci 6a5f9918aSopenharmony_cidef find_test_functions(collections): 7a5f9918aSopenharmony_ci if not isinstance(collections, list): 8a5f9918aSopenharmony_ci collections = [collections] 9a5f9918aSopenharmony_ci functions = [] 10a5f9918aSopenharmony_ci for collection in collections: 11a5f9918aSopenharmony_ci if not isinstance(collection, dict): 12a5f9918aSopenharmony_ci collection = vars(collection) 13a5f9918aSopenharmony_ci for key in sorted(collection): 14a5f9918aSopenharmony_ci value = collection[key] 15a5f9918aSopenharmony_ci if isinstance(value, types.FunctionType) and hasattr(value, 'unittest'): 16a5f9918aSopenharmony_ci functions.append(value) 17a5f9918aSopenharmony_ci return functions 18a5f9918aSopenharmony_ci 19a5f9918aSopenharmony_cidef find_test_filenames(directory): 20a5f9918aSopenharmony_ci filenames = {} 21a5f9918aSopenharmony_ci for filename in os.listdir(directory): 22a5f9918aSopenharmony_ci if os.path.isfile(os.path.join(directory, filename)): 23a5f9918aSopenharmony_ci base, ext = os.path.splitext(filename) 24a5f9918aSopenharmony_ci if base.endswith('-py2'): 25a5f9918aSopenharmony_ci continue 26a5f9918aSopenharmony_ci filenames.setdefault(base, []).append(ext) 27a5f9918aSopenharmony_ci filenames = sorted(filenames.items()) 28a5f9918aSopenharmony_ci return filenames 29a5f9918aSopenharmony_ci 30a5f9918aSopenharmony_cidef parse_arguments(args): 31a5f9918aSopenharmony_ci if args is None: 32a5f9918aSopenharmony_ci args = sys.argv[1:] 33a5f9918aSopenharmony_ci verbose = False 34a5f9918aSopenharmony_ci if '-v' in args: 35a5f9918aSopenharmony_ci verbose = True 36a5f9918aSopenharmony_ci args.remove('-v') 37a5f9918aSopenharmony_ci if '--verbose' in args: 38a5f9918aSopenharmony_ci verbose = True 39a5f9918aSopenharmony_ci args.remove('--verbose') 40a5f9918aSopenharmony_ci if 'YAML_TEST_VERBOSE' in os.environ: 41a5f9918aSopenharmony_ci verbose = True 42a5f9918aSopenharmony_ci include_functions = [] 43a5f9918aSopenharmony_ci if args: 44a5f9918aSopenharmony_ci include_functions.append(args.pop(0)) 45a5f9918aSopenharmony_ci if 'YAML_TEST_FUNCTIONS' in os.environ: 46a5f9918aSopenharmony_ci include_functions.extend(os.environ['YAML_TEST_FUNCTIONS'].split()) 47a5f9918aSopenharmony_ci include_filenames = [] 48a5f9918aSopenharmony_ci include_filenames.extend(args) 49a5f9918aSopenharmony_ci if 'YAML_TEST_FILENAMES' in os.environ: 50a5f9918aSopenharmony_ci include_filenames.extend(os.environ['YAML_TEST_FILENAMES'].split()) 51a5f9918aSopenharmony_ci return include_functions, include_filenames, verbose 52a5f9918aSopenharmony_ci 53a5f9918aSopenharmony_cidef execute(function, filenames, verbose): 54a5f9918aSopenharmony_ci name = function.__name__ 55a5f9918aSopenharmony_ci if verbose: 56a5f9918aSopenharmony_ci sys.stdout.write('='*75+'\n') 57a5f9918aSopenharmony_ci sys.stdout.write('%s(%s)...\n' % (name, ', '.join(filenames))) 58a5f9918aSopenharmony_ci try: 59a5f9918aSopenharmony_ci function(verbose=verbose, *filenames) 60a5f9918aSopenharmony_ci except Exception as exc: 61a5f9918aSopenharmony_ci info = sys.exc_info() 62a5f9918aSopenharmony_ci if isinstance(exc, AssertionError): 63a5f9918aSopenharmony_ci kind = 'FAILURE' 64a5f9918aSopenharmony_ci else: 65a5f9918aSopenharmony_ci kind = 'ERROR' 66a5f9918aSopenharmony_ci if verbose: 67a5f9918aSopenharmony_ci traceback.print_exc(limit=1, file=sys.stdout) 68a5f9918aSopenharmony_ci else: 69a5f9918aSopenharmony_ci sys.stdout.write(kind[0]) 70a5f9918aSopenharmony_ci sys.stdout.flush() 71a5f9918aSopenharmony_ci else: 72a5f9918aSopenharmony_ci kind = 'SUCCESS' 73a5f9918aSopenharmony_ci info = None 74a5f9918aSopenharmony_ci if not verbose: 75a5f9918aSopenharmony_ci sys.stdout.write('.') 76a5f9918aSopenharmony_ci sys.stdout.flush() 77a5f9918aSopenharmony_ci return (name, filenames, kind, info) 78a5f9918aSopenharmony_ci 79a5f9918aSopenharmony_cidef display(results, verbose): 80a5f9918aSopenharmony_ci if results and not verbose: 81a5f9918aSopenharmony_ci sys.stdout.write('\n') 82a5f9918aSopenharmony_ci total = len(results) 83a5f9918aSopenharmony_ci failures = 0 84a5f9918aSopenharmony_ci errors = 0 85a5f9918aSopenharmony_ci for name, filenames, kind, info in results: 86a5f9918aSopenharmony_ci if kind == 'SUCCESS': 87a5f9918aSopenharmony_ci continue 88a5f9918aSopenharmony_ci if kind == 'FAILURE': 89a5f9918aSopenharmony_ci failures += 1 90a5f9918aSopenharmony_ci if kind == 'ERROR': 91a5f9918aSopenharmony_ci errors += 1 92a5f9918aSopenharmony_ci sys.stdout.write('='*75+'\n') 93a5f9918aSopenharmony_ci sys.stdout.write('%s(%s): %s\n' % (name, ', '.join(filenames), kind)) 94a5f9918aSopenharmony_ci if kind == 'ERROR': 95a5f9918aSopenharmony_ci traceback.print_exception(file=sys.stdout, *info) 96a5f9918aSopenharmony_ci else: 97a5f9918aSopenharmony_ci sys.stdout.write('Traceback (most recent call last):\n') 98a5f9918aSopenharmony_ci traceback.print_tb(info[2], file=sys.stdout) 99a5f9918aSopenharmony_ci sys.stdout.write('%s: see below\n' % info[0].__name__) 100a5f9918aSopenharmony_ci sys.stdout.write('~'*75+'\n') 101a5f9918aSopenharmony_ci for arg in info[1].args: 102a5f9918aSopenharmony_ci pprint.pprint(arg, stream=sys.stdout) 103a5f9918aSopenharmony_ci for filename in filenames: 104a5f9918aSopenharmony_ci sys.stdout.write('-'*75+'\n') 105a5f9918aSopenharmony_ci sys.stdout.write('%s:\n' % filename) 106a5f9918aSopenharmony_ci with open(filename, 'r', errors='replace') as file: 107a5f9918aSopenharmony_ci data = file.read() 108a5f9918aSopenharmony_ci sys.stdout.write(data) 109a5f9918aSopenharmony_ci if data and data[-1] != '\n': 110a5f9918aSopenharmony_ci sys.stdout.write('\n') 111a5f9918aSopenharmony_ci sys.stdout.write('='*75+'\n') 112a5f9918aSopenharmony_ci sys.stdout.write('TESTS: %s\n' % total) 113a5f9918aSopenharmony_ci if failures: 114a5f9918aSopenharmony_ci sys.stdout.write('FAILURES: %s\n' % failures) 115a5f9918aSopenharmony_ci if errors: 116a5f9918aSopenharmony_ci sys.stdout.write('ERRORS: %s\n' % errors) 117a5f9918aSopenharmony_ci return not (failures or errors) 118a5f9918aSopenharmony_ci 119a5f9918aSopenharmony_cidef run(collections, args=None): 120a5f9918aSopenharmony_ci test_functions = find_test_functions(collections) 121a5f9918aSopenharmony_ci test_filenames = find_test_filenames(DATA) 122a5f9918aSopenharmony_ci include_functions, include_filenames, verbose = parse_arguments(args) 123a5f9918aSopenharmony_ci results = [] 124a5f9918aSopenharmony_ci for function in test_functions: 125a5f9918aSopenharmony_ci if include_functions and function.__name__ not in include_functions: 126a5f9918aSopenharmony_ci continue 127a5f9918aSopenharmony_ci if function.unittest and function.unittest is not True: 128a5f9918aSopenharmony_ci for base, exts in test_filenames: 129a5f9918aSopenharmony_ci if include_filenames and base not in include_filenames: 130a5f9918aSopenharmony_ci continue 131a5f9918aSopenharmony_ci filenames = [] 132a5f9918aSopenharmony_ci for ext in function.unittest: 133a5f9918aSopenharmony_ci if ext not in exts: 134a5f9918aSopenharmony_ci break 135a5f9918aSopenharmony_ci filenames.append(os.path.join(DATA, base+ext)) 136a5f9918aSopenharmony_ci else: 137a5f9918aSopenharmony_ci skip_exts = getattr(function, 'skip', []) 138a5f9918aSopenharmony_ci for skip_ext in skip_exts: 139a5f9918aSopenharmony_ci if skip_ext in exts: 140a5f9918aSopenharmony_ci break 141a5f9918aSopenharmony_ci else: 142a5f9918aSopenharmony_ci result = execute(function, filenames, verbose) 143a5f9918aSopenharmony_ci results.append(result) 144a5f9918aSopenharmony_ci else: 145a5f9918aSopenharmony_ci result = execute(function, [], verbose) 146a5f9918aSopenharmony_ci results.append(result) 147a5f9918aSopenharmony_ci return display(results, verbose=verbose) 148a5f9918aSopenharmony_ci 149