Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows support to run integration tests with Gradle #14051

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class ClusterConfiguration {
FileCollection file
@Override
String toString() {
return "file://${file.singleFile}"
return file.singleFile.toURI().toURL().toString();
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
package org.elasticsearch.gradle.test

import org.apache.tools.ant.taskdefs.condition.Os
import org.elasticsearch.gradle.ElasticsearchProperties
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
Expand Down Expand Up @@ -76,7 +77,12 @@ class ClusterFormationTasks {
for (Map.Entry<String, String> command : config.setupCommands.entrySet()) {
Task nextSetup = project.tasks.create(name: "${task.name}#${command.getKey()}", type: Exec, dependsOn: setup) {
workingDir home
executable 'sh'
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
executable 'cmd'
args '/C', 'call'
} else {
executable 'sh'
}
args command.getValue()
// only show output on failure, when not in info or debug mode
if (logger.isInfoEnabled() == false) {
Expand All @@ -95,42 +101,56 @@ class ClusterFormationTasks {
}

File pidFile = pidFile(baseDir)
Task start = project.tasks.create(name: "${task.name}#start", type: Exec, dependsOn: setup) {
workingDir home
executable 'sh'
List esArgs = [
'bin/elasticsearch',
'-d', // daemonize!
"-Des.http.port=${config.httpPort}",
"-Des.transport.tcp.port=${config.transportPort}",
"-Des.pidfile=${pidFile}",
"-Des.path.repo=${home}/repo",
"-Des.path.shared_data=${home}/../",
]
esArgs.addAll(config.systemProperties.collect {key, value -> "-D${key}=${value}"})
args esArgs
errorOutput = new ByteArrayOutputStream()
doLast {
if (errorOutput.toString().isEmpty() == false) {
logger.error(errorOutput.toString())
new File(home, 'logs' + File.separator + clusterName + '.log').eachLine {
line -> logger.error(line)
List esArgs = [
"-Des.http.port=${config.httpPort}",
"-Des.transport.tcp.port=${config.transportPort}",
"-Des.pidfile=${pidFile}",
"-Des.path.repo=${home}/repo",
"-Des.path.shared_data=${home}/../",
]
esArgs.addAll(config.systemProperties.collect {key, value -> "-D${key}=${value}"})
Closure esPostStartActions = { ant, logger ->
ant.waitfor(maxwait: '30', maxwaitunit: 'second', checkevery: '500', checkeveryunit: 'millisecond', timeoutproperty: "failed${task.name}#start") {
and {
resourceexists {
file file: pidFile.toString()
}
throw new GradleException('Failed to start elasticsearch')
http(url: "http://localhost:${config.httpPort}")
}
ant.waitfor(maxwait: '30', maxwaitunit: 'second', checkevery: '500', checkeveryunit: 'millisecond', timeoutproperty: "failed${task.name}#start") {
and {
resourceexists {
file file: pidFile.toString()
}
http(url: "http://localhost:${config.httpPort}")
}
}
if (ant.properties.containsKey("failed${task.name}#start".toString())) {
new File(home, 'logs' + File.separator + clusterName + '.log').eachLine {
line -> logger.error(line)
}
if (ant.properties.containsKey("failed${task.name}#start")) {
new File(home, 'logs' + File.separator + clusterName + '.log').eachLine {
line -> logger.error(line)
throw new GradleException('Failed to start elasticsearch')
}
}
Task start;
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
// elasticsearch.bat is spawned as it has no daemon mode
start = project.tasks.create(name: "${task.name}#start", type: DefaultTask, dependsOn: setup) << {
// Fall back to Ant exec task as Gradle Exec task does not support spawning yet
ant.exec(executable: 'cmd', spawn: true, dir: home) {
(['/C', 'call', 'bin/elasticsearch'] + esArgs).each { arg(value: it) }
}
esPostStartActions(ant, logger)
}
} else {
start = project.tasks.create(name: "${task.name}#start", type: Exec, dependsOn: setup) {
workingDir home
executable 'sh'
args 'bin/elasticsearch', '-d' // daemonize!
args esArgs
errorOutput = new ByteArrayOutputStream()
doLast {
if (errorOutput.toString().isEmpty() == false) {
logger.error(errorOutput.toString())
new File(home, 'logs' + File.separator + clusterName + '.log').eachLine {
line -> logger.error(line)
}
throw new GradleException('Failed to start elasticsearch')
}
throw new GradleException('Failed to start elasticsearch')
esPostStartActions(ant, logger)
}
}
}
Expand All @@ -140,8 +160,13 @@ class ClusterFormationTasks {
static void addNodeStopTask(Project project, Task task, File baseDir) {
LazyPidReader pidFile = new LazyPidReader(pidFile: pidFile(baseDir))
Task stop = project.tasks.create(name: task.name + '#stop', type: Exec) {
executable 'kill'
args '-9', pidFile
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
executable 'Taskkill'
args '/PID', pidFile, '/F'
} else {
executable 'kill'
args '-9', pidFile
}
doLast {
// TODO: wait for pid to close, or kill -9 and fail
}
Expand Down
93 changes: 32 additions & 61 deletions test-framework/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,70 +28,41 @@ project.ext {
srcDir = new File(project.buildDir, 'src')
coreDir = new File(project("${projectsPrefix}:core").projectDir, 'src' + File.separator + 'test')
}
class ExecHack extends DefaultTask {
File srcDir = project.ext.srcDir
File coreDir = project.ext.coreDir
List commands = ["rm -rf ${srcDir}", "mkdir -p ${srcDir}"]
void copy(String path) {
File corePath = project.file("${coreDir}/${path}")
File srcPath = project.file("${srcDir}/${path}")
String dir = path
if (corePath.isDirectory()) {
srcPath = srcPath.getParentFile()
} else {
dir = coreDir.toURI().relativize(corePath.getParentFile().toURI()).getPath()
}
commands.add("mkdir -p ${srcDir}/${dir}")
commands.add("cp -a ${corePath} ${srcPath}")
}
void remove(String path) {
commands.add("rm -rf ${srcDir}/${path}")
}
@TaskAction
void executeHack() {
for (String command : commands) {
logger.info(command)
def p = command.execute()
p.waitFor()
if (p.exitValue()) {
logger.error(p.text)
throw new GradleException("Failed to execute '${command}'")
}
}
}
}
sourceSets.main.java.srcDir(new File(srcDir, "java"))
sourceSets.main.resources.srcDir(new File(srcDir, "resources"))
task copySourceFiles(type: ExecHack) {
copy 'resources/log4j.properties'
copy 'java/org/elasticsearch/test'
copy 'java/org/elasticsearch/bootstrap/BootstrapForTesting.java'
copy 'java/org/elasticsearch/bootstrap/MockPluginPolicy.java'
copy 'java/org/elasticsearch/common/cli/CliToolTestCase.java'
copy 'java/org/elasticsearch/cluster/MockInternalClusterInfoService.java'
copy 'java/org/elasticsearch/index/MockEngineFactoryPlugin.java'
copy 'java/org/elasticsearch/search/MockSearchService.java'
copy 'java/org/elasticsearch/search/aggregations/bucket/AbstractTermsTestCase.java'
copy 'java/org/elasticsearch/search/aggregations/bucket/script/NativeSignificanceScoreScriptNoParams.java'
copy 'java/org/elasticsearch/search/aggregations/bucket/script/NativeSignificanceScoreScriptWithParams.java'
copy 'java/org/elasticsearch/search/aggregations/bucket/script/TestScript.java'
copy 'java/org/elasticsearch/search/aggregations/metrics/AbstractNumericTestCase.java'
copy 'java/org/elasticsearch/percolator/PercolatorTestUtil.java'
copy 'java/org/elasticsearch/cache/recycler/MockPageCacheRecycler.java'
copy 'java/org/elasticsearch/common/util/MockBigArrays.java'
copy 'java/org/elasticsearch/node/NodeMocksPlugin.java'
copy 'java/org/elasticsearch/node/MockNode.java'
copy 'java/org/elasticsearch/common/io/PathUtilsForTesting.java'
// unit tests for yaml suite parser & rest spec parser need to be excluded
remove 'java/org/elasticsearch/test/rest/test'
// unit tests for test framework classes
remove 'java/org/elasticsearch/test/test'
task copySourceFiles(type: Sync) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not know about this type, thank you!

from(coreDir) {
include 'resources/log4j.properties'
include 'java/org/elasticsearch/test/**'
include 'java/org/elasticsearch/bootstrap/BootstrapForTesting.java'
include 'java/org/elasticsearch/bootstrap/MockPluginPolicy.java'
include 'java/org/elasticsearch/common/cli/CliToolTestCase.java'
include 'java/org/elasticsearch/cluster/MockInternalClusterInfoService.java'
include 'java/org/elasticsearch/index/MockEngineFactoryPlugin.java'
include 'java/org/elasticsearch/search/MockSearchService.java'
include 'java/org/elasticsearch/search/aggregations/bucket/AbstractTermsTestCase.java'
include 'java/org/elasticsearch/search/aggregations/bucket/script/NativeSignificanceScoreScriptNoParams.java'
include 'java/org/elasticsearch/search/aggregations/bucket/script/NativeSignificanceScoreScriptWithParams.java'
include 'java/org/elasticsearch/search/aggregations/bucket/script/TestScript.java'
include 'java/org/elasticsearch/search/aggregations/metrics/AbstractNumericTestCase.java'
include 'java/org/elasticsearch/percolator/PercolatorTestUtil.java'
include 'java/org/elasticsearch/cache/recycler/MockPageCacheRecycler.java'
include 'java/org/elasticsearch/common/util/MockBigArrays.java'
include 'java/org/elasticsearch/node/NodeMocksPlugin.java'
include 'java/org/elasticsearch/node/MockNode.java'
include 'java/org/elasticsearch/common/io/PathUtilsForTesting.java'
// unit tests for yaml suite parser & rest spec parser need to be excluded
exclude 'java/org/elasticsearch/test/rest/test/**'
// unit tests for test framework classes
exclude 'java/org/elasticsearch/test/test/**'

// no geo (requires optional deps)
remove 'java/org/elasticsearch/test/hamcrest/ElasticsearchGeoAssertions.java'
remove 'java/org/elasticsearch/test/geo/RandomShapeGenerator.java'
// this mock is just for a single logging test
remove 'java/org/elasticsearch/test/MockLogAppender.java'
// no geo (requires optional deps)
exclude 'java/org/elasticsearch/test/hamcrest/ElasticsearchGeoAssertions.java'
exclude 'java/org/elasticsearch/test/geo/RandomShapeGenerator.java'
// this mock is just for a single logging test
exclude 'java/org/elasticsearch/test/MockLogAppender.java'
}
into srcDir
}
compileJava.dependsOn copySourceFiles

Expand Down