test-prof 1.2.2 → 1.2.3
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/test_prof/any_fixture/dump/sqlite.rb +1 -1
- data/lib/test_prof/any_fixture.rb +1 -1
- data/lib/test_prof/before_all.rb +1 -1
- data/lib/test_prof/core.rb +167 -0
- data/lib/test_prof/factory_all_stub.rb +1 -1
- data/lib/test_prof/factory_default.rb +1 -1
- data/lib/test_prof/recipes/logging.rb +1 -1
- data/lib/test_prof/recipes/minitest/sample.rb +2 -2
- data/lib/test_prof/recipes/rspec/let_it_be.rb +1 -1
- data/lib/test_prof/ruby_prof.rb +19 -3
- data/lib/test_prof/stack_prof.rb +1 -1
- data/lib/test_prof/version.rb +1 -1
- data/lib/test_prof.rb +1 -165
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9571b8fb7edc3bb1f92d9a6db079791a97c3cbeb11a29763ddc3e9f88bd5780a
|
4
|
+
data.tar.gz: 4011afa256c8a5f250a6a62e9745ed254f5fe020a366e3b3e4c0a91afb227d68
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9008e4dbd6131efde863a100447d0658663cfbea0486e3043664ddadff097f652230ddb162ee85893883eaf49c54ddeba806ba30563199857848466786e91d34
|
7
|
+
data.tar.gz: f86145f0d6539f6de7b3cedd315583d977df01e7e64ff22c8300bbc7f29bfd946e9f738d3b3388696c3344a8ab9e444371993e90b79f204cacf06846d314b930
|
data/CHANGELOG.md
CHANGED
data/lib/test_prof/before_all.rb
CHANGED
@@ -0,0 +1,167 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fileutils"
|
4
|
+
require "logger"
|
5
|
+
|
6
|
+
require "test_prof/logging"
|
7
|
+
require "test_prof/utils"
|
8
|
+
|
9
|
+
# Ruby applications tests profiling tools.
|
10
|
+
#
|
11
|
+
# Contains tools to analyze factories usage, integrate with Ruby profilers,
|
12
|
+
# profile your examples using ActiveSupport notifications (if any) and
|
13
|
+
# statically analyze your code with custom RuboCop cops.
|
14
|
+
#
|
15
|
+
# Example usage:
|
16
|
+
#
|
17
|
+
# require 'test_prof'
|
18
|
+
#
|
19
|
+
# # Activate a tool by providing environment variable, e.g.
|
20
|
+
# TEST_RUBY_PROF=1 rspec ...
|
21
|
+
#
|
22
|
+
# # or manually in your code
|
23
|
+
# TestProf::RubyProf.run
|
24
|
+
#
|
25
|
+
# See other modules for more examples.
|
26
|
+
module TestProf
|
27
|
+
class << self
|
28
|
+
include Logging
|
29
|
+
|
30
|
+
def config
|
31
|
+
@config ||= Configuration.new
|
32
|
+
end
|
33
|
+
|
34
|
+
def configure
|
35
|
+
yield config
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns true if we're inside RSpec
|
39
|
+
def rspec?
|
40
|
+
defined?(RSpec::Core)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns true if we're inside Minitest
|
44
|
+
def minitest?
|
45
|
+
defined?(Minitest)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns true if Spring is used and not disabled
|
49
|
+
def spring?
|
50
|
+
# See https://github.com/rails/spring/blob/577cf01f232bb6dbd0ade7df2df2ac209697e741/lib/spring/binstub.rb
|
51
|
+
disabled = ENV["DISABLE_SPRING"]
|
52
|
+
defined?(::Spring::Application) && (disabled.nil? || disabled.empty? || disabled == "0")
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns the current process time
|
56
|
+
def now
|
57
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Require gem and shows a custom
|
61
|
+
# message if it fails to load
|
62
|
+
def require(gem_name, msg = nil)
|
63
|
+
Kernel.require gem_name
|
64
|
+
block_given? ? yield : true
|
65
|
+
rescue LoadError
|
66
|
+
log(:error, msg) if msg
|
67
|
+
false
|
68
|
+
end
|
69
|
+
|
70
|
+
# Run block only if provided env var is present and
|
71
|
+
# equal to the provided value (if any).
|
72
|
+
# Contains workaround for applications using Spring.
|
73
|
+
def activate(env_var, val = nil)
|
74
|
+
if spring?
|
75
|
+
notify_spring_detected
|
76
|
+
::Spring.after_fork do
|
77
|
+
activate!(env_var, val) do
|
78
|
+
notify_spring_activate env_var
|
79
|
+
yield
|
80
|
+
end
|
81
|
+
end
|
82
|
+
else
|
83
|
+
activate!(env_var, val) { yield }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Return absolute path to asset
|
88
|
+
def asset_path(filename)
|
89
|
+
::File.expand_path(filename, ::File.join(::File.dirname(__FILE__), "..", "..", "assets"))
|
90
|
+
end
|
91
|
+
|
92
|
+
# Return a path to store artifact
|
93
|
+
def artifact_path(filename)
|
94
|
+
create_artifact_dir
|
95
|
+
|
96
|
+
with_timestamps(
|
97
|
+
::File.join(
|
98
|
+
config.output_dir,
|
99
|
+
with_report_suffix(
|
100
|
+
filename
|
101
|
+
)
|
102
|
+
)
|
103
|
+
)
|
104
|
+
end
|
105
|
+
|
106
|
+
def create_artifact_dir
|
107
|
+
FileUtils.mkdir_p(config.output_dir)[0]
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def activate!(env_var, val)
|
113
|
+
yield if ENV[env_var] && (val.nil? || val === ENV[env_var])
|
114
|
+
end
|
115
|
+
|
116
|
+
def with_timestamps(path)
|
117
|
+
return path unless config.timestamps?
|
118
|
+
timestamps = "-#{now.to_i}"
|
119
|
+
"#{path.sub(/\.\w+$/, "")}#{timestamps}#{::File.extname(path)}"
|
120
|
+
end
|
121
|
+
|
122
|
+
def with_report_suffix(path)
|
123
|
+
return path if config.report_suffix.nil?
|
124
|
+
|
125
|
+
"#{path.sub(/\.\w+$/, "")}-#{config.report_suffix}#{::File.extname(path)}"
|
126
|
+
end
|
127
|
+
|
128
|
+
def notify_spring_detected
|
129
|
+
return if instance_variable_defined?(:@spring_notified)
|
130
|
+
log :info, "Spring detected"
|
131
|
+
@spring_notified = true
|
132
|
+
end
|
133
|
+
|
134
|
+
def notify_spring_activate(env_var)
|
135
|
+
log :info, "Activating #{env_var} with `Spring.after_fork`"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# TestProf configuration
|
140
|
+
class Configuration
|
141
|
+
attr_accessor :output, # IO to write logs
|
142
|
+
:color, # Whether to colorize output or not
|
143
|
+
:output_dir, # Directory to store artifacts
|
144
|
+
:timestamps, # Whether to use timestamped names for artifacts,
|
145
|
+
:report_suffix # Custom suffix for reports/artifacts
|
146
|
+
|
147
|
+
def initialize
|
148
|
+
@output = $stdout
|
149
|
+
@color = true
|
150
|
+
@output_dir = "tmp/test_prof"
|
151
|
+
@timestamps = false
|
152
|
+
@report_suffix = ENV["TEST_PROF_REPORT"]
|
153
|
+
end
|
154
|
+
|
155
|
+
def color?
|
156
|
+
color == true && output.is_a?(IO) && output.tty?
|
157
|
+
end
|
158
|
+
|
159
|
+
def timestamps?
|
160
|
+
timestamps == true
|
161
|
+
end
|
162
|
+
|
163
|
+
def logger
|
164
|
+
@logger ||= Logger.new(output, formatter: Logging::Formatter.new)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
@@ -6,9 +6,9 @@ module TestProf
|
|
6
6
|
# Do not add these classes to resulted sample
|
7
7
|
CORE_RUNNABLES = [
|
8
8
|
Minitest::Test,
|
9
|
-
Minitest::Unit::TestCase,
|
9
|
+
defined?(Minitest::Unit::TestCase) ? Minitest::Unit::TestCase : nil,
|
10
10
|
Minitest::Spec
|
11
|
-
].freeze
|
11
|
+
].compact.freeze
|
12
12
|
|
13
13
|
class << self
|
14
14
|
def suites
|
data/lib/test_prof/ruby_prof.rb
CHANGED
@@ -53,7 +53,7 @@ module TestProf
|
|
53
53
|
def initialize
|
54
54
|
@printer = ENV["TEST_RUBY_PROF"].to_sym if PRINTERS.key?(ENV["TEST_RUBY_PROF"])
|
55
55
|
@printer ||= ENV.fetch("TEST_RUBY_PROF_PRINTER", :flat).to_sym
|
56
|
-
@mode = ENV.fetch("TEST_RUBY_PROF_MODE", :wall).
|
56
|
+
@mode = ENV.fetch("TEST_RUBY_PROF_MODE", :wall).to_s
|
57
57
|
@min_percent = 1
|
58
58
|
@include_threads = false
|
59
59
|
@exclude_common_methods = true
|
@@ -84,6 +84,22 @@ module TestProf
|
|
84
84
|
|
85
85
|
[type, ::RubyProf.const_get(PRINTERS[type])]
|
86
86
|
end
|
87
|
+
|
88
|
+
# Based on deprecated https://github.com/ruby-prof/ruby-prof/blob/fd3a5236a459586c5ca7ce4de506c1835129516a/lib/ruby-prof.rb#L36
|
89
|
+
def ruby_prof_mode
|
90
|
+
case mode
|
91
|
+
when "wall", "wall_time"
|
92
|
+
::RubyProf::WALL_TIME
|
93
|
+
when "allocations"
|
94
|
+
::RubyProf::ALLOCATIONS
|
95
|
+
when "memory"
|
96
|
+
::RubyProf::MEMORY
|
97
|
+
when "process", "process_time"
|
98
|
+
::RubyProf::PROCESS_TIME
|
99
|
+
else
|
100
|
+
::RubyProf::WALL_TIME
|
101
|
+
end
|
102
|
+
end
|
87
103
|
end
|
88
104
|
|
89
105
|
# Wrapper over RubyProf profiler and printer
|
@@ -166,7 +182,7 @@ module TestProf
|
|
166
182
|
log :warn, <<~MSG
|
167
183
|
RubyProf is activated globally, you cannot generate per-example report.
|
168
184
|
|
169
|
-
Make sure you haven'
|
185
|
+
Make sure you haven't set the TEST_RUBY_PROF environmental variable.
|
170
186
|
MSG
|
171
187
|
return
|
172
188
|
end
|
@@ -177,6 +193,7 @@ module TestProf
|
|
177
193
|
|
178
194
|
options[:include_threads] = [Thread.current] unless
|
179
195
|
config.include_threads?
|
196
|
+
options[:measure_mode] = config.ruby_prof_mode
|
180
197
|
|
181
198
|
profiler = ::RubyProf::Profile.new(options)
|
182
199
|
profiler.exclude_common_methods! if config.exclude_common_methods?
|
@@ -206,7 +223,6 @@ module TestProf
|
|
206
223
|
|
207
224
|
def init_ruby_prof
|
208
225
|
return @initialized if instance_variable_defined?(:@initialized)
|
209
|
-
ENV["RUBY_PROF_MEASURE_MODE"] = config.mode.to_s
|
210
226
|
@initialized = TestProf.require(
|
211
227
|
"ruby-prof",
|
212
228
|
<<~MSG
|
data/lib/test_prof/stack_prof.rb
CHANGED
@@ -83,7 +83,7 @@ module TestProf
|
|
83
83
|
log :warn, <<~MSG
|
84
84
|
StackProf is activated globally, you cannot generate per-example report.
|
85
85
|
|
86
|
-
Make sure you haven'
|
86
|
+
Make sure you haven't set the TEST_STACK_PROF environmental variable.
|
87
87
|
MSG
|
88
88
|
return false
|
89
89
|
end
|
data/lib/test_prof/version.rb
CHANGED
data/lib/test_prof.rb
CHANGED
@@ -1,171 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "fileutils"
|
4
|
-
require "logger"
|
5
|
-
|
6
3
|
require "test_prof/version"
|
7
|
-
require "test_prof/
|
8
|
-
require "test_prof/utils"
|
9
|
-
|
10
|
-
# Ruby applications tests profiling tools.
|
11
|
-
#
|
12
|
-
# Contains tools to analyze factories usage, integrate with Ruby profilers,
|
13
|
-
# profile your examples using ActiveSupport notifications (if any) and
|
14
|
-
# statically analyze your code with custom RuboCop cops.
|
15
|
-
#
|
16
|
-
# Example usage:
|
17
|
-
#
|
18
|
-
# require 'test_prof'
|
19
|
-
#
|
20
|
-
# # Activate a tool by providing environment variable, e.g.
|
21
|
-
# TEST_RUBY_PROF=1 rspec ...
|
22
|
-
#
|
23
|
-
# # or manually in your code
|
24
|
-
# TestProf::RubyProf.run
|
25
|
-
#
|
26
|
-
# See other modules for more examples.
|
27
|
-
module TestProf
|
28
|
-
class << self
|
29
|
-
include Logging
|
30
|
-
|
31
|
-
def config
|
32
|
-
@config ||= Configuration.new
|
33
|
-
end
|
34
|
-
|
35
|
-
def configure
|
36
|
-
yield config
|
37
|
-
end
|
38
|
-
|
39
|
-
# Returns true if we're inside RSpec
|
40
|
-
def rspec?
|
41
|
-
defined?(RSpec::Core)
|
42
|
-
end
|
43
|
-
|
44
|
-
# Returns true if we're inside Minitest
|
45
|
-
def minitest?
|
46
|
-
defined?(Minitest)
|
47
|
-
end
|
48
|
-
|
49
|
-
# Returns true if Spring is used and not disabled
|
50
|
-
def spring?
|
51
|
-
# See https://github.com/rails/spring/blob/577cf01f232bb6dbd0ade7df2df2ac209697e741/lib/spring/binstub.rb
|
52
|
-
disabled = ENV["DISABLE_SPRING"]
|
53
|
-
defined?(::Spring::Application) && (disabled.nil? || disabled.empty? || disabled == "0")
|
54
|
-
end
|
55
|
-
|
56
|
-
# Returns the current process time
|
57
|
-
def now
|
58
|
-
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
59
|
-
end
|
60
|
-
|
61
|
-
# Require gem and shows a custom
|
62
|
-
# message if it fails to load
|
63
|
-
def require(gem_name, msg = nil)
|
64
|
-
Kernel.require gem_name
|
65
|
-
block_given? ? yield : true
|
66
|
-
rescue LoadError
|
67
|
-
log(:error, msg) if msg
|
68
|
-
false
|
69
|
-
end
|
70
|
-
|
71
|
-
# Run block only if provided env var is present and
|
72
|
-
# equal to the provided value (if any).
|
73
|
-
# Contains workaround for applications using Spring.
|
74
|
-
def activate(env_var, val = nil)
|
75
|
-
if spring?
|
76
|
-
notify_spring_detected
|
77
|
-
::Spring.after_fork do
|
78
|
-
activate!(env_var, val) do
|
79
|
-
notify_spring_activate env_var
|
80
|
-
yield
|
81
|
-
end
|
82
|
-
end
|
83
|
-
else
|
84
|
-
activate!(env_var, val) { yield }
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
# Return absolute path to asset
|
89
|
-
def asset_path(filename)
|
90
|
-
::File.expand_path(filename, ::File.join(::File.dirname(__FILE__), "..", "assets"))
|
91
|
-
end
|
92
|
-
|
93
|
-
# Return a path to store artifact
|
94
|
-
def artifact_path(filename)
|
95
|
-
create_artifact_dir
|
96
|
-
|
97
|
-
with_timestamps(
|
98
|
-
::File.join(
|
99
|
-
config.output_dir,
|
100
|
-
with_report_suffix(
|
101
|
-
filename
|
102
|
-
)
|
103
|
-
)
|
104
|
-
)
|
105
|
-
end
|
106
|
-
|
107
|
-
def create_artifact_dir
|
108
|
-
FileUtils.mkdir_p(config.output_dir)[0]
|
109
|
-
end
|
110
|
-
|
111
|
-
private
|
112
|
-
|
113
|
-
def activate!(env_var, val)
|
114
|
-
yield if ENV[env_var] && (val.nil? || val === ENV[env_var])
|
115
|
-
end
|
116
|
-
|
117
|
-
def with_timestamps(path)
|
118
|
-
return path unless config.timestamps?
|
119
|
-
timestamps = "-#{now.to_i}"
|
120
|
-
"#{path.sub(/\.\w+$/, "")}#{timestamps}#{::File.extname(path)}"
|
121
|
-
end
|
122
|
-
|
123
|
-
def with_report_suffix(path)
|
124
|
-
return path if config.report_suffix.nil?
|
125
|
-
|
126
|
-
"#{path.sub(/\.\w+$/, "")}-#{config.report_suffix}#{::File.extname(path)}"
|
127
|
-
end
|
128
|
-
|
129
|
-
def notify_spring_detected
|
130
|
-
return if instance_variable_defined?(:@spring_notified)
|
131
|
-
log :info, "Spring detected"
|
132
|
-
@spring_notified = true
|
133
|
-
end
|
134
|
-
|
135
|
-
def notify_spring_activate(env_var)
|
136
|
-
log :info, "Activating #{env_var} with `Spring.after_fork`"
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
# TestProf configuration
|
141
|
-
class Configuration
|
142
|
-
attr_accessor :output, # IO to write logs
|
143
|
-
:color, # Whether to colorize output or not
|
144
|
-
:output_dir, # Directory to store artifacts
|
145
|
-
:timestamps, # Whether to use timestamped names for artifacts,
|
146
|
-
:report_suffix # Custom suffix for reports/artifacts
|
147
|
-
|
148
|
-
def initialize
|
149
|
-
@output = $stdout
|
150
|
-
@color = true
|
151
|
-
@output_dir = "tmp/test_prof"
|
152
|
-
@timestamps = false
|
153
|
-
@report_suffix = ENV["TEST_PROF_REPORT"]
|
154
|
-
end
|
155
|
-
|
156
|
-
def color?
|
157
|
-
color == true && output.is_a?(IO) && output.tty?
|
158
|
-
end
|
159
|
-
|
160
|
-
def timestamps?
|
161
|
-
timestamps == true
|
162
|
-
end
|
163
|
-
|
164
|
-
def logger
|
165
|
-
@logger ||= Logger.new(output, formatter: Logging::Formatter.new)
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|
4
|
+
require "test_prof/core"
|
169
5
|
|
170
6
|
require "test_prof/ruby_prof"
|
171
7
|
require "test_prof/stack_prof"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: test-prof
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladimir Dementyev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-09-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -143,6 +143,7 @@ files:
|
|
143
143
|
- lib/test_prof/cops/rspec/aggregate_examples/metadata_helpers.rb
|
144
144
|
- lib/test_prof/cops/rspec/aggregate_examples/node_matchers.rb
|
145
145
|
- lib/test_prof/cops/rspec/language.rb
|
146
|
+
- lib/test_prof/core.rb
|
146
147
|
- lib/test_prof/event_prof.rb
|
147
148
|
- lib/test_prof/event_prof/custom_events.rb
|
148
149
|
- lib/test_prof/event_prof/custom_events/factory_create.rb
|