xref: /aosp_15_r20/build/bazel/rules/cc/cc_proto_test.bzl (revision 7594170e27e0732bc44b93d1440d87a54b6ffe7c)
1*7594170eSAndroid Build Coastguard Worker"""Copyright (C) 2022 The Android Open Source Project
2*7594170eSAndroid Build Coastguard Worker
3*7594170eSAndroid Build Coastguard WorkerLicensed under the Apache License, Version 2.0 (the "License");
4*7594170eSAndroid Build Coastguard Workeryou may not use this file except in compliance with the License.
5*7594170eSAndroid Build Coastguard WorkerYou may obtain a copy of the License at
6*7594170eSAndroid Build Coastguard Worker
7*7594170eSAndroid Build Coastguard Worker     http://www.apache.org/licenses/LICENSE-2.0
8*7594170eSAndroid Build Coastguard Worker
9*7594170eSAndroid Build Coastguard WorkerUnless required by applicable law or agreed to in writing, software
10*7594170eSAndroid Build Coastguard Workerdistributed under the License is distributed on an "AS IS" BASIS,
11*7594170eSAndroid Build Coastguard WorkerWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*7594170eSAndroid Build Coastguard WorkerSee the License for the specific language governing permissions and
13*7594170eSAndroid Build Coastguard Workerlimitations under the License.
14*7594170eSAndroid Build Coastguard Worker"""
15*7594170eSAndroid Build Coastguard Worker
16*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:paths.bzl", "paths")
17*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:sets.bzl", "sets")
18*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
19*7594170eSAndroid Build Coastguard Workerload(":cc_proto.bzl", "PROTO_GEN_NAME_SUFFIX", "cc_proto_library")
20*7594170eSAndroid Build Coastguard Worker
21*7594170eSAndroid Build Coastguard WorkerPROTO_GEN = "external/protobuf/bin/aprotoc/aprotoc"
22*7594170eSAndroid Build Coastguard WorkerVIRTUAL_IMPORT = "_virtual_imports"
23*7594170eSAndroid Build Coastguard WorkerRUNFILES = "_middlemen/external_Sprotobuf_Sbin_Saprotoc_Saprotoc-runfiles"
24*7594170eSAndroid Build Coastguard Worker
25*7594170eSAndroid Build Coastguard WorkerGEN_SUFFIX = [
26*7594170eSAndroid Build Coastguard Worker    ".pb.h",
27*7594170eSAndroid Build Coastguard Worker    ".pb.cc",
28*7594170eSAndroid Build Coastguard Worker]
29*7594170eSAndroid Build Coastguard Worker
30*7594170eSAndroid Build Coastguard Workerdef _get_search_paths(action):
31*7594170eSAndroid Build Coastguard Worker    cmd = action.argv
32*7594170eSAndroid Build Coastguard Worker    search_paths = sets.make()
33*7594170eSAndroid Build Coastguard Worker    cmd_len = len(cmd)
34*7594170eSAndroid Build Coastguard Worker    for i in range(cmd_len):
35*7594170eSAndroid Build Coastguard Worker        if cmd[i].startswith("-I"):
36*7594170eSAndroid Build Coastguard Worker            sets.insert(search_paths, cmd[i].lstrip("- I"))
37*7594170eSAndroid Build Coastguard Worker
38*7594170eSAndroid Build Coastguard Worker    return search_paths
39*7594170eSAndroid Build Coastguard Worker
40*7594170eSAndroid Build Coastguard Workerdef _proto_code_gen_test_impl(ctx):
41*7594170eSAndroid Build Coastguard Worker    env = analysistest.begin(ctx)
42*7594170eSAndroid Build Coastguard Worker    target_under_test = analysistest.target_under_test(env)
43*7594170eSAndroid Build Coastguard Worker    actions = analysistest.target_actions(env)
44*7594170eSAndroid Build Coastguard Worker    package_root = ctx.label.package
45*7594170eSAndroid Build Coastguard Worker    local_file_output_path = paths.join(
46*7594170eSAndroid Build Coastguard Worker        package_root,
47*7594170eSAndroid Build Coastguard Worker        target_under_test.label.name,
48*7594170eSAndroid Build Coastguard Worker        package_root,
49*7594170eSAndroid Build Coastguard Worker    )
50*7594170eSAndroid Build Coastguard Worker
51*7594170eSAndroid Build Coastguard Worker    input_files = [
52*7594170eSAndroid Build Coastguard Worker        ctx.attr.local_file_path,
53*7594170eSAndroid Build Coastguard Worker        ctx.attr.external_file_path,
54*7594170eSAndroid Build Coastguard Worker        ctx.attr.deps_file_path,
55*7594170eSAndroid Build Coastguard Worker    ]
56*7594170eSAndroid Build Coastguard Worker
57*7594170eSAndroid Build Coastguard Worker    output_files = [
58*7594170eSAndroid Build Coastguard Worker        ctx.attr.local_file_path,
59*7594170eSAndroid Build Coastguard Worker        ctx.attr.external_file_path,
60*7594170eSAndroid Build Coastguard Worker    ]
61*7594170eSAndroid Build Coastguard Worker
62*7594170eSAndroid Build Coastguard Worker    asserts.true(
63*7594170eSAndroid Build Coastguard Worker        env,
64*7594170eSAndroid Build Coastguard Worker        len(actions) == 1,
65*7594170eSAndroid Build Coastguard Worker        "Proto gen action not found: %s" % actions,
66*7594170eSAndroid Build Coastguard Worker    )
67*7594170eSAndroid Build Coastguard Worker
68*7594170eSAndroid Build Coastguard Worker    action = actions[0]
69*7594170eSAndroid Build Coastguard Worker
70*7594170eSAndroid Build Coastguard Worker    asserts.set_equals(
71*7594170eSAndroid Build Coastguard Worker        env,
72*7594170eSAndroid Build Coastguard Worker        expected = sets.make(
73*7594170eSAndroid Build Coastguard Worker            [paths.join(package_root, file) for file in input_files] + [
74*7594170eSAndroid Build Coastguard Worker                PROTO_GEN,
75*7594170eSAndroid Build Coastguard Worker                RUNFILES,
76*7594170eSAndroid Build Coastguard Worker            ],
77*7594170eSAndroid Build Coastguard Worker        ),
78*7594170eSAndroid Build Coastguard Worker        actual = sets.make([
79*7594170eSAndroid Build Coastguard Worker            file.short_path
80*7594170eSAndroid Build Coastguard Worker            for file in action.inputs.to_list()
81*7594170eSAndroid Build Coastguard Worker        ]),
82*7594170eSAndroid Build Coastguard Worker    )
83*7594170eSAndroid Build Coastguard Worker
84*7594170eSAndroid Build Coastguard Worker    asserts.set_equals(
85*7594170eSAndroid Build Coastguard Worker        env,
86*7594170eSAndroid Build Coastguard Worker        expected = sets.make(
87*7594170eSAndroid Build Coastguard Worker            [
88*7594170eSAndroid Build Coastguard Worker                paths.join(
89*7594170eSAndroid Build Coastguard Worker                    local_file_output_path,
90*7594170eSAndroid Build Coastguard Worker                    paths.replace_extension(file, ext),
91*7594170eSAndroid Build Coastguard Worker                )
92*7594170eSAndroid Build Coastguard Worker                for ext in GEN_SUFFIX
93*7594170eSAndroid Build Coastguard Worker                for file in output_files
94*7594170eSAndroid Build Coastguard Worker            ],
95*7594170eSAndroid Build Coastguard Worker        ),
96*7594170eSAndroid Build Coastguard Worker        actual = sets.make([
97*7594170eSAndroid Build Coastguard Worker            file.short_path
98*7594170eSAndroid Build Coastguard Worker            for file in action.outputs.to_list()
99*7594170eSAndroid Build Coastguard Worker        ]),
100*7594170eSAndroid Build Coastguard Worker    )
101*7594170eSAndroid Build Coastguard Worker
102*7594170eSAndroid Build Coastguard Worker    search_paths = _get_search_paths(action)
103*7594170eSAndroid Build Coastguard Worker
104*7594170eSAndroid Build Coastguard Worker    asserts.equals(
105*7594170eSAndroid Build Coastguard Worker        env,
106*7594170eSAndroid Build Coastguard Worker        expected = sets.make(
107*7594170eSAndroid Build Coastguard Worker            ["."] +
108*7594170eSAndroid Build Coastguard Worker            [paths.join(package_root, f) + "=" + paths.join(package_root, f) for f in input_files],
109*7594170eSAndroid Build Coastguard Worker        ),
110*7594170eSAndroid Build Coastguard Worker        actual = search_paths,
111*7594170eSAndroid Build Coastguard Worker    )
112*7594170eSAndroid Build Coastguard Worker
113*7594170eSAndroid Build Coastguard Worker    return analysistest.end(env)
114*7594170eSAndroid Build Coastguard Worker
115*7594170eSAndroid Build Coastguard Workerproto_code_gen_test = analysistest.make(
116*7594170eSAndroid Build Coastguard Worker    _proto_code_gen_test_impl,
117*7594170eSAndroid Build Coastguard Worker    attrs = {
118*7594170eSAndroid Build Coastguard Worker        "local_file_path": attr.string(),
119*7594170eSAndroid Build Coastguard Worker        "deps_file_path": attr.string(),
120*7594170eSAndroid Build Coastguard Worker        "external_file_path": attr.string(),
121*7594170eSAndroid Build Coastguard Worker    },
122*7594170eSAndroid Build Coastguard Worker)
123*7594170eSAndroid Build Coastguard Worker
124*7594170eSAndroid Build Coastguard Workerdef _test_proto_code_gen():
125*7594170eSAndroid Build Coastguard Worker    test_name = "proto_code_gen_test"
126*7594170eSAndroid Build Coastguard Worker    local_file_path = "local/proto_local.proto"
127*7594170eSAndroid Build Coastguard Worker    external_file_path = "external/proto_external.proto"
128*7594170eSAndroid Build Coastguard Worker    deps_file_path = "deps/proto_deps.proto"
129*7594170eSAndroid Build Coastguard Worker    external_proto_name = test_name + "_external_proto"
130*7594170eSAndroid Build Coastguard Worker    deps_proto_name = test_name + "_deps_proto"
131*7594170eSAndroid Build Coastguard Worker    local_proto_name = test_name + "_proto"
132*7594170eSAndroid Build Coastguard Worker    cc_name = test_name + "_cc_proto"
133*7594170eSAndroid Build Coastguard Worker
134*7594170eSAndroid Build Coastguard Worker    native.proto_library(
135*7594170eSAndroid Build Coastguard Worker        name = external_proto_name,
136*7594170eSAndroid Build Coastguard Worker        srcs = [external_file_path],
137*7594170eSAndroid Build Coastguard Worker        tags = ["manual"],
138*7594170eSAndroid Build Coastguard Worker    )
139*7594170eSAndroid Build Coastguard Worker
140*7594170eSAndroid Build Coastguard Worker    native.proto_library(
141*7594170eSAndroid Build Coastguard Worker        name = deps_proto_name,
142*7594170eSAndroid Build Coastguard Worker        srcs = [deps_file_path],
143*7594170eSAndroid Build Coastguard Worker        tags = ["manual"],
144*7594170eSAndroid Build Coastguard Worker    )
145*7594170eSAndroid Build Coastguard Worker
146*7594170eSAndroid Build Coastguard Worker    native.proto_library(
147*7594170eSAndroid Build Coastguard Worker        name = local_proto_name,
148*7594170eSAndroid Build Coastguard Worker        srcs = [local_file_path],
149*7594170eSAndroid Build Coastguard Worker        deps = [":" + deps_proto_name],
150*7594170eSAndroid Build Coastguard Worker        tags = ["manual"],
151*7594170eSAndroid Build Coastguard Worker    )
152*7594170eSAndroid Build Coastguard Worker
153*7594170eSAndroid Build Coastguard Worker    cc_proto_library(
154*7594170eSAndroid Build Coastguard Worker        name = cc_name,
155*7594170eSAndroid Build Coastguard Worker        deps = [
156*7594170eSAndroid Build Coastguard Worker            ":" + local_proto_name,
157*7594170eSAndroid Build Coastguard Worker            ":" + external_proto_name,
158*7594170eSAndroid Build Coastguard Worker        ],
159*7594170eSAndroid Build Coastguard Worker        tags = ["manual"],
160*7594170eSAndroid Build Coastguard Worker    )
161*7594170eSAndroid Build Coastguard Worker
162*7594170eSAndroid Build Coastguard Worker    proto_code_gen_test(
163*7594170eSAndroid Build Coastguard Worker        name = test_name,
164*7594170eSAndroid Build Coastguard Worker        target_under_test = cc_name + PROTO_GEN_NAME_SUFFIX,
165*7594170eSAndroid Build Coastguard Worker        local_file_path = local_file_path,
166*7594170eSAndroid Build Coastguard Worker        deps_file_path = deps_file_path,
167*7594170eSAndroid Build Coastguard Worker        external_file_path = external_file_path,
168*7594170eSAndroid Build Coastguard Worker    )
169*7594170eSAndroid Build Coastguard Worker
170*7594170eSAndroid Build Coastguard Worker    return test_name
171*7594170eSAndroid Build Coastguard Worker
172*7594170eSAndroid Build Coastguard Workerdef _proto_strip_import_prefix_test_impl(ctx):
173*7594170eSAndroid Build Coastguard Worker    env = analysistest.begin(ctx)
174*7594170eSAndroid Build Coastguard Worker    actions = analysistest.target_actions(env)
175*7594170eSAndroid Build Coastguard Worker    package_root = ctx.label.package
176*7594170eSAndroid Build Coastguard Worker
177*7594170eSAndroid Build Coastguard Worker    # strip the proto file path, src/stripped/stripped.proto -> stripped/stripped.proto
178*7594170eSAndroid Build Coastguard Worker    stripped_file_name = paths.relativize(ctx.attr.stripped_file_name, ctx.attr.strip_import_prefix)
179*7594170eSAndroid Build Coastguard Worker    stripped_file_input_path = paths.join(
180*7594170eSAndroid Build Coastguard Worker        package_root,
181*7594170eSAndroid Build Coastguard Worker        VIRTUAL_IMPORT,
182*7594170eSAndroid Build Coastguard Worker        ctx.attr.stripped_proto_name,
183*7594170eSAndroid Build Coastguard Worker    )
184*7594170eSAndroid Build Coastguard Worker    stripped_file_input_full_path = paths.join(
185*7594170eSAndroid Build Coastguard Worker        stripped_file_input_path,
186*7594170eSAndroid Build Coastguard Worker        stripped_file_name,
187*7594170eSAndroid Build Coastguard Worker    )
188*7594170eSAndroid Build Coastguard Worker
189*7594170eSAndroid Build Coastguard Worker    asserts.true(
190*7594170eSAndroid Build Coastguard Worker        env,
191*7594170eSAndroid Build Coastguard Worker        len(actions) == 1,
192*7594170eSAndroid Build Coastguard Worker        "Proto gen action not found: %s" % actions,
193*7594170eSAndroid Build Coastguard Worker    )
194*7594170eSAndroid Build Coastguard Worker
195*7594170eSAndroid Build Coastguard Worker    action = actions[0]
196*7594170eSAndroid Build Coastguard Worker
197*7594170eSAndroid Build Coastguard Worker    asserts.set_equals(
198*7594170eSAndroid Build Coastguard Worker        env,
199*7594170eSAndroid Build Coastguard Worker        expected = sets.make(
200*7594170eSAndroid Build Coastguard Worker            [
201*7594170eSAndroid Build Coastguard Worker                paths.join(package_root, ctx.attr.unstripped_file_name),
202*7594170eSAndroid Build Coastguard Worker                stripped_file_input_full_path,
203*7594170eSAndroid Build Coastguard Worker                PROTO_GEN,
204*7594170eSAndroid Build Coastguard Worker                RUNFILES,
205*7594170eSAndroid Build Coastguard Worker            ],
206*7594170eSAndroid Build Coastguard Worker        ),
207*7594170eSAndroid Build Coastguard Worker        actual = sets.make([
208*7594170eSAndroid Build Coastguard Worker            file.short_path
209*7594170eSAndroid Build Coastguard Worker            for file in action.inputs.to_list()
210*7594170eSAndroid Build Coastguard Worker        ]),
211*7594170eSAndroid Build Coastguard Worker    )
212*7594170eSAndroid Build Coastguard Worker
213*7594170eSAndroid Build Coastguard Worker    asserts.set_equals(
214*7594170eSAndroid Build Coastguard Worker        env,
215*7594170eSAndroid Build Coastguard Worker        expected = sets.make(ctx.attr.expected_outputs),
216*7594170eSAndroid Build Coastguard Worker        actual = sets.make([
217*7594170eSAndroid Build Coastguard Worker            file.short_path
218*7594170eSAndroid Build Coastguard Worker            for file in action.outputs.to_list()
219*7594170eSAndroid Build Coastguard Worker        ]),
220*7594170eSAndroid Build Coastguard Worker    )
221*7594170eSAndroid Build Coastguard Worker
222*7594170eSAndroid Build Coastguard Worker    search_paths = _get_search_paths(action)
223*7594170eSAndroid Build Coastguard Worker
224*7594170eSAndroid Build Coastguard Worker    asserts.equals(
225*7594170eSAndroid Build Coastguard Worker        env,
226*7594170eSAndroid Build Coastguard Worker        expected = sets.make([
227*7594170eSAndroid Build Coastguard Worker            ".",
228*7594170eSAndroid Build Coastguard Worker            paths.join(package_root, ctx.attr.unstripped_file_name) + "=" + paths.join(package_root, ctx.attr.unstripped_file_name),
229*7594170eSAndroid Build Coastguard Worker            stripped_file_input_full_path + "=" +
230*7594170eSAndroid Build Coastguard Worker            paths.join(
231*7594170eSAndroid Build Coastguard Worker                ctx.genfiles_dir.path,
232*7594170eSAndroid Build Coastguard Worker                stripped_file_input_full_path,
233*7594170eSAndroid Build Coastguard Worker            ),
234*7594170eSAndroid Build Coastguard Worker            paths.join(
235*7594170eSAndroid Build Coastguard Worker                ctx.genfiles_dir.path,
236*7594170eSAndroid Build Coastguard Worker                stripped_file_input_path,
237*7594170eSAndroid Build Coastguard Worker            ),
238*7594170eSAndroid Build Coastguard Worker        ]),
239*7594170eSAndroid Build Coastguard Worker        actual = search_paths,
240*7594170eSAndroid Build Coastguard Worker    )
241*7594170eSAndroid Build Coastguard Worker
242*7594170eSAndroid Build Coastguard Worker    return analysistest.end(env)
243*7594170eSAndroid Build Coastguard Worker
244*7594170eSAndroid Build Coastguard Workerproto_strip_import_prefix_test = analysistest.make(
245*7594170eSAndroid Build Coastguard Worker    _proto_strip_import_prefix_test_impl,
246*7594170eSAndroid Build Coastguard Worker    attrs = {
247*7594170eSAndroid Build Coastguard Worker        "stripped_proto_name": attr.string(),
248*7594170eSAndroid Build Coastguard Worker        "stripped_file_name": attr.string(),
249*7594170eSAndroid Build Coastguard Worker        "unstripped_file_name": attr.string(),
250*7594170eSAndroid Build Coastguard Worker        "strip_import_prefix": attr.string(),
251*7594170eSAndroid Build Coastguard Worker        "expected_outputs": attr.string_list(),
252*7594170eSAndroid Build Coastguard Worker    },
253*7594170eSAndroid Build Coastguard Worker)
254*7594170eSAndroid Build Coastguard Worker
255*7594170eSAndroid Build Coastguard Workerdef _test_proto_strip_import_prefix():
256*7594170eSAndroid Build Coastguard Worker    test_name = "proto_strip_import_prefix_test"
257*7594170eSAndroid Build Coastguard Worker    unstripped_proto_name = test_name + "_unstripped_proto"
258*7594170eSAndroid Build Coastguard Worker    stripped_proto_name = test_name + "_stripped_proto"
259*7594170eSAndroid Build Coastguard Worker    unstripped_file_name = "unstripped/unstripped.proto"
260*7594170eSAndroid Build Coastguard Worker    stripped_file_name = "src/stripped/stripped.proto"
261*7594170eSAndroid Build Coastguard Worker    cc_name = test_name + "_cc_proto"
262*7594170eSAndroid Build Coastguard Worker    strip_import_prefix = "src"
263*7594170eSAndroid Build Coastguard Worker
264*7594170eSAndroid Build Coastguard Worker    native.proto_library(
265*7594170eSAndroid Build Coastguard Worker        name = unstripped_proto_name,
266*7594170eSAndroid Build Coastguard Worker        srcs = [unstripped_file_name],
267*7594170eSAndroid Build Coastguard Worker        tags = ["manual"],
268*7594170eSAndroid Build Coastguard Worker    )
269*7594170eSAndroid Build Coastguard Worker
270*7594170eSAndroid Build Coastguard Worker    native.proto_library(
271*7594170eSAndroid Build Coastguard Worker        name = stripped_proto_name,
272*7594170eSAndroid Build Coastguard Worker        srcs = [stripped_file_name],
273*7594170eSAndroid Build Coastguard Worker        strip_import_prefix = strip_import_prefix,
274*7594170eSAndroid Build Coastguard Worker        tags = ["manual"],
275*7594170eSAndroid Build Coastguard Worker    )
276*7594170eSAndroid Build Coastguard Worker
277*7594170eSAndroid Build Coastguard Worker    cc_proto_library(
278*7594170eSAndroid Build Coastguard Worker        name = cc_name,
279*7594170eSAndroid Build Coastguard Worker        deps = [
280*7594170eSAndroid Build Coastguard Worker            ":" + stripped_proto_name,
281*7594170eSAndroid Build Coastguard Worker            ":" + unstripped_proto_name,
282*7594170eSAndroid Build Coastguard Worker        ],
283*7594170eSAndroid Build Coastguard Worker        tags = ["manual"],
284*7594170eSAndroid Build Coastguard Worker    )
285*7594170eSAndroid Build Coastguard Worker
286*7594170eSAndroid Build Coastguard Worker    expected_outputs = [
287*7594170eSAndroid Build Coastguard Worker        # unstripped, the default behavior
288*7594170eSAndroid Build Coastguard Worker        # bazel package is added to the path
289*7594170eSAndroid Build Coastguard Worker        "build/bazel/rules/cc/proto_strip_import_prefix_test_cc_proto_proto_gen/build/bazel/rules/cc/unstripped/unstripped.pb.cc",
290*7594170eSAndroid Build Coastguard Worker        "build/bazel/rules/cc/proto_strip_import_prefix_test_cc_proto_proto_gen/build/bazel/rules/cc/unstripped/unstripped.pb.h",
291*7594170eSAndroid Build Coastguard Worker        # stripped - src/stripped/stripped.proto --> stripped/stripped.pb.cc
292*7594170eSAndroid Build Coastguard Worker        # since strip_import_prefix is not nil, the bazel package is not added to the path
293*7594170eSAndroid Build Coastguard Worker        "build/bazel/rules/cc/proto_strip_import_prefix_test_cc_proto_proto_gen/stripped/stripped.pb.cc",
294*7594170eSAndroid Build Coastguard Worker        "build/bazel/rules/cc/proto_strip_import_prefix_test_cc_proto_proto_gen/stripped/stripped.pb.h",
295*7594170eSAndroid Build Coastguard Worker    ]
296*7594170eSAndroid Build Coastguard Worker
297*7594170eSAndroid Build Coastguard Worker    proto_strip_import_prefix_test(
298*7594170eSAndroid Build Coastguard Worker        name = test_name,
299*7594170eSAndroid Build Coastguard Worker        target_under_test = cc_name + PROTO_GEN_NAME_SUFFIX,
300*7594170eSAndroid Build Coastguard Worker        stripped_proto_name = stripped_proto_name,
301*7594170eSAndroid Build Coastguard Worker        stripped_file_name = stripped_file_name,
302*7594170eSAndroid Build Coastguard Worker        unstripped_file_name = unstripped_file_name,
303*7594170eSAndroid Build Coastguard Worker        strip_import_prefix = strip_import_prefix,
304*7594170eSAndroid Build Coastguard Worker        expected_outputs = expected_outputs,
305*7594170eSAndroid Build Coastguard Worker    )
306*7594170eSAndroid Build Coastguard Worker
307*7594170eSAndroid Build Coastguard Worker    return test_name
308*7594170eSAndroid Build Coastguard Worker
309*7594170eSAndroid Build Coastguard Workerdef _proto_with_external_packages_test_impl(ctx):
310*7594170eSAndroid Build Coastguard Worker    env = analysistest.begin(ctx)
311*7594170eSAndroid Build Coastguard Worker    target_under_test = analysistest.target_under_test(env)
312*7594170eSAndroid Build Coastguard Worker    actions = analysistest.target_actions(env)
313*7594170eSAndroid Build Coastguard Worker    package_root = ctx.label.package
314*7594170eSAndroid Build Coastguard Worker    deps_file_path = ctx.attr.deps_file_path
315*7594170eSAndroid Build Coastguard Worker    external_file_path = ctx.attr.external_file_path
316*7594170eSAndroid Build Coastguard Worker    local_file_path = ctx.attr.local_file_path
317*7594170eSAndroid Build Coastguard Worker
318*7594170eSAndroid Build Coastguard Worker    asserts.true(
319*7594170eSAndroid Build Coastguard Worker        env,
320*7594170eSAndroid Build Coastguard Worker        len(actions) == 1,
321*7594170eSAndroid Build Coastguard Worker        "Proto gen action not found: %s" % actions,
322*7594170eSAndroid Build Coastguard Worker    )
323*7594170eSAndroid Build Coastguard Worker
324*7594170eSAndroid Build Coastguard Worker    action = actions[0]
325*7594170eSAndroid Build Coastguard Worker
326*7594170eSAndroid Build Coastguard Worker    asserts.set_equals(
327*7594170eSAndroid Build Coastguard Worker        env,
328*7594170eSAndroid Build Coastguard Worker        expected = sets.make(
329*7594170eSAndroid Build Coastguard Worker            [
330*7594170eSAndroid Build Coastguard Worker                paths.join(package_root, local_file_path),
331*7594170eSAndroid Build Coastguard Worker                deps_file_path,
332*7594170eSAndroid Build Coastguard Worker                external_file_path,
333*7594170eSAndroid Build Coastguard Worker                PROTO_GEN,
334*7594170eSAndroid Build Coastguard Worker                RUNFILES,
335*7594170eSAndroid Build Coastguard Worker            ],
336*7594170eSAndroid Build Coastguard Worker        ),
337*7594170eSAndroid Build Coastguard Worker        actual = sets.make([
338*7594170eSAndroid Build Coastguard Worker            file.short_path
339*7594170eSAndroid Build Coastguard Worker            for file in action.inputs.to_list()
340*7594170eSAndroid Build Coastguard Worker        ]),
341*7594170eSAndroid Build Coastguard Worker    )
342*7594170eSAndroid Build Coastguard Worker
343*7594170eSAndroid Build Coastguard Worker    asserts.set_equals(
344*7594170eSAndroid Build Coastguard Worker        env,
345*7594170eSAndroid Build Coastguard Worker        expected = sets.make(
346*7594170eSAndroid Build Coastguard Worker            [
347*7594170eSAndroid Build Coastguard Worker                paths.join(
348*7594170eSAndroid Build Coastguard Worker                    package_root,
349*7594170eSAndroid Build Coastguard Worker                    target_under_test.label.name,
350*7594170eSAndroid Build Coastguard Worker                    package_root,
351*7594170eSAndroid Build Coastguard Worker                    paths.replace_extension(local_file_path, ext),
352*7594170eSAndroid Build Coastguard Worker                )
353*7594170eSAndroid Build Coastguard Worker                for ext in GEN_SUFFIX
354*7594170eSAndroid Build Coastguard Worker            ] +
355*7594170eSAndroid Build Coastguard Worker            [
356*7594170eSAndroid Build Coastguard Worker                paths.join(
357*7594170eSAndroid Build Coastguard Worker                    package_root,
358*7594170eSAndroid Build Coastguard Worker                    target_under_test.label.name,
359*7594170eSAndroid Build Coastguard Worker                    paths.replace_extension(external_file_path, ext),
360*7594170eSAndroid Build Coastguard Worker                )
361*7594170eSAndroid Build Coastguard Worker                for ext in GEN_SUFFIX
362*7594170eSAndroid Build Coastguard Worker            ],
363*7594170eSAndroid Build Coastguard Worker        ),
364*7594170eSAndroid Build Coastguard Worker        actual = sets.make([
365*7594170eSAndroid Build Coastguard Worker            file.short_path
366*7594170eSAndroid Build Coastguard Worker            for file in action.outputs.to_list()
367*7594170eSAndroid Build Coastguard Worker        ]),
368*7594170eSAndroid Build Coastguard Worker    )
369*7594170eSAndroid Build Coastguard Worker
370*7594170eSAndroid Build Coastguard Worker    search_paths = _get_search_paths(action)
371*7594170eSAndroid Build Coastguard Worker
372*7594170eSAndroid Build Coastguard Worker    asserts.equals(
373*7594170eSAndroid Build Coastguard Worker        env,
374*7594170eSAndroid Build Coastguard Worker        expected = sets.make([
375*7594170eSAndroid Build Coastguard Worker            ".",
376*7594170eSAndroid Build Coastguard Worker            paths.join(package_root, local_file_path) + "=" + paths.join(package_root, local_file_path),
377*7594170eSAndroid Build Coastguard Worker            deps_file_path + "=" + deps_file_path,
378*7594170eSAndroid Build Coastguard Worker            external_file_path + "=" + external_file_path,
379*7594170eSAndroid Build Coastguard Worker        ]),
380*7594170eSAndroid Build Coastguard Worker        actual = search_paths,
381*7594170eSAndroid Build Coastguard Worker    )
382*7594170eSAndroid Build Coastguard Worker
383*7594170eSAndroid Build Coastguard Worker    return analysistest.end(env)
384*7594170eSAndroid Build Coastguard Worker
385*7594170eSAndroid Build Coastguard Workerproto_with_external_packages_test = analysistest.make(
386*7594170eSAndroid Build Coastguard Worker    _proto_with_external_packages_test_impl,
387*7594170eSAndroid Build Coastguard Worker    attrs = {
388*7594170eSAndroid Build Coastguard Worker        "local_file_path": attr.string(),
389*7594170eSAndroid Build Coastguard Worker        "deps_file_path": attr.string(),
390*7594170eSAndroid Build Coastguard Worker        "external_file_path": attr.string(),
391*7594170eSAndroid Build Coastguard Worker    },
392*7594170eSAndroid Build Coastguard Worker)
393*7594170eSAndroid Build Coastguard Worker
394*7594170eSAndroid Build Coastguard Workerdef _test_proto_with_external_packages():
395*7594170eSAndroid Build Coastguard Worker    test_name = "proto_with_external_packages_test"
396*7594170eSAndroid Build Coastguard Worker    proto_name = test_name + "_proto"
397*7594170eSAndroid Build Coastguard Worker    cc_name = test_name + "_cc_proto"
398*7594170eSAndroid Build Coastguard Worker    local_file_path = "local/proto_local.proto"
399*7594170eSAndroid Build Coastguard Worker    deps_file_path = "build/bazel/examples/cc/proto/deps/src/enums/proto_deps.proto"
400*7594170eSAndroid Build Coastguard Worker    external_file_path = "build/bazel/examples/cc/proto/external/src/enums/proto_external.proto"
401*7594170eSAndroid Build Coastguard Worker
402*7594170eSAndroid Build Coastguard Worker    native.proto_library(
403*7594170eSAndroid Build Coastguard Worker        name = proto_name,
404*7594170eSAndroid Build Coastguard Worker        srcs = [local_file_path],
405*7594170eSAndroid Build Coastguard Worker        deps = ["//build/bazel/examples/cc/proto/deps:deps_proto"],
406*7594170eSAndroid Build Coastguard Worker        tags = ["manual"],
407*7594170eSAndroid Build Coastguard Worker    )
408*7594170eSAndroid Build Coastguard Worker
409*7594170eSAndroid Build Coastguard Worker    cc_proto_library(
410*7594170eSAndroid Build Coastguard Worker        name = cc_name,
411*7594170eSAndroid Build Coastguard Worker        deps = [
412*7594170eSAndroid Build Coastguard Worker            ":" + proto_name,
413*7594170eSAndroid Build Coastguard Worker            "//build/bazel/examples/cc/proto/external:external_proto",
414*7594170eSAndroid Build Coastguard Worker        ],
415*7594170eSAndroid Build Coastguard Worker        tags = ["manual"],
416*7594170eSAndroid Build Coastguard Worker    )
417*7594170eSAndroid Build Coastguard Worker
418*7594170eSAndroid Build Coastguard Worker    proto_with_external_packages_test(
419*7594170eSAndroid Build Coastguard Worker        name = test_name,
420*7594170eSAndroid Build Coastguard Worker        target_under_test = cc_name + PROTO_GEN_NAME_SUFFIX,
421*7594170eSAndroid Build Coastguard Worker        local_file_path = local_file_path,
422*7594170eSAndroid Build Coastguard Worker        deps_file_path = deps_file_path,
423*7594170eSAndroid Build Coastguard Worker        external_file_path = external_file_path,
424*7594170eSAndroid Build Coastguard Worker    )
425*7594170eSAndroid Build Coastguard Worker
426*7594170eSAndroid Build Coastguard Worker    return test_name
427*7594170eSAndroid Build Coastguard Worker
428*7594170eSAndroid Build Coastguard Workerdef cc_proto_test_suite(name):
429*7594170eSAndroid Build Coastguard Worker    native.test_suite(
430*7594170eSAndroid Build Coastguard Worker        name = name,
431*7594170eSAndroid Build Coastguard Worker        tests = [
432*7594170eSAndroid Build Coastguard Worker            _test_proto_code_gen(),
433*7594170eSAndroid Build Coastguard Worker            _test_proto_strip_import_prefix(),
434*7594170eSAndroid Build Coastguard Worker            _test_proto_with_external_packages(),
435*7594170eSAndroid Build Coastguard Worker        ],
436*7594170eSAndroid Build Coastguard Worker    )
437