Skip to content
Closed
5 changes: 5 additions & 0 deletions lib/knapsack/allocator_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ def allocator
Knapsack::Allocator.new({
report: Knapsack.report.open,
test_file_pattern: test_file_pattern,
test_file_list_source_file: test_file_list_source_file,
ci_node_total: Knapsack::Config::Env.ci_node_total,
ci_node_index: Knapsack::Config::Env.ci_node_index
})
Expand All @@ -33,5 +34,9 @@ def report_path
def test_file_pattern
Knapsack::Config::Env.test_file_pattern || @adapter_class::TEST_DIR_PATTERN
end

def test_file_list_source_file
Knapsack::Config::Env.test_file_list_source_file
end
end
end
4 changes: 4 additions & 0 deletions lib/knapsack/config/env.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ def test_file_pattern
ENV['KNAPSACK_TEST_FILE_PATTERN']
end

def test_file_list_source_file
ENV['KNAPSACK_TEST_FILE_LIST_SOURCE_FILE']
end

def test_dir
ENV['KNAPSACK_TEST_DIR']
end
Expand Down
22 changes: 20 additions & 2 deletions lib/knapsack/distributors/base_distributor.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
module Knapsack
module Distributors
class BaseDistributor
attr_reader :report, :node_tests, :test_file_pattern
attr_reader :report, :node_tests, :test_file_pattern, :test_file_list_source_file

def initialize(args={})
@report = args[:report] || raise('Missing report')
@test_file_pattern = args[:test_file_pattern] || raise('Missing test_file_pattern')
@test_file_list_source_file = args[:test_file_list_source_file]
@ci_node_total = args[:ci_node_total] || raise('Missing ci_node_total')
@ci_node_index = args[:ci_node_index] || raise('Missing ci_node_index')

Expand Down Expand Up @@ -37,7 +38,24 @@ def assign_test_files_to_node
end

def all_tests
@all_tests ||= Dir.glob(test_file_pattern).uniq.sort
@all_tests ||= test_files
end

# NOTE: Use the test_file_pattern by default
# support specifying a list_file to use similar to KnapsackPro
# ref: KnapsackPro/knapsack_pro-ruby/commit/7d7b8db8be524f2f30d7d80d3a6444dad9f85b1b
def test_files
default = Dir.glob(test_file_pattern).uniq.sort

return default if test_file_list_source_file.nil?

test_file_list = File.read(test_file_list_source_file)
.split(/\n/)
.uniq
.sort

return default if test_file_list.empty?
return test_file_list
end

protected
Expand Down
4 changes: 4 additions & 0 deletions lib/knapsack/runners/cucumber_runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ def self.run(args)
Knapsack.logger.info allocator.leftover_node_tests
Knapsack.logger.info

# NOTE: return if there are no specs to execute for this node.
# This can occurr if test_file_list_source_file is used with less then CI_NODES specs
return Knapsack.logger.warn('No specs to execute') if allocator.stringify_node_tests.empty?

cmd = %Q[bundle exec cucumber #{args} --require #{allocator.test_dir} -- #{allocator.stringify_node_tests}]

system(cmd)
Expand Down
4 changes: 4 additions & 0 deletions lib/knapsack/runners/minitest_runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ def self.run(args)
Knapsack.logger.info allocator.leftover_node_tests
Knapsack.logger.info

# NOTE: return if there are no specs to execute for this node.
# This can occurr if test_file_list_source_file is used with less then CI_NODES specs
return Knapsack.logger.warn('No specs to execute') if allocator.stringify_node_tests.empty?

task_name = 'knapsack:minitest_run'

if Rake::Task.task_defined?(task_name)
Expand Down
11 changes: 11 additions & 0 deletions lib/knapsack/runners/rspec_runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,23 @@ def self.run(args)
allocator = Knapsack::AllocatorBuilder.new(Knapsack::Adapters::RSpecAdapter).allocator

Knapsack.logger.info
puts ''
Knapsack.logger.info 'Report specs:'
puts 'Report specs:'
Knapsack.logger.info allocator.report_node_tests
puts allocator.report_node_tests
Knapsack.logger.info
puts ''
Knapsack.logger.info 'Leftover specs:'
puts 'Leftover specs:'
Knapsack.logger.info allocator.leftover_node_tests
puts allocator.leftover_node_tests
Knapsack.logger.info
puts

# NOTE: return if there are no specs to execute for this node.
# This can occurr if test_file_list_source_file is used with less then CI_NODES specs
return Knapsack.logger.warn('No specs to execute') if allocator.stringify_node_tests.empty?

cmd = %Q[bundle exec rspec #{args} --default-path #{allocator.test_dir} -- #{allocator.stringify_node_tests}]

Expand Down
4 changes: 4 additions & 0 deletions lib/knapsack/runners/spinach_runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ def self.run(args)
Knapsack.logger.info allocator.leftover_node_tests
Knapsack.logger.info

# NOTE: return if there are no specs to execute for this node.
# This can occurr if test_file_list_source_file is used with less then CI_NODES specs
return Knapsack.logger.warn('No specs to execute') if allocator.stringify_node_tests.empty?

cmd = %Q[bundle exec spinach #{args} --features_path #{allocator.test_dir} -- #{allocator.stringify_node_tests}]

system(cmd)
Expand Down
5 changes: 5 additions & 0 deletions spec/fixtures/test_file_list_source_file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
./spec/test1_spec.rb
spec/test2_spec.rb[1]
./spec/test3_spec.rb[1:2:3:4]
./spec/test4_spec.rb:4
./spec/test4_spec.rb:5
21 changes: 21 additions & 0 deletions spec/knapsack/allocator_builder_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@
let(:env_ci_node_index) { double }
let(:env_report_path) { nil }
let(:env_test_file_pattern) { nil }
let(:env_test_file_list_source_file) { nil }

describe '#allocator' do
subject { allocator_builder.allocator }

before do
expect(Knapsack::Config::Env).to receive(:report_path).and_return(env_report_path)
expect(Knapsack::Config::Env).to receive(:test_file_pattern).and_return(env_test_file_pattern)
expect(Knapsack::Config::Env).to receive(:test_file_list_source_file).and_return(env_test_file_list_source_file)
expect(Knapsack::Config::Env).to receive(:ci_node_total).and_return(env_ci_node_total)
expect(Knapsack::Config::Env).to receive(:ci_node_index).and_return(env_ci_node_index)

Expand All @@ -36,6 +38,7 @@
{
report: report,
test_file_pattern: adapter_test_file_pattern,
test_file_list_source_file: env_test_file_list_source_file,
ci_node_total: env_ci_node_total,
ci_node_index: env_ci_node_index
}
Expand All @@ -51,6 +54,7 @@
{
report: report,
test_file_pattern: adapter_test_file_pattern,
test_file_list_source_file: env_test_file_list_source_file,
ci_node_total: env_ci_node_total,
ci_node_index: env_ci_node_index
}
Expand All @@ -66,6 +70,23 @@
{
report: report,
test_file_pattern: env_test_file_pattern,
test_file_list_source_file: env_test_file_list_source_file,
ci_node_total: env_ci_node_total,
ci_node_index: env_ci_node_index
}
end

it { should eql allocator }
end

context 'when ENV test_file_list_source_file has value' do
let(:env_test_file_list_source_file) { 'knapsack_custom_file_list.txt' }
let(:report_config) { { report_path: adapter_report_path } }
let(:allocator_args) do
{
report: report,
test_file_pattern: adapter_test_file_pattern,
test_file_list_source_file: env_test_file_list_source_file,
ci_node_total: env_ci_node_total,
ci_node_index: env_ci_node_index
}
Expand Down
14 changes: 14 additions & 0 deletions spec/knapsack/config/env_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,20 @@
end
end

describe '.test_file_list_source_file' do
subject { described_class.test_file_list_source_file }

context 'when ENV exists' do
let(:test_file_list_source_file) { 'spec/fixtures/test_file_list_source_file.txt' }
before { stub_const("ENV", { 'KNAPSACK_TEST_FILE_LIST_SOURCE_FILE' => test_file_list_source_file }) }
it { should eql test_file_list_source_file }
end

context "when ENV doesn't exist" do
it { should be_nil }
end
end

describe '.test_dir' do
subject { described_class.test_dir }

Expand Down
17 changes: 17 additions & 0 deletions spec/knapsack/distributors/leftover_distributor_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
}
end
let(:test_file_pattern) { 'spec/**{,/*/**}/*_spec.rb' }
let(:test_file_list_source_file) { nil }
let(:default_args) do
{
report: report,
test_file_pattern: test_file_pattern,
test_file_list_source_file: test_file_list_source_file,
ci_node_total: '1',
ci_node_index: '0'
}
Expand Down Expand Up @@ -52,6 +54,21 @@
end
end

context 'when given test_file_list_source_file' do
context 'spec/fixtures/test_file_list_source_file.txt' do
let(:test_file_list_source_file) { 'spec/fixtures/test_file_list_source_file.txt' }
it { should_not be_empty }
it { should include './spec/test3_spec.rb[1:2:3:4]' }
it { should include './spec/test4_spec.rb:5' }
it { should_not include 'spec/knapsack/tracker_spec.rb' }
it { should_not include 'spec/knapsack/adapters/rspec_adapter_spec.rb' }

it 'has no duplicated test file paths' do
expect(subject.size).to eq subject.uniq.size
end
end
end

context 'when fake test_file_pattern' do
let(:test_file_pattern) { 'fake_pattern' }
it { should be_empty }
Expand Down