Add Vagrant based testing fixture (#24249)

This commit is contained in:
James Baiera 2017-05-04 10:17:55 -04:00 committed by GitHub
parent 953add8e70
commit d928ae210d
10 changed files with 401 additions and 279 deletions

View File

@ -0,0 +1,291 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you 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
*
* http://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 org.elasticsearch.gradle.test
import org.apache.tools.ant.taskdefs.condition.Os
import org.elasticsearch.gradle.AntTask
import org.elasticsearch.gradle.LoggedExec
import org.gradle.api.GradleException
import org.gradle.api.Task
import org.gradle.api.tasks.Exec
import org.gradle.api.tasks.Input
/**
* A fixture for integration tests which runs in a separate process launched by Ant.
*/
public class AntFixture extends AntTask implements Fixture {
/** The path to the executable that starts the fixture. */
@Input
String executable
private final List<Object> arguments = new ArrayList<>()
@Input
public void args(Object... args) {
arguments.addAll(args)
}
/**
* Environment variables for the fixture process. The value can be any object, which
* will have toString() called at execution time.
*/
private final Map<String, Object> environment = new HashMap<>()
@Input
public void env(String key, Object value) {
environment.put(key, value)
}
/** A flag to indicate whether the command should be executed from a shell. */
@Input
boolean useShell = false
/**
* A flag to indicate whether the fixture should be run in the foreground, or spawned.
* It is protected so subclasses can override (eg RunTask).
*/
protected boolean spawn = true
/**
* A closure to call before the fixture is considered ready. The closure is passed the fixture object,
* as well as a groovy AntBuilder, to enable running ant condition checks. The default wait
* condition is for http on the http port.
*/
@Input
Closure waitCondition = { AntFixture fixture, AntBuilder ant ->
File tmpFile = new File(fixture.cwd, 'wait.success')
ant.get(src: "http://${fixture.addressAndPort}",
dest: tmpFile.toString(),
ignoreerrors: true, // do not fail on error, so logging information can be flushed
retries: 10)
return tmpFile.exists()
}
private final Task stopTask
public AntFixture() {
stopTask = createStopTask()
finalizedBy(stopTask)
}
@Override
public Task getStopTask() {
return stopTask
}
@Override
protected void runAnt(AntBuilder ant) {
project.delete(baseDir) // reset everything
cwd.mkdirs()
final String realExecutable
final List<Object> realArgs = new ArrayList<>()
final Map<String, Object> realEnv = environment
// We need to choose which executable we are using. In shell mode, or when we
// are spawning and thus using the wrapper script, the executable is the shell.
if (useShell || spawn) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
realExecutable = 'cmd'
realArgs.add('/C')
realArgs.add('"') // quote the entire command
} else {
realExecutable = 'sh'
}
} else {
realExecutable = executable
realArgs.addAll(arguments)
}
if (spawn) {
writeWrapperScript(executable)
realArgs.add(wrapperScript)
realArgs.addAll(arguments)
}
if (Os.isFamily(Os.FAMILY_WINDOWS) && (useShell || spawn)) {
realArgs.add('"')
}
commandString.eachLine { line -> logger.info(line) }
ant.exec(executable: realExecutable, spawn: spawn, dir: cwd, taskname: name) {
realEnv.each { key, value -> env(key: key, value: value) }
realArgs.each { arg(value: it) }
}
String failedProp = "failed${name}"
// first wait for resources, or the failure marker from the wrapper script
ant.waitfor(maxwait: '30', maxwaitunit: 'second', checkevery: '500', checkeveryunit: 'millisecond', timeoutproperty: failedProp) {
or {
resourceexists {
file(file: failureMarker.toString())
}
and {
resourceexists {
file(file: pidFile.toString())
}
resourceexists {
file(file: portsFile.toString())
}
}
}
}
if (ant.project.getProperty(failedProp) || failureMarker.exists()) {
fail("Failed to start ${name}")
}
// the process is started (has a pid) and is bound to a network interface
// so now wait undil the waitCondition has been met
// TODO: change this to a loop?
boolean success
try {
success = waitCondition(this, ant) == false
} catch (Exception e) {
String msg = "Wait condition caught exception for ${name}"
logger.error(msg, e)
fail(msg, e)
}
if (success == false) {
fail("Wait condition failed for ${name}")
}
}
/** Returns a debug string used to log information about how the fixture was run. */
protected String getCommandString() {
String commandString = "\n${name} configuration:\n"
commandString += "-----------------------------------------\n"
commandString += " cwd: ${cwd}\n"
commandString += " command: ${executable} ${arguments.join(' ')}\n"
commandString += ' environment:\n'
environment.each { k, v -> commandString += " ${k}: ${v}\n" }
if (spawn) {
commandString += "\n [${wrapperScript.name}]\n"
wrapperScript.eachLine('UTF-8', { line -> commandString += " ${line}\n"})
}
return commandString
}
/**
* Writes a script to run the real executable, so that stdout/stderr can be captured.
* TODO: this could be removed if we do use our own ProcessBuilder and pump output from the process
*/
private void writeWrapperScript(String executable) {
wrapperScript.parentFile.mkdirs()
String argsPasser = '"$@"'
String exitMarker = "; if [ \$? != 0 ]; then touch run.failed; fi"
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
argsPasser = '%*'
exitMarker = "\r\n if \"%errorlevel%\" neq \"0\" ( type nul >> run.failed )"
}
wrapperScript.setText("\"${executable}\" ${argsPasser} > run.log 2>&1 ${exitMarker}", 'UTF-8')
}
/** Fail the build with the given message, and logging relevant info*/
private void fail(String msg, Exception... suppressed) {
if (logger.isInfoEnabled() == false) {
// We already log the command at info level. No need to do it twice.
commandString.eachLine { line -> logger.error(line) }
}
logger.error("${name} output:")
logger.error("-----------------------------------------")
logger.error(" failure marker exists: ${failureMarker.exists()}")
logger.error(" pid file exists: ${pidFile.exists()}")
logger.error(" ports file exists: ${portsFile.exists()}")
// also dump the log file for the startup script (which will include ES logging output to stdout)
if (runLog.exists()) {
logger.error("\n [log]")
runLog.eachLine { line -> logger.error(" ${line}") }
}
logger.error("-----------------------------------------")
GradleException toThrow = new GradleException(msg)
for (Exception e : suppressed) {
toThrow.addSuppressed(e)
}
throw toThrow
}
/** Adds a task to kill an elasticsearch node with the given pidfile */
private Task createStopTask() {
final AntFixture fixture = this
final Object pid = "${ -> fixture.pid }"
Exec stop = project.tasks.create(name: "${name}#stop", type: LoggedExec)
stop.onlyIf { fixture.pidFile.exists() }
stop.doFirst {
logger.info("Shutting down ${fixture.name} with pid ${pid}")
}
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
stop.executable = 'Taskkill'
stop.args('/PID', pid, '/F')
} else {
stop.executable = 'kill'
stop.args('-9', pid)
}
stop.doLast {
project.delete(fixture.pidFile)
}
return stop
}
/**
* A path relative to the build dir that all configuration and runtime files
* will live in for this fixture
*/
protected File getBaseDir() {
return new File(project.buildDir, "fixtures/${name}")
}
/** Returns the working directory for the process. Defaults to "cwd" inside baseDir. */
protected File getCwd() {
return new File(baseDir, 'cwd')
}
/** Returns the file the process writes its pid to. Defaults to "pid" inside baseDir. */
protected File getPidFile() {
return new File(baseDir, 'pid')
}
/** Reads the pid file and returns the process' pid */
public int getPid() {
return Integer.parseInt(pidFile.getText('UTF-8').trim())
}
/** Returns the file the process writes its bound ports to. Defaults to "ports" inside baseDir. */
protected File getPortsFile() {
return new File(baseDir, 'ports')
}
/** Returns an address and port suitable for a uri to connect to this node over http */
public String getAddressAndPort() {
return portsFile.readLines("UTF-8").get(0)
}
/** Returns a file that wraps around the actual command when {@code spawn == true}. */
protected File getWrapperScript() {
return new File(cwd, Os.isFamily(Os.FAMILY_WINDOWS) ? 'run.bat' : 'run')
}
/** Returns a file that the wrapper script writes when the command failed. */
protected File getFailureMarker() {
return new File(cwd, 'run.failed')
}
/** Returns a file that the wrapper script writes when the command failed. */
protected File getRunLog() {
return new File(cwd, 'run.log')
}
}

View File

@ -208,7 +208,7 @@ class ClusterFormationTasks {
start.finalizedBy(stop) start.finalizedBy(stop)
for (Object dependency : config.dependencies) { for (Object dependency : config.dependencies) {
if (dependency instanceof Fixture) { if (dependency instanceof Fixture) {
Task depStop = ((Fixture)dependency).stopTask def depStop = ((Fixture)dependency).stopTask
runner.finalizedBy(depStop) runner.finalizedBy(depStop)
start.finalizedBy(depStop) start.finalizedBy(depStop)
} }

View File

@ -16,272 +16,15 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.elasticsearch.gradle.test package org.elasticsearch.gradle.test
import org.apache.tools.ant.taskdefs.condition.Os
import org.elasticsearch.gradle.AntTask
import org.elasticsearch.gradle.LoggedExec
import org.gradle.api.GradleException
import org.gradle.api.Task
import org.gradle.api.tasks.Exec
import org.gradle.api.tasks.Input
/** /**
* A fixture for integration tests which runs in a separate process. * Any object that can produce an accompanying stop task, meant to tear down
* a previously instantiated service.
*/ */
public class Fixture extends AntTask { public interface Fixture {
/** The path to the executable that starts the fixture. */
@Input
String executable
private final List<Object> arguments = new ArrayList<>()
@Input
public void args(Object... args) {
arguments.addAll(args)
}
/**
* Environment variables for the fixture process. The value can be any object, which
* will have toString() called at execution time.
*/
private final Map<String, Object> environment = new HashMap<>()
@Input
public void env(String key, Object value) {
environment.put(key, value)
}
/** A flag to indicate whether the command should be executed from a shell. */
@Input
boolean useShell = false
/**
* A flag to indicate whether the fixture should be run in the foreground, or spawned.
* It is protected so subclasses can override (eg RunTask).
*/
protected boolean spawn = true
/**
* A closure to call before the fixture is considered ready. The closure is passed the fixture object,
* as well as a groovy AntBuilder, to enable running ant condition checks. The default wait
* condition is for http on the http port.
*/
@Input
Closure waitCondition = { Fixture fixture, AntBuilder ant ->
File tmpFile = new File(fixture.cwd, 'wait.success')
ant.get(src: "http://${fixture.addressAndPort}",
dest: tmpFile.toString(),
ignoreerrors: true, // do not fail on error, so logging information can be flushed
retries: 10)
return tmpFile.exists()
}
/** A task which will stop this fixture. This should be used as a finalizedBy for any tasks that use the fixture. */ /** A task which will stop this fixture. This should be used as a finalizedBy for any tasks that use the fixture. */
public final Task stopTask public Object getStopTask()
public Fixture() {
stopTask = createStopTask()
finalizedBy(stopTask)
}
@Override
protected void runAnt(AntBuilder ant) {
project.delete(baseDir) // reset everything
cwd.mkdirs()
final String realExecutable
final List<Object> realArgs = new ArrayList<>()
final Map<String, Object> realEnv = environment
// We need to choose which executable we are using. In shell mode, or when we
// are spawning and thus using the wrapper script, the executable is the shell.
if (useShell || spawn) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
realExecutable = 'cmd'
realArgs.add('/C')
realArgs.add('"') // quote the entire command
} else {
realExecutable = 'sh'
}
} else {
realExecutable = executable
realArgs.addAll(arguments)
}
if (spawn) {
writeWrapperScript(executable)
realArgs.add(wrapperScript)
realArgs.addAll(arguments)
}
if (Os.isFamily(Os.FAMILY_WINDOWS) && (useShell || spawn)) {
realArgs.add('"')
}
commandString.eachLine { line -> logger.info(line) }
ant.exec(executable: realExecutable, spawn: spawn, dir: cwd, taskname: name) {
realEnv.each { key, value -> env(key: key, value: value) }
realArgs.each { arg(value: it) }
}
String failedProp = "failed${name}"
// first wait for resources, or the failure marker from the wrapper script
ant.waitfor(maxwait: '30', maxwaitunit: 'second', checkevery: '500', checkeveryunit: 'millisecond', timeoutproperty: failedProp) {
or {
resourceexists {
file(file: failureMarker.toString())
}
and {
resourceexists {
file(file: pidFile.toString())
}
resourceexists {
file(file: portsFile.toString())
}
}
}
}
if (ant.project.getProperty(failedProp) || failureMarker.exists()) {
fail("Failed to start ${name}")
}
// the process is started (has a pid) and is bound to a network interface
// so now wait undil the waitCondition has been met
// TODO: change this to a loop?
boolean success
try {
success = waitCondition(this, ant) == false
} catch (Exception e) {
String msg = "Wait condition caught exception for ${name}"
logger.error(msg, e)
fail(msg, e)
}
if (success == false) {
fail("Wait condition failed for ${name}")
}
}
/** Returns a debug string used to log information about how the fixture was run. */
protected String getCommandString() {
String commandString = "\n${name} configuration:\n"
commandString += "-----------------------------------------\n"
commandString += " cwd: ${cwd}\n"
commandString += " command: ${executable} ${arguments.join(' ')}\n"
commandString += ' environment:\n'
environment.each { k, v -> commandString += " ${k}: ${v}\n" }
if (spawn) {
commandString += "\n [${wrapperScript.name}]\n"
wrapperScript.eachLine('UTF-8', { line -> commandString += " ${line}\n"})
}
return commandString
}
/**
* Writes a script to run the real executable, so that stdout/stderr can be captured.
* TODO: this could be removed if we do use our own ProcessBuilder and pump output from the process
*/
private void writeWrapperScript(String executable) {
wrapperScript.parentFile.mkdirs()
String argsPasser = '"$@"'
String exitMarker = "; if [ \$? != 0 ]; then touch run.failed; fi"
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
argsPasser = '%*'
exitMarker = "\r\n if \"%errorlevel%\" neq \"0\" ( type nul >> run.failed )"
}
wrapperScript.setText("\"${executable}\" ${argsPasser} > run.log 2>&1 ${exitMarker}", 'UTF-8')
}
/** Fail the build with the given message, and logging relevant info*/
private void fail(String msg, Exception... suppressed) {
if (logger.isInfoEnabled() == false) {
// We already log the command at info level. No need to do it twice.
commandString.eachLine { line -> logger.error(line) }
}
logger.error("${name} output:")
logger.error("-----------------------------------------")
logger.error(" failure marker exists: ${failureMarker.exists()}")
logger.error(" pid file exists: ${pidFile.exists()}")
logger.error(" ports file exists: ${portsFile.exists()}")
// also dump the log file for the startup script (which will include ES logging output to stdout)
if (runLog.exists()) {
logger.error("\n [log]")
runLog.eachLine { line -> logger.error(" ${line}") }
}
logger.error("-----------------------------------------")
GradleException toThrow = new GradleException(msg)
for (Exception e : suppressed) {
toThrow.addSuppressed(e)
}
throw toThrow
}
/** Adds a task to kill an elasticsearch node with the given pidfile */
private Task createStopTask() {
final Fixture fixture = this
final Object pid = "${ -> fixture.pid }"
Exec stop = project.tasks.create(name: "${name}#stop", type: LoggedExec)
stop.onlyIf { fixture.pidFile.exists() }
stop.doFirst {
logger.info("Shutting down ${fixture.name} with pid ${pid}")
}
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
stop.executable = 'Taskkill'
stop.args('/PID', pid, '/F')
} else {
stop.executable = 'kill'
stop.args('-9', pid)
}
stop.doLast {
project.delete(fixture.pidFile)
}
return stop
}
/**
* A path relative to the build dir that all configuration and runtime files
* will live in for this fixture
*/
protected File getBaseDir() {
return new File(project.buildDir, "fixtures/${name}")
}
/** Returns the working directory for the process. Defaults to "cwd" inside baseDir. */
protected File getCwd() {
return new File(baseDir, 'cwd')
}
/** Returns the file the process writes its pid to. Defaults to "pid" inside baseDir. */
protected File getPidFile() {
return new File(baseDir, 'pid')
}
/** Reads the pid file and returns the process' pid */
public int getPid() {
return Integer.parseInt(pidFile.getText('UTF-8').trim())
}
/** Returns the file the process writes its bound ports to. Defaults to "ports" inside baseDir. */
protected File getPortsFile() {
return new File(baseDir, 'ports')
}
/** Returns an address and port suitable for a uri to connect to this node over http */
public String getAddressAndPort() {
return portsFile.readLines("UTF-8").get(0)
}
/** Returns a file that wraps around the actual command when {@code spawn == true}. */
protected File getWrapperScript() {
return new File(cwd, Os.isFamily(Os.FAMILY_WINDOWS) ? 'run.bat' : 'run')
}
/** Returns a file that the wrapper script writes when the command failed. */
protected File getFailureMarker() {
return new File(cwd, 'run.failed')
}
/** Returns a file that the wrapper script writes when the command failed. */
protected File getRunLog() {
return new File(cwd, 'run.log')
}
} }

View File

@ -129,7 +129,7 @@ public class RestIntegTestTask extends DefaultTask {
runner.dependsOn(dependencies) runner.dependsOn(dependencies)
for (Object dependency : dependencies) { for (Object dependency : dependencies) {
if (dependency instanceof Fixture) { if (dependency instanceof Fixture) {
runner.finalizedBy(((Fixture)dependency).stopTask) runner.finalizedBy(((Fixture)dependency).getStopTask())
} }
} }
return this return this
@ -140,7 +140,7 @@ public class RestIntegTestTask extends DefaultTask {
runner.setDependsOn(dependencies) runner.setDependsOn(dependencies)
for (Object dependency : dependencies) { for (Object dependency : dependencies) {
if (dependency instanceof Fixture) { if (dependency instanceof Fixture) {
runner.finalizedBy(((Fixture)dependency).stopTask) runner.finalizedBy(((Fixture)dependency).getStopTask())
} }
} }
} }

View File

@ -0,0 +1,54 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you 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
*
* http://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 org.elasticsearch.gradle.test
import org.elasticsearch.gradle.vagrant.VagrantCommandTask
import org.gradle.api.Task
/**
* A fixture for integration tests which runs in a virtual machine launched by Vagrant.
*/
class VagrantFixture extends VagrantCommandTask implements Fixture {
private VagrantCommandTask stopTask
public VagrantFixture() {
this.stopTask = project.tasks.create(name: "${name}#stop", type: VagrantCommandTask) {
command 'halt'
}
finalizedBy this.stopTask
}
@Override
void setBoxName(String boxName) {
super.setBoxName(boxName)
this.stopTask.setBoxName(boxName)
}
@Override
void setEnvironmentVars(Map<String, String> environmentVars) {
super.setEnvironmentVars(environmentVars)
this.stopTask.setEnvironmentVars(environmentVars)
}
@Override
public Task getStopTask() {
return this.stopTask
}
}

View File

@ -27,12 +27,15 @@ import org.gradle.api.tasks.Input
public class BatsOverVagrantTask extends VagrantCommandTask { public class BatsOverVagrantTask extends VagrantCommandTask {
@Input @Input
String command String remoteCommand
BatsOverVagrantTask() { BatsOverVagrantTask() {
project.afterEvaluate { command = 'ssh'
args 'ssh', boxName, '--command', command
} }
void setRemoteCommand(String remoteCommand) {
this.remoteCommand = Objects.requireNonNull(remoteCommand)
setArgs(['--command', remoteCommand])
} }
@Override @Override

View File

@ -21,9 +21,15 @@ package org.elasticsearch.gradle.vagrant
import org.apache.commons.io.output.TeeOutputStream import org.apache.commons.io.output.TeeOutputStream
import org.elasticsearch.gradle.LoggedExec import org.elasticsearch.gradle.LoggedExec
import org.gradle.api.tasks.Input import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction
import org.gradle.internal.logging.progress.ProgressLoggerFactory import org.gradle.internal.logging.progress.ProgressLoggerFactory
import javax.inject.Inject import javax.inject.Inject
import java.util.concurrent.CountDownLatch
import java.util.concurrent.locks.Lock
import java.util.concurrent.locks.ReadWriteLock
import java.util.concurrent.locks.ReentrantLock
/** /**
* Runs a vagrant command. Pretty much like Exec task but with a nicer output * Runs a vagrant command. Pretty much like Exec task but with a nicer output
@ -31,6 +37,12 @@ import javax.inject.Inject
*/ */
public class VagrantCommandTask extends LoggedExec { public class VagrantCommandTask extends LoggedExec {
@Input
String command
@Input @Optional
String subcommand
@Input @Input
String boxName String boxName
@ -40,12 +52,28 @@ public class VagrantCommandTask extends LoggedExec {
public VagrantCommandTask() { public VagrantCommandTask() {
executable = 'vagrant' executable = 'vagrant'
// We're using afterEvaluate here to slot in some logic that captures configurations and
// modifies the command line right before the main execution happens. The reason that we
// call doFirst instead of just doing the work in the afterEvaluate is that the latter
// restricts how subclasses can extend functionality. Calling afterEvaluate is like having
// all the logic of a task happening at construction time, instead of at execution time
// where a subclass can override or extend the logic.
project.afterEvaluate { project.afterEvaluate {
// It'd be nice if --machine-readable were, well, nice doFirst {
standardOutput = new TeeOutputStream(standardOutput, createLoggerOutputStream())
if (environmentVars != null) { if (environmentVars != null) {
environment environmentVars environment environmentVars
} }
// Build our command line for vagrant
def vagrantCommand = [executable, command]
if (subcommand != null) {
vagrantCommand = vagrantCommand + subcommand
}
commandLine([*vagrantCommand, boxName, *args])
// It'd be nice if --machine-readable were, well, nice
standardOutput = new TeeOutputStream(standardOutput, createLoggerOutputStream())
}
} }
} }

View File

@ -391,21 +391,23 @@ class VagrantTestPlugin implements Plugin<Project> {
// always add a halt task for all boxes, so clean makes sure they are all shutdown // always add a halt task for all boxes, so clean makes sure they are all shutdown
Task halt = project.tasks.create("vagrant${boxTask}#halt", VagrantCommandTask) { Task halt = project.tasks.create("vagrant${boxTask}#halt", VagrantCommandTask) {
command 'halt'
boxName box boxName box
environmentVars vagrantEnvVars environmentVars vagrantEnvVars
args 'halt', box
} }
stop.dependsOn(halt) stop.dependsOn(halt)
Task update = project.tasks.create("vagrant${boxTask}#update", VagrantCommandTask) { Task update = project.tasks.create("vagrant${boxTask}#update", VagrantCommandTask) {
command 'box'
subcommand 'update'
boxName box boxName box
environmentVars vagrantEnvVars environmentVars vagrantEnvVars
args 'box', 'update', box
dependsOn vagrantCheckVersion, virtualboxCheckVersion dependsOn vagrantCheckVersion, virtualboxCheckVersion
} }
update.mustRunAfter(setupBats) update.mustRunAfter(setupBats)
Task up = project.tasks.create("vagrant${boxTask}#up", VagrantCommandTask) { Task up = project.tasks.create("vagrant${boxTask}#up", VagrantCommandTask) {
command 'up'
boxName box boxName box
environmentVars vagrantEnvVars environmentVars vagrantEnvVars
/* Its important that we try to reprovision the box even if it already /* Its important that we try to reprovision the box even if it already
@ -418,7 +420,7 @@ class VagrantTestPlugin implements Plugin<Project> {
vagrant's default but its possible to change that default and folks do. vagrant's default but its possible to change that default and folks do.
But the boxes that we use are unlikely to work properly with other But the boxes that we use are unlikely to work properly with other
virtualization providers. Thus the lock. */ virtualization providers. Thus the lock. */
args 'up', box, '--provision', '--provider', 'virtualbox' args '--provision', '--provider', 'virtualbox'
/* It'd be possible to check if the box is already up here and output /* It'd be possible to check if the box is already up here and output
SKIPPED but that would require running vagrant status which is slow! */ SKIPPED but that would require running vagrant status which is slow! */
dependsOn update dependsOn update
@ -434,11 +436,11 @@ class VagrantTestPlugin implements Plugin<Project> {
vagrantSmokeTest.dependsOn(smoke) vagrantSmokeTest.dependsOn(smoke)
Task packaging = project.tasks.create("vagrant${boxTask}#packagingTest", BatsOverVagrantTask) { Task packaging = project.tasks.create("vagrant${boxTask}#packagingTest", BatsOverVagrantTask) {
remoteCommand BATS_TEST_COMMAND
boxName box boxName box
environmentVars vagrantEnvVars environmentVars vagrantEnvVars
dependsOn up, setupBats dependsOn up, setupBats
finalizedBy halt finalizedBy halt
command BATS_TEST_COMMAND
} }
TaskExecutionAdapter packagingReproListener = new TaskExecutionAdapter() { TaskExecutionAdapter packagingReproListener = new TaskExecutionAdapter() {
@ -461,11 +463,12 @@ class VagrantTestPlugin implements Plugin<Project> {
} }
Task platform = project.tasks.create("vagrant${boxTask}#platformTest", VagrantCommandTask) { Task platform = project.tasks.create("vagrant${boxTask}#platformTest", VagrantCommandTask) {
command 'ssh'
boxName box boxName box
environmentVars vagrantEnvVars environmentVars vagrantEnvVars
dependsOn up dependsOn up
finalizedBy halt finalizedBy halt
args 'ssh', boxName, '--command', PLATFORM_TEST_COMMAND + " -Dtests.seed=${-> project.extensions.esvagrant.formattedTestSeed}" args '--command', PLATFORM_TEST_COMMAND + " -Dtests.seed=${-> project.extensions.esvagrant.formattedTestSeed}"
} }
TaskExecutionAdapter platformReproListener = new TaskExecutionAdapter() { TaskExecutionAdapter platformReproListener = new TaskExecutionAdapter() {
@Override @Override

View File

@ -33,7 +33,7 @@ dependencies {
exampleFixture project(':test:fixtures:example-fixture') exampleFixture project(':test:fixtures:example-fixture')
} }
task exampleFixture(type: org.elasticsearch.gradle.test.Fixture) { task exampleFixture(type: org.elasticsearch.gradle.test.AntFixture) {
dependsOn project.configurations.exampleFixture dependsOn project.configurations.exampleFixture
executable = new File(project.javaHome, 'bin/java') executable = new File(project.javaHome, 'bin/java')
args '-cp', "${ -> project.configurations.exampleFixture.asPath }", args '-cp', "${ -> project.configurations.exampleFixture.asPath }",

View File

@ -60,7 +60,7 @@ dependencyLicenses {
mapping from: /hadoop-.*/, to: 'hadoop' mapping from: /hadoop-.*/, to: 'hadoop'
} }
task hdfsFixture(type: org.elasticsearch.gradle.test.Fixture) { task hdfsFixture(type: org.elasticsearch.gradle.test.AntFixture) {
dependsOn project.configurations.hdfsFixture dependsOn project.configurations.hdfsFixture
executable = new File(project.javaHome, 'bin/java') executable = new File(project.javaHome, 'bin/java')
env 'CLASSPATH', "${ -> project.configurations.hdfsFixture.asPath }" env 'CLASSPATH', "${ -> project.configurations.hdfsFixture.asPath }"