1#!/usr/bin/python3 2# Copyright (c) 2021 The Chromium OS 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"""Generate metadata for build from Autotest ctrl files.""" 6 7import argparse 8import os 9import six 10import sys 11 12# If running in Autotest dir, keep this. 13os.environ["PY_VERSION"] = '3' 14 15import common 16 17# NOTE: this MUST be run in Python3, if we get configured back to PY2, exit. 18if six.PY2: 19 exit(1) 20 21from autotest_lib.server.cros.dynamic_suite import control_file_getter 22from autotest_lib.client.common_lib import control_data 23 24from chromiumos.test.api import test_case_metadata_pb2 as tc_metadata_pb 25from chromiumos.test.api import test_harness_pb2 as th_pb 26from chromiumos.test.api import test_case_pb2 as tc_pb 27 28HARNESS = th_pb.TestHarness.Tauto() 29 30 31def parse_local_arguments(args): 32 """Parse the CLI.""" 33 parser = argparse.ArgumentParser( 34 description="Prep Autotest, Tast, & Services for DockerBuild.") 35 parser.add_argument('-autotest_path', 36 dest='autotest_path', 37 default='../../../../third_party/autotest/files/', 38 help='path to autotest/files relative to this script.') 39 parser.add_argument('-output_file', 40 dest='output_file', 41 default=None, 42 help='Where to write the serialized pb.') 43 return parser.parse_args(args) 44 45 46def read_file(filename): 47 """Read the given file.""" 48 with open(filename, 'r') as f: 49 return f.read() 50 51 52def all_control_files(args): 53 """Return all control files as control file objs.""" 54 subpaths = ['server/site_tests', 'client/site_tests'] 55 start_cwd = os.getcwd() 56 try: 57 os.chdir(args.autotest_path) 58 59 # Might not be needed, but this resolves out the ../ 60 autotest_path = os.getcwd() 61 62 directories = [os.path.join(autotest_path, p) for p in subpaths] 63 f = control_file_getter.FileSystemGetter(directories) 64 except Exception as e: 65 raise Exception("Failed to find control files at path %s", 66 args.autotest_path) 67 68 finally: 69 os.chdir(start_cwd) 70 return f._get_control_file_list() 71 72 73def serialize_test_case_info(data): 74 """Return a serialized TestCaseInfo obj.""" 75 serialized_contacts = tc_metadata_pb.Contact(email=data.author) 76 return tc_metadata_pb.TestCaseInfo(owners=[serialized_contacts]) 77 78 79def serialize_tags(data): 80 """Return a serialized tags obj (list).""" 81 serialized_tags = [] 82 for value in data.dependencies: 83 serialized_tags.append(tc_pb.TestCase.Tag(value=value)) 84 for value in data.attributes: 85 serialized_tags.append(tc_pb.TestCase.Tag(value=value)) 86 if data.test_class: 87 serialized_tags.append( 88 tc_pb.TestCase.Tag( 89 value="test_class:{}".format(data.test_class))) 90 return serialized_tags 91 92 93def serialize_test_case(data): 94 """Return a serialized api.TestCase obj.""" 95 serialized_testcase_id = tc_pb.TestCase.Id(value="tauto." + data.name) 96 tags = serialize_tags(data) 97 return tc_pb.TestCase(id=serialized_testcase_id, name=data.name, tags=tags) 98 99 100def serialized_test_case_exec(data): 101 """Return a serialized TestCaseExec obj.""" 102 serialized_test_harness = th_pb.TestHarness(tauto=HARNESS) 103 return tc_metadata_pb.TestCaseExec(test_harness=serialized_test_harness) 104 105 106def serialized_test_case_metadata(data): 107 """Return a TestCaseMetadata obj from a given control file.""" 108 serialized_meta_data = tc_metadata_pb.TestCaseMetadata( 109 test_case_exec=serialized_test_case_exec(data), 110 test_case=serialize_test_case(data), 111 test_case_info=serialize_test_case_info(data)) 112 return serialized_meta_data 113 114 115def serialized_test_case_metadata_list(data): 116 """Return a TestCaseMetadataList obj from a list of TestCaseMetadata pb.""" 117 serialized_meta_data_list = tc_metadata_pb.TestCaseMetadataList( 118 values=data) 119 return serialized_meta_data_list 120 121 122def main(): 123 """Generate the metadata, and if an output path is given, save it.""" 124 args = parse_local_arguments(sys.argv[1:]) 125 ctrlfiles = all_control_files(args) 126 serialized_metadata = [] 127 for file_path in ctrlfiles: 128 text = read_file(file_path) 129 path = ctrlfiles[1] 130 131 test = control_data.parse_control_string(text, 132 raise_warnings=True, 133 path=path) 134 serialized_metadata.append(serialized_test_case_metadata(test)) 135 136 serialized = serialized_test_case_metadata_list(serialized_metadata) 137 if args.output_file: 138 with open(args.output_file, 'wb') as wf: 139 wf.write(serialized.SerializeToString()) 140 141 142if __name__ == '__main__': 143 main() 144