Skip to content

Commit 548b176

Browse files
committed
Add test_dependency_versions, update test_runner
Adds `test_dependency_versions.sh` to validate the minimum Bazel and dependency versions required by `rules_scala`, with and without the precompiled protocol compiler toolchain. Extracts setup, run, and teardown helpers from `test/shell/test_bzlmod_helpers.sh` into `test_runner.sh` for reuse by `test_dependency_versions.sh`. Also: - Adds test files supporting `test_dependency_versions.sh` in `deps/test`. - Adds a mechanism to skip tests by prefixing their name with `_` to `run_test_local` and `run_test_ci`. - Adds the `RULES_SCALA_TEST_REGEX` environment variable to `test_runner.sh`. - Adds documentation for `RULES_SCALA_TEST_{ONLY,REGEX,VERBOSE}` to the header comment of `test_runner.sh`. - Adds `./test_dependency_versions` jobs to `.bazelci/presubmit.yml`. --- Continuation of the previous change to ensure we don't force users to upgrade their dependencies beyond the minimum versions supported by `rules_scala`. Only builds using Bzlmod, as `WORKSPACE` is considered legacy. Inspired by a thread in the #bzlmod channel of the Bazel Slack workspace on 2025-01-01 indicating that rules should require the minumum versions possible: - https://bazelbuild.slack.com/archives/C014RARENH0/p1743597941149639
1 parent 96afa0e commit 548b176

12 files changed

+640
-36
lines changed

.bazelci/presubmit.yml

+15
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,18 @@ tasks:
117117
- echo "build --tool_java_language_version=21" >> .bazelrc
118118
- echo "build --tool_java_runtime_version=21" >> .bazelrc
119119
- "./test_rules_scala.sh"
120+
dependency_versions_linux:
121+
name: "./test_dependency_versions"
122+
platform: ubuntu2004
123+
shell_commands:
124+
- "./test_dependency_versions.sh"
125+
dependency_versions_macos:
126+
name: "./test_dependency_versions"
127+
platform: macos
128+
shell_commands:
129+
- "./test_dependency_versions.sh"
130+
dependency_versions_windows:
131+
name: "./test_dependency_versions"
132+
platform: windows
133+
shell_commands:
134+
- "./test_dependency_versions.sh"

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,8 @@ by default](#protoc-msvc) section below for details.
349349
#### Minimum dependency versions
350350

351351
These are the minimum dependency versions required to enable the precompiled
352-
protocol compiler toolchain.
352+
protocol compiler toolchain. These are validated by
353+
[`test_dependency_versions.sh`](./test/shell/test_dependency_versions.sh).
353354

354355
Note that `rules_java` can be as low as 8.3.0, compared to `rules_java` 8.5.0
355356
specified in [Compatible Bazel versions](#compatible-bazel-versions).

deps/test/BUILD.bazel.test

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
"""Test targets to ensure dependency version compatibility.
2+
3+
Copied and adapted targets from the main repo as noted.
4+
"""
5+
load(
6+
":defs.bzl",
7+
"default_outputs_test",
8+
"scalafmt_scala_test",
9+
"scrooge_transitive_outputs_test",
10+
)
11+
load("@rules_proto//proto:defs.bzl", "proto_library")
12+
load("@rules_scala//jmh:jmh.bzl", "scala_benchmark_jmh")
13+
load("@rules_scala//scala/scalafmt:phase_scalafmt_ext.bzl", "ext_scalafmt")
14+
load("@rules_scala//scala:advanced_usage/scala.bzl", "make_scala_test")
15+
load(
16+
"@rules_scala//scala:scala.bzl",
17+
"scala_binary",
18+
"scala_doc",
19+
"scala_junit_test",
20+
"scala_library",
21+
"scala_specs2_junit_test",
22+
"scala_test",
23+
)
24+
load("@rules_scala//scala_proto:scala_proto.bzl", "scala_proto_library")
25+
load("@rules_scala//thrift:thrift.bzl", "thrift_library")
26+
load(
27+
"@rules_scala//twitter_scrooge:twitter_scrooge.bzl",
28+
"scrooge_java_library",
29+
"scrooge_scala_library",
30+
)
31+
32+
# From: `test/BUILD`
33+
scala_binary(
34+
name = "ScalaBinary",
35+
srcs = ["ScalaBinary.scala"],
36+
main_class = "scalarules.test.ScalaBinary",
37+
deps = [
38+
":HelloLib",
39+
],
40+
)
41+
42+
scala_library(
43+
name = "HelloLib",
44+
srcs = ["HelloLib.scala"],
45+
)
46+
47+
scala_doc(
48+
name = "ScalaDoc",
49+
deps = [":HelloLib"],
50+
)
51+
52+
# From: `examples/testing/multi_frameworks_toolchain/example/BUILD`
53+
scala_test(
54+
name = "scalatest_example",
55+
srcs = ["ScalaTestExampleTest.scala"],
56+
)
57+
58+
scala_specs2_junit_test(
59+
name = "specs2_example",
60+
srcs = ["Specs2ExampleTest.scala"],
61+
suffixes = ["Test"],
62+
)
63+
64+
# Manufactured based on `docs/phase_scalafmt.md` and `test/scalafmt/BUILD`.
65+
scalafmt_scala_test(
66+
name = "ScalafmtTest",
67+
srcs = ["ScalaTestExampleTest.scala"],
68+
format = True,
69+
)
70+
71+
# From: `test/proto/BUILD`
72+
proto_library(
73+
name = "standalone_proto",
74+
srcs = ["standalone.proto"],
75+
)
76+
77+
scala_proto_library(
78+
name = "standalone_scala_proto",
79+
deps = [":standalone_proto"],
80+
)
81+
82+
default_outputs_test(
83+
name = "standalone_scala_proto_outs_test",
84+
expected_outs = [
85+
"standalone_proto_scalapb-src.jar",
86+
"standalone_proto_scalapb.jar",
87+
],
88+
target_under_test = ":standalone_scala_proto",
89+
)
90+
91+
# From: `test/jmh/BUILD`
92+
scala_benchmark_jmh(
93+
name = "test_benchmark",
94+
srcs = ["TestBenchmark.scala"],
95+
data = ["data.txt"],
96+
deps = ["@rules_scala//test/jmh:add_numbers"],
97+
)
98+
99+
# From: `test/src/main/scala/scalarules/test/twitter_scrooge/BUILD`
100+
101+
thrift_library(
102+
name = "thrift3",
103+
srcs = ["Thrift3.thrift"],
104+
visibility = ["//visibility:public"],
105+
)
106+
107+
scrooge_scala_library(
108+
name = "scrooge3",
109+
visibility = ["//visibility:public"],
110+
deps = [":thrift3"],
111+
)
112+
113+
scrooge_java_library(
114+
name = "scrooge3_java",
115+
visibility = ["//visibility:public"],
116+
deps = [":thrift3"],
117+
)
118+
119+
scrooge_transitive_outputs_test(
120+
name = "scrooge_test_scala",
121+
dep = ":scrooge3",
122+
expected_jars = ["thrift3_scrooge_scala.jar"],
123+
)
124+
125+
scrooge_transitive_outputs_test(
126+
name = "scrooge_test_java",
127+
dep = ":scrooge3_java",
128+
expected_jars = ["thrift3_scrooge_java.jar"],
129+
)

deps/test/HelloLib.scala

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2016 The Bazel Authors. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package scalarules.test
16+
17+
object HelloLib {
18+
def printMessage(arg: String) {
19+
println(arg)
20+
}
21+
}
22+

deps/test/MODULE.bazel.template

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
"""Bazel module template for test/shell/test_deps_versions.sh tests."""
2+
3+
module(
4+
name = "rules_scala_deps_versions_test",
5+
bazel_compatibility = [">=${bazelversion}"],
6+
)
7+
8+
bazel_dep(name = "rules_scala")
9+
local_path_override(
10+
module_name = "rules_scala",
11+
path = "../..",
12+
)
13+
14+
bazel_dep(name = "bazel_skylib")
15+
single_version_override(
16+
module_name = "bazel_skylib",
17+
version = "${skylib_version}",
18+
)
19+
20+
bazel_dep(name = "platforms")
21+
single_version_override(
22+
module_name = "platforms",
23+
version = "${platforms_version}",
24+
)
25+
26+
bazel_dep(name = "rules_java")
27+
single_version_override(
28+
module_name = "rules_java",
29+
version = "${rules_java_version}",
30+
)
31+
32+
bazel_dep(name = "rules_proto")
33+
single_version_override(
34+
module_name = "rules_proto",
35+
version = "${rules_proto_version}",
36+
)
37+
38+
# Requires the patch for `protoc` toolchainization until resolution of
39+
# protocolbuffers/protobuf#19679.
40+
bazel_dep(name = "protobuf")
41+
single_version_override(
42+
module_name = "protobuf",
43+
patch_strip = 1,
44+
patches = ["//:protobuf.patch"],
45+
version = "${protobuf_version}",
46+
)
47+
48+
scala_protoc = use_extension(
49+
"@rules_scala//scala/extensions:protoc.bzl",
50+
"scala_protoc",
51+
dev_dependency = True,
52+
)
53+
use_repo(scala_protoc, "rules_scala_protoc_toolchains")
54+
55+
register_toolchains(
56+
"@rules_scala_protoc_toolchains//...:all",
57+
dev_dependency = True,
58+
)
59+
60+
scala_deps = use_extension(
61+
"@rules_scala//scala/extensions:deps.bzl",
62+
"scala_deps",
63+
)
64+
scala_deps.scala()
65+
scala_deps.jmh()
66+
scala_deps.junit()
67+
scala_deps.scala_proto()
68+
scala_deps.scalafmt()
69+
scala_deps.scalatest()
70+
scala_deps.specs2()
71+
scala_deps.twitter_scrooge()

deps/test/ScalaBinary.scala

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2016 The Bazel Authors. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package scalarules.test
16+
17+
object ScalaBinary {
18+
def main(args: Array[String]) {
19+
HelloLib.printMessage("Hello");
20+
}
21+
}

deps/test/defs.bzl

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts", "unittest")
2+
load("@bazel_skylib//lib:collections.bzl", "collections")
3+
load("@rules_scala//scala:advanced_usage/scala.bzl", "make_scala_test")
4+
load("@rules_scala//scala/scalafmt:phase_scalafmt_ext.bzl", "ext_scalafmt")
5+
6+
# From //test/scalafmt:phase_scalafmt_test.bzl
7+
scalafmt_scala_test = make_scala_test(ext_scalafmt)
8+
9+
# From //test/proto:default_outputs_test.bzl
10+
def _default_outputs_test(ctx):
11+
env = analysistest.begin(ctx)
12+
13+
target_under_test = analysistest.target_under_test(env)
14+
actual_outs = [f.basename for f in target_under_test[DefaultInfo].files.to_list()]
15+
16+
asserts.equals(env, sorted(ctx.attr.expected_outs), sorted(actual_outs))
17+
18+
return analysistest.end(env)
19+
20+
default_outputs_test = analysistest.make(
21+
_default_outputs_test,
22+
attrs = {
23+
"expected_outs": attr.string_list(),
24+
},
25+
)
26+
27+
# From
28+
# //test/src/main/scala/scalarules/test/twitter_scrooge:twitter_scrooge_test.bzl
29+
def _scrooge_transitive_outputs(ctx):
30+
env = unittest.begin(ctx)
31+
32+
asserts.equals(
33+
env,
34+
sorted(ctx.attr.expected_jars),
35+
sorted(collections.uniq([out.class_jar.basename for out in ctx.attr.dep[JavaInfo].outputs.jars])),
36+
)
37+
38+
return unittest.end(env)
39+
40+
scrooge_transitive_outputs_test = unittest.make(
41+
_scrooge_transitive_outputs,
42+
attrs = {
43+
"dep": attr.label(),
44+
"expected_jars": attr.string_list(),
45+
},
46+
)

test/shell/test_bzlmod_macros.sh

+6-29
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ test_source="${dir}/test/shell/${BASH_SOURCE[0]#*test/shell/}"
99
# shellcheck source=./test_runner.sh
1010
. "${dir}"/test/shell/test_runner.sh
1111
. "${dir}"/test/shell/test_helper.sh
12-
runner=$(get_test_runner "${1:-local}")
1312
export USE_BAZEL_VERSION=${USE_BAZEL_VERSION:-$(cat $dir/.bazelversion)}
1413

1514
# Setup and teardown
@@ -23,14 +22,11 @@ setup_suite() {
2322
fi
2423

2524
original_dir="$PWD"
26-
test_tmpdir="${dir}/tmp/${BASH_SOURCE[0]##*/}"
27-
test_tmpdir="${test_tmpdir%.*}"
28-
test_srcs_dir="${dir}/scala/private/macros/test"
29-
30-
mkdir -p "$test_tmpdir"
31-
cd "$test_tmpdir"
25+
setup_test_tmpdir_for_file "$original_dir" "$test_source"
26+
test_tmpdir="$PWD"
3227

33-
rules_scala_dir="../.."
28+
rules_scala_dir="$(relative_path_to_parent "$original_dir" "$test_tmpdir")"
29+
test_srcs_dir="${dir}/scala/private/macros/test"
3430
test_tmpdir_base="${test_tmpdir##*/}"
3531
test_module_bazel_regex="[^ ]+${test_tmpdir_base}/MODULE.bazel"
3632

@@ -44,10 +40,7 @@ setup_suite() {
4440
}
4541

4642
teardown_suite() {
47-
# Make sure bazel isn't still running for this workspace.
48-
bazel clean --expunge_async 2>/dev/null
49-
cd "$original_dir"
50-
rm -rf "$test_tmpdir"
43+
teardown_test_tmpdir "$original_dir" "$test_tmpdir"
5144
}
5245

5346
setup_test_module() {
@@ -223,22 +216,6 @@ test_bzlmod_repeated_tag_values_fails_on_duplicate_key() {
223216
"${bazel_run_args[@]}" "$print_repeated_test_tag_values_target"
224217
}
225218

226-
# Run tests
227-
# To skip a test, add a `_` prefix to its function name.
228-
# To run a specific test, set the `RULES_SCALA_TEST_ONLY` env var to its name.
229-
230219
setup_suite
231-
232-
while IFS= read -r line; do
233-
if [[ "$line" =~ ^_?(test_[A-Za-z0-9_]+)\(\)\ ?\{$ ]]; then
234-
test_name="${BASH_REMATCH[1]}"
235-
236-
if [[ "${line:0:1}" == '_' ]]; then
237-
echo -e "${YELLOW}skipping ${test_name}${NC}"
238-
else
239-
"$runner" "$test_name"
240-
fi
241-
fi
242-
done <"$test_source"
243-
220+
run_tests "$test_source" "$(get_test_runner "${1:-local}")"
244221
teardown_suite

0 commit comments

Comments
 (0)