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.
- checksums.yaml +4 -4
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.rubocop.yml +69 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/README.md +2 -16
- data/Rakefile +8 -0
- data/bin/setup +8 -0
- data/circle.yml +11 -0
- data/guides/any_fixture.md +1 -1
- data/guides/ruby_prof.md +0 -2
- data/guides/stack_prof.md +1 -5
- data/lib/test_prof.rb +6 -31
- data/lib/test_prof/event_prof.rb +4 -2
- data/lib/test_prof/event_prof/custom_events.rb +3 -3
- data/lib/test_prof/event_prof/custom_events/factory_create.rb +9 -11
- data/lib/test_prof/event_prof/custom_events/sidekiq_inline.rb +9 -11
- data/lib/test_prof/event_prof/custom_events/sidekiq_jobs.rb +11 -13
- data/lib/test_prof/event_prof/rspec.rb +1 -5
- data/lib/test_prof/factory_doctor.rb +9 -11
- data/lib/test_prof/factory_doctor/rspec.rb +3 -5
- data/lib/test_prof/ruby_prof.rb +12 -6
- data/lib/test_prof/stack_prof.rb +7 -14
- data/lib/test_prof/version.rb +1 -1
- data/spec/integrations/any_fixture_spec.rb +11 -0
- data/spec/integrations/before_all_spec.rb +11 -0
- data/spec/integrations/event_prof_spec.rb +100 -0
- data/spec/integrations/factory_doctor_spec.rb +20 -0
- data/spec/integrations/fixtures/rspec/any_fixture_fixture.rb +37 -0
- data/spec/integrations/fixtures/rspec/before_all_fixture.rb +32 -0
- data/spec/integrations/fixtures/rspec/event_prof_factory_create_fixture.rb +23 -0
- data/spec/integrations/fixtures/rspec/event_prof_fixture.rb +51 -0
- data/spec/integrations/fixtures/rspec/event_prof_sidekiq_fixture.rb +54 -0
- data/spec/integrations/fixtures/rspec/factory_doctor_fixture.rb +33 -0
- data/spec/spec_helper.rb +38 -0
- data/spec/support/ar_models.rb +43 -0
- data/spec/support/instrumenter_stub.rb +19 -0
- data/spec/support/integration_helpers.rb +13 -0
- data/spec/support/transactional_context.rb +11 -0
- data/spec/test_prof/any_fixture_spec.rb +66 -0
- data/spec/test_prof/event_prof_spec.rb +138 -0
- data/spec/test_prof/ext/float_duration_spec.rb +12 -0
- data/spec/test_prof/factory_doctor_spec.rb +84 -0
- data/spec/test_prof/ruby_prof_spec.rb +109 -0
- data/spec/test_prof/stack_prof_spec.rb +73 -0
- data/spec/test_prof_spec.rb +23 -0
- data/test-prof.gemspec +35 -0
- metadata +34 -49
- data/CHANGELOG.md +0 -7
- data/assets/flamegraph.demo.html +0 -173
- data/assets/flamegraph.template.html +0 -196
- data/assets/src/d3-tip.js +0 -352
- data/assets/src/d3-tip.min.js +0 -1
- data/assets/src/d3.flameGraph.css +0 -92
- data/assets/src/d3.flameGraph.js +0 -459
- data/assets/src/d3.flameGraph.min.css +0 -1
- data/assets/src/d3.flameGraph.min.js +0 -1
- data/assets/src/d3.v4.min.js +0 -8
- data/guides/factory_default.md +0 -109
- data/guides/factory_prof.md +0 -85
- data/guides/rspec_stamp.md +0 -53
- data/guides/rubocop.md +0 -48
- data/guides/tag_prof.md +0 -52
- data/guides/tests_sampling.md +0 -24
- data/lib/test_prof/cops/rspec/aggregate_failures.rb +0 -140
- data/lib/test_prof/factory_default.rb +0 -58
- data/lib/test_prof/factory_default/factory_girl_patch.rb +0 -22
- data/lib/test_prof/factory_prof.rb +0 -140
- data/lib/test_prof/factory_prof/factory_girl_patch.rb +0 -12
- data/lib/test_prof/factory_prof/printers/flamegraph.rb +0 -71
- data/lib/test_prof/factory_prof/printers/simple.rb +0 -28
- data/lib/test_prof/recipes/minitest/sample.rb +0 -29
- data/lib/test_prof/recipes/rspec/factory_default.rb +0 -9
- data/lib/test_prof/recipes/rspec/sample.rb +0 -13
- data/lib/test_prof/rspec_stamp.rb +0 -135
- data/lib/test_prof/rspec_stamp/parser.rb +0 -103
- data/lib/test_prof/rspec_stamp/rspec.rb +0 -95
- data/lib/test_prof/rubocop.rb +0 -3
- data/lib/test_prof/tag_prof.rb +0 -8
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 528abbfd18c27537ab52c1bf580c73b4327fdbbc
|
4
|
+
data.tar.gz: dfaaa8adc9c93ec2ba4e562cf57ec3f4807ae489
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db4e05c01a501eb9e9a50d8c4d1f857437ca7c14323c7a25e739736e1139c8201c87fbefcff91c84cf0932c475e9fc2f12006f3f7feb9d6d5068d23b492bdf61
|
7
|
+
data.tar.gz: 2ba7680b870ef1acf274cabb3fd0f4bdfc73558af1d3211e2808f2e99f7864c212212fce9c7ef6f68f78d55f7d5cba1ff44674273fdb6bedfce3c135c77af2d4
|
data/.gitignore
ADDED
data/.rspec
ADDED
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
data/Gemfile
ADDED
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
|
-
-
|
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/))
|
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
data/bin/setup
ADDED
data/circle.yml
ADDED
data/guides/any_fixture.md
CHANGED
@@ -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
|
-
|
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/
|
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
|
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
|
49
|
-
if defined?(::Spring)
|
50
|
-
|
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
|
-
|
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}#{
|
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"
|
data/lib/test_prof/event_prof.rb
CHANGED
@@ -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
|
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.
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
Failed to load FactoryGirl.
|
42
|
+
if TestProf.require(
|
43
|
+
'factory_girl',
|
44
|
+
<<~MSG
|
45
|
+
Failed to load FactoryGirl.
|
47
46
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
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
|
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.
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
Failed to load Sidekiq.
|
39
|
+
if TestProf.require(
|
40
|
+
'sidekiq/testing',
|
41
|
+
<<~MSG
|
42
|
+
Failed to load Sidekiq.
|
44
43
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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
|
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.
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
Failed to load Sidekiq.
|
26
|
+
if TestProf.require(
|
27
|
+
'sidekiq/testing',
|
28
|
+
<<~MSG
|
29
|
+
Failed to load Sidekiq.
|
31
30
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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.
|
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
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
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
|
-
|
93
|
-
end
|
91
|
+
@time += (Time.now - ts) if @depth.zero?
|
94
92
|
end
|
95
93
|
|
96
94
|
private
|