blob: f4f56a3d0ce797d89858bb828fb6c54498d05bf0 [file] [log] [blame]
# Copyright 2014 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
load("//go/private:common.bzl", "get_go_toolchain", "emit_generate_params_action", "go_filetype")
load("//go/private:library.bzl", "emit_library_actions", "go_importpath", "emit_go_compile_action", "get_gc_goopts", "emit_go_pack_action")
load("//go/private:binary.bzl", "emit_go_link_action", "gc_linkopts")
def _go_test_impl(ctx):
"""go_test_impl implements go testing.
It emits an action to run the test generator, and then compiles the
test into a binary."""
go_toolchain = get_go_toolchain(ctx)
lib_result = emit_library_actions(ctx,
sources = depset(ctx.files.srcs),
deps = ctx.attr.deps,
cgo_object = None,
library = ctx.attr.library,
)
main_go = ctx.new_file(ctx.label.name + "_main_test.go")
main_object = ctx.new_file(ctx.label.name + "_main_test.o")
main_lib = ctx.new_file(ctx.label.name + "_main_test.a")
go_import = go_importpath(ctx)
cmds = [
'UNFILTERED_TEST_FILES=(%s)' %
' '.join(["'%s'" % f.path for f in lib_result.go_sources]),
'FILTERED_TEST_FILES=()',
'while read -r line; do',
' if [ -n "$line" ]; then',
' FILTERED_TEST_FILES+=("$line")',
' fi',
'done < <(\'%s\' -cgo "${UNFILTERED_TEST_FILES[@]}")' %
go_toolchain.filter_tags.path,
' '.join([
"'%s'" % go_toolchain.test_generator.path,
'--package',
go_import,
'--output',
"'%s'" % main_go.path,
'"${FILTERED_TEST_FILES[@]}"',
]),
]
f = emit_generate_params_action(
cmds, ctx, ctx.label.name + ".GoTestGenTest.params")
inputs = (list(lib_result.go_sources) + list(go_toolchain.tools) +
[f, go_toolchain.filter_tags, go_toolchain.test_generator])
ctx.action(
inputs = inputs,
outputs = [main_go],
command = f.path,
mnemonic = "GoTestGenTest",
env = dict(go_toolchain.env, RUNDIR=ctx.label.package))
emit_go_compile_action(
ctx,
sources=depset([main_go]),
libs=lib_result.transitive_go_libraries,
libpaths=lib_result.transitive_go_library_paths,
out_object=main_object,
gc_goopts=get_gc_goopts(ctx),
)
emit_go_pack_action(ctx, main_lib, [main_object])
emit_go_link_action(
ctx,
transitive_go_library_paths=lib_result.transitive_go_library_paths,
transitive_go_libraries=lib_result.transitive_go_libraries,
cgo_deps=lib_result.transitive_cgo_deps,
libs=[main_lib],
executable=ctx.outputs.executable,
gc_linkopts=gc_linkopts(ctx))
# TODO(bazel-team): the Go tests should do a chdir to the directory
# holding the data files, so open-source go tests continue to work
# without code changes.
runfiles = ctx.runfiles(files = [ctx.outputs.executable])
runfiles = runfiles.merge(lib_result.runfiles)
return struct(
files = set([ctx.outputs.executable]),
runfiles = runfiles,
)
go_test = rule(
_go_test_impl,
attrs = {
"data": attr.label_list(allow_files = True, cfg = "data"),
"srcs": attr.label_list(allow_files = go_filetype),
"deps": attr.label_list(
providers = [
"transitive_go_library_paths",
"transitive_go_libraries",
"transitive_cgo_deps",
],
),
"importpath": attr.string(),
"library": attr.label(
providers = [
"direct_deps",
"go_sources",
"asm_sources",
"cgo_object",
"gc_goopts",
],
),
"gc_goopts": attr.string_list(),
"gc_linkopts": attr.string_list(),
"linkstamp": attr.string(),
"x_defs": attr.string_dict(),
#TODO(toolchains): Remove _toolchain attribute when real toolchains arrive
"_go_toolchain": attr.label(default = Label("@io_bazel_rules_go_toolchain//:go_toolchain")),
"_go_prefix": attr.label(default=Label("//:go_prefix", relative_to_caller_repository = True)),
},
executable = True,
fragments = ["cpp"],
test = True,
)