1"""Copyright (C) 2022 The Android Open Source Project
2Licensed under the Apache License, Version 2.0 (the "License");
3you may not use this file except in compliance with the License.
4You may obtain a copy of the License at
5     http://www.apache.org/licenses/LICENSE-2.0
6Unless required by applicable law or agreed to in writing, software
7distributed under the License is distributed on an "AS IS" BASIS,
8WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9See the License for the specific language governing permissions and
10limitations under the License.
11"""
12
13load("@bazel_skylib//lib:new_sets.bzl", "sets")
14load("@bazel_skylib//lib:paths.bzl", "paths")
15load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
16load("@soong_injection//cc_toolchain:config_constants.bzl", "constants")
17load(
18    "//build/bazel/rules/test_common:args.bzl",
19    "get_arg_value",
20    "get_arg_values",
21)
22load(":rscript_to_cpp.bzl", "rscript_to_cpp")
23
24SRCS = ["foo.rscript", "bar.fs"]
25USER_FLAGS = ["userFlag1"]
26
27def _test_rscript_to_cpp_commands_impl(ctx):
28    env = analysistest.begin(ctx)
29    actions = analysistest.target_actions(env)
30
31    args = actions[0].argv
32    asserts.true(env, len(args) >= 6)
33    expected_output_path = paths.join(
34        analysistest.target_bin_dir_path(env),
35        ctx.label.package,
36    )
37    asserts.equals(
38        env,
39        get_arg_value(args, "-o"),
40        expected_output_path,
41        "Argument -o not found or had unexpected value. Expected {} got {}"
42            .format(expected_output_path, get_arg_value(args, "-o")),
43    )
44
45    asserts.true(
46        env,
47        "-reflect-c++" in args,
48        "Argument -reflect-c++ not found",
49    )
50
51    asserts.true(
52        env,
53        "-Wall" in args,
54        "Argument -Wall not found",
55    )
56
57    asserts.true(
58        env,
59        "-Werror" in args,
60        "Argument -Werror not found",
61    )
62
63    for flag in USER_FLAGS:
64        asserts.true(
65            env,
66            flag in args,
67            "Expected user defined flag {} not found".format(flag),
68        )
69
70    includeFlags = get_arg_values(args, "-I")
71    asserts.set_equals(
72        env,
73        sets.make(constants.RsGlobalIncludes),
74        sets.make(includeFlags),
75        "Incorrect include statements",
76    )
77
78    asserts.true(
79        env,
80        paths.join(ctx.label.package, "baz.rscript"),
81        "Expected argument baz.rscript not found",
82    )
83
84    return analysistest.end(env)
85
86rscript_to_cpp_commands_test = analysistest.make(
87    _test_rscript_to_cpp_commands_impl,
88)
89
90def _test_rscript_to_cpp_commands():
91    name = "rscript_to_cpp_commands"
92    test_name = name + "_test"
93    rscript_to_cpp(
94        name = name,
95        srcs = ["baz.rscript"],
96        flags = USER_FLAGS,
97        tags = ["manual"],
98    )
99
100    rscript_to_cpp_commands_test(
101        name = test_name,
102        target_under_test = name,
103    )
104
105    return [test_name]
106
107def _test_rscript_to_cpp_config_impl(ctx):
108    env = analysistest.begin(ctx)
109    actions = analysistest.target_actions(env)
110
111    args = actions[0].argv
112
113    asserts.true(
114        env,
115        ctx.attr._expectedConfigFlag in args,
116        "Expected configuration {} not found"
117            .format(ctx.attr._expectedConfigFlag),
118    )
119
120    return analysistest.end(env)
121
122rscript_to_cpp_config_x86_test = analysistest.make(
123    _test_rscript_to_cpp_config_impl,
124    attrs = {
125        "_expectedConfigFlag": attr.string(default = "-m32"),
126    },
127    config_settings = {
128        "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_x86_for_testing",
129    },
130)
131
132rscript_to_cpp_config_x86_64_test = analysistest.make(
133    _test_rscript_to_cpp_config_impl,
134    attrs = {
135        "_expectedConfigFlag": attr.string(default = "-m64"),
136    },
137    config_settings = {
138        "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_x86_64_for_testing",
139    },
140)
141
142rscript_to_cpp_config_arm_test = analysistest.make(
143    _test_rscript_to_cpp_config_impl,
144    attrs = {
145        "_expectedConfigFlag": attr.string(default = "-m32"),
146    },
147    config_settings = {
148        "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_arm_for_testing",
149    },
150)
151
152rscript_to_cpp_config_arm64_test = analysistest.make(
153    _test_rscript_to_cpp_config_impl,
154    attrs = {
155        "_expectedConfigFlag": attr.string(default = "-m64"),
156    },
157    config_settings = {
158        "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_arm64_for_testing",
159    },
160)
161
162def _test_rscript_to_cpp_config():
163    name = "rscript_to_cpp_config"
164    x86_test_name = name + "_x86_test"
165    x86_64_test_name = name + "_x86_64_test"
166    arm_test_name = name + "_arm_test"
167    arm64_test_name = name + "_arm64_test"
168
169    rscript_to_cpp(
170        name = name,
171        srcs = SRCS,
172        tags = ["manual"],
173    )
174
175    rscript_to_cpp_config_x86_test(
176        name = x86_test_name,
177        target_under_test = name,
178    )
179
180    rscript_to_cpp_config_x86_64_test(
181        name = x86_64_test_name,
182        target_under_test = name,
183    )
184
185    rscript_to_cpp_config_arm_test(
186        name = arm_test_name,
187        target_under_test = name,
188    )
189
190    rscript_to_cpp_config_arm64_test(
191        name = arm64_test_name,
192        target_under_test = name,
193    )
194    return [x86_test_name, x86_64_test_name, arm_test_name, arm64_test_name]
195
196def _test_rscript_to_cpp_inputs_impl(ctx):
197    env = analysistest.begin(ctx)
198    actions = analysistest.target_actions(env)
199    asserts.equals(
200        env,
201        1,
202        len(actions),
203        "expected  1 action got {}".format(actions),
204    )
205
206    in_files = [x.basename for x in actions[0].inputs.to_list()]
207
208    for f in in_files:
209        asserts.true(
210            env,
211            f in SRCS or paths.split_extension(f)[1] in [".rsh", ".h"] or
212            f == "llvm-rs-cc",
213            "Expected inputs to be .rsh/.h header files, llvm-rs-cc," +
214            "or in srcs {} but got {}".format(SRCS, f),
215        )
216
217    return analysistest.end(env)
218
219rscript_to_cpp_inputs_test = analysistest.make(_test_rscript_to_cpp_inputs_impl)
220
221def _test_rscript_to_cpp_inputs():
222    name = "rscript_to_cpp_inputs"
223    test_name = name + "_test"
224
225    rscript_to_cpp(
226        name = name,
227        srcs = SRCS,
228        tags = ["manual"],
229    )
230
231    rscript_to_cpp_inputs_test(
232        name = test_name,
233        target_under_test = name,
234    )
235    return [test_name]
236
237def _test_rscript_to_cpp_outputs_impl(ctx):
238    env = analysistest.begin(ctx)
239    actions = analysistest.target_actions(env)
240    out_files = [x.basename for x in actions[0].outputs.to_list()]
241    expected_outs = []
242    for f in SRCS:
243        expected_outs.append("ScriptC_" + paths.replace_extension(f, ".cpp"))
244        expected_outs.append("ScriptC_" + paths.replace_extension(f, ".h"))
245
246    asserts.set_equals(
247        env,
248        sets.make(expected_outs),
249        sets.make(out_files),
250        "Output: Expected {} but got {}".format(expected_outs, out_files),
251    )
252
253    target_under_test = analysistest.target_under_test(env)
254    info = target_under_test[DefaultInfo]
255    info_output = [x.basename for x in info.files.to_list()]
256    asserts.set_equals(
257        env,
258        sets.make(expected_outs),
259        sets.make(info_output),
260        "expected output filename to be {} but got {}".format(
261            expected_outs,
262            info_output,
263        ),
264    )
265
266    return analysistest.end(env)
267
268rscript_to_cpp_outputs_test = analysistest.make(_test_rscript_to_cpp_outputs_impl)
269
270def _test_rscript_to_cpp_outputs():
271    name = "rscript_to_cpp_outputs"
272    test_name = name + "_test"
273
274    rscript_to_cpp(
275        name = name,
276        srcs = SRCS,
277        tags = ["manual"],
278    )
279
280    rscript_to_cpp_outputs_test(
281        name = test_name,
282        target_under_test = name,
283    )
284    return [test_name]
285
286def rscript_to_cpp_test_suite(name):
287    native.test_suite(
288        name = name,
289        tests =
290            _test_rscript_to_cpp_commands() +
291            _test_rscript_to_cpp_config() +
292            _test_rscript_to_cpp_inputs() +
293            _test_rscript_to_cpp_outputs(),
294    )
295