diff --git a/TESTING.asciidoc b/TESTING.asciidoc index 75874d09c6f..68740c2b42e 100644 --- a/TESTING.asciidoc +++ b/TESTING.asciidoc @@ -326,152 +326,63 @@ vagrant plugin install vagrant-cachier . Validate your installed dependencies: ------------------------------------- -gradle :qa:vagrant:validate +gradle :qa:vagrant:checkVagrantVersion ------------------------------------- -. Download the VMs. Since Maven or ant or something eats the progress reports -from Vagrant when you run it inside mvn its probably best if you run this one -time to setup all the VMs one at a time. Run this to download and setup the VMs -we use for testing by default: +. Download and smoke test the VMs with `gradle vagrantSmokeTest` or +`gradle vagrantSmokeTestAllDistros`. The first time you run this it will +download the base images and provision the boxes and immediately quit. If you +you this again it'll skip the download step. --------------------------------------------------------- -vagrant up --provision trusty --provider virtualbox && vagrant halt trusty -vagrant up --provision centos-7 --provider virtualbox && vagrant halt centos-7 --------------------------------------------------------- +. Run the tests with `gradle checkPackages`. This will cause gradle to build +the tar, zip, and deb packages and all the plugins. It will then run the tests +on ubuntu-1404 and centos-7. We chose those two distributions as the default +because they cover deb and rpm packaging and SyvVinit and systemd. -or run this to download and setup all the VMs: +You can run on all the VMs by running `gradle checkPackagesAllDistros`. You can +run a particular VM with a command like `gradle checkOel7`. See `gradle tasks` +for a list. Its important to know that if you ctrl-c any of these `gradle` +commands then the boxes will remain running and you'll have to terminate them +with `vagrant halt`. -------------------------------------------------------------------------------- -vagrant halt -for box in $(vagrant status | grep 'poweroff\|not created' | cut -f1 -d' '); do - vagrant up --provision $box --provider virtualbox - vagrant halt $box -done -------------------------------------------------------------------------------- - -. Smoke test the maven/ant dance that we use to get vagrant involved in -integration testing is working: - ---------------------------------------------- -mvn -Dtests.vagrant -Psmoke-vms -pl qa/vagrant verify ---------------------------------------------- - -or this to validate all the VMs: - -------------------------------------------------- -mvn -Dtests.vagrant=all -Psmoke-vms -pl qa/vagrant verify -------------------------------------------------- - -That will start up the VMs and then immediate quit. - -. Finally run the tests. The fastest way to get this started is to run: - ------------------------------------ -mvn clean install -DskipTests -mvn -Dtests.vagrant -pl qa/vagrant verify ------------------------------------ - -You could just run: - --------------------- -mvn -Dtests.vagrant verify --------------------- - -but that will run all the tests. Which is probably a good thing, but not always -what you want. - -Whichever snippet you run mvn will build the tar, zip and deb packages. If you -have rpmbuild installed it'll build the rpm package as well. Then mvn will -spin up trusty and verify the tar, zip, and deb package. If you have rpmbuild -installed it'll spin up centos-7 and verify the tar, zip and rpm packages. We -chose those two distributions as the default because they cover deb and rpm -packaging and SyvVinit and systemd. - -You can control the boxes that are used for testing like so. Run just -fedora-22 with: - --------------------------------------------- -mvn -Dtests.vagrant -pl qa/vagrant verify -DboxesToTest=fedora-22 --------------------------------------------- - -or run jessie and trusty: - ------------------------------------------------------------------- -mvn -Dtests.vagrant -pl qa/vagrant verify -DboxesToTest='jessie, trusty' ------------------------------------------------------------------- - -or run all the boxes: - ---------------------------------------- -mvn -Dtests.vagrant=all -pl qa/vagrant verify ---------------------------------------- - -If you want to run a specific test on several boxes you can do: - ---------------------------------------- -mvn -Dtests.vagrant=all -pl qa/vagrant verify -DtestScripts=*tar*.bats ---------------------------------------- - -Its important to know that if you ctrl-c any of these `mvn` runs that you'll -probably leave a VM up. You can terminate it by running: - ------------- -vagrant halt ------------- - -This is just regular vagrant so you can run normal multi box vagrant commands -to test things manually. Just run: - ---------------------------------------- -vagrant up trusty --provider virtualbox && vagrant ssh trusty ---------------------------------------- - -to get an Ubuntu or - -------------------------------------------- -vagrant up centos-7 --provider virtualbox && vagrant ssh centos-7 -------------------------------------------- - -to get a CentOS. Once you are done with them you should halt them: - -------------------- -vagrant halt trusty -------------------- +All the regular vagrant commands should just work so you can get a shell in a +VM running trusty by running +`vagrant up ubuntu-1404 --provider virtualbox && vagrant ssh ubuntu-1404`. These are the linux flavors the Vagrantfile currently supports: -* precise aka Ubuntu 12.04 -* trusty aka Ubuntu 14.04 -* vivid aka Ubuntun 15.04 -* jessie aka Debian 8, the current debina stable distribution +* ubuntu-1204 aka precise +* ubuntu-1404 aka trusty +* ubuntu-1504 aka vivid +* debian-8 aka jessie, the current debian stable distribution * centos-6 * centos-7 * fedora-22 * oel-7 aka Oracle Enterprise Linux 7 * sles-12 +* opensuse-13 We're missing the following from the support matrix because there aren't high quality boxes available in vagrant atlas: * sles-11 -* opensuse-13 * oel-6 We're missing the follow because our tests are very linux/bash centric: * Windows Server 2012 -Its important to think of VMs like cattle: if they become lame you just shoot +Its important to think of VMs like cattle. If they become lame you just shoot them and let vagrant reprovision them. Say you've hosed your precise VM: ---------------------------------------------------- -vagrant ssh precise -c 'sudo rm -rf /bin'; echo oops +vagrant ssh ubuntu-1404 -c 'sudo rm -rf /bin'; echo oops ---------------------------------------------------- All you've got to do to get another one is ---------------------------------------------- -vagrant destroy -f trusty && vagrant up trusty --provider virtualbox +vagrant destroy -f ubuntu-1404 && vagrant up ubuntu-1404 --provider virtualbox ---------------------------------------------- The whole process takes a minute and a half on a modern laptop, two and a half @@ -489,13 +400,8 @@ vagrant halt vagrant destroy -f ------------------ - ----------- -vagrant up ----------- - -would normally start all the VMs but we've prevented that because that'd -consume a ton of ram. +`vagrant up` would normally start all the VMs but we've prevented that because +that'd consume a ton of ram. == Testing scripts more directly @@ -504,7 +410,7 @@ destructive. When working with a single package its generally faster to run its tests in a tighter loop than maven provides. In one window: -------------------------------- -mvn -pl distribution/rpm package +gradle :distribution:rpm:assemble -------------------------------- and in another window: @@ -518,10 +424,7 @@ sudo bats $BATS/*rpm*.bats If you wanted to retest all the release artifacts on a single VM you could: ------------------------------------------------- -# Build all the distributions fresh but skip recompiling elasticsearch: -mvn -amd -pl distribution install -DskipTests -# Copy them all the testroot -mvn -Dtests.vagrant -pl qa/vagrant pre-integration-test +gradle copyDepsToTestRoot vagrant up trusty --provider virtualbox && vagrant ssh trusty cd $TESTROOT sudo bats $BATS/*.bats diff --git a/Vagrantfile b/Vagrantfile index 7c76e23df8e..32b48f5c610 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -22,15 +22,15 @@ # under the License. Vagrant.configure(2) do |config| - config.vm.define "precise" do |config| + config.vm.define "ubuntu-1204" do |config| config.vm.box = "ubuntu/precise64" ubuntu_common config end - config.vm.define "trusty" do |config| + config.vm.define "ubuntu-1404" do |config| config.vm.box = "ubuntu/trusty64" ubuntu_common config end - config.vm.define "vivid" do |config| + config.vm.define "ubuntu-1504" do |config| config.vm.box = "ubuntu/vivid64" ubuntu_common config, extra: <<-SHELL # Install Jayatana so we can work around it being present. @@ -40,7 +40,7 @@ Vagrant.configure(2) do |config| # Wheezy's backports don't contain Openjdk 8 and the backflips required to # get the sun jdk on there just aren't worth it. We have jessie for testing # debian and it works fine. - config.vm.define "jessie" do |config| + config.vm.define "debian-8" do |config| config.vm.box = "debian/jessie64" deb_common config, 'echo deb http://http.debian.net/debian jessie-backports main > /etc/apt/sources.list.d/backports.list', 'backports' @@ -137,7 +137,7 @@ def deb_common(config, add_openjdk_repository_command, openjdk_list, extra: '') extra: <<-SHELL export DEBIAN_FRONTEND=noninteractive ls /etc/apt/sources.list.d/#{openjdk_list}.list > /dev/null 2>&1 || - (echo "Importing java-8 ppa" && + (echo "==> Importing java-8 ppa" && #{add_openjdk_repository_command} && apt-get update) #{extra} @@ -223,9 +223,11 @@ def provision(config, install() { # Only apt-get update if we haven't in the last day if [ ! -f #{update_tracking_file} ] || [ "x$(find #{update_tracking_file} -mtime +0)" == "x#{update_tracking_file}" ]; then - #{update_command} || true - touch #{update_tracking_file} + echo "==> Updating repository" + #{update_command} || true + touch #{update_tracking_file} fi + echo "==> Installing $1" #{install_command} $1 } ensure() { @@ -242,17 +244,18 @@ def provision(config, installed bats || { # Bats lives in a git repository.... ensure git + echo "==> Installing bats" git clone https://github.com/sstephenson/bats /tmp/bats # Centos doesn't add /usr/local/bin to the path.... /tmp/bats/install.sh /usr rm -rf /tmp/bats } cat \<\ /etc/profile.d/elasticsearch_vars.sh -export ZIP=/elasticsearch/distribution/zip/target/releases -export TAR=/elasticsearch/distribution/tar/target/releases -export RPM=/elasticsearch/distribution/rpm/target/releases -export DEB=/elasticsearch/distribution/deb/target/releases -export TESTROOT=/elasticsearch/qa/vagrant/target/testroot +export ZIP=/elasticsearch/distribution/zip/build/releases +export TAR=/elasticsearch/distribution/tar/build/releases +export RPM=/elasticsearch/distribution/rpm/build/releases +export DEB=/elasticsearch/distribution/deb/build/releases +export TESTROOT=/elasticsearch/qa/vagrant/build/testroot export BATS=/elasticsearch/qa/vagrant/src/test/resources/packaging/scripts VARS SHELL diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index eadf1f63784..137b28964dd 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -63,4 +63,3 @@ eclipse { defaultOutputDir = new File(file('build'), 'eclipse') } } - diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/vagrant/BatsOverVagrantTask.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/vagrant/BatsOverVagrantTask.groovy new file mode 100644 index 00000000000..6af9edd119c --- /dev/null +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/vagrant/BatsOverVagrantTask.groovy @@ -0,0 +1,71 @@ +/* + * 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.vagrant + +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.* +import org.gradle.logging.ProgressLogger +import org.gradle.logging.ProgressLoggerFactory +import org.gradle.process.internal.ExecAction +import org.gradle.process.internal.ExecActionFactory + +import javax.inject.Inject + +/** + * Runs bats over vagrant. Pretty much like running it using Exec but with a + * nicer output formatter. + */ +class BatsOverVagrantTask extends DefaultTask { + String command + String boxName + ExecAction execAction + + BatsOverVagrantTask() { + execAction = getExecActionFactory().newExecAction() + } + + @Inject + ProgressLoggerFactory getProgressLoggerFactory() { + throw new UnsupportedOperationException(); + } + + @Inject + ExecActionFactory getExecActionFactory() { + throw new UnsupportedOperationException(); + } + + void boxName(String boxName) { + this.boxName = boxName + } + + void command(String command) { + this.command = command + } + + @TaskAction + void exec() { + // It'd be nice if --machine-readable were, well, nice + execAction.commandLine(['vagrant', 'ssh', boxName, '--command', command]) + execAction.setStandardOutput(new TapLoggerOutputStream( + command: command, + factory: getProgressLoggerFactory(), + logger: logger)) + execAction.execute(); + } +} diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/vagrant/TapLoggerOutputStream.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/vagrant/TapLoggerOutputStream.groovy new file mode 100644 index 00000000000..65a1aba3c9a --- /dev/null +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/vagrant/TapLoggerOutputStream.groovy @@ -0,0 +1,108 @@ +/* + * 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.vagrant + +import com.carrotsearch.gradle.junit4.LoggingOutputStream +import org.gradle.api.GradleScriptException +import org.gradle.api.InvalidUserDataException +import org.gradle.api.logging.Logger +import org.gradle.logging.ProgressLogger +import org.gradle.logging.ProgressLoggerFactory +import java.util.regex.Matcher + +/** + * Adapts an OutputStream containing output from bats into a ProgressLogger + * and a Logger. Every test output goes to the ProgressLogger and all failures + * and non-test output goes to the Logger. That means you can always glance + * at the result of the last test and the cumulative pass/fail/skip stats and + * the failures are all logged. + * + * There is a Tap4j project but we can't use it because it wants to parse the + * entire TAP stream at once and won't parse it stream-wise. + */ +class TapLoggerOutputStream extends LoggingOutputStream { + ProgressLogger progressLogger + Logger logger + int testsCompleted = 0 + int testsFailed = 0 + int testsSkipped = 0 + Integer testCount + String countsFormat + + TapLoggerOutputStream(Map args) { + logger = args.logger + progressLogger = args.factory.newOperation(VagrantLoggerOutputStream) + progressLogger.setDescription("TAP output for $args.command") + progressLogger.started() + progressLogger.progress("Starting $args.command...") + } + + void flush() { + if (end == start) return + line(new String(buffer, start, end - start)) + start = end + } + + void line(String line) { + // System.out.print "===> $line\n" + if (testCount == null) { + try { + testCount = line.split('\\.').last().toInteger() + def length = (testCount as String).length() + countsFormat = "%0${length}d" + countsFormat = "[$countsFormat|$countsFormat|$countsFormat/$countsFormat]" + return + } catch (Exception e) { + throw new GradleScriptException( + 'Error parsing first line of TAP stream!!', e) + } + } + Matcher m = line =~ /(?ok|not ok) \d+(? # skip (?\(.+\))?)? \[(?.+)\] (?.+)/ + if (!m.matches()) { + /* These might be failure report lines or comments or whatever. Its hard + to tell and it doesn't matter. */ + logger.warn(line) + return + } + boolean skipped = m.group('skip') != null + boolean success = !skipped && m.group('status') == 'ok' + String skipReason = m.group('skipReason') + String suiteName = m.group('suite') + String testName = m.group('test') + + String status + if (skipped) { + status = "SKIPPED" + testsSkipped++ + } else if (success) { + status = " OK" + testsCompleted++ + } else { + status = " FAILED" + testsFailed++ + } + + String counts = sprintf(countsFormat, + [testsCompleted, testsFailed, testsSkipped, testCount]) + progressLogger.progress("Tests $counts, $status [$suiteName] $testName") + if (!success) { + logger.warn(line) + } + } +} diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/vagrant/VagrantCommandTask.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/vagrant/VagrantCommandTask.groovy new file mode 100644 index 00000000000..351c34a893b --- /dev/null +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/vagrant/VagrantCommandTask.groovy @@ -0,0 +1,73 @@ +/* + * 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.vagrant + +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.* +import org.gradle.logging.ProgressLogger +import org.gradle.logging.ProgressLoggerFactory +import org.gradle.process.internal.ExecAction +import org.gradle.process.internal.ExecActionFactory + +import javax.inject.Inject + +/** + * Runs a vagrant command. Pretty much like Exec task but with a nicer output + * formatter and defaults to `vagrant` as first part of commandLine. + */ +class VagrantCommandTask extends DefaultTask { + List commandLine + String boxName + ExecAction execAction + + VagrantCommandTask() { + execAction = getExecActionFactory().newExecAction() + } + + @Inject + ProgressLoggerFactory getProgressLoggerFactory() { + throw new UnsupportedOperationException(); + } + + @Inject + ExecActionFactory getExecActionFactory() { + throw new UnsupportedOperationException(); + } + + void boxName(String boxName) { + this.boxName = boxName + } + + void commandLine(Object... commandLine) { + this.commandLine = commandLine + } + + @TaskAction + void exec() { + // It'd be nice if --machine-readable were, well, nice + execAction.commandLine(['vagrant'] + commandLine) + execAction.setStandardOutput(new VagrantLoggerOutputStream( + command: commandLine.join(' '), + factory: getProgressLoggerFactory(), + /* Vagrant tends to output a lot of stuff, but most of the important + stuff starts with ==> $box */ + squashedPrefix: "==> $boxName: ")) + execAction.execute(); + } +} diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/vagrant/VagrantLoggerOutputStream.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/vagrant/VagrantLoggerOutputStream.groovy new file mode 100644 index 00000000000..e4c3d236b94 --- /dev/null +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/vagrant/VagrantLoggerOutputStream.groovy @@ -0,0 +1,121 @@ +/* + * 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.vagrant + +import com.carrotsearch.gradle.junit4.LoggingOutputStream +import org.gradle.logging.ProgressLogger +import org.gradle.logging.ProgressLoggerFactory + +/** + * Adapts an OutputStream being written to by vagrant into a ProcessLogger. It + * has three hacks to make the output nice: + * + * 1. Attempt to filter out the "unimportant" output from vagrant. Usually + * vagrant prefixes its more important output with "==> $boxname: ". The stuff + * that isn't prefixed that way can just be thrown out. + * + * 2. It also attempts to detect when vagrant does tricks assuming its writing + * to a terminal emulator and renders the output more like gradle users expect. + * This means that progress indicators for things like box downloading work and + * box importing look pretty good. + * + * 3. It catches lines that look like "==> $boxName ==> Heading text" and stores + * the text after the second arrow as a "heading" for use in annotating + * provisioning. It does this because provisioning can spit out _lots_ of text + * and its very easy to lose context when there isn't a scrollback. So we've + * sprinkled `echo "==> Heading text"` into the provisioning scripts for this + * to catch so it can render the output like + * "Heading text > stdout from the provisioner". + */ +class VagrantLoggerOutputStream extends LoggingOutputStream { + static final String HEADING_PREFIX = '==> ' + + ProgressLogger progressLogger + String squashedPrefix + String lastLine = '' + boolean inProgressReport = false + String heading = '' + + VagrantLoggerOutputStream(Map args) { + progressLogger = args.factory.newOperation(VagrantLoggerOutputStream) + progressLogger.setDescription("Vagrant $args.command") + progressLogger.started() + progressLogger.progress("Starting vagrant $args.command...") + squashedPrefix = args.squashedPrefix + } + + void flush() { + if (end == start) return + line(new String(buffer, start, end - start)) + start = end + } + + void line(String line) { + // debugPrintLine(line) // Uncomment me to log every incoming line + if (line.startsWith('\r\u001b')) { + /* We don't want to try to be a full terminal emulator but we want to + keep the escape sequences from leaking and catch _some_ of the + meaning. */ + line = line.substring(2) + if ('[K' == line) { + inProgressReport = true + } + return + } + if (line.startsWith(squashedPrefix)) { + line = line.substring(squashedPrefix.length()) + inProgressReport = false + lastLine = line + if (line.startsWith(HEADING_PREFIX)) { + line = line.substring(HEADING_PREFIX.length()) + heading = line + ' > ' + } else { + line = heading + line + } + } else if (inProgressReport) { + inProgressReport = false + line = lastLine + line + } else { + return + } + // debugLogLine(line) // Uncomment me to log every line we add to the logger + progressLogger.progress(line) + } + + void debugPrintLine(line) { + System.out.print '----------> ' + for (int i = start; i < end; i++) { + switch (buffer[i] as char) { + case ' '..'~': + System.out.print buffer[i] as char + break + default: + System.out.print '%' + System.out.print Integer.toHexString(buffer[i]) + } + } + System.out.print '\n' + } + + void debugLogLine(line) { + System.out.print '>>>>>>>>>>> ' + System.out.print line + System.out.print '\n' + } +} diff --git a/qa/vagrant/build.gradle b/qa/vagrant/build.gradle new file mode 100644 index 00000000000..92e12ec5933 --- /dev/null +++ b/qa/vagrant/build.gradle @@ -0,0 +1,156 @@ +/* + * 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.vagrant.VagrantCommandTask +import org.elasticsearch.gradle.vagrant.BatsOverVagrantTask +import org.gradle.api.InvalidUserDataException + +def testScripts = '2*.bats' // Once the rpm and deb are build this should be *.bats +def testCommand = "cd \$TESTROOT && sudo bats --tap \$BATS/$testScripts" +def smokeTestCommand = 'echo I work' +def representativeBoxes = ['ubuntu-1404', 'centos-7'] +def boxes = representativeBoxes + ['ubuntu-1204', 'ubuntu-1504', 'debian-8', + 'centos-6', 'oel-7', 'fedora-22', 'opensuse-13', 'sles-12'] + +configurations { + test +} + +dependencies { + test project(path: ':distribution:tar', configuration: 'archives') + // NOCOMMMIT: we need the rpm and deb! + // 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(subproj.path) + } + } +} + +task checkPackages { + group 'Verification' + description 'Check the packages against a representative sample of the ' + + 'linux distributions we have in our Vagrantfile' +} + +task checkPackagesAllDistros { + group 'Verification' + description 'Check the packages against all the linux distributions we ' + + 'have in our Vagrantfile' +} + +task clean(type: Delete) { + group = 'Build' + delete buildDir +} + +task copyDepsToTestRoot(type: Copy) { + description "Dump bats test dependencies into the \$TESTROOT." + into "$buildDir/testroot" + from configurations.test +} + +task checkVagrantVersion(type: Exec) { + group 'Package Verification' + description 'Check that the version of vagrant is ok' + commandLine 'vagrant', '--version' + standardOutput = new ByteArrayOutputStream() + doLast { + def 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 'Vagrant' + description 'Smoke test some representative distros from the Vagrantfile' +} + +task vagrantSmokeTestAllDistros { + group 'Vagrant' + description 'Smoke test all distros from the Vagrantfile' +} + +// Each box gets it own set of tasks +boxes.each { box -> + def boxTask = taskifyBoxName box + task "vagrantUp$boxTask"(type: VagrantCommandTask) { + group 'Vagrant' + description "Startup a vagrant VM running $box" + 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. */ + commandLine '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 checkVagrantVersion + } + task "vagrantHalt$boxTask"(type: VagrantCommandTask) { + group 'Vagrant' + description "Shutdown the vagrant VM running $box" + boxName box + commandLine 'halt', box + } + + task "smokeTest$boxTask"(type: Exec) { + group 'Vagrant' + description "Smoke test the $box VM" + dependsOn "vagrantUp$boxTask" + finalizedBy "vagrantHalt$boxTask" + commandLine 'vagrant', 'ssh', box, '--command', + "set -o pipefail && $smokeTestCommand | sed -ue \'s/^/ $box: /'" + vagrantSmokeTestAllDistros.dependsOn name + if (representativeBoxes.contains(box)) { + vagrantSmokeTest.dependsOn name + } + } + + task "check$boxTask"(type: BatsOverVagrantTask) { + group 'Package Verification' + description "Run packaging tests against $box" + dependsOn "vagrantUp$boxTask" + finalizedBy "vagrantHalt$boxTask" + boxName box + command testCommand + dependsOn copyDepsToTestRoot + checkPackagesAllDistros.dependsOn name + if (representativeBoxes.contains(box)) { + checkPackages.dependsOn name + } + } +} + + +// Twists the box name into a sensible task name +def taskifyBoxName(box) { + box.capitalize().replace('-', '') +} diff --git a/qa/vagrant/pom.xml b/qa/vagrant/pom.xml deleted file mode 100644 index e303da5b6a2..00000000000 --- a/qa/vagrant/pom.xml +++ /dev/null @@ -1,413 +0,0 @@ - - - 4.0.0 - - org.elasticsearch.qa - elasticsearch-qa - 3.0.0-SNAPSHOT - - - qa-vagrant - QA: Elasticsearch Vagrant Tests - Tests the Elasticsearch distribution artifacts on virtual - machines using vagrant and bats. - pom - - - - *.bats - sudo bats $BATS/${testScripts} - - precise, trusty, vivid, jessie - centos-6, centos-7, oel-7, fedora-22, opensuse-13, sles-12 - - trusty - centos-7 - - - - - /usr/bin/rpmbuild - - - 2.0.0-beta1 - - - - - - - maven-clean-plugin - - - clean-testroot - pre-integration-test - - clean - - - true - - - ${project.build.directory}/testroot - - - - - - - - - maven-dependency-plugin - - - copy-common-to-testroot - pre-integration-test - - copy - - - ${project.build.directory}/testroot - - - org.elasticsearch.distribution.zip - elasticsearch - ${elasticsearch.version} - zip - - - org.elasticsearch.distribution.tar - elasticsearch - ${elasticsearch.version} - tar.gz - - - org.elasticsearch.distribution.deb - elasticsearch - ${elasticsearch.version} - deb - - - - org.elasticsearch.distribution.deb - elasticsearch - ${upgrade.from.version} - deb - - - org.elasticsearch.plugin - jvm-example - ${elasticsearch.version} - zip - - - org.elasticsearch.plugin - analysis-icu - ${elasticsearch.version} - zip - - - org.elasticsearch.plugin - analysis-kuromoji - ${elasticsearch.version} - zip - - - org.elasticsearch.plugin - analysis-phonetic - ${elasticsearch.version} - zip - - - org.elasticsearch.plugin - analysis-smartcn - ${elasticsearch.version} - zip - - - org.elasticsearch.plugin - analysis-stempel - ${elasticsearch.version} - zip - - - org.elasticsearch.plugin - discovery-gce - ${elasticsearch.version} - zip - - - org.elasticsearch.plugin - delete-by-query - ${elasticsearch.version} - zip - - - org.elasticsearch.plugin - discovery-azure - ${elasticsearch.version} - zip - - - org.elasticsearch.plugin - discovery-ec2 - ${elasticsearch.version} - zip - - - org.elasticsearch.plugin - discovery-multicast - ${elasticsearch.version} - zip - - - org.elasticsearch.plugin - lang-expression - ${elasticsearch.version} - zip - - - org.elasticsearch.plugin - lang-groovy - ${elasticsearch.version} - zip - - - org.elasticsearch.plugin - lang-javascript - ${elasticsearch.version} - zip - - - org.elasticsearch.plugin - lang-python - ${elasticsearch.version} - zip - - - org.elasticsearch.plugin - mapper-murmur3 - ${elasticsearch.version} - zip - - - org.elasticsearch.plugin - mapper-size - ${elasticsearch.version} - zip - - - org.elasticsearch.plugin - repository-azure - ${elasticsearch.version} - zip - - - org.elasticsearch.plugin - repository-s3 - ${elasticsearch.version} - zip - - - org.elasticsearch.plugin - store-smb - ${elasticsearch.version} - zip - - - org.elasticsearch.plugin - site-example - ${elasticsearch.version} - zip - - - - - - - - org.apache.maven.plugins - maven-antrun-plugin - - - ant-contrib - ant-contrib - 1.0b3 - - - ant - ant - - - - - - - check-vagrant-version - validate - - run - - - - - - - - - - setup-version-files - pre-integration-test - - run - - - - - - - - - - test-vms - integration-test - - run - - - - - - - - - - - - - - - - - rpm - - - ${packaging.rpm.rpmbuild} - - - - - - maven-dependency-plugin - - - copy-rpm-to-testroot - pre-integration-test - - copy - - - ${project.build.directory}/testroot - - - org.elasticsearch.distribution.rpm - elasticsearch - ${elasticsearch.version} - rpm - - - - org.elasticsearch.distribution.rpm - elasticsearch - ${upgrade.from.version} - rpm - - - - - - - - - - ok - - - - - rpm-via-homebrew - - - /usr/local/bin/rpmbuild - - - - - - maven-dependency-plugin - - - copy-rpm-to-testroot - pre-integration-test - - copy - - - ${project.build.directory}/testroot - - - org.elasticsearch.distribution.rpm - elasticsearch - ${elasticsearch.version} - rpm - - - - org.elasticsearch.distribution.rpm - elasticsearch - ${upgrade.from.version} - rpm - - - - - - - - - - ok - - - - - - - smoke-vms - - echo skipping tests - - - - diff --git a/qa/vagrant/src/dev/ant/vagrant-integration-tests.xml b/qa/vagrant/src/dev/ant/vagrant-integration-tests.xml deleted file mode 100644 index 67b208803b9..00000000000 --- a/qa/vagrant/src/dev/ant/vagrant-integration-tests.xml +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/qa/vagrant/src/test/resources/packaging/scripts/packaging_test_utils.bash b/qa/vagrant/src/test/resources/packaging/scripts/packaging_test_utils.bash index 666e4881eb5..11961e06921 100644 --- a/qa/vagrant/src/test/resources/packaging/scripts/packaging_test_utils.bash +++ b/qa/vagrant/src/test/resources/packaging/scripts/packaging_test_utils.bash @@ -417,9 +417,7 @@ run_elasticsearch_tests() { }' | grep \"count\"\ :\ 1 curl -s -XGET 'http://localhost:9200/library/book/_search/template?pretty' -d '{ - "template": { - "file": "is_guide" - } + "file": "is_guide" }' | grep \"total\"\ :\ 1 curl -s -XDELETE 'http://localhost:9200/_all' diff --git a/qa/vagrant/src/test/resources/packaging/scripts/plugins.bash b/qa/vagrant/src/test/resources/packaging/scripts/plugins.bash index 8052fc1340c..7200f28b139 100644 --- a/qa/vagrant/src/test/resources/packaging/scripts/plugins.bash +++ b/qa/vagrant/src/test/resources/packaging/scripts/plugins.bash @@ -149,7 +149,7 @@ install_and_check_plugin() { # $2 description of the source of the plugin list compare_plugins_list() { cat $1 | sort > /tmp/plugins - ls /elasticsearch/plugins/*/pom.xml | cut -d '/' -f 4 | + ls /elasticsearch/plugins/*/build.gradle | cut -d '/' -f 4 | sort > /tmp/expected echo "Checking plugins from $2 (<) against expected plugins (>):" diff /tmp/expected /tmp/plugins diff --git a/settings.gradle b/settings.gradle index 296026b7c08..ac09ea65557 100644 --- a/settings.gradle +++ b/settings.gradle @@ -30,7 +30,8 @@ String[] projects = [ 'plugins:site-example', 'plugins:store-smb', 'qa:smoke-test-client', - 'qa:smoke-test-plugins' + 'qa:smoke-test-plugins', + 'qa:vagrant', ] if (hasProperty('elasticsearch.projectsPrefix')) { @@ -39,4 +40,3 @@ if (hasProperty('elasticsearch.projectsPrefix')) { } include projects -