1*9c5db199SXin Li# Lint as: python3 2*9c5db199SXin Li# Copyright 2020 The Chromium OS Authors. All rights reserved. 3*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be 4*9c5db199SXin Li# found in the LICENSE file. 5*9c5db199SXin Li 6*9c5db199SXin Liimport ast 7*9c5db199SXin Liimport collections 8*9c5db199SXin Liimport glob 9*9c5db199SXin Liimport logging 10*9c5db199SXin Liimport os 11*9c5db199SXin Liimport shutil 12*9c5db199SXin Lifrom typing import Generator, List, DefaultDict, NoReturn, Optional, Tuple 13*9c5db199SXin Li 14*9c5db199SXin Liimport control_files 15*9c5db199SXin Li 16*9c5db199SXin Li_ROOT_DIR = os.path.realpath( 17*9c5db199SXin Li os.path.join(os.path.realpath(__file__), '../../..')) 18*9c5db199SXin Li_METADATA_DIR = os.path.join(_ROOT_DIR, 'metadata') 19*9c5db199SXin Li_CATEGORY_DEFS_DIR = os.path.join(_METADATA_DIR, 'tests') 20*9c5db199SXin Li_CATEGORY_DEFS_PACKAGE = '//metadata/tests' 21*9c5db199SXin Li_ALL_TESTS_FILE = os.path.join(_METADATA_DIR, 'tests.star') 22*9c5db199SXin Li 23*9c5db199SXin Li 24*9c5db199SXin Liclass ExtractionError(Exception): 25*9c5db199SXin Li """Generic error from this package.""" 26*9c5db199SXin Li 27*9c5db199SXin Li 28*9c5db199SXin Lidef main(): 29*9c5db199SXin Li """Extract starlark metadata for all tests in this project. 30*9c5db199SXin Li 31*9c5db199SXin Li This script generates the starlark config files by parsing control files. 32*9c5db199SXin Li The intent is to backfill majority of the required starlark configs this way, 33*9c5db199SXin Li followed by hand-editing. 34*9c5db199SXin Li """ 35*9c5db199SXin Li logging.basicConfig(level=logging.INFO) 36*9c5db199SXin Li controls = control_files.load_all() 37*9c5db199SXin Li logging.info('Loaded %d control files', len(controls)) 38*9c5db199SXin Li categorized = dict(_categorize_control_files(controls)) 39*9c5db199SXin Li logging.info('Categorized control files into %d categories', len(categorized)) 40*9c5db199SXin Li 41*9c5db199SXin Li _delete_existing_defs() 42*9c5db199SXin Li for category, control in categorized.items(): 43*9c5db199SXin Li with open(_category_def_file(category), 'w') as f: 44*9c5db199SXin Li f.write(_generate_category_def(control)) 45*9c5db199SXin Li logging.info('Wrote starlark files to %s', _CATEGORY_DEFS_DIR) 46*9c5db199SXin Li with open(_ALL_TESTS_FILE, 'w') as f: 47*9c5db199SXin Li f.write(_generate_all_tests_def(categorized.keys())) 48*9c5db199SXin Li logging.info('Included all categories in %s', _ALL_TESTS_FILE) 49*9c5db199SXin Li 50*9c5db199SXin Li 51*9c5db199SXin Lidef _delete_existing_defs() -> NoReturn: 52*9c5db199SXin Li if os.path.exists(_CATEGORY_DEFS_DIR): 53*9c5db199SXin Li shutil.rmtree(_CATEGORY_DEFS_DIR) 54*9c5db199SXin Li os.mkdir(_CATEGORY_DEFS_DIR) 55*9c5db199SXin Li if os.path.exists(_ALL_TESTS_FILE): 56*9c5db199SXin Li os.unlink(_ALL_TESTS_FILE) 57*9c5db199SXin Li 58*9c5db199SXin Li 59*9c5db199SXin Lidef _categorize_control_files(controls: List[control_files.Control] 60*9c5db199SXin Li ) -> DefaultDict[str, control_files.Control]: 61*9c5db199SXin Li categorized = collections.defaultdict(list) 62*9c5db199SXin Li for c in controls: 63*9c5db199SXin Li categorized[c.category].append(c) 64*9c5db199SXin Li if 'uncategorized' in categorized: 65*9c5db199SXin Li raise ExtractionError('"uncategorized" is reserved') 66*9c5db199SXin Li if '' in categorized: 67*9c5db199SXin Li categorized['uncategorized'] = categorized[''] 68*9c5db199SXin Li del categorized[''] 69*9c5db199SXin Li return categorized 70*9c5db199SXin Li 71*9c5db199SXin Li 72*9c5db199SXin Lidef _category_def_file(category: str) -> str: 73*9c5db199SXin Li return os.path.join(_CATEGORY_DEFS_DIR, '%s.star' % category) 74*9c5db199SXin Li 75*9c5db199SXin Li 76*9c5db199SXin Li_CATEGORY_TEMPLATE = """ 77*9c5db199SXin Li# Copyright 2020 The Chromium OS Authors. All rights reserved. 78*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be 79*9c5db199SXin Li# found in the LICENSE file. 80*9c5db199SXin Li 81*9c5db199SXin Li# !!! GENERATED FILE. DO NOT EDIT !!! 82*9c5db199SXin Li 83*9c5db199SXin Liload('//metadata/test_common.star', 'test_common') 84*9c5db199SXin Li 85*9c5db199SXin Lidef define_tests(): 86*9c5db199SXin Li return [%(test_list)s 87*9c5db199SXin Li ] 88*9c5db199SXin Li""" 89*9c5db199SXin Li 90*9c5db199SXin Li_TEST_TEMPLATE = """ 91*9c5db199SXin Li test_common.define_test( 92*9c5db199SXin Li %(name)s, 93*9c5db199SXin Li suites = %(suites)s, 94*9c5db199SXin Li main_package = %(main_package)s, 95*9c5db199SXin Li )""" 96*9c5db199SXin Li 97*9c5db199SXin Li 98*9c5db199SXin Lidef _generate_category_def(controls: List[control_files.Control]) -> str: 99*9c5db199SXin Li controls = sorted(controls, key=lambda c: c.name) 100*9c5db199SXin Li test_list = ','.join([ 101*9c5db199SXin Li _TEST_TEMPLATE % { 102*9c5db199SXin Li 'name': "'%s/%s'" % (c.category, c.name), 103*9c5db199SXin Li 'suites': sorted(c.suites), 104*9c5db199SXin Li 'main_package': "'%s'" % c.main_package, 105*9c5db199SXin Li } for c in controls 106*9c5db199SXin Li ]) 107*9c5db199SXin Li return _CATEGORY_TEMPLATE % {'test_list': test_list} 108*9c5db199SXin Li 109*9c5db199SXin Li 110*9c5db199SXin Li_ALL_CATEGORIES_TEMPLATE = """ 111*9c5db199SXin Li# Copyright 2020 The Chromium OS Authors. All rights reserved. 112*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be 113*9c5db199SXin Li# found in the LICENSE file. 114*9c5db199SXin Li 115*9c5db199SXin Li# !!! GENERATED FILE. DO NOT EDIT !!! 116*9c5db199SXin Li 117*9c5db199SXin Li%(load_inclusions)s 118*9c5db199SXin Li 119*9c5db199SXin Lidef define_tests(): 120*9c5db199SXin Li tests = [] 121*9c5db199SXin Li %(append_inclusions)s 122*9c5db199SXin Li return tests 123*9c5db199SXin Li""" 124*9c5db199SXin Li 125*9c5db199SXin Li_LOAD_CATEGORY_TEMPLATE = """ 126*9c5db199SXin Liload('%(path)s', define_%(name)s = 'define_tests')""" 127*9c5db199SXin Li 128*9c5db199SXin Li_APPEND_CATEGORY_TEMPLATE = """ 129*9c5db199SXin Li tests += define_%(name)s()""" 130*9c5db199SXin Li 131*9c5db199SXin Li 132*9c5db199SXin Lidef _generate_all_tests_def(categories: List[str]) -> str: 133*9c5db199SXin Li load_inclusions = [ 134*9c5db199SXin Li _LOAD_CATEGORY_TEMPLATE % { 135*9c5db199SXin Li 'name': c, 136*9c5db199SXin Li 'path': '%s/%s.star' % (_CATEGORY_DEFS_PACKAGE, c), 137*9c5db199SXin Li } for c in categories 138*9c5db199SXin Li ] 139*9c5db199SXin Li append_inclusions = [ 140*9c5db199SXin Li _APPEND_CATEGORY_TEMPLATE % { 141*9c5db199SXin Li 'name': c 142*9c5db199SXin Li } for c in categories 143*9c5db199SXin Li ] 144*9c5db199SXin Li return _ALL_CATEGORIES_TEMPLATE % { 145*9c5db199SXin Li 'load_inclusions': ''.join(load_inclusions), 146*9c5db199SXin Li 'append_inclusions': ''.join(append_inclusions), 147*9c5db199SXin Li } 148*9c5db199SXin Li 149*9c5db199SXin Li 150*9c5db199SXin Liif __name__ == '__main__': 151*9c5db199SXin Li main() 152