knapsack_pro 0.27.0 → 0.28.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +51 -25
- data/lib/knapsack_pro/runners/queue/rspec_runner.rb +29 -7
- data/lib/knapsack_pro/version.rb +1 -1
- data/spec/knapsack_pro/runners/queue/rspec_runner_spec.rb +10 -10
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 558ebb63c8dd85721ac6b3b0fd3a4ec13a84727f
|
4
|
+
data.tar.gz: d28a11954c0412babd8f6de1f1d1c9171f371d6c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e31031c889f546e3fa8d19c719cf6c3ddf9cf8e76c5728c915959e05e02e3762577a8aa06bb3d3434e9d308a0c4705b5d395f3eed6368d10fe6cfbc449cefc22
|
7
|
+
data.tar.gz: ce06127801cc30c4d53a53e3566dfebc262b3b7d8339a3ab330b21fae49e26e521b1528c1cc08affa6c295dd2167497f39ea1405e6c187898f9d96a9d3300c94
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,13 @@
|
|
2
2
|
|
3
3
|
* TODO
|
4
4
|
|
5
|
+
### 0.28.0
|
6
|
+
|
7
|
+
* Show at the end of `knapsack_pro:queue:rspec` command the example how to run all tests executed for the CI node in the development environment.
|
8
|
+
* Show for each intermediate request to Knapsack Pro API queue how to run a subset of tests fetched from API.
|
9
|
+
|
10
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v0.27.0...v0.28.0
|
11
|
+
|
5
12
|
### 0.27.0
|
6
13
|
|
7
14
|
* Save build subset to API even when no test files were executed on CI node. Add warnings to notify why the test files were not executed on CI node in particular mode: regular or queue mode.
|
data/README.md
CHANGED
@@ -109,6 +109,7 @@ The knapsack_pro has also [queue mode](#queue-mode) to get most optimal test sui
|
|
109
109
|
- [How is that data secured?](#how-is-that-data-secured)
|
110
110
|
- [Who has access to the data?](#who-has-access-to-the-data)
|
111
111
|
- [Why when I use Queue Mode for RSpec and test fails then I see multiple times info about failed test in RSpec result?](#why-when-i-use-queue-mode-for-rspec-and-test-fails-then-i-see-multiple-times-info-about-failed-test-in-rspec-result)
|
112
|
+
- [Why when I use Queue Mode for RSpec then I see multiple times the same pending tests?](#why-when-i-use-queue-mode-for-rspec-then-i-see-multiple-times-the-same-pending-tests)
|
112
113
|
- [Does in Queue Mode the RSpec is initialized many times that causes Rails load over and over again?](#does-in-queue-mode-the-rspec-is-initialized-many-times-that-causes-rails-load-over-and-over-again)
|
113
114
|
- [Gem tests](#gem-tests)
|
114
115
|
- [Spec](#spec)
|
@@ -347,17 +348,25 @@ There might be some cached test suite splits for git commits you run in past for
|
|
347
348
|
|
348
349
|
* If you are not using one of [supported CI providers](#supported-ci-providers) then please note that knapsack_pro gem doesn't know what is CI build ID in order to generated queue for particular CI build. This may result in two different CI builds taking tests from the same queue when CI builds are running at the same time against the same git commit.
|
349
350
|
|
350
|
-
To avoid this you
|
351
|
+
To avoid this you should specify unique `KNAPSACK_PRO_CI_NODE_BUILD_ID` environment variable for each CI build. This mean that each CI node that is part of particular CI build should have the same value for `KNAPSACK_PRO_CI_NODE_BUILD_ID`.
|
351
352
|
|
352
353
|
* Note that in the Queue Mode by default you cannot retry the failed CI node with exactly the same subset of tests that were run on the CI node in the first place. It's possible in regular mode ([read more](#knapsack_pro_fixed_test_suite_splite-test-suite-split-based-on-seed)). If you want to have similar behavior in Queue Mode you need to explicitly [enable it](#knapsack_pro_fixed_queue_split-remember-queue-split-on-retry-ci-node).
|
353
354
|
|
354
355
|
By default the Queue Mode works this way:
|
355
356
|
|
356
|
-
* If you retry the failed build and your all CI nodes will start a new build then there will be a new dynamic test suite split across CI nodes.
|
357
|
+
* If you retry the failed build and your all CI nodes will start a new build then there will be a new dynamic test suite split across CI nodes. The reason is that the most of the CI providers schedule a new CI build with different ID when you retry CI build. They retry all CI nodes again. In that case you don't have to worry with below edge cases because the CI build ID will be different so a new queue will be initialized on Knapsack Pro API side and all retried CI node will connect to that queue.
|
357
358
|
|
358
|
-
|
359
|
+
Edge cases:
|
359
360
|
|
360
|
-
*
|
361
|
+
* Let's say one of the CI nodes failed and you retry just this single CI node while other CI nodes are still running. Let's assume this retried CI node is part of the same CI build ID when you use supported CI provider or `KNAPSACK_PRO_CI_NODE_BUILD_ID` is defined and stays the same. The retried CI node will be connected to the queue consumed by still running CI nodes. You probably would expect the retried CI node to run the tests that were executed there on the first place. To achieve that you need to [enable it](#knapsack_pro_fixed_queue_split-remember-queue-split-on-retry-ci-node).
|
362
|
+
|
363
|
+
* Let's say one of the CI nodes failed and you retry just this single CI node while other CI nodes already finished work. Let's assume this retried CI node is part of the same CI build ID when you use supported CI provider or `KNAPSACK_PRO_CI_NODE_BUILD_ID` is defined and stays the same. The fact is all CI nodes finished work so the queue was consumed.
|
364
|
+
* If you retry CI node in first hour since the CI build started for the first time then the retried CI node won't execute tests because the queue was consumed. There is important reason why it works like that. For instance some CI providers like Buildkite allows to start CI node later than the others so sometimes the particular CI node may start work while all other CI nodes finished work. In that case we don't want to run tests on the CI node because queue was already consumed. We don't know whether the CI node is part of the build or it is retried CI node hence the 1 hour lock on initializing a new queue.
|
365
|
+
* If you retry CI node after 1 hour since the CI build started for the first time then the retried CI node will initialize a new queue and it will run whole test suite from the queue because there will be no other CI nodes running connected to the queue. The order of tests on retried CI node will be different than on the first run. You probably would expect the retried CI node to run the tests that were executed there on the first place. To achieve that you need to [enable it](#knapsack_pro_fixed_queue_split-remember-queue-split-on-retry-ci-node).
|
366
|
+
|
367
|
+
* When you use unsupported CI provider by knapack_pro gem or you forget to set unique `KNAPSACK_PRO_CI_NODE_BUILD_ID` per CI build then:
|
368
|
+
* when you retry single CI node then it will initialize a new queue and it will run whole test suite from the queue because there will be no other CI nodes running connected to the queue. The order of tests on retried CI node will be different than on the first run.
|
369
|
+
* when you retry all CI nodes then a new queue will be initialized and all CI nodes will connect to it.
|
361
370
|
|
362
371
|
### Extra configuration for Queue Mode
|
363
372
|
|
@@ -382,6 +391,8 @@ There might be some cached test suite splits for git commits you run in past for
|
|
382
391
|
|
383
392
|
[knapsack_pro] {"queue_name"=>nil, "test_files"=>[{"path"=>"spec/foo_spec.rb", "time_execution"=>1.23}]}
|
384
393
|
|
394
|
+
To [reproduce tests executed on CI node](#for-knapsack_pro-queue-mode) in development environment please see FAQ.
|
395
|
+
|
385
396
|
### Supported test runners in queue mode
|
386
397
|
|
387
398
|
At this moment the queue mode works for:
|
@@ -688,34 +699,42 @@ If you were running your tests with `--order random` on your CI then you can add
|
|
688
699
|
|
689
700
|
#### for knapsack_pro queue mode
|
690
701
|
|
691
|
-
|
702
|
+
There are a few ways to reproduce tests executed on CI node in your development environment.
|
692
703
|
|
693
|
-
|
694
|
-
KNAPSACK_PRO_REPOSITORY_ADAPTER=git \
|
695
|
-
KNAPSACK_PRO_PROJECT_DIR=~/projects/rails-app \
|
696
|
-
KNAPSACK_PRO_CI_NODE_TOTAL=2 \
|
697
|
-
KNAPSACK_PRO_CI_NODE_INDEX=0 \
|
698
|
-
KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true \
|
699
|
-
bundle exec rake "knapsack_pro:queue:rspec"
|
704
|
+
* At the end of `knapsack_pro:queue:rspec` results you will find example of command that you can copy and paste to your development machine. It will run all tests executed on the CI node in a single run.
|
700
705
|
|
701
|
-
|
706
|
+
* For each intermediate request to Knapsack Pro API queue you will also find example of command to run a subset of tests fetched from API. This might be helpful when you use `--order random` for rspec and you would like to reproduce the tests with the same seed.
|
702
707
|
|
703
|
-
|
708
|
+
* You can also retry tests and record the time execution data for them again for the particular CI node. Note you must be checkout on the same branch and git commit as your CI node was.
|
704
709
|
|
705
|
-
|
710
|
+
To retry the particular CI node do this on your machine:
|
706
711
|
|
707
|
-
|
708
|
-
|
712
|
+
KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC=token \
|
713
|
+
KNAPSACK_PRO_REPOSITORY_ADAPTER=git \
|
714
|
+
KNAPSACK_PRO_PROJECT_DIR=~/projects/rails-app \
|
715
|
+
KNAPSACK_PRO_CI_NODE_TOTAL=2 \
|
716
|
+
KNAPSACK_PRO_CI_NODE_INDEX=0 \
|
717
|
+
KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true \
|
718
|
+
bundle exec rake "knapsack_pro:queue:rspec"
|
709
719
|
|
710
|
-
|
720
|
+
If you were running your tests with `--order random` on your CI like this:
|
711
721
|
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
722
|
+
bundle exec rake "knapsack_pro:queue:rspec[--order random]"
|
723
|
+
|
724
|
+
Then you can find the seed number visible in rspec output:
|
725
|
+
|
726
|
+
(...)
|
727
|
+
Randomized with seed 123
|
728
|
+
|
729
|
+
You can pass the seed in your local environment to reproduce the tests in the same order as they were executed on CI node:
|
730
|
+
|
731
|
+
KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC=token \
|
732
|
+
KNAPSACK_PRO_REPOSITORY_ADAPTER=git \
|
733
|
+
KNAPSACK_PRO_PROJECT_DIR=~/projects/rails-app \
|
734
|
+
KNAPSACK_PRO_CI_NODE_TOTAL=2 \
|
735
|
+
KNAPSACK_PRO_CI_NODE_INDEX=0 \
|
736
|
+
KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true \
|
737
|
+
bundle exec rake "knapsack_pro:queue:rspec[--seed 123]"
|
719
738
|
|
720
739
|
### What happens when Knapsack Pro API is not available/not reachable temporarily?
|
721
740
|
|
@@ -834,6 +853,13 @@ When you use Queue Mode then knapack_pro does multiple requests to Knapsack Pro
|
|
834
853
|
This means RSpec will remember failed tests so far and it will present them at the end of each executed test subset.
|
835
854
|
You can see the list of all failed test files at the end of knapack_pro queue mode command.
|
836
855
|
|
856
|
+
### Why when I use Queue Mode for RSpec then I see multiple times the same pending tests?
|
857
|
+
|
858
|
+
RSpec collects information about pending tests and presents it at the end of RSpec result.
|
859
|
+
When you use Queue Mode then knapack_pro does multiple requests to Knapsack Pro API and fetches a few test files to execute.
|
860
|
+
This means RSpec will remember pending tests so far and it will present them at the end of each executed test subset.
|
861
|
+
You can see the list of all pending test files at the end of knapack_pro queue mode command.
|
862
|
+
|
837
863
|
### Does in Queue Mode the RSpec is initialized many times that causes Rails load over and over again?
|
838
864
|
|
839
865
|
No. In Queue Mode the RSpec configuration is updated every time when knapsack_pro gem gets a new set of test files from the Knapsack Pro API and it looks in knapsack_pro output like RSpec was loaded many times but in fact, it loads your project environment only once.
|
@@ -11,30 +11,52 @@ module KnapsackPro
|
|
11
11
|
|
12
12
|
runner = new(KnapsackPro::Adapters::RSpecAdapter)
|
13
13
|
|
14
|
-
cli_args = (args || '').split
|
15
|
-
|
14
|
+
cli_args = (args || '').split + [
|
15
|
+
'--default-path', runner.test_dir,
|
16
|
+
]
|
17
|
+
run_tests(runner, true, cli_args, 0, [])
|
16
18
|
end
|
17
19
|
|
18
|
-
def self.run_tests(runner, can_initialize_queue, args, exitstatus)
|
20
|
+
def self.run_tests(runner, can_initialize_queue, args, exitstatus, all_test_file_paths)
|
19
21
|
test_file_paths = runner.test_file_paths(can_initialize_queue: can_initialize_queue)
|
20
22
|
|
21
23
|
if test_file_paths.empty?
|
24
|
+
unless all_test_file_paths.empty?
|
25
|
+
cli_args = args + all_test_file_paths
|
26
|
+
|
27
|
+
log_rspec_command(cli_args, :end_of_queue)
|
28
|
+
end
|
29
|
+
|
22
30
|
KnapsackPro::Report.save_node_queue_to_api
|
23
31
|
exit(exitstatus)
|
24
32
|
else
|
25
33
|
subset_queue_id = KnapsackPro::Config::EnvGenerator.set_subset_queue_id
|
26
34
|
ENV['KNAPSACK_PRO_SUBSET_QUEUE_ID'] = subset_queue_id
|
27
35
|
|
28
|
-
|
29
|
-
|
30
|
-
|
36
|
+
all_test_file_paths += test_file_paths
|
37
|
+
cli_args = args + test_file_paths
|
38
|
+
|
39
|
+
log_rspec_command(cli_args, :subset_queue)
|
40
|
+
|
31
41
|
options = RSpec::Core::ConfigurationOptions.new(cli_args)
|
32
42
|
exit_code = RSpec::Core::Runner.new(options).run($stderr, $stdout)
|
33
43
|
exitstatus = exit_code if exit_code != 0
|
34
44
|
RSpec.world.example_groups.clear
|
35
45
|
|
36
|
-
run_tests(runner, false, args, exitstatus)
|
46
|
+
run_tests(runner, false, args, exitstatus, all_test_file_paths)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def self.log_rspec_command(cli_args, type)
|
53
|
+
case type
|
54
|
+
when :subset_queue
|
55
|
+
KnapsackPro.logger.info("To retry in development the subset of tests fetched from API queue please run below command on your machine. If you use --order random then remember to add proper --seed 123 that you will find at the end of rspec command.")
|
56
|
+
when :end_of_queue
|
57
|
+
KnapsackPro.logger.info("To retry in development the tests for this CI node please run below command on your machine. It will run all tests in a single run. If you need to reproduce a particular subset of tests fetched from API queue then above after each request to Knapsack Pro API you will find example rspec command.")
|
37
58
|
end
|
59
|
+
KnapsackPro.logger.info("bundle exec rspec " + cli_args.join(' '))
|
38
60
|
end
|
39
61
|
end
|
40
62
|
end
|
data/lib/knapsack_pro/version.rb
CHANGED
@@ -2,7 +2,10 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
|
|
2
2
|
describe '.run' do
|
3
3
|
let(:test_suite_token_rspec) { 'fake-token' }
|
4
4
|
let(:queue_id) { 'fake-queue-id' }
|
5
|
-
let(:
|
5
|
+
let(:test_dir) { 'fake-test-dir' }
|
6
|
+
let(:runner) do
|
7
|
+
instance_double(described_class, test_dir: test_dir)
|
8
|
+
end
|
6
9
|
|
7
10
|
subject { described_class.run(args) }
|
8
11
|
|
@@ -22,7 +25,7 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
|
|
22
25
|
|
23
26
|
it do
|
24
27
|
result = double
|
25
|
-
expect(described_class).to receive(:run_tests).with(runner, true, ['--example-arg', 'example-value'], 0).and_return(result)
|
28
|
+
expect(described_class).to receive(:run_tests).with(runner, true, ['--example-arg', 'example-value', '--default-path', 'fake-test-dir'], 0, []).and_return(result)
|
26
29
|
|
27
30
|
expect(subject).to eq result
|
28
31
|
end
|
@@ -33,7 +36,7 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
|
|
33
36
|
|
34
37
|
it do
|
35
38
|
result = double
|
36
|
-
expect(described_class).to receive(:run_tests).with(runner, true, [], 0).and_return(result)
|
39
|
+
expect(described_class).to receive(:run_tests).with(runner, true, ['--default-path', 'fake-test-dir'], 0, []).and_return(result)
|
37
40
|
|
38
41
|
expect(subject).to eq result
|
39
42
|
end
|
@@ -41,15 +44,12 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
|
|
41
44
|
end
|
42
45
|
|
43
46
|
describe '.run_tests' do
|
44
|
-
let(:
|
45
|
-
let(:runner) do
|
46
|
-
instance_double(described_class, test_dir: test_dir)
|
47
|
-
end
|
47
|
+
let(:runner) { instance_double(described_class) }
|
48
48
|
let(:can_initialize_queue) { double(:can_initialize_queue) }
|
49
|
-
let(:args) { ['--example-arg', 'example-value'] }
|
49
|
+
let(:args) { ['--example-arg', 'example-value', '--default-path', 'fake-test-dir'] }
|
50
50
|
let(:exitstatus) { double }
|
51
51
|
|
52
|
-
subject { described_class.run_tests(runner, can_initialize_queue, args, exitstatus) }
|
52
|
+
subject { described_class.run_tests(runner, can_initialize_queue, args, exitstatus, []) }
|
53
53
|
|
54
54
|
before do
|
55
55
|
expect(runner).to receive(:test_file_paths).with(can_initialize_queue: can_initialize_queue).and_return(test_file_paths)
|
@@ -67,7 +67,7 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
|
|
67
67
|
options = double
|
68
68
|
expect(RSpec::Core::ConfigurationOptions).to receive(:new).with([
|
69
69
|
'--example-arg', 'example-value',
|
70
|
-
'--default-path',
|
70
|
+
'--default-path', 'fake-test-dir',
|
71
71
|
'a_spec.rb', 'b_spec.rb',
|
72
72
|
]).and_return(options)
|
73
73
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knapsack_pro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.28.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ArturT
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-02-
|
11
|
+
date: 2017-02-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|