knapsack_pro 0.47.0 → 0.48.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
  SHA1:
3
- metadata.gz: 134f144c4fb7cd10705a73ccf858439ee3d9e907
4
- data.tar.gz: 4edada383933812bbb739d7f471a28b21530492a
3
+ metadata.gz: 151892af0770ba792636180322d5d2f84a57f15e
4
+ data.tar.gz: ee84887be53f55c9675dfdf0734372cf1bccfd06
5
5
  SHA512:
6
- metadata.gz: 6ab40a05f0201ce49cc2c184741d31327e2a2ae2317b1895e7e6cba258c53062aa3bb9b8032141c9476f9ed20bb617c2c9fd55c84250cb7eaeec58c63d7d66c9
7
- data.tar.gz: 482638d2f37f274b7cc3cc512d8dc24a8e5a6dd562e35c31cc8d373d8b3690cea0a23d1965844ce060d742b3e3493b3557d4118b7b2baef14b77f385efefd3f9
6
+ metadata.gz: 89a7c9aa3fdb0ab8607b9550500629b059ad7a1e423eaca112d1f8f5d20e2e5c6af85bbd318d236e1f5ee6b2b2f00c9524dc7060cf71e5a9f93dfd0edb9abab7
7
+ data.tar.gz: 139a5250785423e6d8af9a9961859c606ef68bfcf87657b02436d891b144b05da5b3bdd646bb05ab92084541f6678f27c8ac94c8fcb94871bae31517e8ec3c1b
data/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  * TODO
4
4
 
5
+ ### 0.48.0
6
+
7
+ * Fallback mode for Queue Mode when Knapsack Pro API doesn't work.
8
+
9
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/49
10
+
11
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v0.47.0...v0.48.0
12
+
5
13
  ### 0.47.0
6
14
 
7
15
  * Add in Queue Mode the RSpec summary with info about examples, failures and pending tests.
data/README.md CHANGED
@@ -1014,11 +1014,11 @@ There are a few ways to reproduce tests executed on CI node in your development
1014
1014
 
1015
1015
  ##### for knapack_pro regular mode
1016
1016
 
1017
- knapack_pro gem will retry requests to Knapsack Pro API multiple times every few seconds til it switch to fallback behaviour and it will split test files across CI nodes based on popular test directory names.
1017
+ knapack_pro gem will retry requests to Knapsack Pro API multiple times every few seconds til it switch to fallback behavior and it will split test files across CI nodes based on popular test directory names. When knapack_pro starts fallback mode then you will see a warning in the output.
1018
1018
 
1019
1019
  ##### for knapsack_pro queue mode
1020
1020
 
1021
- knapack_pro gem will retry requests to Knapsack Pro API multiple times every few seconds til it fails.
1021
+ knapack_pro gem will retry requests to Knapsack Pro API multiple times every few seconds till it switches to fallback behavior and it will split test files across CI nodes based on popular test directory names. Note that if one of CI nodes will lose connection to Knapsack Pro API but other not then you may see that some of the test files will be executed on multiple CI nodes. Fallback mode guarantees each of test files is run at least once across CI nodes. Thanks to that we know if the whole test suite is green or not. When knapack_pro starts fallback mode then you will see a warning in the output.
1022
1022
 
1023
1023
  #### How can I change log level?
1024
1024
 
@@ -14,6 +14,7 @@ module KnapsackPro
14
14
  raise ArgumentError.new(response) if connection.errors?
15
15
  prepare_test_files(response)
16
16
  else
17
+ 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")
17
18
  fallback_test_files
18
19
  end
19
20
  end
@@ -1,7 +1,7 @@
1
1
  module KnapsackPro
2
2
  module Client
3
3
  class Connection
4
- TIMEOUT = 30
4
+ TIMEOUT = 15
5
5
  REQUEST_RETRY_TIMEBOX = 2
6
6
 
7
7
  def initialize(action)
@@ -103,7 +103,7 @@ module KnapsackPro
103
103
  rescue Errno::ECONNREFUSED, EOFError, SocketError, Net::OpenTimeout, Net::ReadTimeout => e
104
104
  logger.warn(e.inspect)
105
105
  retries += 1
106
- if retries < 5
106
+ if retries < 3
107
107
  wait = retries * REQUEST_RETRY_TIMEBOX
108
108
  logger.warn("Wait #{wait}s and retry request to Knapsack Pro API.")
109
109
  sleep wait
@@ -8,7 +8,8 @@ module KnapsackPro
8
8
  @repository_adapter = args.fetch(:repository_adapter)
9
9
  end
10
10
 
11
- def test_file_paths(can_initialize_queue)
11
+ def test_file_paths(can_initialize_queue, executed_test_files)
12
+ return [] if @fallback_activated
12
13
  action = build_action(can_initialize_queue)
13
14
  connection = KnapsackPro::Client::Connection.new(action)
14
15
  response = connection.call
@@ -16,7 +17,9 @@ module KnapsackPro
16
17
  raise ArgumentError.new(response) if connection.errors?
17
18
  prepare_test_files(response)
18
19
  else
19
- raise ArgumentError.new("Couldn't connect with Knapsack Pro API. Response: #{response}")
20
+ @fallback_activated = true
21
+ 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")
22
+ fallback_test_files(executed_test_files)
20
23
  end
21
24
  end
22
25
 
@@ -52,5 +55,11 @@ module KnapsackPro
52
55
  decrypted_test_files = KnapsackPro::Crypto::Decryptor.call(test_files, response['test_files'])
53
56
  KnapsackPro::TestFilePresenter.paths(decrypted_test_files)
54
57
  end
58
+
59
+ def fallback_test_files(executed_test_files)
60
+ test_flat_distributor = KnapsackPro::TestFlatDistributor.new(test_files, ci_node_total)
61
+ test_files_for_node_index = test_flat_distributor.test_files_for_node(ci_node_index)
62
+ KnapsackPro::TestFilePresenter.paths(test_files_for_node_index) - executed_test_files
63
+ end
55
64
  end
56
65
  end
@@ -57,7 +57,9 @@ module KnapsackPro
57
57
  response = connection.call
58
58
  if connection.success?
59
59
  raise ArgumentError.new(response) if connection.errors?
60
- KnapsackPro.logger.debug('Saved time execution report on API server.')
60
+ KnapsackPro.logger.debug('Saved time execution report on Knapsack Pro API server.')
61
+ else
62
+ KnapsackPro.logger.warn('Time execution report was not saved on Knapsack Pro API server due to connection problem.')
61
63
  end
62
64
  end
63
65
 
@@ -17,7 +17,8 @@ module KnapsackPro
17
17
 
18
18
  def test_file_paths(args)
19
19
  can_initialize_queue = args.fetch(:can_initialize_queue)
20
- allocator.test_file_paths(can_initialize_queue)
20
+ executed_test_files = args.fetch(:executed_test_files)
21
+ allocator.test_file_paths(can_initialize_queue, executed_test_files)
21
22
  end
22
23
 
23
24
  def test_dir
@@ -25,7 +25,10 @@ module KnapsackPro
25
25
  end
26
26
 
27
27
  def self.run_tests(runner, can_initialize_queue, args, exitstatus, all_test_file_paths)
28
- test_file_paths = runner.test_file_paths(can_initialize_queue: can_initialize_queue)
28
+ test_file_paths = runner.test_file_paths(
29
+ can_initialize_queue: can_initialize_queue,
30
+ executed_test_files: all_test_file_paths
31
+ )
29
32
 
30
33
  if test_file_paths.empty?
31
34
  unless all_test_file_paths.empty?
@@ -1,3 +1,3 @@
1
1
  module KnapsackPro
2
- VERSION = '0.47.0'
2
+ VERSION = '0.48.0'
3
3
  end
@@ -30,8 +30,8 @@ describe KnapsackPro::Client::Connection do
30
30
  expect(Net::HTTP).to receive(:new).with('api.knapsackpro.dev', 3000).and_return(http)
31
31
 
32
32
  expect(http).to receive(:use_ssl=).with(false)
33
- expect(http).to receive(:open_timeout=).with(30)
34
- expect(http).to receive(:read_timeout=).with(30)
33
+ expect(http).to receive(:open_timeout=).with(15)
34
+ expect(http).to receive(:read_timeout=).with(15)
35
35
 
36
36
  header = { 'X-Request-Id' => 'fake-uuid' }
37
37
  http_response = instance_double(Net::HTTPOK, body: body, header: header)
@@ -17,9 +17,10 @@ describe KnapsackPro::QueueAllocator do
17
17
 
18
18
  describe '#test_file_paths' do
19
19
  let(:can_initialize_queue) { double }
20
+ let(:executed_test_files) { [] }
20
21
  let(:response) { double }
21
22
 
22
- subject { queue_allocator.test_file_paths(can_initialize_queue) }
23
+ subject { queue_allocator.test_file_paths(can_initialize_queue, executed_test_files) }
23
24
 
24
25
  before do
25
26
  encrypted_test_files = double
@@ -80,8 +81,30 @@ describe KnapsackPro::QueueAllocator do
80
81
  let(:success?) { false }
81
82
  let(:errors?) { false }
82
83
 
83
- it do
84
- expect { subject }.to raise_error("Couldn't connect with Knapsack Pro API. Response: #{response}")
84
+
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
+ ])
92
+ end
93
+
94
+ context 'when no test files were executed yet' do
95
+ let(:executed_test_files) { [] }
96
+
97
+ it 'enables fallback mode and returns fallback test files' do
98
+ expect(subject).to eq ['c_spec.rb', 'd_spec.rb']
99
+ end
100
+ end
101
+
102
+ context 'when test files were already executed' do
103
+ let(:executed_test_files) { ['c_spec.rb', 'additional_executed_spec.rb'] }
104
+
105
+ it 'enables fallback mode and returns fallback test files' do
106
+ expect(subject).to eq ['d_spec.rb']
107
+ end
85
108
  end
86
109
  end
87
110
  end
@@ -132,7 +132,7 @@ describe KnapsackPro::Report do
132
132
  it do
133
133
  logger = instance_double(Logger)
134
134
  expect(KnapsackPro).to receive(:logger).and_return(logger)
135
- expect(logger).to receive(:debug).with('Saved time execution report on API server.')
135
+ expect(logger).to receive(:debug).with('Saved time execution report on Knapsack Pro API server.')
136
136
  subject
137
137
  end
138
138
  end
@@ -142,7 +142,12 @@ describe KnapsackPro::Report do
142
142
  let(:success?) { false }
143
143
  let(:errors?) { nil }
144
144
 
145
- it { subject }
145
+ it do
146
+ logger = instance_double(Logger)
147
+ expect(KnapsackPro).to receive(:logger).and_return(logger)
148
+ expect(logger).to receive(:warn).with('Time execution report was not saved on Knapsack Pro API server due to connection problem.')
149
+ subject
150
+ end
146
151
  end
147
152
  end
148
153
 
@@ -33,11 +33,17 @@ describe KnapsackPro::Runners::Queue::BaseRunner do
33
33
 
34
34
  context 'when can_initialize_queue flag has value' do
35
35
  let(:can_initialize_queue) { double }
36
- let(:args) { { can_initialize_queue: can_initialize_queue } }
36
+ let(:executed_test_files) { double }
37
+ let(:args) do
38
+ {
39
+ can_initialize_queue: can_initialize_queue,
40
+ executed_test_files: executed_test_files,
41
+ }
42
+ end
37
43
  let(:test_file_paths) { double }
38
44
 
39
45
  before do
40
- expect(allocator).to receive(:test_file_paths).and_return(test_file_paths)
46
+ expect(allocator).to receive(:test_file_paths).with(can_initialize_queue, executed_test_files).and_return(test_file_paths)
41
47
  end
42
48
 
43
49
  it { should eq test_file_paths }
@@ -74,7 +74,7 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
74
74
  subject { described_class.run_tests(runner, can_initialize_queue, args, exitstatus, []) }
75
75
 
76
76
  before do
77
- expect(runner).to receive(:test_file_paths).with(can_initialize_queue: can_initialize_queue).and_return(test_file_paths)
77
+ expect(runner).to receive(:test_file_paths).with(can_initialize_queue: can_initialize_queue, executed_test_files: []).and_return(test_file_paths)
78
78
  end
79
79
 
80
80
  context 'when test files exist' do
@@ -102,7 +102,7 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
102
102
  expect(KnapsackPro::Hooks::Queue).to receive(:call_after_subset_queue)
103
103
 
104
104
  # second call of run_tests because of recursion
105
- expect(runner).to receive(:test_file_paths).with(can_initialize_queue: false).and_return([])
105
+ expect(runner).to receive(:test_file_paths).with(can_initialize_queue: false, executed_test_files: ['a_spec.rb', 'b_spec.rb']).and_return([])
106
106
  end
107
107
 
108
108
  context 'when exit code is zero' do
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.47.0
4
+ version: 0.48.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-08-13 00:00:00.000000000 Z
11
+ date: 2017-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake