test_suite_splitter 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/README.md +18 -1
- data/Rakefile +10 -0
- data/bin/test_suite_splitter +7 -2
- data/lib/test_suite_splitter/release.rb +69 -0
- data/lib/test_suite_splitter/rspec_helper.rb +23 -6
- data/lib/test_suite_splitter.rb +1 -0
- metadata +46 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ac2544ca288e5c7cb4c154043483963b1dbc9f7666c058caca6b89da805a8e2a
|
|
4
|
+
data.tar.gz: 6dc90fe1986b9f55b7aa82dda12c1545e566ed3830725d72bda19fbd863cedbd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6ee0867d88f4e7ffcc864ac2fad277071d8cf15e85bea3bdbf107ac8254ac276746d6a6e218ce31667a58779162c51871c61cb55e60319638d25f907130658ab
|
|
7
|
+
data.tar.gz: c4d31874181ec420bbc0e28e6e2b494bbb540513c91fa0e75112eabed4f6de1d6ae9090815a2aade27ee6eb1ef42d927ffb665052f53c0bb23b0d4f01f14223c
|
data/README.md
CHANGED
|
@@ -12,11 +12,28 @@ Change your CI configuration file to execute something like this:
|
|
|
12
12
|
bundle exec rspec `bundle exec test_suite_splitter --groups=6 --group-number=3`
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
On Semaphore that could be done dynamically like this:
|
|
16
16
|
```bash
|
|
17
17
|
bundle exec rspec `bundle exec test_suite_splitter --groups=${SEMAPHORE_JOB_COUNT} --group-number=${SEMAPHORE_JOB_INDEX}`
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
+
Run only a certain type of specs:
|
|
21
|
+
```bash
|
|
22
|
+
bundle exec rspec `bundle exec test_suite_splitter --groups=6 --group-number=3 --only-types=system,model`
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Exclude a certain type of specs:
|
|
26
|
+
```bash
|
|
27
|
+
bundle exec rspec `bundle exec test_suite_splitter --groups=6 --group-number=3 --exclude-types=system,feature`
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Release a new gem version:
|
|
31
|
+
```bash
|
|
32
|
+
bundle exec rake release:patch
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`release:path` is available as an alias for the same flow.
|
|
36
|
+
|
|
20
37
|
## Contributing to test_suite_splitter
|
|
21
38
|
|
|
22
39
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
data/Rakefile
CHANGED
|
@@ -8,6 +8,7 @@ rescue Bundler::BundlerError => e
|
|
|
8
8
|
exit e.status_code
|
|
9
9
|
end
|
|
10
10
|
require "rake"
|
|
11
|
+
require_relative "lib/test_suite_splitter"
|
|
11
12
|
task default: :test
|
|
12
13
|
|
|
13
14
|
require "rdoc/task"
|
|
@@ -19,3 +20,12 @@ Rake::RDocTask.new do |rdoc|
|
|
|
19
20
|
rdoc.rdoc_files.include("README*")
|
|
20
21
|
rdoc.rdoc_files.include("lib/**/*.rb")
|
|
21
22
|
end
|
|
23
|
+
|
|
24
|
+
namespace :release do
|
|
25
|
+
desc "Bump the patch version, commit it, push master, build the gem, and push it"
|
|
26
|
+
task :patch do
|
|
27
|
+
TestSuiteSplitter::Release.call(part: :patch)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
task path: :patch
|
|
31
|
+
end
|
data/bin/test_suite_splitter
CHANGED
|
@@ -24,6 +24,11 @@ ARGV.each do |arg|
|
|
|
24
24
|
args[hash_key] = value
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
begin
|
|
28
|
+
rspec_helper = ::TestSuiteSplitter::RspecHelper.new(**args)
|
|
28
29
|
|
|
29
|
-
print rspec_helper.group_files.map { |group_file| group_file.fetch(:path) }.join(" ")
|
|
30
|
+
print rspec_helper.group_files.map { |group_file| group_file.fetch(:path) }.join(" ")
|
|
31
|
+
rescue StandardError => e
|
|
32
|
+
puts e.message
|
|
33
|
+
exit 1
|
|
34
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
module TestSuiteSplitter
|
|
2
|
+
end
|
|
3
|
+
|
|
4
|
+
class TestSuiteSplitter::Release
|
|
5
|
+
VERSION_FILE = File.expand_path("../../VERSION", __dir__)
|
|
6
|
+
GEMSPEC_FILE = "test_suite_splitter.gemspec".freeze
|
|
7
|
+
MASTER_BRANCH = "master".freeze
|
|
8
|
+
|
|
9
|
+
def self.call(part: :patch)
|
|
10
|
+
new(part: part).call
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def initialize(part:)
|
|
14
|
+
@part = part.to_sym
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def call
|
|
18
|
+
next_version = bumped_version
|
|
19
|
+
write_version(next_version)
|
|
20
|
+
run("git", "commit", "VERSION", GEMSPEC_FILE, "-m", "Release #{next_version}")
|
|
21
|
+
run("git", "push", "origin", MASTER_BRANCH)
|
|
22
|
+
run("gem", "build", GEMSPEC_FILE)
|
|
23
|
+
run("gem", "push", gem_file_name(next_version))
|
|
24
|
+
next_version
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
attr_reader :part
|
|
30
|
+
|
|
31
|
+
def bumped_version
|
|
32
|
+
case part
|
|
33
|
+
when :patch, :path
|
|
34
|
+
major, minor, patch = current_version_segments
|
|
35
|
+
[major, minor, patch + 1].join(".")
|
|
36
|
+
else
|
|
37
|
+
raise ArgumentError, "Unsupported release part: #{part}"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def current_version
|
|
42
|
+
File.read(VERSION_FILE).strip
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def current_version_segments
|
|
46
|
+
segments = current_version.split(".").map do |segment|
|
|
47
|
+
Integer(segment, 10)
|
|
48
|
+
rescue ArgumentError
|
|
49
|
+
raise ArgumentError, "Invalid version: #{current_version}"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
raise ArgumentError, "Invalid version: #{current_version}" unless segments.length == 3
|
|
53
|
+
|
|
54
|
+
segments
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def gem_file_name(version)
|
|
58
|
+
"test_suite_splitter-#{version}.gem"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def run(*command)
|
|
62
|
+
success = system(*command)
|
|
63
|
+
raise "Command failed: #{command.join(' ')}" unless success
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def write_version(version)
|
|
67
|
+
File.write(VERSION_FILE, "#{version}\n")
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -143,11 +143,11 @@ private
|
|
|
143
143
|
require "stringio"
|
|
144
144
|
|
|
145
145
|
output_capture = StringIO.new
|
|
146
|
-
RSpec::Core::Runner.run(rspec_options, $stderr, output_capture)
|
|
146
|
+
exit_code = RSpec::Core::Runner.run(rspec_options, $stderr, output_capture)
|
|
147
147
|
|
|
148
148
|
result = ::JSON.parse(output_capture.string)
|
|
149
149
|
|
|
150
|
-
raise
|
|
150
|
+
raise dry_run_error_message(result: result, exit_code: exit_code) if result.fetch("examples").empty?
|
|
151
151
|
|
|
152
152
|
result
|
|
153
153
|
end
|
|
@@ -161,9 +161,11 @@ private
|
|
|
161
161
|
@files ||= begin
|
|
162
162
|
result = {}
|
|
163
163
|
dry_result.fetch("examples").each do |example|
|
|
164
|
-
|
|
164
|
+
file_path_id = example.fetch("id")
|
|
165
|
+
file_path = file_path_id.gsub(/\[([\d:]+)\]$/, "") # Same as ID but remove any [1:2:3] at the end
|
|
166
|
+
|
|
165
167
|
file_path = file_path[2, file_path.length]
|
|
166
|
-
type = type_from_path(
|
|
168
|
+
type = type_from_path(file_path_id)
|
|
167
169
|
points = points_from_type(type)
|
|
168
170
|
|
|
169
171
|
next if ignore_type?(type)
|
|
@@ -185,7 +187,9 @@ private
|
|
|
185
187
|
end
|
|
186
188
|
|
|
187
189
|
def points_from_type(type)
|
|
188
|
-
if type == "
|
|
190
|
+
if type == "system"
|
|
191
|
+
20
|
|
192
|
+
elsif type == "feature"
|
|
189
193
|
10
|
|
190
194
|
elsif type == "controllers"
|
|
191
195
|
3
|
|
@@ -207,8 +211,21 @@ private
|
|
|
207
211
|
rspec_options
|
|
208
212
|
end
|
|
209
213
|
|
|
214
|
+
def dry_run_error_message(result:, exit_code:)
|
|
215
|
+
error_summary = []
|
|
216
|
+
errors_outside_of_examples_count = result.dig("summary", "errors_outside_of_examples_count")
|
|
217
|
+
|
|
218
|
+
error_summary << "exit_code=#{exit_code}"
|
|
219
|
+
error_summary << "errors_outside_of_examples_count=#{errors_outside_of_examples_count}" if errors_outside_of_examples_count.to_i.positive?
|
|
220
|
+
|
|
221
|
+
first_message = result.fetch("messages", []).find { |message| message.strip != "" }
|
|
222
|
+
details = first_message&.strip || "No examples were found"
|
|
223
|
+
|
|
224
|
+
"RSpec dry-run failed (#{error_summary.join(', ')})\n\n#{details}"
|
|
225
|
+
end
|
|
226
|
+
|
|
210
227
|
def type_from_path(file_path)
|
|
211
|
-
match = file_path.match(
|
|
228
|
+
match = file_path.match(/^\.\/spec\/(.+?)\//)
|
|
212
229
|
match[1] if match
|
|
213
230
|
end
|
|
214
231
|
end
|
data/lib/test_suite_splitter.rb
CHANGED
metadata
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: test_suite_splitter
|
|
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
|
- kaspernj
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: base64
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :development
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
13
26
|
- !ruby/object:Gem::Dependency
|
|
14
27
|
name: bundler
|
|
15
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -24,6 +37,34 @@ dependencies:
|
|
|
24
37
|
- - ">="
|
|
25
38
|
- !ruby/object:Gem::Version
|
|
26
39
|
version: '0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: racc
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: rake
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0'
|
|
27
68
|
- !ruby/object:Gem::Dependency
|
|
28
69
|
name: rspec
|
|
29
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -94,13 +135,13 @@ files:
|
|
|
94
135
|
- Rakefile
|
|
95
136
|
- bin/test_suite_splitter
|
|
96
137
|
- lib/test_suite_splitter.rb
|
|
138
|
+
- lib/test_suite_splitter/release.rb
|
|
97
139
|
- lib/test_suite_splitter/rspec_helper.rb
|
|
98
140
|
homepage: http://github.com/kaspernj/test_suite_splitter
|
|
99
141
|
licenses:
|
|
100
142
|
- MIT
|
|
101
143
|
metadata:
|
|
102
144
|
rubygems_mfa_required: 'true'
|
|
103
|
-
post_install_message:
|
|
104
145
|
rdoc_options: []
|
|
105
146
|
require_paths:
|
|
106
147
|
- lib
|
|
@@ -115,8 +156,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
115
156
|
- !ruby/object:Gem::Version
|
|
116
157
|
version: '0'
|
|
117
158
|
requirements: []
|
|
118
|
-
rubygems_version: 3.
|
|
119
|
-
signing_key:
|
|
159
|
+
rubygems_version: 3.6.9
|
|
120
160
|
specification_version: 4
|
|
121
161
|
summary: Split your RSpec test suite up into several groups and run them in parallel.
|
|
122
162
|
test_files: []
|