diff --git a/qa/Rakefile b/qa/Rakefile index fdaf91556..5c8ea3cf7 100644 --- a/qa/Rakefile +++ b/qa/Rakefile @@ -1,7 +1,7 @@ require "rspec" require "rspec/core/runner" require "rspec/core/rake_task" -require_relative "vagrant-helpers" +require_relative "vagrant/helpers" require_relative "platform_config" platforms = PlatformConfig.new diff --git a/qa/Vagrantfile b/qa/Vagrantfile index fa98a6f93..280a87594 100644 --- a/qa/Vagrantfile +++ b/qa/Vagrantfile @@ -17,6 +17,10 @@ Vagrant.configure(2) do |config| sh.path = "sys/#{platform.type}/bootstrap.sh" sh.privileged = true end + machine.vm.provision :shell do |sh| + sh.path = "sys/#{platform.type}/user_bootstrap.sh" + sh.privileged = false + end end end end diff --git a/qa/acceptance/spec/lib/artifact_operation_spec.rb b/qa/acceptance/spec/lib/artifact_operation_spec.rb index 49094dba7..faf722673 100644 --- a/qa/acceptance/spec/lib/artifact_operation_spec.rb +++ b/qa/acceptance/spec/lib/artifact_operation_spec.rb @@ -2,12 +2,13 @@ require_relative '../spec_helper' require_relative '../shared_examples/installed' require_relative '../shared_examples/running' +require_relative '../shared_examples/updated' describe "artifacts operation" do config = ServiceTester.configuration config.servers.each do |address| logstash = ServiceTester::Artifact.new(address, config.lookup[address]) it_behaves_like "installable", logstash - it_behaves_like "runnable", logstash + it_behaves_like "updated", logstash end end diff --git a/qa/acceptance/spec/shared_examples/installed.rb b/qa/acceptance/spec/shared_examples/installed.rb index 9ca89ab00..045003433 100644 --- a/qa/acceptance/spec/shared_examples/installed.rb +++ b/qa/acceptance/spec/shared_examples/installed.rb @@ -7,17 +7,17 @@ RSpec.shared_examples "installable" do |logstash| logstash.install(LOGSTASH_VERSION) end - it "is installed on #{logstash.host}" do + it "is installed on #{logstash.hostname}" do expect(logstash).to be_installed end - it "is running on #{logstash.host}" do + it "is running on #{logstash.hostname}" do logstash.start_service expect(logstash).to be_running logstash.stop_service end - it "is removable on #{logstash.host}" do + it "is removable on #{logstash.hostname}" do logstash.uninstall expect(logstash).to be_removed end diff --git a/qa/acceptance/spec/shared_examples/running.rb b/qa/acceptance/spec/shared_examples/running.rb index 0e2166f70..787a43c39 100644 --- a/qa/acceptance/spec/shared_examples/running.rb +++ b/qa/acceptance/spec/shared_examples/running.rb @@ -7,7 +7,7 @@ RSpec.shared_examples "runnable" do |logstash| logstash.install(LOGSTASH_VERSION) end - it "is running on #{logstash.host}" do + it "is running on #{logstash.hostname}" do logstash.start_service expect(logstash).to be_running logstash.stop_service diff --git a/qa/acceptance/spec/shared_examples/updated.rb b/qa/acceptance/spec/shared_examples/updated.rb new file mode 100644 index 000000000..60409a4bd --- /dev/null +++ b/qa/acceptance/spec/shared_examples/updated.rb @@ -0,0 +1,21 @@ +require_relative '../spec_helper' +require 'logstash/version' + +RSpec.shared_examples "updated" do |logstash| + + before (:all) { logstash.snapshot } + after (:all) { logstash.restore } + + it "can update on #{logstash.hostname}" do + logstash.install(LOGSTASH_LATEST_VERSION, "./") + expect(logstash).to be_installed + logstash.install(LOGSTASH_VERSION) + expect(logstash).to be_installed + end + + it "can run on #{logstash.hostname}" do + logstash.start_service + expect(logstash).to be_running + logstash.stop_service + end +end diff --git a/qa/acceptance/spec/spec_helper.rb b/qa/acceptance/spec/spec_helper.rb index 1aefa9192..8cceefd5c 100644 --- a/qa/acceptance/spec/spec_helper.rb +++ b/qa/acceptance/spec/spec_helper.rb @@ -16,7 +16,9 @@ end platform = ENV['LS_TEST_PLATFORM'] || 'all' -config = PlatformConfig.new +config = PlatformConfig.new +LOGSTASH_LATEST_VERSION = config.latest + default_vagrant_boxes = ( platform == 'all' ? config.platforms : config.filter_type(platform) ) selected_boxes = if ENV.include?('LS_VAGRANT_HOST') then diff --git a/qa/config/platforms.json b/qa/config/platforms.json new file mode 100644 index 000000000..d918a4985 --- /dev/null +++ b/qa/config/platforms.json @@ -0,0 +1,16 @@ +{ + "latest": "5.0.0-alpha2", + "platforms" : { + "ubuntu-1204": { "box": "elastic/ubuntu-12.04-x86_64", "type": "debian" }, + "ubuntu-1404": { "box": "elastic/ubuntu-14.04-x86_64", "type": "debian" }, + "ubuntu-1504": { "box": "elastic/ubuntu-15.04-x86_64", "type": "debian" }, + "centos-6": { "box": "elastic/centos-6-x86_64", "type": "redhat" }, + "centos-7": { "box": "elastic/centos-7-x86_64", "type": "redhat" }, + "oel-6": { "box": "elastic/oraclelinux-6-x86_64", "type": "redhat" }, + "oel-7": { "box": "elastic/oraclelinux-7-x86_64", "type": "redhat" }, + "fedora-22": { "box": "elastic/fedora-22-x86_64", "type": "redhat" }, + "debian-8": { "box": "elastic/debian-8-x86_64", "type": "debian" }, + "opensuse-13": { "box": "elastic/opensuse-13-x86_64", "type": "suse" }, + "sles-12": { "box": "elastic/sles-12-x86_64", "type": "suse" } + } +} diff --git a/qa/platform_config.rb b/qa/platform_config.rb index 9827f6ea8..a8c4940d1 100644 --- a/qa/platform_config.rb +++ b/qa/platform_config.rb @@ -5,20 +5,20 @@ class PlatformConfig Platform = Struct.new(:name, :box, :type) - DEFAULT_CONFIG_LOCATION = File.join(File.dirname(__FILE__), "platforms.json").freeze + DEFAULT_CONFIG_LOCATION = File.join(File.dirname(__FILE__), "config", "platforms.json").freeze - attr_reader :platforms + attr_reader :platforms, :latest def initialize(config_path = DEFAULT_CONFIG_LOCATION) @config_path = config_path @platforms = [] data = JSON.parse(File.read(@config_path)) - data.each do |k, v| + data["platforms"].each do |k, v| @platforms << Platform.new(k, v["box"], v["type"]) end - @platforms.sort! { |a, b| a.name <=> b.name } + @latest = data["latest"] end def find!(platform_name) diff --git a/qa/platforms.json b/qa/platforms.json deleted file mode 100644 index 157f87cbe..000000000 --- a/qa/platforms.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "ubuntu-1204": { "box": "elastic/ubuntu-12.04-x86_64", "type": "debian" }, - "ubuntu-1404": { "box": "elastic/ubuntu-14.04-x86_64", "type": "debian" }, - "ubuntu-1504": { "box": "elastic/ubuntu-15.04-x86_64", "type": "debian" }, - "centos-6": { "box": "elastic/centos-6-x86_64", "type": "redhat" }, - "centos-7": { "box": "elastic/centos-7-x86_64", "type": "redhat" }, - "oel-6": { "box": "elastic/oraclelinux-6-x86_64", "type": "redhat" }, - "oel-7": { "box": "elastic/oraclelinux-7-x86_64", "type": "redhat" }, - "fedora-22": { "box": "elastic/fedora-22-x86_64", "type": "redhat" }, - "debian-8": { "box": "elastic/debian-8-x86_64", "type": "debian" }, - "opensuse-13": { "box": "elastic/opensuse-13-x86_64", "type": "suse" }, - "sles-12": { "box": "elastic/sles-12-x86_64", "type": "suse" } -} diff --git a/qa/rspec/commands.rb b/qa/rspec/commands.rb index 8f868ea8c..57c67a814 100644 --- a/qa/rspec/commands.rb +++ b/qa/rspec/commands.rb @@ -20,6 +20,10 @@ module ServiceTester @client = CommandsFactory.fetch(options["type"], options["host"]) end + def hostname + @options["host"] + end + def name "logstash" end @@ -28,6 +32,14 @@ module ServiceTester [@host] end + def snapshot + client.snapshot(@options["host"]) + end + + def restore + client.restore(@options["host"]) + end + def start_service client.start_service(name, host) end @@ -36,8 +48,8 @@ module ServiceTester client.stop_service(name, host) end - def install(version) - package = client.package_for(version) + def install(version, base=ServiceTester::Base::LOCATION) + package = client.package_for(version, base) client.install(package, host) end diff --git a/qa/rspec/commands/base.rb b/qa/rspec/commands/base.rb index 148dcdd9e..0f4f6daa2 100644 --- a/qa/rspec/commands/base.rb +++ b/qa/rspec/commands/base.rb @@ -1,4 +1,5 @@ # encoding: utf-8 +require_relative "../../vagrant/helpers" module ServiceTester @@ -6,6 +7,14 @@ module ServiceTester LOCATION="/logstash-build".freeze + def snapshot(host) + LogStash::VagrantHelpers.save_snapshot(host) + end + + def restore(host) + LogStash::VagrantHelpers.restore_snapshot(host) + end + def start_service(service, host=nil) service_manager(service, "start", host) end diff --git a/qa/rspec/commands/debian.rb b/qa/rspec/commands/debian.rb index 3dabb1d31..e007de88f 100644 --- a/qa/rspec/commands/debian.rb +++ b/qa/rspec/commands/debian.rb @@ -14,8 +14,8 @@ module ServiceTester stdout.match(/^Status: install ok installed$/) end - def package_for(version) - File.join(ServiceTester::Base::LOCATION, "logstash-#{version}_all.deb") + def package_for(version, base=ServiceTester::Base::LOCATION) + File.join(base, "logstash-#{version}_all.deb") end def install(package, host=nil) diff --git a/qa/rspec/commands/redhat.rb b/qa/rspec/commands/redhat.rb index 707261123..d29934da3 100644 --- a/qa/rspec/commands/redhat.rb +++ b/qa/rspec/commands/redhat.rb @@ -14,8 +14,8 @@ module ServiceTester stdout.match(/^logstash.noarch/) end - def package_for(version) - File.join(ServiceTester::Base::LOCATION, "logstash-#{version}.noarch.rpm") + def package_for(version, base=ServiceTester::Base::LOCATION) + File.join(base, "logstash-#{version}.noarch.rpm") end def install(package, host=nil) diff --git a/qa/sys/debian/bootstrap.sh b/qa/sys/debian/bootstrap.sh index 7d385b934..29c2c8403 100644 --- a/qa/sys/debian/bootstrap.sh +++ b/qa/sys/debian/bootstrap.sh @@ -1,4 +1,7 @@ #!/usr/bin/env bash +add-apt-repository ppa:openjdk-r/ppa apt-get update -apt-get install -y openjdk-7-jdk +apt-get install -y openjdk-8-jdk +update-alternatives --config java +update-alternatives --config javac diff --git a/qa/sys/debian/user_bootstrap.sh b/qa/sys/debian/user_bootstrap.sh new file mode 100644 index 000000000..19cd405f5 --- /dev/null +++ b/qa/sys/debian/user_bootstrap.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +VERSION=`cat /vagrant/config/platforms.json | grep latest | cut -d":" -f2 | sed 's/["\|,| ]//g'` +LOGSTASH_FILENAME="logstash-${VERSION}_all.deb" +wget -q https://download.elastic.co/logstash/logstash/packages/debian/$LOGSTASH_FILENAME diff --git a/qa/sys/redhat/user_bootstrap.sh b/qa/sys/redhat/user_bootstrap.sh new file mode 100644 index 000000000..2961e53ec --- /dev/null +++ b/qa/sys/redhat/user_bootstrap.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +VERSION=`cat /vagrant/config/platforms.json | grep latest | cut -d":" -f2 | sed 's/["\|,| ]//g'` +LOGSTASH_FILENAME="logstash-${VERSION}.noarch.rpm" +wget -q https://download.elastic.co/logstash/logstash/packages/centos/$LOGSTASH_FILENAME diff --git a/qa/sys/suse/user_bootstrap.sh b/qa/sys/suse/user_bootstrap.sh new file mode 100644 index 000000000..f1f641af1 --- /dev/null +++ b/qa/sys/suse/user_bootstrap.sh @@ -0,0 +1 @@ +#!/usr/bin/env bash diff --git a/qa/vagrant-helpers.rb b/qa/vagrant-helpers.rb deleted file mode 100644 index 70cb870bb..000000000 --- a/qa/vagrant-helpers.rb +++ /dev/null @@ -1,84 +0,0 @@ -# encoding: utf-8 -require "open3" -require "bundler" - -module LogStash - class CommandExecutor - class CommandError < StandardError; end - - class CommandResponse - attr_reader :stdin, :stdout, :stderr, :exitstatus - - def initialize(stdin, stdout, stderr, exitstatus) - @stdin = stdin, - @stdout = stdout - @stderr = stderr - @exitstatus = exitstatus - end - - def success? - exitstatus == 0 - end - end - - def self.run(cmd) - # This block is require to be able to launch a ruby subprocess - # that use bundler. - Bundler.with_clean_env do - Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr| - CommandResponse.new(stdin, stdout.read.chomp, stderr.read.chomp, wait_thr.value.exitstatus) - end - end - end - - # This method will raise an exception if the `CMD` - # was not run successfully and will display the content of STDERR - def self.run!(cmd) - response = run(cmd) - - unless response.success? - raise CommandError, "CMD: #{cmd} STDERR: #{response.stderr}" - end - response - end - end - - class VagrantHelpers - - def self.halt(machines="") - CommandExecutor.run!("vagrant halt #{machines.join(' ')}") - end - - def self.destroy(machines="") - CommandExecutor.run!("vagrant destroy --force #{machines.join(' ')}") - end - - def self.bootstrap(machines="") - CommandExecutor.run!("vagrant up #{machines.join(' ')}") - end - - def self.fetch_config - cmd = CommandExecutor.run!("vagrant status") - machines = cmd.stdout.split("\n").select { |m| m.include?("running") }.map { |s| s.split(" ")[0] } - CommandExecutor.run!("vagrant ssh-config #{machines.join(' ')}") - end - - def self.parse(lines) - hosts, host = [], {} - lines.each do |line| - if line.match(/Host\s(.*)$/) - host = { :host => line.gsub("Host","").strip } - elsif line.match(/HostName\s(.*)$/) - host[:hostname] = line.gsub("HostName","").strip - elsif line.match(/Port\s(.*)$/) - host[:port] = line.gsub("Port","").strip - elsif line.empty? - hosts << host - host = {} - end - end - hosts << host - hosts - end - end -end diff --git a/qa/vagrant/command.rb b/qa/vagrant/command.rb new file mode 100644 index 000000000..740514df8 --- /dev/null +++ b/qa/vagrant/command.rb @@ -0,0 +1,45 @@ +# encoding: utf-8 +require "open3" +require "bundler" + +module LogStash + class CommandExecutor + class CommandError < StandardError; end + + class CommandResponse + attr_reader :stdin, :stdout, :stderr, :exitstatus + + def initialize(stdin, stdout, stderr, exitstatus) + @stdin = stdin + @stdout = stdout + @stderr = stderr + @exitstatus = exitstatus + end + + def success? + exitstatus == 0 + end + end + + def self.run(cmd) + # This block is require to be able to launch a ruby subprocess + # that use bundler. + Bundler.with_clean_env do + Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr| + CommandResponse.new(stdin, stdout.read.chomp, stderr.read.chomp, wait_thr.value.exitstatus) + end + end + end + + # This method will raise an exception if the `CMD` + # was not run successfully and will display the content of STDERR + def self.run!(cmd) + response = run(cmd) + + unless response.success? + raise CommandError, "CMD: #{cmd} STDERR: #{response.stderr}" + end + response + end + end +end diff --git a/qa/vagrant/helpers.rb b/qa/vagrant/helpers.rb new file mode 100644 index 000000000..1b2a63929 --- /dev/null +++ b/qa/vagrant/helpers.rb @@ -0,0 +1,52 @@ +# encoding: utf-8 +require "open3" +require "bundler" +require_relative "command" + +module LogStash + class VagrantHelpers + + def self.halt(machines="") + CommandExecutor.run!("vagrant halt #{machines.join(' ')}") + end + + def self.destroy(machines="") + CommandExecutor.run!("vagrant destroy --force #{machines.join(' ')}") + end + + def self.bootstrap(machines="") + CommandExecutor.run!("vagrant up #{machines.join(' ')}") + end + + def self.save_snapshot(machine="") + CommandExecutor.run!("vagrant snapshot save #{machine} #{machine}-snapshot") + end + + def self.restore_snapshot(machine="") + CommandExecutor.run!("vagrant snapshot restore #{machine} #{machine}-snapshot") + end + + def self.fetch_config + machines = CommandExecutor.run!("vagrant status").stdout.split("\n").select { |l| l.include?("running") }.map { |r| r.split(' ')[0]} + CommandExecutor.run!("vagrant ssh-config #{machines.join(' ')}") + end + + def self.parse(lines) + hosts, host = [], {} + lines.each do |line| + if line.match(/Host\s(.*)$/) + host = { :host => line.gsub("Host","").strip } + elsif line.match(/HostName\s(.*)$/) + host[:hostname] = line.gsub("HostName","").strip + elsif line.match(/Port\s(.*)$/) + host[:port] = line.gsub("Port","").strip + elsif line.empty? + hosts << host + host = {} + end + end + hosts << host + hosts + end + end +end