Skip to content

Commit 9e590dc

Browse files
committed
add debug logs
1 parent 785c01f commit 9e590dc

1 file changed

Lines changed: 69 additions & 30 deletions

File tree

  • java-storage/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry

java-storage/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/TestBench.java

Lines changed: 69 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -115,7 +115,7 @@ private TestBench(
115115
String dockerImageName,
116116
String dockerImageTag,
117117
String containerName) {
118-
this.ignorePullError = true;
118+
this.ignorePullError = ignorePullError;
119119
this.baseUri = baseUri;
120120
this.gRPCBaseUri = gRPCBaseUri;
121121
this.dockerImageName = dockerImageName;
@@ -133,6 +133,10 @@ private TestBench(
133133
.getHeaders()
134134
.setUserAgent(
135135
String.format(Locale.US, "%s/ test-bench/", this.containerName));
136+
137+
// ADDED: Prevent client-side infinite hangs if the server is unresponsive
138+
request.setConnectTimeout(15000);
139+
request.setReadTimeout(15000);
136140
});
137141
}
138142

@@ -210,19 +214,27 @@ public void start() {
210214
// expected when the server isn't running already
211215
}
212216
try {
213-
tempDirectory = Files.createTempDirectory(containerName);
214-
outPath = tempDirectory.resolve("stdout");
215-
errPath = tempDirectory.resolve("stderr");
217+
// ADDED: Route logs to Bazel/Sponge artifact directories so Test Fusion can see them
218+
String bazelOutputDir = System.getenv("TEST_UNDECLARED_OUTPUTS_DIR");
219+
Path baseArtifactDir;
220+
if (bazelOutputDir != null && !bazelOutputDir.isEmpty()) {
221+
baseArtifactDir = java.nio.file.Paths.get(bazelOutputDir);
222+
} else {
223+
baseArtifactDir = java.nio.file.Paths.get("target", "testbench-logs");
224+
}
225+
226+
tempDirectory = baseArtifactDir.resolve(containerName);
227+
Files.createDirectories(tempDirectory);
228+
outPath = tempDirectory.resolve("gunicorn-stdout.log");
229+
errPath = tempDirectory.resolve("gunicorn-stderr.log");
216230

217231
File outFile = outPath.toFile();
218232
File errFile = errPath.toFile();
219-
LOGGER.info("Redirecting server stdout to: {}", outFile.getAbsolutePath());
220-
LOGGER.info("Redirecting server stderr to: {}", errFile.getAbsolutePath());
233+
LOGGER.info("Redirecting server stdout to artifact: {}", outFile.getAbsolutePath());
234+
LOGGER.info("Redirecting server stderr to artifact: {}", errFile.getAbsolutePath());
235+
221236
String dockerImage = String.format(Locale.US, "%s:%s", dockerImageName, dockerImageTag);
222-
// First try and pull the docker image, this validates docker is available and running
223-
// on the host, as well as gives time for the image to be downloaded independently of
224-
// trying to start the container. (Below, when we first start the container we then attempt
225-
// to issue a call against the api before we yield to run our tests.)
237+
// First try and pull the docker image
226238
try {
227239
Process p =
228240
new ProcessBuilder()
@@ -248,6 +260,8 @@ public void start() {
248260

249261
int port = URI.create(baseUri).getPort();
250262
int gRPCPort = URI.create(gRPCBaseUri).getPort();
263+
264+
// ADDED: gthread, 40 threads, and debug logging
251265
final List<String> command =
252266
ImmutableList.of(
253267
"docker",
@@ -263,20 +277,34 @@ public void start() {
263277
"gunicorn",
264278
"--bind=0.0.0.0:9000",
265279
"--worker-class=gthread",
266-
"--threads=10",
280+
"--threads=40",
267281
"--access-logfile=-",
282+
"--error-logfile=-",
283+
"--log-level=debug",
268284
"--keep-alive=0",
269285
"testbench:run()");
286+
270287
process =
271288
new ProcessBuilder()
272289
.command(command)
273290
.redirectOutput(outFile)
274291
.redirectError(errFile)
275292
.start();
276293
LOGGER.info(command.toString());
294+
277295
try {
278296
// wait a small amount of time for the server to come up before probing
279297
Thread.sleep(500);
298+
299+
// ADDED: Fail fast if container crashed due to port collision
300+
if (!process.isAlive()) {
301+
dumpServerLogs(outPath, errPath);
302+
throw new IllegalStateException(
303+
"TestBench Docker container died immediately. Exit code: "
304+
+ process.exitValue()
305+
+ ". Probable port collision.");
306+
}
307+
280308
// wait for the server to come up
281309
List<RetryTestResource> existingResources =
282310
runWithRetries(
@@ -370,13 +398,16 @@ public boolean shouldRetry(Throwable previousThrowable, List<?> previousResponse
370398
}
371399
},
372400
NanoClock.getDefaultClock());
373-
try {
374-
Files.delete(errPath);
375-
Files.delete(outPath);
376-
Files.delete(tempDirectory);
377-
} catch (IOException e) {
378-
throw new RuntimeException(e);
379-
}
401+
402+
// ADDED: Commented out file deletion so Test Fusion can preserve artifacts
403+
// try {
404+
// Files.delete(errPath);
405+
// Files.delete(outPath);
406+
// Files.delete(tempDirectory);
407+
// } catch (IOException e) {
408+
// throw new RuntimeException(e);
409+
// }
410+
LOGGER.info("Skipping artifact deletion to preserve logs for Test Fusion.");
380411
} catch (InterruptedException | IOException e) {
381412
throw new RuntimeException(e);
382413
}
@@ -393,6 +424,7 @@ private void dumpServerLogs(Path outFile, Path errFile) throws IOException {
393424
}
394425

395426
private void dumpServerLog(String prefix, File out) throws IOException {
427+
if (!out.exists()) return;
396428
try (BufferedReader reader = new BufferedReader(new FileReader(out))) {
397429
String line;
398430
while ((line = reader.readLine()) != null) {
@@ -401,9 +433,11 @@ private void dumpServerLog(String prefix, File out) throws IOException {
401433
}
402434
}
403435

436+
// ADDED: Fixed findFreePort to properly apply setReuseAddress
404437
private static int findFreePort() {
405-
try (java.net.ServerSocket socket = new java.net.ServerSocket(0)) {
438+
try (java.net.ServerSocket socket = new java.net.ServerSocket()) {
406439
socket.setReuseAddress(true);
440+
socket.bind(new java.net.InetSocketAddress(0));
407441
return socket.getLocalPort();
408442
} catch (java.io.IOException e) {
409443
throw new RuntimeException("Failed to find a free port", e);
@@ -503,17 +537,15 @@ static final class Builder {
503537
private String dockerImageTag;
504538
private String containerName;
505539

540+
// ADDED: Refactored constructor to prevent uninitialized variables
506541
private Builder() {
507-
int httpPort = findFreePort();
508-
int grpcPort = findFreePort();
509-
String uuid = java.util.UUID.randomUUID().toString().substring(0, 8);
510-
511-
this.ignorePullError = false;
512-
this.baseUri = "http://127.0.0.1:" + httpPort;
513-
this.gRPCBaseUri = "http://127.0.0.1:" + grpcPort;
514-
this.dockerImageName = DEFAULT_IMAGE_NAME;
515-
this.dockerImageTag = DEFAULT_IMAGE_TAG;
516-
this.containerName = DEFAULT_CONTAINER_NAME + "_" + uuid;
542+
this(
543+
false,
544+
"http://127.0.0.1:" + findFreePort(),
545+
"http://127.0.0.1:" + findFreePort(),
546+
DEFAULT_IMAGE_NAME,
547+
DEFAULT_IMAGE_TAG,
548+
DEFAULT_CONTAINER_NAME + "_" + java.util.UUID.randomUUID().toString().substring(0, 8));
517549
}
518550

519551
private Builder(
@@ -529,6 +561,13 @@ private Builder(
529561
this.dockerImageName = dockerImageName;
530562
this.dockerImageTag = dockerImageTag;
531563
this.containerName = containerName;
564+
565+
// ADDED: Trace logging for port assignments to verify collisions in CI
566+
LOGGER.info(
567+
"DEBUG-BUILDER: Initialized testbench config -> Container: {}, HTTP: {}, GRPC: {}",
568+
containerName,
569+
baseUri,
570+
gRPCBaseUri);
532571
}
533572

534573
public Builder setIgnorePullError(boolean ignorePullError) {

0 commit comments

Comments
 (0)