Skip to content

Commit f89d3a1

Browse files
authored
test(showcase): add integration tests for resumable upload (#14326)
Adds initial happy path integration tests in `ITResumableUpload.java` validating the generated Showcase client against a running GAPIC Showcase server.
1 parent f9ebd79 commit f89d3a1

2 files changed

Lines changed: 220 additions & 0 deletions

File tree

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
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+
* https://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.showcase.v1beta1.it;
18+
19+
import static com.google.common.truth.Truth.assertThat;
20+
21+
import com.google.api.gax.rpc.ResumableUploadCallSettings;
22+
import com.google.api.gax.rpc.ResumableUploadFuture;
23+
import com.google.showcase.v1beta1.ResumableUploadServiceClient;
24+
import com.google.showcase.v1beta1.UploadMediaRequest;
25+
import com.google.showcase.v1beta1.UploadMediaResponse;
26+
import com.google.showcase.v1beta1.it.util.TestClientInitializer;
27+
import java.io.IOException;
28+
import java.io.InputStream;
29+
import java.nio.charset.StandardCharsets;
30+
import java.nio.file.Files;
31+
import java.nio.file.Path;
32+
import java.util.concurrent.TimeUnit;
33+
import org.junit.jupiter.api.AfterAll;
34+
import org.junit.jupiter.api.BeforeAll;
35+
import org.junit.jupiter.api.Test;
36+
import org.junit.jupiter.api.io.TempDir;
37+
38+
/**
39+
* Integration tests for generated {@link ResumableUploadServiceClient} against the Showcase server.
40+
*/
41+
class ITResumableUpload {
42+
43+
private static final int SHOWCASE_CHUNK_SIZE = 256 * 1024; // 256KB
44+
private static ResumableUploadServiceClient client;
45+
46+
@BeforeAll
47+
static void createClients() throws Exception {
48+
client = TestClientInitializer.createHttpJsonResumableUploadClient(SHOWCASE_CHUNK_SIZE);
49+
}
50+
51+
@AfterAll
52+
static void destroyClients() throws InterruptedException {
53+
if (client != null) {
54+
client.close();
55+
client.awaitTermination(TestClientInitializer.AWAIT_TERMINATION_SECONDS, TimeUnit.SECONDS);
56+
}
57+
}
58+
59+
@Test
60+
void testGeneratedClient_uploadMedia_synchronousConvenienceMethod(@TempDir Path tempDir)
61+
throws Exception {
62+
Path file =
63+
createTempFile(
64+
tempDir,
65+
"it-client-sync.txt",
66+
"Hello from generated ResumableUploadServiceClient synchronous convenience method!"
67+
.getBytes(StandardCharsets.UTF_8));
68+
UploadMediaRequest request =
69+
UploadMediaRequest.newBuilder().setName("it-client-sync.txt").build();
70+
71+
try (InputStream stream = Files.newInputStream(file)) {
72+
UploadMediaResponse response = client.uploadMedia(request, stream, null);
73+
assertThat(response.getName()).isEqualTo("it-client-sync.txt");
74+
assertThat(response.getSize()).isEqualTo(Files.size(file));
75+
}
76+
}
77+
78+
@Test
79+
void testGeneratedClient_uploadMediaCallable_asynchronousFutureCall(@TempDir Path tempDir)
80+
throws Exception {
81+
Path file =
82+
createTempFile(
83+
tempDir,
84+
"it-client-callable.txt",
85+
"Hello from generated ResumableUploadServiceClient callable futureCall!"
86+
.getBytes(StandardCharsets.UTF_8));
87+
UploadMediaRequest request =
88+
UploadMediaRequest.newBuilder().setName("it-client-callable.txt").build();
89+
90+
try (InputStream stream = Files.newInputStream(file)) {
91+
ResumableUploadFuture<UploadMediaResponse> future =
92+
client
93+
.uploadMediaCallable()
94+
.futureCall(request, stream, (ResumableUploadCallSettings) null);
95+
96+
UploadMediaResponse response = future.get(10, TimeUnit.SECONDS);
97+
assertThat(future.isDone()).isTrue();
98+
assertThat(future.isCancelled()).isFalse();
99+
assertThat(future.getUploadSessionUrl()).isNotNull();
100+
assertThat(future.getUploadSessionUrl()).contains("/resumable/upload");
101+
assertThat(response.getName()).isEqualTo("it-client-callable.txt");
102+
assertThat(response.getSize()).isEqualTo(Files.size(file));
103+
}
104+
}
105+
106+
@Test
107+
void testGeneratedClient_multiChunkUpload(@TempDir Path tempDir) throws Exception {
108+
// 600KB payload = 2 full 256KB chunks + 1 partial 88KB chunk
109+
int totalBytes = 600 * 1024;
110+
Path file = createTempFile(tempDir, "it-client-multi-chunk.txt", totalBytes);
111+
UploadMediaRequest request =
112+
UploadMediaRequest.newBuilder().setName("it-client-multi-chunk.txt").build();
113+
114+
try (InputStream stream = Files.newInputStream(file)) {
115+
UploadMediaResponse response = client.uploadMedia(request, stream, null);
116+
assertThat(response.getName()).isEqualTo("it-client-multi-chunk.txt");
117+
assertThat(response.getSize()).isEqualTo(Files.size(file));
118+
}
119+
}
120+
121+
@Test
122+
void testGeneratedClient_grpcClientDelegation_uploadMedia(@TempDir Path tempDir)
123+
throws Exception {
124+
Path file =
125+
createTempFile(
126+
tempDir,
127+
"it-grpc-delegation.txt",
128+
"Hello from generated ResumableUploadServiceClient gRPC delegation!"
129+
.getBytes(StandardCharsets.UTF_8));
130+
UploadMediaRequest request =
131+
UploadMediaRequest.newBuilder().setName("it-grpc-delegation.txt").build();
132+
133+
try (ResumableUploadServiceClient grpcClient =
134+
TestClientInitializer.createGrpcResumableUploadClient(SHOWCASE_CHUNK_SIZE)) {
135+
try (InputStream stream = Files.newInputStream(file)) {
136+
UploadMediaResponse response = grpcClient.uploadMedia(request, stream, null);
137+
assertThat(response.getName()).isEqualTo("it-grpc-delegation.txt");
138+
assertThat(response.getSize()).isEqualTo(Files.size(file));
139+
}
140+
141+
try (InputStream stream = Files.newInputStream(file)) {
142+
ResumableUploadFuture<UploadMediaResponse> future =
143+
grpcClient
144+
.uploadMediaCallable()
145+
.futureCall(request, stream, (ResumableUploadCallSettings) null);
146+
UploadMediaResponse response = future.get(10, TimeUnit.SECONDS);
147+
assertThat(future.isDone()).isTrue();
148+
assertThat(future.isCancelled()).isFalse();
149+
assertThat(future.getUploadSessionUrl()).isNotNull();
150+
assertThat(future.getUploadSessionUrl()).contains("/resumable/upload");
151+
assertThat(response.getName()).isEqualTo("it-grpc-delegation.txt");
152+
assertThat(response.getSize()).isEqualTo(Files.size(file));
153+
}
154+
}
155+
}
156+
157+
@Test
158+
void testGeneratedClient_uploadMedia_withCustomCallSettings(@TempDir Path tempDir)
159+
throws Exception {
160+
// 600KB payload with custom per-call 512KB chunk size override (default is 256KB)
161+
int totalBytes = 600 * 1024;
162+
Path file = createTempFile(tempDir, "it-client-custom-call-settings.txt", totalBytes);
163+
UploadMediaRequest request =
164+
UploadMediaRequest.newBuilder().setName("it-client-custom-call-settings.txt").build();
165+
ResumableUploadCallSettings callSettings =
166+
ResumableUploadCallSettings.newBuilder().setChunkSize(512 * 1024).build();
167+
168+
try (InputStream stream = Files.newInputStream(file)) {
169+
UploadMediaResponse response = client.uploadMedia(request, stream, callSettings);
170+
assertThat(response.getName()).isEqualTo("it-client-custom-call-settings.txt");
171+
assertThat(response.getSize()).isEqualTo(Files.size(file));
172+
}
173+
}
174+
175+
private static Path createTempFile(Path dir, String fileName, byte[] data) throws IOException {
176+
Path path = dir.resolve(fileName);
177+
Files.write(path, data);
178+
return path;
179+
}
180+
181+
private static Path createTempFile(Path dir, String fileName, int size) throws IOException {
182+
byte[] data = new byte[size];
183+
for (int i = 0; i < size; i++) {
184+
data[i] = (byte) (i % 256);
185+
}
186+
return createTempFile(dir, fileName, data);
187+
}
188+
}

‎java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/util/TestClientInitializer.java‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
import com.google.showcase.v1beta1.EchoSettings;
3434
import com.google.showcase.v1beta1.IdentityClient;
3535
import com.google.showcase.v1beta1.IdentitySettings;
36+
import com.google.showcase.v1beta1.ResumableUploadServiceClient;
37+
import com.google.showcase.v1beta1.ResumableUploadServiceSettings;
3638
import com.google.showcase.v1beta1.SequenceServiceClient;
3739
import com.google.showcase.v1beta1.SequenceServiceSettings;
3840
import com.google.showcase.v1beta1.WaitRequest;
@@ -539,4 +541,34 @@ public static SequenceServiceClient createHttpJsonSequenceClientWithRetrySetting
539541
.build());
540542
return SequenceServiceClient.create(settingsBuilder.build());
541543
}
544+
545+
public static ResumableUploadServiceClient createHttpJsonResumableUploadClient(int chunkSize)
546+
throws Exception {
547+
ResumableUploadServiceSettings.Builder settingsBuilder =
548+
ResumableUploadServiceSettings.newHttpJsonBuilder();
549+
settingsBuilder
550+
.setCredentialsProvider(NoCredentialsProvider.create())
551+
.setTransportChannelProvider(
552+
ResumableUploadServiceSettings.defaultHttpJsonTransportProviderBuilder()
553+
.setHttpTransport(new NetHttpTransport.Builder().doNotValidateCertificate().build())
554+
.setEndpoint(DEFAULT_HTTPJSON_ENDPOINT)
555+
.build());
556+
settingsBuilder.uploadMediaSettings().setChunkSize(chunkSize);
557+
return ResumableUploadServiceClient.create(settingsBuilder.build());
558+
}
559+
560+
public static ResumableUploadServiceClient createGrpcResumableUploadClient(int chunkSize)
561+
throws Exception {
562+
ResumableUploadServiceSettings.Builder settingsBuilder =
563+
ResumableUploadServiceSettings.newBuilder()
564+
.setCredentialsProvider(NoCredentialsProvider.create())
565+
.setTransportChannelProvider(
566+
ResumableUploadServiceSettings.defaultGrpcTransportProviderBuilder()
567+
.setEndpoint(DEFAULT_GRPC_ENDPOINT)
568+
.setChannelConfigurator(ManagedChannelBuilder::usePlaintext)
569+
.build())
570+
.setEndpoint(DEFAULT_HTTPJSON_ENDPOINT);
571+
settingsBuilder.uploadMediaSettings().setChunkSize(chunkSize);
572+
return ResumableUploadServiceClient.create(settingsBuilder.build());
573+
}
542574
}

0 commit comments

Comments
 (0)