Skip to content

Tests using protobuf Any field PackFrom() method failing with protobuf 33 #15682

@strophy

Description

@strophy

Does this issue affect the google-cloud-cpp project?
Yes

What component of google-cloud-cpp is this related to?
Tests using protobuf Any field PackFrom() method

Describe the bug
Building google-cloud-cpp 2.43.0 against protobuf 33.0 results in some tests failing as follows:

[ RUN      ] MakeStatusFromRpcError.AllCodesWithPayloadAndErrorDetails
/builds/strophy/aports/community/google-cloud-cpp/src/google-cloud-cpp-2.43.0/google/cloud/grpc_error_delegate_test.cc:186: Failure
Expected equality of these values:
  expected
    Which is: CANCELLED: test message error_info={reason=reason, domain=domain, metadata={key=val}}
  actual
    Which is: CANCELLED: test message

/builds/strophy/aports/community/google-cloud-cpp/src/google-cloud-cpp-2.43.0/google/cloud/grpc_error_delegate_test.cc:188: Failure
Expected equality of these values:
  error_info
    Which is: 120-byte object <18-B9 79-9D FC-7F 00-00 06-00 00-00 00-00 00-00 72-65 61-73 6F-6E 00-00 00-7A 1B-81 A3-7F 00-00 38-B9 79-9D FC-7F 00-00 06-00 00-00 00-00 00-00 64-6F 6D-61 69-6E 00-03 00-00 00-00 00-00 00-00 70-73 3A-81 A3-7F 00-00 0D-00 00-00 00-00 00-00 10-65 5F-81 A3-7F 00-00 01-00 00-00 00-00 00-00 00-00 80-3F E5-36 00-00 0D-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00>
  actual.error_info()
    Which is: 120-byte object <48-0F BE-81 A3-7F 00-00 00-00 00-00 00-00 00-00 00-04 00-00 09-00 00-00 00-00 00-00 00-00 00-00 68-0F BE-81 A3-7F 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 80-49 DD-82 A3-7F 00-00 A8-0F BE-81 A3-7F 00-00 01-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 80-3F FC-7F 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00>

/builds/strophy/aports/community/google-cloud-cpp/src/google-cloud-cpp-2.43.0/google/cloud/grpc_error_delegate_test.cc:189: Failure
Value of: internal::GetRetryInfo(actual)
Expected: value is equal to 8-byte object <00-B8 64-D9 45-00 00-00>
  Actual: (8-byte object <00-00 00-00 00-00 00-00>), whose value 8-byte object <00-00 00-00 00-00 00-00> doesn't match
... (more identical failures for different error codes, all showing loss of payload)
[ RUN      ] DebugStringStatus.Basic
/builds/strophy/aports/community/google-cloud-cpp/src/google-cloud-cpp-2.43.0/google/cloud/internal/debug_string_status_test.cc:44: Failure
Value of: actual
Expected: has substring "my_field"
  Actual: "INVALID_ARGUMENT: oh noes! + google.rpc.BadRequest { }"

/builds/strophy/aports/community/google-cloud-cpp/src/google-cloud-cpp-2.43.0/google/cloud/internal/debug_string_status_test.cc:45: Failure
Value of: actual
Expected: has substring "it is immutable"
  Actual: "INVALID_ARGUMENT: oh noes! + google.rpc.BadRequest { }"

[  FAILED  ] DebugStringStatus.Basic (6 ms)
[ RUN      ] DebugStringStatus.WithDetails
/builds/strophy/aports/community/google-cloud-cpp/src/google-cloud-cpp-2.43.0/google/cloud/internal/debug_string_status_test.cc:64: Failure
Value of: s
Expected: has substring "type.googleapis.com/google.cloud.service.v1.Resource"
  Actual: "NOT_FOUND: Resource not found + google.rpc.ResourceInfo { }"

/builds/strophy/aports/community/google-cloud-cpp/src/google-cloud-cpp-2.43.0/google/cloud/internal/debug_string_status_test.cc:65: Failure
Value of: s
Expected: has substring "projects/project/resources/resource"
  Actual: "NOT_FOUND: Resource not found + google.rpc.ResourceInfo { }"

/builds/strophy/aports/community/google-cloud-cpp/src/google-cloud-cpp-2.43.0/google/cloud/internal/debug_string_status_test.cc:66: Failure
Value of: s
Expected: has substring "Resource does not exist."
  Actual: "NOT_FOUND: Resource not found + google.rpc.ResourceInfo { }"

[  FAILED  ] DebugStringStatus.WithDetails (0 ms)
[ RUN      ] AsyncConnectionImplTest.HandleRedirectErrors
/builds/strophy/aports/community/google-cloud-cpp/src/google-cloud-cpp-2.43.0/google/cloud/storage/internal/async/connection_impl_open_test.cc:262: Failure
Value of: r.read_object_spec()
Expected: Checks whether protos are equal
  Actual: <
goo.gle/debugstr  
bucket: "test-only-invalid"
object: "test-object"
generation: 24
if_generation_match: 42
read_handle {
}
routing_token: ""
> (of type google::storage::v2::BidiReadObjectSpec), 
added: read_handle.handle: "test-read-handle"
modified: routing_token: "" -> "test-routing-token"


/builds/strophy/aports/community/google-cloud-cpp/src/google-cloud-cpp-2.43.0/google/cloud/storage/internal/async/connection_impl_open_test.cc:262: Failure
Value of: r.read_object_spec()
Expected: Checks whether protos are equal
  Actual: <
goo.gle/debugstr  
bucket: "test-only-invalid"
object: "test-object"
generation: 24
if_generation_match: 42
read_handle {
}
routing_token: ""
> (of type google::storage::v2::BidiReadObjectSpec), 
added: read_handle.handle: "test-read-handle"
modified: routing_token: "" -> "test-routing-token"


[  FAILED  ] AsyncConnectionImplTest.HandleRedirectErrors (157 ms)
[ RUN      ] ClientTest.CommitMutatorSessionNotFound

GMOCK WARNING:
Uninteresting mock function call - returning default value.
    Function call: options()
          Returns: 56-byte object <A0-80 9C-82 FF-7F 00-00 01-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 80-3F 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00>
NOTE: You can safely ignore the above warning unless this call should not happen.  Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call.  See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect-useoncall for details.

GMOCK WARNING:
Uninteresting mock function call - returning default value.
    Function call: Rollback(16-byte object <20-FB 83-AF 99-7F 00-00 10-FB 83-AF 99-7F 00-00>)
          Returns: OK
NOTE: You can safely ignore the above warning unless this call should not happen.  Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call.  See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect-useoncall for details.
/builds/strophy/aports/community/google-cloud-cpp/src/google-cloud-cpp-2.43.0/google/cloud/spanner/client_test.cc:984: Failure
Value of: result
Expected: code is equal to OK and message is anything
  Actual: 48-byte object <80-0E 6D-AE 99-7F 00-00 00-00 00-00 00-00 00-00 01-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 B0-40 9C-AF 99-7F 00-00 00-3A 77-B0 99-7F 00-00>, whose status is NOT_FOUND: Session not found, with a code that isn't equal to OK, but a message that is anything

/builds/strophy/aports/community/google-cloud-cpp/src/google-cloud-cpp-2.43.0/google/cloud/spanner/client_test.cc:967: Failure
Actual function call count doesn't match EXPECT_CALL(*conn, Commit)...
         Expected: to be called once
           Actual: never called - unsatisfied and active

[  FAILED  ] ClientTest.CommitMutatorSessionNotFound (0 ms)
[ RUN      ] ClientTest.CommitSessionNotFound

GMOCK WARNING:
Uninteresting mock function call - returning default value.
    Function call: options()
          Returns: 56-byte object <70-80 9C-82 FF-7F 00-00 01-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 80-3F 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00>
NOTE: You can safely ignore the above warning unless this call should not happen.  Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call.  See https://github.com/google/googletest/blob/main/docs/gmock_cook_book.md#knowing-when-to-expect-useoncall for details.
/builds/strophy/aports/community/google-cloud-cpp/src/google-cloud-cpp-2.43.0/google/cloud/spanner/client_test.cc:1013: Failure
Value of: result
Expected: code is equal to OK and message is anything
  Actual: 48-byte object <90-AE 2A-AE 99-7F 00-00 00-00 00-00 00-00 00-00 3A-4A 9E-AF 99-7F 00-00 18-87 27-AE 99-7F 00-00 50-88 9C-82 FF-7F 00-00 00-00 00-00 00-00 00-00>, whose status is NOT_FOUND: Session not found, with a code that isn't equal to OK, but a message that is anything

/builds/strophy/aports/community/google-cloud-cpp/src/google-cloud-cpp-2.43.0/google/cloud/spanner/client_test.cc:994: Failure
Actual function call count doesn't match EXPECT_CALL(*conn, Commit)...
         Expected: to be called twice
           Actual: called once - unsatisfied and active

[  FAILED  ] ClientTest.CommitSessionNotFound (0 ms)
[ RUN      ] StatusUtils.SessionNotFoundResourceInfo
/builds/strophy/aports/community/google-cloud-cpp/src/google-cloud-cpp-2.43.0/google/cloud/spanner/internal/status_utils_test.cc:42: Failure
Value of: IsSessionNotFound(not_found)
  Actual: false
Expected: true
NOT_FOUND: Session not found

/builds/strophy/aports/community/google-cloud-cpp/src/google-cloud-cpp-2.43.0/google/cloud/spanner/internal/status_utils_test.cc:51: Failure
Value of: IsSessionNotFound(still_not_found)
  Actual: false
Expected: true
NOT_FOUND: foo bar

[  FAILED  ] StatusUtils.SessionNotFoundResourceInfo (1 ms)
[ RUN      ] ConnectionImplTest.CommitAtLeastOnceBatchedSessionNotFound
/builds/strophy/aports/community/google-cloud-cpp/src/google-cloud-cpp-2.43.0/google/cloud/spanner/internal/connection_impl_test.cc:3436: Failure
Value of: IsSessionNotFound(it->status())
  Actual: false
Expected: true
NOT_FOUND: Session not found

/builds/strophy/aports/community/google-cloud-cpp/src/google-cloud-cpp-2.43.0/google/cloud/spanner/internal/connection_impl_test.cc:3418: Failure
Expected equality of these values:
  "test-session-name-2"
  request.session()
    Which is: "test-session-name-1"

unknown file: Failure

Unexpected mock function call - returning default value.
    Function call: AsyncDeleteSession(@0x7f35a3cd5eb8 16-byte object <50-B1 C7-A3 35-7F 00-00 70-89 F7-A4 35-7F 00-00>, (ptr = 0x7f35a39dede0, value = 480-byte object <00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 FF-FF FF-FF FF-FF FF-7F 00-00 00-00 01-00 00-00 ... 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00>), (ptr = 0x7f35a3a84a30, value = 56-byte object <60-4A A8-A3 35-7F 00-00 01-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 80-3F 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00>), @0x7f35a3cd5ed8 <goo.gle/debugonly  name: "test-session-name-1">)
          Returns: 16-byte object <00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00>
Google Mock tried the following 1 expectation, but it didn't match:

/builds/strophy/aports/community/google-cloud-cpp/src/google-cloud-cpp-2.43.0/google/cloud/spanner/internal/connection_impl_test.cc:3425: EXPECT_CALL(*mock, AsyncDeleteSession(_, _, _, HasSessionName("test-session-name-2")))...
  Expected arg #3: has session name
           Actual: <goo.gle/debugonly  name: "test-session-name-1">
         Expected: to be called once
           Actual: never called - unsatisfied and active

terminate called after throwing an instance of 'std::future_error'
  what():  std::future_error: No associated state

To Reproduce Steps to reproduce the behavior:

  1. Build google-cloud-cpp 2.43.0 against protobuf 33
  2. Run tests, observe errors

Expected behavior
Tests should pass

Operating system:
Alpine Linux 3.22

What compiler and version are you using?

6868aa1168e3:~/package$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-alpine-linux-musl/15.2.0/lto-wrapper
Target: x86_64-alpine-linux-musl
Configured with: /home/buildozer/aports/main/gcc/src/gcc-15.2.0/configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --build=x86_64-alpine-linux-musl --host=x86_64-alpine-linux-musl --target=x86_64-alpine-linux-musl --enable-checking=release --disable-cet --disable-fixed-point --disable-libstdcxx-pch --disable-multilib --disable-nls --disable-werror --disable-symvers --enable-__cxa_atexit --enable-default-pie --enable-default-ssp --enable-languages=c,c++,d,objc,go,fortran,ada --enable-link-serialization=2 --enable-linker-build-id --disable-libssp --enable-libsanitizer --enable-shared --enable-threads --enable-tls --with-bugurl=https://gitlab.alpinelinux.org/alpine/aports/-/issues --with-system-zlib --with-linker-hash-style=gnu --with-pkgversion='Alpine 15.2.0'
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 15.2.0 (Alpine 15.2.0) 

What version of google-cloud-cpp are you using?
2.43.0

Additional context
I worked with Claude a bit to try and narrow the problem down to the use of PackFrom(). Modifying the tests using PackFrom() to instead pack the messages manually results in test success. Is this a problem in google-cloud-cpp or protobuf, or am I just doing something wrong?

diff --git a/google/cloud/grpc_error_delegate_test.cc b/google/cloud/grpc_error_delegate_test.cc
index 2a9ac50374..47070e0107 100644
--- a/google/cloud/grpc_error_delegate_test.cc
+++ b/google/cloud/grpc_error_delegate_test.cc
@@ -54,8 +54,14 @@ std::string MakeErrorDetails(grpc::StatusCode code, std::string message,
   *retry_info_proto.mutable_retry_delay() =
       internal::ToDurationProto(retry_info.retry_delay());
 
-  proto.add_details()->PackFrom(error_info_proto);
-  proto.add_details()->PackFrom(retry_info_proto);
+  auto* detail1 = proto.add_details();
+  detail1->set_type_url("type.googleapis.com/google.rpc.ErrorInfo");
+  detail1->set_value(error_info_proto.SerializeAsString());
+
+  auto* detail2 = proto.add_details();
+  detail2->set_type_url("type.googleapis.com/google.rpc.RetryInfo");
+  detail2->set_value(retry_info_proto.SerializeAsString());
+
   return MakeErrorDetails(proto);
 }
 
diff --git a/google/cloud/internal/debug_string_status_test.cc b/google/cloud/internal/debug_string_status_test.cc
index d1f1bec903..abc0443b60 100644
--- a/google/cloud/internal/debug_string_status_test.cc
+++ b/google/cloud/internal/debug_string_status_test.cc
@@ -36,7 +36,9 @@ TEST(DebugStringStatus, Basic) {
   auto proto = google::rpc::Status();
   proto.set_code(static_cast<std::int32_t>(StatusCode::kInvalidArgument));
   proto.set_message("oh noes!");
-  proto.add_details()->PackFrom(detail);
+  auto* any = proto.add_details();
+  any->set_type_url("type.googleapis.com/google.rpc.BadRequest");
+  any->set_value(detail.SerializeAsString());
 
   auto const status = MakeStatusFromRpcError(proto);
   auto const actual = DebugString(status, TracingOptions());
@@ -55,7 +57,9 @@ TEST(DebugStringStatus, WithDetails) {
   google::rpc::Status proto;
   proto.set_code(grpc::StatusCode::NOT_FOUND);
   proto.set_message("Resource not found");
-  proto.add_details()->PackFrom(resource_info);
+  auto* any = proto.add_details();
+  any->set_type_url("type.googleapis.com/google.rpc.ResourceInfo");
+  any->set_value(resource_info.SerializeAsString());
 
   TracingOptions tracing_options;
   auto s = DebugString(MakeStatusFromRpcError(proto), tracing_options);
diff --git a/google/cloud/spanner/testing/status_utils.cc b/google/cloud/spanner/testing/status_utils.cc
index 1629f3110b..3371794fbb 100644
--- a/google/cloud/spanner/testing/status_utils.cc
+++ b/google/cloud/spanner/testing/status_utils.cc
@@ -37,7 +37,9 @@ grpc::Status SessionNotFoundRpcError(std::string name) {
   google::rpc::Status proto;
   proto.set_code(grpc::StatusCode::NOT_FOUND);
   proto.set_message("Session not found");
-  proto.add_details()->PackFrom(resource_info);
+  auto* any = proto.add_details();
+  any->set_type_url("type.googleapis.com/google.rpc.ResourceInfo");
+  any->set_value(resource_info.SerializeAsString());
 
   return grpc::Status(grpc::StatusCode::NOT_FOUND, proto.message(),
                       proto.SerializeAsString());
diff --git a/google/cloud/storage/internal/async/connection_impl_open_test.cc b/google/cloud/storage/internal/async/connection_impl_open_test.cc
index 6d72d6f40a..05fec9305a 100644
--- a/google/cloud/storage/internal/async/connection_impl_open_test.cc
+++ b/google/cloud/storage/internal/async/connection_impl_open_test.cc
@@ -97,7 +97,10 @@ Status RedirectError(absl::string_view handle, absl::string_view token) {
     auto details_proto = google::rpc::Status{};
     details_proto.set_code(grpc::StatusCode::ABORTED);
     details_proto.set_message("redirect");
-    details_proto.add_details()->PackFrom(redirected);
+    auto* any = details_proto.add_details();
+    any->set_type_url(
+        "type.googleapis.com/google.storage.v2.BidiReadObjectRedirectedError");
+    any->set_value(redirected.SerializeAsString());
 
     std::string details;
     details_proto.SerializeToString(&details);
diff --git a/google/cloud/storage/internal/async/object_descriptor_impl_test.cc b/google/cloud/storage/internal/async/object_descriptor_impl_test.cc
index 595dd34231..449bd9f507 100644
--- a/google/cloud/storage/internal/async/object_descriptor_impl_test.cc
+++ b/google/cloud/storage/internal/async/object_descriptor_impl_test.cc
@@ -822,7 +822,9 @@ Status RedirectError(absl::string_view handle, absl::string_view token) {
     auto details_proto = google::rpc::Status{};
     details_proto.set_code(grpc::StatusCode::UNAVAILABLE);
     details_proto.set_message("redirect");
-    details_proto.add_details()->PackFrom(redirected);
+    auto* any = details_proto.add_details();
+    any->set_type_url("type.googleapis.com/google.storage.v2.BidiReadObjectRedirectedError");
+    any->set_value(redirected.SerializeAsString());
 
     std::string details;
     details_proto.SerializeToString(&details);
@@ -1043,7 +1045,9 @@ Status PartialFailure(std::int64_t read_id) {
     auto details_proto = google::rpc::Status{};
     details_proto.set_code(grpc::StatusCode::INVALID_ARGUMENT);
     details_proto.set_message("some reads are out of range");
-    details_proto.add_details()->PackFrom(error);
+    auto* any = details_proto.add_details();
+    any->set_type_url("type.googleapis.com/google.storage.v2.BidiReadObjectError");
+    any->set_value(error.SerializeAsString());
 
     std::string details;
     details_proto.SerializeToString(&details);

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority: p2Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions