OpenSearch/qa/vagrant/build.gradle

284 lines
9.0 KiB
Groovy

/*
* 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.
*/
import org.elasticsearch.gradle.FileContentsTask
import org.elasticsearch.gradle.vagrant.BatsOverVagrantTask
import org.elasticsearch.gradle.vagrant.VagrantCommandTask
String testScripts = '*.bats'
String testCommand = "cd \$TESTROOT && sudo bats --tap \$BATS/$testScripts"
String smokeTestCommand = 'echo I work'
// the images we allow testing with
List<String> availableBoxes = [
'centos-6',
'centos-7',
'debian-8',
'fedora-24',
'oel-6',
'oel-7',
'opensuse-13',
'sles-12',
'ubuntu-1204',
'ubuntu-1404',
'ubuntu-1504',
'ubuntu-1604'
]
String vagrantBoxes = getProperties().get('vagrant.boxes', 'sample')
List<String> boxes = []
for (String box : vagrantBoxes.split(',')) {
if (box == 'sample') {
boxes.add('centos-7')
boxes.add('ubuntu-1404')
} else if (box == 'all') {
boxes = availableBoxes
break
} else {
if (availableBoxes.contains(box) == false) {
throw new IllegalArgumentException("Unknown vagrant box '${box}'")
}
boxes.add(box)
}
}
long seed
String formattedSeed = null
String[] upgradeFromVersions
String upgradeFromVersion
String maybeTestsSeed = System.getProperty("tests.seed", null);
if (maybeTestsSeed != null) {
List<String> seeds = maybeTestsSeed.tokenize(':')
if (seeds.size() != 0) {
String masterSeed = seeds.get(0)
seed = new BigInteger(masterSeed, 16).longValue()
formattedSeed = maybeTestsSeed
}
}
if (formattedSeed == null) {
seed = new Random().nextLong()
formattedSeed = String.format("%016X", seed)
}
String maybeUpdradeFromVersions = System.getProperty("tests.packaging.upgrade.from.versions", null)
if (maybeUpdradeFromVersions != null) {
upgradeFromVersions = maybeUpdradeFromVersions.split(",")
} else {
upgradeFromVersions = new File(project.projectDir, 'versions')
}
upgradeFromVersion = upgradeFromVersions[new Random(seed).nextInt(upgradeFromVersions.length)]
configurations {
test
}
repositories {
mavenCentral()
}
dependencies {
test project(path: ':distribution:tar', configuration: 'archives')
test project(path: ':distribution:rpm', configuration: 'archives')
test project(path: ':distribution:deb', configuration: 'archives')
// Collect all the plugins
for (Project subproj : project.rootProject.subprojects) {
if (subproj.path.startsWith(':plugins:')) {
test project(path: "${subproj.path}", configuration: 'zip')
}
}
// The version of elasticsearch that we upgrade *from*
test "org.elasticsearch.distribution.deb:elasticsearch:$upgradeFromVersion@deb"
test "org.elasticsearch.distribution.rpm:elasticsearch:$upgradeFromVersion@rpm"
}
task clean(type: Delete) {
group 'Build'
delete buildDir
}
task stop {
group 'Verification'
description 'Stop any tasks from tests that still may be running'
}
Set<String> getVersions() {
Node xml
new URL('https://repo1.maven.org/maven2/org/elasticsearch/elasticsearch/maven-metadata.xml').openStream().withStream { s ->
xml = new XmlParser().parse(s)
}
// List all N-1 releases from maven central
int major = Integer.parseInt(project.version.substring(0, project.version.indexOf('.'))) - 1
Set<String> versions = new TreeSet<>(xml.versioning.versions.version.collect { it.text() }.findAll { it ==~ /$major\.\d\.\d/ })
if (versions.isEmpty() == false) {
return versions;
}
// If no version is found, we run the tests with the current version
return Collections.singleton(project.version);
}
task updatePackagingTestUpgradeFromVersions {
group 'Verification'
description 'Update file containing options for the\n "starting" version in the "upgrade from" packaging tests.'
doLast {
Set<String> versions = getVersions()
new File(project.projectDir, 'versions').text = versions.join('\n') + '\n'
}
}
task verifyPackagingTestUpgradeFromVersions {
doLast {
String maybeUpdateFromVersions = System.getProperty("tests.packaging.upgrade.from.versions", null)
if (maybeUpdateFromVersions == null) {
Set<String> versions = getVersions()
Set<String> actualVersions = new HashSet<>(Arrays.asList(upgradeFromVersions))
if (!versions.equals(actualVersions)) {
throw new GradleException("out-of-date versions [" + actualVersions + "], expected [" + versions + "]; run gradle updatePackagingTestUpgradeFromVersions")
}
}
}
}
File testRoot = new File("$buildDir/testroot")
task createTestRoot {
dependsOn verifyPackagingTestUpgradeFromVersions
outputs.dir testRoot
doLast {
testRoot.mkdirs()
}
}
task createVersionFile(type: FileContentsTask) {
dependsOn createTestRoot
file "${testRoot}/version"
contents = version
}
task createUpgradeFromFile(type: FileContentsTask) {
dependsOn createTestRoot
file "${testRoot}/upgrade_from_version"
contents = upgradeFromVersion
}
task prepareTestRoot(type: Copy) {
description 'Dump bats test dependencies into the $TESTROOT'
into testRoot
from configurations.test
dependsOn createVersionFile, createUpgradeFromFile
doFirst {
gradle.addBuildListener new BuildAdapter() {
@Override
void buildFinished(BuildResult result) {
if (result.failure) {
println "Reproduce with: gradle packagingTest -Pvagrant.boxes=${vagrantBoxes} -Dtests.seed=${formattedSeed} -Dtests.packaging.upgrade.from.versions=${upgradeFromVersions.join(",")}"
}
}
}
}
}
task checkVagrantVersion(type: Exec) {
commandLine 'vagrant', '--version'
standardOutput = new ByteArrayOutputStream()
doLast {
String version = standardOutput.toString().trim()
if ((version ==~ /Vagrant 1\.[789]\..+/) == false) {
throw new InvalidUserDataException(
"Illegal version of vagrant [${version}]. Need [Vagrant 1.7+]")
}
}
}
task vagrantSmokeTest {
group 'Verification'
description 'Smoke test the specified vagrant boxes'
}
task packagingTest {
group 'Verification'
description "Tests yum/apt packages using vagrant and bats.\n" +
" Specify the vagrant boxes to test using the gradle property 'vagrant.boxes'.\n" +
" 'sample' can be used to test a single yum and apt box. 'all' can be used to\n" +
" test all available boxes. The available boxes are: \n" +
" ${availableBoxes}"
}
// Each box gets it own set of tasks
for (String box : availableBoxes) {
String boxTask = box.capitalize().replace('-', '')
// always add a halt task for all boxes, so clean makes sure they are all shutdown
Task halt = tasks.create("vagrant${boxTask}#halt", VagrantCommandTask) {
boxName box
args 'halt', box
}
stop.dependsOn(halt)
if (boxes.contains(box) == false) {
// we only need a halt task if this box was not specified
continue;
}
Task update = tasks.create("vagrant${boxTask}#update", VagrantCommandTask) {
boxName box
args 'box', 'update', box
dependsOn checkVagrantVersion
}
Task up = tasks.create("vagrant${boxTask}#up", VagrantCommandTask) {
boxName box
/* Its important that we try to reprovision the box even if it already
exists. That way updates to the vagrant configuration take automatically.
That isn't to say that the updates will always be compatible. Its ok to
just destroy the boxes if they get busted but that is a manual step
because its slow-ish. */
/* We lock the provider to virtualbox because the Vagrantfile specifies
lots of boxes that only work properly in virtualbox. Virtualbox is
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
virtualization providers. Thus the lock. */
args 'up', box, '--provision', '--provider', 'virtualbox'
/* 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! */
dependsOn update
}
Task smoke = tasks.create("vagrant${boxTask}#smoketest", Exec) {
dependsOn up
finalizedBy halt
commandLine 'vagrant', 'ssh', box, '--command',
"set -o pipefail && ${smokeTestCommand} | sed -ue 's/^/ ${box}: /'"
}
vagrantSmokeTest.dependsOn(smoke)
Task packaging = tasks.create("packagingTest${boxTask}", BatsOverVagrantTask) {
dependsOn up
finalizedBy halt
boxName box
command testCommand
dependsOn prepareTestRoot
}
packagingTest.dependsOn(packaging)
}