Created
December 17, 2013 22:59
-
-
Save vincentbernat/8014225 to your computer and use it in GitHub Desktop.
Rakefile for running parallel serverspec
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rake' | |
require 'rspec/core/rake_task' | |
require 'xpool' | |
require 'colorize' | |
$REPORTS = "./reports" # Where to store JSON reports | |
$PARALLEL = 10 # How many parallel tasks should we run? | |
# Return all roles of a given host | |
def roles(host) | |
roles = [ "all" ] | |
case host | |
when /^blm-web-/ | |
roles << "web" | |
when /^blm-memc-/ | |
roles << "memcache" | |
when /^blm-lb-/ | |
roles << "lb" | |
when /^blm-bigdata-/ | |
roles << "bigdata" | |
when /^blm-proxy-/ | |
roles << "proxy" | |
end | |
return roles | |
end | |
# Run RSpec in the background. It is important to define this before | |
# creating a pool. | |
class BackgroundServerspecTask | |
def run(verbose, target, command) | |
print "[..] ".blue if verbose | |
puts target if verbose | |
ENV['TARGET_HOST'] = target | |
system(command) | |
print "[OK] ".green if verbose | |
puts target if verbose | |
end | |
def recover(e) | |
print "[ERROR] ".red | |
puts e.to_s | |
end | |
end | |
# Special version of RakeTask that will be executed using a process | |
# pool. This process pool is handled by xpool. | |
class ServerspecTask < RSpec::Core::RakeTask | |
attr_accessor :target | |
@@pool = XPool.new $PARALLEL | |
def self.shutdown | |
@@pool.shutdown | |
end | |
def run_task(verbose) | |
@rspec_opts = ["--format", "json", "--out", "#{$REPORTS}/report-#{target}.json"] | |
command = spec_command | |
@@pool.schedule BackgroundServerspecTask.new, verbose, target, command | |
end | |
end | |
hosts = File.foreach(ENV["HOSTS"] || "./hosts") | |
.map { |line| line.strip } | |
.map do |host| | |
{ | |
:name => host.strip, | |
:roles => roles(host.strip), | |
} | |
end | |
desc "Run serverspec to all hosts" | |
task :spec => "check:server:all" | |
namespace :check do | |
# Per server tasks | |
namespace :server do | |
desc "Run serverspec to all hosts" | |
task :all => hosts.map { |h| "check:server:" + h[:name] } | |
hosts.each do |host| | |
desc "Run serverspec to host #{host[:name]}" | |
ServerspecTask.new(host[:name].to_sym) do |t| | |
t.target = host[:name] | |
t.pattern = './spec/{' + host[:roles].join(",") + '}*_spec.rb' | |
end | |
end | |
end | |
# Per role tasks | |
namespace :role do | |
roles = hosts.map {|h| h[:roles]} | |
roles = roles.flatten.uniq | |
roles.each do |role| | |
hosts.select { |h| h[:roles].include? role }.each do |host| | |
desc "Run serverspec to role #{role}" | |
ServerspecTask.new(role.to_sym) do |t| | |
t.target = host[:name] | |
t.pattern = "./spec/#{role}/*_spec.rb" | |
end | |
end | |
end | |
end | |
end | |
namespace :reports do | |
desc "Clean up old reports" | |
task :clean do | |
FileUtils.rm_rf $REPORTS | |
end | |
end | |
check_tasks = Rake.application.top_level_tasks.select { |task| task.start_with?("check:") } | |
puts check_tasks | |
if not check_tasks.empty? then | |
# Before starting, cleanup reports | |
Rake::Task[check_tasks.first].enhance [ "reports:clean" ] | |
end | |
Kernel.at_exit do | |
ServerspecTask.shutdown | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment