Skip to content

Commit abb0825

Browse files
committed
test(gax-grpc, storage): add additional unit and integration tests for DirectPath and custom URI validation
Adds coverage for custom URI validation, interconnect fallback without directpath, and interconnect fallback on non-GDU universes. Restores integration test for interconnect under a standalone test runner. [Generated-by: AI]
1 parent ff83eb4 commit abb0825

3 files changed

Lines changed: 143 additions & 23 deletions

File tree

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright 2026 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud.storage.it;
18+
19+
import static org.junit.Assume.assumeTrue;
20+
21+
import com.google.cloud.storage.Storage;
22+
import com.google.cloud.storage.StorageOptions;
23+
import com.google.cloud.storage.TransportCompatibility.Transport;
24+
import com.google.cloud.storage.it.runner.StorageITRunner;
25+
import com.google.cloud.storage.it.runner.annotations.Backend;
26+
import com.google.cloud.storage.it.runner.annotations.Inject;
27+
import com.google.cloud.storage.it.runner.annotations.SingleBackend;
28+
import com.google.cloud.storage.it.runner.annotations.StorageFixture;
29+
import org.junit.Test;
30+
import org.junit.runner.RunWith;
31+
32+
@RunWith(StorageITRunner.class)
33+
@SingleBackend(Backend.PROD)
34+
public final class ITGrpcDirectPathTest {
35+
36+
@Inject
37+
@StorageFixture(Transport.GRPC)
38+
public Storage storage;
39+
40+
@Test
41+
public void clientShouldWork_directPathXdsOverInterconnect() throws Exception {
42+
assumeTrue(
43+
"Environment cannot resolve storage-direct.googleapis.com", canResolveDirectPathAddress());
44+
StorageOptions options =
45+
StorageOptions.grpc()
46+
.setCredentials(storage.getOptions().getCredentials())
47+
.setAttemptDirectPathXdsOverInterconnect(true)
48+
.setEnableGrpcClientMetrics(false)
49+
.build();
50+
try (Storage client = options.getService()) {
51+
client.list(Storage.BucketListOption.pageSize(1));
52+
}
53+
}
54+
55+
private static boolean canResolveDirectPathAddress() {
56+
try {
57+
java.net.InetAddress.getAllByName("storage-direct.googleapis.com");
58+
return true;
59+
} catch (java.net.UnknownHostException e) {
60+
return false;
61+
}
62+
}
63+
}

java-storage/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITStorageOptionsTest.java

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -95,20 +95,6 @@ public void clientShouldConstructCleanly_directPathXdsOverInterconnect() throws
9595
doTest(options);
9696
}
9797

98-
@Test
99-
public void clientShouldWork_directPathXdsOverInterconnect() throws Exception {
100-
assumeTrue(
101-
"Environment cannot resolve storage-direct.googleapis.com", canResolveDirectPathAddress());
102-
StorageOptions options =
103-
StorageOptions.grpc()
104-
.setCredentials(credentials)
105-
.setAttemptDirectPathXdsOverInterconnect(true)
106-
.setEnableGrpcClientMetrics(false)
107-
.build();
108-
try (Storage storage = options.getService()) {
109-
storage.list(Storage.BucketListOption.pageSize(1));
110-
}
111-
}
11298

11399
@Test
114100
public void lackOfProjectIdDoesNotPreventConstruction_http() throws Exception {
@@ -131,13 +117,5 @@ private static void doTest(StorageOptions options) throws Exception {
131117
//noinspection EmptyTryBlock
132118
try (Storage ignore = options.getService()) {}
133119
}
134-
135-
private static boolean canResolveDirectPathAddress() {
136-
try {
137-
java.net.InetAddress.getAllByName("storage-direct.googleapis.com");
138-
return true;
139-
} catch (java.net.UnknownHostException e) {
140-
return false;
141-
}
142-
}
143120
}
121+

sdk-platform-java/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,6 +1741,85 @@ void testLogDirectPathMisconfigDirectPathSetXdsNotSet() throws Exception {
17411741
InstantiatingGrpcChannelProvider.LOG.removeHandler(logHandler);
17421742
}
17431743

1744+
@Test
1745+
void validateEndpoint_invalidCustomUri_throws() {
1746+
InstantiatingGrpcChannelProvider.Builder builder =
1747+
InstantiatingGrpcChannelProvider.newBuilder()
1748+
.setCertificateBasedAccess(certificateBasedAccess)
1749+
.setExecutor(mock(Executor.class))
1750+
.setHeaderProvider(mock(HeaderProvider.class, withSettings().withoutAnnotations()));
1751+
1752+
IllegalArgumentException exception =
1753+
assertThrows(
1754+
IllegalArgumentException.class,
1755+
() -> builder.setEndpoint("google-c2p:///invalid uri with spaces"));
1756+
assertThat(exception.getMessage()).contains("invalid endpoint URI:");
1757+
}
1758+
1759+
@Test
1760+
void canUseDirectPath_interconnectEnabledButDirectPathDisabled_fallsBackToCloudPath()
1761+
throws Exception {
1762+
FakeLogHandler logHandler = new FakeLogHandler();
1763+
InstantiatingGrpcChannelProvider.LOG.setLevel(Level.FINE);
1764+
InstantiatingGrpcChannelProvider.LOG.addHandler(logHandler);
1765+
1766+
EnvironmentProvider envProvider =
1767+
mock(EnvironmentProvider.class, withSettings().withoutAnnotations());
1768+
when(envProvider.getenv(InstantiatingGrpcChannelProvider.DIRECT_PATH_ENV_DISABLE_DIRECT_PATH))
1769+
.thenReturn("false");
1770+
1771+
InstantiatingGrpcChannelProvider provider =
1772+
InstantiatingGrpcChannelProvider.newBuilder()
1773+
.setAttemptDirectPath(false)
1774+
.setAttemptDirectPathXdsOverInterconnect(true)
1775+
.setHeaderProvider(mock(HeaderProvider.class, withSettings().withoutAnnotations()))
1776+
.setExecutor(mock(Executor.class))
1777+
.setEndpoint(DEFAULT_ENDPOINT)
1778+
.setCertificateBasedAccess(certificateBasedAccess)
1779+
.setEnvProvider(envProvider)
1780+
.build();
1781+
1782+
TransportChannel transportChannel = provider.getTransportChannel();
1783+
transportChannel.close();
1784+
transportChannel.awaitTermination(10, TimeUnit.SECONDS);
1785+
1786+
assertThat(logHandler.getAllMessages())
1787+
.contains("DirectPath was requested but is not available. Falling back to CloudPath.");
1788+
InstantiatingGrpcChannelProvider.LOG.removeHandler(logHandler);
1789+
}
1790+
1791+
@Test
1792+
void canUseDirectPath_interconnectAndDirectPathEnabledButNonGduUniverse_fallsBackToCloudPath()
1793+
throws Exception {
1794+
FakeLogHandler logHandler = new FakeLogHandler();
1795+
InstantiatingGrpcChannelProvider.LOG.setLevel(Level.FINE);
1796+
InstantiatingGrpcChannelProvider.LOG.addHandler(logHandler);
1797+
1798+
EnvironmentProvider envProvider =
1799+
mock(EnvironmentProvider.class, withSettings().withoutAnnotations());
1800+
when(envProvider.getenv(InstantiatingGrpcChannelProvider.DIRECT_PATH_ENV_DISABLE_DIRECT_PATH))
1801+
.thenReturn("false");
1802+
1803+
InstantiatingGrpcChannelProvider provider =
1804+
InstantiatingGrpcChannelProvider.newBuilder()
1805+
.setAttemptDirectPath(true)
1806+
.setAttemptDirectPathXdsOverInterconnect(true)
1807+
.setHeaderProvider(mock(HeaderProvider.class, withSettings().withoutAnnotations()))
1808+
.setExecutor(mock(Executor.class))
1809+
.setEndpoint("storage-direct.some-other-universe.com:443")
1810+
.setCertificateBasedAccess(certificateBasedAccess)
1811+
.setEnvProvider(envProvider)
1812+
.build();
1813+
1814+
TransportChannel transportChannel = provider.getTransportChannel();
1815+
transportChannel.close();
1816+
transportChannel.awaitTermination(10, TimeUnit.SECONDS);
1817+
1818+
assertThat(logHandler.getAllMessages())
1819+
.contains("DirectPath was requested but is not available. Falling back to CloudPath.");
1820+
InstantiatingGrpcChannelProvider.LOG.removeHandler(logHandler);
1821+
}
1822+
17441823
private static class FakeLogHandler extends Handler {
17451824

17461825
List<LogRecord> records = new ArrayList<>();

0 commit comments

Comments
 (0)