knapsack_pro 2.6.0 → 2.10.1

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: b4167b51e7f0af27a7d1482efb7a6c019f9aa99dd849f9488e47c4a33b5bd943
4
- data.tar.gz: fff1d5e557813cd2829298c422d4ffae857e047d27aa001cf746a516270d9259
3
+ metadata.gz: 9b0ef524a80bd3e88c8c12c631880e644734fc8be8253bd4aa8d9c58fcc2dc48
4
+ data.tar.gz: 7fa53878c1cbf1fb421f2637c98db03133654df1abf07d058179b2516a01da49
5
5
  SHA512:
6
- metadata.gz: fd9b442c01b5b58b295e6fc36d3879ddbf97b8770d4f96243f594f225ef3f73e23e75555cfba7adb6439dd5afa39a38ea756e5758628eed54c9305a12bd8b716
7
- data.tar.gz: 7401c76f35ce8485a7dc8dc5742514803c8a045d7f431899b32aaa4795433b723b68e554386b7670abb367b1f9dfde2be9e4bc8b661ead354dbab366b56c1705
6
+ metadata.gz: 6faf1e8b52b3d93c424945e560dba8caeda53a208b002c370b2e050f31aafbffd66856e06e7475043891923ef5315f40a3f6ee9e58fad243eb91fc12bde47ad7
7
+ data.tar.gz: c4767bf21996e966db844779e177b10086626b6a8bfd7ffd67333842aa2376814234b54a00a945b70a676d481c70bea07ae74480c3f2359e5ab7588490194eca
@@ -1,5 +1,45 @@
1
1
  # Change Log
2
2
 
3
+ ### 2.10.1
4
+
5
+ * Fix RSpec split by test examples feature broken by lazy generating of JSON report with test example ids
6
+
7
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/135
8
+
9
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v2.10.0...v2.10.1
10
+
11
+ ### 2.10.0
12
+
13
+ * Add support for an attempt to connect to existing Queue on API side to reduce slow requests number
14
+
15
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/133
16
+
17
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v2.9.0...v2.10.0
18
+
19
+ ### 2.9.0
20
+
21
+ * Use `Process.clock_gettime` to measure track execution time
22
+
23
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/132
24
+
25
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v2.8.0...v2.9.0
26
+
27
+ ### 2.8.0
28
+
29
+ * More actionable error message when RSpec split by examples is not working due to RSpec dry-run failure
30
+
31
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/130
32
+
33
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v2.7.0...v2.8.0
34
+
35
+ ### 2.7.0
36
+
37
+ * Add support for env var `KNAPSACK_PRO_TEST_FILE_LIST_SOURCE_FILE` to allow accepting file containing test files to run
38
+
39
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/129
40
+
41
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v2.6.0...v2.7.0
42
+
3
43
  ### 2.6.0
4
44
 
5
45
  * Improve logger to show failed requests URL and when retry will happen
data/README.md CHANGED
@@ -50,7 +50,7 @@ We keep this old FAQ in README to not break old links spread across the web. You
50
50
 
51
51
  # Requirements
52
52
 
53
- `>= Ruby 2.0.0`
53
+ `>= Ruby 2.1.0`
54
54
 
55
55
  # Table of Contents
56
56
 
@@ -3082,7 +3082,9 @@ The test file pattern and exclude pattern support any glob pattern handled by [`
3082
3082
 
3083
3083
  #### How to run a specific list of test files or only some tests from test file?
3084
3084
 
3085
- :information_source: If you don't want to use the pattern [`KNAPSACK_PRO_TEST_FILE_PATTERN`](#how-can-i-run-tests-from-multiple-directories) to define a list of tests to run then read below.
3085
+ :information_source: If you don't want to use the pattern [`KNAPSACK_PRO_TEST_FILE_PATTERN`](#how-can-i-run-tests-from-multiple-directories) to define a list of tests to run then read below two options.
3086
+
3087
+ **Option 1:**
3086
3088
 
3087
3089
  If you want to run a specific list of test files that are explicitly defined by you or auto-generated by some kind of script you created then please use:
3088
3090
 
@@ -3090,7 +3092,24 @@ If you want to run a specific list of test files that are explicitly defined by
3090
3092
 
3091
3093
  Note `KNAPSACK_PRO_TEST_FILE_LIST` must be a list of test files comma separated. You can provide line number for tests inside of spec file in case of RSpec (this way you can run only one test or a group of tests from RSpec spec file). You can provide the same file a few times with different test line number.
3092
3094
 
3093
- Note when you set `KNAPSACK_PRO_TEST_FILE_LIST` then below environment variables are ignored:
3095
+ **Option 2:**
3096
+
3097
+ Similarly, you can also provide a source file containing the test files that you would like to run. For example:
3098
+ `KNAPSACK_PRO_TEST_FILE_LIST_SOURCE_FILE=spec/fixtures/test_file_list_source_file.txt`
3099
+ And the content of the source file can be any of the format below:
3100
+
3101
+ ```
3102
+ ./spec/test1_spec.rb
3103
+ spec/test2_spec.rb[1]
3104
+ ./spec/test3_spec.rb[1:2:3:4]
3105
+ ./spec/test4_spec.rb:4
3106
+ ./spec/test4_spec.rb:5
3107
+ ```
3108
+
3109
+ > Note that each of the line must be ending with `\n` the new line.
3110
+
3111
+ Note when you set `KNAPSACK_PRO_TEST_FILE_LIST` or `KNAPSACK_PRO_TEST_FILE_LIST_SOURCE_FILE` then below environment variables are ignored:
3112
+
3094
3113
  * `KNAPSACK_PRO_TEST_FILE_PATTERN`
3095
3114
  * `KNAPSACK_PRO_TEST_FILE_EXCLUDE_PATTERN`
3096
3115
 
@@ -3,11 +3,14 @@ module KnapsackPro
3
3
  module API
4
4
  module V1
5
5
  class Queues < Base
6
+ CODE_ATTEMPT_CONNECT_TO_QUEUE_FAILED = 'ATTEMPT_CONNECT_TO_QUEUE_FAILED'
7
+
6
8
  class << self
7
9
  def queue(args)
8
10
  request_hash = {
9
11
  :fixed_queue_split => KnapsackPro::Config::Env.fixed_queue_split,
10
12
  :can_initialize_queue => args.fetch(:can_initialize_queue),
13
+ :attempt_connect_to_queue => args.fetch(:attempt_connect_to_queue),
11
14
  :commit_hash => args.fetch(:commit_hash),
12
15
  :branch => args.fetch(:branch),
13
16
  :node_total => args.fetch(:node_total),
@@ -15,7 +18,7 @@ module KnapsackPro
15
18
  :node_build_id => KnapsackPro::Config::Env.ci_node_build_id,
16
19
  }
17
20
 
18
- if request_hash[:can_initialize_queue]
21
+ if request_hash[:can_initialize_queue] && !request_hash[:attempt_connect_to_queue]
19
22
  request_hash.merge!({
20
23
  :test_files => args.fetch(:test_files)
21
24
  })
@@ -25,6 +25,11 @@ module KnapsackPro
25
25
  !!(response_body && (response_body['errors'] || response_body['error']))
26
26
  end
27
27
 
28
+ def api_code
29
+ return unless response_body
30
+ response_body['code']
31
+ end
32
+
28
33
  def server_error?
29
34
  status = http_response.code.to_i
30
35
  status >= 500 && status < 600
@@ -74,6 +74,10 @@ module KnapsackPro
74
74
  ENV['KNAPSACK_PRO_TEST_FILE_LIST']
75
75
  end
76
76
 
77
+ def test_file_list_source_file
78
+ ENV['KNAPSACK_PRO_TEST_FILE_LIST_SOURCE_FILE']
79
+ end
80
+
77
81
  def test_dir
78
82
  ENV['KNAPSACK_PRO_TEST_DIR']
79
83
  end
@@ -11,9 +11,18 @@ module KnapsackPro
11
11
 
12
12
  def test_file_paths(can_initialize_queue, executed_test_files)
13
13
  return [] if @fallback_activated
14
- action = build_action(can_initialize_queue)
14
+ action = build_action(can_initialize_queue, attempt_connect_to_queue: can_initialize_queue)
15
15
  connection = KnapsackPro::Client::Connection.new(action)
16
16
  response = connection.call
17
+
18
+ # when attempt to connect to existing queue on API side failed because queue does not exist yet
19
+ if can_initialize_queue && connection.success? && connection.api_code == KnapsackPro::Client::API::V1::Queues::CODE_ATTEMPT_CONNECT_TO_QUEUE_FAILED
20
+ # make attempt to initalize a new queue on API side
21
+ action = build_action(can_initialize_queue, attempt_connect_to_queue: false)
22
+ connection = KnapsackPro::Client::Connection.new(action)
23
+ response = connection.call
24
+ end
25
+
17
26
  if connection.success?
18
27
  raise ArgumentError.new(response) if connection.errors?
19
28
  prepare_test_files(response)
@@ -52,15 +61,22 @@ module KnapsackPro
52
61
  KnapsackPro::Crypto::BranchEncryptor.call(repository_adapter.branch)
53
62
  end
54
63
 
55
- def build_action(can_initialize_queue)
64
+ def build_action(can_initialize_queue, attempt_connect_to_queue:)
65
+ # read test files from disk only when needed because it can be slow operation
66
+ test_files =
67
+ if can_initialize_queue && !attempt_connect_to_queue
68
+ encrypted_test_files
69
+ end
70
+
56
71
  KnapsackPro::Client::API::V1::Queues.queue(
57
72
  can_initialize_queue: can_initialize_queue,
73
+ attempt_connect_to_queue: attempt_connect_to_queue,
58
74
  commit_hash: repository_adapter.commit_hash,
59
75
  branch: encrypted_branch,
60
76
  node_total: ci_node_total,
61
77
  node_index: ci_node_index,
62
78
  node_build_id: ci_node_build_id,
63
- test_files: encrypted_test_files,
79
+ test_files: test_files,
64
80
  )
65
81
  end
66
82
 
@@ -33,7 +33,16 @@ module KnapsackPro
33
33
  options = ::RSpec::Core::ConfigurationOptions.new(cli_args)
34
34
  exit_code = ::RSpec::Core::Runner.new(options).run($stderr, $stdout)
35
35
  if exit_code != 0
36
- raise 'There was problem to generate test examples for test suite'
36
+ debug_cmd = ([
37
+ 'bundle exec rspec',
38
+ ] + cli_args).join(' ')
39
+
40
+ KnapsackPro.logger.error('-'*10 + ' START of actionable error message ' + '-'*50)
41
+ KnapsackPro.logger.error('There was a problem while generating test examples for the slow test files using the RSpec dry-run flag. To reproduce the error triggered by the RSpec, please try to run below command (this way, you can find out what is causing the error):')
42
+ KnapsackPro.logger.error(debug_cmd)
43
+ KnapsackPro.logger.error('-'*10 + ' END of actionable error message ' + '-'*50)
44
+
45
+ raise 'There was a problem while generating test examples for the slow test files. Please read actionable error message above.'
37
46
  end
38
47
  end
39
48
 
@@ -63,6 +63,10 @@ module KnapsackPro
63
63
  return KnapsackPro::Config::Env.test_file_list.split(',').map(&:strip)
64
64
  end
65
65
 
66
+ if test_file_list_enabled && KnapsackPro::Config::Env.test_file_list_source_file
67
+ return File.read(KnapsackPro::Config::Env.test_file_list_source_file).split(/\n/)
68
+ end
69
+
66
70
  test_file_paths = Dir.glob(test_file_pattern).uniq
67
71
 
68
72
  excluded_test_file_paths =
@@ -90,11 +90,7 @@ module KnapsackPro
90
90
  end
91
91
 
92
92
  def now_without_mock_time
93
- if defined?(Timecop)
94
- Time.now_without_mock_time
95
- else
96
- Time.raw_now
97
- end
93
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
98
94
  end
99
95
  end
100
96
  end
@@ -1,3 +1,3 @@
1
1
  module KnapsackPro
2
- VERSION = '2.6.0'
2
+ VERSION = '2.10.1'
3
3
  end
@@ -0,0 +1,6 @@
1
+ ./spec/test1_spec.rb
2
+ spec/test2_spec.rb[1]
3
+ ./spec/test3_spec.rb[1:2:3:4]
4
+ ./spec/test4_spec.rb:4
5
+ ./spec/test4_spec.rb:5
6
+
@@ -11,6 +11,7 @@ describe KnapsackPro::Client::API::V1::Queues do
11
11
  subject do
12
12
  described_class.queue(
13
13
  can_initialize_queue: can_initialize_queue,
14
+ attempt_connect_to_queue: attempt_connect_to_queue,
14
15
  commit_hash: commit_hash,
15
16
  branch: branch,
16
17
  node_total: node_total,
@@ -24,8 +25,33 @@ describe KnapsackPro::Client::API::V1::Queues do
24
25
  expect(KnapsackPro::Config::Env).to receive(:ci_node_build_id).and_return(node_build_id)
25
26
  end
26
27
 
27
- context 'when can_initialize_queue=true' do
28
+ context 'when can_initialize_queue=true and attempt_connect_to_queue=true' do
28
29
  let(:can_initialize_queue) { true }
30
+ let(:attempt_connect_to_queue) { true }
31
+
32
+ it 'does not send test_files among other params' do
33
+ action = double
34
+ expect(KnapsackPro::Client::API::Action).to receive(:new).with({
35
+ endpoint_path: '/v1/queues/queue',
36
+ http_method: :post,
37
+ request_hash: {
38
+ fixed_queue_split: fixed_queue_split,
39
+ can_initialize_queue: can_initialize_queue,
40
+ attempt_connect_to_queue: attempt_connect_to_queue,
41
+ commit_hash: commit_hash,
42
+ branch: branch,
43
+ node_total: node_total,
44
+ node_index: node_index,
45
+ node_build_id: node_build_id,
46
+ }
47
+ }).and_return(action)
48
+ expect(subject).to eq action
49
+ end
50
+ end
51
+
52
+ context 'when can_initialize_queue=true and attempt_connect_to_queue=false' do
53
+ let(:can_initialize_queue) { true }
54
+ let(:attempt_connect_to_queue) { false }
29
55
 
30
56
  it 'sends test_files among other params' do
31
57
  action = double
@@ -35,6 +61,7 @@ describe KnapsackPro::Client::API::V1::Queues do
35
61
  request_hash: {
36
62
  fixed_queue_split: fixed_queue_split,
37
63
  can_initialize_queue: can_initialize_queue,
64
+ attempt_connect_to_queue: attempt_connect_to_queue,
38
65
  commit_hash: commit_hash,
39
66
  branch: branch,
40
67
  node_total: node_total,
@@ -47,8 +74,9 @@ describe KnapsackPro::Client::API::V1::Queues do
47
74
  end
48
75
  end
49
76
 
50
- context 'when can_initialize_queue=false' do
77
+ context 'when can_initialize_queue=false and attempt_connect_to_queue=false' do
51
78
  let(:can_initialize_queue) { false }
79
+ let(:attempt_connect_to_queue) { false }
52
80
 
53
81
  it 'does not send test_files among other params' do
54
82
  action = double
@@ -58,6 +86,7 @@ describe KnapsackPro::Client::API::V1::Queues do
58
86
  request_hash: {
59
87
  fixed_queue_split: fixed_queue_split,
60
88
  can_initialize_queue: can_initialize_queue,
89
+ attempt_connect_to_queue: attempt_connect_to_queue,
61
90
  commit_hash: commit_hash,
62
91
  branch: branch,
63
92
  node_total: node_total,
@@ -238,6 +238,20 @@ describe KnapsackPro::Config::Env do
238
238
  end
239
239
  end
240
240
 
241
+ describe '.test_file_list_source_file' do
242
+ subject { described_class.test_file_list_source_file }
243
+
244
+ context 'when ENV exists' do
245
+ let(:test_file_list_source_file) { 'spec/fixtures/test_file_list_source_file.txt' }
246
+ before { stub_const("ENV", { 'KNAPSACK_PRO_TEST_FILE_LIST_SOURCE_FILE' => test_file_list_source_file }) }
247
+ it { should eq test_file_list_source_file }
248
+ end
249
+
250
+ context "when ENV doesn't exist" do
251
+ it { should be_nil }
252
+ end
253
+ end
254
+
241
255
  describe '.test_dir' do
242
256
  subject { described_class.test_dir }
243
257
 
@@ -18,71 +18,13 @@ describe KnapsackPro::QueueAllocator do
18
18
  end
19
19
 
20
20
  describe '#test_file_paths' do
21
- let(:can_initialize_queue) { double }
22
21
  let(:executed_test_files) { [] }
23
22
  let(:response) { double }
23
+ let(:api_code) { nil }
24
24
 
25
25
  subject { queue_allocator.test_file_paths(can_initialize_queue, executed_test_files) }
26
26
 
27
- before do
28
- encrypted_test_files = double
29
- expect(KnapsackPro::Crypto::Encryptor).to receive(:call).with(fast_and_slow_test_files_to_run).and_return(encrypted_test_files)
30
-
31
- encrypted_branch = double
32
- expect(KnapsackPro::Crypto::BranchEncryptor).to receive(:call).with(repository_adapter.branch).and_return(encrypted_branch)
33
-
34
- action = double
35
- expect(KnapsackPro::Client::API::V1::Queues).to receive(:queue).with(
36
- can_initialize_queue: can_initialize_queue,
37
- commit_hash: repository_adapter.commit_hash,
38
- branch: encrypted_branch,
39
- node_total: ci_node_total,
40
- node_index: ci_node_index,
41
- node_build_id: ci_node_build_id,
42
- test_files: encrypted_test_files,
43
- ).and_return(action)
44
-
45
- connection = instance_double(KnapsackPro::Client::Connection,
46
- call: response,
47
- success?: success?,
48
- errors?: errors?)
49
- expect(KnapsackPro::Client::Connection).to receive(:new).with(action).and_return(connection)
50
- end
51
-
52
- context 'when successful request to API' do
53
- let(:success?) { true }
54
-
55
- context 'when response has errors' do
56
- let(:errors?) { true }
57
-
58
- it do
59
- expect { subject }.to raise_error(ArgumentError)
60
- end
61
- end
62
-
63
- context 'when response has no errors' do
64
- let(:errors?) { false }
65
- let(:response) do
66
- {
67
- 'test_files' => [
68
- { 'path' => 'a_spec.rb' },
69
- { 'path' => 'b_spec.rb' },
70
- ]
71
- }
72
- end
73
-
74
- before do
75
- expect(KnapsackPro::Crypto::Decryptor).to receive(:call).with(fast_and_slow_test_files_to_run, response['test_files']).and_call_original
76
- end
77
-
78
- it { should eq ['a_spec.rb', 'b_spec.rb'] }
79
- end
80
- end
81
-
82
- context 'when not successful request to API' do
83
- let(:success?) { false }
84
- let(:errors?) { false }
85
-
27
+ shared_examples_for 'when connection to API failed (fallback mode)' do
86
28
  context 'when fallback mode is disabled' do
87
29
  before do
88
30
  expect(KnapsackPro::Config::Env).to receive(:fallback_mode_enabled?).and_return(false)
@@ -146,5 +88,220 @@ describe KnapsackPro::QueueAllocator do
146
88
  end
147
89
  end
148
90
  end
91
+
92
+ context 'when can_initialize_queue=true' do
93
+ let(:can_initialize_queue) { true }
94
+
95
+ before do
96
+ encrypted_branch = double
97
+ expect(KnapsackPro::Crypto::BranchEncryptor).to receive(:call).with(repository_adapter.branch).and_return(encrypted_branch)
98
+
99
+ action = double
100
+ expect(KnapsackPro::Client::API::V1::Queues).to receive(:queue).with(
101
+ can_initialize_queue: can_initialize_queue,
102
+ attempt_connect_to_queue: true, # when can_initialize_queue=true then expect attempt_connect_to_queue=true
103
+ commit_hash: repository_adapter.commit_hash,
104
+ branch: encrypted_branch,
105
+ node_total: ci_node_total,
106
+ node_index: ci_node_index,
107
+ node_build_id: ci_node_build_id,
108
+ test_files: nil, # when attempt_connect_to_queue=true then expect test_files is nil to make fast request to API
109
+ ).and_return(action)
110
+
111
+ connection = instance_double(KnapsackPro::Client::Connection,
112
+ call: response,
113
+ success?: success?,
114
+ errors?: errors?,
115
+ api_code: api_code)
116
+ expect(KnapsackPro::Client::Connection).to receive(:new).with(action).and_return(connection)
117
+ end
118
+
119
+ context 'when successful request to API' do
120
+ let(:success?) { true }
121
+
122
+ context 'when response has errors' do
123
+ let(:errors?) { true }
124
+
125
+ it do
126
+ expect { subject }.to raise_error(ArgumentError)
127
+ end
128
+ end
129
+
130
+ context 'when response has no errors' do
131
+ let(:errors?) { false }
132
+
133
+ context 'when response returns test files (successful attempt to connect to queue already existing on the API side)' do
134
+ let(:response) do
135
+ {
136
+ 'test_files' => [
137
+ { 'path' => 'a_spec.rb' },
138
+ { 'path' => 'b_spec.rb' },
139
+ ]
140
+ }
141
+ end
142
+
143
+ before do
144
+ expect(KnapsackPro::Crypto::Decryptor).to receive(:call).with(fast_and_slow_test_files_to_run, response['test_files']).and_call_original
145
+ end
146
+
147
+ it { should eq ['a_spec.rb', 'b_spec.rb'] }
148
+ end
149
+
150
+ context 'when response has code=ATTEMPT_CONNECT_TO_QUEUE_FAILED' do
151
+ let(:response) do
152
+ { 'code' => 'ATTEMPT_CONNECT_TO_QUEUE_FAILED' }
153
+ end
154
+ let(:api_code) { 'ATTEMPT_CONNECT_TO_QUEUE_FAILED' }
155
+
156
+ before do
157
+ encrypted_branch = double
158
+ expect(KnapsackPro::Crypto::BranchEncryptor).to receive(:call).with(repository_adapter.branch).and_return(encrypted_branch)
159
+
160
+ encrypted_test_files = double
161
+ expect(KnapsackPro::Crypto::Encryptor).to receive(:call).with(fast_and_slow_test_files_to_run).and_return(encrypted_test_files)
162
+
163
+ # 2nd request is no more an attempt to connect to queue.
164
+ # We want to try to initalize a new queue so we will also send list of test files from disk.
165
+ action = double
166
+ expect(KnapsackPro::Client::API::V1::Queues).to receive(:queue).with(
167
+ can_initialize_queue: can_initialize_queue,
168
+ attempt_connect_to_queue: false,
169
+ commit_hash: repository_adapter.commit_hash,
170
+ branch: encrypted_branch,
171
+ node_total: ci_node_total,
172
+ node_index: ci_node_index,
173
+ node_build_id: ci_node_build_id,
174
+ test_files: encrypted_test_files,
175
+ ).and_return(action)
176
+
177
+ connection = instance_double(KnapsackPro::Client::Connection,
178
+ call: response2,
179
+ success?: response2_success?,
180
+ errors?: response2_errors?,
181
+ api_code: nil)
182
+ expect(KnapsackPro::Client::Connection).to receive(:new).with(action).and_return(connection)
183
+ end
184
+
185
+ context 'when successful 2nd request to API' do
186
+ let(:response2_success?) { true }
187
+
188
+ context 'when 2nd response has errors' do
189
+ let(:response2_errors?) { true }
190
+ let(:response2) { nil }
191
+
192
+ it do
193
+ expect { subject }.to raise_error(ArgumentError)
194
+ end
195
+ end
196
+
197
+ context 'when 2nd response has no errors' do
198
+ let(:response2_errors?) { false }
199
+
200
+ context 'when 2nd response returns test files (successful attempt to connect to queue already existing on the API side)' do
201
+ let(:response2) do
202
+ {
203
+ 'test_files' => [
204
+ { 'path' => 'a_spec.rb' },
205
+ { 'path' => 'b_spec.rb' },
206
+ ]
207
+ }
208
+ end
209
+
210
+ before do
211
+ expect(KnapsackPro::Crypto::Decryptor).to receive(:call).with(fast_and_slow_test_files_to_run, response2['test_files']).and_call_original
212
+ end
213
+
214
+ it { should eq ['a_spec.rb', 'b_spec.rb'] }
215
+ end
216
+ end
217
+ end
218
+
219
+ context 'when not successful 2nd request to API' do
220
+ let(:response2_success?) { false }
221
+ let(:response2_errors?) { false }
222
+ let(:response2) { nil }
223
+
224
+ it_behaves_like 'when connection to API failed (fallback mode)'
225
+ end
226
+ end
227
+ end
228
+ end
229
+
230
+ context 'when not successful request to API' do
231
+ let(:success?) { false }
232
+ let(:errors?) { false }
233
+
234
+ it_behaves_like 'when connection to API failed (fallback mode)'
235
+ end
236
+ end
237
+
238
+ context 'when can_initialize_queue=false' do
239
+ let(:can_initialize_queue) { false }
240
+ let(:api_code) { nil }
241
+
242
+ before do
243
+ encrypted_branch = double
244
+ expect(KnapsackPro::Crypto::BranchEncryptor).to receive(:call).with(repository_adapter.branch).and_return(encrypted_branch)
245
+
246
+ action = double
247
+ expect(KnapsackPro::Client::API::V1::Queues).to receive(:queue).with(
248
+ can_initialize_queue: can_initialize_queue,
249
+ attempt_connect_to_queue: false, # when can_initialize_queue=false then expect attempt_connect_to_queue=false
250
+ commit_hash: repository_adapter.commit_hash,
251
+ branch: encrypted_branch,
252
+ node_total: ci_node_total,
253
+ node_index: ci_node_index,
254
+ node_build_id: ci_node_build_id,
255
+ test_files: nil, # when can_initialize_queue=false then expect test_files is nil to make fast request to API
256
+ ).and_return(action)
257
+
258
+ connection = instance_double(KnapsackPro::Client::Connection,
259
+ call: response,
260
+ success?: success?,
261
+ errors?: errors?,
262
+ api_code: api_code)
263
+ expect(KnapsackPro::Client::Connection).to receive(:new).with(action).and_return(connection)
264
+ end
265
+
266
+ context 'when successful request to API' do
267
+ let(:success?) { true }
268
+
269
+ context 'when response has errors' do
270
+ let(:errors?) { true }
271
+
272
+ it do
273
+ expect { subject }.to raise_error(ArgumentError)
274
+ end
275
+ end
276
+
277
+ context 'when response has no errors' do
278
+ let(:errors?) { false }
279
+
280
+ context 'when response returns test files (successful attempt to connect to queue already existing on the API side)' do
281
+ let(:response) do
282
+ {
283
+ 'test_files' => [
284
+ { 'path' => 'a_spec.rb' },
285
+ { 'path' => 'b_spec.rb' },
286
+ ]
287
+ }
288
+ end
289
+
290
+ before do
291
+ expect(KnapsackPro::Crypto::Decryptor).to receive(:call).with(fast_and_slow_test_files_to_run, response['test_files']).and_call_original
292
+ end
293
+
294
+ it { should eq ['a_spec.rb', 'b_spec.rb'] }
295
+ end
296
+ end
297
+ end
298
+
299
+ context 'when not successful request to API' do
300
+ let(:success?) { false }
301
+ let(:errors?) { false }
302
+
303
+ it_behaves_like 'when connection to API failed (fallback mode)'
304
+ end
305
+ end
149
306
  end
150
307
  end
@@ -67,7 +67,7 @@ describe KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector do
67
67
  let(:exit_code) { 1 }
68
68
 
69
69
  it do
70
- expect { subject }.to raise_error(RuntimeError, 'There was problem to generate test examples for test suite')
70
+ expect { subject }.to raise_error(RuntimeError, 'There was a problem while generating test examples for the slow test files. Please read actionable error message above.')
71
71
  end
72
72
  end
73
73
  end
@@ -154,5 +154,23 @@ describe KnapsackPro::TestFileFinder do
154
154
  end
155
155
  end
156
156
  end
157
+
158
+ context 'when KNAPSACK_PRO_TEST_FILE_LIST_SOURCE_FILE is defined' do
159
+ let(:test_file_list_source_file) { 'spec/fixtures/test_file_list_source_file.txt' }
160
+
161
+ before do
162
+ stub_const("ENV", { 'KNAPSACK_PRO_TEST_FILE_LIST_SOURCE_FILE' => test_file_list_source_file })
163
+ end
164
+
165
+ it do
166
+ expect(subject).to eq([
167
+ { 'path' => 'spec/test1_spec.rb' },
168
+ { 'path' => 'spec/test2_spec.rb[1]' },
169
+ { 'path' => 'spec/test3_spec.rb[1:2:3:4]' },
170
+ { 'path' => 'spec/test4_spec.rb:4' },
171
+ { 'path' => 'spec/test4_spec.rb:5' },
172
+ ])
173
+ end
174
+ end
157
175
  end
158
176
  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: 2.6.0
4
+ version: 2.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - ArturT
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-23 00:00:00.000000000 Z
11
+ date: 2020-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -308,6 +308,7 @@ files:
308
308
  - lib/tasks/salt.rake
309
309
  - lib/tasks/spinach.rake
310
310
  - lib/tasks/test_unit.rake
311
+ - spec/fixtures/test_file_list_source_file.txt
311
312
  - spec/fixtures/vcr_cassettes/api/v1/build_distributions/subset/invalid_test_suite_token.yml
312
313
  - spec/fixtures/vcr_cassettes/api/v1/build_distributions/subset/success.yml
313
314
  - spec/fixtures/vcr_cassettes/api/v1/build_subsets/create/invalid_test_suite_token.yml
@@ -428,6 +429,7 @@ specification_version: 4
428
429
  summary: Knapsack Pro splits tests across parallel CI nodes and ensures each parallel
429
430
  job finish work at a similar time.
430
431
  test_files:
432
+ - spec/fixtures/test_file_list_source_file.txt
431
433
  - spec/fixtures/vcr_cassettes/api/v1/build_distributions/subset/invalid_test_suite_token.yml
432
434
  - spec/fixtures/vcr_cassettes/api/v1/build_distributions/subset/success.yml
433
435
  - spec/fixtures/vcr_cassettes/api/v1/build_subsets/create/invalid_test_suite_token.yml