Skip to content

Commit

Permalink
chore: make integration test infrastructure sane (#904)
Browse files Browse the repository at this point in the history
The you-can-do-anything-in-bazel mentality can easily lure one to a state where you are programming a build with a build tool instead of configuring a build.

I just extracted the shell script portion out of a `.bzl` file into a file.

This should also help switching to any build system from Bazel.
  • Loading branch information
chanseokoh authored Jan 21, 2022
1 parent bfb35cd commit 128039b
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 108 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Bazel.
bazel-*
.gradle/

# IDE
.idea
Expand Down
100 changes: 0 additions & 100 deletions rules_bazel/java/integration_test.bzl
Original file line number Diff line number Diff line change
@@ -1,103 +1,3 @@
def _diff_integration_goldens_impl(ctx):
# Extract the Java source files from the generated 3 srcjars from API bazel target,
# and put them in the temporary folder `codegen_tmp`.
# Compare the `codegen_tmp` with the goldens folder e.g `test/integration/goldens/redis`
# and save the differences in output file `diff_output.txt`.

diff_output = ctx.outputs.diff_output
check_diff_script = ctx.outputs.check_diff_script
gapic_library = ctx.attr.gapic_library
resource_name_library = ctx.attr.resource_name_library
test_library = ctx.attr.test_library
srcs = ctx.files.srcs
api_name = ctx.attr.name

script = """
mkdir codegen_tmp
unzip {input} -d codegen_tmp
unzip {input_resource_name} -d codegen_tmp
unzip {input_test} -d codegen_tmp
cd codegen_tmp
# Remove unneeded non-Java files, like MANIFEST
rm -rf $(find ./ -type f ! -name '*.java' -a ! -name '*gapic_metadata.json')
rm -rf $(find ./ -type f -name 'PlaceholderFile.java')
rm -r $(find ./ -type d -empty)
cd ..
diff -r codegen_tmp test/integration/goldens/{api_name} > {diff_output}
# Bash `diff` command will return exit code 1 when there are differences between the two
# folders. So we explicitly `exit 0` after the diff command to avoid build failure.
exit 0
""".format(
diff_output = diff_output.path,
input = gapic_library[JavaInfo].source_jars[0].path,
input_resource_name = resource_name_library[JavaInfo].source_jars[0].path,
input_test = test_library[JavaInfo].source_jars[0].path,
api_name = api_name,
)
ctx.actions.run_shell(
inputs = srcs + [
gapic_library[JavaInfo].source_jars[0],
resource_name_library[JavaInfo].source_jars[0],
test_library[JavaInfo].source_jars[0],
],
outputs = [diff_output],
command = script,
)

# Check the generated diff_output file, if it is empty, that means there is no difference
# between generated source code and goldens files, test should pass. If it is not empty, then
# test will fail by exiting 1.

check_diff_script_content = """
# This will not print diff_output to the console unless `--test_output=all` option
# is enabled, it only emits the comparison results to the test.log.
# We could not copy the diff_output.txt to the test.log ($XML_OUTPUT_FILE) because that
# file is not existing at the moment. It is generated once test is finished.
cat $PWD/test/integration/{api_name}_diff_output.txt
if [ -s $PWD/test/integration/{api_name}_diff_output.txt ]
then
exit 1
fi
""".format(
api_name = api_name,
)

ctx.actions.write(
output = check_diff_script,
content = check_diff_script_content,
)
runfiles = ctx.runfiles(files = [ctx.outputs.diff_output])
return [DefaultInfo(executable = check_diff_script, runfiles = runfiles)]

diff_integration_goldens_test = rule(
attrs = {
"gapic_library": attr.label(),
"resource_name_library": attr.label(),
"test_library": attr.label(),
"srcs": attr.label_list(
allow_files = True,
mandatory = True,
),
},
outputs = {
"diff_output": "%{name}_diff_output.txt",
"check_diff_script": "%{name}_check_diff_script.sh",
},
implementation = _diff_integration_goldens_impl,
test = True,
)

def integration_test(name, target, data):
# Bazel target `java_gapic_library` will generate 3 source jars including the
# the source Java code of the gapic_library, resource_name_library and test_library.
diff_integration_goldens_test(
name = name,
gapic_library = target,
resource_name_library = "%s_resource_name" % target,
test_library = "%s_test" % target,
srcs = data,
)

def _overwrite_golden_impl(ctx):
# Extract the Java source files from the generated 3 srcjars from API bazel target,
# and put them in the temporary folder `codegen_tmp`, zip as `goldens_output_zip`.
Expand Down
3 changes: 3 additions & 0 deletions scripts/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package(default_visibility = ["//test/integration:__pkg__"])

exports_files(["diff_gen_and_golden.sh"])
23 changes: 23 additions & 0 deletions scripts/diff_gen_and_golden.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/sh

set -o errexit

API_NAME=$1
RAW_SRCJAR=$( find . -name '*_java_gapic_srcjar_raw.srcjar' )

mkdir unpacked src
cd unpacked
unzip -q -c "../${RAW_SRCJAR}" temp-codegen.srcjar | jar x
cp -rf src/main/java/* ../src
cp -rf src/test/java/* ../src
[ -d proto ] && cp -rf proto/src/main/java/* ../src
cd ..

# Remove unneeded non-Java files, like MANIFEST
find src -type f ! -name '*.java' -a ! -name '*gapic_metadata.json' -delete
find src -type f -name 'PlaceholderFile.java' -delete
find src -type d -empty -delete

# This will not print diff_output to the console unless `--test_output=all` option
# is enabled, it only emits the comparison results to the test.log.
diff -ru src test/integration/goldens/${API_NAME}
16 changes: 8 additions & 8 deletions test/integration/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@ load(
"java_gapic_assembly_gradle_pkg",
)
load("@rules_gapic//:gapic.bzl", "proto_library_with_info")
load(
"//:rules_bazel/java/integration_test.bzl",
"golden_update",
"integration_test",
)
load("//:rules_bazel/java/integration_test.bzl", "golden_update")
load("@rules_proto//proto:defs.bzl", "proto_library")

package(default_visibility = ["//visibility:public"])
Expand Down Expand Up @@ -49,10 +45,14 @@ API_GAPIC_TARGETS = {
"compute": "@com_google_googleapis_discovery//google/cloud/compute/v1:compute_small_java_gapic",
}

[integration_test(
[sh_test(
name = lib_name,
data = ["//test/integration/goldens/%s:goldens_files" % lib_name],
target = API_GAPIC_TARGETS[lib_name],
srcs = ["//scripts:diff_gen_and_golden.sh"],
args = [lib_name],
data = [
API_GAPIC_TARGETS[lib_name] + "_srcjar_raw.srcjar",
"//test/integration/goldens/%s:goldens_files" % lib_name,
],
) for lib_name in INTEGRATION_TEST_LIBRARIES]

[golden_update(
Expand Down

0 comments on commit 128039b

Please sign in to comment.