Add initial end-to-end test directory structure.
This turns out to be quite of a yak shave to be able to perfectly test both kernels without having to pass extra Blaze flags.
PiperOrigin-RevId: 521850709
diff --git a/.github/workflows/test_rust.yml b/.github/workflows/test_rust.yml
index 8f9b16a..3edec3e 100644
--- a/.github/workflows/test_rust.yml
+++ b/.github/workflows/test_rust.yml
@@ -24,6 +24,7 @@
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: rust_linux
bazel: |
- test //rust:protobuf_test //rust/cpp_kernel:cpp_test \
+ test //rust:protobuf_upb_test //rust:protobuf_cpp_test \
+ //rust/upb_kernel:upb_test //rust/cpp_kernel:cpp_test \
//rust/test/rust_proto_library_unit_test:rust_upb_aspect_test \
//rust/upb_kernel:upb_test //src/google/protobuf/compiler/rust/...
\ No newline at end of file
diff --git a/rust/BUILD b/rust/BUILD
index 4ea1156..247fa67 100644
--- a/rust/BUILD
+++ b/rust/BUILD
@@ -11,29 +11,56 @@
rust_library(
name = "protobuf",
- srcs = ["lib.rs"],
+ srcs = ["protobuf.rs"],
rustc_flags = select({
":use_upb_kernel": ["--cfg=upb_kernel"],
"//conditions:default": ["--cfg=cpp_kernel"],
}),
deps = select({
- ":use_upb_kernel": ["//rust/upb_kernel:upb"],
- "//conditions:default": ["//rust/cpp_kernel:cpp"],
+ ":use_upb_kernel": [":protobuf_upb"],
+ "//conditions:default": [":protobuf_cpp"],
}),
)
+rust_library(
+ name = "protobuf_upb",
+ srcs = ["shared.rs"],
+ rustc_flags = ["--cfg=upb_kernel"],
+ deps = ["//rust/upb_kernel:upb"],
+)
+
rust_test(
- name = "protobuf_test",
- crate = ":protobuf",
- rustc_flags = select({
- ":use_upb_kernel": ["--cfg=upb_kernel"],
- "//conditions:default": ["--cfg=cpp_kernel"],
- }),
+ name = "protobuf_upb_test",
+ crate = ":protobuf_upb",
+ rustc_flags = ["--cfg=upb_kernel"],
tags = [
+ # TODO(b/270274576): Enable testing on arm once we have a Rust Arm toolchain.
+ "not_build:arm",
+ # TODO(b/243126140): Enable tsan once we support sanitizers with Rust.
+ "notsan",
# TODO(b/243126140): Enable msan once we support sanitizers with Rust.
"nomsan",
+ ],
+)
+
+rust_library(
+ name = "protobuf_cpp",
+ srcs = ["shared.rs"],
+ rustc_flags = ["--cfg=cpp_kernel"],
+ deps = ["//rust/cpp_kernel:cpp"],
+)
+
+rust_test(
+ name = "protobuf_cpp_test",
+ crate = ":protobuf_cpp",
+ rustc_flags = ["--cfg=cpp_kernel"],
+ tags = [
+ # TODO(b/270274576): Enable testing on arm once we have a Rust Arm toolchain.
"not_build:arm",
+ # TODO(b/243126140): Enable tsan once we support sanitizers with Rust.
"notsan",
+ # TODO(b/243126140): Enable msan once we support sanitizers with Rust.
+ "nomsan",
],
)
@@ -42,7 +69,7 @@
name = "proto_rust_upb_toolchain",
command_line = "--rust_out=experimental-codegen=enabled,kernel=upb:$(OUT)",
progress_message = "Generating Rust proto_library %{label}",
- runtime = ":protobuf",
+ runtime = ":protobuf_upb",
visibility = ["//visibility:public"],
)
@@ -50,7 +77,7 @@
name = "proto_rust_cpp_toolchain",
command_line = "--rust_out=experimental-codegen=enabled,kernel=cpp:$(OUT)",
progress_message = "Generating Rust proto_library %{label}",
- runtime = ":protobuf",
+ runtime = ":protobuf_cpp",
visibility = ["//visibility:public"],
)
diff --git a/rust/protobuf.rs b/rust/protobuf.rs
new file mode 100644
index 0000000..9965375
--- /dev/null
+++ b/rust/protobuf.rs
@@ -0,0 +1,46 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2023 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+//! Rust Protobuf Runtime
+//!
+//! This file forwards to the kernel specific implementation. Rust Protobuf
+//! gencode actually depends directly on kernel specific crates. The only reason
+//! this crate exists is to be able to use `protobuf` as a crate name for both
+//! cpp and upb kernels from user code.
+
+#[cfg(cpp_kernel)]
+pub use protobuf_cpp::__runtime;
+#[cfg(cpp_kernel)]
+pub use protobuf_cpp::*;
+
+#[cfg(upb_kernel)]
+pub use protobuf_upb::__runtime;
+#[cfg(upb_kernel)]
+pub use protobuf_upb::*;
diff --git a/rust/lib.rs b/rust/shared.rs
similarity index 94%
rename from rust/lib.rs
rename to rust/shared.rs
index ebe3659..e5c499d 100644
--- a/rust/lib.rs
+++ b/rust/shared.rs
@@ -28,7 +28,10 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//! Rust Protobuf Runtime
+//! Kernel-agnostic logic for the Rust Protobuf Runtime.
+//!
+//! For kernel-specific logic this crate delegates to the respective __runtime
+//! crate.
#[cfg(cpp_kernel)]
pub extern crate cpp as __runtime;
diff --git a/rust/test/BUILD b/rust/test/BUILD
index 55dfeea..037c7c8 100644
--- a/rust/test/BUILD
+++ b/rust/test/BUILD
@@ -1,26 +1,40 @@
-load("//rust:defs.bzl", "rust_proto_library")
-load("@rules_rust//rust:defs.bzl", "rust_test")
+load("@rules_cc//cc:defs.bzl", "cc_proto_library")
+load(
+ "//rust:defs.bzl",
+ "rust_cc_proto_library",
+ "rust_proto_library",
+ "rust_upb_proto_library",
+)
+
+UNITTEST_PROTO_TARGET = (
+ "//src/google/protobuf:test_protos"
+)
rust_proto_library(
name = "unittest_rust_proto",
testonly = True,
- deps = [
- "//src/google/protobuf:test_protos",
- ],
+ visibility = ["//rust/test/shared:__subpackages__"],
+ deps = [UNITTEST_PROTO_TARGET],
)
-rust_test(
- name = "unittest_proto_test",
- srcs = ["unittest_proto_test.rs"],
- # TODO(b/270274576): Enable testing on arm once we have a Rust Arm toolchain.
- tags = [
- "not_build:arm",
- # TODO(b/225892643): Enable once we use Blaze-bootstrapped Rust toolchain.
- "notsan",
- # TODO(b/243126140): Enable msan once we support sanitizers with Rust.
- "nomsan",
+rust_upb_proto_library(
+ name = "unittest_upb_rust_proto",
+ testonly = True,
+ visibility = [
+ "//rust/test/shared:__subpackages__",
+ "//rust/test/upb:__subpackages__",
],
- deps = [":unittest_rust_proto"],
+ deps = [UNITTEST_PROTO_TARGET],
+)
+
+rust_cc_proto_library(
+ name = "unittest_cc_rust_proto",
+ testonly = True,
+ visibility = [
+ "//rust/test/cpp:__subpackages__",
+ "//rust/test/shared:__subpackages__",
+ ],
+ deps = [":unittest_cc_proto"],
)
proto_library(
@@ -30,34 +44,60 @@
proto_library(
name = "child_proto",
+ testonly = True,
srcs = ["child.proto"],
exports = [":parent_proto"],
deps = [":parent_proto"],
)
-rust_proto_library(
- name = "parent_rust_proto",
+rust_upb_proto_library(
+ name = "parent_upb_rust_proto",
+ testonly = True,
+ visibility = [
+ "//rust/test/shared:__subpackages__",
+ "//rust/test/upb:__subpackages__",
+ ],
deps = [":parent_proto"],
)
-rust_proto_library(
- name = "child_rust_proto",
+rust_upb_proto_library(
+ name = "child_upb_rust_proto",
+ testonly = True,
+ visibility = [
+ "//rust/test/shared:__subpackages__",
+ "//rust/test/upb:__subpackages__",
+ ],
deps = [":child_proto"],
)
-rust_test(
- name = "child_parent_test",
- srcs = ["child_parent_test.rs"],
- # TODO(b/270274576): Enable testing on arm once we have a Rust Arm toolchain.
- tags = [
- "not_build:arm",
- # TODO(b/225892643): Enable once we use Blaze-bootstrapped Rust toolchain.
- "notsan",
- # TODO(b/243126140): Enable msan once we support sanitizers with Rust.
- "nomsan",
+cc_proto_library(
+ name = "parent_cc_proto",
+ testonly = True,
+ deps = [":parent_proto"],
+)
+
+cc_proto_library(
+ name = "child_cc_proto",
+ testonly = True,
+ deps = [":child_proto"],
+)
+
+rust_cc_proto_library(
+ name = "parent_cc_rust_proto",
+ testonly = True,
+ visibility = [
+ "//rust/test/cpp:__subpackages__",
+ "//rust/test/shared:__subpackages__",
],
- deps = [
- ":child_rust_proto",
- ":parent_rust_proto",
+ deps = [":parent_cc_proto"],
+)
+
+rust_cc_proto_library(
+ name = "child_cc_rust_proto",
+ testonly = True,
+ visibility = [
+ "//rust/test/cpp:__subpackages__",
+ "//rust/test/shared:__subpackages__",
],
+ deps = [":child_cc_proto"],
)
diff --git a/rust/test/cpp/BUILD b/rust/test/cpp/BUILD
new file mode 100644
index 0000000..91782bf
--- /dev/null
+++ b/rust/test/cpp/BUILD
@@ -0,0 +1,11 @@
+# Tests specific to cpp kernel.
+#
+# Only add tests that are cpp kernel specific and it is not possible to make them work for upb (
+# for example tests exercising ABI compatibility with C++ Protobuf API).
+#
+# All the tests under this package should ignore
+# `//rust:rust_proto_library_kernel` flag and should always select `cpp`.
+#
+# To do that use:
+# * `rust_cc_proto_library` instead of `rust_proto_library`.
+# * `//rust:protobuf_cpp` instead of `//rust:protobuf``.
diff --git a/rust/test/shared/BUILD b/rust/test/shared/BUILD
new file mode 100644
index 0000000..5e9591f
--- /dev/null
+++ b/rust/test/shared/BUILD
@@ -0,0 +1,79 @@
+# Tests that are exercising and should pass with both kernels.
+#
+# All the tests under this package should ignore
+# `//rust:rust_proto_library_kernel` flag and should always cover both
+# kernels.
+#
+# To do that:
+# * Declare 2 rust_test targets and share the same sources from both.
+# * First copy will only depend on `rust_cc_proto_library` Rust proto targets, and if needed will
+# only depend on `//rust:protobuf_cpp.
+# * Second copy will only depend on `rust_upb_proto_library` Rust proto targets, and if needed will
+# only depend on `//rust:protobuf_upb
+#
+# Once we have a couple of these tests we will investigate ways to remove boilerplate (for example
+# by introducing a build macro that registers 2 rust_test targets).
+
+load("@rules_rust//rust:defs.bzl", "rust_test")
+
+rust_test(
+ name = "unittest_proto_upb_test",
+ srcs = ["unittest_proto_test.rs"],
+ tags = [
+ # TODO(b/270274576): Enable testing on arm once we have a Rust Arm toolchain.
+ "not_build:arm",
+ # TODO(b/243126140): Enable tsan once we support sanitizers with Rust.
+ "notsan",
+ # TODO(b/243126140): Enable msan once we support sanitizers with Rust.
+ "nomsan",
+ ],
+ deps = ["//rust/test:unittest_upb_rust_proto"],
+)
+
+rust_test(
+ name = "unittest_proto_cpp_test",
+ srcs = ["unittest_proto_test.rs"],
+ tags = [
+ # TODO(b/270274576): Enable testing on arm once we have a Rust Arm toolchain.
+ "not_build:arm",
+ # TODO(b/243126140): Enable tsan once we support sanitizers with Rust.
+ "notsan",
+ # TODO(b/243126140): Enable msan once we support sanitizers with Rust.
+ "nomsan",
+ ],
+ deps = ["//rust/test:unittest_cc_rust_proto"],
+)
+
+rust_test(
+ name = "child_parent_upb_test",
+ srcs = ["child_parent_test.rs"],
+ tags = [
+ # TODO(b/270274576): Enable testing on arm once we have a Rust Arm toolchain.
+ "not_build:arm",
+ # TODO(b/243126140): Enable tsan once we support sanitizers with Rust.
+ "notsan",
+ # TODO(b/243126140): Enable msan once we support sanitizers with Rust.
+ "nomsan",
+ ],
+ deps = [
+ "//rust/test:child_upb_rust_proto",
+ "//rust/test:parent_upb_rust_proto",
+ ],
+)
+
+rust_test(
+ name = "child_parent_cpp_test",
+ srcs = ["child_parent_test.rs"],
+ tags = [
+ # TODO(b/270274576): Enable testing on arm once we have a Rust Arm toolchain.
+ "not_build:arm",
+ # TODO(b/243126140): Enable tsan once we support sanitizers with Rust.
+ "notsan",
+ # TODO(b/243126140): Enable msan once we support sanitizers with Rust.
+ "nomsan",
+ ],
+ deps = [
+ "//rust/test:child_cc_rust_proto",
+ "//rust/test:parent_cc_rust_proto",
+ ],
+)
diff --git a/rust/test/child_parent_test.rs b/rust/test/shared/child_parent_test.rs
similarity index 100%
rename from rust/test/child_parent_test.rs
rename to rust/test/shared/child_parent_test.rs
diff --git a/rust/test/unittest_proto_test.rs b/rust/test/shared/unittest_proto_test.rs
similarity index 100%
rename from rust/test/unittest_proto_test.rs
rename to rust/test/shared/unittest_proto_test.rs
diff --git a/rust/test/upb/BUILD b/rust/test/upb/BUILD
new file mode 100644
index 0000000..33f2962
--- /dev/null
+++ b/rust/test/upb/BUILD
@@ -0,0 +1,11 @@
+# Tests specific to upb kernel.
+#
+# Only add tests that are cpp kernel specific and it is not possible to make them work for upb (
+# for example tests exercising ABI compatibility with other UPB-based Protobuf implementations).
+#
+# All the tests under this package should ignore
+# `//rust:rust_proto_library_kernel` flag and should always select `upb`.
+#
+# To do that use:
+# * `rust_upb_proto_library` instead of `rust_proto_library`.
+# * `//rust:protobuf_upb` instead of `//rust:protobuf``.
diff --git a/rust/upb_kernel/BUILD b/rust/upb_kernel/BUILD
index 8389b80..1d362c4 100644
--- a/rust/upb_kernel/BUILD
+++ b/rust/upb_kernel/BUILD
@@ -5,7 +5,10 @@
rust_library(
name = "upb",
srcs = ["upb.rs"],
- visibility = ["//src/google/protobuf:__subpackages__"],
+ visibility = [
+ "//src/google/protobuf:__subpackages__",
+ "//rust:__subpackages__",
+ ],
deps = [":upb_c_api"],
)
diff --git a/src/google/protobuf/compiler/rust/generator.cc b/src/google/protobuf/compiler/rust/generator.cc
index a92467a..5e6f755 100644
--- a/src/google/protobuf/compiler/rust/generator.cc
+++ b/src/google/protobuf/compiler/rust/generator.cc
@@ -173,6 +173,17 @@
}
}
+std::string GetKernelRustName(Kernel kernel) {
+ switch (kernel) {
+ case Kernel::kUpb:
+ return "upb";
+ case Kernel::kCpp:
+ return "cpp";
+ }
+ ABSL_LOG(FATAL) << "Unknown kernel type: ";
+ return "";
+}
+
bool RustGenerator::Generate(const FileDescriptor* file,
const std::string& parameter,
GeneratorContext* generator_context,
@@ -201,8 +212,8 @@
absl::StrCat(basename, GetFileExtensionForKernel(*kernel))));
google::protobuf::io::Printer p(outfile.get());
- p.Emit(R"rs(
- extern crate protobuf as __pb;
+ p.Emit({{"kernel", GetKernelRustName(*kernel)}}, R"rs(
+ extern crate protobuf_$kernel$ as __pb;
extern crate std as __std;
)rs");