lab_tech 0.1.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +323 -0
- data/Rakefile +30 -0
- data/app/models/lab_tech/application_record.rb +5 -0
- data/app/models/lab_tech/default_cleaner.rb +87 -0
- data/app/models/lab_tech/experiment.rb +190 -0
- data/app/models/lab_tech/observation.rb +40 -0
- data/app/models/lab_tech/percentile.rb +41 -0
- data/app/models/lab_tech/result.rb +130 -0
- data/app/models/lab_tech/speedup.rb +65 -0
- data/app/models/lab_tech/summary.rb +183 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20190815192130_create_experiment_tables.rb +50 -0
- data/lib/lab_tech.rb +176 -0
- data/lib/lab_tech/engine.rb +6 -0
- data/lib/lab_tech/version.rb +3 -0
- data/lib/tasks/lab_tech_tasks.rake +4 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/config/manifest.js +1 -0
- data/spec/dummy/app/assets/javascripts/application.js +14 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +2 -0
- data/spec/dummy/app/jobs/application_job.rb +2 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +33 -0
- data/spec/dummy/bin/update +28 -0
- data/spec/dummy/config.ru +5 -0
- data/spec/dummy/config/application.rb +35 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +46 -0
- data/spec/dummy/config/environments/production.rb +71 -0
- data/spec/dummy/config/environments/test.rb +36 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cors.rb +16 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +33 -0
- data/spec/dummy/config/puma.rb +34 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/spring.rb +6 -0
- data/spec/dummy/db/schema.rb +52 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +0 -0
- data/spec/dummy/log/test.log +1519 -0
- data/spec/examples.txt +79 -0
- data/spec/models/lab_tech/default_cleaner_spec.rb +32 -0
- data/spec/models/lab_tech/experiment_spec.rb +110 -0
- data/spec/models/lab_tech/percentile_spec.rb +85 -0
- data/spec/models/lab_tech/result_spec.rb +198 -0
- data/spec/models/lab_tech/speedup_spec.rb +133 -0
- data/spec/models/lab_tech/summary_spec.rb +325 -0
- data/spec/models/lab_tech_spec.rb +23 -0
- data/spec/rails_helper.rb +62 -0
- data/spec/spec_helper.rb +98 -0
- data/spec/support/misc_helpers.rb +7 -0
- metadata +238 -0
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
RSpec.describe LabTech::Speedup do
|
4
|
+
# Some quick reference calculations.
|
5
|
+
#
|
6
|
+
# baseline | comparison | time | factor | comment
|
7
|
+
# 2.0 | 1.0 | +1.0 | +2.0 |
|
8
|
+
# 2.0 | 1.5 | +0.5 | +1.333 |
|
9
|
+
# 2.0 | 2.0 | 0.0 | +0.0 | zero by definition
|
10
|
+
# 2.0 | 2.5 | -0.5 | -1.25 |
|
11
|
+
# 2.0 | 3.0 | -1.0 | -1.5 |
|
12
|
+
# 2.0 | 3.5 | -1.5 | -1.75 |
|
13
|
+
# 2.0 | 4.0 | -2.0 | -2.0 |
|
14
|
+
|
15
|
+
specify ".compute_time_delta" do
|
16
|
+
aggregate_failures do
|
17
|
+
expect( described_class.compute_time_delta( 2.0, 1.0 ) ).to be_within( 0.001 ).of( +1.0 )
|
18
|
+
expect( described_class.compute_time_delta( 2.0, 1.5 ) ).to be_within( 0.001 ).of( +0.5 )
|
19
|
+
expect( described_class.compute_time_delta( 2.0, 2.0 ) ).to be_within( 0.001 ).of( 0.0 )
|
20
|
+
expect( described_class.compute_time_delta( 2.0, 2.5 ) ).to be_within( 0.001 ).of( -0.5 )
|
21
|
+
expect( described_class.compute_time_delta( 2.0, 3.0 ) ).to be_within( 0.001 ).of( -1.0 )
|
22
|
+
expect( described_class.compute_time_delta( 2.0, 3.5 ) ).to be_within( 0.001 ).of( -1.5 )
|
23
|
+
expect( described_class.compute_time_delta( 2.0, 4.0 ) ).to be_within( 0.001 ).of( -2.0 )
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
specify ".compute_factor" do
|
28
|
+
aggregate_failures do
|
29
|
+
expect( described_class.compute_factor( 2.0, 1.0 ) ).to be_within( 0.001 ).of( +2.0 )
|
30
|
+
expect( described_class.compute_factor( 2.0, 1.5 ) ).to be_within( 0.001 ).of( +1.333 )
|
31
|
+
expect( described_class.compute_factor( 2.0, 2.0 ) ).to be_within( 0.001 ).of( 0.0 )
|
32
|
+
expect( described_class.compute_factor( 2.0, 2.5 ) ).to be_within( 0.001 ).of( -1.25 )
|
33
|
+
expect( described_class.compute_factor( 2.0, 3.0 ) ).to be_within( 0.001 ).of( -1.5 )
|
34
|
+
expect( described_class.compute_factor( 2.0, 3.5 ) ).to be_within( 0.001 ).of( -1.75 )
|
35
|
+
expect( described_class.compute_factor( 2.0, 4.0 ) ).to be_within( 0.001 ).of( -2.0 )
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def new_speedup(baseline = nil, comparison = nil, time = nil, factor = nil)
|
40
|
+
described_class.new( baseline: baseline, comparison: comparison, time: time, factor: factor )
|
41
|
+
end
|
42
|
+
|
43
|
+
it "acts like a simple model when all attributes are provided" do
|
44
|
+
x = new_speedup( 2.0, 1.0, -1.0, 2.0 )
|
45
|
+
|
46
|
+
expect( x.baseline ).to eq( +2.0 )
|
47
|
+
expect( x.comparison ).to eq( +1.0 )
|
48
|
+
expect( x.time ).to eq( -1.0 )
|
49
|
+
expect( x.factor ).to eq( +2.0 )
|
50
|
+
end
|
51
|
+
|
52
|
+
it "cheerfully tolerates missing baseline and comparison" do
|
53
|
+
x = new_speedup( nil, nil, -1.0, 2.0 )
|
54
|
+
|
55
|
+
expect( x.baseline ).to be nil
|
56
|
+
expect( x.comparison ).to be nil
|
57
|
+
expect( x.time ).to eq( -1.0 )
|
58
|
+
expect( x.factor ).to eq( +2.0 )
|
59
|
+
end
|
60
|
+
|
61
|
+
it "computes time and factor if they're missing (and it has enough data to do so)" do
|
62
|
+
x = new_speedup( 2.0, 1.0, nil, nil )
|
63
|
+
|
64
|
+
expect( x.baseline ).to eq( +2.0 )
|
65
|
+
expect( x.comparison ).to eq( +1.0 )
|
66
|
+
expect( x.time ).to eq( +1.0 )
|
67
|
+
expect( x.factor ).to eq( +2.0 )
|
68
|
+
end
|
69
|
+
|
70
|
+
it "doesn't compute time and factor if baseline is missing" do
|
71
|
+
x = new_speedup( 2.0, nil, nil, nil )
|
72
|
+
|
73
|
+
expect( x.baseline ).to eq( +2.0 )
|
74
|
+
expect( x.comparison ).to be nil
|
75
|
+
expect( x.time ).to be nil
|
76
|
+
expect( x.factor ).to be nil
|
77
|
+
end
|
78
|
+
|
79
|
+
it "doesn't compute time and factor if comparison is missing" do
|
80
|
+
x = new_speedup( nil, 2.0, nil, nil )
|
81
|
+
|
82
|
+
expect( x.baseline ).to be nil
|
83
|
+
expect( x.comparison ).to eq( +2.0 )
|
84
|
+
expect( x.time ).to be nil
|
85
|
+
expect( x.factor ).to be nil
|
86
|
+
end
|
87
|
+
|
88
|
+
it "is Comparable" do
|
89
|
+
x = new_speedup( 2.0, 1.0 )
|
90
|
+
y = new_speedup( 2.0, 2.0 )
|
91
|
+
z = new_speedup( 2.0, 3.0 )
|
92
|
+
|
93
|
+
expect( [ x, z, y ].sort ).to eq( [ z, y, x ] )
|
94
|
+
end
|
95
|
+
|
96
|
+
it "is not valid if time is nil" do
|
97
|
+
x = new_speedup( nil, nil, -1.0, 2.0 )
|
98
|
+
allow( x ).to receive( :time ).and_return nil
|
99
|
+
|
100
|
+
expect( x ).to_not be_valid
|
101
|
+
end
|
102
|
+
|
103
|
+
it "is not valid if factor is nil" do
|
104
|
+
x = new_speedup( nil, nil, -1.0, 2.0 )
|
105
|
+
allow( x ).to receive( :factor ).and_return nil
|
106
|
+
|
107
|
+
expect( x ).to_not be_valid
|
108
|
+
end
|
109
|
+
|
110
|
+
it "is valid if time and factor are present (and can't be disproved)" do
|
111
|
+
x = new_speedup( nil, nil, -1.0, 2.0 )
|
112
|
+
expect( x.time ).to be_present # precondition check
|
113
|
+
expect( x.factor ).to be_present # precondition check
|
114
|
+
|
115
|
+
expect( x ).to be_valid
|
116
|
+
end
|
117
|
+
|
118
|
+
it "is not valid if time doesn't agree with timing data" do
|
119
|
+
x = new_speedup( 2.0, 1.0, nil, nil )
|
120
|
+
allow( x ).to receive( :time ).and_return( 42 )
|
121
|
+
|
122
|
+
expect( x ).to_not be_valid
|
123
|
+
end
|
124
|
+
|
125
|
+
it "is not valid if factor doesn't agree with timing data" do
|
126
|
+
x = new_speedup( 2.0, 1.0, nil, nil )
|
127
|
+
allow( x ).to receive( :factor ).and_return( 42 )
|
128
|
+
|
129
|
+
expect( x ).to_not be_valid
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
@@ -0,0 +1,325 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
RSpec.describe LabTech::Summary do
|
4
|
+
let!(:experiment) { LabTech::Experiment.create(name: "wibble", percent_enabled: 100) }
|
5
|
+
let(:summary_text) { experiment.summary.to_s }
|
6
|
+
|
7
|
+
def record_experiment(cont: "foo", cand: "foo", speedup_factor: nil, baseline: 1.0, comparison: nil)
|
8
|
+
LabTech.publish_results_in_test_mode do
|
9
|
+
|
10
|
+
LabTech.science "wibble" do |e|
|
11
|
+
e.use { cont.respond_to?(:call) ? cont.call : cont }
|
12
|
+
e.try { cand.respond_to?(:call) ? cand.call : cand }
|
13
|
+
end
|
14
|
+
|
15
|
+
#######################################
|
16
|
+
|
17
|
+
######## ##### ###### #####
|
18
|
+
## ## ## ## ## ## ##
|
19
|
+
## ## ## ## ## ## ##
|
20
|
+
## ## ## ## ## ## ##
|
21
|
+
## ## ## ## ## ## ##
|
22
|
+
## ## ## ## ## ## ##
|
23
|
+
## ##### ###### #####
|
24
|
+
|
25
|
+
#######################################
|
26
|
+
# TODO: use Scientist's fabricate_durations_for_testing_purposes to make
|
27
|
+
# the below comment (and code?) unnecessary
|
28
|
+
#######################################
|
29
|
+
# Don't bother stubbing Scientist's clock; you'll get the wrong results 50%
|
30
|
+
# of the time because it runs the `try` and `use` blocks in random order,
|
31
|
+
# and then you'll be very very confused.
|
32
|
+
if speedup_factor && comparison.nil?
|
33
|
+
baseline = baseline.to_f
|
34
|
+
comparison = \
|
35
|
+
case
|
36
|
+
when speedup_factor > 0 ; +1.0 * baseline / speedup_factor
|
37
|
+
when speedup_factor == 0 ; +1.0 * baseline
|
38
|
+
else ; -1.0 * baseline * speedup_factor
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
if baseline && comparison && speedup_factor.nil?
|
43
|
+
speedup_factor = LabTech::Speedup.compute_factor(baseline, comparison)
|
44
|
+
end
|
45
|
+
|
46
|
+
if baseline && comparison && speedup_factor
|
47
|
+
result = experiment.results.last
|
48
|
+
result.update_attributes({
|
49
|
+
control_duration: baseline,
|
50
|
+
candidate_duration: comparison,
|
51
|
+
speedup_factor: speedup_factor,
|
52
|
+
time_delta: baseline - comparison,
|
53
|
+
})
|
54
|
+
|
55
|
+
# Technically, we only needed to update the result... but for consistency, let's update the observations too.
|
56
|
+
result.control .update_attributes duration: baseline
|
57
|
+
result.candidates.first .update_attributes duration: comparison
|
58
|
+
end
|
59
|
+
|
60
|
+
end # LabTech.publish_results_in_test_mode do
|
61
|
+
end
|
62
|
+
|
63
|
+
def wtf
|
64
|
+
puts
|
65
|
+
puts "", "Experiment" ; tp experiment
|
66
|
+
puts "", "Results" ; tp experiment.results
|
67
|
+
puts "", "Observations" ; tp experiment.observations
|
68
|
+
puts
|
69
|
+
end
|
70
|
+
|
71
|
+
context "when there are no results" do
|
72
|
+
before do
|
73
|
+
expect( experiment.results ).to be_empty # precondition check
|
74
|
+
end
|
75
|
+
|
76
|
+
it "says there are no results" do
|
77
|
+
expect( summary_text ).to match( /No results for experiment/ )
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "when the only result is a mismatch" do
|
82
|
+
before do
|
83
|
+
record_experiment cont: "foo", cand: "bar"
|
84
|
+
end
|
85
|
+
|
86
|
+
it "reports the correct counts" do
|
87
|
+
aggregate_failures do
|
88
|
+
expect( summary_text ).to_not include( "0 of 1 (0.00%) correct" )
|
89
|
+
expect( summary_text ).to include( "1 of 1 (100.00%) mismatched" )
|
90
|
+
expect( summary_text ).to_not include( "0 of 1 (0.00%) timed out" )
|
91
|
+
expect( summary_text ).to_not include( "0 of 1 (0.00%) raised errors" )
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "when the only result is an error" do
|
97
|
+
before do
|
98
|
+
record_experiment cont: "foo", cand: ->{ raise "nope" }
|
99
|
+
end
|
100
|
+
|
101
|
+
it "reports the correct counts" do
|
102
|
+
aggregate_failures do
|
103
|
+
expect( summary_text ).to_not include( "0 of 1 (0.00%) correct" )
|
104
|
+
expect( summary_text ).to_not include( "0 of 1 (0.00%) mismatched" )
|
105
|
+
expect( summary_text ).to_not include( "0 of 1 (0.00%) timed out" )
|
106
|
+
expect( summary_text ).to include( "1 of 1 (100.00%) raised errors" )
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context "when the only result is a timeout" do
|
112
|
+
before do
|
113
|
+
record_experiment cont: "foo", cand: ->{ raise Timeout::Error, "too slow" }
|
114
|
+
end
|
115
|
+
|
116
|
+
it "reports the correct counts" do
|
117
|
+
aggregate_failures do
|
118
|
+
expect( summary_text ).to_not include( "0 of 1 (0.00%) correct" )
|
119
|
+
expect( summary_text ).to_not include( "0 of 1 (0.00%) mismatched" )
|
120
|
+
expect( summary_text ).to include( "1 of 1 (100.00%) timed out" )
|
121
|
+
expect( summary_text ).to_not include( "0 of 1 (0.00%) raised errors" )
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "when there are correct results that somehow lack any timing data" do
|
127
|
+
before do
|
128
|
+
record_experiment
|
129
|
+
experiment.results.update_all time_delta: nil, speedup_factor: nil
|
130
|
+
end
|
131
|
+
|
132
|
+
it "reports the correct counts" do
|
133
|
+
aggregate_failures do
|
134
|
+
expect( summary_text ).to include( "1 of 1 (100.00%) correct" )
|
135
|
+
expect( summary_text ).to_not include( "0 of 1 (0.00%) mismatched" )
|
136
|
+
expect( summary_text ).to_not include( "0 of 1 (0.00%) timed out" )
|
137
|
+
expect( summary_text ).to_not include( "0 of 1 (0.00%) raised errors" )
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
it "doesn't try to print the big table thingy" do
|
142
|
+
expect( summary_text ).to_not include( "Time deltas/speedups:" )
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe "when there are correct results that include timing data" do
|
147
|
+
def expect_percentile_line(percentile, *expected_strings)
|
148
|
+
line = summary_text.lines.detect { |e| e =~ /\s#{percentile.to_i}%/ }
|
149
|
+
aggregate_failures do
|
150
|
+
expected_strings.each do |string|
|
151
|
+
expect( line ).to include( string )
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context "with a speedup factor of 0x (yawn)" do
|
157
|
+
before do
|
158
|
+
record_experiment speedup_factor: 0
|
159
|
+
|
160
|
+
# Make sure we got the math right there...
|
161
|
+
result = experiment.results.first
|
162
|
+
aggregate_failures do
|
163
|
+
expect( result.control.duration ).to be_within( 0.001 ).of( 1.0 )
|
164
|
+
expect( result.candidates.first.duration ).to be_within( 0.001 ).of( 1.0 )
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
it "reports the correct counts" do
|
169
|
+
aggregate_failures do
|
170
|
+
expect( summary_text ).to include( "1 of 1 (100.00%) correct" )
|
171
|
+
expect( summary_text ).to_not include( "0 of 1 (0.00%) mismatched" )
|
172
|
+
expect( summary_text ).to_not include( "0 of 1 (0.00%) timed out" )
|
173
|
+
expect( summary_text ).to_not include( "0 of 1 (0.00%) raised errors" )
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
it "prints the stats visualization, including the correct speedup factor" do
|
178
|
+
expect_percentile_line( 50, "+0.0x" )
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context "with a speedup factor of 10x (yay!)" do
|
183
|
+
before do
|
184
|
+
record_experiment speedup_factor: 10
|
185
|
+
|
186
|
+
# Make sure we got the math right there...
|
187
|
+
result = experiment.results.first
|
188
|
+
aggregate_failures do
|
189
|
+
expect( result.control.duration ).to be_within( 0.001 ).of( 1.0 )
|
190
|
+
expect( result.candidates.first.duration ).to be_within( 0.001 ).of( 0.1 )
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
it "prints the stats visualization, including the correct speedup factor" do
|
195
|
+
expect_percentile_line( 50, "+10.0x" )
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
context "with a speedup factor of -10x (boo!)" do
|
200
|
+
before do
|
201
|
+
record_experiment speedup_factor: -10
|
202
|
+
|
203
|
+
# Make sure we got the math right there...
|
204
|
+
result = experiment.results.first
|
205
|
+
aggregate_failures do
|
206
|
+
expect( result.control.duration ).to be_within( 0.001 ).of( 1.0 )
|
207
|
+
expect( result.candidates.first.duration ).to be_within( 0.001 ).of( 10.0 )
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
it "prints the stats visualization, including the correct speedup factor" do
|
212
|
+
expect_percentile_line( 50, "-10.0x" )
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
context "with multiple results and different speedups" do
|
217
|
+
before do
|
218
|
+
record_experiment speedup_factor: -10
|
219
|
+
record_experiment speedup_factor: -2
|
220
|
+
record_experiment speedup_factor: 0
|
221
|
+
record_experiment speedup_factor: 2
|
222
|
+
record_experiment speedup_factor: 10
|
223
|
+
end
|
224
|
+
|
225
|
+
it "reports the correct counts" do
|
226
|
+
aggregate_failures do
|
227
|
+
expect( summary_text ).to include( "5 of 5 (100.00%) correct" )
|
228
|
+
expect( summary_text ).to_not include( "0 of 5 (0.00%) mismatched" )
|
229
|
+
expect( summary_text ).to_not include( "0 of 5 (0.00%) timed out" )
|
230
|
+
expect( summary_text ).to_not include( "0 of 5 (0.00%) raised errors" )
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
it "reports median time deltas, as well as 5th & 95th percentiles, on their own line" do
|
235
|
+
time_delta_line = summary_text.lines.detect { |e| e =~ /Median time delta/i }
|
236
|
+
expect( time_delta_line ).to be_present
|
237
|
+
|
238
|
+
expect( time_delta_line ).to include( "-9.000s" ) # 5th percentile
|
239
|
+
expect( time_delta_line ).to include( "+0.000s" ) # Median
|
240
|
+
expect( time_delta_line ).to include( "+0.900s" ) # 95th percentile
|
241
|
+
end
|
242
|
+
|
243
|
+
it "prints the stats visualization, including the correct speedup factor" do
|
244
|
+
# This is effectively acting as an integration test for the Array#percentile method we've monkeypatched in
|
245
|
+
aggregate_failures do
|
246
|
+
expect_percentile_line( 0, "-10.0x" )
|
247
|
+
expect_percentile_line( 20, "-10.0x" )
|
248
|
+
|
249
|
+
expect_percentile_line( 25, "-2.0x" )
|
250
|
+
expect_percentile_line( 40, "-2.0x" )
|
251
|
+
|
252
|
+
expect_percentile_line( 45, "+0.0x" )
|
253
|
+
expect_percentile_line( 60, "+0.0x" )
|
254
|
+
|
255
|
+
expect_percentile_line( 65, "+2.0x" )
|
256
|
+
expect_percentile_line( 80, "+2.0x" )
|
257
|
+
|
258
|
+
expect_percentile_line( 85, "+10.0x" )
|
259
|
+
expect_percentile_line(100, "+10.0x" )
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
context "real-world(ish) data that led to a scaling error" do
|
265
|
+
before do
|
266
|
+
record_experiment baseline: 1.7367, speedup_factor: 10.9099
|
267
|
+
record_experiment baseline: 0.0642, speedup_factor: -3.2183
|
268
|
+
record_experiment baseline: 0.0702, speedup_factor: -1.0906
|
269
|
+
record_experiment baseline: 0.0552, speedup_factor: 1.1123
|
270
|
+
record_experiment baseline: 0.0539, speedup_factor: 1.1808
|
271
|
+
record_experiment baseline: 0.0554, speedup_factor: -1.1269
|
272
|
+
end
|
273
|
+
|
274
|
+
it "renders properly" do
|
275
|
+
aggregate_failures do
|
276
|
+
expect_percentile_line( 0, "-3.2x" )
|
277
|
+
expect_percentile_line( 15, "-3.2x" )
|
278
|
+
expect_percentile_line( 20, "-1.1x" )
|
279
|
+
expect_percentile_line( 30, "-1.1x" )
|
280
|
+
expect_percentile_line( 35, "-1.1x" )
|
281
|
+
expect_percentile_line( 50, "-1.1x" )
|
282
|
+
expect_percentile_line( 55, "+1.1x" )
|
283
|
+
expect_percentile_line( 65, "+1.1x" )
|
284
|
+
expect_percentile_line( 70, "+1.2x" )
|
285
|
+
expect_percentile_line( 80, "+1.2x" )
|
286
|
+
expect_percentile_line( 85, "+10.9x" )
|
287
|
+
expect_percentile_line(100, "+10.9x" )
|
288
|
+
end
|
289
|
+
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
context "real-world(ish) data that led to a scaling error, part 2" do
|
294
|
+
before do
|
295
|
+
record_experiment baseline: 0.0030516 , comparison: 0.00306088
|
296
|
+
record_experiment baseline: 0.000261548 , comparison: 0.00220928
|
297
|
+
record_experiment baseline: 0.000781327 , comparison: 0.00279742
|
298
|
+
record_experiment baseline: 0.00201508 , comparison: 0.002386
|
299
|
+
record_experiment baseline: 0.000593603 , comparison: 0.00275979
|
300
|
+
record_experiment baseline: 0.000259521 , comparison: 0.0021131
|
301
|
+
record_experiment baseline: 0.000673067 , comparison: 0.00250636
|
302
|
+
record_experiment baseline: 0.00229586 , comparison: 0.00285059
|
303
|
+
record_experiment baseline: 0.002911 , comparison: 0.00275513
|
304
|
+
record_experiment baseline: 0.00275274 , comparison: 0.00251802
|
305
|
+
record_experiment baseline: 0.000236285 , comparison: 0.00198174
|
306
|
+
record_experiment baseline: 0.000225291 , comparison: 0.00257419
|
307
|
+
record_experiment baseline: 0.000356831 , comparison: 0.00244557
|
308
|
+
record_experiment baseline: 0.000287118 , comparison: 0.00248476
|
309
|
+
record_experiment baseline: 0.000556486 , comparison: 0.00261352
|
310
|
+
record_experiment baseline: 0.00237066 , comparison: 0.00265087
|
311
|
+
record_experiment baseline: 0.00183386 , comparison: 0.00211302
|
312
|
+
record_experiment baseline: 0.00296087 , comparison: 0.00294441
|
313
|
+
record_experiment baseline: 0.00031988 , comparison: 0.00323599
|
314
|
+
end
|
315
|
+
|
316
|
+
it "renders properly" do
|
317
|
+
aggregate_failures do
|
318
|
+
expect_percentile_line( 0, "-11.4x" )
|
319
|
+
expect_percentile_line( 50, "-3.7x" )
|
320
|
+
expect_percentile_line(100, "+1.1x" )
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|