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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 86141c7add4d4159437103ebcb72460961d1a2b7f69493f6c517bcd3160785a1
4
- data.tar.gz: 257c9d52f6d1a43c1f92ad0e48eda4d3ec5753d684068a63ea19dcb46484f792
3
+ metadata.gz: 030ea46e8f4a421824a682b4286f7e362d0eec9a3bc50cd113e703391a51e40f
4
+ data.tar.gz: 47ab9de263fce5a5576ac2d1054fc66ea15b7982f01595b3ac237534deede7cf
5
5
  SHA512:
6
- metadata.gz: 2ebc1c14cb430ca87497d946bfeb20d4a2c47f9c1f563663aeb0062192c453de84ab1455a6e109f870eed4a44e8b83a2757391e48c3338feebeccb01cce6ef3e
7
- data.tar.gz: f407c9d6566e5cfe73a0198519e513a4d7aa1e55b2371bc3ca1aad6a5818526d16f41b8a1a69a50b3c4277d0272862ec5e59a9e8d5577597222c9d048ae6bb02
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
- - [KNAPSACK_PRO_FIXED_TEST_SUITE_SPLITE (test suite split based on seed)](#knapsack_pro_fixed_test_suite_splite-test-suite-split-based-on-seed)
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
- #### KNAPSACK_PRO_FIXED_TEST_SUITE_SPLITE (test suite split based on seed)
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
- 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
613
- 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
+ __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
- 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
616
- before your test starts. The message looks like:
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
- [knapsack_pro] Test suite split seed: 8a606431-02a1-4766-9878-0ea42a07ad21
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
@@ -5,7 +5,7 @@ module KnapsackPro
5
5
 
6
6
  TIMEOUT = 15
7
7
  MAX_RETRY = 3
8
- REQUEST_RETRY_TIMEBOX = 2
8
+ REQUEST_RETRY_TIMEBOX = 4
9
9
 
10
10
  def initialize(action)
11
11
  @action = action
@@ -11,6 +11,9 @@ module KnapsackPro
11
11
  def node_build_id
12
12
  end
13
13
 
14
+ def node_retry_count
15
+ end
16
+
14
17
  def commit_hash
15
18
  end
16
19
 
@@ -14,6 +14,10 @@ module KnapsackPro
14
14
  ENV['BUILDKITE_BUILD_NUMBER']
15
15
  end
16
16
 
17
+ def node_retry_count
18
+ ENV['BUILDKITE_RETRY_COUNT']
19
+ end
20
+
17
21
  def commit_hash
18
22
  ENV['BUILDKITE_COMMIT']
19
23
  end
@@ -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")
@@ -1,3 +1,3 @@
1
1
  module KnapsackPro
2
- VERSION = '1.17.0'
2
+ VERSION = '1.18.0'
3
3
  end
@@ -75,16 +75,54 @@ describe KnapsackPro::Allocator do
75
75
  let(:success?) { false }
76
76
  let(:errors?) { false }
77
77
 
78
- before do
79
- test_flat_distributor = instance_double(KnapsackPro::TestFlatDistributor)
80
- expect(KnapsackPro::TestFlatDistributor).to receive(:new).with(test_files, ci_node_total).and_return(test_flat_distributor)
81
- expect(test_flat_distributor).to receive(:test_files_for_node).with(ci_node_index).and_return([
82
- { 'path' => 'c_spec.rb' },
83
- { 'path' => 'd_spec.rb' },
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
- it { should eq ['c_spec.rb', 'd_spec.rb'] }
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(Kernel).to receive(:sleep).with(2)
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
- before do
86
- test_flat_distributor = instance_double(KnapsackPro::TestFlatDistributor)
87
- expect(KnapsackPro::TestFlatDistributor).to receive(:new).with(test_files, ci_node_total).and_return(test_flat_distributor)
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 no test files were executed yet' do
95
- let(:executed_test_files) { [] }
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
- it 'enables fallback mode and returns fallback test files' do
98
- expect(subject).to eq ['c_spec.rb', 'd_spec.rb']
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 test files were already executed' do
103
- let(:executed_test_files) { ['c_spec.rb', 'additional_executed_spec.rb'] }
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
- it 'enables fallback mode and returns fallback test files' do
106
- expect(subject).to eq ['d_spec.rb']
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.17.0
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-02-06 00:00:00.000000000 Z
11
+ date: 2020-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake