knapsack_pro 1.17.0 → 1.18.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 +14 -0
- data/README.md +34 -7
- data/lib/knapsack_pro/allocator.rb +11 -0
- data/lib/knapsack_pro/client/connection.rb +1 -1
- data/lib/knapsack_pro/config/ci/base.rb +3 -0
- data/lib/knapsack_pro/config/ci/buildkite.rb +4 -0
- data/lib/knapsack_pro/config/env.rb +24 -0
- data/lib/knapsack_pro/queue_allocator.rb +11 -0
- data/lib/knapsack_pro/version.rb +1 -1
- data/spec/knapsack_pro/allocator_spec.rb +46 -8
- data/spec/knapsack_pro/client/connection_spec.rb +2 -2
- data/spec/knapsack_pro/config/ci/base_spec.rb +1 -0
- data/spec/knapsack_pro/config/ci/buildkite_spec.rb +13 -0
- data/spec/knapsack_pro/config/env_spec.rb +91 -0
- data/spec/knapsack_pro/queue_allocator_spec.rb +52 -15
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 030ea46e8f4a421824a682b4286f7e362d0eec9a3bc50cd113e703391a51e40f
|
4
|
+
data.tar.gz: 47ab9de263fce5a5576ac2d1054fc66ea15b7982f01595b3ac237534deede7cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c94a8c86cd5114919737a385c792e564d373d82d0f9e195d18c45c043cf28d7ffc8e90bdab81d8d02ffd896aa1761b895c06d60d0dc8b232daffa347e73e2c06
|
7
|
+
data.tar.gz: 2f920d5b94aa829b975d3385e70df37a0817bc1b88962fc34b017cb3095d3b6cecd6e6c4cb0e2c69bb9643962c40b340ffbc8ba780558012949608296a17c3c0
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
### 1.18.0
|
4
|
+
|
5
|
+
* __IMPORTANT__ Do not allow Fallback Mode when the CI node was retried to avoid running the wrong set of tests
|
6
|
+
|
7
|
+
Please read the PR description if you are using retry failed CI node feature on your CI (for instance you use Buildkite).
|
8
|
+
|
9
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/pull/100
|
10
|
+
|
11
|
+
* Increase delay between request retry to Knapsack Pro API from 2s to 4s for 2nd request and from 4s to 8s for 3rd request
|
12
|
+
|
13
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/pull/99
|
14
|
+
|
15
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v1.17.0...v1.18.0
|
16
|
+
|
3
17
|
### 1.17.0
|
4
18
|
|
5
19
|
* Add `KNAPSACK_PRO_CUCUMBER_QUEUE_PREFIX` to allow run Cucumber with spring gem in Queue Mode
|
data/README.md
CHANGED
@@ -84,8 +84,9 @@ We keep this old FAQ in README to not break old links spread across the web. You
|
|
84
84
|
- [Supported test runners in queue mode](#supported-test-runners-in-queue-mode)
|
85
85
|
- [Extra configuration for CI server](#extra-configuration-for-ci-server)
|
86
86
|
- [Info about ENV variables](#info-about-env-variables)
|
87
|
-
- [
|
87
|
+
- [KNAPSACK_PRO_FIXED_TEST_SUITE_SPLIT (test suite split based on seed)](#knapsack_pro_fixed_test_suite_split-test-suite-split-based-on-seed)
|
88
88
|
- [Environment variables for debugging gem](#environment-variables-for-debugging-gem)
|
89
|
+
- [Required CI configuration if you use retry single failed CI node feature on your CI server when KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true (in Queue Mode) or KNAPSACK_PRO_FIXED_TEST_SUITE_SPLIT=true (in Regular Mode)](#required-ci-configuration-if-you-use-retry-single-failed-ci-node-feature-on-your-ci-server-when-knapsack_pro_fixed_queue_splittrue-in-queue-mode-or-knapsack_pro_fixed_test_suite_splittrue-in-regular-mode)
|
89
90
|
- [Passing arguments to rake task](#passing-arguments-to-rake-task)
|
90
91
|
- [Passing arguments to rspec](#passing-arguments-to-rspec)
|
91
92
|
- [Passing arguments to cucumber](#passing-arguments-to-cucumber)
|
@@ -551,6 +552,10 @@ There might be some cached test suite splits for git commits you have run in pas
|
|
551
552
|
|
552
553
|
Thanks to that when tests on one of your node failed you can retry the node with exactly the same subset of tests that were run on the node in the first place.
|
553
554
|
|
555
|
+
__IMPORTANT__: [Required CI configuration if you use retry single failed CI node feature on your CI server when KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true (in Queue Mode) or KNAPSACK_PRO_FIXED_TEST_SUITE_SPLIT=true (in Regular Mode)](#required-ci-configuration-if-you-use-retry-single-failed-ci-node-feature-on-your-ci-server-when-knapsack_pro_fixed_queue_splittrue-in-queue-mode-or-knapsack_pro_fixed_test_suite_splittrue-in-regular-mode)
|
556
|
+
|
557
|
+
Other useful info:
|
558
|
+
|
554
559
|
* Note when fixed queue split is enabled then you can run tests in a dynamic way only once for particular commit hash and a total number of nodes and for the same branch.
|
555
560
|
|
556
561
|
* When Knapsack Pro API server has already information about previous queue split then the information will be used. You will see at the beginning of the knapsack command the log with info that queue name is nil because it was not generated this time. You will get the list of all test files that were executed on the particular CI node in the past.
|
@@ -598,7 +603,7 @@ In case when you use other CI provider for instance [Jenkins](https://jenkins-ci
|
|
598
603
|
|
599
604
|
`KNAPSACK_PRO_CI_NODE_INDEX` - index of current CI node starts from 0. Second CI node should have `KNAPSACK_PRO_CI_NODE_INDEX=1`.
|
600
605
|
|
601
|
-
####
|
606
|
+
#### KNAPSACK_PRO_FIXED_TEST_SUITE_SPLIT (test suite split based on seed)
|
602
607
|
|
603
608
|
Note this is for knapsack_pro regular mode only.
|
604
609
|
|
@@ -609,13 +614,19 @@ Note this is for knapsack_pro regular mode only.
|
|
609
614
|
|
610
615
|
Thanks to that when tests on one of your node failed you can retry the node with exactly the same subset of tests that were run on the node in the first place.
|
611
616
|
|
612
|
-
|
613
|
-
|
617
|
+
__IMPORTANT__: [Required CI configuration if you use retry single failed CI node feature on your CI server when KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true (in Queue Mode) or KNAPSACK_PRO_FIXED_TEST_SUITE_SPLIT=true (in Regular Mode)](#required-ci-configuration-if-you-use-retry-single-failed-ci-node-feature-on-your-ci-server-when-knapsack_pro_fixed_queue_splittrue-in-queue-mode-or-knapsack_pro_fixed_test_suite_splittrue-in-regular-mode)
|
618
|
+
|
619
|
+
Other useful info:
|
614
620
|
|
615
|
-
|
616
|
-
|
621
|
+
* There is one edge case. When you run tests for the first time and there is no data collected about time execution of your tests then
|
622
|
+
we need to collect data to prepare the first test suite split. The second run of your tests will have fixed test suite split.
|
617
623
|
|
618
|
-
|
624
|
+
To compare if all your CI nodes are running based on the same test suite split seed you can check the value for seed in knapsack logging message
|
625
|
+
before your test starts. The message looks like:
|
626
|
+
|
627
|
+
```
|
628
|
+
[knapsack_pro] Test suite split seed: 8a606431-02a1-4766-9878-0ea42a07ad21
|
629
|
+
```
|
619
630
|
|
620
631
|
* `KNAPSACK_PRO_FIXED_TEST_SUITE_SPLIT=false`
|
621
632
|
|
@@ -642,6 +653,22 @@ This is only for maintainer of knapsack_pro gem. Not for the end users.
|
|
642
653
|
* When mode is `development` then endpoint is `http://api.knapsackpro.test:3000`.
|
643
654
|
* When mode is `test` then endpoint is `https://api-staging.knapsackpro.com`.
|
644
655
|
|
656
|
+
### Required CI configuration if you use retry single failed CI node feature on your CI server when KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true (in Queue Mode) or KNAPSACK_PRO_FIXED_TEST_SUITE_SPLIT=true (in Regular Mode)
|
657
|
+
|
658
|
+
Read below required configuration step if you use Queue Mode and you set [`KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true`](#knapsack_pro_fixed_queue_split-remember-queue-split-on-retry-ci-node) or you use Regular Mode which has by default [`KNAPSACK_PRO_FIXED_TEST_SUITE_SPLIT=true`](#knapsack_pro_fixed_test_suite_splite-test-suite-split-based-on-seed).
|
659
|
+
|
660
|
+
* __IMPORTANT:__ If you use __the feature to retry only a single failed CI node__ on your CI server (for instance you use Buildkite and you use [auto-retry](https://buildkite.com/docs/pipelines/command-step#retry-attributes) for the failed job) then you need to be aware of [a race condition that could happen](https://github.com/KnapsackPro/knapsack_pro-ruby/pull/100). knapsack_pro should not allow running tests in Fallback Mode in the case when the failed CI node was retried to prevent running the wrong set of tests.
|
661
|
+
|
662
|
+
knapsack_pro has built-in support for retries of failed parallel CI nodes for listed CI servers:
|
663
|
+
|
664
|
+
* Buildkite (knapsack_pro reads `BUILDKITE_RETRY_COUNT`)
|
665
|
+
|
666
|
+
knapsack_pro reads ENV vars for above CI servers and it disables Fallback Mode when failed parallel CI node can't connect with Knapsack Pro API. This way we prevent running the wrong set of tests by Fallback Mode on retried CI node.
|
667
|
+
|
668
|
+
If you use other CI server you need to manually configure your CI server to set `KNAPSACK_PRO_CI_NODE_RETRY_COUNT=1` only during retry CI node attempt. If `KNAPSACK_PRO_CI_NODE_RETRY_COUNT > 0` then knapsack_pro won't allow starting running tests in Fallback Mode and instead will raise error so a user can manually retry CI node later when a connection to Knapsack Pro API can be established.
|
669
|
+
|
670
|
+
If you cannot set `KNAPSACK_PRO_CI_NODE_RETRY_COUNT` only for retried CI node or it is not possible for your CI server then you can disable Fallback Mode completely `KNAPSACK_PRO_FALLBACK_MODE_ENABLED=false`.
|
671
|
+
|
645
672
|
### Passing arguments to rake task
|
646
673
|
|
647
674
|
#### Passing arguments to rspec
|
@@ -13,6 +13,17 @@ module KnapsackPro
|
|
13
13
|
if connection.success?
|
14
14
|
raise ArgumentError.new(response) if connection.errors?
|
15
15
|
prepare_test_files(response)
|
16
|
+
elsif !KnapsackPro::Config::Env.fallback_mode_enabled?
|
17
|
+
message = 'Fallback Mode was disabled with KNAPSACK_PRO_FALLBACK_MODE_ENABLED=false. Please restart this CI node to retry tests. Most likely Fallback Mode was disabled due to https://github.com/KnapsackPro/knapsack_pro-ruby#required-ci-configuration-if-you-use-retry-single-failed-ci-node-feature-on-your-ci-server-when-knapsack_pro_fixed_queue_splittrue-in-queue-mode-or-knapsack_pro_fixed_test_suite_splittrue-in-regular-mode'
|
18
|
+
KnapsackPro.logger.error(message)
|
19
|
+
raise message
|
20
|
+
elsif KnapsackPro::Config::Env.ci_node_retry_count > 0
|
21
|
+
message = 'knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://github.com/KnapsackPro/knapsack_pro-ruby#required-ci-configuration-if-you-use-retry-single-failed-ci-node-feature-on-your-ci-server-when-knapsack_pro_fixed_queue_splittrue-in-queue-mode-or-knapsack_pro_fixed_test_suite_splittrue-in-regular-mode'
|
22
|
+
unless KnapsackPro::Config::Env.fixed_test_suite_split?
|
23
|
+
message += ' Please ensure you have set KNAPSACK_PRO_FIXED_TEST_SUITE_SPLIT=true to allow Knapsack Pro API remember the recorded CI node tests so when you retry failed tests on the CI node then the same set of tests will be executed. See more https://github.com/KnapsackPro/knapsack_pro-ruby#knapsack_pro_fixed_test_suite_split-test-suite-split-based-on-seed'
|
24
|
+
end
|
25
|
+
KnapsackPro.logger.error(message)
|
26
|
+
raise message
|
16
27
|
else
|
17
28
|
KnapsackPro.logger.warn("Fallback mode started. We could not connect with Knapsack Pro API. Your tests will be executed based on directory names. Read more about fallback mode at https://github.com/KnapsackPro/knapsack_pro-ruby#what-happens-when-knapsack-pro-api-is-not-availablenot-reachable-temporarily")
|
18
29
|
fallback_test_files
|
@@ -28,6 +28,14 @@ module KnapsackPro
|
|
28
28
|
'missing-build-id'
|
29
29
|
end
|
30
30
|
|
31
|
+
def ci_node_retry_count
|
32
|
+
(
|
33
|
+
ENV['KNAPSACK_PRO_CI_NODE_RETRY_COUNT'] ||
|
34
|
+
ci_env_for(:node_retry_count) ||
|
35
|
+
0
|
36
|
+
).to_i
|
37
|
+
end
|
38
|
+
|
31
39
|
def commit_hash
|
32
40
|
ENV['KNAPSACK_PRO_COMMIT_HASH'] ||
|
33
41
|
ci_env_for(:commit_hash)
|
@@ -87,6 +95,14 @@ module KnapsackPro
|
|
87
95
|
ENV['KNAPSACK_PRO_SUBSET_QUEUE_ID'] || raise('Missing Subset Queue ID')
|
88
96
|
end
|
89
97
|
|
98
|
+
def fallback_mode_enabled
|
99
|
+
ENV.fetch('KNAPSACK_PRO_FALLBACK_MODE_ENABLED', true)
|
100
|
+
end
|
101
|
+
|
102
|
+
def fallback_mode_enabled?
|
103
|
+
fallback_mode_enabled.to_s == 'true'
|
104
|
+
end
|
105
|
+
|
90
106
|
def test_files_encrypted
|
91
107
|
ENV['KNAPSACK_PRO_TEST_FILES_ENCRYPTED']
|
92
108
|
end
|
@@ -135,10 +151,18 @@ module KnapsackPro
|
|
135
151
|
ENV.fetch('KNAPSACK_PRO_FIXED_TEST_SUITE_SPLIT', true)
|
136
152
|
end
|
137
153
|
|
154
|
+
def fixed_test_suite_split?
|
155
|
+
fixed_test_suite_split.to_s == 'true'
|
156
|
+
end
|
157
|
+
|
138
158
|
def fixed_queue_split
|
139
159
|
ENV.fetch('KNAPSACK_PRO_FIXED_QUEUE_SPLIT', false)
|
140
160
|
end
|
141
161
|
|
162
|
+
def fixed_queue_split?
|
163
|
+
fixed_queue_split.to_s == 'true'
|
164
|
+
end
|
165
|
+
|
142
166
|
def cucumber_queue_prefix
|
143
167
|
ENV.fetch('KNAPSACK_PRO_CUCUMBER_QUEUE_PREFIX', 'bundle exec')
|
144
168
|
end
|
@@ -16,6 +16,17 @@ module KnapsackPro
|
|
16
16
|
if connection.success?
|
17
17
|
raise ArgumentError.new(response) if connection.errors?
|
18
18
|
prepare_test_files(response)
|
19
|
+
elsif !KnapsackPro::Config::Env.fallback_mode_enabled?
|
20
|
+
message = 'Fallback Mode was disabled with KNAPSACK_PRO_FALLBACK_MODE_ENABLED=false. Please restart this CI node to retry tests. Most likely Fallback Mode was disabled due to https://github.com/KnapsackPro/knapsack_pro-ruby#required-ci-configuration-if-you-use-retry-single-failed-ci-node-feature-on-your-ci-server-when-knapsack_pro_fixed_queue_splittrue-in-queue-mode-or-knapsack_pro_fixed_test_suite_splittrue-in-regular-mode'
|
21
|
+
KnapsackPro.logger.error(message)
|
22
|
+
raise message
|
23
|
+
elsif KnapsackPro::Config::Env.ci_node_retry_count > 0
|
24
|
+
message = 'knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://github.com/KnapsackPro/knapsack_pro-ruby#required-ci-configuration-if-you-use-retry-single-failed-ci-node-feature-on-your-ci-server-when-knapsack_pro_fixed_queue_splittrue-in-queue-mode-or-knapsack_pro_fixed_test_suite_splittrue-in-regular-mode'
|
25
|
+
unless KnapsackPro::Config::Env.fixed_queue_split?
|
26
|
+
message += ' Please ensure you have set KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true to allow Knapsack Pro API remember the recorded CI node tests so when you retry failed tests on the CI node then the same set of tests will be executed. See more https://github.com/KnapsackPro/knapsack_pro-ruby#knapsack_pro_fixed_queue_split-remember-queue-split-on-retry-ci-node'
|
27
|
+
end
|
28
|
+
KnapsackPro.logger.error(message)
|
29
|
+
raise message
|
19
30
|
else
|
20
31
|
@fallback_activated = true
|
21
32
|
KnapsackPro.logger.warn("Fallback mode started. We could not connect with Knapsack Pro API. Your tests will be executed based on directory names. If other CI nodes were able to connect with Knapsack Pro API then you may notice that some of the test files will be executed twice across CI nodes. The most important thing is to guarantee each of test files is run at least once! Read more about fallback mode at https://github.com/KnapsackPro/knapsack_pro-ruby#what-happens-when-knapsack-pro-api-is-not-availablenot-reachable-temporarily")
|
data/lib/knapsack_pro/version.rb
CHANGED
@@ -75,16 +75,54 @@ describe KnapsackPro::Allocator do
|
|
75
75
|
let(:success?) { false }
|
76
76
|
let(:errors?) { false }
|
77
77
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
78
|
+
context 'when fallback mode is disabled' do
|
79
|
+
before do
|
80
|
+
expect(KnapsackPro::Config::Env).to receive(:fallback_mode_enabled?).and_return(false)
|
81
|
+
end
|
82
|
+
|
83
|
+
it do
|
84
|
+
expect { subject }.to raise_error(RuntimeError, 'Fallback Mode was disabled with KNAPSACK_PRO_FALLBACK_MODE_ENABLED=false. Please restart this CI node to retry tests. Most likely Fallback Mode was disabled due to https://github.com/KnapsackPro/knapsack_pro-ruby#required-ci-configuration-if-you-use-retry-single-failed-ci-node-feature-on-your-ci-server-when-knapsack_pro_fixed_queue_splittrue-in-queue-mode-or-knapsack_pro_fixed_test_suite_splittrue-in-regular-mode')
|
85
|
+
end
|
85
86
|
end
|
86
87
|
|
87
|
-
|
88
|
+
context 'when CI node retry count > 0' do
|
89
|
+
before do
|
90
|
+
expect(KnapsackPro::Config::Env).to receive(:ci_node_retry_count).and_return(1)
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'when fixed_test_suite_split=true' do
|
94
|
+
before do
|
95
|
+
expect(KnapsackPro::Config::Env).to receive(:fixed_test_suite_split).and_return(true)
|
96
|
+
end
|
97
|
+
|
98
|
+
it do
|
99
|
+
expect { subject }.to raise_error(RuntimeError, 'knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://github.com/KnapsackPro/knapsack_pro-ruby#required-ci-configuration-if-you-use-retry-single-failed-ci-node-feature-on-your-ci-server-when-knapsack_pro_fixed_queue_splittrue-in-queue-mode-or-knapsack_pro_fixed_test_suite_splittrue-in-regular-mode')
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context 'when fixed_test_suite_split=false' do
|
104
|
+
before do
|
105
|
+
expect(KnapsackPro::Config::Env).to receive(:fixed_test_suite_split).and_return(false)
|
106
|
+
end
|
107
|
+
|
108
|
+
it do
|
109
|
+
expect { subject }.to raise_error(RuntimeError, 'knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://github.com/KnapsackPro/knapsack_pro-ruby#required-ci-configuration-if-you-use-retry-single-failed-ci-node-feature-on-your-ci-server-when-knapsack_pro_fixed_queue_splittrue-in-queue-mode-or-knapsack_pro_fixed_test_suite_splittrue-in-regular-mode Please ensure you have set KNAPSACK_PRO_FIXED_TEST_SUITE_SPLIT=true to allow Knapsack Pro API remember the recorded CI node tests so when you retry failed tests on the CI node then the same set of tests will be executed. See more https://github.com/KnapsackPro/knapsack_pro-ruby#knapsack_pro_fixed_test_suite_split-test-suite-split-based-on-seed')
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'when fallback mode started' do
|
115
|
+
before do
|
116
|
+
test_flat_distributor = instance_double(KnapsackPro::TestFlatDistributor)
|
117
|
+
expect(KnapsackPro::TestFlatDistributor).to receive(:new).with(test_files, ci_node_total).and_return(test_flat_distributor)
|
118
|
+
expect(test_flat_distributor).to receive(:test_files_for_node).with(ci_node_index).and_return([
|
119
|
+
{ 'path' => 'c_spec.rb' },
|
120
|
+
{ 'path' => 'd_spec.rb' },
|
121
|
+
])
|
122
|
+
end
|
123
|
+
|
124
|
+
it { should eq ['c_spec.rb', 'd_spec.rb'] }
|
125
|
+
end
|
88
126
|
end
|
89
127
|
end
|
90
128
|
end
|
@@ -152,10 +152,10 @@ describe KnapsackPro::Client::Connection do
|
|
152
152
|
server_error = described_class::ServerError.new(parsed_response)
|
153
153
|
expect(logger).to receive(:warn).exactly(3).with(server_error.inspect)
|
154
154
|
|
155
|
-
expect(logger).to receive(:warn).with("Wait 2s and retry request to Knapsack Pro API.")
|
156
155
|
expect(logger).to receive(:warn).with("Wait 4s and retry request to Knapsack Pro API.")
|
157
|
-
expect(
|
156
|
+
expect(logger).to receive(:warn).with("Wait 8s and retry request to Knapsack Pro API.")
|
158
157
|
expect(Kernel).to receive(:sleep).with(4)
|
158
|
+
expect(Kernel).to receive(:sleep).with(8)
|
159
159
|
|
160
160
|
expect(subject).to eq(parsed_response)
|
161
161
|
|
@@ -2,6 +2,7 @@ describe KnapsackPro::Config::CI::Base do
|
|
2
2
|
its(:node_total) { should be nil }
|
3
3
|
its(:node_index) { should be nil }
|
4
4
|
its(:node_build_id) { should be nil }
|
5
|
+
its(:node_retry_count) { should be nil }
|
5
6
|
its(:commit_hash) { should be nil }
|
6
7
|
its(:branch) { should be nil }
|
7
8
|
its(:project_dir) { should be nil }
|
@@ -46,6 +46,19 @@ describe KnapsackPro::Config::CI::Buildkite do
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
+
describe '#node_retry_count' do
|
50
|
+
subject { described_class.new.node_retry_count }
|
51
|
+
|
52
|
+
context 'when environment exists' do
|
53
|
+
let(:env) { { 'BUILDKITE_RETRY_COUNT' => '1' } }
|
54
|
+
it { should eql '1' }
|
55
|
+
end
|
56
|
+
|
57
|
+
context "when environment doesn't exist" do
|
58
|
+
it { should be nil }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
49
62
|
describe '#commit_hash' do
|
50
63
|
subject { described_class.new.commit_hash }
|
51
64
|
|
@@ -77,6 +77,29 @@ describe KnapsackPro::Config::Env do
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
|
+
describe '.ci_node_retry_count' do
|
81
|
+
subject { described_class.ci_node_retry_count }
|
82
|
+
|
83
|
+
context 'when ENV exists' do
|
84
|
+
context 'when KNAPSACK_PRO_CI_NODE_RETRY_COUNT has value' do
|
85
|
+
before { stub_const("ENV", { 'KNAPSACK_PRO_CI_NODE_RETRY_COUNT' => '1' }) }
|
86
|
+
it { should eq 1 }
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'when CI environment has value' do
|
90
|
+
before do
|
91
|
+
expect(described_class).to receive(:ci_env_for).with(:node_retry_count).and_return('2')
|
92
|
+
end
|
93
|
+
|
94
|
+
it { should eq 2 }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "when ENV doesn't exist" do
|
99
|
+
it { should eq 0 }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
80
103
|
describe '.commit_hash' do
|
81
104
|
subject { described_class.commit_hash }
|
82
105
|
|
@@ -317,6 +340,32 @@ describe KnapsackPro::Config::Env do
|
|
317
340
|
end
|
318
341
|
end
|
319
342
|
|
343
|
+
describe '.fallback_mode_enabled' do
|
344
|
+
subject { described_class.fallback_mode_enabled }
|
345
|
+
|
346
|
+
context 'when ENV exists' do
|
347
|
+
before { stub_const("ENV", { 'KNAPSACK_PRO_FALLBACK_MODE_ENABLED' => 'false' }) }
|
348
|
+
it { should eq 'false' }
|
349
|
+
end
|
350
|
+
|
351
|
+
context "when ENV doesn't exist" do
|
352
|
+
it { should be true }
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
describe '.fallback_mode_enabled?' do
|
357
|
+
subject { described_class.fallback_mode_enabled? }
|
358
|
+
|
359
|
+
context 'when ENV exists' do
|
360
|
+
before { stub_const("ENV", { 'KNAPSACK_PRO_FALLBACK_MODE_ENABLED' => 'false' }) }
|
361
|
+
it { should be false }
|
362
|
+
end
|
363
|
+
|
364
|
+
context "when ENV doesn't exist" do
|
365
|
+
it { should be true }
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
320
369
|
describe '.test_files_encrypted' do
|
321
370
|
subject { described_class.test_files_encrypted }
|
322
371
|
|
@@ -490,6 +539,27 @@ describe KnapsackPro::Config::Env do
|
|
490
539
|
end
|
491
540
|
end
|
492
541
|
|
542
|
+
describe '.fixed_test_suite_split?' do
|
543
|
+
subject { described_class.fixed_test_suite_split? }
|
544
|
+
|
545
|
+
context 'when ENV exists' do
|
546
|
+
context 'when KNAPSACK_PRO_FIXED_TEST_SUITE_SPLIT=true' do
|
547
|
+
before { stub_const("ENV", { 'KNAPSACK_PRO_FIXED_TEST_SUITE_SPLIT' => 'true' }) }
|
548
|
+
it { should be true }
|
549
|
+
end
|
550
|
+
|
551
|
+
context 'when KNAPSACK_PRO_FIXED_TEST_SUITE_SPLIT=false' do
|
552
|
+
before { stub_const("ENV", { 'KNAPSACK_PRO_FIXED_TEST_SUITE_SPLIT' => 'false' }) }
|
553
|
+
it { should be false }
|
554
|
+
end
|
555
|
+
end
|
556
|
+
|
557
|
+
context "when ENV doesn't exist" do
|
558
|
+
before { stub_const("ENV", {}) }
|
559
|
+
it { should be true }
|
560
|
+
end
|
561
|
+
end
|
562
|
+
|
493
563
|
describe '.fixed_queue_split' do
|
494
564
|
subject { described_class.fixed_queue_split }
|
495
565
|
|
@@ -504,6 +574,27 @@ describe KnapsackPro::Config::Env do
|
|
504
574
|
end
|
505
575
|
end
|
506
576
|
|
577
|
+
describe '.fixed_queue_split?' do
|
578
|
+
subject { described_class.fixed_queue_split? }
|
579
|
+
|
580
|
+
context 'when ENV exists' do
|
581
|
+
context 'when KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true' do
|
582
|
+
before { stub_const("ENV", { 'KNAPSACK_PRO_FIXED_QUEUE_SPLIT' => 'true' }) }
|
583
|
+
it { should be true }
|
584
|
+
end
|
585
|
+
|
586
|
+
context 'when KNAPSACK_PRO_FIXED_QUEUE_SPLIT=false' do
|
587
|
+
before { stub_const("ENV", { 'KNAPSACK_PRO_FIXED_QUEUE_SPLIT' => 'false' }) }
|
588
|
+
it { should be false }
|
589
|
+
end
|
590
|
+
end
|
591
|
+
|
592
|
+
context "when ENV doesn't exist" do
|
593
|
+
before { stub_const("ENV", {}) }
|
594
|
+
it { should be false }
|
595
|
+
end
|
596
|
+
end
|
597
|
+
|
507
598
|
describe '.cucumber_queue_prefix' do
|
508
599
|
subject { described_class.cucumber_queue_prefix }
|
509
600
|
|
@@ -81,29 +81,66 @@ describe KnapsackPro::QueueAllocator do
|
|
81
81
|
let(:success?) { false }
|
82
82
|
let(:errors?) { false }
|
83
83
|
|
84
|
+
context 'when fallback mode is disabled' do
|
85
|
+
before do
|
86
|
+
expect(KnapsackPro::Config::Env).to receive(:fallback_mode_enabled?).and_return(false)
|
87
|
+
end
|
84
88
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
expect(test_flat_distributor).to receive(:test_files_for_node).with(ci_node_index).and_return([
|
89
|
-
{ 'path' => 'c_spec.rb' },
|
90
|
-
{ 'path' => 'd_spec.rb' },
|
91
|
-
])
|
89
|
+
it do
|
90
|
+
expect { subject }.to raise_error(RuntimeError, 'Fallback Mode was disabled with KNAPSACK_PRO_FALLBACK_MODE_ENABLED=false. Please restart this CI node to retry tests. Most likely Fallback Mode was disabled due to https://github.com/KnapsackPro/knapsack_pro-ruby#required-ci-configuration-if-you-use-retry-single-failed-ci-node-feature-on-your-ci-server-when-knapsack_pro_fixed_queue_splittrue-in-queue-mode-or-knapsack_pro_fixed_test_suite_splittrue-in-regular-mode')
|
91
|
+
end
|
92
92
|
end
|
93
93
|
|
94
|
-
context 'when
|
95
|
-
|
94
|
+
context 'when CI node retry count > 0' do
|
95
|
+
before do
|
96
|
+
expect(KnapsackPro::Config::Env).to receive(:ci_node_retry_count).and_return(1)
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'when fixed_queue_split=true' do
|
100
|
+
before do
|
101
|
+
expect(KnapsackPro::Config::Env).to receive(:fixed_queue_split).and_return(true)
|
102
|
+
end
|
103
|
+
|
104
|
+
it do
|
105
|
+
expect { subject }.to raise_error(RuntimeError, 'knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://github.com/KnapsackPro/knapsack_pro-ruby#required-ci-configuration-if-you-use-retry-single-failed-ci-node-feature-on-your-ci-server-when-knapsack_pro_fixed_queue_splittrue-in-queue-mode-or-knapsack_pro_fixed_test_suite_splittrue-in-regular-mode')
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'when fixed_queue_split=false' do
|
110
|
+
before do
|
111
|
+
expect(KnapsackPro::Config::Env).to receive(:fixed_queue_split).and_return(false)
|
112
|
+
end
|
96
113
|
|
97
|
-
|
98
|
-
|
114
|
+
it do
|
115
|
+
expect { subject }.to raise_error(RuntimeError, 'knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://github.com/KnapsackPro/knapsack_pro-ruby#required-ci-configuration-if-you-use-retry-single-failed-ci-node-feature-on-your-ci-server-when-knapsack_pro_fixed_queue_splittrue-in-queue-mode-or-knapsack_pro_fixed_test_suite_splittrue-in-regular-mode Please ensure you have set KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true to allow Knapsack Pro API remember the recorded CI node tests so when you retry failed tests on the CI node then the same set of tests will be executed. See more https://github.com/KnapsackPro/knapsack_pro-ruby#knapsack_pro_fixed_queue_split-remember-queue-split-on-retry-ci-node')
|
116
|
+
end
|
99
117
|
end
|
100
118
|
end
|
101
119
|
|
102
|
-
context 'when
|
103
|
-
|
120
|
+
context 'when fallback mode started' do
|
121
|
+
before do
|
122
|
+
test_flat_distributor = instance_double(KnapsackPro::TestFlatDistributor)
|
123
|
+
expect(KnapsackPro::TestFlatDistributor).to receive(:new).with(test_files, ci_node_total).and_return(test_flat_distributor)
|
124
|
+
expect(test_flat_distributor).to receive(:test_files_for_node).with(ci_node_index).and_return([
|
125
|
+
{ 'path' => 'c_spec.rb' },
|
126
|
+
{ 'path' => 'd_spec.rb' },
|
127
|
+
])
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'when no test files were executed yet' do
|
131
|
+
let(:executed_test_files) { [] }
|
132
|
+
|
133
|
+
it 'enables fallback mode and returns fallback test files' do
|
134
|
+
expect(subject).to eq ['c_spec.rb', 'd_spec.rb']
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'when test files were already executed' do
|
139
|
+
let(:executed_test_files) { ['c_spec.rb', 'additional_executed_spec.rb'] }
|
104
140
|
|
105
|
-
|
106
|
-
|
141
|
+
it 'enables fallback mode and returns fallback test files' do
|
142
|
+
expect(subject).to eq ['d_spec.rb']
|
143
|
+
end
|
107
144
|
end
|
108
145
|
end
|
109
146
|
end
|
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: 1.
|
4
|
+
version: 1.18.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ArturT
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-03-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|