parallelized_specs 0.4.50 → 0.4.51

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.50"
15
+ gem.version = "0.4.51"
16
16
  end
17
17
  Jeweler::GemcutterTasks.new
18
18
  rescue LoadError
data/Readme.md CHANGED
@@ -3,16 +3,17 @@ ParallelizedSpecs splits tests into even groups(by number of tests or runtime) a
3
3
 
4
4
  Setup Requirements
5
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
6
+ **OutcomeBuilder Formatter and FailuresFormatter must be enabled when using reruns or some ruby 1.9.3 version will provide false positives.
7
+ This allows streamlined pass\fail determination and thorough false positive checking while handling unusual pass\fail conditions in some versions of ruby 1.9.3
8
+
9
+ See FailuresFormatter readme section and set RERUNS to 0 if don't want to allow reruns but are using a ruby 1.9.3 version
9
10
 
10
11
 
11
12
  Setup for Rails
12
13
  ===============
13
14
  ## Install
14
15
  ### Rails 3
15
- If you use RSpec: ensure you got >= 2.4
16
+ If you use RSpec: ensure you have >= 2.4
16
17
 
17
18
  As gem
18
19
 
@@ -66,8 +67,8 @@ ParallelizedSpecs uses 1 database per test-process, 2 processes will use `*_test
66
67
  rake parallel:spec # RSpec
67
68
 
68
69
  rake parallel:spec[1] --> force 1 CPU --> 86 seconds
69
- rake parallel:spec --> got 2 CPUs? --> 47 seconds
70
- rake parallel:spec --> got 4 CPUs? --> 26 seconds
70
+ rake parallel:spec --> have 2 CPUs? --> 47 seconds
71
+ rake parallel:spec --> have 4 CPUs? --> 26 seconds
71
72
  ...
72
73
 
73
74
  Test by pattern (e.g. use one integration server per subfolder / see if you broke any 'user'-related tests)
@@ -124,7 +125,7 @@ SpecFailuresLogger
124
125
 
125
126
  This logger produces pasteable command-line snippets for each failed example.
126
127
 
127
- This also stores all failures in this file for later consumption during in optional RERUN process
128
+ This also stores all failures in this file for later consumption during an optional RERUN process
128
129
  which can rerun all failed specs and potentially change the pass\fail outcome of a build if all specs pass.
129
130
  Enable this formatter
130
131
 
@@ -150,7 +151,7 @@ FailuresFormatter
150
151
 
151
152
 
152
153
  This formatter captures all needed data about failed examples and stores them in a file for an additional run
153
- at the end of the first build. If all specs that failed the first time pass the build will be marked as passed in the exit status
154
+ at the end of the first build. If all specs that failed the first time pass the build will be marked as passed in the exit status.
154
155
  The output location defined below is not optional and if this formatter is used must not be changed.
155
156
 
156
157
  Use default MAX_RERUNS of 9 or set max number of failed specs to be allowed for reruns by exporting environment variable
@@ -177,7 +178,7 @@ OutcomeBuilder
177
178
 
178
179
 
179
180
  Because previously the pass\fail determination was solely on exit status and now we do things besides always fail on non 0 exits
180
- we must handle many other causes of non 0 exit codes that we don't want to start the rerun process if they happen
181
+ we must handle many other causes of non 0 exit codes that we don't want to start the rerun process if they happen.
181
182
 
182
183
  E.g.
183
184
 
@@ -202,6 +203,7 @@ E.g.
202
203
 
203
204
 
204
205
  Add the following to your `spec/parallelized_spec.opts` (or `spec/spec.opts`) :
206
+
205
207
  RSpec 1.x:
206
208
  --format progress
207
209
  --require parallelized_specs/trending_example_failures_logger
@@ -211,7 +213,29 @@ Add the following to your `spec/parallelized_spec.opts` (or `spec/spec.opts`) :
211
213
  --format progress
212
214
  --format ParallelizedSpecs::SpecFailuresLogger --out tmp/parallel_log/trends.log
213
215
 
216
+ SlowestSpecLogger
217
+ -----------------------
218
+ creates a text file with any specs taking longer than 30 seconds by default but can be overridden by setting a ENV["MAX_TIME"] var
219
+
220
+ E.g.
221
+
222
+
223
+ Add the following to your `spec/parallelized_spec.opts` (or `spec/spec.opts`) :
224
+
225
+ RSpec 1.x:
226
+ --format progress
227
+ --require parallelized_specs/slow_spec_logger
228
+ --format ParallelizedSpecs::SpecFailuresLogger:tmp/parallel_log/slowest_specs.log
229
+ RSpec >= 2.4:
230
+ If installed as plugin: -I vendor/plugins/parallelized_specs/lib
231
+ --format progress
232
+ --format ParallelizedSpecs::SpecFailuresLogger --out tmp/parallel_log/slowest_specs.log
233
+
234
+ Tools
214
235
 
236
+ selenium_trending_collector.rb
237
+ ------------------------
238
+ This consumes the text files created by the trender formatter and parses it associates the data and pushes it to a database for storage
215
239
 
216
240
 
217
241
  Setup for non-rails
@@ -238,7 +262,7 @@ TIPS
238
262
  - [ActiveRecord] if you do not have `db:abort_if_pending_migrations` add this to your Rakefile: `task('db:abort_if_pending_migrations'){}`
239
263
  - `export PARALLEL_TEST_PROCESSORS=X` in your environment and parallelized_specs will use this number of processors by default
240
264
  - with zsh this would be `rake "parallel:prepare[3]"`
241
- - [RERUNS] if your using reruns formatter also use the outcome builder to make your builds handle syntax issues in some threads files
265
+ - [RERUNS] if you're using reruns formatter also use the outcome builder to make your builds handle syntax issues during example_group generation from rspec
242
266
  and thread crashes more cleanly
243
267
 
244
268
  Authors
@@ -249,8 +273,9 @@ based loosely from https://github.com/grosser/parallel_tests
249
273
  ### [Contributors](http://github.com/jakesorce/parallelized_specs/contributors)
250
274
  - [Bryan Madsen](http://github.com/bmad)
251
275
 
252
- [Jake Sorce](http://github.com/jakesorce)<br/>
276
+ - [Jake Sorce](http://github.com/jakesorce)
277
+
278
+ - [Shawn Meredith](https://github.com/smeredith0506)
253
279
 
254
- [Shawn Meredith](https://github.com/smeredith0506)<br/>
255
280
  Hereby placed under public domain, do what you want, just do not hold me accountable...<br/>
256
281
  [![Flattr](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=jakesorce&url=https://github.com/jakesorce/parallelized_specs&title=parallelized_specs&language=en_GB&tags=github&category=software)
@@ -0,0 +1,56 @@
1
+ require 'rubygems'
2
+ require 'active_record'
3
+ require 'date'
4
+
5
+ ActiveRecord::Base.establish_connection(
6
+ :adapter => 'yourdbtype',
7
+ :host => 'yourhost',
8
+ :encoding => 'utf8',
9
+ :database => 'selenium_trending',
10
+ :username => 'youruser',
11
+ :password => 'youtpass'
12
+ )
13
+
14
+ class SeleniumTrend < ActiveRecord::Base
15
+ ActiveRecord::Migration.class_eval do
16
+ unless SeleniumTrend.table_exists?
17
+ create_table :selenium_trends do |t|
18
+ t.integer :hudson_build
19
+ t.string :hudson_project
20
+ t.string :hudson_url
21
+ t.string :spec_line_failure
22
+ t.string :spec_name
23
+ t.string :nested_spec_name
24
+ t.string :trace
25
+ t.string :full_path
26
+ t.date :failure_date
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ def store_failure_data
33
+ dir = Dir.pwd
34
+ data = "#{dir}/tmp/parallel_log/trends.log"
35
+ File.open("#{data}", 'r') do |f|
36
+ f.each_line do |line|
37
+ values = line.split("*").to_a
38
+
39
+ if values != nil
40
+ spec_line_failure = values[0]
41
+ spec_name = values[1]
42
+ nested_spec_name = values[2]
43
+ trace = values[3]
44
+ full_path = values[4]
45
+ failure_date = values[5]
46
+ hudson_build = values[6]
47
+ hudson_project = values[7]
48
+ hudson_url = values[8]
49
+
50
+ SeleniumTrend.create!(:spec_line_failure => spec_line_failure, :spec_name => spec_name, :nested_spec_name => nested_spec_name, :trace => trace, :full_path => full_path, :failure_date => failure_date, :hudson_build => hudson_build, :hudson_project => hudson_project, :hudson_url => hudson_url)
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ store_failure_data
@@ -20,11 +20,13 @@ class ParallelizedSpecs::TrendingExampleFailures < ParallelizedSpecs::SpecLogger
20
20
  def dump_pending(*args);end
21
21
 
22
22
  def dump_summary(*args)
23
+
23
24
  if File.exists?("#{Rails.root}/spec/build_info.txt")
24
25
  @hudson_build_info = File.read("#{Rails.root}/spec/build_info.txt")
25
26
  else
26
27
  @hudson_build_info = "no*hudson build*info"
27
28
  end
29
+
28
30
  lock_output do
29
31
  (@failed_examples||{}).each_pair do |example, details|
30
32
  @output.puts "#{example}#{details}#{@hudson_build_info}"
@@ -114,24 +114,24 @@ class ParallelizedSpecs
114
114
  failed = test_results.any? { |result| result[:exit_status] != 0 } #ruby 1.8.7 works breaks on 1.9.3
115
115
  slowest_spec_determination("#{Rails.root}/tmp/parallel_log/slowest_specs.log") if @slow_specs_enabled
116
116
 
117
- #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
118
117
  results = find_results(test_results.map { |result| result[:stdout] }*"")
119
- @outcome_builder_enabled ? spec_summary = calculate_total_spec_details : spec_summary = summarize_results(results)
118
+
120
119
 
121
120
  if @outcome_builder_enabled
122
121
  puts "INFO: OutcomeBuilder is enabled now checking for false positives"
123
- 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"
122
+ @total_specs, @total_failures, @total_pending = calculate_total_spec_details
123
+ puts "INFO: Total specs run #{total_specs} failed specs #{total_failures} pending specs #{total_pending}\n INFO: Took #{Time.now - start} seconds"
124
+ #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
124
125
  false_positive_sniffer(num_processes)
125
- if @reruns_enabled
126
+ if @reruns_enabled && @total_failures != 0
126
127
  puts "INFO: RERUNS are enabled"
127
- rerun_initializer(name, failed, spec_summary)
128
+ rerun_initializer
128
129
  else
129
- abort("SEVERE: #{name.capitalize}s Failed") if failed || spec_summary[2].to_i != 0
130
+ abort("SEVERE: #{name.capitalize}s Failed") if @total_failures != 0
130
131
  end
131
132
  else
132
133
  puts "WARNING: OutcomeBuilder is disabled not checking for false positives its likely things like thread failures and rspec non 0 exit codes will cause false positives"
133
- puts spec_summary
134
- puts "INFO: Took #{Time.now - start} seconds"
134
+ puts "INFO: #{summarize_results(results)} Took #{Time.now - start} seconds"
135
135
  abort("SEVERE: #{name.capitalize}s Failed") if failed
136
136
  end
137
137
  puts "INFO: marking build as PASSED"
@@ -145,7 +145,7 @@ class ParallelizedSpecs
145
145
  spec_total_details[1] += thread_spec_details[1].to_i
146
146
  spec_total_details[2] += thread_spec_details[2].to_i
147
147
  end
148
- spec_total_details
148
+ [spec_total_details[0], spec_total_details[1], spec_total_details[2]]
149
149
  end
150
150
 
151
151
  def self.formatters_setup
@@ -178,13 +178,15 @@ class ParallelizedSpecs
178
178
  end
179
179
  end
180
180
 
181
- def self.rerun_initializer(name, failed, spec_summary)
182
- if spec_summary[2].to_i != 0 && !File.zero?("#{Rails.root}/tmp/parallel_log/rspec.failures") # works on both 1.8.7\1.9.3
181
+ def self.rerun_initializer()
182
+
183
+ if @total_failures != 0 && !File.zero?("#{Rails.root}/tmp/parallel_log/rspec.failures") # works on both 1.8.7\1.9.3
183
184
  puts "INFO: some specs failed, about to start the rerun process\n...\n..\n."
184
185
  ParallelizedSpecs.rerun()
185
186
  else
186
187
  #works on both 1.8.7\1.9.3
187
- abort "SEVERE: #{name.capitalize}s Failed" if spec_summary[2].to_i != 0 || failed
188
+ puts "ERROR: the build had failures but the rspec.failures file is null"
189
+ abort "SEVERE: SPECS Failed"
188
190
  end
189
191
  end
190
192
 
@@ -192,7 +194,7 @@ class ParallelizedSpecs
192
194
  if Dir.glob("#{Rails.root}/tmp/parallel_log/spec_count/{*,.*}").count == 2 && Dir.glob("#{Rails.root}/tmp/parallel_log/thread_started/{*,.*}").count == num_processes + 2
193
195
  (puts "INFO: All threads completed")
194
196
  elsif Dir.glob("#{Rails.root}/tmp/parallel_log/thread_started/{*,.*}").count != num_processes + 2
195
- File.open("#{Rails.root}/tmp/parallel_log/error.log", 'a+') { |f| f.write "\n\n\n syntax issues" }
197
+ File.open("#{Rails.root}/tmp/parallel_log/error.log", 'a+') { |f| f.write "\n\n\n syntax errors" }
196
198
  File.open("#{Rails.root}/tmp/failure_cause.log", 'a+') { |f| f.write "syntax errors" }
197
199
  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"
198
200
  else
@@ -563,8 +565,4 @@ class ParallelizedSpecs
563
565
  File.open(file, 'a+') { |f| f.puts slow_spec }
564
566
  end
565
567
  end
566
-
567
- end
568
-
569
-
570
-
568
+ end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "parallelized_specs"
8
- s.version = "0.4.50"
8
+ s.version = "0.4.51"
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"]
12
- s.date = "2013-04-09"
12
+ s.date = "2013-04-12"
13
13
  s.email = "jake@instructure.com"
14
14
  s.files = [
15
15
  "Gemfile",
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
24
24
  "lib/parallelized_specs/outcome_builder.rb",
25
25
  "lib/parallelized_specs/railtie.rb",
26
26
  "lib/parallelized_specs/runtime_logger.rb",
27
+ "lib/parallelized_specs/selenium_trending_collector.rb",
27
28
  "lib/parallelized_specs/slow_spec_logger.rb",
28
29
  "lib/parallelized_specs/spec_error_count_logger.rb",
29
30
  "lib/parallelized_specs/spec_error_logger.rb",
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: 107
4
+ hash: 105
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 4
9
- - 50
10
- version: 0.4.50
9
+ - 51
10
+ version: 0.4.51
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jake Sorce, Bryan Madsen, Shawn Meredith
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2013-04-09 00:00:00 Z
18
+ date: 2013-04-12 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: parallel
@@ -52,6 +52,7 @@ files:
52
52
  - lib/parallelized_specs/outcome_builder.rb
53
53
  - lib/parallelized_specs/railtie.rb
54
54
  - lib/parallelized_specs/runtime_logger.rb
55
+ - lib/parallelized_specs/selenium_trending_collector.rb
55
56
  - lib/parallelized_specs/slow_spec_logger.rb
56
57
  - lib/parallelized_specs/spec_error_count_logger.rb
57
58
  - lib/parallelized_specs/spec_error_logger.rb