semaphore_test_boosters 1.8.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|