Fix the GCP integration tests

This commit is contained in:
dzou
2020-05-26 16:27:24 -04:00
committed by Oleg Zhurakousky
parent 7c8ba881c9
commit 1462a1e8eb
3 changed files with 149 additions and 59 deletions

View File

@@ -16,77 +16,23 @@
package com.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.boot.test.web.client.TestRestTemplate;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class FunctionSampleGcpIntegrationTest {
private TestRestTemplate rest = new TestRestTemplate();
private CountDownLatch startedSuccessfully = new CountDownLatch(1);
@Test
@Ignore
public void testSample() throws IOException {
Process process = new ProcessBuilder("./../../mvnw", "function:run").start();
try {
Executors.defaultThreadFactory().newThread(new OutputCapture(process.getErrorStream())).start();
Executors.defaultThreadFactory().newThread(new OutputCapture(process.getInputStream())).start();
if (startedSuccessfully.await(10, TimeUnit.SECONDS)) {
String result = rest.postForObject("http://localhost:8080/", "Hello", String.class);
assertThat(result).isEqualTo("\"HELLO\"");
}
else {
fail("Failed to start the function.");
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
finally {
process.destroy();
public void testSample() throws IOException, InterruptedException {
try (LocalServerTestSupport.ServerProcess process = LocalServerTestSupport.startServer(CloudFunctionMain.class)) {
String result = rest.postForObject("http://localhost:8080/", "Hello", String.class);
assertThat(result).isEqualTo("\"HELLO\"");
}
}
class OutputCapture implements Runnable {
private InputStream inputStream;
OutputCapture(InputStream inputStream) {
this.inputStream = inputStream;
}
@Override
public void run() {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
if (line.equals("INFO: URL: http://localhost:8080/")) {
startedSuccessfully.countDown();
}
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,139 @@
/*
* Copyright 2020-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example;
import java.io.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import com.google.cloud.functions.invoker.runner.Invoker;
import org.springframework.cloud.function.adapter.gcp.GcfJarLauncher;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Test support class for running tests on the local Cloud Function server.
*
* @author Daniel Zou
* @author Mike Eltsufin
*/
final public class LocalServerTestSupport {
private static final ExecutorService EXECUTOR = Executors.newCachedThreadPool();
private static final String SERVER_READY_STRING = "Started ServerConnector";
private static AtomicInteger nextPort = new AtomicInteger(8080);
private LocalServerTestSupport() {
}
public static ServerProcess startServer(Class<?> springApplicationMainClass)
throws InterruptedException, IOException {
// Get the Java class path.
String myClassPath = System.getProperty("java.class.path");
assertThat(myClassPath).isNotNull();
// Setup the Java Process command line string
List<String> command = Arrays.asList(getJavaCommand(), "-classpath", myClassPath, Invoker.class.getName());
ProcessBuilder processBuilder = new ProcessBuilder().command(command).redirectErrorStream(true);
// Set environment variables.
Map<String, String> environment = new HashMap<>();
environment.put("PORT", String.valueOf(nextPort.getAndIncrement()));
environment.put("K_SERVICE", "test-function");
environment.put("FUNCTION_SIGNATURE_TYPE", "http");
environment.put("FUNCTION_TARGET", GcfJarLauncher.class.getCanonicalName());
environment.put("MAIN_CLASS", springApplicationMainClass.getCanonicalName());
processBuilder.environment().putAll(environment);
// Start the process and monitor the output logs in a separate thread.
// Once the SERVER_READY_STRING is found in the logs, we know we are ready.
Process serverProcess = processBuilder.start();
CountDownLatch ready = new CountDownLatch(1);
EXECUTOR.submit(() -> monitorOutput(serverProcess.getInputStream(), ready));
boolean serverReady = ready.await(5, TimeUnit.SECONDS);
if (!serverReady) {
serverProcess.destroy();
throw new AssertionError("Server never became ready");
}
return new ServerProcess(serverProcess);
}
private static void monitorOutput(InputStream processOutput, CountDownLatch ready) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(processOutput))) {
String line;
while ((line = reader.readLine()) != null) {
if (line.contains(SERVER_READY_STRING)) {
ready.countDown();
}
System.out.println(line);
if (line.contains("WARNING")) {
throw new AssertionError("Found warning in server output:\n" + line);
}
}
}
catch (IOException e) {
throw new UncheckedIOException(e);
}
}
/**
* Returns the path to the java executable.
*/
private static String getJavaCommand() {
File javaHome = new File(System.getProperty("java.home"));
assertThat(javaHome.exists()).isTrue();
File javaBin = new File(javaHome, "bin");
File javaCommand = new File(javaBin, "java");
assertThat(javaCommand.exists()).isTrue();
return javaCommand.toString();
}
static class ServerProcess implements AutoCloseable {
private final Process process;
ServerProcess(Process process) {
this.process = process;
}
Process process() {
return process;
}
@Override
public void close() {
process().destroy();
}
}
}