stable_profile 0.4.1 → 0.6.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.
- checksums.yaml +4 -4
- data/lib/stable_profile/cli.rb +4 -2
- data/lib/stable_profile.rb +14 -23
- metadata +21 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 924cfdff88d8cc5778394fdab96b6bf5e446d92e700e995aaddea7744fbf1eaf
|
4
|
+
data.tar.gz: d80755e9aa8810910baa570e9fca02db34efd52d3cad8bae22fb883f8c5ea2c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f1310ffc4a01c70433b737342d862e3de0540168dc43d1e237c4e0549b0376b675efb10435277ae65c15ebda335d25eaf20965b43587453ed742c6728f25959c
|
7
|
+
data.tar.gz: 9ab86cfbd9ec8194c645be23b35d94e3860da7f4a23f6967832cc82f5e84cc7dc4bb31138c4eeb05c403ee97557572b8a2b3fd38a0aaa936e9bac3daba8a82ac
|
data/lib/stable_profile/cli.rb
CHANGED
@@ -4,9 +4,11 @@ require 'stable_profile'
|
|
4
4
|
|
5
5
|
module StableProfile
|
6
6
|
class CLI < Thor
|
7
|
-
desc "profile", "Run RSpec profile
|
7
|
+
desc "profile", "Run RSpec profile multiple times, averaging the results."
|
8
|
+
method_option :iterations, aliases: "-i", type: :numeric, default: 20, desc: "Number of times to run RSpec"
|
9
|
+
method_option :top_slowest_examples, aliases: "-t", type: :numeric, default: 5, desc: "Number of slowest examples to output"
|
8
10
|
def profile
|
9
|
-
StableProfile.run
|
11
|
+
StableProfile.run(iterations: options[:iterations], top_slowest_examples: options[:top_slowest_examples])
|
10
12
|
end
|
11
13
|
default_task :profile
|
12
14
|
end
|
data/lib/stable_profile.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'colorize'
|
3
4
|
require 'fileutils'
|
4
5
|
require 'json'
|
5
6
|
require 'ruby-progressbar'
|
@@ -15,18 +16,8 @@ module StableProfile
|
|
15
16
|
module_function
|
16
17
|
|
17
18
|
# How many items to output in each category.
|
18
|
-
|
19
|
-
|
20
|
-
# The more iterations you run, the more accurate the results will be.
|
21
|
-
# 20 seems like plenty, but it could take a while depending on the
|
22
|
-
# size of your test suite.
|
23
|
-
ITERATIONS = 4
|
24
|
-
|
25
|
-
# It's a slow one if it showed up in at least half the profile runs.
|
26
|
-
MINIMUM_SAMPLE_SIZE = ITERATIONS / 2
|
27
|
-
DECIMAL_PLACES = 4
|
28
|
-
|
29
|
-
OUTPUT_DIR = 'tmp/multi_profile'
|
19
|
+
DECIMAL_PLACES = 4
|
20
|
+
OUTPUT_DIR = 'tmp/stable_profile'
|
30
21
|
|
31
22
|
|
32
23
|
def bold(string)
|
@@ -34,17 +25,17 @@ module StableProfile
|
|
34
25
|
end
|
35
26
|
|
36
27
|
|
37
|
-
def run
|
38
|
-
|
28
|
+
def run(iterations:, top_slowest_examples:)
|
29
|
+
minimum_sample_size = iterations * 0.75
|
39
30
|
|
40
31
|
# Erase and Create the output directory
|
41
32
|
FileUtils.rm_rf(OUTPUT_DIR)
|
42
33
|
FileUtils.mkdir_p(OUTPUT_DIR)
|
43
34
|
|
44
35
|
# Run the specs ITERATIONS times, each time with a different random seed
|
45
|
-
progressbar = ProgressBar.create(title: 'Running profiles', total:
|
46
|
-
|
47
|
-
system("rspec --profile
|
36
|
+
progressbar = ProgressBar.create(title: 'Running profiles', total: iterations, format: '%t: |%B| %p%% %a')
|
37
|
+
iterations.times do |i|
|
38
|
+
system("rspec --profile --order random --format json > #{OUTPUT_DIR}/multi_profile_#{i+1}.json")
|
48
39
|
progressbar.increment
|
49
40
|
end
|
50
41
|
|
@@ -82,30 +73,30 @@ module StableProfile
|
|
82
73
|
|
83
74
|
# Mimic RSpec profile output
|
84
75
|
puts
|
85
|
-
puts "Top #{
|
76
|
+
puts "Top #{top_slowest_examples} slowest examples:"
|
86
77
|
count = 0
|
87
78
|
example_times.sort_by { |id, record| record[:average_time] }.reverse.each do |id, record|
|
88
79
|
next if count == TOP_SLOWEST_EXAMPLES
|
89
|
-
next if record[:run_times].size <
|
80
|
+
next if record[:run_times].size < minimum_sample_size
|
90
81
|
count += 1
|
91
82
|
|
92
83
|
example = record.fetch(:example)
|
93
84
|
|
94
|
-
puts " #{example['full_description']}"
|
85
|
+
puts " #{example['full_description']}".colorize(:light_black)
|
95
86
|
puts bold(" #{record[:average_time]} seconds").ljust(27) + " (N=#{record[:run_times].size})".ljust(7) + " #{example['file_path']}:#{example['line_number']}"
|
96
87
|
end
|
97
88
|
|
98
89
|
puts
|
99
|
-
puts "Top #{
|
90
|
+
puts "Top #{top_slowest_examples} slowest example groups:"
|
100
91
|
count = 0
|
101
92
|
group_times.sort_by { |id, record| record[:average_time] }.reverse.each do |id, record|
|
102
93
|
next if count == TOP_SLOWEST_EXAMPLES
|
103
|
-
next if record[:run_times].size <
|
94
|
+
next if record[:run_times].size < minimum_sample_size
|
104
95
|
count += 1
|
105
96
|
|
106
97
|
group = record.fetch(:group)
|
107
98
|
|
108
|
-
puts " #{group['description']}"
|
99
|
+
puts " #{group['description']}".colorize(:light_black)
|
109
100
|
puts bold(" #{record[:average_time]} seconds").ljust(27) + " (N=#{record[:run_times].size})".ljust(7) + " #{group['location']}"
|
110
101
|
end
|
111
102
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stable_profile
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robb Shecter
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-11-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: colorize
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: ruby-progressbar
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,7 +94,11 @@ dependencies:
|
|
80
94
|
- - "~>"
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: 3.12.0
|
83
|
-
description:
|
97
|
+
description: 'Solves a quirk of rspec --profile in some code bases: result vary with
|
98
|
+
every random spec ordering. This seems to be due to differences in dependency load
|
99
|
+
order, class initialization, and test server startup. This lib runs rspec --profile
|
100
|
+
many times, averaging the results to always give the same (stable) and meaningful
|
101
|
+
result.'
|
84
102
|
email:
|
85
103
|
- robb@public.law
|
86
104
|
executables:
|