rspec-sharder 0.0.2 → 0.0.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/Gemfile.lock +1 -1
- data/bin/rspec-sharder +1 -73
- data/lib/rspec-sharder/command.rb +73 -0
- data/lib/rspec-sharder/version.rb +1 -1
- data/lib/rspec-sharder.rb +11 -11
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7abffffb75542211fc36495edeca3b96f32f59b6975686568b3532d2df6ff9c6
|
4
|
+
data.tar.gz: 64bccf923c9897fa23205ade6af164ca10eb60dfc3c89b760b9a73be35d382bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3cbba17bc9116dbe0a8e3f6aef9d7865f57e40c6393d2e3d3243afacfc5dee658d33fe2c729734fb43ad291280a67f124913807f0b5d69eb28f13671d194309f
|
7
|
+
data.tar.gz: 809210eec8b32c39a87c6f64dbe6e9f699c1f1242b8edb1c0a9ea8120c7945801461744ad17065913f981a81bdfe1b5e1a031a2ce68a746871db995504e39ff1
|
data/Gemfile.lock
CHANGED
data/bin/rspec-sharder
CHANGED
@@ -1,75 +1,3 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require '
|
4
|
-
require 'rspec-sharder'
|
5
|
-
|
6
|
-
def fail(message)
|
7
|
-
warn message
|
8
|
-
puts
|
9
|
-
puts @parser.help
|
10
|
-
exit 1
|
11
|
-
end
|
12
|
-
|
13
|
-
@total_shards = 1
|
14
|
-
@shard_num = 1
|
15
|
-
@persist = false
|
16
|
-
|
17
|
-
@parser = OptionParser.new do |opts|
|
18
|
-
opts.banner = <<~EOF
|
19
|
-
Groups specs into shards, ensuring that each shard has a similar size, and runs
|
20
|
-
the specified shard.
|
21
|
-
|
22
|
-
Shard size is determined by summing the saved durations for each spec file in
|
23
|
-
the shard. Durations are saved in .spec_durations. If a spec file is not found
|
24
|
-
in .spec_durations, the duration is estimated based on the number of examples in
|
25
|
-
the spec file.
|
26
|
-
|
27
|
-
.spec_durations is generate/updated after a successful run when --persist is
|
28
|
-
specified, but only for the shard which was actually executed. To generate
|
29
|
-
durations for all shards simultaneously, run with the default options of 1 total
|
30
|
-
shards and --persist:
|
31
|
-
|
32
|
-
bundle exec rspec-sharder --persist -- [<rspec-args...>]
|
33
|
-
|
34
|
-
Usage: bundle exec rspec-sharder [--total-shards <num> [--shard <num>]] [--persist] -- [<rspec-args...>]
|
35
|
-
|
36
|
-
Options:
|
37
|
-
EOF
|
38
|
-
|
39
|
-
opts.on('-h', '--help', "Print this message.") do
|
40
|
-
puts opts
|
41
|
-
exit
|
42
|
-
end
|
43
|
-
|
44
|
-
opts.on('-t', '--total-shards <num>', 'The total number of shards. Defaults to 1.') do |total_shards|
|
45
|
-
begin
|
46
|
-
@total_shards = Integer(total_shards)
|
47
|
-
rescue ArgumentError
|
48
|
-
fail('fatal: invalid value for --total-shards')
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
opts.on('-s', '--shard <num>', 'The shard to run. Defaults to 1.') do |shard|
|
53
|
-
begin
|
54
|
-
@shard = Integer(shard)
|
55
|
-
rescue ArgumentError
|
56
|
-
fail('fatal: invalid value for --shard')
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
opts.on('-p', '--persist', 'Save durations to .spec_durations.') do
|
61
|
-
@persist = true
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
begin
|
66
|
-
@parser.parse!
|
67
|
-
rescue StandardError => e
|
68
|
-
fail("fatal: #{e.message}")
|
69
|
-
end
|
70
|
-
|
71
|
-
fail('fatal: invalid value for --total-shards') unless @total_shards > 0
|
72
|
-
fail('fatal: invalid value for --shard') unless @shard > 0
|
73
|
-
fail('fatal: --shard may not be greater than --total-shards') unless @shard <= @total_shards
|
74
|
-
|
75
|
-
RSpec::Sharder.run(total_shards: @total_shards, shard_num: @shard, persist: @persist, rspec_args: ARGV)
|
3
|
+
require 'rspec-sharder/command'
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'rspec-sharder'
|
3
|
+
|
4
|
+
def fail(message)
|
5
|
+
warn message
|
6
|
+
puts
|
7
|
+
puts @parser.help
|
8
|
+
exit 1
|
9
|
+
end
|
10
|
+
|
11
|
+
@total_shards = 1
|
12
|
+
@shard = 1
|
13
|
+
@persist = false
|
14
|
+
|
15
|
+
@parser = OptionParser.new do |opts|
|
16
|
+
opts.banner = <<~EOF
|
17
|
+
Groups specs into shards, ensuring that each shard has a similar size, and runs
|
18
|
+
the specified shard.
|
19
|
+
|
20
|
+
Shard size is determined by summing the saved durations for each spec file in
|
21
|
+
the shard. Durations are saved in .spec_durations. If a spec file is not found
|
22
|
+
in .spec_durations, the duration is estimated based on the number of examples in
|
23
|
+
the spec file.
|
24
|
+
|
25
|
+
.spec_durations is generate/updated after a successful run when --persist is
|
26
|
+
specified, but only for the shard which was actually executed. To generate
|
27
|
+
durations for all shards simultaneously, run with the default options of 1 total
|
28
|
+
shards and --persist:
|
29
|
+
|
30
|
+
bundle exec rspec-sharder --persist -- [<rspec-args...>]
|
31
|
+
|
32
|
+
Usage: bundle exec rspec-sharder [--total-shards <num> [--shard <num>]] [--persist] -- [<rspec-args...>]
|
33
|
+
|
34
|
+
Options:
|
35
|
+
EOF
|
36
|
+
|
37
|
+
opts.on('-h', '--help', "Print this message.") do
|
38
|
+
puts opts
|
39
|
+
exit
|
40
|
+
end
|
41
|
+
|
42
|
+
opts.on('-t', '--total-shards <num>', 'The total number of shards. Defaults to 1.') do |total_shards|
|
43
|
+
begin
|
44
|
+
@total_shards = Integer(total_shards)
|
45
|
+
rescue ArgumentError
|
46
|
+
fail('fatal: invalid value for --total-shards')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
opts.on('-s', '--shard <num>', 'The shard to run. Defaults to 1.') do |shard|
|
51
|
+
begin
|
52
|
+
@shard = Integer(shard)
|
53
|
+
rescue ArgumentError
|
54
|
+
fail('fatal: invalid value for --shard')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
opts.on('-p', '--persist', 'Save durations to .spec_durations.') do
|
59
|
+
@persist = true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
begin
|
64
|
+
@parser.parse!
|
65
|
+
rescue StandardError => e
|
66
|
+
fail("fatal: #{e.message}")
|
67
|
+
end
|
68
|
+
|
69
|
+
fail('fatal: invalid value for --total-shards') unless @total_shards > 0
|
70
|
+
fail('fatal: invalid value for --shard') unless @shard > 0
|
71
|
+
fail('fatal: --shard may not be greater than --total-shards') unless @shard <= @total_shards
|
72
|
+
|
73
|
+
RSpec::Sharder.run(total_shards: @total_shards, shard_num: @shard, persist: @persist, rspec_args: ARGV)
|
data/lib/rspec-sharder.rb
CHANGED
@@ -50,12 +50,9 @@ module RSpec
|
|
50
50
|
end
|
51
51
|
|
52
52
|
group_results = example_groups.map do |example_group|
|
53
|
-
|
54
|
-
result = example_group.run(reporter)
|
55
|
-
end_time = current_time_millis
|
53
|
+
result, duration = run_example_group(example_group, reporter)
|
56
54
|
|
57
55
|
file_path = example_group.metadata[:file_path]
|
58
|
-
duration = (end_time - start_time).to_i
|
59
56
|
actual_total_duration += duration
|
60
57
|
new_durations[file_path] ||= 0
|
61
58
|
new_durations[file_path] += duration
|
@@ -88,10 +85,7 @@ module RSpec
|
|
88
85
|
else
|
89
86
|
if exit_code == 0
|
90
87
|
# Print recorded durations and summary.
|
91
|
-
::RSpec.configuration.output_stream.puts
|
92
|
-
|
93
|
-
Durations:
|
94
|
-
EOF
|
88
|
+
::RSpec.configuration.output_stream.puts 'Durations'
|
95
89
|
|
96
90
|
new_durations.sort_by { |file_path, duration| file_path }.each do |file_path, duration|
|
97
91
|
::RSpec.configuration.output_stream.puts "#{file_path},#{duration}"
|
@@ -177,7 +171,7 @@ module RSpec
|
|
177
171
|
if durations[file_path]
|
178
172
|
files[file_path] = durations[file_path]
|
179
173
|
else
|
180
|
-
::RSpec.configuration.
|
174
|
+
::RSpec.configuration.output_stream.puts "warning: recorded duration not found for #{file_path}"
|
181
175
|
|
182
176
|
# Assume 1000 milliseconds per example.
|
183
177
|
files[file_path] += ::RSpec.world.example_count([example_group]) * 1000
|
@@ -209,7 +203,7 @@ module RSpec
|
|
209
203
|
end
|
210
204
|
::RSpec::Core::ExampleStatusPersister.persist(examples, path)
|
211
205
|
rescue SystemCallError => e
|
212
|
-
::RSpec.configuration.
|
206
|
+
::RSpec.configuration.output_stream.puts "warning: failed to write results to #{path}"
|
213
207
|
end
|
214
208
|
|
215
209
|
def self.pretty_duration(duration_millis)
|
@@ -236,7 +230,7 @@ module RSpec
|
|
236
230
|
shard[:file_paths].each do |file_path|
|
237
231
|
::RSpec.configuration.output_stream.puts file_path
|
238
232
|
end
|
239
|
-
::RSpec.configuration.output_stream.puts
|
233
|
+
::RSpec.configuration.output_stream.puts unless i == shards.size - 1
|
240
234
|
end
|
241
235
|
end
|
242
236
|
|
@@ -255,5 +249,11 @@ module RSpec
|
|
255
249
|
def self.current_time_millis
|
256
250
|
(Process.clock_gettime(Process::CLOCK_MONOTONIC) * 1000).to_i
|
257
251
|
end
|
252
|
+
|
253
|
+
def self.run_example_group(example_group, reporter)
|
254
|
+
start_time = current_time_millis
|
255
|
+
result = example_group.run(reporter)
|
256
|
+
[result, (current_time_millis - start_time).to_i]
|
257
|
+
end
|
258
258
|
end
|
259
259
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-sharder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Dower
|
@@ -39,6 +39,7 @@ files:
|
|
39
39
|
- README.md
|
40
40
|
- bin/rspec-sharder
|
41
41
|
- lib/rspec-sharder.rb
|
42
|
+
- lib/rspec-sharder/command.rb
|
42
43
|
- lib/rspec-sharder/version.rb
|
43
44
|
- rspec-sharder.gemspec
|
44
45
|
- scripts/release.sh
|