Fix the GCP integration tests
This commit is contained in:
@@ -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.endsWith("URL: http://localhost:8080/")) {
|
||||
startedSuccessfully.countDown();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user