blob: 4a1dd7dd8ff463ee1d519bf7398a647c6d159e8f [file] [log] [blame]
Fathi Boudra422bf772019-12-02 11:10:16 +02001#!/usr/bin/env python3
2#
Leonardo Sandoval579c7372020-10-23 15:23:32 -05003# Copyright (c) 2019-2020 Arm Limited. All rights reserved.
Fathi Boudra422bf772019-12-02 11:10:16 +02004#
5# SPDX-License-Identifier: BSD-3-Clause
6#
7#
8# Generate .test files in $workspace based on the $TEST_GROUPS parameter. Test
9# files are prefixed with a zero-padded number for a predictable ordering
10# amongst them.
11
12import os
13
14TEST_SUFFIX = ".test"
15
16
17def touch(a_file):
18 with open(a_file, "w"):
19 pass
20
21
22# Obtain the value of either $variable or $VARIABLE.
23def get_env(variable):
24 var_list = [variable, variable.upper()]
25 for v in var_list:
26 value = os.environ.get(v)
27 if value:
28 return value
29 else:
30 raise Exception("couldn't find {} in env".format(" or ".join(var_list)))
31
32
33# Perform group-specific translation on the build config
34def translate_build_config(group, config_list):
35 # config_list contains build configs as read from the test config
36 if group.startswith("scp-"):
37 # SCP configs would be specified in the following format:
Zelalem219df412020-05-17 19:21:20 -050038 # scp_config, tf_config, tftf_config, scp_tools
Fathi Boudra422bf772019-12-02 11:10:16 +020039 # Reshuffle them into the canonical format
Zelalem219df412020-05-17 19:21:20 -050040 config_list = [config_list[1], config_list[2], config_list[0], config_list[3]]
Fathi Boudra422bf772019-12-02 11:10:16 +020041
Olivier Deprez0a9a3482019-12-16 14:10:31 +010042 if group.startswith("spm-"):
43 # SPM configs would be specified in the following format:
44 # spm_config, tf_config, tftf_config, scp_config, scp_tools
45 # Reshuffle them into the canonical format
46 config_list = [config_list[1], config_list[2], config_list[3], config_list[4], config_list[0]]
47
Manish V Badarkhec36c4bf2025-03-12 14:56:54 +000048 if group.startswith("rmm-"):
49 # RMM configs would be specified in the following format:
50 # rmm_config, tf_config, tftf_config, spm_config, scp_config, scp_tools
51 # Reshuffle them into the canonical format
52 config_list = [config_list[1], config_list[2], config_list[4], config_list[5], config_list[3], config_list[0]]
53
Tomás Gonzálezfa3e24b2025-07-22 10:59:06 +010054 if group.startswith("rfa-"):
55 # RF-A configs would be specified in the following format:
56 # rfa_config, rmm_config, tf_config
57 # Reshuffle them into the canonical format
58 config_list = [config_list[2], config_list[3], config_list[5], config_list[6], config_list[4], config_list[1], config_list[0]]
59
Manish Pandey1a56ddb2024-03-22 17:09:21 +000060 if group.startswith("tf-l3-code-coverage"):
61 # coverage configs would be specified in the following format:
62 # tf_config, tftf_config, spm_config, scp_config, scp_tools
63 # Reshuffle them into the canonical format
64 config_list = [config_list[0], config_list[1], config_list[3], config_list[4], config_list[2]]
65
Fathi Boudra422bf772019-12-02 11:10:16 +020066 return config_list
67
68
69def gen_desc(group, test):
70 global num_spawn
71
72 build_config, run_config = test.split(":")
73
74 # Test descriptors are always generated in the following order:
Tomás Gonzálezfa3e24b2025-07-22 10:59:06 +010075 # tf_config, tftf_config, scp_config, scp_tools, spm_config, rmm_config, rfa_config
Fathi Boudra422bf772019-12-02 11:10:16 +020076 # Fill missing configs to the right with "nil".
Tomás Gonzálezfa3e24b2025-07-22 10:59:06 +010077 config_list = (build_config.split(",") + ["nil"] * 7)[:7]
Fathi Boudra422bf772019-12-02 11:10:16 +020078
79 # Perform any group-specific translation on the config
80 config_list = translate_build_config(group, config_list)
81
82 test_config = ",".join(config_list) + ":" + run_config
83
84 # Create descriptor. Write the name of the original test config as its
85 # content.
Paul Sokolovsky3cb66032021-11-03 13:36:17 +030086 desc_base = "%".join([str(num_spawn).zfill(4), os.path.basename(group),
87 test_config + TEST_SUFFIX])
88 desc = os.path.join(workspace, desc_base)
Fathi Boudra422bf772019-12-02 11:10:16 +020089 with open(desc, "wt") as fd:
90 print(test, file=fd)
Paul Sokolovsky3cb66032021-11-03 13:36:17 +030091 # Create .testprop file for smoother integration with Jenkins
92 # (allows to pass test config as a normal string param instead
93 # of binary file which takes extra clicks to view).
94 with open(desc + "prop", "wt") as fd:
95 print("TEST_CONFIG={}".format(test), file=fd)
96 print("TEST_DESC={}".format(desc_base), file=fd)
Fathi Boudra422bf772019-12-02 11:10:16 +020097
98 num_spawn += 1
99
100
101def process_item(item):
102 # If an item starts with @, then it's deemed to be an indirection--a file
103 # from which test groups are to be read.
104 if item.startswith("@"):
105 with open(item[1:]) as fd:
106 for line in fd:
107 line = line.strip()
108 if not line:
109 continue
110 process_item(line)
111
112 return
113
114 item_loc = os.path.join(group_dir, item)
115
116 if os.path.isfile(item_loc):
117 gen_desc(*item_loc.split(os.sep)[-2:])
118 elif os.path.isdir(item_loc):
119 # If it's a directory, select all files inside it
120 for a_file in next(os.walk(item_loc))[2]:
Paul Sokolovskya99999c2023-06-14 14:11:40 +0300121 if a_file.endswith(".inactive"):
122 continue
Fathi Boudra422bf772019-12-02 11:10:16 +0200123 gen_desc(item, a_file)
124 else:
125 # The item doesn't exist
126 if ":" in item:
127 # A non-existent test config is specified
128 if "/" in item:
129 # The test config doesn't exist, and a group is also specified.
130 # This is not allowed.
131 raise Exception("'{}' doesn't exist.".format(item))
132 else:
133 # The user probably intended to create one on the fly; so create
134 # one in the superficial 'GENERATED' group.
135 print("note: '{}' doesn't exist; generated.".format(item))
136 touch(os.path.join(generated_dir, item))
137 gen_desc(os.path.basename(generated_dir), item)
138 else:
139 raise Exception("'{}' is not valid for test generation!".format(item))
140
141
142ci_root = os.path.abspath(os.path.join(__file__, os.pardir, os.pardir))
143group_dir = os.path.join(ci_root, "group")
144num_spawn = 0
145
146# Obtain variables from environment
147test_groups = get_env("test_groups")
148workspace = get_env("workspace")
149
150# Remove all test files, if any
151_, _, files = next(os.walk(workspace))
152for test_file in files:
153 if test_file.endswith(TEST_SUFFIX):
154 os.remove(os.path.join(workspace, test_file))
155
156generated_dir = os.path.join(group_dir, "GENERATED")
157os.makedirs(generated_dir, exist_ok=True)
158
159for item in test_groups.split():
160 process_item(item)
161
162print()
Paul Sokolovskye2538732021-11-03 11:59:54 +0300163print("{} test configurations to be built...".format(num_spawn))
Fathi Boudra422bf772019-12-02 11:10:16 +0200164print()