From fe85e1f87fb773216fe2bc44ead3f7e10ad75f25 Mon Sep 17 00:00:00 2001 From: Gauri Kalra Date: Wed, 2 Sep 2026 09:05:59 +0000 Subject: [PATCH 1/4] feat(storage): support DirectPath over Interconnect in GCS gRPC --- google/cloud/storage/grpc_plugin.h | 11 ++ .../storage/internal/grpc/default_options.cc | 34 ++++- .../internal/grpc/default_options_test.cc | 143 ++++++++++++++++++ 3 files changed, 181 insertions(+), 7 deletions(-) diff --git a/google/cloud/storage/grpc_plugin.h b/google/cloud/storage/grpc_plugin.h index 51f25f2fdc73c..42119d615ff68 100644 --- a/google/cloud/storage/grpc_plugin.h +++ b/google/cloud/storage/grpc_plugin.h @@ -128,6 +128,17 @@ struct GrpcMetricsExcludedLabelsOption { using Type = std::set; }; +/** + * Option to attempt DirectPath over Interconnect. + * + * When this option is enabled, the client bypasses GCE VM environment/BIOS + * checks and configures the gRPC channel to target + * `google-c2p:///storage-direct.googleapis.com?force-xds` with standard TLS. + */ +struct DirectPathXdsOverInterconnectOption { + using Type = bool; +}; + GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace storage_experimental } // namespace cloud diff --git a/google/cloud/storage/internal/grpc/default_options.cc b/google/cloud/storage/internal/grpc/default_options.cc index 27ac0996a369b..a8fb1198109f8 100644 --- a/google/cloud/storage/internal/grpc/default_options.cc +++ b/google/cloud/storage/internal/grpc/default_options.cc @@ -100,13 +100,33 @@ Options DefaultOptionsGrpc( auto const ep = google::cloud::internal::UniverseDomainEndpoint( "storage.googleapis.com", options); - // Set default to direct connectivity if we can detect we are running in GCP - // and there is not already a set endpoint or unviverse domain endpoint. - if ((!options.has() && - !options.has()) && - (gcp_detector->IsGoogleCloudBios() || - gcp_detector->IsGoogleCloudServerless())) { - options.set("google-c2p:///storage.googleapis.com"); + if (!options + .has()) { + auto const env = + GetEnv("GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS_OVER_INTERCONNECT"); + if (env.has_value() && *env == "true") { + options.set( + true); + } + } + auto const direct_path_interconnect = + options.get(); + + // Set default to direct connectivity if DirectPath over Interconnect is + // enabled, or if running in GCP and no endpoint or universe domain is + // explicitly configured. + if (!options.has() && + !options.has()) { + if (direct_path_interconnect) { + options.set( + "google-c2p:///storage-direct.googleapis.com?force-xds"); + if (!options.has()) { + options.set("storage.googleapis.com"); + } + } else if (gcp_detector->IsGoogleCloudBios() || + gcp_detector->IsGoogleCloudServerless()) { + options.set("google-c2p:///storage.googleapis.com"); + } } options = google::cloud::internal::MergeOptions( diff --git a/google/cloud/storage/internal/grpc/default_options_test.cc b/google/cloud/storage/internal/grpc/default_options_test.cc index 64600ed41b7a3..b2b387a8528ad 100644 --- a/google/cloud/storage/internal/grpc/default_options_test.cc +++ b/google/cloud/storage/internal/grpc/default_options_test.cc @@ -54,6 +54,7 @@ TEST(DefaultOptionsGrpc, DefaultOptionsGrpcChannelCount) { {"storage.googleapis.com", 4, std::numeric_limits::max()}, {"google-c2p:///storage.googleapis.com", 1, 1}, {"google-c2p-experimental:///storage.googleapis.com", 1, 1}, + {"google-c2p:///storage-direct.googleapis.com?force-xds", 1, 1}, }; for (auto const& test : cases) { @@ -95,6 +96,148 @@ TEST(DefaultOptionsGrpc, DefaultEndpointsDirectPath) { EXPECT_EQ(options.get(), "storage.googleapis.com"); } +TEST(DefaultOptionsGrpc, DefaultEndpointsDirectPathOverInterconnectOption) { + auto mock_detector = std::make_shared(); + EXPECT_CALL(*mock_detector, IsGoogleCloudBios()) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*mock_detector, IsGoogleCloudServerless()) + .WillRepeatedly(Return(false)); + + auto options = DefaultOptionsGrpc( + Options{}.set( + true), + mock_detector); + EXPECT_EQ(options.get(), + "google-c2p:///storage-direct.googleapis.com?force-xds"); + EXPECT_EQ(options.get(), "storage.googleapis.com"); + EXPECT_EQ(options.get(), 1); +} + +TEST(DefaultOptionsGrpc, DefaultEndpointsDirectPathOverInterconnectEnvVar) { + ScopedEnvironment env("GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS_OVER_INTERCONNECT", + "true"); + auto mock_detector = std::make_shared(); + EXPECT_CALL(*mock_detector, IsGoogleCloudBios()) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*mock_detector, IsGoogleCloudServerless()) + .WillRepeatedly(Return(false)); + + auto options = DefaultOptionsGrpc(Options{}, mock_detector); + EXPECT_EQ(options.get(), + "google-c2p:///storage-direct.googleapis.com?force-xds"); + EXPECT_EQ(options.get(), "storage.googleapis.com"); + EXPECT_EQ(options.get(), 1); +} + +TEST(DefaultOptionsGrpc, DefaultEndpointsDirectPathOverInterconnectDisabled) { + auto mock_detector = std::make_shared(); + EXPECT_CALL(*mock_detector, IsGoogleCloudBios()) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*mock_detector, IsGoogleCloudServerless()) + .WillRepeatedly(Return(false)); + + auto options = DefaultOptionsGrpc( + Options{}.set( + false), + mock_detector); + EXPECT_EQ(options.get(), "storage.googleapis.com"); + EXPECT_EQ(options.get(), "storage.googleapis.com"); + EXPECT_GE(options.get(), 4); +} + +TEST(DefaultOptionsGrpc, + DefaultEndpointsDirectPathOverInterconnectUserEndpointOverride) { + auto mock_detector = std::make_shared(); + EXPECT_CALL(*mock_detector, IsGoogleCloudBios()) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*mock_detector, IsGoogleCloudServerless()) + .WillRepeatedly(Return(false)); + + auto options = DefaultOptionsGrpc( + Options{} + .set(true) + .set("custom-endpoint") + .set("custom-authority"), + mock_detector); + EXPECT_EQ(options.get(), "custom-endpoint"); + EXPECT_EQ(options.get(), "custom-authority"); +} + +TEST(DefaultOptionsGrpc, + DefaultEndpointsDirectPathOverInterconnectUniverseDomainOverride) { + auto mock_detector = std::make_shared(); + EXPECT_CALL(*mock_detector, IsGoogleCloudBios()) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*mock_detector, IsGoogleCloudServerless()) + .WillRepeatedly(Return(false)); + + auto options = DefaultOptionsGrpc( + Options{} + .set(true) + .set("my-ud.net"), + mock_detector); + EXPECT_EQ(options.get(), "storage.my-ud.net"); + EXPECT_EQ(options.get(), "storage.my-ud.net"); +} + +TEST( + DefaultOptionsGrpc, + DefaultEndpointsDirectPathOverInterconnectProgrammaticFalseOverridesEnvVar) { + ScopedEnvironment env("GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS_OVER_INTERCONNECT", + "true"); + auto mock_detector = std::make_shared(); + EXPECT_CALL(*mock_detector, IsGoogleCloudBios()) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*mock_detector, IsGoogleCloudServerless()) + .WillRepeatedly(Return(false)); + + auto options = DefaultOptionsGrpc( + Options{}.set( + false), + mock_detector); + EXPECT_EQ(options.get(), "storage.googleapis.com"); + EXPECT_EQ(options.get(), "storage.googleapis.com"); + EXPECT_FALSE( + options.get()); + EXPECT_GE(options.get(), 4); +} + +TEST(DefaultOptionsGrpc, + DefaultEndpointsDirectPathOverInterconnectPreservesCustomAuthority) { + auto mock_detector = std::make_shared(); + EXPECT_CALL(*mock_detector, IsGoogleCloudBios()) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*mock_detector, IsGoogleCloudServerless()) + .WillRepeatedly(Return(false)); + + auto options = DefaultOptionsGrpc( + Options{} + .set(true) + .set("custom-authority"), + mock_detector); + EXPECT_EQ(options.get(), + "google-c2p:///storage-direct.googleapis.com?force-xds"); + EXPECT_EQ(options.get(), "custom-authority"); + EXPECT_EQ(options.get(), 1); +} + +TEST(DefaultOptionsGrpc, + DefaultEndpointsDirectPathOverInterconnectUniverseDomainEnvVar) { + ScopedEnvironment ud("GOOGLE_CLOUD_UNIVERSE_DOMAIN", "my-ud.net"); + auto mock_detector = std::make_shared(); + EXPECT_CALL(*mock_detector, IsGoogleCloudBios()) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*mock_detector, IsGoogleCloudServerless()) + .WillRepeatedly(Return(false)); + + auto options = DefaultOptionsGrpc( + Options{}.set( + true), + mock_detector); + EXPECT_EQ(options.get(), "storage.my-ud.net"); + EXPECT_EQ(options.get(), "storage.my-ud.net"); +} + TEST(DefaultOptionsGrpc, EndpointOptionsOverrideDefaults) { ScopedEnvironment ud("GOOGLE_CLOUD_UNIVERSE_DOMAIN", "ud-env-var.net"); From b667bda331d5c90cc94b8180211d283378ac823a Mon Sep 17 00:00:00 2001 From: Gauri Kalra Date: Wed, 2 Sep 2026 10:52:34 +0000 Subject: [PATCH 2/4] Address feedback from Gemini code assistant --- google/cloud/storage/internal/grpc/default_options.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google/cloud/storage/internal/grpc/default_options.cc b/google/cloud/storage/internal/grpc/default_options.cc index a8fb1198109f8..df20b98eca68d 100644 --- a/google/cloud/storage/internal/grpc/default_options.cc +++ b/google/cloud/storage/internal/grpc/default_options.cc @@ -109,7 +109,7 @@ Options DefaultOptionsGrpc( true); } } - auto const direct_path_interconnect = + bool const direct_path_interconnect = options.get(); // Set default to direct connectivity if DirectPath over Interconnect is From c7c7c6f398e419cd35dc6ed0cbf80052f8a7069a Mon Sep 17 00:00:00 2001 From: Gauri Kalra Date: Mon, 14 Sep 2026 10:56:40 +0000 Subject: [PATCH 3/4] Add explicit default and document it --- .../storage/doc/environment-variables.dox | 16 ++- google/cloud/storage/grpc_plugin.h | 23 ++++ .../storage/internal/grpc/default_options.cc | 25 +++- .../internal/grpc/default_options_test.cc | 124 +++++++++++++++--- 4 files changed, 166 insertions(+), 22 deletions(-) diff --git a/google/cloud/storage/doc/environment-variables.dox b/google/cloud/storage/doc/environment-variables.dox index cc28d724252d3..0d75a214c643a 100644 --- a/google/cloud/storage/doc/environment-variables.dox +++ b/google/cloud/storage/doc/environment-variables.dox @@ -37,7 +37,21 @@ protocol, but currently unused. `GOOGLE_CLOUD_CPP_STORAGE_GRPC_CONFIG=...`: this is deprecated. -[project-definition-link]: https://cloud.google.com/storage/docs/projects 'Project Definition in GCS' +`GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS_OVER_INTERCONNECT=true`: attempt DirectPath +over [Cloud Interconnect][interconnect-link]. This bypasses the usual GCE +environment detection, making DirectPath usable from on-premise hosts. Set to +`false` to disable the feature even when the corresponding option is enabled in +code. Only these exact values are recognized, and the comparison is +case-sensitive; any other value, such as `1` or `TRUE`, is treated as if the +variable were not set. This environment variable takes precedence over the +option. + +@see google::cloud::storage_experimental::DirectPathXdsOverInterconnectOption + +[project-definition-link]: https://cloud.google.com/storage/docs/projects +'Project Definition in GCS' [interconnect-link]: +https://cloud.google.com/network-connectivity/docs/interconnect 'Cloud +Interconnect' @section storage-env-logging Logging diff --git a/google/cloud/storage/grpc_plugin.h b/google/cloud/storage/grpc_plugin.h index 42119d615ff68..ed0a40df0dce6 100644 --- a/google/cloud/storage/grpc_plugin.h +++ b/google/cloud/storage/grpc_plugin.h @@ -134,6 +134,29 @@ struct GrpcMetricsExcludedLabelsOption { * When this option is enabled, the client bypasses GCE VM environment/BIOS * checks and configures the gRPC channel to target * `google-c2p:///storage-direct.googleapis.com?force-xds` with standard TLS. + * This makes DirectPath usable from on-premise hosts reaching Google Cloud over + * [Cloud Interconnect], where the usual GCE environment detection would + * otherwise disable it. + * + * The default is `false`. The + * `GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS_OVER_INTERCONNECT` environment variable + * overrides this option: set it to `"true"` to enable the feature, or to + * `"false"` to disable it even when this option is set. Only these exact + * values are recognized, and the comparison is case-sensitive; any other + * value, for example `"1"` or `"TRUE"`, is treated as if the variable were not + * set. This lets a deployment turn the feature on or off without rebuilding + * the application. + * + * @par Example: Enable DirectPath over Interconnect + * @code + * namespace gcs_ex = google::cloud::storage_experimental; + * auto client = google::cloud::storage::MakeGrpcClient( + * google::cloud::Options{} + * .set(true)); + * @endcode + * + * [Cloud Interconnect]: + * https://cloud.google.com/network-connectivity/docs/interconnect */ struct DirectPathXdsOverInterconnectOption { using Type = bool; diff --git a/google/cloud/storage/internal/grpc/default_options.cc b/google/cloud/storage/internal/grpc/default_options.cc index df20b98eca68d..e8342f101ed95 100644 --- a/google/cloud/storage/internal/grpc/default_options.cc +++ b/google/cloud/storage/internal/grpc/default_options.cc @@ -36,6 +36,7 @@ namespace { auto constexpr kMinMetricsPeriod = std::chrono::seconds(5); auto constexpr kDefaultMetricsPeriod = std::chrono::seconds(60); auto constexpr kDefaultMetricsExportTimeout = std::chrono::seconds(30); +bool constexpr kDefaultDirectPathXdsOverInterconnect = false; int DefaultGrpcNumChannels(std::string const& endpoint) { // When using Direct Connectivity the gRPC library already does load balancing @@ -102,19 +103,31 @@ Options DefaultOptionsGrpc( if (!options .has()) { - auto const env = - GetEnv("GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS_OVER_INTERCONNECT"); - if (env.has_value() && *env == "true") { + options.set( + kDefaultDirectPathXdsOverInterconnect); + } + + // The environment variable takes precedence over the option, consistent with. + // An explicit "false" disables the feature even when the option is set, so + // deployments can opt out without rebuilding the application. Any other value + // is treated as if the variable were not set. + auto const direct_path_interconnect_env = + GetEnv("GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS_OVER_INTERCONNECT"); + if (direct_path_interconnect_env.has_value()) { + if (*direct_path_interconnect_env == "true") { options.set( true); + } else if (*direct_path_interconnect_env == "false") { + options.set( + false); } } bool const direct_path_interconnect = options.get(); - // Set default to direct connectivity if DirectPath over Interconnect is - // enabled, or if running in GCP and no endpoint or universe domain is - // explicitly configured. + // Unless the application configured an endpoint or universe domain, default + // to direct connectivity: the Interconnect target when that feature is + // enabled, otherwise the standard target when running in GCP. if (!options.has() && !options.has()) { if (direct_path_interconnect) { diff --git a/google/cloud/storage/internal/grpc/default_options_test.cc b/google/cloud/storage/internal/grpc/default_options_test.cc index b2b387a8528ad..451c80d8b92af 100644 --- a/google/cloud/storage/internal/grpc/default_options_test.cc +++ b/google/cloud/storage/internal/grpc/default_options_test.cc @@ -96,7 +96,31 @@ TEST(DefaultOptionsGrpc, DefaultEndpointsDirectPath) { EXPECT_EQ(options.get(), "storage.googleapis.com"); } -TEST(DefaultOptionsGrpc, DefaultEndpointsDirectPathOverInterconnectOption) { +/// @test Verify the option defaults to disabled, and that the resolved default +/// is reported when neither the option nor the environment variable is set. +TEST(DefaultOptionsGrpc, DirectPathOverInterconnectDefault) { + ScopedEnvironment env("GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS_OVER_INTERCONNECT", + {}); + auto mock_detector = std::make_shared(); + EXPECT_CALL(*mock_detector, IsGoogleCloudBios()) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*mock_detector, IsGoogleCloudServerless()) + .WillRepeatedly(Return(false)); + + auto options = DefaultOptionsGrpc(Options{}, mock_detector); + EXPECT_TRUE( + options.has()); + EXPECT_FALSE( + options.get()); + EXPECT_EQ(options.get(), "storage.googleapis.com"); + EXPECT_EQ(options.get(), "storage.googleapis.com"); +} + +/// @test Verify enabling the option off-GCE targets the DirectPath resolver, +/// overrides the authority so TLS/SNI matches, and uses a single channel. +TEST(DefaultOptionsGrpc, DirectPathOverInterconnectOption) { + ScopedEnvironment env("GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS_OVER_INTERCONNECT", + {}); auto mock_detector = std::make_shared(); EXPECT_CALL(*mock_detector, IsGoogleCloudBios()) .WillRepeatedly(Return(false)); @@ -113,7 +137,9 @@ TEST(DefaultOptionsGrpc, DefaultEndpointsDirectPathOverInterconnectOption) { EXPECT_EQ(options.get(), 1); } -TEST(DefaultOptionsGrpc, DefaultEndpointsDirectPathOverInterconnectEnvVar) { +/// @test Verify the environment variable enables the feature when the option is +/// unset, i.e. the zero-code rollout path for operators. +TEST(DefaultOptionsGrpc, DirectPathOverInterconnectEnvVar) { ScopedEnvironment env("GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS_OVER_INTERCONNECT", "true"); auto mock_detector = std::make_shared(); @@ -129,7 +155,11 @@ TEST(DefaultOptionsGrpc, DefaultEndpointsDirectPathOverInterconnectEnvVar) { EXPECT_EQ(options.get(), 1); } -TEST(DefaultOptionsGrpc, DefaultEndpointsDirectPathOverInterconnectDisabled) { +/// @test Verify explicitly disabling the option off-GCE keeps the client on +/// CloudPath, including the CloudPath multi-channel defaults. +TEST(DefaultOptionsGrpc, DirectPathOverInterconnectDisabled) { + ScopedEnvironment env("GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS_OVER_INTERCONNECT", + {}); auto mock_detector = std::make_shared(); EXPECT_CALL(*mock_detector, IsGoogleCloudBios()) .WillRepeatedly(Return(false)); @@ -145,8 +175,9 @@ TEST(DefaultOptionsGrpc, DefaultEndpointsDirectPathOverInterconnectDisabled) { EXPECT_GE(options.get(), 4); } -TEST(DefaultOptionsGrpc, - DefaultEndpointsDirectPathOverInterconnectUserEndpointOverride) { +/// @test Verify a caller-supplied endpoint wins over the DirectPath target, so +/// testbench and private-endpoint setups keep working. +TEST(DefaultOptionsGrpc, DirectPathOverInterconnectUserEndpointOverride) { auto mock_detector = std::make_shared(); EXPECT_CALL(*mock_detector, IsGoogleCloudBios()) .WillRepeatedly(Return(false)); @@ -163,8 +194,9 @@ TEST(DefaultOptionsGrpc, EXPECT_EQ(options.get(), "custom-authority"); } -TEST(DefaultOptionsGrpc, - DefaultEndpointsDirectPathOverInterconnectUniverseDomainOverride) { +/// @test Verify a caller-supplied universe domain wins over the DirectPath +/// target, as DirectPath is only available in the default universe. +TEST(DefaultOptionsGrpc, DirectPathOverInterconnectUniverseDomainOverride) { auto mock_detector = std::make_shared(); EXPECT_CALL(*mock_detector, IsGoogleCloudBios()) .WillRepeatedly(Return(false)); @@ -180,9 +212,9 @@ TEST(DefaultOptionsGrpc, EXPECT_EQ(options.get(), "storage.my-ud.net"); } -TEST( - DefaultOptionsGrpc, - DefaultEndpointsDirectPathOverInterconnectProgrammaticFalseOverridesEnvVar) { +/// @test Verify `GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS_OVER_INTERCONNECT=true` +/// overrides the option, consistent with other environment variables. +TEST(DefaultOptionsGrpc, DirectPathOverInterconnectEnvVarOverridesOption) { ScopedEnvironment env("GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS_OVER_INTERCONNECT", "true"); auto mock_detector = std::make_shared(); @@ -195,15 +227,76 @@ TEST( Options{}.set( false), mock_detector); - EXPECT_EQ(options.get(), "storage.googleapis.com"); + EXPECT_TRUE( + options.get()); + EXPECT_EQ(options.get(), + "google-c2p:///storage-direct.googleapis.com?force-xds"); EXPECT_EQ(options.get(), "storage.googleapis.com"); + EXPECT_EQ(options.get(), 1); +} + +/// @test Verify `GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS_OVER_INTERCONNECT=false` +/// disables the feature even when the option is set, providing an opt-out that +/// does not require rebuilding the application. +TEST(DefaultOptionsGrpc, DirectPathOverInterconnectEnvVarFalseOverridesOption) { + ScopedEnvironment env("GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS_OVER_INTERCONNECT", + "false"); + auto mock_detector = std::make_shared(); + EXPECT_CALL(*mock_detector, IsGoogleCloudBios()) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*mock_detector, IsGoogleCloudServerless()) + .WillRepeatedly(Return(false)); + + auto options = DefaultOptionsGrpc( + Options{}.set( + true), + mock_detector); EXPECT_FALSE( options.get()); + EXPECT_EQ(options.get(), "storage.googleapis.com"); + EXPECT_EQ(options.get(), "storage.googleapis.com"); EXPECT_GE(options.get(), 4); } -TEST(DefaultOptionsGrpc, - DefaultEndpointsDirectPathOverInterconnectPreservesCustomAuthority) { +/// @test Verify unrecognized environment variable values are ignored and leave +/// the option as the application configured it. Each value is tried against +/// both an enabled and a disabled option, so that a case-insensitive match +/// (for example treating `"TRUE"` as `"true"`) would be detected. +TEST(DefaultOptionsGrpc, DirectPathOverInterconnectEnvVarInvalidValueIgnored) { + for (auto const* value : {"1", "0", "TRUE", "False", "yes", ""}) { + for (auto const configured : {false, true}) { + SCOPED_TRACE("Testing with value " + std::string(value) + + ", option configured as " + (configured ? "true" : "false")); + ScopedEnvironment env( + "GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS_OVER_INTERCONNECT", value); + auto mock_detector = std::make_shared(); + EXPECT_CALL(*mock_detector, IsGoogleCloudBios()) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*mock_detector, IsGoogleCloudServerless()) + .WillRepeatedly(Return(false)); + + auto options = DefaultOptionsGrpc( + Options{} + .set( + configured), + mock_detector); + EXPECT_EQ( + options + .get(), + configured); + EXPECT_EQ(options.get(), + configured + ? "google-c2p:///storage-direct.googleapis.com?force-xds" + : "storage.googleapis.com"); + } + } +} + +/// @test Verify a caller-supplied authority is preserved when the DirectPath +/// target is selected; `storage.googleapis.com` is only the default. +TEST(DefaultOptionsGrpc, DirectPathOverInterconnectPreservesCustomAuthority) { + ScopedEnvironment env("GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS_OVER_INTERCONNECT", + {}); auto mock_detector = std::make_shared(); EXPECT_CALL(*mock_detector, IsGoogleCloudBios()) .WillRepeatedly(Return(false)); @@ -221,8 +314,9 @@ TEST(DefaultOptionsGrpc, EXPECT_EQ(options.get(), 1); } -TEST(DefaultOptionsGrpc, - DefaultEndpointsDirectPathOverInterconnectUniverseDomainEnvVar) { +/// @test Verify universe domain precedence also holds when the domain comes +/// from `GOOGLE_CLOUD_UNIVERSE_DOMAIN` rather than an option. +TEST(DefaultOptionsGrpc, DirectPathOverInterconnectUniverseDomainEnvVar) { ScopedEnvironment ud("GOOGLE_CLOUD_UNIVERSE_DOMAIN", "my-ud.net"); auto mock_detector = std::make_shared(); EXPECT_CALL(*mock_detector, IsGoogleCloudBios()) From c672a0c94990d1d49fd97084a034ffe44e3d85c8 Mon Sep 17 00:00:00 2001 From: Gauri Kalra Date: Tue, 15 Sep 2026 10:23:34 +0000 Subject: [PATCH 4/4] Address reviewer feedback about env variable description --- google/cloud/storage/doc/environment-variables.dox | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/google/cloud/storage/doc/environment-variables.dox b/google/cloud/storage/doc/environment-variables.dox index 0d75a214c643a..93f782cc8be24 100644 --- a/google/cloud/storage/doc/environment-variables.dox +++ b/google/cloud/storage/doc/environment-variables.dox @@ -39,12 +39,12 @@ protocol, but currently unused. `GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS_OVER_INTERCONNECT=true`: attempt DirectPath over [Cloud Interconnect][interconnect-link]. This bypasses the usual GCE -environment detection, making DirectPath usable from on-premise hosts. Set to -`false` to disable the feature even when the corresponding option is enabled in -code. Only these exact values are recognized, and the comparison is -case-sensitive; any other value, such as `1` or `TRUE`, is treated as if the -variable were not set. This environment variable takes precedence over the -option. +environment detection, making DirectPath usable from on-premise hosts. Set it +to `true` to enable the feature. Set it to `false` to disable the feature even +when the corresponding option is enabled in code. Only these exact values are +recognized, and the comparison is case-sensitive; any other value, such as `1` +or `TRUE`, is treated as if the variable were not set. This environment +variable takes precedence over the option. @see google::cloud::storage_experimental::DirectPathXdsOverInterconnectOption