knapsack_pro 6.0.4 → 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 +80 -19
- data/.github/pull_request_template.md +22 -0
- data/.gitignore +4 -0
- data/CHANGELOG.md +87 -0
- data/Gemfile +9 -0
- data/README.md +0 -4
- data/knapsack_pro.gemspec +2 -1
- data/lib/knapsack_pro/adapters/base_adapter.rb +7 -2
- data/lib/knapsack_pro/adapters/cucumber_adapter.rb +1 -3
- data/lib/knapsack_pro/adapters/rspec_adapter.rb +16 -9
- data/lib/knapsack_pro/config/env.rb +1 -9
- data/lib/knapsack_pro/extensions/rspec_extension.rb +137 -0
- data/lib/knapsack_pro/formatters/time_tracker.rb +10 -26
- data/lib/knapsack_pro/formatters/time_tracker_fetcher.rb +6 -0
- data/lib/knapsack_pro/presenter.rb +1 -1
- data/lib/knapsack_pro/pure/queue/rspec_pure.rb +92 -0
- data/lib/knapsack_pro/runners/queue/base_runner.rb +6 -1
- data/lib/knapsack_pro/runners/queue/cucumber_runner.rb +6 -6
- data/lib/knapsack_pro/runners/queue/minitest_runner.rb +6 -6
- data/lib/knapsack_pro/runners/queue/rspec_runner.rb +124 -173
- data/lib/knapsack_pro/urls.rb +2 -0
- data/lib/knapsack_pro/version.rb +1 -1
- data/lib/knapsack_pro.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 +17 -11
- data/spec/knapsack_pro/adapters/cucumber_adapter_spec.rb +2 -5
- data/spec/knapsack_pro/adapters/rspec_adapter_spec.rb +2 -24
- data/spec/knapsack_pro/config/env_spec.rb +1 -35
- data/spec/knapsack_pro/formatters/time_tracker_specs.rb +8 -37
- 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/runners/queue/cucumber_runner_spec.rb +16 -16
- data/spec/knapsack_pro/runners/queue/minitest_runner_spec.rb +14 -14
- data/spec/knapsack_pro_spec.rb +3 -3
- metadata +17 -12
- data/lib/knapsack_pro/formatters/rspec_queue_profile_formatter_extension.rb +0 -58
- data/lib/knapsack_pro/formatters/rspec_queue_summary_formatter.rb +0 -145
- data/spec/knapsack_pro/runners/queue/rspec_runner_spec.rb +0 -536
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f27ac674f611af638b9d0ea3dd1d3441a9e680e70296738ff5b93d5d18f9741
|
4
|
+
data.tar.gz: 79bdc380a1c882178b4a3cde626de7e2db1d30ae64ae1a301f023a5ff5d71623
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75bf722c575fce515b8a1a79f7e05ad5ed8ce6f69c05f4ff7cff8fdd570e5eb3e170cbf83765c66b2d1a187a5c076235637188ef9e7bd9d3d703fa37d1bf989c
|
7
|
+
data.tar.gz: 1a355724b69bd0d62b23dd32b6e995dbdd882d0fcb0299d5cddb42c3b4c0635a588839c7194cfb2af83504d91ba4db192a68cc393a8380713450b44971c682bf
|
data/.circleci/config.yml
CHANGED
@@ -37,7 +37,8 @@ commands:
|
|
37
37
|
fi
|
38
38
|
- restore_cache:
|
39
39
|
keys:
|
40
|
-
- v1-bundler-rails-{{ checksum "Gemfile.lock" }}-<< parameters.ruby >>
|
40
|
+
- v1-bundler-rails-{{ checksum "Gemfile.lock" }}-ruby-<< parameters.ruby >>-rspec-<< parameters.rspec >>
|
41
|
+
- v1-bundler-rails-{{ checksum "Gemfile.lock" }}-ruby-<< parameters.ruby >>-
|
41
42
|
- v1-bundler-rails-{{ checksum "Gemfile.lock" }}-
|
42
43
|
- v1-bundler-rails-
|
43
44
|
- run:
|
@@ -48,14 +49,15 @@ commands:
|
|
48
49
|
- save_cache:
|
49
50
|
paths:
|
50
51
|
- << parameters.path >>/vendor/bundle
|
51
|
-
key: v1-bundler-rails-{{ checksum "Gemfile.lock" }}-<< parameters.ruby >>
|
52
|
+
key: v1-bundler-rails-{{ checksum "Gemfile.lock" }}-ruby-<< parameters.ruby >>-rspec-<< parameters.rspec >>
|
52
53
|
|
53
54
|
jobs:
|
54
55
|
unit:
|
55
56
|
parallelism: 1
|
56
57
|
working_directory: ~/knapsack_pro-ruby
|
58
|
+
resource_class: small
|
57
59
|
docker:
|
58
|
-
- image: cimg/ruby:3.
|
60
|
+
- image: cimg/ruby:3.3
|
59
61
|
steps:
|
60
62
|
- setup_knapsack_pro_ruby
|
61
63
|
- run: gem install rubocop
|
@@ -63,9 +65,51 @@ jobs:
|
|
63
65
|
- run: bundle exec rspec spec
|
64
66
|
- run: bundle exec ruby spec/knapsack_pro/formatters/time_tracker_specs.rb
|
65
67
|
|
66
|
-
integration-
|
68
|
+
integration-rspec:
|
69
|
+
parallelism: 1
|
70
|
+
working_directory: ~/knapsack_pro-ruby
|
71
|
+
resource_class: small
|
72
|
+
parameters:
|
73
|
+
ruby:
|
74
|
+
type: string
|
75
|
+
rspec:
|
76
|
+
type: string
|
77
|
+
docker:
|
78
|
+
- image: cimg/ruby:<< parameters.ruby >>
|
79
|
+
steps:
|
80
|
+
- checkout
|
81
|
+
- run:
|
82
|
+
command: |
|
83
|
+
if [[ "<< parameters.rspec >>" != "" ]]; then
|
84
|
+
sed -i 's/.*gem.*rspec-core.*/gem "rspec-core", "<< parameters.rspec >>"/g' ./Gemfile
|
85
|
+
echo "Updated RSpec version in Gemfile"
|
86
|
+
fi
|
87
|
+
- restore_cache:
|
88
|
+
keys:
|
89
|
+
- v1-bundler-gem-{{ checksum "knapsack_pro.gemspec" }}-ruby-<< parameters.ruby >>-rspec-<< parameters.rspec >>
|
90
|
+
- v1-bundler-gem-{{ checksum "knapsack_pro.gemspec" }}-ruby-<< parameters.ruby >>-
|
91
|
+
- v1-bundler-gem-{{ checksum "knapsack_pro.gemspec" }}-
|
92
|
+
- v1-bundler-gem-
|
93
|
+
- run:
|
94
|
+
command: |
|
95
|
+
bundle config set --local path './vendor/bundle'
|
96
|
+
bundle install --jobs=4 --retry=3
|
97
|
+
- save_cache:
|
98
|
+
paths:
|
99
|
+
- ./vendor/bundle
|
100
|
+
key: v1-bundler-gem-{{ checksum "knapsack_pro.gemspec" }}-ruby-<< parameters.ruby >>-rspec-<< parameters.rspec >>
|
101
|
+
- run:
|
102
|
+
command: |
|
103
|
+
ruby --version
|
104
|
+
bundle exec rspec --version
|
105
|
+
RSPEC=$(bundle exec rspec --version | grep rspec-core | head -n1 | cut -d " " -f5)
|
106
|
+
[ $RSPEC != << parameters.rspec >> ] && exit 1 || echo "Correct version of RSpec installed: $RSPEC"
|
107
|
+
- run: bundle exec rspec spec/integration/runners/queue/rspec_runner_spec.rb
|
108
|
+
|
109
|
+
e2e-regular-rspec:
|
67
110
|
parallelism: 2
|
68
111
|
working_directory: ~/knapsack_pro-ruby
|
112
|
+
resource_class: small
|
69
113
|
parameters:
|
70
114
|
ruby:
|
71
115
|
type: string
|
@@ -122,8 +166,16 @@ jobs:
|
|
122
166
|
export KNAPSACK_PRO_BRANCH="$CIRCLE_BRANCH--$CIRCLE_BUILD_NUM--regular--split"
|
123
167
|
export KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES=true
|
124
168
|
bundle exec rake knapsack_pro:rspec
|
169
|
+
- run:
|
170
|
+
working_directory: ~/rails-app-with-knapsack_pro
|
171
|
+
command: |
|
172
|
+
# split custom files by test examples ||
|
173
|
+
export KNAPSACK_PRO_BRANCH="$CIRCLE_BRANCH--$CIRCLE_BUILD_NUM--regular--split-custom-files"
|
174
|
+
export KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES=true
|
175
|
+
export KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN="spec/features/calculator_spec.rb"
|
176
|
+
bundle exec rake knapsack_pro:rspec
|
125
177
|
|
126
|
-
|
178
|
+
e2e-queue-rspec:
|
127
179
|
parameters:
|
128
180
|
ruby:
|
129
181
|
type: string
|
@@ -131,6 +183,7 @@ jobs:
|
|
131
183
|
type: string
|
132
184
|
parallelism: 2
|
133
185
|
working_directory: ~/knapsack_pro-ruby
|
186
|
+
resource_class: small
|
134
187
|
docker:
|
135
188
|
- image: cimg/ruby:<< parameters.ruby >>-browsers
|
136
189
|
environment:
|
@@ -216,9 +269,10 @@ jobs:
|
|
216
269
|
export KNAPSACK_PRO_TEST_FILE_PATTERN="turnip/**/*.feature"
|
217
270
|
bundle exec rake "knapsack_pro:queue:rspec[-r turnip/rspec]"
|
218
271
|
|
219
|
-
|
272
|
+
e2e-regular-minitest:
|
220
273
|
parallelism: 2
|
221
274
|
working_directory: ~/knapsack_pro-ruby
|
275
|
+
resource_class: small
|
222
276
|
parameters:
|
223
277
|
ruby:
|
224
278
|
type: string
|
@@ -255,12 +309,13 @@ jobs:
|
|
255
309
|
export KNAPSACK_PRO_BRANCH="$CIRCLE_BRANCH--$CIRCLE_BUILD_NUM--regular"
|
256
310
|
bundle exec rake knapsack_pro:minitest[--verbose]
|
257
311
|
|
258
|
-
|
312
|
+
e2e-queue-minitest:
|
259
313
|
parameters:
|
260
314
|
ruby:
|
261
315
|
type: string
|
262
316
|
parallelism: 2
|
263
317
|
working_directory: ~/knapsack_pro-ruby
|
318
|
+
resource_class: small
|
264
319
|
docker:
|
265
320
|
- image: cimg/ruby:<< parameters.ruby >>-browsers
|
266
321
|
environment:
|
@@ -307,25 +362,31 @@ workflows:
|
|
307
362
|
tests:
|
308
363
|
jobs:
|
309
364
|
- unit
|
310
|
-
- integration-
|
311
|
-
name:
|
365
|
+
- integration-rspec:
|
366
|
+
name: integration__ruby-<< matrix.ruby >>__rspec-<< matrix.rspec >>
|
367
|
+
matrix:
|
368
|
+
parameters:
|
369
|
+
ruby: ["3.0", "3.1", "3.2", "3.3"]
|
370
|
+
rspec: ["3.10.2", "3.11.0", "3.12.2"]
|
371
|
+
- e2e-regular-rspec:
|
372
|
+
name: e2e-regular__ruby-<< matrix.ruby >>__rspec-<< matrix.rspec >>
|
312
373
|
matrix:
|
313
374
|
parameters:
|
314
|
-
ruby: ["3.0", "3.1", "3.2"]
|
375
|
+
ruby: ["3.0", "3.1", "3.2", "3.3"]
|
315
376
|
rspec: ["3.10.2", "3.11.0", "3.12.2"]
|
316
|
-
-
|
317
|
-
name:
|
377
|
+
- e2e-queue-rspec:
|
378
|
+
name: e2e-queue__ruby-<< matrix.ruby >>__rspec-<< matrix.rspec >>
|
318
379
|
matrix:
|
319
380
|
parameters:
|
320
|
-
ruby: ["3.0", "3.1", "3.2"]
|
381
|
+
ruby: ["3.0", "3.1", "3.2", "3.3"]
|
321
382
|
rspec: ["3.10.2", "3.11.0", "3.12.2"]
|
322
|
-
-
|
323
|
-
name:
|
383
|
+
- e2e-regular-minitest:
|
384
|
+
name: e2e-regular__ruby-<< matrix.ruby >>__minitest
|
324
385
|
matrix:
|
325
386
|
parameters:
|
326
|
-
ruby: ["3.0", "3.1", "3.2"]
|
327
|
-
-
|
328
|
-
name:
|
387
|
+
ruby: ["3.0", "3.1", "3.2", "3.3"]
|
388
|
+
- e2e-queue-minitest:
|
389
|
+
name: e2e-queue__ruby-<< matrix.ruby >>__minitest
|
329
390
|
matrix:
|
330
391
|
parameters:
|
331
|
-
ruby: ["3.0", "3.1", "3.2"]
|
392
|
+
ruby: ["3.0", "3.1", "3.2", "3.3"]
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Story
|
2
|
+
|
3
|
+
TODO: link to the internal story
|
4
|
+
|
5
|
+
## Related
|
6
|
+
|
7
|
+
TODO: links to related PRs or issues
|
8
|
+
|
9
|
+
# Description
|
10
|
+
|
11
|
+
TODO
|
12
|
+
|
13
|
+
# Changes
|
14
|
+
|
15
|
+
TODO: changes introduced by this PR
|
16
|
+
|
17
|
+
# Checklist reminder
|
18
|
+
|
19
|
+
- [ ] You follow the architecture outlined below for RSpec in Queue Mode, which is a work in progress (feel free to propose changes):
|
20
|
+
- Pure: `lib/knapsack_pro/pure/queue/rspec_pure.rb` contains pure functions that are unit tested.
|
21
|
+
- Extension: `lib/knapsack_pro/extensions/rspec_extension.rb` encapsulates calls to RSpec internals and is integration and e2e tested.
|
22
|
+
- Runner: `lib/knapsack_pro/runners/queue/rspec_runner.rb` invokes the pure code and the extension to produce side effects, which are integration and e2e tested.
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,92 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
### 7.0.0
|
4
|
+
|
5
|
+
* __(breaking change)__ RSpec in Queue Mode:
|
6
|
+
* The default for `KNAPSACK_PRO_LOG_LEVEL` is `info` instead of `debug`.
|
7
|
+
* The RSpec `before(:suite)` and `after(:suite)` hooks changed:
|
8
|
+
|
9
|
+
__Before:__<br>
|
10
|
+
The `before(:suite)` and `after(:suite)` hooks were executed multiple times. Each time for a batch of tests fetched from Knapsack Pro Queue API.
|
11
|
+
|
12
|
+
__After:__<br>
|
13
|
+
The `before(:suite)` and `after(:suite)` hooks are executed only once: `before(:suite)` is executed before starting tests, `after(:suite)` is executed after all tests are completed. (It is what you would expect from RSpec).
|
14
|
+
|
15
|
+
* The `KnapsackPro::Hooks::Queue.after_queue` hook change:
|
16
|
+
|
17
|
+
__Before:__<br>
|
18
|
+
The `KnapsackPro::Hooks::Queue.after_queue` hook is executed outside of the `after(:suite)` hook.
|
19
|
+
|
20
|
+
__After:__<br>
|
21
|
+
The `KnapsackPro::Hooks::Queue.after_queue` hook is executed __inside__ of the `after(:suite)` hook.
|
22
|
+
|
23
|
+
* Recommended RSpec changes in your project:
|
24
|
+
* Remove the following code if you use Queue Mode and the `rspec_junit_formatter` gem to generate JUnit XML or JSON reports:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
# REMOVE THE FOLLOWING CODE
|
28
|
+
|
29
|
+
# spec_helper.rb or rails_helper.rb
|
30
|
+
TMP_REPORT = "tmp/rspec_#{ENV['KNAPSACK_PRO_CI_NODE_INDEX']}.xml"
|
31
|
+
FINAL_REPORT = "tmp/final_rspec_#{ENV['KNAPSACK_PRO_CI_NODE_INDEX']}.xml"
|
32
|
+
|
33
|
+
KnapsackPro::Hooks::Queue.after_subset_queue do |queue_id, subset_queue_id|
|
34
|
+
if File.exist?(TMP_REPORT)
|
35
|
+
FileUtils.mv(TMP_REPORT, FINAL_REPORT)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
```
|
39
|
+
|
40
|
+
Learn more about [using Knapsack Pro with RSpec formatters](https://docs.knapsackpro.com/ruby/rspec/#formatters-rspec_junit_formatter-json) and [using Knapsack Pro with CircleCI](https://docs.knapsackpro.com/ruby/circleci/) in the docs.
|
41
|
+
|
42
|
+
* Replace the following code if you are using Queue Mode and the `percy-capybara` gem on a version older than 4:
|
43
|
+
|
44
|
+
Before:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
KnapsackPro::Hooks::Queue.before_queue { |queue_id| Percy::Capybara.initialize_build }
|
48
|
+
KnapsackPro::Hooks::Queue.after_queue { |queue_id| Percy::Capybara.finalize_build }
|
49
|
+
```
|
50
|
+
|
51
|
+
After:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
# recommended
|
55
|
+
before(:suite) { Percy::Capybara.initialize_build }
|
56
|
+
after(:suite) { Percy::Capybara.finalize_build }
|
57
|
+
```
|
58
|
+
|
59
|
+
Learn more about [using Knapsack Pro with Percy](https://docs.knapsackpro.com/ruby/hooks/#percy-capybara) in the docs.
|
60
|
+
|
61
|
+
* We are no longer modifying the default RSpec formatters in Queue Mode. You can remove the [`KNAPSACK_PRO_MODIFY_DEFAULT_RSPEC_FORMATTERS`](https://docs.knapsackpro.com/ruby/reference/#knapsack_pro_modify_default_rspec_formatters-removed-rspec) environment variable from your CI config if you are using it.
|
62
|
+
|
63
|
+
* RSpec improvements in Queue Mode:
|
64
|
+
* Termination signals (`HUP`, `INT`, `TERM`, `ABRT`, `QUIT`, `USR1`, and `USR2`) are handled earlier: the process will terminate before the next top-level example group (`describe` or `context`) instead of waiting for the next Knapsack Pro batch of tests.
|
65
|
+
|
66
|
+
* Respect the `--error-exit-code` option. It sets a custom exit code (instead of `1`) when RSpec fails outside an example (e.g. lack of memory, termination signal).
|
67
|
+
|
68
|
+
```bash
|
69
|
+
bundle exec rake "knapsack_pro:queue:rspec[--error-exit-code 3]"
|
70
|
+
```
|
71
|
+
|
72
|
+
* Respect the `--failure-exit-code` option. It sets a custom exit code for when any examples fail.
|
73
|
+
|
74
|
+
```bash
|
75
|
+
bundle exec rake "knapsack_pro:queue:rspec[--failure-exit-code 2]"
|
76
|
+
```
|
77
|
+
|
78
|
+
* Respect the `--fail-fast` option and show a warning in the Knapsack Pro log.
|
79
|
+
|
80
|
+
* Ignore the `fail_if_no_examples` option in Queue Mode:
|
81
|
+
* A late CI node, started after all tests were executed by other nodes, is expected to receive an empty batch.
|
82
|
+
* A batch could contain tests with no examples (e.g. commented out)
|
83
|
+
|
84
|
+
* Raise an exception if the [deprecated `run_all_when_everything_filtered`](https://docs.knapsackpro.com/ruby/rspec/#some-of-my-test-files-are-not-executed) option is detected.
|
85
|
+
|
86
|
+
PR with the above changes: https://github.com/KnapsackPro/knapsack_pro-ruby/pull/237
|
87
|
+
|
88
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v6.0.4...v7.0.0
|
89
|
+
|
3
90
|
### 6.0.4
|
4
91
|
|
5
92
|
* fix(minitest): avoid installing `at_exit` (that would result in an empty run of Minitest after Knapsack Pro is finished in Queue Mode)
|
data/Gemfile
CHANGED
@@ -2,3 +2,12 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in knapsack.gemspec
|
4
4
|
gemspec
|
5
|
+
|
6
|
+
group :test do
|
7
|
+
gem 'rspec_junit_formatter', require: false
|
8
|
+
gem 'nokogiri', require: false
|
9
|
+
gem 'simplecov', require: false
|
10
|
+
|
11
|
+
# This line is going to be replaced on CI to test different RSpec versions.
|
12
|
+
# gem 'rspec-core', 'x.x.x'
|
13
|
+
end
|
data/README.md
CHANGED
@@ -42,10 +42,6 @@ The `knapsack_pro` gem supports all CIs and the following test runners:
|
|
42
42
|
- Spinach
|
43
43
|
- Turnip
|
44
44
|
|
45
|
-
## Requirements
|
46
|
-
|
47
|
-
`>= Ruby 2.1.0`
|
48
|
-
|
49
45
|
## Installation
|
50
46
|
|
51
47
|
The [Installation Guide](https://docs.knapsackpro.com/knapsack_pro-ruby/guide/?utm_source=github&utm_medium=readme&utm_campaign=knapsack_pro-ruby_gem&utm_content=installation_guide) will ask you a few questions and generate instruction steps for your project:
|
data/knapsack_pro.gemspec
CHANGED
@@ -6,10 +6,11 @@ require 'knapsack_pro/version'
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = 'knapsack_pro'
|
8
8
|
spec.version = KnapsackPro::VERSION
|
9
|
+
spec.required_ruby_version = '>= 2.7.0'
|
9
10
|
spec.authors = ['ArturT']
|
10
11
|
spec.email = ['support@knapsackpro.com']
|
11
12
|
spec.summary = %q{Knapsack Pro splits tests across parallel CI nodes and ensures each parallel job finish work at a similar time.}
|
12
|
-
spec.description = %q{
|
13
|
+
spec.description = %q{Knapsack Pro wraps your current test runner(s) and works with your existing CI infrastructure to parallelize tests optimally. It dynamically splits your tests based on up-to-date test execution data. It's designed from the ground up for CI and supports all of them.}
|
13
14
|
spec.homepage = 'https://knapsackpro.com'
|
14
15
|
spec.license = 'MIT'
|
15
16
|
spec.metadata = {
|
@@ -60,13 +60,13 @@ module KnapsackPro
|
|
60
60
|
File.write(self.class.adapter_bind_method_called_file, nil)
|
61
61
|
|
62
62
|
if KnapsackPro::Config::Env.recording_enabled?
|
63
|
-
KnapsackPro.logger.debug('
|
63
|
+
KnapsackPro.logger.debug('Regular Mode enabled.')
|
64
64
|
bind_time_tracker
|
65
65
|
bind_save_report
|
66
66
|
end
|
67
67
|
|
68
68
|
if KnapsackPro::Config::Env.queue_recording_enabled?
|
69
|
-
KnapsackPro.logger.debug('
|
69
|
+
KnapsackPro.logger.debug('Queue Mode enabled.')
|
70
70
|
bind_queue_mode
|
71
71
|
end
|
72
72
|
end
|
@@ -83,8 +83,13 @@ module KnapsackPro
|
|
83
83
|
raise NotImplementedError
|
84
84
|
end
|
85
85
|
|
86
|
+
def bind_after_queue_hook
|
87
|
+
raise NotImplementedError
|
88
|
+
end
|
89
|
+
|
86
90
|
def bind_queue_mode
|
87
91
|
bind_before_queue_hook
|
92
|
+
bind_after_queue_hook
|
88
93
|
bind_time_tracker
|
89
94
|
end
|
90
95
|
end
|
@@ -87,7 +87,7 @@ module KnapsackPro
|
|
87
87
|
|
88
88
|
def bind_time_tracker
|
89
89
|
ensure_no_focus!
|
90
|
-
|
90
|
+
log_tests_duration
|
91
91
|
end
|
92
92
|
|
93
93
|
def ensure_no_focus!
|
@@ -105,12 +105,14 @@ module KnapsackPro
|
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
|
-
def
|
108
|
+
def log_tests_duration
|
109
109
|
::RSpec.configure do |config|
|
110
|
-
config.
|
110
|
+
config.append_after(:suite) do
|
111
111
|
time_tracker = KnapsackPro::Formatters::TimeTrackerFetcher.call
|
112
|
-
|
113
|
-
|
112
|
+
if time_tracker
|
113
|
+
formatted = KnapsackPro::Presenter.global_time(time_tracker.duration)
|
114
|
+
KnapsackPro.logger.debug(formatted)
|
115
|
+
end
|
114
116
|
end
|
115
117
|
end
|
116
118
|
end
|
@@ -127,10 +129,15 @@ module KnapsackPro
|
|
127
129
|
def bind_before_queue_hook
|
128
130
|
::RSpec.configure do |config|
|
129
131
|
config.before(:suite) do
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
132
|
+
KnapsackPro::Hooks::Queue.call_before_queue
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def bind_after_queue_hook
|
138
|
+
::RSpec.configure do |config|
|
139
|
+
config.after(:suite) do
|
140
|
+
KnapsackPro::Hooks::Queue.call_after_queue
|
134
141
|
end
|
135
142
|
end
|
136
143
|
end
|
@@ -144,14 +144,6 @@ module KnapsackPro
|
|
144
144
|
test_files_encrypted == 'true'
|
145
145
|
end
|
146
146
|
|
147
|
-
def modify_default_rspec_formatters
|
148
|
-
ENV.fetch('KNAPSACK_PRO_MODIFY_DEFAULT_RSPEC_FORMATTERS', true)
|
149
|
-
end
|
150
|
-
|
151
|
-
def modify_default_rspec_formatters?
|
152
|
-
modify_default_rspec_formatters.to_s == 'true'
|
153
|
-
end
|
154
|
-
|
155
147
|
def branch_encrypted
|
156
148
|
ENV['KNAPSACK_PRO_BRANCH_ENCRYPTED']
|
157
149
|
end
|
@@ -276,7 +268,7 @@ module KnapsackPro
|
|
276
268
|
end
|
277
269
|
|
278
270
|
def log_level
|
279
|
-
LOG_LEVELS[ENV['KNAPSACK_PRO_LOG_LEVEL'].to_s.downcase] || ::Logger::
|
271
|
+
LOG_LEVELS[ENV['KNAPSACK_PRO_LOG_LEVEL'].to_s.downcase] || ::Logger::INFO
|
280
272
|
end
|
281
273
|
|
282
274
|
def log_dir
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KnapsackPro
|
4
|
+
module Extensions
|
5
|
+
# Facade to abstract calls to internal RSpec methods.
|
6
|
+
# To allow comparing the monkey patch with the original RSpec code, keep a similar method structure and permalink to the source.
|
7
|
+
module RSpecExtension
|
8
|
+
Seed = Struct.new(:value, :used?)
|
9
|
+
|
10
|
+
def self.setup!
|
11
|
+
RSpec::Core::World.prepend(World)
|
12
|
+
RSpec::Core::Runner.prepend(Runner)
|
13
|
+
RSpec::Core::Configuration.prepend(Configuration)
|
14
|
+
end
|
15
|
+
|
16
|
+
module World
|
17
|
+
# Based on:
|
18
|
+
# https://github.com/rspec/rspec-core/blob/f8c8880dabd8f0544a6f91d8d4c857c1bd8df903/lib/rspec/core/world.rb#L171
|
19
|
+
#
|
20
|
+
# Filters are not announced because we do not load tests during setup. It would print `No examples found.` and we don't want that.
|
21
|
+
def knapsack__announce_filters
|
22
|
+
fail_if_config_and_cli_options_invalid
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module Runner
|
27
|
+
# Based on:
|
28
|
+
# https://github.com/rspec/rspec-core/blob/f8c8880dabd8f0544a6f91d8d4c857c1bd8df903/lib/rspec/core/runner.rb#L98
|
29
|
+
#
|
30
|
+
# `@configuration.load_spec_files` is not called because we load tests in batches with `knapsack__load_spec_files_batch` later on.
|
31
|
+
def knapsack__setup(stream_error = $stderr, stream_out = $stdout)
|
32
|
+
configure(stream_error, stream_out)
|
33
|
+
ensure
|
34
|
+
world.knapsack__announce_filters
|
35
|
+
end
|
36
|
+
|
37
|
+
def knapsack__wants_to_quit?
|
38
|
+
world.wants_to_quit
|
39
|
+
end
|
40
|
+
|
41
|
+
def knapsack__rspec_is_quitting?
|
42
|
+
world.respond_to?(:rspec_is_quitting) && world.rspec_is_quitting
|
43
|
+
end
|
44
|
+
|
45
|
+
def knapsack__exit_early
|
46
|
+
_exit_status = configuration.reporter.exit_early(exit_code)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Based on:
|
50
|
+
# https://github.com/rspec/rspec-core/blob/f8c8880dabd8f0544a6f91d8d4c857c1bd8df903/lib/rspec/core/configuration.rb#L546
|
51
|
+
def knapsack__error_exit_code
|
52
|
+
configuration.error_exit_code # nil unless `--error-exit-code` is specified
|
53
|
+
end
|
54
|
+
|
55
|
+
# must be called after `Runner#knapsack__setup` that loads the `spec_helper.rb` configuration
|
56
|
+
def knapsack__deprecated_run_all_when_everything_filtered_enabled?
|
57
|
+
configuration.respond_to?(:run_all_when_everything_filtered) && !!configuration.run_all_when_everything_filtered
|
58
|
+
end
|
59
|
+
|
60
|
+
def knapsack__seed
|
61
|
+
Seed.new(configuration.seed.to_s, configuration.seed_used?)
|
62
|
+
end
|
63
|
+
|
64
|
+
# @param test_file_paths Array[String]
|
65
|
+
# Example: ['a_spec.rb', 'b_spec.rb[1:1]']
|
66
|
+
def knapsack__load_spec_files_batch(test_file_paths)
|
67
|
+
world.reset
|
68
|
+
|
69
|
+
# Reset filters, but do not reset `configuration.static_config_filter_manager` to preserve the --tag option
|
70
|
+
filter_manager = RSpec::Core::FilterManager.new
|
71
|
+
options.configure_filter_manager(filter_manager)
|
72
|
+
configuration.filter_manager = filter_manager
|
73
|
+
|
74
|
+
configuration.knapsack__load_spec_files(test_file_paths)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Based on:
|
78
|
+
# https://github.com/rspec/rspec-core/blob/f8c8880dabd8f0544a6f91d8d4c857c1bd8df903/lib/rspec/core/runner.rb#L113
|
79
|
+
#
|
80
|
+
# Ignore `configuration.fail_if_no_examples` in Queue Mode:
|
81
|
+
# * a late CI node, started after all tests were executed by other nodes, is expected to receive an empty batch
|
82
|
+
# * a batch could contain tests with no examples (e.g. commented out)
|
83
|
+
#
|
84
|
+
# @return [Fixnum] exit status code.
|
85
|
+
def knapsack__run_specs(queue_runner)
|
86
|
+
# Based on:
|
87
|
+
# https://github.com/rspec/rspec-core/blob/f8c8880dabd8f0544a6f91d8d4c857c1bd8df903/lib/rspec/core/world.rb#L53
|
88
|
+
ordering_strategy = configuration.ordering_registry.fetch(:global)
|
89
|
+
node_examples_passed = true
|
90
|
+
|
91
|
+
configuration.reporter.report(_expected_example_count = 0) do |reporter|
|
92
|
+
configuration.with_suite_hooks do
|
93
|
+
queue_runner.with_batch do |test_file_paths|
|
94
|
+
knapsack__load_spec_files_batch(test_file_paths)
|
95
|
+
|
96
|
+
examples_passed = ordering_strategy.order(world.example_groups).map do |example_group|
|
97
|
+
queue_runner.handle_signal!
|
98
|
+
example_group.run(reporter)
|
99
|
+
end.all?
|
100
|
+
|
101
|
+
node_examples_passed = false unless examples_passed
|
102
|
+
|
103
|
+
knapsack__persist_example_statuses
|
104
|
+
|
105
|
+
if reporter.fail_fast_limit_met?
|
106
|
+
queue_runner.log_fail_fast_limit_met
|
107
|
+
break
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
exit_code(node_examples_passed)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Based on:
|
117
|
+
# https://github.com/rspec/rspec-core/blob/f8c8880dabd8f0544a6f91d8d4c857c1bd8df903/lib/rspec/core/runner.rb#L90
|
118
|
+
def knapsack__persist_example_statuses
|
119
|
+
persist_example_statuses
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
module Configuration
|
124
|
+
# Based on:
|
125
|
+
# https://github.com/rspec/rspec-core/blob/f8c8880dabd8f0544a6f91d8d4c857c1bd8df903/lib/rspec/core/configuration.rb#L1619
|
126
|
+
def knapsack__load_spec_files(test_file_paths)
|
127
|
+
batch_of_files_to_run = get_files_to_run(test_file_paths)
|
128
|
+
batch_of_files_to_run.each do |f|
|
129
|
+
file = File.expand_path(f)
|
130
|
+
load_file_handling_errors(:load, file)
|
131
|
+
loaded_spec_files << file
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|