blob: b1ddc91e831e3048e3a96b87759149ea41771e55 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
# frozen_string_literal: true
require 'knapsack'
# A custom parallel rspec runner based on Knapsack runner
# which takes in additional option for a file containing
# list of test files.
#
# When executing RSpec in CI, the list of tests allocated by Knapsack
# will be compared with the test files listed in the file.
#
# Only the test files allocated by Knapsack and listed in the file
# would be executed in the CI node.
#
# Reference:
# https://github.com/ArturT/knapsack/blob/v1.20.0/lib/knapsack/runners/rspec_runner.rb
module Tooling
class ParallelRSpecRunner
def self.run(rspec_args: nil, filter_tests_file: nil)
new(rspec_args: rspec_args, filter_tests_file: filter_tests_file).run
end
def initialize(allocator: knapsack_allocator, filter_tests_file: nil, rspec_args: nil)
@allocator = allocator
@filter_tests_file = filter_tests_file
@rspec_args = rspec_args&.split(' ') || []
end
def run
Knapsack.logger.info
Knapsack.logger.info 'Knapsack node specs:'
Knapsack.logger.info node_tests
Knapsack.logger.info
Knapsack.logger.info 'Filter specs:'
Knapsack.logger.info filter_tests
Knapsack.logger.info
Knapsack.logger.info 'Running specs:'
Knapsack.logger.info tests_to_run
Knapsack.logger.info
if tests_to_run.empty?
Knapsack.logger.info 'No tests to run on this node, exiting.'
return
end
Knapsack.logger.info "Running command: #{rspec_command.join(' ')}"
exec(*rspec_command)
end
private
attr_reader :allocator, :filter_tests_file, :rspec_args
def rspec_command
%w[bundle exec rspec].tap do |cmd|
cmd.push(*rspec_args)
cmd.push('--default-path', allocator.test_dir)
cmd.push('--')
cmd.push(*tests_to_run)
end
end
def tests_to_run
if filter_tests.empty?
Knapsack.logger.info 'Running all node tests without filter'
return node_tests
end
@tests_to_run ||= node_tests & filter_tests
end
def node_tests
allocator.node_tests
end
def filter_tests
@filter_tests ||=
filter_tests_file ? tests_from_file(filter_tests_file) : []
end
def tests_from_file(filter_tests_file)
return [] unless File.exist?(filter_tests_file)
File.read(filter_tests_file).split(' ')
end
def knapsack_allocator
Knapsack::AllocatorBuilder.new(Knapsack::Adapters::RSpecAdapter).allocator
end
end
end
|