knapsack_pro 1.9.0 → 1.10.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 +12 -0
- data/README.md +10 -1
- data/lib/knapsack_pro/report.rb +10 -4
- data/lib/knapsack_pro/runners/queue/minitest_runner.rb +1 -1
- data/lib/knapsack_pro/runners/queue/rspec_runner.rb +1 -1
- data/lib/knapsack_pro/tracker.rb +25 -5
- data/lib/knapsack_pro/version.rb +1 -1
- data/spec/knapsack_pro/report_spec.rb +71 -19
- data/spec/knapsack_pro/runners/queue/minitest_runner_spec.rb +1 -1
- data/spec/knapsack_pro/runners/queue/rspec_runner_spec.rb +2 -2
- data/spec/knapsack_pro/tracker_spec.rb +6 -6
- 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: 15d64502a63c7087b4d8793ad780d0f7454d2414c93c0da46967e20620578fe0
|
4
|
+
data.tar.gz: 88addd61d85b84f2fc043ff17e554564d95b40be262fe55a51714efa5ae4f719
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 67664f1170199a4f5f6cb2fbabdfd15fbebd2c73d04a0646bacdc20411411722f5b7b0946d8a76417150fcbe60211b13b97f27a09ca10840a44caaea8beccb0a
|
7
|
+
data.tar.gz: d835f28e6af4885f42e6daa218caace7401f1ab9e406d1f8a4c06af6f20ad671e37b8501e35aceaea41183d94d56feec462badb86747053843b7a1957ec64867
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
### 1.10.0
|
4
|
+
|
5
|
+
* Logs error on lost info about recorded timing for test files due to missing json files in Queue Mode
|
6
|
+
|
7
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/pull/83
|
8
|
+
|
9
|
+
* Fix bug: default test file time should not be added to measured time
|
10
|
+
|
11
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/pull/84
|
12
|
+
|
13
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v1.9.0...v1.10.0
|
14
|
+
|
3
15
|
### 1.9.0
|
4
16
|
|
5
17
|
* Reduce data transfer and speed up usage of Knapsack Pro API for Queue Mode
|
data/README.md
CHANGED
@@ -1414,7 +1414,7 @@ end
|
|
1414
1414
|
##### Why when I use Queue Mode for RSpec then my tests fail?
|
1415
1415
|
|
1416
1416
|
knapsack_pro Queue Mode uses `RSpec::Core::Runner` feature that allows [running specs multiple times with different runner options in the same process](https://relishapp.com/rspec/rspec-core/docs/running-specs-multiple-times-with-different-runner-options-in-the-same-process).
|
1417
|
-
Thanks to that we can run subset of test suite pulled from Knapsack Pro API work queue. This allows dynamic allocation of your tests across CI nodes without reloading whole Ruby/Rails application for each run of test suite subset
|
1417
|
+
Thanks to that we can run subset of test suite pulled from Knapsack Pro API work queue. This allows dynamic allocation of your tests across CI nodes without reloading whole Ruby/Rails application for each run of test suite subset.
|
1418
1418
|
|
1419
1419
|
If you have custom things that are not common in how typical RSpec spec looks like then the RSpec feature won't be able to handle it between test suite subset runs.
|
1420
1420
|
In that case you need to resolve failed tests in a way that allows RSpec to run the tests. Feel free to [ask me for help](https://knapsackpro.com/contact).
|
@@ -1540,6 +1540,15 @@ If you go to [user dashboard](https://knapsackpro.com/dashboard) and open `Build
|
|
1540
1540
|
If you go to [user dashboard](https://knapsackpro.com/dashboard) and open `Build metrics` for your API token and you open CI build for your last git commit you should see there info about collected time execution data from all CI nodes. If you see all test files have 0.1s time execution then please ensure:
|
1541
1541
|
|
1542
1542
|
* you don't clean up `tmp` directory in your tests (for instance in RSpec hooks like `before` or `after`) so knapsack_pro can publish measured time execution data to Knapsack Pro API server. knapsack_pro Queue Mode saves temporary files with collected time execution data in `your_rails_project/tmp/knapsack_pro/queue/`.
|
1543
|
+
* please ensure you have in your `rails_helper.rb` or `spec_helper.rb` line:
|
1544
|
+
|
1545
|
+
```ruby
|
1546
|
+
require 'knapsack_pro'
|
1547
|
+
|
1548
|
+
# CUSTOM_CONFIG_GOES_HERE
|
1549
|
+
|
1550
|
+
KnapsackPro::Adapters::RSpecAdapter.bind
|
1551
|
+
```
|
1543
1552
|
|
1544
1553
|
The 0.1s is a default time execution used when test file is an empty file or its content are all pending tests.
|
1545
1554
|
|
data/lib/knapsack_pro/report.rb
CHANGED
@@ -27,7 +27,7 @@ module KnapsackPro
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
def self.save_node_queue_to_api
|
30
|
+
def self.save_node_queue_to_api(executed_test_files_count)
|
31
31
|
test_files = []
|
32
32
|
Dir.glob("#{queue_path}/*.json").each do |file|
|
33
33
|
report = JSON.parse(File.read(file))
|
@@ -35,9 +35,15 @@ module KnapsackPro
|
|
35
35
|
end
|
36
36
|
|
37
37
|
if test_files.empty?
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
if executed_test_files_count == 0
|
39
|
+
KnapsackPro.logger.warn("No test files were executed on this CI node.")
|
40
|
+
KnapsackPro.logger.debug("When you use knapsack_pro queue mode then probably reason might be that CI node was started after the test files from the queue were already executed by other CI nodes. That is why this CI node has no test files to execute.")
|
41
|
+
KnapsackPro.logger.debug("Another reason might be when your CI node failed in a way that prevented knapsack_pro to save time execution data to Knapsack Pro API and you have just tried to retry failed CI node but instead you got no test files to execute. In that case knapsack_pro don't know what testes should be executed here.")
|
42
|
+
end
|
43
|
+
|
44
|
+
if executed_test_files_count > 0
|
45
|
+
KnapsackPro.logger.error("#{executed_test_files_count} test files were executed on this CI node but the recorded time of it was lost. Probably you have a code (i.e. RSpec hooks) that clears tmp directory in your project. Please ensure you do not remove the content of tmp/knapsack_pro/queue/ directory between tests run. Another reason might be that you forgot to add Knapsack::Adapters::RspecAdapter.bind in your rails_helper.rb or spec_helper.rb. Please follow the installation guide again: https://docs.knapsackpro.com/integration/")
|
46
|
+
end
|
41
47
|
end
|
42
48
|
|
43
49
|
create_build_subset(test_files)
|
data/lib/knapsack_pro/tracker.rb
CHANGED
@@ -2,6 +2,10 @@ module KnapsackPro
|
|
2
2
|
class Tracker
|
3
3
|
include Singleton
|
4
4
|
|
5
|
+
# when test file is pending, empty with no tests or has syntax error then assume time execution
|
6
|
+
# to better allocate it in Queue Mode for future CI build runs
|
7
|
+
DEFAULT_TEST_FILE_TIME = 0.1 # seconds
|
8
|
+
|
5
9
|
attr_reader :global_time_since_beginning, :global_time, :test_files_with_time
|
6
10
|
attr_writer :current_test_path
|
7
11
|
|
@@ -36,16 +40,19 @@ module KnapsackPro
|
|
36
40
|
# in case when the test file will not be run
|
37
41
|
# due syntax error or being pending.
|
38
42
|
# The time is required by Knapsack Pro API.
|
39
|
-
@test_files_with_time[test_file_path] =
|
43
|
+
@test_files_with_time[test_file_path] = {
|
44
|
+
time_execution: DEFAULT_TEST_FILE_TIME,
|
45
|
+
measured_time: false,
|
46
|
+
}
|
40
47
|
end
|
41
48
|
end
|
42
49
|
|
43
50
|
def to_a
|
44
51
|
test_files = []
|
45
|
-
@test_files_with_time.each do |path,
|
52
|
+
@test_files_with_time.each do |path, hash|
|
46
53
|
test_files << {
|
47
54
|
path: path,
|
48
|
-
time_execution: time_execution
|
55
|
+
time_execution: hash[:time_execution]
|
49
56
|
}
|
50
57
|
end
|
51
58
|
test_files
|
@@ -65,8 +72,21 @@ module KnapsackPro
|
|
65
72
|
end
|
66
73
|
|
67
74
|
def update_test_file_time(execution_time)
|
68
|
-
@test_files_with_time[current_test_path] ||=
|
69
|
-
|
75
|
+
@test_files_with_time[current_test_path] ||= {
|
76
|
+
time_execution: 0,
|
77
|
+
measured_time: false,
|
78
|
+
}
|
79
|
+
|
80
|
+
hash = @test_files_with_time[current_test_path]
|
81
|
+
|
82
|
+
if hash[:measured_time]
|
83
|
+
hash[:time_execution] += execution_time
|
84
|
+
else
|
85
|
+
hash[:time_execution] = execution_time
|
86
|
+
hash[:measured_time] = true
|
87
|
+
end
|
88
|
+
|
89
|
+
@test_files_with_time[current_test_path] = hash
|
70
90
|
end
|
71
91
|
|
72
92
|
def now_without_mock_time
|
data/lib/knapsack_pro/version.rb
CHANGED
@@ -43,33 +43,85 @@ describe KnapsackPro::Report do
|
|
43
43
|
end
|
44
44
|
|
45
45
|
describe '.save_node_queue_to_api' do
|
46
|
-
|
47
|
-
|
46
|
+
context 'when json files with recorded time exist for executed test files' do
|
47
|
+
let(:json_test_file_a_path) { double }
|
48
|
+
let(:json_test_file_a) { [{ 'path' => 'a_spec.rb' }] }
|
48
49
|
|
49
|
-
|
50
|
-
|
50
|
+
let(:json_test_file_b_path) { double }
|
51
|
+
let(:json_test_file_b) { [{ 'path' => 'b_spec.rb' }] }
|
51
52
|
|
52
|
-
|
53
|
+
let(:executed_test_files_count) { 2 }
|
53
54
|
|
54
|
-
|
55
|
-
queue_id = 'fake-queue-id'
|
56
|
-
expect(KnapsackPro::Config::Env).to receive(:queue_id).and_return(queue_id)
|
55
|
+
subject { described_class.save_node_queue_to_api(executed_test_files_count) }
|
57
56
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
57
|
+
before do
|
58
|
+
queue_id = 'fake-queue-id'
|
59
|
+
expect(KnapsackPro::Config::Env).to receive(:queue_id).and_return(queue_id)
|
60
|
+
|
61
|
+
expect(Dir).to receive(:glob).with('tmp/knapsack_pro/queue/fake-queue-id/*.json').and_return([
|
62
|
+
json_test_file_a_path,
|
63
|
+
json_test_file_b_path
|
64
|
+
])
|
65
|
+
|
66
|
+
expect(File).to receive(:read).with(json_test_file_a_path).and_return(json_test_file_a.to_json)
|
67
|
+
expect(File).to receive(:read).with(json_test_file_b_path).and_return(json_test_file_b.to_json)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'creates build subset for 2 recorded test files timing' do
|
71
|
+
expect(described_class).to receive(:create_build_subset).with(
|
72
|
+
json_test_file_a + json_test_file_b
|
73
|
+
)
|
62
74
|
|
63
|
-
|
64
|
-
|
75
|
+
subject
|
76
|
+
end
|
65
77
|
end
|
66
78
|
|
67
|
-
|
68
|
-
|
69
|
-
json_test_file_a + json_test_file_b
|
70
|
-
)
|
79
|
+
context 'when json files with recorded time does not exist for executed test files' do
|
80
|
+
let(:executed_test_files_count) { 2 }
|
71
81
|
|
72
|
-
subject
|
82
|
+
subject { described_class.save_node_queue_to_api(executed_test_files_count) }
|
83
|
+
|
84
|
+
before do
|
85
|
+
queue_id = 'fake-queue-id'
|
86
|
+
expect(KnapsackPro::Config::Env).to receive(:queue_id).and_return(queue_id)
|
87
|
+
|
88
|
+
expect(Dir).to receive(:glob).with('tmp/knapsack_pro/queue/fake-queue-id/*.json').and_return([])
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'logs error on lost info about recorded timing for test files due missing json files AND creates empty build subset' do
|
92
|
+
logger = instance_double(Logger)
|
93
|
+
expect(KnapsackPro).to receive(:logger).and_return(logger)
|
94
|
+
expect(logger).to receive(:error).with('2 test files were executed on this CI node but the recorded time of it was lost. Probably you have a code (i.e. RSpec hooks) that clears tmp directory in your project. Please ensure you do not remove the content of tmp/knapsack_pro/queue/ directory between tests run. Another reason might be that you forgot to add Knapsack::Adapters::RspecAdapter.bind in your rails_helper.rb or spec_helper.rb. Please follow the installation guide again: https://docs.knapsackpro.com/integration/')
|
95
|
+
|
96
|
+
expect(described_class).to receive(:create_build_subset).with([])
|
97
|
+
|
98
|
+
subject
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'when json files with recorded time does not exist AND no executed test files' do
|
103
|
+
let(:executed_test_files_count) { 0 }
|
104
|
+
|
105
|
+
subject { described_class.save_node_queue_to_api(executed_test_files_count) }
|
106
|
+
|
107
|
+
before do
|
108
|
+
queue_id = 'fake-queue-id'
|
109
|
+
expect(KnapsackPro::Config::Env).to receive(:queue_id).and_return(queue_id)
|
110
|
+
|
111
|
+
expect(Dir).to receive(:glob).with('tmp/knapsack_pro/queue/fake-queue-id/*.json').and_return([])
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'logs warning about reasons why no test files were executed on this CI node' do
|
115
|
+
logger = instance_double(Logger)
|
116
|
+
expect(KnapsackPro).to receive(:logger).exactly(3).and_return(logger)
|
117
|
+
expect(logger).to receive(:warn).with('No test files were executed on this CI node.')
|
118
|
+
expect(logger).to receive(:debug).with('When you use knapsack_pro queue mode then probably reason might be that CI node was started after the test files from the queue were already executed by other CI nodes. That is why this CI node has no test files to execute.')
|
119
|
+
expect(logger).to receive(:debug).with("Another reason might be when your CI node failed in a way that prevented knapsack_pro to save time execution data to Knapsack Pro API and you have just tried to retry failed CI node but instead you got no test files to execute. In that case knapsack_pro don't know what testes should be executed here.")
|
120
|
+
|
121
|
+
expect(described_class).to receive(:create_build_subset).with([])
|
122
|
+
|
123
|
+
subject
|
124
|
+
end
|
73
125
|
end
|
74
126
|
end
|
75
127
|
|
@@ -161,7 +161,7 @@ describe KnapsackPro::Runners::Queue::MinitestRunner do
|
|
161
161
|
|
162
162
|
it 'returns exit code 0' do
|
163
163
|
expect(KnapsackPro::Hooks::Queue).to receive(:call_after_queue)
|
164
|
-
expect(KnapsackPro::Report).to receive(:save_node_queue_to_api)
|
164
|
+
expect(KnapsackPro::Report).to receive(:save_node_queue_to_api).with(0)
|
165
165
|
|
166
166
|
expect(subject).to eq({
|
167
167
|
status: :completed,
|
@@ -203,7 +203,7 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
|
|
203
203
|
expect(KnapsackPro::Formatters::RSpecQueueProfileFormatterExtension).to receive(:print_summary)
|
204
204
|
|
205
205
|
expect(KnapsackPro::Hooks::Queue).to receive(:call_after_queue)
|
206
|
-
expect(KnapsackPro::Report).to receive(:save_node_queue_to_api)
|
206
|
+
expect(KnapsackPro::Report).to receive(:save_node_queue_to_api).with(1)
|
207
207
|
|
208
208
|
expect(subject).to eq({
|
209
209
|
status: :completed,
|
@@ -217,7 +217,7 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
|
|
217
217
|
|
218
218
|
it do
|
219
219
|
expect(KnapsackPro::Hooks::Queue).to receive(:call_after_queue)
|
220
|
-
expect(KnapsackPro::Report).to receive(:save_node_queue_to_api)
|
220
|
+
expect(KnapsackPro::Report).to receive(:save_node_queue_to_api).with(0)
|
221
221
|
|
222
222
|
expect(subject).to eq({
|
223
223
|
status: :completed,
|
@@ -56,8 +56,8 @@ describe KnapsackPro::Tracker do
|
|
56
56
|
|
57
57
|
it { expect(tracker.global_time).to be_within(delta).of(0.3) }
|
58
58
|
it { expect(tracker.test_files_with_time.keys.size).to eql 2 }
|
59
|
-
it { expect(tracker.test_files_with_time['a_spec.rb']).to be_within(delta).of(0.1) }
|
60
|
-
it { expect(tracker.test_files_with_time['b_spec.rb']).to be_within(delta).of(0.2) }
|
59
|
+
it { expect(tracker.test_files_with_time['a_spec.rb'][:time_execution]).to be_within(delta).of(0.1) }
|
60
|
+
it { expect(tracker.test_files_with_time['b_spec.rb'][:time_execution]).to be_within(delta).of(0.2) }
|
61
61
|
it_behaves_like '#to_a'
|
62
62
|
end
|
63
63
|
|
@@ -81,8 +81,8 @@ describe KnapsackPro::Tracker do
|
|
81
81
|
it { expect(tracker.global_time).to be > 0 }
|
82
82
|
it { expect(tracker.global_time).to be_within(delta).of(0) }
|
83
83
|
it { expect(tracker.test_files_with_time.keys.size).to eql 2 }
|
84
|
-
it { expect(tracker.test_files_with_time['a_spec.rb']).to be_within(delta).of(0) }
|
85
|
-
it { expect(tracker.test_files_with_time['b_spec.rb']).to be_within(delta).of(0) }
|
84
|
+
it { expect(tracker.test_files_with_time['a_spec.rb'][:time_execution]).to be_within(delta).of(0) }
|
85
|
+
it { expect(tracker.test_files_with_time['b_spec.rb'][:time_execution]).to be_within(delta).of(0) }
|
86
86
|
it_behaves_like '#to_a'
|
87
87
|
end
|
88
88
|
|
@@ -97,8 +97,8 @@ describe KnapsackPro::Tracker do
|
|
97
97
|
|
98
98
|
it { expect(tracker.global_time).to eq 0 }
|
99
99
|
it { expect(tracker.test_files_with_time.keys.size).to eql 2 }
|
100
|
-
it { expect(tracker.test_files_with_time['a_spec.rb']).to eq 0 }
|
101
|
-
it { expect(tracker.test_files_with_time['b_spec.rb']).to eq 0 }
|
100
|
+
it { expect(tracker.test_files_with_time['a_spec.rb'][:time_execution]).to eq 0 }
|
101
|
+
it { expect(tracker.test_files_with_time['b_spec.rb'][:time_execution]).to eq 0 }
|
102
102
|
it_behaves_like '#to_a'
|
103
103
|
end
|
104
104
|
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.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ArturT
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-05-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|