rspec-gc-control 1.0.0

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/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ ### dev
2
+ [full changelog](http://github.com/MrJoy/rspec-gc-control/compare/v1.0.0...master)
3
+
4
+ Changes
5
+
6
+ * Forgot to update changelog before tagging release.
7
+
8
+
9
+ ### v1.0.0
10
+ [full changelog](http://github.com/MrJoy/rspec-gc-control/compare/1d2bd61...v1.0.0)
11
+
12
+ Initial Version
13
+
14
+ * Add support for controlling how often GC runs on RSpec 2.11.1.
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2012 Jon Frisby
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,60 @@
1
+ # rspec-gc-control
2
+
3
+ ## Summary
4
+
5
+ This gem extends RSpec to allow you to control how often GC cycles happen
6
+ in order to trade increased memory usage for faster test runs. It's an
7
+ encapsulated and reusable version of the code shown in this article:
8
+
9
+ <http://www.rubyinside.com/careful-cutting-to-get-faster-rspec-runs-with-rails-5207.html>
10
+
11
+
12
+ ## Requirements
13
+
14
+ For this to work, you need a Ruby that supports explicit control over the
15
+ garbage collector, and RSpec 2.11.1 or higher.
16
+
17
+ Supported Rubies include MRI 1.9.2 and 1.9.3, and most likely Rubinius.
18
+
19
+ Unsupported Rubies are:
20
+
21
+ * MRI 1.8.x: No support for `GC.count`.
22
+ * JRuby: `GC.enable` / `GC.disable` are no-ops.
23
+
24
+ On unsupported platforms, attempting to enable explicit GC control via this
25
+ plugin will produce a warning and have no other effect.
26
+
27
+
28
+ ## Installation and Usage
29
+
30
+ Install the gem:
31
+
32
+ ```ruby
33
+ gem install rspec-gc-control
34
+ ```
35
+
36
+ Or if you're using bundler, add this line to your `Gemfile` and run
37
+ `bundle install`:
38
+
39
+ ```ruby
40
+ gem 'rspec-gc-control'
41
+ ```
42
+
43
+ Once you have the gem installed, edit your `spec_helper.rb` file to set
44
+ `gc_every_n_examples` to an appropriate value. You may want to play with this
45
+ value while watching memory consumption for the process to get a feeling for
46
+ how significant a tradeoff you're making in terms of increased memory usage.
47
+
48
+ ```ruby
49
+ RSpec.configure do |c|
50
+ c.gc_every_n_examples = 10
51
+ end
52
+ ```
53
+
54
+ You'll know it's working if you see output like the following at the end of
55
+ your test run:
56
+
57
+ ```
58
+ Finished in 6.45 seconds (including 7 forced GC cycle(s), totalling 0.67116 seconds)
59
+ 71 examples, 0 failures, 1 pending
60
+ ```
@@ -0,0 +1,6 @@
1
+ $:.unshift(File.expand_path("..", __FILE__))
2
+
3
+ require 'rspec-gc-control/configuration'
4
+ require 'rspec-gc-control/example'
5
+ require 'rspec-gc-control/base_text_formatter'
6
+
@@ -0,0 +1,31 @@
1
+ require 'rspec/core/formatters/base_formatter'
2
+
3
+ module RSpec
4
+ module Core
5
+ module Formatters
6
+
7
+ class BaseTextFormatter < BaseFormatter
8
+
9
+ # Overridden version of this method, to include output about forced GC
10
+ # count and duration, if explicit GC control is enabled.
11
+ def dump_summary(duration, example_count, failure_count, pending_count)
12
+ super(duration, example_count, failure_count, pending_count)
13
+ # Don't print out profiled info if there are failures, it just clutters the output
14
+ dump_profile if profile_examples? && failure_count == 0
15
+ output.print "\nFinished in #{format_duration(duration)}"
16
+
17
+ gc_times = examples.map { |ex| ex.execution_result[:gc_time] }.select { |t| !t.nil? && (t > 0) }
18
+ if(gc_times.count > 0)
19
+ gc_count = gc_times.count
20
+ gc_time = gc_times.reduce(:+)
21
+ output.print " (including #{gc_count} forced GC cycle(s), totalling #{format_duration(gc_time)})"
22
+ end
23
+ output.print "\n"
24
+ output.puts colorise_summary(summary_line(example_count, failure_count, pending_count))
25
+ dump_commands_to_rerun_failed_examples
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,62 @@
1
+ require 'rspec/core/configuration'
2
+
3
+ module RSpec
4
+ module Core
5
+ # Extensions to RSpec::Core::Configuration to allow configuration of
6
+ # desired GC behavior.
7
+ class Configuration
8
+ # @private
9
+ define_reader :gc_every_n_examples
10
+
11
+ # @private
12
+ alias_method :initialize_without_gc, :initialize
13
+
14
+ # Overridden constructor to initialize `gc_every_n_examples` to 0.
15
+ # This disables the explicit GC control.
16
+ def initialize
17
+ initialize_without_gc
18
+ @gc_every_n_examples = 0
19
+ end
20
+
21
+ # @private
22
+ def gc_if_needed
23
+ gc_time = 0
24
+ if(@gc_every_n_examples > 0)
25
+ @test_counter = -1 if(!defined?(@test_counter))
26
+ @test_counter += 1
27
+ if(@test_counter >= (@gc_every_n_examples - 1))
28
+ t_before = Time.now
29
+ GC.enable
30
+ GC.start
31
+ GC.disable
32
+ gc_time = Time.now - t_before
33
+
34
+ @test_counter = 0
35
+ end
36
+ end
37
+ return gc_time
38
+ end
39
+
40
+ # If set to a value above 0, turns automatic GC off and runs it only
41
+ # every N tests, which can result in higher peak memory usage but lower
42
+ # total execution time.
43
+ def gc_every_n_examples=(n)
44
+ if(defined?(JRuby))
45
+ warn "Ignoring gc_every_n_examples because JRuby doesn't support GC control."
46
+ return
47
+ end
48
+ if(!GC.respond_to?(:count))
49
+ warn "Ignoring gc_every_n_examples because this Ruby implementation doesn't implement GC.count."
50
+ return
51
+ end
52
+ @gc_every_n_examples = n
53
+ if(@gc_every_n_examples > 0)
54
+ GC.disable
55
+ else
56
+ GC.enable
57
+ end
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,26 @@
1
+ require 'rspec/core/example'
2
+
3
+ module RSpec
4
+ module Core
5
+ # Extensions to RSpec::Core::Example to perform explicit GC and capture
6
+ # GC execution time.
7
+ class Example
8
+ private
9
+
10
+ undef :record_finished
11
+ def record_finished(status, results={})
12
+ finished_at = Time.now
13
+ record results.merge(:status => status, :finished_at => finished_at, :run_time => (finished_at - (execution_result[:started_at] + (execution_result[:gc_time] || 0))))
14
+ end
15
+
16
+ alias_method :run_after_each_without_gc, :run_after_each
17
+
18
+ def run_after_each
19
+ run_after_each_without_gc
20
+ ensure
21
+ execution_result[:gc_time] = RSpec.configuration.gc_if_needed
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,47 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "rspec-gc-control"
8
+ s.version = "1.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jon Frisby"]
12
+ s.date = "2012-08-12"
13
+ s.description = "Explicit control over garbage collection behavior for RSpec."
14
+ s.email = "jfrisby@mrjoy.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ "CHANGELOG.md",
21
+ "LICENSE",
22
+ "README.md",
23
+ "lib/rspec-gc-control.rb",
24
+ "lib/rspec-gc-control/base_text_formatter.rb",
25
+ "lib/rspec-gc-control/configuration.rb",
26
+ "lib/rspec-gc-control/example.rb",
27
+ "rspec-gc-control.gemspec"
28
+ ]
29
+ s.homepage = "http://MrJoy.com"
30
+ s.licenses = ["MIT"]
31
+ s.require_paths = ["lib"]
32
+ s.rubygems_version = "1.8.24"
33
+ s.summary = "Explicit control over garbage collection behavior for RSpec."
34
+
35
+ if s.respond_to? :specification_version then
36
+ s.specification_version = 3
37
+
38
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
39
+ s.add_runtime_dependency(%q<rspec-core>, [">= 2.11.1"])
40
+ else
41
+ s.add_dependency(%q<rspec-core>, [">= 2.11.1"])
42
+ end
43
+ else
44
+ s.add_dependency(%q<rspec-core>, [">= 2.11.1"])
45
+ end
46
+ end
47
+
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rspec-gc-control
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jon Frisby
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-12 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec-core
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 2.11.1
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 2.11.1
30
+ description: Explicit control over garbage collection behavior for RSpec.
31
+ email: jfrisby@mrjoy.com
32
+ executables: []
33
+ extensions: []
34
+ extra_rdoc_files:
35
+ - LICENSE
36
+ - README.md
37
+ files:
38
+ - CHANGELOG.md
39
+ - LICENSE
40
+ - README.md
41
+ - lib/rspec-gc-control.rb
42
+ - lib/rspec-gc-control/base_text_formatter.rb
43
+ - lib/rspec-gc-control/configuration.rb
44
+ - lib/rspec-gc-control/example.rb
45
+ - rspec-gc-control.gemspec
46
+ homepage: http://MrJoy.com
47
+ licenses:
48
+ - MIT
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ segments:
60
+ - 0
61
+ hash: -2268877769317612634
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ requirements: []
69
+ rubyforge_project:
70
+ rubygems_version: 1.8.24
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: Explicit control over garbage collection behavior for RSpec.
74
+ test_files: []