semaphore_test_boosters 1.8.0 → 2.0.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/exe/cucumber_booster +1 -8
- data/exe/ex_unit_booster +5 -0
- data/exe/go_test_booster +5 -0
- data/exe/minitest_booster +5 -0
- data/exe/rspec_booster +1 -8
- data/lib/test_boosters.rb +10 -6
- data/lib/test_boosters/boosters/base.rb +65 -0
- data/lib/test_boosters/boosters/cucumber.rb +37 -0
- data/lib/test_boosters/boosters/ex_unit.rb +17 -0
- data/lib/test_boosters/boosters/go_test.rb +17 -0
- data/lib/test_boosters/boosters/minitest.rb +21 -0
- data/lib/test_boosters/boosters/rspec.rb +41 -0
- data/lib/test_boosters/files/distributor.rb +45 -0
- data/lib/test_boosters/files/leftover_files.rb +42 -0
- data/lib/test_boosters/files/split_configuration.rb +68 -0
- data/lib/test_boosters/insights_uploader.rb +2 -0
- data/lib/test_boosters/job.rb +40 -0
- data/lib/test_boosters/project_info.rb +6 -8
- data/lib/test_boosters/shell.rb +4 -2
- data/lib/test_boosters/version.rb +1 -1
- data/test_boosters.gemspec +0 -1
- metadata +18 -22
- data/lib/test_boosters/cucumber/booster.rb +0 -59
- data/lib/test_boosters/cucumber/job.rb +0 -71
- data/lib/test_boosters/leftover_files.rb +0 -40
- data/lib/test_boosters/rspec/booster.rb +0 -59
- data/lib/test_boosters/rspec/job.rb +0 -64
- data/lib/test_boosters/split_configuration.rb +0 -66
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 818fb423cc0dca748176dcc676e1827e76215f86
|
4
|
+
data.tar.gz: 5829ff0d66e9613f0f9705617604dd7a447670eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 104ea0a5bb98c8479fdc8a8d6a1d73b0b5c4f71d851582b33db7176e855bd1f800c508adf3a37438ac0d3b1ad614c182de4bb0e77267fa85d399f9c2ac911637
|
7
|
+
data.tar.gz: 9029ac6ab8388faa94cb18af5487611e60f9d8c2fd4d4af9b6763e3cd45c4cb2cba704f3596995ce3c0f7702e52cd5b6398b4ea7cddf3f6fe61271cc013e35eb
|
data/exe/cucumber_booster
CHANGED
@@ -2,11 +2,4 @@
|
|
2
2
|
|
3
3
|
require "test_boosters"
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
job_index = cli_options[:job_index] - 1
|
8
|
-
job_count = cli_options[:job_count]
|
9
|
-
|
10
|
-
cucumber_booster = TestBoosters::Cucumber::Booster.new(job_index, job_count)
|
11
|
-
|
12
|
-
exit(cucumber_booster.run)
|
5
|
+
exit(TestBoosters::Boosters::Cucumber.new.run)
|
data/exe/ex_unit_booster
ADDED
data/exe/go_test_booster
ADDED
data/exe/rspec_booster
CHANGED
@@ -2,11 +2,4 @@
|
|
2
2
|
|
3
3
|
require "test_boosters"
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
job_index = cli_options[:job_index] - 1
|
8
|
-
job_count = cli_options[:job_count]
|
9
|
-
|
10
|
-
rspec_booster = TestBoosters::Rspec::Booster.new(job_index, job_count)
|
11
|
-
|
12
|
-
exit(rspec_booster.run)
|
5
|
+
exit(TestBoosters::Boosters::Rspec.new.run)
|
data/lib/test_boosters.rb
CHANGED
@@ -6,17 +6,21 @@ require "cucumber_booster_config"
|
|
6
6
|
module TestBoosters
|
7
7
|
require "test_boosters/version"
|
8
8
|
|
9
|
-
require "test_boosters/split_configuration"
|
10
9
|
require "test_boosters/cli_parser"
|
11
10
|
require "test_boosters/logger"
|
12
11
|
require "test_boosters/shell"
|
13
|
-
require "test_boosters/leftover_files"
|
14
12
|
require "test_boosters/insights_uploader"
|
15
13
|
require "test_boosters/project_info"
|
14
|
+
require "test_boosters/job"
|
16
15
|
|
17
|
-
require "test_boosters/
|
18
|
-
require "test_boosters/
|
16
|
+
require "test_boosters/files/distributor"
|
17
|
+
require "test_boosters/files/leftover_files"
|
18
|
+
require "test_boosters/files/split_configuration"
|
19
19
|
|
20
|
-
require "test_boosters/
|
21
|
-
require "test_boosters/
|
20
|
+
require "test_boosters/boosters/base"
|
21
|
+
require "test_boosters/boosters/rspec"
|
22
|
+
require "test_boosters/boosters/cucumber"
|
23
|
+
require "test_boosters/boosters/go_test"
|
24
|
+
require "test_boosters/boosters/ex_unit"
|
25
|
+
require "test_boosters/boosters/minitest"
|
22
26
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module TestBoosters
|
2
|
+
module Boosters
|
3
|
+
class Base
|
4
|
+
|
5
|
+
def initialize(file_pattern, split_configuration_path, command)
|
6
|
+
@command = command
|
7
|
+
@file_pattern = file_pattern
|
8
|
+
@split_configuration_path = split_configuration_path
|
9
|
+
end
|
10
|
+
|
11
|
+
# :reek:TooManyStatements
|
12
|
+
def run
|
13
|
+
display_header
|
14
|
+
|
15
|
+
before_job # execute some activities when the before the job starts
|
16
|
+
|
17
|
+
distribution.display_info
|
18
|
+
|
19
|
+
known, leftover = distribution.files_for(job_index)
|
20
|
+
|
21
|
+
exit_status = TestBoosters::Job.run(@command, known, leftover)
|
22
|
+
|
23
|
+
after_job # execute some activities when the job finishes
|
24
|
+
|
25
|
+
exit_status
|
26
|
+
end
|
27
|
+
|
28
|
+
def before_job
|
29
|
+
# Do nothing
|
30
|
+
end
|
31
|
+
|
32
|
+
def after_job
|
33
|
+
# Do nothing
|
34
|
+
end
|
35
|
+
|
36
|
+
def display_header
|
37
|
+
version = "Test Booster v#{TestBoosters::VERSION}"
|
38
|
+
job_info = "Job #{job_index + 1} out of #{job_count}"
|
39
|
+
|
40
|
+
TestBoosters::Shell.display_title("#{version} - #{job_info}")
|
41
|
+
end
|
42
|
+
|
43
|
+
def distribution
|
44
|
+
@distribution ||= TestBoosters::Files::Distributor.new(@split_configuration_path,
|
45
|
+
@file_pattern,
|
46
|
+
job_count)
|
47
|
+
end
|
48
|
+
|
49
|
+
def job_index
|
50
|
+
@job_index ||= cli_options[:job_index] - 1
|
51
|
+
end
|
52
|
+
|
53
|
+
def job_count
|
54
|
+
@job_count ||= cli_options[:job_count]
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def cli_options
|
60
|
+
@cli_options ||= TestBoosters::CliParser.parse
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module TestBoosters
|
2
|
+
module Boosters
|
3
|
+
class Cucumber < Base
|
4
|
+
|
5
|
+
FILE_PATTERN = "features/**/*.feature".freeze
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
super(FILE_PATTERN, split_configuration_path, "bundle exec cucumber")
|
9
|
+
end
|
10
|
+
|
11
|
+
def before_job
|
12
|
+
CucumberBoosterConfig::Injection.new(Dir.pwd, report_path).run
|
13
|
+
end
|
14
|
+
|
15
|
+
def after_job
|
16
|
+
TestBoosters::InsightsUploader.upload("cucumber", report_path)
|
17
|
+
end
|
18
|
+
|
19
|
+
def display_header
|
20
|
+
super
|
21
|
+
|
22
|
+
TestBoosters::ProjectInfo.display_ruby_version
|
23
|
+
TestBoosters::ProjectInfo.display_bundler_version
|
24
|
+
TestBoosters::ProjectInfo.display_cucumber_version
|
25
|
+
end
|
26
|
+
|
27
|
+
def report_path
|
28
|
+
@report_path ||= ENV["REPORT_PATH"] || "#{ENV["HOME"]}/cucumber_report.json"
|
29
|
+
end
|
30
|
+
|
31
|
+
def split_configuration_path
|
32
|
+
ENV["CUCUMBER_SPLIT_CONFIGURATION_PATH"] || "#{ENV["HOME"]}/cucumber_split_configuration.json"
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module TestBoosters
|
2
|
+
module Boosters
|
3
|
+
class ExUnit < Base
|
4
|
+
|
5
|
+
FILE_PATTERN = "test/**/*_test.exs".freeze
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
super(FILE_PATTERN, split_configuration_path, "mix test")
|
9
|
+
end
|
10
|
+
|
11
|
+
def split_configuration_path
|
12
|
+
ENV["EX_UNIT_SPLIT_CONFIGURATION_PATH"] || "#{ENV["HOME"]}/ex_unit_split_configuration.json"
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module TestBoosters
|
2
|
+
module Boosters
|
3
|
+
class GoTest < Base
|
4
|
+
|
5
|
+
FILE_PATTERN = "**/*/*_test.go".freeze
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
super(FILE_PATTERN, split_configuration_path, "go test")
|
9
|
+
end
|
10
|
+
|
11
|
+
def split_configuration_path
|
12
|
+
ENV["GO_TEST_SPLIT_CONFIGURATION_PATH"] || "#{ENV["HOME"]}/go_test_split_configuration.json"
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module TestBoosters
|
2
|
+
module Boosters
|
3
|
+
class Minitest < Base
|
4
|
+
|
5
|
+
FILE_PATTERN = "test/**/*_test.rb".freeze
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
super(FILE_PATTERN, split_configuration_path, command)
|
9
|
+
end
|
10
|
+
|
11
|
+
def command
|
12
|
+
"ruby -e 'ARGV.each { |f| require \"./\#{f}\" }'"
|
13
|
+
end
|
14
|
+
|
15
|
+
def split_configuration_path
|
16
|
+
ENV["MINITEST_SPLIT_CONFIGURATION_PATH"] || "#{ENV["HOME"]}/minitest_split_configuration.json"
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module TestBoosters
|
2
|
+
module Boosters
|
3
|
+
class Rspec < Base
|
4
|
+
|
5
|
+
FILE_PATTERN = "spec/**/*_spec.rb".freeze
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
super(FILE_PATTERN, split_configuration_path, command)
|
9
|
+
end
|
10
|
+
|
11
|
+
def display_header
|
12
|
+
super
|
13
|
+
|
14
|
+
TestBoosters::ProjectInfo.display_ruby_version
|
15
|
+
TestBoosters::ProjectInfo.display_bundler_version
|
16
|
+
TestBoosters::ProjectInfo.display_rspec_version
|
17
|
+
end
|
18
|
+
|
19
|
+
def after_job
|
20
|
+
TestBoosters::InsightsUploader.upload("rspec", report_path)
|
21
|
+
end
|
22
|
+
|
23
|
+
def command
|
24
|
+
@command ||= "bundle exec rspec #{rspec_options}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def rspec_options
|
28
|
+
@rspec_options ||= "#{ENV["TB_RSPEC_OPTIONS"]} --format documentation --format json --out #{report_path}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def report_path
|
32
|
+
@report_path ||= ENV["REPORT_PATH"] || "#{ENV["HOME"]}/rspec_report.json"
|
33
|
+
end
|
34
|
+
|
35
|
+
def split_configuration_path
|
36
|
+
ENV["RSPEC_SPLIT_CONFIGURATION_PATH"] || "#{ENV["HOME"]}/rspec_split_configuration.json"
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module TestBoosters
|
2
|
+
module Files
|
3
|
+
|
4
|
+
#
|
5
|
+
# Distributes test files based on split configuration, file pattern, and their file size
|
6
|
+
#
|
7
|
+
class Distributor
|
8
|
+
|
9
|
+
def initialize(split_configuration_path, file_pattern, job_count)
|
10
|
+
@split_configuration_path = split_configuration_path
|
11
|
+
@file_pattern = file_pattern
|
12
|
+
@job_count = job_count
|
13
|
+
end
|
14
|
+
|
15
|
+
def display_info
|
16
|
+
puts "Split configuration present: #{split_configuration.present? ? "yes" : "no"}"
|
17
|
+
puts "Split configuration valid: #{split_configuration.valid? ? "yes" : "no"}"
|
18
|
+
puts "Split configuration file count: #{split_configuration.all_files.size}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def files_for(job_index)
|
22
|
+
known = all_files & split_configuration.files_for_job(job_index)
|
23
|
+
leftover = leftover_files.select(:index => job_index, :total => @job_count)
|
24
|
+
|
25
|
+
[known, leftover]
|
26
|
+
end
|
27
|
+
|
28
|
+
def all_files
|
29
|
+
@all_files ||= Dir[@file_pattern].sort
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def leftover_files
|
35
|
+
@leftover_files ||= TestBoosters::Files::LeftoverFiles.new(all_files - split_configuration.all_files)
|
36
|
+
end
|
37
|
+
|
38
|
+
def split_configuration
|
39
|
+
@split_configuration ||= TestBoosters::Files::SplitConfiguration.new(@split_configuration_path)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module TestBoosters
|
2
|
+
module Files
|
3
|
+
class LeftoverFiles
|
4
|
+
|
5
|
+
attr_reader :files
|
6
|
+
|
7
|
+
def initialize(files)
|
8
|
+
@files = files
|
9
|
+
end
|
10
|
+
|
11
|
+
def select(options = {})
|
12
|
+
index = options.fetch(:index)
|
13
|
+
total = options.fetch(:total)
|
14
|
+
|
15
|
+
file_distribution(total)[index]
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def file_distribution(job_count)
|
21
|
+
# create N empty boxes
|
22
|
+
jobs = Array.new(job_count) { [] }
|
23
|
+
|
24
|
+
# distribute files in Round Robin fashion
|
25
|
+
sorted_files_by_file_size.each.with_index do |file, index|
|
26
|
+
jobs[index % job_count] << file
|
27
|
+
end
|
28
|
+
|
29
|
+
jobs
|
30
|
+
end
|
31
|
+
|
32
|
+
def sorted_files_by_file_size
|
33
|
+
@sorted_files_by_file_size ||= existing_files.sort_by { |file| -File.size(file) }
|
34
|
+
end
|
35
|
+
|
36
|
+
def existing_files
|
37
|
+
@existing_files ||= @files.select { |file| File.file?(file) }
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module TestBoosters
|
2
|
+
module Files
|
3
|
+
class SplitConfiguration
|
4
|
+
|
5
|
+
Job = Struct.new(:files)
|
6
|
+
|
7
|
+
def initialize(path)
|
8
|
+
@path = path
|
9
|
+
@valid = true
|
10
|
+
end
|
11
|
+
|
12
|
+
def present?
|
13
|
+
File.exist?(@path)
|
14
|
+
end
|
15
|
+
|
16
|
+
def valid?
|
17
|
+
jobs # try to load data into memory
|
18
|
+
|
19
|
+
@valid
|
20
|
+
end
|
21
|
+
|
22
|
+
def all_files
|
23
|
+
@all_files ||= jobs.map(&:files).flatten.sort
|
24
|
+
end
|
25
|
+
|
26
|
+
def files_for_job(job_index)
|
27
|
+
job = jobs[job_index]
|
28
|
+
|
29
|
+
job ? job.files : []
|
30
|
+
end
|
31
|
+
|
32
|
+
def jobs
|
33
|
+
@jobs ||= present? ? load_data : []
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# :reek:TooManyStatements
|
39
|
+
def load_data
|
40
|
+
@valid = false
|
41
|
+
|
42
|
+
content = JSON.parse(File.read(@path)).map do |raw_job|
|
43
|
+
files = raw_job.fetch("files").sort
|
44
|
+
|
45
|
+
TestBoosters::Files::SplitConfiguration::Job.new(files)
|
46
|
+
end
|
47
|
+
|
48
|
+
@valid = true
|
49
|
+
|
50
|
+
content
|
51
|
+
rescue TypeError, KeyError => ex
|
52
|
+
log_error("Split Configuration has invalid structure", ex)
|
53
|
+
|
54
|
+
[]
|
55
|
+
rescue JSON::ParserError => ex
|
56
|
+
log_error("Split Configuration is not parsable", ex)
|
57
|
+
|
58
|
+
[]
|
59
|
+
end
|
60
|
+
|
61
|
+
def log_error(message, exception)
|
62
|
+
TestBoosters::Logger.error(message)
|
63
|
+
TestBoosters::Logger.error(exception.inspect)
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module TestBoosters
|
2
|
+
class Job
|
3
|
+
|
4
|
+
def self.run(command, known_files, leftover_files)
|
5
|
+
new(command, known_files, leftover_files).run
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(command, known_files, leftover_files)
|
9
|
+
@command = command
|
10
|
+
@known_files = known_files
|
11
|
+
@leftover_files = leftover_files
|
12
|
+
end
|
13
|
+
|
14
|
+
def display_header
|
15
|
+
puts
|
16
|
+
TestBoosters::Shell.display_files("Known files for this job", @known_files)
|
17
|
+
TestBoosters::Shell.display_files("Leftover files for this job", @leftover_files)
|
18
|
+
|
19
|
+
puts "=" * 80
|
20
|
+
puts ""
|
21
|
+
end
|
22
|
+
|
23
|
+
def files
|
24
|
+
@all_files ||= @known_files + @leftover_files
|
25
|
+
end
|
26
|
+
|
27
|
+
def run
|
28
|
+
display_header
|
29
|
+
|
30
|
+
if files.empty?
|
31
|
+
puts("No files to run in this job!")
|
32
|
+
|
33
|
+
return 0
|
34
|
+
end
|
35
|
+
|
36
|
+
TestBoosters::Shell.execute("#{@command} #{files.join(" ")}")
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -3,33 +3,31 @@ module TestBoosters
|
|
3
3
|
module_function
|
4
4
|
|
5
5
|
def display_ruby_version
|
6
|
-
version =
|
6
|
+
version = evaluate("ruby --version").gsub("ruby ", "")
|
7
7
|
|
8
8
|
puts "Ruby Version: #{version}"
|
9
9
|
end
|
10
10
|
|
11
11
|
def display_bundler_version
|
12
|
-
version =
|
12
|
+
version = evaluate("bundle --version").gsub("Bundler version ", "")
|
13
13
|
|
14
14
|
puts "Bundler Version: #{version}"
|
15
15
|
end
|
16
16
|
|
17
17
|
def display_rspec_version
|
18
|
-
version =
|
18
|
+
version = evaluate("(bundle list | grep -q '* rspec') && bundle exec rspec --version || echo 'not found'")
|
19
19
|
|
20
20
|
puts "RSpec Version: #{version}"
|
21
21
|
end
|
22
22
|
|
23
23
|
def display_cucumber_version
|
24
|
-
version =
|
24
|
+
version = evaluate("(bundle list | grep -q '* cucumber') && bundle exec cucumber --version || echo 'not found'")
|
25
25
|
|
26
26
|
puts "Cucumber Version: #{version}"
|
27
27
|
end
|
28
28
|
|
29
|
-
def
|
30
|
-
|
31
|
-
puts "Split configuration valid: #{split_configuration.valid? ? "yes" : "no"}"
|
32
|
-
puts "Split configuration file count: #{split_configuration.all_files.size}"
|
29
|
+
def evaluate(command)
|
30
|
+
Bundler.with_clean_env { `#{command}` }
|
33
31
|
end
|
34
32
|
|
35
33
|
end
|
data/lib/test_boosters/shell.rb
CHANGED
@@ -8,7 +8,9 @@ module TestBoosters
|
|
8
8
|
|
9
9
|
puts command unless options[:silent] == true
|
10
10
|
|
11
|
-
|
11
|
+
Bundler.with_clean_env do
|
12
|
+
system(command)
|
13
|
+
end
|
12
14
|
|
13
15
|
exit_status = $?.exitstatus
|
14
16
|
|
@@ -19,7 +21,7 @@ module TestBoosters
|
|
19
21
|
|
20
22
|
def display_title(title)
|
21
23
|
puts
|
22
|
-
puts "
|
24
|
+
puts "=== #{title} ===="
|
23
25
|
puts
|
24
26
|
end
|
25
27
|
|
data/test_boosters.gemspec
CHANGED
@@ -24,7 +24,6 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_development_dependency "rake", "~> 10.0"
|
25
25
|
spec.add_development_dependency "rspec", "~> 3.5"
|
26
26
|
spec.add_development_dependency "activesupport", "~> 4.0"
|
27
|
-
spec.add_development_dependency "cucumber-rails", "~> 1.4.3"
|
28
27
|
|
29
28
|
spec.add_development_dependency "rubocop", "~> 0.47.1"
|
30
29
|
spec.add_development_dependency "rubocop-rspec", "~> 1.13.0"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: semaphore_test_boosters
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Developers at Rendered Text
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: semaphore_cucumber_booster_config
|
@@ -66,20 +66,6 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '4.0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: cucumber-rails
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: 1.4.3
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: 1.4.3
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
70
|
name: rubocop
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -141,6 +127,9 @@ email:
|
|
141
127
|
- devops@renderedtext.com
|
142
128
|
executables:
|
143
129
|
- cucumber_booster
|
130
|
+
- ex_unit_booster
|
131
|
+
- go_test_booster
|
132
|
+
- minitest_booster
|
144
133
|
- rspec_booster
|
145
134
|
extensions: []
|
146
135
|
extra_rdoc_files: []
|
@@ -156,19 +145,26 @@ files:
|
|
156
145
|
- bin/setup
|
157
146
|
- config.reek
|
158
147
|
- exe/cucumber_booster
|
148
|
+
- exe/ex_unit_booster
|
149
|
+
- exe/go_test_booster
|
150
|
+
- exe/minitest_booster
|
159
151
|
- exe/rspec_booster
|
160
152
|
- lib/test_boosters.rb
|
153
|
+
- lib/test_boosters/boosters/base.rb
|
154
|
+
- lib/test_boosters/boosters/cucumber.rb
|
155
|
+
- lib/test_boosters/boosters/ex_unit.rb
|
156
|
+
- lib/test_boosters/boosters/go_test.rb
|
157
|
+
- lib/test_boosters/boosters/minitest.rb
|
158
|
+
- lib/test_boosters/boosters/rspec.rb
|
161
159
|
- lib/test_boosters/cli_parser.rb
|
162
|
-
- lib/test_boosters/
|
163
|
-
- lib/test_boosters/
|
160
|
+
- lib/test_boosters/files/distributor.rb
|
161
|
+
- lib/test_boosters/files/leftover_files.rb
|
162
|
+
- lib/test_boosters/files/split_configuration.rb
|
164
163
|
- lib/test_boosters/insights_uploader.rb
|
165
|
-
- lib/test_boosters/
|
164
|
+
- lib/test_boosters/job.rb
|
166
165
|
- lib/test_boosters/logger.rb
|
167
166
|
- lib/test_boosters/project_info.rb
|
168
|
-
- lib/test_boosters/rspec/booster.rb
|
169
|
-
- lib/test_boosters/rspec/job.rb
|
170
167
|
- lib/test_boosters/shell.rb
|
171
|
-
- lib/test_boosters/split_configuration.rb
|
172
168
|
- lib/test_boosters/version.rb
|
173
169
|
- test_boosters.gemspec
|
174
170
|
homepage: https://github.com/renderedtext/test-boosters
|
@@ -1,59 +0,0 @@
|
|
1
|
-
module TestBoosters
|
2
|
-
module Cucumber
|
3
|
-
class Booster
|
4
|
-
|
5
|
-
attr_reader :job_index
|
6
|
-
attr_reader :job_count
|
7
|
-
|
8
|
-
def initialize(job_index, job_count)
|
9
|
-
@job_index = job_index
|
10
|
-
@job_count = job_count
|
11
|
-
end
|
12
|
-
|
13
|
-
def run
|
14
|
-
TestBoosters::Shell.display_title("Cucumber Booster v#{TestBoosters::VERSION}")
|
15
|
-
display_system_info
|
16
|
-
|
17
|
-
jobs[@job_index].run
|
18
|
-
end
|
19
|
-
|
20
|
-
def display_system_info
|
21
|
-
TestBoosters::ProjectInfo.display_ruby_version
|
22
|
-
TestBoosters::ProjectInfo.display_bundler_version
|
23
|
-
TestBoosters::ProjectInfo.display_cucumber_version
|
24
|
-
TestBoosters::ProjectInfo.display_split_configuration_info(split_configuration)
|
25
|
-
puts
|
26
|
-
end
|
27
|
-
|
28
|
-
def jobs
|
29
|
-
@jobs ||= Array.new(job_count) do |job_index|
|
30
|
-
known = all_specs & split_configuration.files_for_job(job_index)
|
31
|
-
leftover = leftover_specs.select(:index => job_index, :total => job_count)
|
32
|
-
|
33
|
-
TestBoosters::Cucumber::Job.new(known, leftover)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def all_specs
|
38
|
-
@all_specs ||= Dir["#{specs_path}/**/*.feature"].sort
|
39
|
-
end
|
40
|
-
|
41
|
-
def leftover_specs
|
42
|
-
@leftover_specs ||= TestBoosters::LeftoverFiles.new(all_specs - split_configuration.all_files)
|
43
|
-
end
|
44
|
-
|
45
|
-
def split_configuration
|
46
|
-
@split_configuration ||= TestBoosters::SplitConfiguration.new(split_configuration_path)
|
47
|
-
end
|
48
|
-
|
49
|
-
def specs_path
|
50
|
-
@specs_path ||= ENV["SPEC_PATH"] || "features"
|
51
|
-
end
|
52
|
-
|
53
|
-
def split_configuration_path
|
54
|
-
ENV["CUCUMBER_SPLIT_CONFIGURATION_PATH"] || "#{ENV["HOME"]}/cucumber_split_configuration.json"
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
@@ -1,71 +0,0 @@
|
|
1
|
-
module TestBoosters
|
2
|
-
module Cucumber
|
3
|
-
class Job
|
4
|
-
|
5
|
-
attr_reader :files_from_split_configuration
|
6
|
-
attr_reader :leftover_files
|
7
|
-
|
8
|
-
def initialize(files_from_split_configuration, leftover_files)
|
9
|
-
@files_from_split_configuration = files_from_split_configuration
|
10
|
-
@leftover_files = leftover_files
|
11
|
-
end
|
12
|
-
|
13
|
-
# :reek:TooManyStatements { max_statements: 10 }
|
14
|
-
def run
|
15
|
-
if all_files.empty?
|
16
|
-
puts("No files to run in this job!")
|
17
|
-
|
18
|
-
return 0
|
19
|
-
end
|
20
|
-
|
21
|
-
run_cucumber_config
|
22
|
-
|
23
|
-
display_job_info
|
24
|
-
|
25
|
-
exit_status = run_cucumber
|
26
|
-
|
27
|
-
upload_report
|
28
|
-
|
29
|
-
exit_status
|
30
|
-
end
|
31
|
-
|
32
|
-
def display_job_info
|
33
|
-
TestBoosters::Shell.display_files(
|
34
|
-
"Known specs for this job",
|
35
|
-
files_from_split_configuration)
|
36
|
-
|
37
|
-
TestBoosters::Shell.display_files(
|
38
|
-
"Leftover specs for this job",
|
39
|
-
leftover_files)
|
40
|
-
end
|
41
|
-
|
42
|
-
def run_cucumber_config
|
43
|
-
CucumberBoosterConfig::Injection.new(Dir.pwd, report_path).run
|
44
|
-
puts "-------------------------------------------------------"
|
45
|
-
puts
|
46
|
-
end
|
47
|
-
|
48
|
-
def run_cucumber
|
49
|
-
TestBoosters::Shell.display_title("Running Cucumber")
|
50
|
-
TestBoosters::Shell.execute(cucumber_command)
|
51
|
-
end
|
52
|
-
|
53
|
-
def upload_report
|
54
|
-
TestBoosters::InsightsUploader.upload("cucumber", report_path)
|
55
|
-
end
|
56
|
-
|
57
|
-
def all_files
|
58
|
-
@all_files ||= files_from_split_configuration + leftover_files
|
59
|
-
end
|
60
|
-
|
61
|
-
def cucumber_command
|
62
|
-
"bundle exec cucumber #{all_files.join(" ")}"
|
63
|
-
end
|
64
|
-
|
65
|
-
def report_path
|
66
|
-
@report_path ||= ENV["REPORT_PATH"] || "#{ENV["HOME"]}/cucumber_report.json"
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
module TestBoosters
|
2
|
-
class LeftoverFiles
|
3
|
-
|
4
|
-
attr_reader :files
|
5
|
-
|
6
|
-
def initialize(files)
|
7
|
-
@files = files
|
8
|
-
end
|
9
|
-
|
10
|
-
def select(options = {})
|
11
|
-
index = options.fetch(:index)
|
12
|
-
total = options.fetch(:total)
|
13
|
-
|
14
|
-
file_distribution(total)[index]
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def file_distribution(job_count)
|
20
|
-
# create N empty boxes
|
21
|
-
jobs = Array.new(job_count) { [] }
|
22
|
-
|
23
|
-
# distribute files in Round Robin fashion
|
24
|
-
sorted_files_by_file_size.each.with_index do |file, index|
|
25
|
-
jobs[index % job_count] << file
|
26
|
-
end
|
27
|
-
|
28
|
-
jobs
|
29
|
-
end
|
30
|
-
|
31
|
-
def sorted_files_by_file_size
|
32
|
-
@sorted_files_by_file_size ||= existing_files.sort_by { |file| -File.size(file) }
|
33
|
-
end
|
34
|
-
|
35
|
-
def existing_files
|
36
|
-
@existing_files ||= @files.select { |file| File.file?(file) }
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
40
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
module TestBoosters
|
2
|
-
module Rspec
|
3
|
-
class Booster
|
4
|
-
|
5
|
-
attr_reader :job_index
|
6
|
-
attr_reader :job_count
|
7
|
-
|
8
|
-
def initialize(job_index, job_count)
|
9
|
-
@job_index = job_index
|
10
|
-
@job_count = job_count
|
11
|
-
end
|
12
|
-
|
13
|
-
def run
|
14
|
-
TestBoosters::Shell.display_title("RSpec Booster v#{TestBoosters::VERSION}")
|
15
|
-
display_system_info
|
16
|
-
|
17
|
-
jobs[@job_index].run
|
18
|
-
end
|
19
|
-
|
20
|
-
def display_system_info
|
21
|
-
TestBoosters::ProjectInfo.display_ruby_version
|
22
|
-
TestBoosters::ProjectInfo.display_bundler_version
|
23
|
-
TestBoosters::ProjectInfo.display_rspec_version
|
24
|
-
TestBoosters::ProjectInfo.display_split_configuration_info(split_configuration)
|
25
|
-
puts
|
26
|
-
end
|
27
|
-
|
28
|
-
def jobs
|
29
|
-
@jobs ||= Array.new(job_count) do |job_index|
|
30
|
-
known = all_specs & split_configuration.files_for_job(job_index)
|
31
|
-
leftover = leftover_specs.select(:index => job_index, :total => job_count)
|
32
|
-
|
33
|
-
TestBoosters::Rspec::Job.new(known, leftover)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def all_specs
|
38
|
-
@all_specs ||= Dir["#{specs_path}/**/*_spec.rb"].sort
|
39
|
-
end
|
40
|
-
|
41
|
-
def leftover_specs
|
42
|
-
@leftover_specs ||= TestBoosters::LeftoverFiles.new(all_specs - split_configuration.all_files)
|
43
|
-
end
|
44
|
-
|
45
|
-
def split_configuration
|
46
|
-
@split_configuration ||= TestBoosters::SplitConfiguration.new(split_configuration_path)
|
47
|
-
end
|
48
|
-
|
49
|
-
def specs_path
|
50
|
-
@specs_path ||= ENV["SPEC_PATH"] || "spec"
|
51
|
-
end
|
52
|
-
|
53
|
-
def split_configuration_path
|
54
|
-
ENV["RSPEC_SPLIT_CONFIGURATION_PATH"] || "#{ENV["HOME"]}/rspec_split_configuration.json"
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
module TestBoosters
|
2
|
-
module Rspec
|
3
|
-
class Job
|
4
|
-
|
5
|
-
attr_reader :files_from_split_configuration
|
6
|
-
attr_reader :leftover_files
|
7
|
-
|
8
|
-
def initialize(files_from_split_configuration, leftover_files)
|
9
|
-
@files_from_split_configuration = files_from_split_configuration
|
10
|
-
@leftover_files = leftover_files
|
11
|
-
end
|
12
|
-
|
13
|
-
# :reek:TooManyStatements { max_statements: 10 }
|
14
|
-
def run
|
15
|
-
if all_files.empty?
|
16
|
-
puts("No files to run in this job!")
|
17
|
-
|
18
|
-
return 0
|
19
|
-
end
|
20
|
-
|
21
|
-
display_job_info
|
22
|
-
|
23
|
-
exit_status = run_rspec
|
24
|
-
|
25
|
-
upload_report
|
26
|
-
|
27
|
-
exit_status
|
28
|
-
end
|
29
|
-
|
30
|
-
def display_job_info
|
31
|
-
TestBoosters::Shell.display_files("Known specs for this job", files_from_split_configuration)
|
32
|
-
TestBoosters::Shell.display_files("Leftover specs for this job", leftover_files)
|
33
|
-
|
34
|
-
puts "RSpec options: #{rspec_options}"
|
35
|
-
end
|
36
|
-
|
37
|
-
def run_rspec
|
38
|
-
TestBoosters::Shell.display_title("Running RSpec")
|
39
|
-
TestBoosters::Shell.execute(rspec_command)
|
40
|
-
end
|
41
|
-
|
42
|
-
def upload_report
|
43
|
-
TestBoosters::InsightsUploader.upload("rspec", report_path)
|
44
|
-
end
|
45
|
-
|
46
|
-
def all_files
|
47
|
-
@all_files ||= files_from_split_configuration + leftover_files
|
48
|
-
end
|
49
|
-
|
50
|
-
def rspec_options
|
51
|
-
"#{ENV["TB_RSPEC_OPTIONS"]} --format documentation --format json --out #{report_path}"
|
52
|
-
end
|
53
|
-
|
54
|
-
def rspec_command
|
55
|
-
"bundle exec rspec #{rspec_options} #{all_files.join(" ")}"
|
56
|
-
end
|
57
|
-
|
58
|
-
def report_path
|
59
|
-
@report_path ||= ENV["REPORT_PATH"] || "#{ENV["HOME"]}/rspec_report.json"
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
module TestBoosters
|
2
|
-
class SplitConfiguration
|
3
|
-
|
4
|
-
Job = Struct.new(:files)
|
5
|
-
|
6
|
-
def initialize(path)
|
7
|
-
@path = path
|
8
|
-
@valid = true
|
9
|
-
end
|
10
|
-
|
11
|
-
def present?
|
12
|
-
File.exist?(@path)
|
13
|
-
end
|
14
|
-
|
15
|
-
def valid?
|
16
|
-
jobs # try to load data into memory
|
17
|
-
|
18
|
-
@valid
|
19
|
-
end
|
20
|
-
|
21
|
-
def all_files
|
22
|
-
@all_files ||= jobs.map(&:files).flatten.sort
|
23
|
-
end
|
24
|
-
|
25
|
-
def files_for_job(job_index)
|
26
|
-
job = jobs[job_index]
|
27
|
-
|
28
|
-
job ? job.files : []
|
29
|
-
end
|
30
|
-
|
31
|
-
def jobs
|
32
|
-
@jobs ||= present? ? load_data : []
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
# :reek:TooManyStatements
|
38
|
-
def load_data
|
39
|
-
@valid = false
|
40
|
-
|
41
|
-
content = JSON.parse(File.read(@path)).map do |raw_job|
|
42
|
-
files = raw_job.fetch("files").sort
|
43
|
-
|
44
|
-
TestBoosters::SplitConfiguration::Job.new(files)
|
45
|
-
end
|
46
|
-
|
47
|
-
@valid = true
|
48
|
-
|
49
|
-
content
|
50
|
-
rescue TypeError, KeyError => ex
|
51
|
-
log_error("Split Configuration has invalid structure", ex)
|
52
|
-
|
53
|
-
[]
|
54
|
-
rescue JSON::ParserError => ex
|
55
|
-
log_error("Split Configuration is not parsable", ex)
|
56
|
-
|
57
|
-
[]
|
58
|
-
end
|
59
|
-
|
60
|
-
def log_error(message, exception)
|
61
|
-
TestBoosters::Logger.error(message)
|
62
|
-
TestBoosters::Logger.error(exception.inspect)
|
63
|
-
end
|
64
|
-
|
65
|
-
end
|
66
|
-
end
|