Introduction of an update scenario for artifacts, including snapshot/restore for VM's and initial schema for this scenario.

Some other minor changes include:

* add back the user level boostrap scripts, useful in that case to pull latest released LS
* cleanup formatting for specs and fixed bootstrap scripts for redhats
* make the latest logstash version available from the current platform config file
* make sure debian based machines use java8
* make sure to use hostname and not just ip:port address when reporting the names

Fixes #5350
This commit is contained in:
Pere Urbon-Bayes 2016-05-04 14:41:41 +02:00
parent ced5e5e020
commit e52bda64c6
21 changed files with 194 additions and 115 deletions

View file

@ -1,7 +1,7 @@
require "rspec" require "rspec"
require "rspec/core/runner" require "rspec/core/runner"
require "rspec/core/rake_task" require "rspec/core/rake_task"
require_relative "vagrant-helpers" require_relative "vagrant/helpers"
require_relative "platform_config" require_relative "platform_config"
platforms = PlatformConfig.new platforms = PlatformConfig.new

4
qa/Vagrantfile vendored
View file

@ -17,6 +17,10 @@ Vagrant.configure(2) do |config|
sh.path = "sys/#{platform.type}/bootstrap.sh" sh.path = "sys/#{platform.type}/bootstrap.sh"
sh.privileged = true sh.privileged = true
end end
machine.vm.provision :shell do |sh|
sh.path = "sys/#{platform.type}/user_bootstrap.sh"
sh.privileged = false
end
end end
end end
end end

View file

@ -2,12 +2,13 @@
require_relative '../spec_helper' require_relative '../spec_helper'
require_relative '../shared_examples/installed' require_relative '../shared_examples/installed'
require_relative '../shared_examples/running' require_relative '../shared_examples/running'
require_relative '../shared_examples/updated'
describe "artifacts operation" do describe "artifacts operation" do
config = ServiceTester.configuration config = ServiceTester.configuration
config.servers.each do |address| config.servers.each do |address|
logstash = ServiceTester::Artifact.new(address, config.lookup[address]) logstash = ServiceTester::Artifact.new(address, config.lookup[address])
it_behaves_like "installable", logstash it_behaves_like "installable", logstash
it_behaves_like "runnable", logstash it_behaves_like "updated", logstash
end end
end end

View file

@ -7,17 +7,17 @@ RSpec.shared_examples "installable" do |logstash|
logstash.install(LOGSTASH_VERSION) logstash.install(LOGSTASH_VERSION)
end end
it "is installed on #{logstash.host}" do it "is installed on #{logstash.hostname}" do
expect(logstash).to be_installed expect(logstash).to be_installed
end end
it "is running on #{logstash.host}" do it "is running on #{logstash.hostname}" do
logstash.start_service logstash.start_service
expect(logstash).to be_running expect(logstash).to be_running
logstash.stop_service logstash.stop_service
end end
it "is removable on #{logstash.host}" do it "is removable on #{logstash.hostname}" do
logstash.uninstall logstash.uninstall
expect(logstash).to be_removed expect(logstash).to be_removed
end end

View file

@ -7,7 +7,7 @@ RSpec.shared_examples "runnable" do |logstash|
logstash.install(LOGSTASH_VERSION) logstash.install(LOGSTASH_VERSION)
end end
it "is running on #{logstash.host}" do it "is running on #{logstash.hostname}" do
logstash.start_service logstash.start_service
expect(logstash).to be_running expect(logstash).to be_running
logstash.stop_service logstash.stop_service

View file

@ -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

View file

@ -17,6 +17,8 @@ end
platform = ENV['LS_TEST_PLATFORM'] || 'all' 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) ) default_vagrant_boxes = ( platform == 'all' ? config.platforms : config.filter_type(platform) )
selected_boxes = if ENV.include?('LS_VAGRANT_HOST') then selected_boxes = if ENV.include?('LS_VAGRANT_HOST') then

16
qa/config/platforms.json Normal file
View file

@ -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" }
}
}

View file

@ -5,20 +5,20 @@ class PlatformConfig
Platform = Struct.new(:name, :box, :type) 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) def initialize(config_path = DEFAULT_CONFIG_LOCATION)
@config_path = config_path @config_path = config_path
@platforms = [] @platforms = []
data = JSON.parse(File.read(@config_path)) 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"]) @platforms << Platform.new(k, v["box"], v["type"])
end end
@platforms.sort! { |a, b| a.name <=> b.name } @platforms.sort! { |a, b| a.name <=> b.name }
@latest = data["latest"]
end end
def find!(platform_name) def find!(platform_name)

View file

@ -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" }
}

View file

@ -20,6 +20,10 @@ module ServiceTester
@client = CommandsFactory.fetch(options["type"], options["host"]) @client = CommandsFactory.fetch(options["type"], options["host"])
end end
def hostname
@options["host"]
end
def name def name
"logstash" "logstash"
end end
@ -28,6 +32,14 @@ module ServiceTester
[@host] [@host]
end end
def snapshot
client.snapshot(@options["host"])
end
def restore
client.restore(@options["host"])
end
def start_service def start_service
client.start_service(name, host) client.start_service(name, host)
end end
@ -36,8 +48,8 @@ module ServiceTester
client.stop_service(name, host) client.stop_service(name, host)
end end
def install(version) def install(version, base=ServiceTester::Base::LOCATION)
package = client.package_for(version) package = client.package_for(version, base)
client.install(package, host) client.install(package, host)
end end

View file

@ -1,4 +1,5 @@
# encoding: utf-8 # encoding: utf-8
require_relative "../../vagrant/helpers"
module ServiceTester module ServiceTester
@ -6,6 +7,14 @@ module ServiceTester
LOCATION="/logstash-build".freeze 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) def start_service(service, host=nil)
service_manager(service, "start", host) service_manager(service, "start", host)
end end

View file

@ -14,8 +14,8 @@ module ServiceTester
stdout.match(/^Status: install ok installed$/) stdout.match(/^Status: install ok installed$/)
end end
def package_for(version) def package_for(version, base=ServiceTester::Base::LOCATION)
File.join(ServiceTester::Base::LOCATION, "logstash-#{version}_all.deb") File.join(base, "logstash-#{version}_all.deb")
end end
def install(package, host=nil) def install(package, host=nil)

View file

@ -14,8 +14,8 @@ module ServiceTester
stdout.match(/^logstash.noarch/) stdout.match(/^logstash.noarch/)
end end
def package_for(version) def package_for(version, base=ServiceTester::Base::LOCATION)
File.join(ServiceTester::Base::LOCATION, "logstash-#{version}.noarch.rpm") File.join(base, "logstash-#{version}.noarch.rpm")
end end
def install(package, host=nil) def install(package, host=nil)

View file

@ -1,4 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
add-apt-repository ppa:openjdk-r/ppa
apt-get update 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

View file

@ -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

View file

@ -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

View file

@ -0,0 +1 @@
#!/usr/bin/env bash

View file

@ -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

45
qa/vagrant/command.rb Normal file
View file

@ -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

52
qa/vagrant/helpers.rb Normal file
View file

@ -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