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 +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +2 -2
- data/lib/knapsack_pro/allocator.rb +1 -0
- data/lib/knapsack_pro/client/connection.rb +2 -2
- data/lib/knapsack_pro/queue_allocator.rb +11 -2
- data/lib/knapsack_pro/report.rb +3 -1
- data/lib/knapsack_pro/runners/queue/base_runner.rb +2 -1
- data/lib/knapsack_pro/runners/queue/rspec_runner.rb +4 -1
- data/lib/knapsack_pro/version.rb +1 -1
- data/spec/knapsack_pro/client/connection_spec.rb +2 -2
- data/spec/knapsack_pro/queue_allocator_spec.rb +26 -3
- data/spec/knapsack_pro/report_spec.rb +7 -2
- data/spec/knapsack_pro/runners/queue/base_runner_spec.rb +8 -2
- data/spec/knapsack_pro/runners/queue/rspec_runner_spec.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 151892af0770ba792636180322d5d2f84a57f15e
|
4
|
+
data.tar.gz: ee84887be53f55c9675dfdf0734372cf1bccfd06
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
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 =
|
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 <
|
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
|
-
|
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
|
data/lib/knapsack_pro/report.rb
CHANGED
@@ -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
|
-
|
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(
|
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?
|
data/lib/knapsack_pro/version.rb
CHANGED
@@ -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(
|
34
|
-
expect(http).to receive(:read_timeout=).with(
|
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
|
-
|
84
|
-
|
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
|
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(:
|
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.
|
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-
|
11
|
+
date: 2017-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|