test-prof 0.1.0.beta4 → 0.1.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +10 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +69 -0
  5. data/.travis.yml +5 -0
  6. data/Gemfile +4 -0
  7. data/README.md +2 -16
  8. data/Rakefile +8 -0
  9. data/bin/setup +8 -0
  10. data/circle.yml +11 -0
  11. data/guides/any_fixture.md +1 -1
  12. data/guides/ruby_prof.md +0 -2
  13. data/guides/stack_prof.md +1 -5
  14. data/lib/test_prof.rb +6 -31
  15. data/lib/test_prof/event_prof.rb +4 -2
  16. data/lib/test_prof/event_prof/custom_events.rb +3 -3
  17. data/lib/test_prof/event_prof/custom_events/factory_create.rb +9 -11
  18. data/lib/test_prof/event_prof/custom_events/sidekiq_inline.rb +9 -11
  19. data/lib/test_prof/event_prof/custom_events/sidekiq_jobs.rb +11 -13
  20. data/lib/test_prof/event_prof/rspec.rb +1 -5
  21. data/lib/test_prof/factory_doctor.rb +9 -11
  22. data/lib/test_prof/factory_doctor/rspec.rb +3 -5
  23. data/lib/test_prof/ruby_prof.rb +12 -6
  24. data/lib/test_prof/stack_prof.rb +7 -14
  25. data/lib/test_prof/version.rb +1 -1
  26. data/spec/integrations/any_fixture_spec.rb +11 -0
  27. data/spec/integrations/before_all_spec.rb +11 -0
  28. data/spec/integrations/event_prof_spec.rb +100 -0
  29. data/spec/integrations/factory_doctor_spec.rb +20 -0
  30. data/spec/integrations/fixtures/rspec/any_fixture_fixture.rb +37 -0
  31. data/spec/integrations/fixtures/rspec/before_all_fixture.rb +32 -0
  32. data/spec/integrations/fixtures/rspec/event_prof_factory_create_fixture.rb +23 -0
  33. data/spec/integrations/fixtures/rspec/event_prof_fixture.rb +51 -0
  34. data/spec/integrations/fixtures/rspec/event_prof_sidekiq_fixture.rb +54 -0
  35. data/spec/integrations/fixtures/rspec/factory_doctor_fixture.rb +33 -0
  36. data/spec/spec_helper.rb +38 -0
  37. data/spec/support/ar_models.rb +43 -0
  38. data/spec/support/instrumenter_stub.rb +19 -0
  39. data/spec/support/integration_helpers.rb +13 -0
  40. data/spec/support/transactional_context.rb +11 -0
  41. data/spec/test_prof/any_fixture_spec.rb +66 -0
  42. data/spec/test_prof/event_prof_spec.rb +138 -0
  43. data/spec/test_prof/ext/float_duration_spec.rb +12 -0
  44. data/spec/test_prof/factory_doctor_spec.rb +84 -0
  45. data/spec/test_prof/ruby_prof_spec.rb +109 -0
  46. data/spec/test_prof/stack_prof_spec.rb +73 -0
  47. data/spec/test_prof_spec.rb +23 -0
  48. data/test-prof.gemspec +35 -0
  49. metadata +34 -49
  50. data/CHANGELOG.md +0 -7
  51. data/assets/flamegraph.demo.html +0 -173
  52. data/assets/flamegraph.template.html +0 -196
  53. data/assets/src/d3-tip.js +0 -352
  54. data/assets/src/d3-tip.min.js +0 -1
  55. data/assets/src/d3.flameGraph.css +0 -92
  56. data/assets/src/d3.flameGraph.js +0 -459
  57. data/assets/src/d3.flameGraph.min.css +0 -1
  58. data/assets/src/d3.flameGraph.min.js +0 -1
  59. data/assets/src/d3.v4.min.js +0 -8
  60. data/guides/factory_default.md +0 -109
  61. data/guides/factory_prof.md +0 -85
  62. data/guides/rspec_stamp.md +0 -53
  63. data/guides/rubocop.md +0 -48
  64. data/guides/tag_prof.md +0 -52
  65. data/guides/tests_sampling.md +0 -24
  66. data/lib/test_prof/cops/rspec/aggregate_failures.rb +0 -140
  67. data/lib/test_prof/factory_default.rb +0 -58
  68. data/lib/test_prof/factory_default/factory_girl_patch.rb +0 -22
  69. data/lib/test_prof/factory_prof.rb +0 -140
  70. data/lib/test_prof/factory_prof/factory_girl_patch.rb +0 -12
  71. data/lib/test_prof/factory_prof/printers/flamegraph.rb +0 -71
  72. data/lib/test_prof/factory_prof/printers/simple.rb +0 -28
  73. data/lib/test_prof/recipes/minitest/sample.rb +0 -29
  74. data/lib/test_prof/recipes/rspec/factory_default.rb +0 -9
  75. data/lib/test_prof/recipes/rspec/sample.rb +0 -13
  76. data/lib/test_prof/rspec_stamp.rb +0 -135
  77. data/lib/test_prof/rspec_stamp/parser.rb +0 -103
  78. data/lib/test_prof/rspec_stamp/rspec.rb +0 -95
  79. data/lib/test_prof/rubocop.rb +0 -3
  80. data/lib/test_prof/tag_prof.rb +0 -8
  81. data/lib/test_prof/tag_prof/rspec.rb +0 -84
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4bebeb0abae778ec18d0ec11538784b0255bd26d
4
- data.tar.gz: '098fa4a951eba03ac7fcda3e6565ca01936dd182'
3
+ metadata.gz: 528abbfd18c27537ab52c1bf580c73b4327fdbbc
4
+ data.tar.gz: dfaaa8adc9c93ec2ba4e562cf57ec3f4807ae489
5
5
  SHA512:
6
- metadata.gz: 1099d6a1805f71697cccbb555025bffba6589e87016e33d715a046368e20dda1d5d1b2df259792b144c2ba0e7f816f64e6dd745f14114b1bb4ee6446e2edbba2
7
- data.tar.gz: 4212b16b0487b6a5c4853e855a07278778cc487f0b378148d4903e180d20a935e3110542bdaf553070f499ddce220a046366b2b18049ae598b6dc36e4a54e0dc
6
+ metadata.gz: db4e05c01a501eb9e9a50d8c4d1f857437ca7c14323c7a25e739736e1139c8201c87fbefcff91c84cf0932c475e9fc2f12006f3f7feb9d6d5068d23b492bdf61
7
+ data.tar.gz: 2ba7680b870ef1acf274cabb3fd0f4bdfc73558af1d3211e2808f2e99f7864c212212fce9c7ef6f68f78d55f7d5cba1ff44674273fdb6bedfce3c135c77af2d4
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,69 @@
1
+ AllCops:
2
+ Include:
3
+ - 'lib/**/*.rb'
4
+ - 'lib/**/*.rake'
5
+ - 'spec/**/*.rb'
6
+ Exclude:
7
+ - 'bin/**/*'
8
+ - 'spec/dummy/**/*'
9
+ - 'tmp/**/*'
10
+ - 'Rakefile'
11
+ - 'Gemfile'
12
+ - '*.gemspec'
13
+ DisplayCopNames: true
14
+ StyleGuideCopsOnly: false
15
+ TargetRubyVersion: 2.3
16
+
17
+ Rails:
18
+ Enabled: false
19
+
20
+ Style/AccessorMethodName:
21
+ Enabled: false
22
+
23
+ Style/TrivialAccessors:
24
+ Enabled: false
25
+
26
+ Style/Documentation:
27
+ Exclude:
28
+ - 'spec/**/*.rb'
29
+
30
+ Style/StringLiterals:
31
+ Enabled: false
32
+
33
+ Style/RegexpLiteral:
34
+ Enabled: false
35
+
36
+ Style/SpaceInsideStringInterpolation:
37
+ EnforcedStyle: no_space
38
+
39
+ Style/ClassAndModuleChildren:
40
+ Enabled: false
41
+
42
+ Style/BlockDelimiters:
43
+ Exclude:
44
+ - 'spec/**/*.rb'
45
+
46
+ Lint/AmbiguousRegexpLiteral:
47
+ Enabled: false
48
+
49
+
50
+ Metrics/MethodLength:
51
+ Enabled: false
52
+
53
+ Metrics/AbcSize:
54
+ Enabled: false
55
+
56
+ Metrics/LineLength:
57
+ Max: 100
58
+ Exclude:
59
+ - 'spec/**/*.rb'
60
+
61
+ Metrics/BlockLength:
62
+ Exclude:
63
+ - 'spec/**/*.rb'
64
+
65
+ Rails/Date:
66
+ Enabled: false
67
+
68
+ Rails/TimeZone:
69
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.3
5
+ before_install: gem install bundler -v 1.13.6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in test-prof.gemspec
4
+ gemspec
data/README.md CHANGED
@@ -31,8 +31,6 @@ See [Table of Contents](#table-of-contents) for more.
31
31
 
32
32
  - RubyConfBy, 2017, "Run Test Run" talk [[video](https://www.youtube.com/watch?v=q52n4p0wkIs), [slides](https://speakerdeck.com/palkan/rubyconfby-minsk-2017-run-test-run)]
33
33
 
34
- - [Tips to improve speed of your test suite](https://medium.com/appaloosa-store-engineering/tips-to-improve-speed-of-your-test-suite-8418b485205c) by [Benoit Tigeot](https://github.com/benoittgt)
35
-
36
34
  ## Installation
37
35
 
38
36
  Add `test-prof` gem to your application:
@@ -55,13 +53,9 @@ Checkout our guides for each specific tool:
55
53
 
56
54
  - [Instrumentation Profiler](https://github.com/palkan/test-prof/tree/master/guides/event_prof.md) (e.g. ActiveSupport notifications)
57
55
 
58
- - [Tag Profiler](https://github.com/palkan/test-prof/tree/master/guides/tag_prof.md)
59
-
60
56
  - [Factory Doctor](https://github.com/palkan/test-prof/tree/master/guides/factory_doctor.md)
61
57
 
62
- - [Factory Profiler](https://github.com/palkan/test-prof/tree/master/guides/factory_prof.md)
63
-
64
- - [Rubocop Cops](https://github.com/palkan/test-prof/tree/master/guides/rubocop.md)
58
+ - Factory Profiler
65
59
 
66
60
  ## Tips and Tricks (or _Recipes_)
67
61
 
@@ -71,12 +65,6 @@ We also want to share some small code tricks which can help you to improve your
71
65
 
72
66
  - [AnyFixture](https://github.com/palkan/test-prof/tree/master/guides/any_fixture.md)
73
67
 
74
- - [FactoryDefault](https://github.com/palkan/test-prof/tree/master/guides/factory_default.md)
75
-
76
- - [RSpec Stamp](https://github.com/palkan/test-prof/tree/master/guides/rspec_stamp.md)
77
-
78
- - [Tests Sampling](https://github.com/palkan/test-prof/tree/master/guides/tests_sampling.md)
79
-
80
68
  ## Configuration
81
69
 
82
70
  TestProf global configuration is used by most of the profilers:
@@ -100,12 +88,10 @@ Or TODO list:
100
88
 
101
89
  - Better Minitest integration (PRs welcome!)
102
90
 
103
- - Other data generation library support (e.g [Fabricator](http://fabricationgem.org/)). _Does anyone use something except from FactoryGirl?_
91
+ - Other data generation library support (e.g [Fabricator](http://fabricationgem.org/))
104
92
 
105
93
  - Improve FactoryDoctor
106
94
 
107
- - Add more Rubocop cops (e.g. `CreateListLimit`)
108
-
109
95
  ## License
110
96
 
111
97
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require "rubocop/rake_task"
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ RuboCop::RakeTask.new
7
+
8
+ task :default => [:spec, :rubocop]
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/circle.yml ADDED
@@ -0,0 +1,11 @@
1
+ machine:
2
+ ruby:
3
+ version: 2.4.1
4
+
5
+ database:
6
+ override:
7
+ - echo "Skipping DB section."
8
+
9
+ dependencies:
10
+ pre:
11
+ - gem install bundler -v 1.13.6
@@ -18,7 +18,7 @@ RSpec.shared_context "account", account: true do
18
18
  @account = TestProf::AnyFixture.register(:account) do
19
19
  # Do anything here, AnyFixture keeps track of affected DB tables
20
20
  # For example, you can use factories here
21
- FactoryGirl.create(:account)
21
+ create(:account)
22
22
 
23
23
  # or with Fabrication
24
24
  Fabricate(:account)
data/guides/ruby_prof.md CHANGED
@@ -58,6 +58,4 @@ end
58
58
 
59
59
  By default, we use `CallStackPrinter`.
60
60
 
61
- Also, you can specify RubyProf mode (`wall`, `cpu`, etc) through `TEST_RUBY_PROF_MODE` env variable.
62
-
63
61
  See [ruby_prof.rb](https://github.com/palkan/test-prof/tree/master/lib/test_prof/ruby_prof.rb) for all available configuration options and their usage.
data/guides/stack_prof.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Profiling with StackProf
2
2
 
3
- [StackProf](https://github.com/tmm1/stackprof) is a sampling call-stack profiler for ruby.
3
+ [StackProf](https://github.com/ruby-prof/ruby-prof) is a sampling call-stack profiler for ruby.
4
4
 
5
5
  ## Instructions
6
6
 
@@ -40,8 +40,4 @@ end
40
40
 
41
41
  ### Configuration
42
42
 
43
- You can change StackProf mode (which is `wall` by default) through `TEST_STACK_PROF_MODE` env variable.
44
-
45
- If you want to generate flame graphs you should collect _raw_ data. Turn _raw_ collection on by passing `TEST_STACK_PROF_RAW=1`.
46
-
47
43
  See [stack_prof.rb](https://github.com/palkan/test-prof/tree/master/lib/test_prof/stack_prof.rb) for all available configuration options and their usage.
data/lib/test_prof.rb CHANGED
@@ -42,42 +42,20 @@ module TestProf
42
42
  false
43
43
  end
44
44
 
45
- # Run block only if provided env var is present and
46
- # equal to the provided value (if any).
45
+ # Run block only if provided env var is present.
47
46
  # Contains workaround for applications using Spring.
48
- def activate(env_var, val = nil)
49
- if defined?(::Spring)
50
- ::Spring.after_fork { activate!(env_var, val) { yield } }
47
+ def activate(env_var)
48
+ if defined?(::Spring) && !ENV['DISABLE_SPRING']
49
+ Spring.after_fork { yield if ENV[env_var] }
51
50
  else
52
- activate!(env_var, val) { yield }
51
+ yield if ENV[env_var]
53
52
  end
54
53
  end
55
54
 
56
- # Return absolute path to asset
57
- def asset_path(filename)
58
- ::File.expand_path(filename, ::File.join(::File.dirname(__FILE__), "..", "assets"))
59
- end
60
-
61
- # Return a path to store artefact
62
- def artefact_path(filename)
63
- with_timestamps(
64
- ::File.join(
65
- config.output_dir,
66
- filename
67
- )
68
- )
69
- end
70
-
71
- private
72
-
73
- def activate!(env_var, val)
74
- yield if ENV[env_var] && (val.nil? || ENV[env_var] == val)
75
- end
76
-
77
55
  def with_timestamps(path)
78
56
  return path unless config.timestamps?
79
57
  timestamps = "-#{Time.now.to_i}"
80
- "#{path.sub(/\.\w+$/, '')}#{timestamps}#{::File.extname(path)}"
58
+ "#{path.sub(/\.\w+$/, '')}#{timestamps}#{File.extname(path)}"
81
59
  end
82
60
  end
83
61
 
@@ -109,6 +87,3 @@ require "test_prof/ruby_prof"
109
87
  require "test_prof/stack_prof"
110
88
  require "test_prof/event_prof"
111
89
  require "test_prof/factory_doctor"
112
- require "test_prof/factory_prof"
113
- require "test_prof/rspec_stamp"
114
- require "test_prof/tag_prof"
@@ -65,7 +65,9 @@ module TestProf
65
65
  def build
66
66
  Profiler.new(
67
67
  event: config.event,
68
- instrumenter: config.resolve_instrumenter
68
+ instrumenter: config.resolve_instrumenter,
69
+ rank_by: config.rank_by,
70
+ top_count: config.top_count
69
71
  )
70
72
  end
71
73
  end
@@ -75,7 +77,7 @@ module TestProf
75
77
 
76
78
  attr_reader :event, :top_count, :rank_by, :total_count, :total_time
77
79
 
78
- def initialize(event:, instrumenter:)
80
+ def initialize(event:, instrumenter:, rank_by:, top_count:)
79
81
  @event = event
80
82
 
81
83
  log :info, "EventProf enabled (#{@event})"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "test_prof/event_prof/custom_events/factory_create"
4
- require "test_prof/event_prof/custom_events/sidekiq_inline"
5
- require "test_prof/event_prof/custom_events/sidekiq_jobs"
3
+ require "test_prof/event_prof/custom_events/factory_create" if ENV['EVENT_PROF'] == "factory.create"
4
+ require "test_prof/event_prof/custom_events/sidekiq_inline" if ENV['EVENT_PROF'] == "sidekiq.inline"
5
+ require "test_prof/event_prof/custom_events/sidekiq_jobs" if ENV['EVENT_PROF'] == "sidekiq.jobs"
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TestProf::EventProf::CustomEvents
4
- module FactoryCreate # :nodoc: all
4
+ module FactoryCreate
5
5
  module RunnerPatch
6
6
  def run(strategy = @strategy)
7
7
  return super unless strategy == :create
@@ -39,15 +39,13 @@ module TestProf::EventProf::CustomEvents
39
39
  end
40
40
  end
41
41
 
42
- TestProf.activate('EVENT_PROF', 'factory.create') do
43
- if TestProf.require(
44
- 'factory_girl',
45
- <<~MSG
46
- Failed to load FactoryGirl.
42
+ if TestProf.require(
43
+ 'factory_girl',
44
+ <<~MSG
45
+ Failed to load FactoryGirl.
47
46
 
48
- Make sure that "factory_girl" gem is in your Gemfile.
49
- MSG
50
- )
51
- TestProf::EventProf::CustomEvents::FactoryCreate.setup!
52
- end
47
+ Make sure that "factory_girl" gem is in your Gemfile.
48
+ MSG
49
+ )
50
+ TestProf::EventProf::CustomEvents::FactoryCreate.setup!
53
51
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TestProf::EventProf::CustomEvents
4
- module SidekiqInline # :nodoc: all
4
+ module SidekiqInline
5
5
  module ClientPatch
6
6
  def raw_push(*)
7
7
  return super unless Sidekiq::Testing.inline?
@@ -36,15 +36,13 @@ module TestProf::EventProf::CustomEvents
36
36
  end
37
37
  end
38
38
 
39
- TestProf.activate('EVENT_PROF', 'sidekiq.inline') do
40
- if TestProf.require(
41
- 'sidekiq/testing',
42
- <<~MSG
43
- Failed to load Sidekiq.
39
+ if TestProf.require(
40
+ 'sidekiq/testing',
41
+ <<~MSG
42
+ Failed to load Sidekiq.
44
43
 
45
- Make sure that "sidekiq" gem is in your Gemfile.
46
- MSG
47
- )
48
- TestProf::EventProf::CustomEvents::SidekiqInline.setup!
49
- end
44
+ Make sure that "sidekiq" gem is in your Gemfile.
45
+ MSG
46
+ )
47
+ TestProf::EventProf::CustomEvents::SidekiqInline.setup!
50
48
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TestProf::EventProf::CustomEvents
4
- module SidekiqJobs # :nodoc: all
4
+ module SidekiqJobs
5
5
  module ClientPatch
6
6
  def raw_push(*)
7
7
  return super unless Sidekiq::Testing.inline?
@@ -23,18 +23,16 @@ module TestProf::EventProf::CustomEvents
23
23
  end
24
24
  end
25
25
 
26
- TestProf.activate('EVENT_PROF', 'sidekiq.jobs') do
27
- if TestProf.require(
28
- 'sidekiq/testing',
29
- <<~MSG
30
- Failed to load Sidekiq.
26
+ if TestProf.require(
27
+ 'sidekiq/testing',
28
+ <<~MSG
29
+ Failed to load Sidekiq.
31
30
 
32
- Make sure that "sidekiq" gem is in your Gemfile.
33
- MSG
34
- )
35
- TestProf::EventProf::CustomEvents::SidekiqJobs.setup!
36
- TestProf::EventProf.configure do |config|
37
- config.rank_by = :count
38
- end
31
+ Make sure that "sidekiq" gem is in your Gemfile.
32
+ MSG
33
+ )
34
+ TestProf::EventProf::CustomEvents::SidekiqJobs.setup!
35
+ TestProf::EventProf.configure do |config|
36
+ config.rank_by = :count
39
37
  end
40
38
  end
@@ -87,11 +87,7 @@ TestProf.activate('EVENT_PROF') do
87
87
  RSpec.configure do |config|
88
88
  listener = TestProf::EventProf::RSpecListener.new
89
89
 
90
- config.before(:suite) do
91
- config.reporter.register_listener(
92
- listener, *TestProf::EventProf::RSpecListener::NOTIFICATIONS
93
- )
94
- end
90
+ config.reporter.register_listener(listener, *TestProf::EventProf::RSpecListener::NOTIFICATIONS)
95
91
 
96
92
  config.after(:suite) { listener.print }
97
93
  end
@@ -3,8 +3,8 @@
3
3
  require "test_prof/factory_doctor/factory_girl_patch"
4
4
 
5
5
  module TestProf
6
- # FactoryDoctor is a tool that helps you identify
7
- # tests that perform unnecessary database queries.
6
+ # FactoryDoctor is a tool that helps you identify such _bad_ tests,
7
+ # i.e. tests that perform unnecessary database queries.
8
8
  module FactoryDoctor
9
9
  class Result # :nodoc:
10
10
  attr_reader :count, :time, :queries_count
@@ -81,16 +81,14 @@ module TestProf
81
81
  def within_factory(strategy)
82
82
  return yield if ignore? || !running? || (strategy != :create)
83
83
 
84
- begin
85
- ts = Time.now if @depth.zero?
86
- @depth += 1
87
- @count += 1
88
- yield
89
- ensure
90
- @depth -= 1
84
+ ts = Time.now if @depth.zero?
85
+ @depth += 1
86
+ @count += 1
87
+ yield
88
+ ensure
89
+ @depth -= 1
91
90
 
92
- @time += (Time.now - ts) if @depth.zero?
93
- end
91
+ @time += (Time.now - ts) if @depth.zero?
94
92
  end
95
93
 
96
94
  private