1import json 2import os 3import re 4from xml.dom import minidom 5from xml.etree import ElementTree 6 7 8SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__)) 9TEST_JSON = 'tests.json' 10TEST_JSON_PATH = os.path.join(SCRIPT_DIR, TEST_JSON) 11 12 13def write_one_cc_test(test_details, f): 14 # TODO(b/161524664): Remove this exception for spir 15 if test_details['test_name'] == 'spir': 16 return 17 18 stringified_sources = map(lambda s: f'"{s}"', test_details['srcs']) 19 stringified_data = map(lambda s: f'"{s}"', test_details.get('data', [])) 20 stringified_cflags = map(lambda s: f'"{s}"', test_details.get('cflags', [])) 21 22 default = "ocl-test-defaults" 23 if test_details.get('image_type', False): 24 default = "ocl-test-image-defaults" 25 26 rtti = test_details.get('rtti', False) 27 28 cc_test_string = """ 29cc_test {{ 30 name: "{}", 31 srcs: [ {} ], 32 data: [ {} ], 33 cflags: [ {} ], 34 defaults: [ "{}" ], 35 rtti: {}, 36 gtest: false 37}} 38 39""".format(test_details['binary_name'], 40 ", ".join(stringified_sources), 41 ", ".join(stringified_data), 42 ", ".join(stringified_cflags), 43 default, 44 (str(rtti)).lower()) 45 46 empty_field_regex = re.compile("^\s*\w+: \[\s*\],?$") 47 cc_test_string = '\n'.join([line for line in cc_test_string.split('\n') 48 if not empty_field_regex.match(line)]) 49 f.write(cc_test_string) 50 51 52def generate_android_bp(): 53 android_bp_head_path = os.path.join(SCRIPT_DIR, 'android_bp_head') 54 android_bp_tail_path = os.path.join(SCRIPT_DIR, 'android_bp_tail') 55 56 with open('Android.bp', 'w') as android_bp: 57 with open(android_bp_head_path, 'r') as android_bp_head: 58 android_bp.write(android_bp_head.read()) 59 60 with open(TEST_JSON_PATH) as f: 61 tests = json.load(f) 62 for test in tests: 63 write_one_cc_test(test, android_bp) 64 65 with open(android_bp_tail_path, 'r') as android_bp_tail: 66 android_bp.write(android_bp_tail.read()) 67 68 69def create_subelement_with_attribs(element, tag, attribs): 70 subelement = ElementTree.SubElement(element, tag) 71 72 for key, value in attribs.items(): 73 subelement.attrib[key] = value 74 75 return subelement 76 77 78def generate_push_file_rules(configuration): 79 create_subelement_with_attribs(configuration, 'target_preparer', 80 { 'class': "com.android.tradefed.targetprep.RootTargetPreparer" }) 81 file_pusher = create_subelement_with_attribs(configuration, 'target_preparer', 82 { 'class': "com.android.compatibility.common.tradefed.targetprep.FilePusher" }) 83 create_subelement_with_attribs(file_pusher, 'option', 84 { 'name': "cleanup", 'value': "true" }) 85 create_subelement_with_attribs(file_pusher, 'option', 86 { 'name': "append-bitness", 'value': "true" }) 87 88 with open(TEST_JSON_PATH, "r") as f: 89 tests = json.load(f) 90 91 for test in tests: 92 if test.get('manual_only', False): 93 continue 94 95 create_subelement_with_attribs(file_pusher, 'option', 96 { 97 'name': "push-file", 98 'key': test['binary_name'], 99 'value': "/data/nativetest64/unrestricted/{}".format(test['binary_name']) 100 }) 101 102 103def generate_test_rules(configuration): 104 with open(TEST_JSON_PATH, "r") as f: 105 tests = json.load(f) 106 107 for test in tests: 108 if test.get('manual_only', False): 109 continue 110 111 test_rule = create_subelement_with_attribs(configuration, 'test', 112 { 'class': "com.android.tradefed.testtype.python.PythonBinaryHostTest" }) 113 114 create_subelement_with_attribs(test_rule, 'option', 115 { 'name': "par-file-name", 'value': "opencl_cts" }) 116 create_subelement_with_attribs(test_rule, 'option', 117 { 'name': "inject-android-serial", 'value': "true" }) 118 create_subelement_with_attribs(test_rule, 'option', 119 { 'name': "test-timeout", 'value': test.get('timeout', "30m") }) 120 create_subelement_with_attribs(test_rule, 'option', 121 { 'name': "python-options", 'value': test["test_name"] }) 122 create_subelement_with_attribs(test_rule, 'option', 123 { 'name': "python-options", 124 'value': "/data/nativetest64/unrestricted/{}".format(test['binary_name']) }) 125 126 for arg in test.get('arguments', []): 127 create_subelement_with_attribs(test_rule, 'option', 128 { 'name': "python-options", 'value': arg }) 129 130 131def generate_test_xml(): 132 configuration = ElementTree.Element('configuration') 133 configuration.attrib['description'] = "Config to run OpenCL CTS" 134 135 logcat = ElementTree.SubElement(configuration, 'option') 136 logcat.attrib['name'] = "logcat-on-failure" 137 logcat.attrib['value'] = "false" 138 139 generate_push_file_rules(configuration) 140 generate_test_rules(configuration) 141 142 stringified_configuration = ElementTree.tostring(configuration, 'utf-8') 143 reparsed_configuration = minidom.parseString(stringified_configuration) 144 with open('test_opencl_cts.xml', 'w') as f: 145 f.write(reparsed_configuration.toprettyxml(indent=" "*4)) 146 147 148def main(): 149 generate_android_bp() 150 generate_test_xml() 151 152 print("Don't forget to move -") 153 print(" Android.bp -> {ANDROID_ROOT}/external/OpenCL-CTS/Android.bp") 154 print(" test_opencl_cts.xml -> {ANDROID_ROOT}/external/OpenCL-CTS/scripts/test_opencl_cts.xml") 155 156 157if __name__ == '__main__': 158 main() 159