parallelized_specs 0.4.47 → 0.4.48

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -12,7 +12,7 @@ begin
12
12
  gem.email = "jake@instructure.com"
13
13
  gem.homepage = "http://github.com/jakesorce/#{gem.name}"
14
14
  gem.authors = "Jake Sorce, Bryan Madsen, Shawn Meredith"
15
- gem.version = "0.4.47"
15
+ gem.version = "0.4.48"
16
16
  end
17
17
  Jeweler::GemcutterTasks.new
18
18
  rescue LoadError
data/Readme.md CHANGED
@@ -1,6 +1,12 @@
1
1
  Speedup Test::RSpec by running parallel on multiple CPUs (or cores).<br/>
2
2
  ParallelizedSpecs splits tests into even groups(by number of tests or runtime) and runs each group in a single process with its own database.
3
- Optional rerunning of failed specs allowing intermittent specs to not cause builds to fail with configurable max failures to try to rerun post build.
3
+
4
+ Setup Requirements
5
+ ***IMPORTANT***
6
+ **OutcomeBuilder Formatter and FailuresFormatter must be enabled in the way specified starting from 4.47**
7
+ This allows streamlined pass\fail determination and thorough false positive checking while handing unusual pass\fail conditions in ruby 1.9.3
8
+ See FailuresFormatter read section and set RERUNS to 0 if don't want to allow reruns
9
+
4
10
 
5
11
  Setup for Rails
6
12
  ===============
@@ -26,6 +26,11 @@ module RSpec
26
26
  puts "Thread example failure count = #{failure_count}"
27
27
  failure_count > 0 ? (File.open(failure_file, 'a+') { |f| f.write(failure_count) }) : (puts "All specs in Thread #{env_test_number} passed")
28
28
  puts "Thread #{env_test_number} has completed in #{duration}"
29
+
30
+ lock_output do
31
+ File.open("#{Rails.root}/tmp/parallel_log/total_specs.txt", 'a+') { |f| f.puts("#{example_count}*#{failure_count}*#{pending_count}") }
32
+ end
33
+
29
34
  end
30
35
 
31
36
  def dump_failures(*args)
@@ -85,7 +85,8 @@ class ParallelizedSpecs
85
85
 
86
86
  def self.run_specs(tests, options)
87
87
  formatters = formatters_setup
88
-
88
+ @outcome_builder_enabled = formatters.any? { |formatter| formatter.match(/OutcomeBuilder/) }
89
+ @reruns_enabled = formatters.any? { |formatter| formatter.match(/FailuresFormatter/) }
89
90
  num_processes = options[:count] || Parallel.processor_count
90
91
  name = 'spec'
91
92
 
@@ -109,20 +110,42 @@ class ParallelizedSpecs
109
110
  test_results = Parallel.map(groups, :in_processes => num_processes) do |group|
110
111
  run_tests(group, groups.index(group), options)
111
112
  end
113
+ failed = test_results.any? { |result| result[:exit_status] != 0 } #ruby 1.8.7 works breaks on 1.9.3
112
114
  slowest_spec_determination("#{Rails.root}/tmp/parallel_log/slowest_specs.log")
113
115
 
114
- #parse and print results
115
- results = find_results(test_results.map { |result| result[:stdout] }*"")
116
- puts summarize_results(results)
117
- puts "INFO: Took #{Time.now - start} seconds"
118
-
119
116
  #determines if any tricky conditions happened that can cause false positives and offers logging into what was the last spec to start or finishing running
120
- false_positive_sniffer(num_processes) if formatters.any? { |formatter| formatter.match(/OutcomeBuilder/) }
121
- failed = test_results.any? { |result| result[:exit_status] != 0 } #ruby 1.8.7 works breaks on 1.9.3
122
- formatters.any? { |formatter| formatter.match(/FailuresFormatter/) } ? rerun_initializer(name, failed) : abort("SEVERE: #{name.capitalize}s Failed") if failed
117
+ if @outcome_builder_enabled
118
+ puts "INFO: OutcomeBuilder is enabled now checking for false positives"
119
+ spec_summary = calculate_total_spec_details
120
+ puts "INFO: Total specs run #{spec_summary[0]} failed specs #{spec_summary[1]} pending specs #{spec_summary[2]}\n INFO: Took #{Time.now - start} seconds"
121
+ false_positive_sniffer(num_processes)
122
+ else
123
+ puts "INFO: OutcomeBuilder is disabled not checking for false positives"
124
+ results = find_results(test_results.map { |result| result[:stdout] }*"")
125
+ puts summarize_results(results)
126
+ puts "INFO: Took #{Time.now - start} seconds"
127
+ end
128
+
129
+ if @reruns_enabled
130
+ puts "INFO: RERUNS are enabled starting the rerun process"
131
+ rerun_initializer(name, failed)
132
+ else
133
+ abort("SEVERE: #{name.capitalize}s Failed") if failed
134
+ end
123
135
  puts "INFO: marking build as PASSED"
124
136
  end
125
137
 
138
+ def self.calculate_total_spec_details
139
+ spec_total_details = [0,0,0]
140
+ File.open("#{Rails.root}/tmp/parallel_log/total_specs.txt").each_line do |count|
141
+ thread_spec_details = count.split("*")
142
+ spec_total_details[0] += thread_spec_details[0].to_i
143
+ spec_total_details[1] += thread_spec_details[1].to_i
144
+ spec_total_details[2] += thread_spec_details[2].to_i
145
+ end
146
+ spec_total_details
147
+ end
148
+
126
149
  def self.formatters_setup
127
150
  formatters = []
128
151
  File.open("#{Rails.root}/spec/spec.opts").each_line do |line|
@@ -134,7 +157,7 @@ class ParallelizedSpecs
134
157
 
135
158
  def self.formatter_directory_management(formatters)
136
159
  FileUtils.mkdir_p('parallel_log') if !File.directory?('tmp/parallel_log')
137
- if formatters.any? { |formatter| formatter.match(/FailuresFormatter/) }
160
+ if @reruns_enabled || @outcome_builder_enabled
138
161
  begin
139
162
  %w['tmp/parallel_log/spec_count','tmp/parallel_log/failed_specs', 'tmp/parallel_log/thread_started'].each do |dir|
140
163
  directory_cleanup_and_create(dir)
@@ -156,7 +179,7 @@ class ParallelizedSpecs
156
179
  end
157
180
 
158
181
  def self.rerun_initializer(name, failed)
159
- if Dir.glob("#{Rails.root}/tmp/parallel_log/failed_specs/{*,.*}").count > 2 && !File.zero?("#{Rails.root}/tmp/parallel_log/rspec.failures") # works on both 1.8.7\1.9.3
182
+ if !File.zero?("#{Rails.root}/tmp/parallel_log/rspec.failures") # works on both 1.8.7\1.9.3
160
183
  puts "INFO: some specs failed, about to start the rerun process\n INFO: no more than 9 specs may be rerun and shared specs are not allowed\n...\n..\n."
161
184
  ParallelizedSpecs.rerun()
162
185
  else
@@ -170,7 +193,7 @@ class ParallelizedSpecs
170
193
  (puts "INFO: All threads completed")
171
194
  elsif Dir.glob("#{Rails.root}/tmp/parallel_log/thread_started/{*,.*}").count != num_processes + 2
172
195
  File.open("#{Rails.root}/tmp/parallel_log/error.log", 'a+') { |f| f.write "\n\n\n syntax issues" }
173
- File.open("#{Rails.root}/tmp/failure_cause.log", 'a+') { |f| f.write "Syntax errors" }
196
+ File.open("#{Rails.root}/tmp/failure_cause.log", 'a+') { |f| f.write "syntax errors" }
174
197
  abort "SEVERE: one or more threads didn't get started by rspec, this may be caused by a syntax issue in specs, check logs right before specs start running"
175
198
  else
176
199
  threads = Dir["#{Rails.root}/tmp/parallel_log/spec_count/*"]
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "parallelized_specs"
8
- s.version = "0.4.47"
8
+ s.version = "0.4.48"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jake Sorce, Bryan Madsen, Shawn Meredith"]
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parallelized_specs
3
3
  version: !ruby/object:Gem::Version
4
- hash: 81
4
+ hash: 111
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 4
9
- - 47
10
- version: 0.4.47
9
+ - 48
10
+ version: 0.4.48
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jake Sorce, Bryan Madsen, Shawn Meredith