Skip to content

Commit 4b6678f

Browse files
Use TestFixturesPlugin to Run Minio in Tests (#37852) (#37983)
* Use TestFixturesPlugin to Run Minio in Tests * Closes #37680 * Closes #37783
1 parent cfa6801 commit 4b6678f

File tree

2 files changed

+49
-159
lines changed

2 files changed

+49
-159
lines changed

plugins/repository-s3/build.gradle

Lines changed: 40 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
import org.apache.tools.ant.taskdefs.condition.Os
2-
import org.elasticsearch.gradle.LoggedExec
1+
import org.elasticsearch.gradle.BuildPlugin
32
import org.elasticsearch.gradle.MavenFilteringHack
43
import org.elasticsearch.gradle.test.AntFixture
54
import org.elasticsearch.gradle.test.ClusterConfiguration
65
import org.elasticsearch.gradle.test.RestIntegTestTask
76
import com.carrotsearch.gradle.junit4.RandomizedTestingTask
87

9-
import java.lang.reflect.Field
10-
118
/*
129
* Licensed to Elasticsearch under one or more contributor
1310
* license agreements. See the NOTICE file distributed with
@@ -139,25 +136,6 @@ if (!s3EC2Bucket && !s3EC2BasePath && !s3ECSBucket && !s3ECSBasePath) {
139136
throw new IllegalArgumentException("not all options specified to run EC2/ECS tests are present")
140137
}
141138

142-
143-
final String minioVersion = 'RELEASE.2018-06-22T23-48-46Z'
144-
final String minioBinDir = "${buildDir}/minio/bin"
145-
final String minioDataDir = "${buildDir}/minio/data"
146-
final String minioAddress = "127.0.0.1"
147-
148-
String minioDistribution
149-
String minioCheckSum
150-
if (Os.isFamily(Os.FAMILY_MAC)) {
151-
minioDistribution = 'darwin-amd64'
152-
minioCheckSum = '96b0bcb2f590e8e65fb83d5c3e221f9bd1106b49fa6f22c6b726b80b845d7c60'
153-
} else if (Os.isFamily(Os.FAMILY_UNIX)) {
154-
minioDistribution = 'linux-amd64'
155-
minioCheckSum = '713dac7c105285eab3b92649be92b5e793b29d3525c7929fa7aaed99374fad99'
156-
} else {
157-
minioDistribution = null
158-
minioCheckSum = null
159-
}
160-
161139
buildscript {
162140
repositories {
163141
maven {
@@ -169,164 +147,67 @@ buildscript {
169147
}
170148
}
171149

172-
if (useFixture && minioDistribution) {
173-
apply plugin: 'de.undercouch.download'
174-
175-
final String minioFileName = "minio.${minioVersion}"
176-
final String minioDownloadURL = "https://dl.minio.io/server/minio/release/${minioDistribution}/archive/${minioFileName}"
177-
final String minioFilePath = "${gradle.gradleUserHomeDir}/downloads/minio/${minioDistribution}/${minioFileName}"
178-
179-
task downloadMinio(type: Download) {
180-
src minioDownloadURL
181-
dest minioFilePath
182-
onlyIfModified true
183-
}
150+
if (useFixture) {
184151

185-
task verifyMinioChecksum(type: Verify, dependsOn: downloadMinio) {
186-
src minioFilePath
187-
algorithm 'SHA-256'
188-
checksum minioCheckSum
189-
}
152+
apply plugin: 'elasticsearch.test.fixtures'
190153

191-
task installMinio(type: Sync, dependsOn: verifyMinioChecksum) {
192-
from minioFilePath
193-
into minioBinDir
194-
fileMode 0755
154+
RestIntegTestTask integTestMinio = project.tasks.create('integTestMinio', RestIntegTestTask.class) {
155+
description = "Runs REST tests using the Minio repository."
195156
}
196157

197-
task startMinio {
198-
dependsOn installMinio
199-
200-
ext.minioPid = 0L
201-
ext.minioPort = 0
202-
158+
Task writeDockerFile = project.tasks.create('writeDockerFile') {
159+
File minioDockerfile = new File("${project.buildDir}/minio-docker/Dockerfile")
160+
outputs.file(minioDockerfile)
203161
doLast {
204-
// get free port
205-
for (int port = 60920; port < 60940; port++) {
206-
try {
207-
javax.net.ServerSocketFactory.getDefault().createServerSocket(port, 1, InetAddress.getByName(minioAddress)).close()
208-
minioPort = port
209-
break
210-
} catch (BindException e) {
211-
logger.info("Port " + port + " for Minio process is already taken", e)
212-
}
213-
}
214-
if (minioPort == 0) {
215-
throw new GradleException("Could not find a free port for Minio")
216-
}
217-
218-
new File("${minioDataDir}/${s3PermanentBucket}").mkdirs()
219-
// we skip these tests on Windows so we do no need to worry about compatibility here
220-
final ProcessBuilder minio = new ProcessBuilder(
221-
"${minioBinDir}/${minioFileName}",
222-
"server",
223-
"--address",
224-
minioAddress + ":" + minioPort,
225-
minioDataDir)
226-
minio.environment().put('MINIO_ACCESS_KEY', s3PermanentAccessKey)
227-
minio.environment().put('MINIO_SECRET_KEY', s3PermanentSecretKey)
228-
final Process process = minio.start()
229-
if (JavaVersion.current() <= JavaVersion.VERSION_1_8) {
230-
try {
231-
Class<?> cProcessImpl = process.getClass()
232-
Field fPid = cProcessImpl.getDeclaredField("pid")
233-
if (!fPid.isAccessible()) {
234-
fPid.setAccessible(true)
235-
}
236-
minioPid = fPid.getInt(process)
237-
} catch (Exception e) {
238-
logger.error("failed to read pid from minio process", e)
239-
process.destroyForcibly()
240-
throw e
241-
}
242-
} else {
243-
minioPid = process.pid()
244-
}
245-
246-
new BufferedReader(new InputStreamReader(process.getInputStream())).withReader { br ->
247-
String line
248-
int httpPort = 0
249-
while ((line = br.readLine()) != null) {
250-
logger.info(line)
251-
if (line.matches('.*Endpoint.*:\\d+$')) {
252-
assert httpPort == 0
253-
final int index = line.lastIndexOf(":")
254-
assert index >= 0
255-
httpPort = Integer.parseInt(line.substring(index + 1))
256-
assert httpPort == minioPort : "Port mismatch, expected ${minioPort} but was ${httpPort}"
257-
258-
final File script = new File(project.buildDir, "minio/minio.killer.sh")
259-
script.setText(
260-
["function shutdown {",
261-
" kill ${minioPid}",
262-
"}",
263-
"trap shutdown EXIT",
264-
// will wait indefinitely for input, but we never pass input, and the pipe is only closed when the build dies
265-
"read line\n"].join('\n'), 'UTF-8')
266-
final ProcessBuilder killer = new ProcessBuilder("bash", script.absolutePath)
267-
killer.start()
268-
break
269-
}
270-
}
271-
272-
assert httpPort > 0
273-
}
162+
minioDockerfile.parentFile.mkdirs()
163+
minioDockerfile.text = "FROM minio/minio:RELEASE.2019-01-23T23-18-58Z\n" +
164+
"RUN mkdir -p /minio/data/${s3PermanentBucket}\n" +
165+
"ENV MINIO_ACCESS_KEY ${s3PermanentAccessKey}\n" +
166+
"ENV MINIO_SECRET_KEY ${s3PermanentSecretKey}"
274167
}
275168
}
276169

277-
task stopMinio(type: LoggedExec) {
278-
onlyIf { startMinio.minioPid > 0 }
279-
280-
doFirst {
281-
logger.info("Shutting down minio with pid ${startMinio.minioPid}")
282-
}
283-
284-
final Object pid = "${ -> startMinio.minioPid }"
285-
286-
// we skip these tests on Windows so we do no need to worry about compatibility here
287-
executable = 'kill'
288-
args('-9', pid)
289-
}
290-
291-
RestIntegTestTask integTestMinio = project.tasks.create('integTestMinio', RestIntegTestTask.class) {
292-
description = "Runs REST tests using the Minio repository."
293-
}
294-
170+
preProcessFixture.dependsOn(writeDockerFile)
295171
// The following closure must execute before the afterEvaluate block in the constructor of the following integrationTest tasks:
296172
project.afterEvaluate {
297-
ClusterConfiguration cluster = project.extensions.getByName('integTestMinioCluster') as ClusterConfiguration
298-
cluster.dependsOn(project.bundlePlugin)
299-
cluster.dependsOn(startMinio) // otherwise we don't know the Minio port
300-
cluster.keystoreSetting 's3.client.integration_test_permanent.access_key', s3PermanentAccessKey
301-
cluster.keystoreSetting 's3.client.integration_test_permanent.secret_key', s3PermanentSecretKey
302-
303-
Closure<String> minioAddressAndPort = {
304-
assert startMinio.minioPort > 0
305-
return 'http://' + minioAddress + ':' + startMinio.minioPort
306-
}
307-
cluster.setting 's3.client.integration_test_permanent.endpoint', "${ -> minioAddressAndPort.call()}"
173+
// Only configure the Minio tests if postProcessFixture is configured to skip them if Docker is not available
174+
// or fixtures have been disabled
175+
if (postProcessFixture.enabled) {
176+
ClusterConfiguration cluster = project.extensions.getByName('integTestMinioCluster') as ClusterConfiguration
177+
cluster.dependsOn(project.bundlePlugin)
178+
cluster.dependsOn(postProcessFixture)
179+
cluster.keystoreSetting 's3.client.integration_test_permanent.access_key', s3PermanentAccessKey
180+
cluster.keystoreSetting 's3.client.integration_test_permanent.secret_key', s3PermanentSecretKey
181+
182+
Closure<String> minioAddressAndPort = {
183+
int minioPort = postProcessFixture.ext."test.fixtures.minio-fixture.tcp.9000"
184+
assert minioPort > 0
185+
return 'http://127.0.0.1:' + minioPort
186+
}
187+
cluster.setting 's3.client.integration_test_permanent.endpoint', "${-> minioAddressAndPort.call()}"
308188

309-
Task restIntegTestTask = project.tasks.getByName('integTestMinio')
310-
restIntegTestTask.clusterConfig.plugin(project.path)
189+
Task restIntegTestTask = project.tasks.getByName('integTestMinio')
190+
restIntegTestTask.clusterConfig.plugin(project.path)
311191

312-
// Default jvm arguments for all test clusters
313-
String jvmArgs = "-Xms" + System.getProperty('tests.heap.size', '512m') +
314-
" " + "-Xmx" + System.getProperty('tests.heap.size', '512m') +
315-
" " + System.getProperty('tests.jvm.argline', '')
192+
// Default jvm arguments for all test clusters
193+
String jvmArgs = "-Xms" + System.getProperty('tests.heap.size', '512m') +
194+
" " + "-Xmx" + System.getProperty('tests.heap.size', '512m') +
195+
" " + System.getProperty('tests.jvm.argline', '')
316196

317-
restIntegTestTask.clusterConfig.jvmArgs = jvmArgs
197+
restIntegTestTask.clusterConfig.jvmArgs = jvmArgs
198+
project.check.dependsOn(integTestMinio)
199+
}
318200
}
319201

320-
integTestMinioRunner.dependsOn(startMinio)
321-
integTestMinioRunner.finalizedBy(stopMinio)
202+
integTestMinioRunner.dependsOn(postProcessFixture)
322203
// Minio only supports a single access key, see https://github.com/minio/minio/pull/5968
323204
integTestMinioRunner.systemProperty 'tests.rest.blacklist', [
324205
'repository_s3/30_repository_temporary_credentials/*',
325206
'repository_s3/40_repository_ec2_credentials/*',
326207
'repository_s3/50_repository_ecs_credentials/*'
327208
].join(",")
328209

329-
project.check.dependsOn(integTestMinio)
210+
BuildPlugin.requireDocker(integTestMinio)
330211
}
331212

332213
File parentFixtures = new File(project.buildDir, "fixtures")
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
version: '3'
2+
services:
3+
minio-fixture:
4+
build:
5+
context: ./build/minio-docker
6+
dockerfile: Dockerfile
7+
ports:
8+
- "9000"
9+
command: ["server", "/minio/data"]

0 commit comments

Comments
 (0)