knapsack_pro 3.8.0 → 7.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +377 -23
- data/.github/dependabot.yml +11 -0
- data/.github/pull_request_template.md +22 -0
- data/.gitignore +4 -0
- data/CHANGELOG.md +325 -1
- data/Gemfile +9 -0
- data/README.md +3 -10
- data/bin/test +15 -0
- data/knapsack_pro.gemspec +7 -6
- data/lib/knapsack_pro/adapters/base_adapter.rb +17 -2
- data/lib/knapsack_pro/adapters/cucumber_adapter.rb +3 -3
- data/lib/knapsack_pro/adapters/minitest_adapter.rb +2 -0
- data/lib/knapsack_pro/adapters/rspec_adapter.rb +88 -49
- data/lib/knapsack_pro/adapters/spinach_adapter.rb +2 -0
- data/lib/knapsack_pro/adapters/test_unit_adapter.rb +2 -0
- data/lib/knapsack_pro/allocator.rb +2 -0
- data/lib/knapsack_pro/allocator_builder.rb +2 -0
- data/lib/knapsack_pro/base_allocator_builder.rb +8 -25
- data/lib/knapsack_pro/build_distribution_fetcher.rb +2 -0
- data/lib/knapsack_pro/client/api/action.rb +2 -0
- data/lib/knapsack_pro/client/api/v1/base.rb +2 -0
- data/lib/knapsack_pro/client/api/v1/build_distributions.rb +5 -0
- data/lib/knapsack_pro/client/api/v1/build_subsets.rb +2 -0
- data/lib/knapsack_pro/client/api/v1/queues.rb +6 -1
- data/lib/knapsack_pro/client/connection.rb +5 -6
- data/lib/knapsack_pro/config/ci/app_veyor.rb +18 -0
- data/lib/knapsack_pro/config/ci/base.rb +27 -0
- data/lib/knapsack_pro/config/ci/buildkite.rb +18 -0
- data/lib/knapsack_pro/config/ci/circle.rb +18 -0
- data/lib/knapsack_pro/config/ci/cirrus_ci.rb +18 -0
- data/lib/knapsack_pro/config/ci/codefresh.rb +18 -0
- data/lib/knapsack_pro/config/ci/codeship.rb +18 -0
- data/lib/knapsack_pro/config/ci/github_actions.rb +26 -0
- data/lib/knapsack_pro/config/ci/gitlab_ci.rb +20 -1
- data/lib/knapsack_pro/config/ci/heroku.rb +18 -0
- data/lib/knapsack_pro/config/ci/semaphore.rb +16 -0
- data/lib/knapsack_pro/config/ci/semaphore2.rb +19 -0
- data/lib/knapsack_pro/config/ci/travis.rb +18 -0
- data/lib/knapsack_pro/config/env.rb +46 -22
- data/lib/knapsack_pro/config/env_generator.rb +2 -0
- data/lib/knapsack_pro/config/temp_files.rb +8 -4
- data/lib/knapsack_pro/crypto/branch_encryptor.rb +2 -0
- data/lib/knapsack_pro/crypto/decryptor.rb +2 -0
- data/lib/knapsack_pro/crypto/digestor.rb +2 -0
- data/lib/knapsack_pro/crypto/encryptor.rb +2 -0
- data/lib/knapsack_pro/extensions/rspec_extension.rb +137 -0
- data/lib/knapsack_pro/formatters/rspec_json_formatter.rb +2 -0
- data/lib/knapsack_pro/formatters/time_tracker.rb +152 -0
- data/lib/knapsack_pro/formatters/time_tracker_fetcher.rb +20 -0
- data/lib/knapsack_pro/hooks/queue.rb +2 -0
- data/lib/knapsack_pro/logger_wrapper.rb +2 -0
- data/lib/knapsack_pro/mask_string.rb +9 -0
- data/lib/knapsack_pro/presenter.rb +6 -3
- data/lib/knapsack_pro/pure/queue/rspec_pure.rb +92 -0
- data/lib/knapsack_pro/queue_allocator.rb +2 -0
- data/lib/knapsack_pro/queue_allocator_builder.rb +2 -0
- data/lib/knapsack_pro/railtie.rb +2 -0
- data/lib/knapsack_pro/report.rb +15 -9
- data/lib/knapsack_pro/repository_adapter_initiator.rb +2 -0
- data/lib/knapsack_pro/repository_adapters/base_adapter.rb +2 -0
- data/lib/knapsack_pro/repository_adapters/env_adapter.rb +2 -0
- data/lib/knapsack_pro/repository_adapters/git_adapter.rb +50 -0
- data/lib/knapsack_pro/runners/base_runner.rb +2 -0
- data/lib/knapsack_pro/runners/cucumber_runner.rb +2 -0
- data/lib/knapsack_pro/runners/minitest_runner.rb +2 -0
- data/lib/knapsack_pro/runners/queue/base_runner.rb +29 -0
- data/lib/knapsack_pro/runners/queue/cucumber_runner.rb +9 -6
- data/lib/knapsack_pro/runners/queue/minitest_runner.rb +13 -6
- data/lib/knapsack_pro/runners/queue/rspec_runner.rb +128 -135
- data/lib/knapsack_pro/runners/rspec_runner.rb +22 -3
- data/lib/knapsack_pro/runners/spinach_runner.rb +2 -0
- data/lib/knapsack_pro/runners/test_unit_runner.rb +2 -0
- data/lib/knapsack_pro/slow_test_file_determiner.rb +2 -0
- data/lib/knapsack_pro/slow_test_file_finder.rb +2 -0
- data/lib/knapsack_pro/task_loader.rb +2 -0
- data/lib/knapsack_pro/test_case_detectors/rspec_test_example_detector.rb +2 -0
- data/lib/knapsack_pro/test_case_mergers/base_merger.rb +2 -0
- data/lib/knapsack_pro/test_case_mergers/rspec_merger.rb +2 -0
- data/lib/knapsack_pro/test_file_cleaner.rb +2 -0
- data/lib/knapsack_pro/test_file_finder.rb +2 -0
- data/lib/knapsack_pro/test_file_pattern.rb +2 -0
- data/lib/knapsack_pro/test_file_presenter.rb +2 -0
- data/lib/knapsack_pro/test_files_with_test_cases_composer.rb +2 -0
- data/lib/knapsack_pro/test_flat_distributor.rb +2 -0
- data/lib/knapsack_pro/tracker.rb +3 -3
- data/lib/knapsack_pro/urls.rb +4 -0
- data/lib/knapsack_pro/utils.rb +2 -0
- data/lib/knapsack_pro/version.rb +3 -1
- data/lib/knapsack_pro.rb +5 -3
- data/lib/tasks/cucumber.rake +2 -0
- data/lib/tasks/encrypted_branch_names.rake +2 -0
- data/lib/tasks/encrypted_test_file_names.rake +2 -0
- data/lib/tasks/minitest.rake +2 -0
- data/lib/tasks/queue/cucumber.rake +13 -0
- data/lib/tasks/queue/minitest.rake +13 -0
- data/lib/tasks/queue/rspec.rake +13 -0
- data/lib/tasks/rspec.rake +5 -0
- data/lib/tasks/salt.rake +2 -0
- data/lib/tasks/spinach.rake +2 -0
- data/lib/tasks/test_unit.rake +2 -0
- data/spec/integration/api/build_distributions_subset_spec.rb +1 -0
- data/spec/integration/runners/queue/rspec_runner.rb +80 -0
- data/spec/integration/runners/queue/rspec_runner_spec.rb +2232 -0
- data/spec/knapsack_pro/adapters/base_adapter_spec.rb +30 -11
- data/spec/knapsack_pro/adapters/cucumber_adapter_spec.rb +2 -5
- data/spec/knapsack_pro/adapters/rspec_adapter_spec.rb +146 -174
- data/spec/knapsack_pro/base_allocator_builder_spec.rb +22 -48
- data/spec/knapsack_pro/client/api/v1/build_distributions_spec.rb +19 -27
- data/spec/knapsack_pro/client/api/v1/queues_spec.rb +23 -43
- data/spec/knapsack_pro/client/connection_spec.rb +59 -7
- data/spec/knapsack_pro/config/ci/app_veyor_spec.rb +22 -8
- data/spec/knapsack_pro/config/ci/base_spec.rb +1 -0
- data/spec/knapsack_pro/config/ci/buildkite_spec.rb +51 -16
- data/spec/knapsack_pro/config/ci/circle_spec.rb +48 -13
- data/spec/knapsack_pro/config/ci/cirrus_ci_spec.rb +12 -12
- data/spec/knapsack_pro/config/ci/codefresh_spec.rb +21 -6
- data/spec/knapsack_pro/config/ci/codeship_spec.rb +20 -6
- data/spec/knapsack_pro/config/ci/github_actions_spec.rb +37 -10
- data/spec/knapsack_pro/config/ci/gitlab_ci_spec.rb +48 -13
- data/spec/knapsack_pro/config/ci/heroku_spec.rb +12 -12
- data/spec/knapsack_pro/config/ci/semaphore2_spec.rb +11 -11
- data/spec/knapsack_pro/config/ci/semaphore_spec.rb +12 -12
- data/spec/knapsack_pro/config/ci/travis_spec.rb +8 -8
- data/spec/knapsack_pro/config/env_spec.rb +204 -124
- data/spec/knapsack_pro/formatters/time_tracker_specs.rb +424 -0
- data/spec/knapsack_pro/hooks/queue_spec.rb +2 -2
- data/spec/knapsack_pro/presenter_spec.rb +1 -1
- data/spec/knapsack_pro/pure/queue/rspec_pure_spec.rb +224 -0
- data/spec/knapsack_pro/repository_adapters/git_adapter_spec.rb +72 -0
- data/spec/knapsack_pro/runners/queue/cucumber_runner_spec.rb +18 -16
- data/spec/knapsack_pro/runners/queue/minitest_runner_spec.rb +17 -14
- data/spec/knapsack_pro/runners/rspec_runner_spec.rb +40 -23
- data/spec/knapsack_pro/test_case_detectors/rspec_test_example_detector_spec.rb +1 -0
- data/spec/knapsack_pro/tracker_spec.rb +0 -4
- data/spec/knapsack_pro_spec.rb +3 -3
- data/spec/spec_helper.rb +0 -1
- metadata +26 -23
- data/lib/knapsack_pro/config/ci/snap_ci.rb +0 -35
- data/lib/knapsack_pro/config/ci/solano_ci.rb +0 -32
- data/lib/knapsack_pro/extensions/time.rb +0 -7
- data/lib/knapsack_pro/formatters/rspec_queue_profile_formatter_extension.rb +0 -56
- data/lib/knapsack_pro/formatters/rspec_queue_summary_formatter.rb +0 -112
- data/spec/knapsack_pro/config/ci/snap_ci_spec.rb +0 -104
- data/spec/knapsack_pro/config/ci/solano_ci_spec.rb +0 -73
- data/spec/knapsack_pro/extensions/time_spec.rb +0 -5
- data/spec/knapsack_pro/runners/queue/rspec_runner_spec.rb +0 -342
@@ -42,6 +42,18 @@ describe KnapsackPro::Adapters::BaseAdapter do
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
describe '.split_by_test_cases_enabled?' do
|
46
|
+
subject { described_class.split_by_test_cases_enabled? }
|
47
|
+
|
48
|
+
it { expect(subject).to be false }
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '.test_file_cases_for' do
|
52
|
+
subject { described_class.test_file_cases_for([]) }
|
53
|
+
|
54
|
+
it { expect { subject }.to raise_error NotImplementedError }
|
55
|
+
end
|
56
|
+
|
45
57
|
describe '.slow_test_file?' do
|
46
58
|
let(:adapter_class) { double }
|
47
59
|
let(:slow_test_files) do
|
@@ -98,6 +110,7 @@ describe KnapsackPro::Adapters::BaseAdapter do
|
|
98
110
|
|
99
111
|
before do
|
100
112
|
expect(::Kernel).to receive(:at_exit).and_yield
|
113
|
+
allow(File).to receive(:exist?)
|
101
114
|
expect(File).to receive(:exist?).with('.knapsack_pro/KnapsackPro-Adapters-BaseAdapter-bind_method_called_for_node_0.txt').and_return(adapter_bind_method_called_file_exists)
|
102
115
|
end
|
103
116
|
|
@@ -146,7 +159,7 @@ describe KnapsackPro::Adapters::BaseAdapter do
|
|
146
159
|
it do
|
147
160
|
logger = instance_double(Logger)
|
148
161
|
expect(KnapsackPro).to receive(:logger).and_return(logger)
|
149
|
-
expect(logger).to receive(:debug).with('
|
162
|
+
expect(logger).to receive(:debug).with('Regular Mode enabled.')
|
150
163
|
end
|
151
164
|
it { expect(subject).to receive(:bind_time_tracker) }
|
152
165
|
it { expect(subject).to receive(:bind_save_report) }
|
@@ -155,24 +168,22 @@ describe KnapsackPro::Adapters::BaseAdapter do
|
|
155
168
|
context 'when queue recording enabled' do
|
156
169
|
let(:queue_recording_enabled?) { true }
|
157
170
|
|
158
|
-
before do
|
159
|
-
allow(subject).to receive(:bind_before_queue_hook)
|
160
|
-
allow(subject).to receive(:bind_time_tracker)
|
161
|
-
end
|
162
|
-
|
163
|
-
it do
|
171
|
+
it 'calls queue hooks in proper order before binding time tracker' do
|
164
172
|
logger = instance_double(Logger)
|
165
173
|
expect(KnapsackPro).to receive(:logger).and_return(logger)
|
166
|
-
expect(logger).to receive(:debug).with('
|
174
|
+
expect(logger).to receive(:debug).with('Queue Mode enabled.')
|
175
|
+
|
176
|
+
expect(subject).to receive(:bind_before_queue_hook).ordered
|
177
|
+
expect(subject).to receive(:bind_after_queue_hook).ordered
|
178
|
+
expect(subject).to receive(:bind_time_tracker).ordered
|
167
179
|
end
|
168
|
-
it { expect(subject).to receive(:bind_before_queue_hook) }
|
169
|
-
it { expect(subject).to receive(:bind_time_tracker) }
|
170
180
|
end
|
171
181
|
|
172
182
|
context 'when recording disabled' do
|
173
|
-
it { expect(subject).not_to receive(:bind_time_tracker) }
|
174
183
|
it { expect(subject).not_to receive(:bind_save_report) }
|
175
184
|
it { expect(subject).not_to receive(:bind_before_queue_hook) }
|
185
|
+
it { expect(subject).not_to receive(:bind_after_queue_hook) }
|
186
|
+
it { expect(subject).not_to receive(:bind_time_tracker) }
|
176
187
|
end
|
177
188
|
end
|
178
189
|
|
@@ -199,4 +210,12 @@ describe KnapsackPro::Adapters::BaseAdapter do
|
|
199
210
|
}.to raise_error(NotImplementedError)
|
200
211
|
end
|
201
212
|
end
|
213
|
+
|
214
|
+
describe '#bind_after_queue_hook' do
|
215
|
+
it do
|
216
|
+
expect {
|
217
|
+
subject.bind_after_queue_hook
|
218
|
+
}.to raise_error(NotImplementedError)
|
219
|
+
end
|
220
|
+
end
|
202
221
|
end
|
@@ -203,16 +203,13 @@ describe KnapsackPro::Adapters::CucumberAdapter do
|
|
203
203
|
end
|
204
204
|
end
|
205
205
|
|
206
|
-
describe '#
|
206
|
+
describe '#bind_after_queue_hook' do
|
207
207
|
it do
|
208
|
-
expect(subject).to receive(:bind_before_queue_hook)
|
209
|
-
expect(subject).to receive(:bind_time_tracker)
|
210
|
-
|
211
208
|
expect(::Kernel).to receive(:at_exit).and_yield
|
212
209
|
expect(KnapsackPro::Hooks::Queue).to receive(:call_after_subset_queue)
|
213
210
|
expect(KnapsackPro::Report).to receive(:save_subset_queue_to_file)
|
214
211
|
|
215
|
-
subject.
|
212
|
+
subject.bind_after_queue_hook
|
216
213
|
end
|
217
214
|
end
|
218
215
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require_relative '../../../lib/knapsack_pro/formatters/time_tracker'
|
2
|
+
|
1
3
|
describe KnapsackPro::Adapters::RSpecAdapter do
|
2
4
|
it 'backwards compatibility with knapsack gem old rspec adapter name' do
|
3
5
|
expect(KnapsackPro::Adapters::RspecAdapter.new).to be_kind_of(described_class)
|
@@ -8,10 +10,85 @@ describe KnapsackPro::Adapters::RSpecAdapter do
|
|
8
10
|
end
|
9
11
|
|
10
12
|
context do
|
11
|
-
before { expect(::RSpec).to receive(:configure) }
|
13
|
+
before { expect(::RSpec).to receive(:configure).at_least(:once) }
|
12
14
|
it_behaves_like 'adapter'
|
13
15
|
end
|
14
16
|
|
17
|
+
describe '.split_by_test_cases_enabled?' do
|
18
|
+
subject { described_class.split_by_test_cases_enabled? }
|
19
|
+
|
20
|
+
before do
|
21
|
+
expect(KnapsackPro::Config::Env).to receive(:rspec_split_by_test_examples?).and_return(rspec_split_by_test_examples_enabled)
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when the RSpec split by test examples is enabled' do
|
25
|
+
let(:rspec_split_by_test_examples_enabled) { true }
|
26
|
+
|
27
|
+
it { expect(subject).to be true }
|
28
|
+
|
29
|
+
context 'when the RSpec version is < 3.3.0' do
|
30
|
+
before do
|
31
|
+
stub_const('RSpec::Core::Version::STRING', '3.2.0')
|
32
|
+
end
|
33
|
+
|
34
|
+
it do
|
35
|
+
expect { subject }.to raise_error RuntimeError, 'RSpec >= 3.3.0 is required to split test files by test examples. Learn more: https://knapsackpro.com/perma/ruby/split-by-test-examples'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'when the RSpec split by test examples is disabled' do
|
41
|
+
let(:rspec_split_by_test_examples_enabled) { false }
|
42
|
+
|
43
|
+
it { expect(subject).to be false }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '.test_file_cases_for' do
|
48
|
+
let(:slow_test_files) do
|
49
|
+
[
|
50
|
+
'1_spec.rb',
|
51
|
+
'2_spec.rb',
|
52
|
+
'3_spec.rb',
|
53
|
+
'4_spec.rb',
|
54
|
+
'5_spec.rb',
|
55
|
+
]
|
56
|
+
end
|
57
|
+
|
58
|
+
subject { described_class.test_file_cases_for(slow_test_files) }
|
59
|
+
|
60
|
+
before do
|
61
|
+
logger = instance_double(Logger)
|
62
|
+
expect(KnapsackPro).to receive(:logger).and_return(logger)
|
63
|
+
expect(logger).to receive(:info).with("Generating RSpec test examples JSON report for slow test files to prepare it to be split by test examples (by individual test cases). Thanks to that, a single slow test file can be split across parallel CI nodes. Analyzing 5 slow test files.")
|
64
|
+
|
65
|
+
cmd = 'RACK_ENV=test RAILS_ENV=test bundle exec rake knapsack_pro:rspec_test_example_detector'
|
66
|
+
expect(Kernel).to receive(:system).with(cmd).and_return(cmd_result)
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'when the rake task to detect RSpec test examples succeeded' do
|
70
|
+
let(:cmd_result) { true }
|
71
|
+
|
72
|
+
it 'returns test example paths for slow test files' do
|
73
|
+
rspec_test_example_detector = instance_double(KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector)
|
74
|
+
expect(KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector).to receive(:new).and_return(rspec_test_example_detector)
|
75
|
+
|
76
|
+
test_file_example_paths = double
|
77
|
+
expect(rspec_test_example_detector).to receive(:test_file_example_paths).and_return(test_file_example_paths)
|
78
|
+
|
79
|
+
expect(subject).to eq test_file_example_paths
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'when the rake task to detect RSpec test examples failed' do
|
84
|
+
let(:cmd_result) { false }
|
85
|
+
|
86
|
+
it do
|
87
|
+
expect { subject }.to raise_error(RuntimeError, 'Could not generate JSON report for RSpec. Rake task failed when running RACK_ENV=test RAILS_ENV=test bundle exec rake knapsack_pro:rspec_test_example_detector')
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
15
92
|
describe '.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!' do
|
16
93
|
let(:cli_args) { double }
|
17
94
|
|
@@ -162,59 +239,79 @@ describe KnapsackPro::Adapters::RSpecAdapter do
|
|
162
239
|
end
|
163
240
|
end
|
164
241
|
|
165
|
-
describe '.
|
166
|
-
let(:
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
242
|
+
describe '.file_path_for' do
|
243
|
+
let(:current_example) { ::RSpec.describe.example }
|
244
|
+
|
245
|
+
subject { described_class.file_path_for(current_example) }
|
246
|
+
|
247
|
+
context "when id ends in _spec.rb" do
|
248
|
+
it "returns the first part of the id" do
|
249
|
+
allow(current_example).to receive(:id).and_return("./foo_spec.rb[1:1]")
|
250
|
+
|
251
|
+
expect(subject).to eq('./foo_spec.rb')
|
252
|
+
end
|
176
253
|
end
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
254
|
+
|
255
|
+
context "when id does not end in _spec.rb" do
|
256
|
+
it "returns the file_path" do
|
257
|
+
allow(current_example).to receive(:id).and_return("./foo.rb")
|
258
|
+
allow(current_example).to receive(:metadata).and_return(file_path: "./foo_spec.rb")
|
259
|
+
|
260
|
+
expect(subject).to eq('./foo_spec.rb')
|
261
|
+
end
|
181
262
|
end
|
182
263
|
|
183
|
-
|
264
|
+
context "when id and file_path do not end in _spec.rb" do
|
265
|
+
it "returns the example_group's file_path" do
|
266
|
+
allow(current_example).to receive(:id).and_return("./foo.rb")
|
267
|
+
allow(current_example).to receive(:metadata).and_return(
|
268
|
+
file_path: "./foo.rb", example_group: { file_path: "./foo_spec.rb" }
|
269
|
+
)
|
184
270
|
|
185
|
-
|
271
|
+
expect(subject).to eq('./foo_spec.rb')
|
272
|
+
end
|
273
|
+
end
|
186
274
|
|
187
|
-
context
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
275
|
+
context "when id, file_path, and example_group's file_path do not end in _spec.rb" do
|
276
|
+
it "returns the top_level_group's file_path" do
|
277
|
+
allow(current_example).to receive(:id).and_return("./foo.rb")
|
278
|
+
allow(current_example).to receive(:metadata).and_return(
|
279
|
+
file_path: "./foo.rb",
|
280
|
+
example_group: {
|
281
|
+
file_path: "./foo.rb",
|
193
282
|
parent_example_group: {
|
194
|
-
file_path: "
|
283
|
+
file_path: "./foo_spec.rb",
|
195
284
|
}
|
196
285
|
}
|
197
|
-
|
198
|
-
|
199
|
-
before { stub_const("Turnip::VERSION", '1.2.4') }
|
286
|
+
)
|
200
287
|
|
201
|
-
|
288
|
+
expect(subject).to eq('./foo_spec.rb')
|
202
289
|
end
|
290
|
+
end
|
203
291
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
292
|
+
context "when id, file_path, example_group's, and top_level_group's file_path do not end in _spec.rb" do
|
293
|
+
it "returns empty string" do
|
294
|
+
allow(current_example).to receive(:id).and_return("./foo.rb")
|
295
|
+
allow(current_example).to receive(:metadata).and_return(
|
296
|
+
file_path: "./foo.rb",
|
297
|
+
example_group: {
|
298
|
+
file_path: "./foo.rb",
|
209
299
|
parent_example_group: {
|
210
|
-
file_path: "./
|
300
|
+
file_path: "./foo.rb",
|
211
301
|
}
|
212
302
|
}
|
213
|
-
|
303
|
+
)
|
214
304
|
|
215
|
-
|
305
|
+
expect(subject).to eq('')
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
context "when id does not end in .feature (nor _spec.rb)" do
|
310
|
+
it "returns the file_path" do
|
311
|
+
allow(current_example).to receive(:id).and_return("./foo.rb")
|
312
|
+
allow(current_example).to receive(:metadata).and_return(file_path: "./foo.feature")
|
216
313
|
|
217
|
-
|
314
|
+
expect(subject).to eq("./foo.feature")
|
218
315
|
end
|
219
316
|
end
|
220
317
|
end
|
@@ -223,155 +320,37 @@ describe KnapsackPro::Adapters::RSpecAdapter do
|
|
223
320
|
let(:config) { double }
|
224
321
|
|
225
322
|
describe '#bind_time_tracker' do
|
226
|
-
let(:tracker) { instance_double(KnapsackPro::Tracker) }
|
227
|
-
let(:logger) { instance_double(Logger) }
|
228
|
-
let(:global_time) { 'Global time: 01m 05s' }
|
229
|
-
let(:test_path) { 'spec/a_spec.rb' }
|
230
323
|
let(:current_example) { double(metadata: {}) }
|
231
324
|
|
232
325
|
context "when the example's metadata has :focus tag AND RSpec inclusion rule includes :focus" do
|
233
326
|
let(:current_example) { double(metadata: { focus: true }) }
|
327
|
+
let(:test_path) { 'spec/a_spec.rb' }
|
234
328
|
|
235
329
|
it do
|
236
|
-
expect(KnapsackPro::Config::Env).to receive(:rspec_split_by_test_examples?).and_return(false)
|
237
|
-
|
238
|
-
expect(config).to receive(:prepend_before).with(:context).and_yield
|
239
|
-
|
240
|
-
allow(KnapsackPro).to receive(:tracker).and_return(tracker)
|
241
|
-
expect(tracker).to receive(:start_timer).ordered
|
242
|
-
|
243
330
|
expect(config).to receive(:around).with(:each).and_yield(current_example)
|
244
331
|
expect(::RSpec).to receive(:configure).and_yield(config)
|
245
332
|
|
246
|
-
expect(
|
247
|
-
expect(tracker).to receive(:stop_timer).ordered
|
248
|
-
|
249
|
-
expect(described_class).to receive(:test_path).with(current_example).and_return(test_path)
|
250
|
-
|
251
|
-
expect(tracker).to receive(:current_test_path=).with(test_path).ordered
|
333
|
+
expect(described_class).to receive(:file_path_for).with(current_example).and_return(test_path)
|
252
334
|
|
253
335
|
expect(described_class).to receive_message_chain(:rspec_configuration, :filter, :rules, :[]).with(:focus).and_return(true)
|
254
336
|
|
255
337
|
expect {
|
256
338
|
subject.bind_time_tracker
|
257
|
-
}.to raise_error /
|
339
|
+
}.to raise_error /Knapsack Pro found an example tagged with focus in spec\/a_spec\.rb/i
|
258
340
|
end
|
259
341
|
end
|
260
342
|
|
261
|
-
context '
|
262
|
-
before do
|
263
|
-
expect(KnapsackPro::Config::Env).to receive(:rspec_split_by_test_examples?).and_return(false)
|
264
|
-
end
|
265
|
-
|
343
|
+
context 'with no focus' do
|
266
344
|
it 'records time for current test path' do
|
267
|
-
expect(config).to receive(:prepend_before).with(:context).and_yield
|
268
|
-
|
269
|
-
allow(KnapsackPro).to receive(:tracker).and_return(tracker)
|
270
|
-
expect(tracker).to receive(:start_timer).ordered
|
271
|
-
|
272
345
|
expect(config).to receive(:around).with(:each).and_yield(current_example)
|
273
|
-
expect(config).to receive(:append_after).with(:
|
274
|
-
expect(
|
275
|
-
expect(::RSpec).to receive(:configure).and_yield(config)
|
276
|
-
|
277
|
-
expect(tracker).to receive(:current_test_path).ordered.and_return(test_path)
|
278
|
-
expect(tracker).to receive(:stop_timer).ordered
|
279
|
-
|
280
|
-
expect(described_class).to receive(:test_path).with(current_example).and_return(test_path)
|
281
|
-
|
282
|
-
expect(tracker).to receive(:current_test_path=).with(test_path).ordered
|
346
|
+
expect(config).to receive(:append_after).with(:suite)
|
347
|
+
expect(::RSpec).to receive(:configure).at_least(1).and_yield(config)
|
283
348
|
|
284
349
|
expect(current_example).to receive(:run)
|
285
350
|
|
286
|
-
expect(tracker).to receive(:stop_timer).ordered
|
287
|
-
|
288
|
-
expect(KnapsackPro::Presenter).to receive(:global_time).and_return(global_time)
|
289
|
-
expect(KnapsackPro).to receive(:logger).and_return(logger)
|
290
|
-
expect(logger).to receive(:debug).with(global_time)
|
291
|
-
|
292
351
|
subject.bind_time_tracker
|
293
352
|
end
|
294
353
|
end
|
295
|
-
|
296
|
-
context 'when rspec split by test examples is enabled' do
|
297
|
-
let(:test_example_path) { 'spec/a_spec.rb[1:1]' }
|
298
|
-
|
299
|
-
before do
|
300
|
-
expect(KnapsackPro::Config::Env).to receive(:rspec_split_by_test_examples?).and_return(true)
|
301
|
-
end
|
302
|
-
|
303
|
-
context 'when current test_path is a slow test file' do
|
304
|
-
before do
|
305
|
-
expect(described_class).to receive(:slow_test_file?).with(described_class, test_path).and_return(true)
|
306
|
-
end
|
307
|
-
|
308
|
-
it 'records time for example.id' do
|
309
|
-
expect(current_example).to receive(:id).and_return(test_example_path)
|
310
|
-
|
311
|
-
expect(config).to receive(:prepend_before).with(:context).and_yield
|
312
|
-
|
313
|
-
allow(KnapsackPro).to receive(:tracker).and_return(tracker)
|
314
|
-
expect(tracker).to receive(:start_timer).ordered
|
315
|
-
|
316
|
-
expect(config).to receive(:around).with(:each).and_yield(current_example)
|
317
|
-
expect(config).to receive(:append_after).with(:context).and_yield
|
318
|
-
expect(config).to receive(:after).with(:suite).and_yield
|
319
|
-
expect(::RSpec).to receive(:configure).and_yield(config)
|
320
|
-
|
321
|
-
expect(tracker).to receive(:current_test_path).ordered.and_return(test_path)
|
322
|
-
expect(tracker).to receive(:stop_timer).ordered
|
323
|
-
|
324
|
-
expect(described_class).to receive(:test_path).with(current_example).and_return(test_path)
|
325
|
-
|
326
|
-
expect(tracker).to receive(:current_test_path=).with(test_example_path).ordered
|
327
|
-
|
328
|
-
expect(current_example).to receive(:run)
|
329
|
-
|
330
|
-
expect(tracker).to receive(:stop_timer).ordered
|
331
|
-
|
332
|
-
expect(KnapsackPro::Presenter).to receive(:global_time).and_return(global_time)
|
333
|
-
expect(KnapsackPro).to receive(:logger).and_return(logger)
|
334
|
-
expect(logger).to receive(:debug).with(global_time)
|
335
|
-
|
336
|
-
subject.bind_time_tracker
|
337
|
-
end
|
338
|
-
end
|
339
|
-
|
340
|
-
context 'when current test_path is not a slow test file' do
|
341
|
-
before do
|
342
|
-
expect(described_class).to receive(:slow_test_file?).with(described_class, test_path).and_return(false)
|
343
|
-
end
|
344
|
-
|
345
|
-
it 'records time for current test path' do
|
346
|
-
expect(config).to receive(:prepend_before).with(:context).and_yield
|
347
|
-
|
348
|
-
allow(KnapsackPro).to receive(:tracker).and_return(tracker)
|
349
|
-
expect(tracker).to receive(:start_timer).ordered
|
350
|
-
|
351
|
-
expect(config).to receive(:around).with(:each).and_yield(current_example)
|
352
|
-
expect(config).to receive(:append_after).with(:context).and_yield
|
353
|
-
expect(config).to receive(:after).with(:suite).and_yield
|
354
|
-
expect(::RSpec).to receive(:configure).and_yield(config)
|
355
|
-
|
356
|
-
expect(described_class).to receive(:test_path).with(current_example).and_return(test_path)
|
357
|
-
|
358
|
-
expect(tracker).to receive(:current_test_path).ordered.and_return(test_path)
|
359
|
-
expect(tracker).to receive(:stop_timer).ordered
|
360
|
-
|
361
|
-
expect(tracker).to receive(:current_test_path=).with(test_path).ordered
|
362
|
-
|
363
|
-
expect(current_example).to receive(:run)
|
364
|
-
|
365
|
-
expect(tracker).to receive(:stop_timer).ordered
|
366
|
-
|
367
|
-
expect(KnapsackPro::Presenter).to receive(:global_time).and_return(global_time)
|
368
|
-
expect(KnapsackPro).to receive(:logger).and_return(logger)
|
369
|
-
expect(logger).to receive(:debug).with(global_time)
|
370
|
-
|
371
|
-
subject.bind_time_tracker
|
372
|
-
end
|
373
|
-
end
|
374
|
-
end
|
375
354
|
end
|
376
355
|
|
377
356
|
describe '#bind_save_report' do
|
@@ -379,21 +358,14 @@ describe KnapsackPro::Adapters::RSpecAdapter do
|
|
379
358
|
expect(config).to receive(:after).with(:suite).and_yield
|
380
359
|
expect(::RSpec).to receive(:configure).and_yield(config)
|
381
360
|
|
382
|
-
|
361
|
+
time_tracker = instance_double(KnapsackPro::Formatters::TimeTracker)
|
362
|
+
times = [{ path: "foo_spec.rb", time_execution: 1.0 }]
|
363
|
+
expect(time_tracker).to receive(:batch).and_return(times)
|
364
|
+
expect(KnapsackPro::Formatters::TimeTrackerFetcher).to receive(:call).and_return(time_tracker)
|
365
|
+
expect(KnapsackPro::Report).to receive(:save).with(times)
|
383
366
|
|
384
367
|
subject.bind_save_report
|
385
368
|
end
|
386
369
|
end
|
387
|
-
|
388
|
-
describe '#bind_before_queue_hook' do
|
389
|
-
it do
|
390
|
-
expect(config).to receive(:before).with(:suite).and_yield
|
391
|
-
expect(::RSpec).to receive(:configure).and_yield(config)
|
392
|
-
|
393
|
-
expect(KnapsackPro::Hooks::Queue).to receive(:call_before_queue)
|
394
|
-
|
395
|
-
subject.bind_before_queue_hook
|
396
|
-
end
|
397
|
-
end
|
398
370
|
end
|
399
371
|
end
|
@@ -117,8 +117,8 @@ describe KnapsackPro::BaseAllocatorBuilder do
|
|
117
117
|
describe '#fast_and_slow_test_files_to_run' do
|
118
118
|
subject { allocator_builder.fast_and_slow_test_files_to_run }
|
119
119
|
|
120
|
-
context 'when
|
121
|
-
it do
|
120
|
+
context 'when split by test cases disabled' do
|
121
|
+
it 'returns test files to run based on test files on the disk' do
|
122
122
|
test_file_pattern = double
|
123
123
|
expect(KnapsackPro::TestFilePattern).to receive(:call).with(adapter_class).and_return(test_file_pattern)
|
124
124
|
|
@@ -129,70 +129,44 @@ describe KnapsackPro::BaseAllocatorBuilder do
|
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
132
|
-
context 'when
|
133
|
-
let(:adapter_class) { KnapsackPro::Adapters::RSpecAdapter }
|
132
|
+
context 'when split by test cases enabled' do
|
134
133
|
let(:test_files_to_run) { double }
|
135
|
-
let(:cmd) { 'RACK_ENV=test RAILS_ENV=test bundle exec rake knapsack_pro:rspec_test_example_detector' }
|
136
134
|
|
137
|
-
before
|
138
|
-
expect(
|
135
|
+
before do
|
136
|
+
expect(adapter_class).to receive(:split_by_test_cases_enabled?).and_return(true)
|
139
137
|
|
140
138
|
test_file_pattern = double
|
141
139
|
expect(KnapsackPro::TestFilePattern).to receive(:call).with(adapter_class).and_return(test_file_pattern)
|
142
140
|
|
143
141
|
expect(KnapsackPro::TestFileFinder).to receive(:call).with(test_file_pattern).and_return(test_files_to_run)
|
144
|
-
end
|
145
142
|
|
146
|
-
|
147
|
-
before do
|
148
|
-
stub_const('RSpec::Core::Version::STRING', '3.2.0')
|
149
|
-
end
|
150
|
-
|
151
|
-
it do
|
152
|
-
expect { subject }.to raise_error RuntimeError, 'RSpec >= 3.3.0 is required to split test files by test examples. Learn more: https://knapsackpro.com/perma/ruby/split-by-test-examples'
|
153
|
-
end
|
143
|
+
expect(allocator_builder).to receive(:get_slow_test_files).and_return(slow_test_files)
|
154
144
|
end
|
155
145
|
|
156
|
-
context 'when
|
157
|
-
let(:slow_test_files)
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
before do
|
164
|
-
expect(allocator_builder).to receive(:get_slow_test_files).and_return(slow_test_files)
|
165
|
-
|
166
|
-
expect(KnapsackPro).to receive(:logger).and_return(logger)
|
167
|
-
|
168
|
-
expect(Kernel).to receive(:system).with(cmd).and_return(cmd_result)
|
169
|
-
|
170
|
-
rspec_test_example_detector = instance_double(KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector)
|
171
|
-
expect(KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector).to receive(:new).and_return(rspec_test_example_detector)
|
172
|
-
expect(rspec_test_example_detector).to receive(:test_file_example_paths).and_return(test_file_example_paths)
|
173
|
-
|
174
|
-
expect(KnapsackPro::TestFilesWithTestCasesComposer).to receive(:call).with(test_files_to_run, slow_test_files, test_file_example_paths).and_return(test_files_with_test_cases)
|
146
|
+
context 'when slow test files are detected' do
|
147
|
+
let(:slow_test_files) do
|
148
|
+
[
|
149
|
+
'1_spec.rb',
|
150
|
+
'2_spec.rb',
|
151
|
+
]
|
175
152
|
end
|
176
153
|
|
177
|
-
it do
|
178
|
-
|
154
|
+
it 'returns test files with test cases' do
|
155
|
+
test_file_cases = double
|
156
|
+
expect(adapter_class).to receive(:test_file_cases_for).with(slow_test_files).and_return(test_file_cases)
|
157
|
+
|
158
|
+
test_files_with_test_cases = double
|
159
|
+
expect(KnapsackPro::TestFilesWithTestCasesComposer).to receive(:call).with(test_files_to_run, slow_test_files, test_file_cases).and_return(test_files_with_test_cases)
|
179
160
|
|
180
161
|
expect(subject).to eq test_files_with_test_cases
|
181
162
|
end
|
182
163
|
end
|
183
164
|
|
184
|
-
context 'when
|
185
|
-
let(:slow_test_files) {
|
186
|
-
let(:cmd_result) { false }
|
187
|
-
|
188
|
-
before do
|
189
|
-
expect(allocator_builder).to receive(:get_slow_test_files).and_return(slow_test_files)
|
190
|
-
|
191
|
-
expect(Kernel).to receive(:system).with(cmd).and_return(cmd_result)
|
192
|
-
end
|
165
|
+
context 'when slow test files are not detected' do
|
166
|
+
let(:slow_test_files) { [] }
|
193
167
|
|
194
|
-
it do
|
195
|
-
expect
|
168
|
+
it 'returns test files without test cases' do
|
169
|
+
expect(subject).to eq test_files_to_run
|
196
170
|
end
|
197
171
|
end
|
198
172
|
end
|
@@ -6,7 +6,9 @@ describe KnapsackPro::Client::API::V1::BuildDistributions do
|
|
6
6
|
let(:node_total) { double }
|
7
7
|
let(:node_index) { double }
|
8
8
|
let(:ci_build_id) { double }
|
9
|
+
let(:masked_user_seat) { double }
|
9
10
|
let(:test_files) { double }
|
11
|
+
let(:cache_read_attempt) { [false, true].sample }
|
10
12
|
|
11
13
|
subject do
|
12
14
|
described_class.subset(
|
@@ -22,6 +24,7 @@ describe KnapsackPro::Client::API::V1::BuildDistributions do
|
|
22
24
|
before do
|
23
25
|
expect(KnapsackPro::Config::Env).to receive(:fixed_test_suite_split).and_return(fixed_test_suite_split)
|
24
26
|
expect(KnapsackPro::Config::Env).to receive(:ci_node_build_id).and_return(ci_build_id)
|
27
|
+
expect(KnapsackPro::Config::Env).to receive(:masked_user_seat).and_return(masked_user_seat)
|
25
28
|
end
|
26
29
|
|
27
30
|
context 'when cache_read_attempt=true' do
|
@@ -29,19 +32,9 @@ describe KnapsackPro::Client::API::V1::BuildDistributions do
|
|
29
32
|
|
30
33
|
it 'does not send test_files among other params' do
|
31
34
|
action = double
|
32
|
-
expect(KnapsackPro::Client::API::Action).to receive(:new).with(
|
33
|
-
|
34
|
-
|
35
|
-
request_hash: {
|
36
|
-
fixed_test_suite_split: fixed_test_suite_split,
|
37
|
-
cache_read_attempt: cache_read_attempt,
|
38
|
-
commit_hash: commit_hash,
|
39
|
-
branch: branch,
|
40
|
-
node_total: node_total,
|
41
|
-
node_index: node_index,
|
42
|
-
ci_build_id: ci_build_id,
|
43
|
-
}
|
44
|
-
}).and_return(action)
|
35
|
+
expect(KnapsackPro::Client::API::Action).to receive(:new).with(
|
36
|
+
hash_including(request_hash: hash_excluding(:test_files))
|
37
|
+
).and_return(action)
|
45
38
|
expect(subject).to eq action
|
46
39
|
end
|
47
40
|
end
|
@@ -51,23 +44,22 @@ describe KnapsackPro::Client::API::V1::BuildDistributions do
|
|
51
44
|
|
52
45
|
it 'sends test_files among other params' do
|
53
46
|
action = double
|
54
|
-
expect(KnapsackPro::Client::API::Action).to receive(:new).with(
|
55
|
-
|
56
|
-
|
57
|
-
request_hash: {
|
58
|
-
fixed_test_suite_split: fixed_test_suite_split,
|
59
|
-
cache_read_attempt: cache_read_attempt,
|
60
|
-
commit_hash: commit_hash,
|
61
|
-
branch: branch,
|
62
|
-
node_total: node_total,
|
63
|
-
node_index: node_index,
|
64
|
-
ci_build_id: ci_build_id,
|
65
|
-
test_files: test_files
|
66
|
-
}
|
67
|
-
}).and_return(action)
|
47
|
+
expect(KnapsackPro::Client::API::Action).to receive(:new).with(
|
48
|
+
hash_including(request_hash: hash_including(test_files: test_files))
|
49
|
+
).and_return(action)
|
68
50
|
expect(subject).to eq action
|
69
51
|
end
|
70
52
|
end
|
53
|
+
|
54
|
+
it "sends authors" do
|
55
|
+
action = double
|
56
|
+
|
57
|
+
expect(KnapsackPro::Client::API::Action).to receive(:new).with(
|
58
|
+
hash_including(request_hash: hash_including(:build_author, :commit_authors))
|
59
|
+
).and_return(action)
|
60
|
+
|
61
|
+
expect(subject).to eq action
|
62
|
+
end
|
71
63
|
end
|
72
64
|
|
73
65
|
describe '.last' do
|