parallel_tests 0.8.12 → 0.8.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile.lock +1 -1
- data/lib/parallel_tests.rb +0 -16
- data/lib/parallel_tests/tasks.rb +72 -37
- data/lib/parallel_tests/version.rb +1 -1
- data/spec/parallel_tests/tasks_spec.rb +134 -0
- data/spec/parallel_tests_spec.rb +0 -22
- metadata +5 -4
data/Gemfile.lock
CHANGED
data/lib/parallel_tests.rb
CHANGED
@@ -12,22 +12,6 @@ module ParallelTests
|
|
12
12
|
].detect{|c| not c.to_s.strip.empty? }.to_i
|
13
13
|
end
|
14
14
|
|
15
|
-
# parallel:spec[:count, :pattern, :options]
|
16
|
-
def self.parse_rake_args(args)
|
17
|
-
# order as given by user
|
18
|
-
args = [args[:count], args[:pattern], args[:options]]
|
19
|
-
|
20
|
-
# count given or empty ?
|
21
|
-
# parallel:spec[2,models,options]
|
22
|
-
# parallel:spec[,models,options]
|
23
|
-
count = args.shift if args.first.to_s =~ /^\d*$/
|
24
|
-
num_processes = count.to_i unless count.to_s.empty?
|
25
|
-
pattern = args.shift
|
26
|
-
options = args.shift
|
27
|
-
|
28
|
-
[num_processes, pattern.to_s, options.to_s]
|
29
|
-
end
|
30
|
-
|
31
15
|
# copied from http://github.com/carlhuda/bundler Bundler::SharedHelpers#find_gemfile
|
32
16
|
def self.bundler_enabled?
|
33
17
|
return true if Object.const_defined?(:Bundler)
|
data/lib/parallel_tests/tasks.rb
CHANGED
@@ -1,48 +1,82 @@
|
|
1
|
-
|
2
|
-
rails_env = ENV['RAILS_ENV'] || 'test'
|
1
|
+
require 'rake'
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
module ParallelTests
|
4
|
+
module Tasks
|
5
|
+
class << self
|
6
|
+
def rails_env
|
7
|
+
ENV['RAILS_ENV'] || 'test'
|
8
|
+
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
# - sed changes 1 exitstatus to 0
|
18
|
-
# - pipefail makes pipe fail with exitstatus of first failed command
|
19
|
-
# - pipefail is not supported in (zsh)
|
20
|
-
# - defining a new rake task like silence_schema would force users to load parallel_tests in test env
|
21
|
-
# - do not use ' since run_in_parallel uses them to quote stuff
|
22
|
-
# - simple system "set -o pipefail" returns nil even though set -o pipefail exists with 0
|
23
|
-
def parallel_tests_suppress_output(command, ignore_regex)
|
24
|
-
activate_pipefail = "set -o pipefail"
|
25
|
-
remove_ignored_lines = %Q{(grep -v "#{ignore_regex}" || test 1)}
|
10
|
+
def run_in_parallel(cmd, options={})
|
11
|
+
count = " -n #{options[:count]}" if options[:count]
|
12
|
+
executable = File.expand_path("../../../bin/parallel_test", __FILE__)
|
13
|
+
command = "#{executable} --exec '#{cmd}'#{count}#{' --non-parallel' if options[:non_parallel]}"
|
14
|
+
abort unless system(command)
|
15
|
+
end
|
26
16
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
17
|
+
# this is a crazy-complex solution for a very simple problem:
|
18
|
+
# removing certain lines from the output without chaning the exit-status
|
19
|
+
# normally I'd not do this, but it has been lots of fun and a great learning experience :)
|
20
|
+
#
|
21
|
+
# - sed does not support | without -r
|
22
|
+
# - grep changes 0 exitstatus to 1 if nothing matches
|
23
|
+
# - sed changes 1 exitstatus to 0
|
24
|
+
# - pipefail makes pipe fail with exitstatus of first failed command
|
25
|
+
# - pipefail is not supported in (zsh)
|
26
|
+
# - defining a new rake task like silence_schema would force users to load parallel_tests in test env
|
27
|
+
# - do not use ' since run_in_parallel uses them to quote stuff
|
28
|
+
# - simple system "set -o pipefail" returns nil even though set -o pipefail exists with 0
|
29
|
+
def suppress_output(command, ignore_regex)
|
30
|
+
activate_pipefail = "set -o pipefail"
|
31
|
+
remove_ignored_lines = %Q{(grep -v "#{ignore_regex}" || test 1)}
|
32
|
+
|
33
|
+
if system("#{activate_pipefail} && test 1")
|
34
|
+
"#{activate_pipefail} && (#{command}) | #{remove_ignored_lines}"
|
35
|
+
else
|
36
|
+
command
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def check_for_pending_migrations
|
41
|
+
abort_migrations = "db:abort_if_pending_migrations"
|
42
|
+
if Rake::Task.task_defined?(abort_migrations)
|
43
|
+
Rake::Task[abort_migrations].invoke
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# parallel:spec[:count, :pattern, :options]
|
48
|
+
def parse_args(args)
|
49
|
+
# order as given by user
|
50
|
+
args = [args[:count], args[:pattern], args[:options]]
|
51
|
+
|
52
|
+
# count given or empty ?
|
53
|
+
# parallel:spec[2,models,options]
|
54
|
+
# parallel:spec[,models,options]
|
55
|
+
count = args.shift if args.first.to_s =~ /^\d*$/
|
56
|
+
num_processes = count.to_i unless count.to_s.empty?
|
57
|
+
pattern = args.shift
|
58
|
+
options = args.shift
|
59
|
+
|
60
|
+
[num_processes, pattern.to_s, options.to_s]
|
61
|
+
end
|
31
62
|
end
|
32
63
|
end
|
64
|
+
end
|
33
65
|
|
66
|
+
namespace :parallel do
|
34
67
|
desc "create test databases via db:create --> parallel:create[num_cpus]"
|
35
68
|
task :create, :count do |t,args|
|
36
|
-
run_in_parallel("rake db:create RAILS_ENV=#{rails_env}", args)
|
69
|
+
ParallelTests::Tasks.run_in_parallel("rake db:create RAILS_ENV=#{ParallelTests::Tasks.rails_env}", args)
|
37
70
|
end
|
38
71
|
|
39
72
|
desc "drop test databases via db:drop --> parallel:drop[num_cpus]"
|
40
73
|
task :drop, :count do |t,args|
|
41
|
-
run_in_parallel("rake db:drop RAILS_ENV=#{rails_env}", args)
|
74
|
+
ParallelTests::Tasks.run_in_parallel("rake db:drop RAILS_ENV=#{ParallelTests::Tasks.rails_env}", args)
|
42
75
|
end
|
43
76
|
|
44
77
|
desc "update test databases by dumping and loading --> parallel:prepare[num_cpus]"
|
45
|
-
task(:prepare, [:count]
|
78
|
+
task(:prepare, [:count]) do |t,args|
|
79
|
+
ParallelTests::Tasks.check_for_pending_migrations
|
46
80
|
if defined?(ActiveRecord) && ActiveRecord::Base.schema_format == :ruby
|
47
81
|
# dump then load in parallel
|
48
82
|
Rake::Task['db:schema:dump'].invoke
|
@@ -50,34 +84,35 @@ namespace :parallel do
|
|
50
84
|
else
|
51
85
|
# there is no separate dump / load for schema_format :sql -> do it safe and slow
|
52
86
|
args = args.to_hash.merge(:non_parallel => true) # normal merge returns nil
|
53
|
-
run_in_parallel('rake db:test:prepare --trace', args)
|
87
|
+
ParallelTests::Tasks.run_in_parallel('rake db:test:prepare --trace', args)
|
54
88
|
end
|
55
89
|
end
|
56
90
|
|
57
91
|
# when dumping/resetting takes too long
|
58
92
|
desc "update test databases via db:migrate --> parallel:migrate[num_cpus]"
|
59
93
|
task :migrate, :count do |t,args|
|
60
|
-
run_in_parallel("rake db:migrate RAILS_ENV=#{rails_env}", args)
|
94
|
+
ParallelTests::Tasks.run_in_parallel("rake db:migrate RAILS_ENV=#{ParallelTests::Tasks.rails_env}", args)
|
61
95
|
end
|
62
96
|
|
63
97
|
# just load the schema (good for integration server <-> no development db)
|
64
98
|
desc "load dumped schema for test databases via db:schema:load --> parallel:load_schema[num_cpus]"
|
65
99
|
task :load_schema, :count do |t,args|
|
66
|
-
command = "rake db:schema:load RAILS_ENV=#{rails_env}"
|
67
|
-
run_in_parallel(
|
100
|
+
command = "rake db:schema:load RAILS_ENV=#{ParallelTests::Tasks.rails_env}"
|
101
|
+
ParallelTests::Tasks.run_in_parallel(ParallelTests::Tasks.suppress_output(command, "^ ->\\|^-- "), args)
|
68
102
|
end
|
69
103
|
|
70
104
|
desc "load the seed data from db/seeds.rb via db:seed --> parallel:seed[num_cpus]"
|
71
105
|
task :seed, :count do |t,args|
|
72
|
-
run_in_parallel("rake db:seed RAILS_ENV=#{rails_env}", args)
|
106
|
+
run_in_parallel("rake db:seed RAILS_ENV=#{ParallelTests::Tasks.rails_env}", args)
|
73
107
|
end
|
74
108
|
|
75
109
|
['test', 'spec', 'features'].each do |type|
|
76
110
|
desc "run #{type} in parallel with parallel:#{type}[num_cpus]"
|
77
|
-
task type, [:count, :pattern, :options]
|
111
|
+
task type, [:count, :pattern, :options] do |t,args|
|
112
|
+
ParallelTests::Tasks.check_for_pending_migrations
|
78
113
|
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
79
114
|
require "parallel_tests"
|
80
|
-
count, pattern, options = ParallelTests.
|
115
|
+
count, pattern, options = ParallelTests::Tasks.parse_args(args)
|
81
116
|
test_framework = {
|
82
117
|
'spec' => 'rspec',
|
83
118
|
'test' => 'test',
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'parallel_tests/tasks'
|
3
|
+
|
4
|
+
describe ParallelTests::Tasks do
|
5
|
+
describe ".parse_args" do
|
6
|
+
it "should return the count" do
|
7
|
+
args = {:count => 2}
|
8
|
+
ParallelTests::Tasks.parse_args(args).should == [2, '', ""]
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should default to the prefix" do
|
12
|
+
args = {:count => "models"}
|
13
|
+
ParallelTests::Tasks.parse_args(args).should == [nil, "models", ""]
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should return the count and pattern" do
|
17
|
+
args = {:count => 2, :pattern => "models"}
|
18
|
+
ParallelTests::Tasks.parse_args(args).should == [2, "models", ""]
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should return the count, pattern, and options" do
|
22
|
+
args = {:count => 2, :pattern => "plain", :options => "-p default" }
|
23
|
+
ParallelTests::Tasks.parse_args(args).should == [2, "plain", "-p default"]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe ".rails_env" do
|
28
|
+
around do |example|
|
29
|
+
begin
|
30
|
+
old = ENV["RAILS_ENV"]
|
31
|
+
ENV.delete "RAILS_ENV"
|
32
|
+
example.call
|
33
|
+
ensure
|
34
|
+
ENV["RAILS_ENV"] = old
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should be test when nothing was set" do
|
39
|
+
ParallelTests::Tasks.rails_env.should == "test"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should be whatever was set" do
|
43
|
+
ENV["RAILS_ENV"] = "foo"
|
44
|
+
ParallelTests::Tasks.rails_env.should == "foo"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe ".run_in_parallel" do
|
49
|
+
let(:full_path){ File.expand_path("../../../bin/parallel_test", __FILE__) }
|
50
|
+
|
51
|
+
it "should have the executable" do
|
52
|
+
File.file?(full_path).should == true
|
53
|
+
File.executable?(full_path).should == true
|
54
|
+
end
|
55
|
+
|
56
|
+
it "runs command in parallel" do
|
57
|
+
ParallelTests::Tasks.should_receive(:system).with("#{full_path} --exec 'echo'").and_return true
|
58
|
+
ParallelTests::Tasks.run_in_parallel("echo")
|
59
|
+
end
|
60
|
+
|
61
|
+
it "runs command with :count option" do
|
62
|
+
ParallelTests::Tasks.should_receive(:system).with("#{full_path} --exec 'echo' -n 123").and_return true
|
63
|
+
ParallelTests::Tasks.run_in_parallel("echo", :count => 123)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "runs command with :non_parallel option" do
|
67
|
+
ParallelTests::Tasks.should_receive(:system).with("#{full_path} --exec 'echo' --non-parallel").and_return true
|
68
|
+
ParallelTests::Tasks.run_in_parallel("echo", :non_parallel => true)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "runs aborts if the command fails" do
|
72
|
+
ParallelTests::Tasks.should_receive(:system).and_return false
|
73
|
+
ParallelTests::Tasks.should_receive(:abort).and_return false
|
74
|
+
ParallelTests::Tasks.run_in_parallel("echo")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe ".suppress_output" do
|
79
|
+
def call(command, grep)
|
80
|
+
result = `#{ParallelTests::Tasks.suppress_output(command, grep)}`
|
81
|
+
[result, $?.success?]
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should hide offending lines" do
|
85
|
+
call("echo 123", "123").should == ["", true]
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should not hide other lines" do
|
89
|
+
call("echo 124", "123").should == ["124\n", true]
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should fail if command fails and the pattern matches" do
|
93
|
+
call("echo 123 && test", "123").should == ["", false]
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should fail if command fails and the pattern fails" do
|
97
|
+
call("echo 124 && test", "123").should == ["124\n", false]
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should not filter if pipefail is not possible" do
|
101
|
+
ParallelTests::Tasks.should_receive(:system).with("set -o pipefail && test 1").and_return false
|
102
|
+
call("echo 123", "123").should == ["123\n", true]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe ".check_for_pending_migrations" do
|
107
|
+
after do
|
108
|
+
Rake.application.instance_variable_get('@tasks').delete("db:abort_if_pending_migrations")
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should do nothing if pending migrations is no defined" do
|
112
|
+
ParallelTests::Tasks.check_for_pending_migrations
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should run pending migrations is task is defined" do
|
116
|
+
foo = 1
|
117
|
+
Rake::Task.define_task("db:abort_if_pending_migrations") do
|
118
|
+
foo = 2
|
119
|
+
end
|
120
|
+
ParallelTests::Tasks.check_for_pending_migrations
|
121
|
+
foo.should == 2
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should not execute the task twice" do
|
125
|
+
foo = 1
|
126
|
+
Rake::Task.define_task("db:abort_if_pending_migrations") do
|
127
|
+
foo += 1
|
128
|
+
end
|
129
|
+
ParallelTests::Tasks.check_for_pending_migrations
|
130
|
+
ParallelTests::Tasks.check_for_pending_migrations
|
131
|
+
foo.should == 2
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
data/spec/parallel_tests_spec.rb
CHANGED
@@ -1,28 +1,6 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe ParallelTests do
|
4
|
-
describe :parse_rake_args do
|
5
|
-
it "should return the count" do
|
6
|
-
args = {:count => 2}
|
7
|
-
ParallelTests.parse_rake_args(args).should == [2, '', ""]
|
8
|
-
end
|
9
|
-
|
10
|
-
it "should default to the prefix" do
|
11
|
-
args = {:count => "models"}
|
12
|
-
ParallelTests.parse_rake_args(args).should == [nil, "models", ""]
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should return the count and pattern" do
|
16
|
-
args = {:count => 2, :pattern => "models"}
|
17
|
-
ParallelTests.parse_rake_args(args).should == [2, "models", ""]
|
18
|
-
end
|
19
|
-
|
20
|
-
it "should return the count, pattern, and options" do
|
21
|
-
args = {:count => 2, :pattern => "plain", :options => "-p default" }
|
22
|
-
ParallelTests.parse_rake_args(args).should == [2, "plain", "-p default"]
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
4
|
describe ".determine_number_of_processes" do
|
27
5
|
before do
|
28
6
|
ENV.delete('PARALLEL_TEST_PROCESSORS')
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parallel_tests
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.13
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-09-
|
12
|
+
date: 2012-09-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: parallel
|
@@ -71,6 +71,7 @@ files:
|
|
71
71
|
- spec/parallel_tests/rspec/runner_spec.rb
|
72
72
|
- spec/parallel_tests/rspec/runtime_logger_spec.rb
|
73
73
|
- spec/parallel_tests/rspec/summary_logger_spec.rb
|
74
|
+
- spec/parallel_tests/tasks_spec.rb
|
74
75
|
- spec/parallel_tests/test/runner_spec.rb
|
75
76
|
- spec/parallel_tests/test/runtime_logger_spec.rb
|
76
77
|
- spec/parallel_tests_spec.rb
|
@@ -90,7 +91,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
90
91
|
version: '0'
|
91
92
|
segments:
|
92
93
|
- 0
|
93
|
-
hash: -
|
94
|
+
hash: -388650261339101456
|
94
95
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
96
|
none: false
|
96
97
|
requirements:
|
@@ -99,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
100
|
version: '0'
|
100
101
|
segments:
|
101
102
|
- 0
|
102
|
-
hash: -
|
103
|
+
hash: -388650261339101456
|
103
104
|
requirements: []
|
104
105
|
rubyforge_project:
|
105
106
|
rubygems_version: 1.8.24
|