Use TestFixturesPlugin to Run Minio in Tests (#37852)
* Use TestFixturesPlugin to Run Minio in Tests * Closes #37680 * Closes #37783
This commit is contained in:
parent
a3baa8f5ef
commit
be6bdab346
|
@ -1,13 +1,10 @@
|
|||
import org.apache.tools.ant.taskdefs.condition.Os
|
||||
import org.elasticsearch.gradle.LoggedExec
|
||||
import org.elasticsearch.gradle.BuildPlugin
|
||||
import org.elasticsearch.gradle.MavenFilteringHack
|
||||
import org.elasticsearch.gradle.test.AntFixture
|
||||
import org.elasticsearch.gradle.test.ClusterConfiguration
|
||||
import org.elasticsearch.gradle.test.RestIntegTestTask
|
||||
import com.carrotsearch.gradle.junit4.RandomizedTestingTask
|
||||
|
||||
import java.lang.reflect.Field
|
||||
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
|
@ -139,25 +136,6 @@ if (!s3EC2Bucket && !s3EC2BasePath && !s3ECSBucket && !s3ECSBasePath) {
|
|||
throw new IllegalArgumentException("not all options specified to run EC2/ECS tests are present")
|
||||
}
|
||||
|
||||
|
||||
final String minioVersion = 'RELEASE.2018-06-22T23-48-46Z'
|
||||
final String minioBinDir = "${buildDir}/minio/bin"
|
||||
final String minioDataDir = "${buildDir}/minio/data"
|
||||
final String minioAddress = "127.0.0.1"
|
||||
|
||||
String minioDistribution
|
||||
String minioCheckSum
|
||||
if (Os.isFamily(Os.FAMILY_MAC)) {
|
||||
minioDistribution = 'darwin-amd64'
|
||||
minioCheckSum = '96b0bcb2f590e8e65fb83d5c3e221f9bd1106b49fa6f22c6b726b80b845d7c60'
|
||||
} else if (Os.isFamily(Os.FAMILY_UNIX)) {
|
||||
minioDistribution = 'linux-amd64'
|
||||
minioCheckSum = '713dac7c105285eab3b92649be92b5e793b29d3525c7929fa7aaed99374fad99'
|
||||
} else {
|
||||
minioDistribution = null
|
||||
minioCheckSum = null
|
||||
}
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
maven {
|
||||
|
@ -169,177 +147,39 @@ buildscript {
|
|||
}
|
||||
}
|
||||
|
||||
private static int freePort(String minioAddress) {
|
||||
int minioPort
|
||||
ServerSocket serverSocket = new ServerSocket(0, 1, InetAddress.getByName(minioAddress))
|
||||
try {
|
||||
minioPort = serverSocket.localPort
|
||||
} finally {
|
||||
serverSocket.close()
|
||||
}
|
||||
if (minioPort == 0) {
|
||||
throw new GradleException("Could not find a free port for Minio")
|
||||
}
|
||||
return minioPort
|
||||
}
|
||||
if (useFixture) {
|
||||
|
||||
private int getMinioPid(Process minioProcess) {
|
||||
int minioPid
|
||||
if (JavaVersion.current() <= JavaVersion.VERSION_1_8) {
|
||||
try {
|
||||
Class<?> cProcessImpl = minioProcess.getClass()
|
||||
Field fPid = cProcessImpl.getDeclaredField("pid")
|
||||
if (!fPid.isAccessible()) {
|
||||
fPid.setAccessible(true)
|
||||
}
|
||||
minioPid = fPid.getInt(minioProcess)
|
||||
} catch (Exception e) {
|
||||
logger.error("failed to read pid from minio process", e)
|
||||
minioProcess.destroyForcibly()
|
||||
throw e
|
||||
}
|
||||
} else {
|
||||
minioPid = minioProcess.pid()
|
||||
}
|
||||
return minioPid
|
||||
}
|
||||
|
||||
private static Process setupMinio(String minioAddress, int minioPort, String minioDataDir, String accessKey, String secretKey,
|
||||
String minioBinDir, String minioFileName) {
|
||||
// we skip these tests on Windows so we do no need to worry about compatibility here
|
||||
final ProcessBuilder minio = new ProcessBuilder(
|
||||
"${minioBinDir}/${minioFileName}",
|
||||
"server",
|
||||
"--address",
|
||||
minioAddress + ":" + minioPort,
|
||||
minioDataDir)
|
||||
minio.environment().put('MINIO_ACCESS_KEY', accessKey)
|
||||
minio.environment().put('MINIO_SECRET_KEY', secretKey)
|
||||
return minio.start()
|
||||
}
|
||||
|
||||
private void addShutdownHook(Process minioProcess, int minioPort, int minioPid) {
|
||||
new BufferedReader(new InputStreamReader(minioProcess.inputStream)).withReader { br ->
|
||||
String line
|
||||
int httpPort = 0
|
||||
while ((line = br.readLine()) != null) {
|
||||
logger.info(line)
|
||||
if (line.matches('.*Endpoint.*:\\d+$')) {
|
||||
assert httpPort == 0
|
||||
final int index = line.lastIndexOf(":")
|
||||
assert index >= 0
|
||||
httpPort = Integer.parseInt(line.substring(index + 1))
|
||||
if (httpPort != minioPort) {
|
||||
throw new IllegalStateException("Port mismatch, expected ${minioPort} but was ${httpPort}")
|
||||
}
|
||||
|
||||
final File script = new File(project.buildDir, "minio/minio.killer.sh")
|
||||
script.setText(
|
||||
["function shutdown {",
|
||||
" kill ${minioPid}",
|
||||
"}",
|
||||
"trap shutdown EXIT",
|
||||
// will wait indefinitely for input, but we never pass input, and the pipe is only closed when the build dies
|
||||
"read line\n"].join('\n'), 'UTF-8')
|
||||
final ProcessBuilder killer = new ProcessBuilder("bash", script.absolutePath)
|
||||
killer.start()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (httpPort <= 0) {
|
||||
throw new IllegalStateException("httpPort must be > 0")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (useFixture && minioDistribution) {
|
||||
apply plugin: 'de.undercouch.download'
|
||||
|
||||
final String minioFileName = "minio.${minioVersion}"
|
||||
final String minioDownloadURL = "https://dl.minio.io/server/minio/release/${minioDistribution}/archive/${minioFileName}"
|
||||
final String minioFilePath = "${gradle.gradleUserHomeDir}/downloads/minio/${minioDistribution}/${minioFileName}"
|
||||
|
||||
task downloadMinio(type: Download) {
|
||||
src minioDownloadURL
|
||||
dest minioFilePath
|
||||
onlyIfModified true
|
||||
}
|
||||
|
||||
task verifyMinioChecksum(type: Verify, dependsOn: downloadMinio) {
|
||||
src minioFilePath
|
||||
algorithm 'SHA-256'
|
||||
checksum minioCheckSum
|
||||
}
|
||||
|
||||
task installMinio(type: Sync, dependsOn: verifyMinioChecksum) {
|
||||
from minioFilePath
|
||||
into minioBinDir
|
||||
fileMode 0755
|
||||
}
|
||||
|
||||
task startMinio {
|
||||
dependsOn installMinio
|
||||
|
||||
ext.minioPid = 0L
|
||||
ext.minioPort = 0
|
||||
|
||||
doLast {
|
||||
new File("${minioDataDir}/${s3PermanentBucket}").mkdirs()
|
||||
|
||||
Exception accumulatedException = null
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
try {
|
||||
minioPort = freePort(minioAddress)
|
||||
final Process process =
|
||||
setupMinio(minioAddress, minioPort, minioDataDir, s3PermanentAccessKey, s3PermanentSecretKey, minioBinDir, minioFileName)
|
||||
minioPid = getMinioPid(process)
|
||||
addShutdownHook(process, minioPort, minioPid)
|
||||
break
|
||||
} catch (Exception e) {
|
||||
logger.error("Exception while trying to start Minio {}", e)
|
||||
if (accumulatedException == null) {
|
||||
accumulated = e
|
||||
} else {
|
||||
accumulatedException.addSuppressed(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (accumulatedException != null) {
|
||||
throw new GradleException("Failed to start Minio", accumulatedException)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task stopMinio(type: LoggedExec) {
|
||||
onlyIf { startMinio.minioPid > 0 }
|
||||
|
||||
doFirst {
|
||||
logger.info("Shutting down minio with pid ${startMinio.minioPid}")
|
||||
}
|
||||
|
||||
final Object pid = "${ -> startMinio.minioPid }"
|
||||
|
||||
// we skip these tests on Windows so we do no need to worry about compatibility here
|
||||
executable = 'kill'
|
||||
args('-9', pid)
|
||||
}
|
||||
apply plugin: 'elasticsearch.test.fixtures'
|
||||
|
||||
RestIntegTestTask integTestMinio = project.tasks.create('integTestMinio', RestIntegTestTask.class) {
|
||||
description = "Runs REST tests using the Minio repository."
|
||||
}
|
||||
|
||||
Task writeDockerFile = project.tasks.create('writeDockerFile') {
|
||||
File minioDockerfile = new File("${project.buildDir}/minio-docker/Dockerfile")
|
||||
outputs.file(minioDockerfile)
|
||||
doLast {
|
||||
minioDockerfile.parentFile.mkdirs()
|
||||
minioDockerfile.text = "FROM minio/minio:RELEASE.2019-01-23T23-18-58Z\n" +
|
||||
"RUN mkdir -p /minio/data/${s3PermanentBucket}\n" +
|
||||
"ENV MINIO_ACCESS_KEY ${s3PermanentAccessKey}\n" +
|
||||
"ENV MINIO_SECRET_KEY ${s3PermanentSecretKey}"
|
||||
}
|
||||
}
|
||||
|
||||
preProcessFixture.dependsOn(writeDockerFile)
|
||||
// The following closure must execute before the afterEvaluate block in the constructor of the following integrationTest tasks:
|
||||
project.afterEvaluate {
|
||||
ClusterConfiguration cluster = project.extensions.getByName('integTestMinioCluster') as ClusterConfiguration
|
||||
cluster.dependsOn(project.bundlePlugin)
|
||||
cluster.dependsOn(startMinio) // otherwise we don't know the Minio port
|
||||
cluster.dependsOn(postProcessFixture)
|
||||
cluster.keystoreSetting 's3.client.integration_test_permanent.access_key', s3PermanentAccessKey
|
||||
cluster.keystoreSetting 's3.client.integration_test_permanent.secret_key', s3PermanentSecretKey
|
||||
|
||||
Closure<String> minioAddressAndPort = {
|
||||
assert startMinio.minioPort > 0
|
||||
return 'http://' + minioAddress + ':' + startMinio.minioPort
|
||||
int minioPort = postProcessFixture.ext."test.fixtures.minio-fixture.tcp.9000"
|
||||
assert minioPort > 0
|
||||
return 'http://127.0.0.1:' + minioPort
|
||||
}
|
||||
cluster.setting 's3.client.integration_test_permanent.endpoint', "${ -> minioAddressAndPort.call()}"
|
||||
|
||||
|
@ -354,8 +194,7 @@ if (useFixture && minioDistribution) {
|
|||
restIntegTestTask.clusterConfig.jvmArgs = jvmArgs
|
||||
}
|
||||
|
||||
integTestMinioRunner.dependsOn(startMinio)
|
||||
integTestMinioRunner.finalizedBy(stopMinio)
|
||||
integTestMinioRunner.dependsOn(postProcessFixture)
|
||||
// Minio only supports a single access key, see https://github.com/minio/minio/pull/5968
|
||||
integTestMinioRunner.systemProperty 'tests.rest.blacklist', [
|
||||
'repository_s3/30_repository_temporary_credentials/*',
|
||||
|
@ -364,6 +203,7 @@ if (useFixture && minioDistribution) {
|
|||
].join(",")
|
||||
|
||||
project.check.dependsOn(integTestMinio)
|
||||
BuildPlugin.requireDocker(integTestMinio)
|
||||
}
|
||||
|
||||
File parentFixtures = new File(project.buildDir, "fixtures")
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
version: '3'
|
||||
services:
|
||||
minio-fixture:
|
||||
build:
|
||||
context: ./build/minio-docker
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "9000"
|
||||
command: ["server", "/minio/data"]
|
Loading…
Reference in New Issue