Created
May 3, 2010 18:43
-
-
Save gnufied/388435 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
module Tickle | |
extend self | |
def load_rails_environment(environment) | |
ENV["RAILS_ENV"] = environment | |
Object.const_set :RAILS_ENV, environment | |
require(File.join(RAILS_ROOT, 'config', 'environment')) | |
$: << "#{Rails.root}/test" | |
require "#{Rails.root}/test/test_helper" | |
end | |
def run_tests(dir, n = 2) | |
dir = "#{Rails.root}/test/#{dir}/**/*_test.rb" unless dir.index(Rails.root.to_s) | |
groups = Dir[dir].sort.in_groups(n, false) | |
pids = fork_tests(groups) | |
Signal.trap 'SIGINT', lambda { pids.each {|p| Process.kill("KILL", p)}; exit 1 } | |
errors = Process.waitall.map { |pid,status| status.exitstatus } | |
raise "Error running test" if(errors.any? { |x| x != 0 }) | |
end | |
def run_cucumber(n = 2) | |
dir = Dir["#{Rails.root}/features/*.feature"] | |
groups = dir.sort.in_groups(n,false) | |
p groups | |
pids = fork_cucumber(groups) | |
Signal.trap 'SIGINT', lambda { pids.each {|p| Process.kill("KILL", p)}; exit 1 } | |
errors = Process.waitall.map { |pid,status| status.exitstatus } | |
raise "Error running cucumber" if(errors.any? { |x| x != 0 }) | |
end | |
def fork_cucumber(groups) | |
pids = [] | |
GC.start | |
groups.each_with_index do |group,db_counter| | |
if(!group.empty?) | |
pids << Process.fork do | |
files = group.find_all {|f| f !~ /^-/ } | |
prepare_analyzer() | |
ENV["RAILS_ENV"] = 'cucumber' | |
Object.const_set :RAILS_ENV, 'cucumber' | |
require(File.join(RAILS_ROOT, 'config', 'environment')) | |
prepare_databse(db_counter) unless try_migration_first(db_counter) | |
require "cucumber/cli/main" | |
cucumber_options = get_cucumber_options(files) | |
failure = Cucumber::Cli::Main.execute(cucumber_options) | |
raise "Cucumber failed" if failure | |
end | |
end | |
end | |
pids | |
end | |
def fork_tests(groups) | |
pids = [] | |
GC.start | |
groups.each_with_index do |group, db_counter| | |
pids << Process.fork { child_run(group,db_counter) } | |
end | |
pids | |
end | |
def get_cucumber_options(files) | |
args = ( | |
['-m'] + ['-q'] + | |
files | |
).flatten.compact | |
args | |
end | |
def child_run(group,db_counter) | |
prepare_analyzer() | |
load_rails_environment('test') | |
prepare_databse(db_counter) unless try_migration_first(db_counter) | |
files = group.find_all {|f| f !~ /^-/ } | |
files.each { |f| load(f) } | |
end | |
def prepare_analyzer() | |
saved_aggregate_data = rcov_load_aggregate_data($options.aggregate_file) | |
if(saved_aggregate_data[:coverage]) | |
$rcov_code_coverage_analyzer = saved_aggregate_data[:coverage] | |
end | |
$rcov_code_coverage_analyzer.install_hook | |
end | |
def try_migration_first(db_counter) | |
begin | |
db_config = get_connection_config(db_counter) | |
ActiveRecord::Base.establish_connection(db_config) | |
ActiveRecord::Base.connection() | |
migrate_db() | |
return true | |
rescue Exception => e | |
puts "Error runnig miration #{e.inspect}" | |
puts e.backtrace | |
return false | |
end | |
end | |
def prepare_databse(db_counter) | |
create_db_using_raw_sql(db_counter) | |
try_migration_first(db_counter) | |
end | |
def create_db_using_raw_sql(db_counter) | |
test_config = get_connection_config(db_counter) | |
sql_connection = Mysql.connect(test_config["host"] || "localhost", | |
test_config["username"], | |
test_config["password"], | |
nil, | |
test_config["port"] || 3306) | |
sql_connection.real_query("DROP database IF EXISTS #{test_config["database"]}") | |
sql_connection.real_query("CREATE DATABASE #{test_config["database"]}") | |
sql_connection.close() | |
end | |
def migrate_db | |
ENV["VERBOSE"] = "false" | |
Rake::Task["db:migrate"].invoke | |
end | |
def get_connection_config(db_counter) | |
default_settings = config["test"].clone() | |
default_settings["database"] = "#{default_settings["database"]}_#{db_counter}" | |
default_settings | |
end | |
def config | |
ActiveRecord::Base.configurations | |
end | |
def rcov_load_aggregate_data(file) | |
begin | |
old_data = nil | |
Zlib::GzipReader.open(file){|gz| old_data = Marshal.load(gz) } | |
rescue | |
old_data = {} | |
end | |
old_data || {} | |
end | |
def rcov_save_aggregate_data(file) | |
Zlib::GzipWriter.open(file) do |f| | |
Marshal.dump({:callsites => nil, :coverage => $rcov_code_coverage_analyzer}, f) | |
end | |
end | |
def make_formatter(klass,options) | |
klass.new(:destdir => options.destdir, :color => options.color, | |
:fsr => options.range, :textmode => options.textmode, | |
:ignore => options.skip, :dont_ignore => options.include, | |
:sort => options.sort, | |
:sort_reverse => options.sort_reverse, | |
:output_threshold => options.output_threshold, | |
:callsite_analyzer => nil, | |
:coverage_diff_mode => options.coverage_diff_mode, | |
:coverage_diff_file => options.coverage_diff_file, | |
:callsites => options.callsites, | |
:cross_references => options.crossrefs, | |
:diff_cmd => options.diff_cmd, | |
:comments_run_by_default => options.comments_run_by_default, | |
:gcc_output => options.gcc_output, | |
:charset => options.charset, | |
:css => options.css, | |
:failure_threshold => options.failure_threshold | |
) | |
end | |
def fetch_rcov_options | |
{ | |
:color => true, :range => 30.0, :profiling => false, | |
:destdir => "coverage", :loadpaths => ["test"], :textmode => false, | |
:skip => Rcov::BaseFormatter::DEFAULT_OPTS[:ignore], :include => [], | |
:html => true, :css => nil, :comments_run_by_default => false, | |
:test_unit_only => false, :spec_only => false, :sort => :name, | |
:sort_reverse => false, :output_threshold => 101, :failure_threshold => nil, | |
:replace_prog_name => false, :callsites => false, :crossrefs => false, | |
:coverage_diff_file => "coverage.info", :coverage_diff_mode => :compare, | |
:coverage_diff_save => false, :diff_cmd => "diff", | |
:report_rcov_bug_for => nil, :aggregate_file => "coverage.data", | |
:gcc_output => false, :charset => nil | |
} | |
end | |
end |
This file contains hidden or 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 File.join(File.dirname(__FILE__), "../lib/tickle") | |
require "rcov" | |
require "ostruct" | |
require "zlib" | |
require "cucumber" | |
require "cucumber/platform" | |
# Yanked from Rails | |
desc 'Run all unit, functional and integration tests' | |
task :tickle, :count do |t, args| | |
$options = OpenStruct.new(Tickle.fetch_rcov_options) | |
p $options | |
$options.skip.concat [%r{\bvendor/},%r{\bconfig/},%r{\benvironment/},%r{\bfeatures/}] | |
saved_aggregate_data = Tickle.rcov_load_aggregate_data($options.aggregate_file) | |
if(saved_aggregate_data[:coverage]) | |
$rcov_code_coverage_analyzer = saved_aggregate_data[:coverage] | |
else | |
$rcov_code_coverage_analyzer = Rcov::CodeCoverageAnalyzer.new | |
end | |
$rcov_callsite_analyzer = nil | |
formatters = [] | |
formatters << Tickle.make_formatter(Rcov::HTMLCoverage,$options) | |
END { | |
puts "########## Running End block ##########" | |
$rcov_code_coverage_analyzer.remove_hook | |
$rcov_code_coverage_analyzer.dump_coverage_info(formatters) | |
Tickle.rcov_save_aggregate_data($options.aggregate_file) | |
} | |
errors = %w(tickle:units tickle:functionals tickle:cucumber).collect do |task| | |
begin | |
Rake::Task[task].invoke(args[:count]) | |
nil | |
rescue => e | |
puts e | |
puts e.backtrace | |
task | |
end | |
end.compact | |
abort "Errors running #{errors.to_sentence}!" if errors.any? | |
end | |
namespace :tickle do | |
[:units, :functionals].each do |t| | |
type = t.to_s.sub(/s$/, '') | |
desc "Run #{type} tests" | |
task t, :count do |t, args| | |
size = args[:count] ? args[:count].to_i : 2 | |
puts "Running #{type} tests using #{size} processes" | |
Tickle.run_tests type, size | |
end | |
end | |
desc "Run cucumeber:tickle test" | |
task :cucumber do |args| | |
size = 2 | |
puts "Running cucumber tests using #{size} processes" | |
Tickle.run_cucumber(2) | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment