knapsack_pro 7.2.0 → 7.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +64 -0
- data/lib/knapsack_pro/batch.rb +20 -0
- data/lib/knapsack_pro/extensions/rspec_extension.rb +7 -2
- data/lib/knapsack_pro/hooks/queue.rb +7 -4
- data/lib/knapsack_pro/queue.rb +40 -0
- data/lib/knapsack_pro/runners/queue/rspec_runner.rb +6 -3
- data/lib/knapsack_pro/version.rb +1 -1
- data/lib/knapsack_pro.rb +2 -0
- data/spec/integration/runners/queue/rspec_runner_spec.rb +133 -0
- data/spec/knapsack_pro/hooks/queue_spec.rb +90 -48
- data/spec/knapsack_pro/queue_spec.rb +35 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36aaf057fe65e4608728092873edfc63eaa1a667347b9a2b1a2d0d6b816be04b
|
4
|
+
data.tar.gz: 02cf4fd1181eece28c72266525498af71a474b954ab919056121b56a135429df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a6c8bf772b04582dcefb03d31e589930da021e60e43b6bb660b83215920030da0f553f24bb255435ce172a78c37fb80d18cf411f150d5b9cd4c5620ba9be91b1
|
7
|
+
data.tar.gz: b543dc597458ad3e3fcfdf9de61117221832d8d472c96300adc8615ab7b36ab7d98951b5f849cff590a8f3db3e708f41051969f753fcaf9c5de0362ab4a6e85b
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,50 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
### 7.3.0
|
4
|
+
|
5
|
+
* [Queue Mode][RSpec] Pass each batch of tests to the queue hooks: `KnapsackPro::Hooks::Queue.before_subset_queue` and `KnapsackPro::Hooks::Queue.after_subset_queue`
|
6
|
+
|
7
|
+
The `KnapsackPro::Hooks::Queue.before_subset_queue` and `KnapsackPro::Hooks::Queue.after_subset_queue` hooks get a 3rd variable - the `queue`.
|
8
|
+
|
9
|
+
The `queue` variable stores an enumerable collection with each batch of tests fetched from the Queue API. The batch has:
|
10
|
+
|
11
|
+
* a list of test file paths (`KnapsackPro::Batch#test_file_paths` returns an array like `['a_spec.rb', 'b_spec.rb']`)
|
12
|
+
* a status of the given set of tests in the batch (`KnapsackPro::Batch#status` returns `:not_executed`, `:passed` or `:failed`)
|
13
|
+
|
14
|
+
Example usage:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
# spec_helper.rb
|
18
|
+
|
19
|
+
KnapsackPro::Hooks::Queue.before_subset_queue do |queue_id, subset_queue_id, queue|
|
20
|
+
print "Tests from all batches fetched from the Queue API so far: "
|
21
|
+
puts queue.map(&:test_file_paths).inspect
|
22
|
+
|
23
|
+
queue.each(&:test_file_paths) # you can use each as well
|
24
|
+
|
25
|
+
print "Current batch tests: "
|
26
|
+
puts queue.current_batch.test_file_paths.inspect
|
27
|
+
|
28
|
+
print "Current batch status: "
|
29
|
+
puts queue.current_batch.status # returns :not_executed in the `before_subset_queue` hook
|
30
|
+
end
|
31
|
+
|
32
|
+
KnapsackPro::Hooks::Queue.after_subset_queue do |queue_id, subset_queue_id, queue|
|
33
|
+
print "Tests from all batches fetched from the Queue API so far: "
|
34
|
+
puts queue.map(&:test_file_paths).inspect
|
35
|
+
|
36
|
+
print "Current batch tests: "
|
37
|
+
puts queue.current_batch.test_file_paths.inspect
|
38
|
+
|
39
|
+
print "Current batch status: "
|
40
|
+
puts queue.current_batch.status # returns :passed or :failed in the `after_subset_queue` hook
|
41
|
+
end
|
42
|
+
```
|
43
|
+
|
44
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/pull/253
|
45
|
+
|
46
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v7.2.0...v7.3.0
|
47
|
+
|
3
48
|
### 7.2.0
|
4
49
|
|
5
50
|
* Always use the original `Net::HTTP` client, even when WebMock replaces it with its own
|
@@ -47,6 +92,25 @@ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v7.0.0...v7.0.1
|
|
47
92
|
__After:__<br>
|
48
93
|
The `before(:suite)` and `after(:suite)` hooks are executed only once: `before(:suite)` is executed before starting tests, `after(:suite)` is executed after all tests are completed. (It is what you would expect from RSpec).
|
49
94
|
|
95
|
+
* It is recommended that you define your `before(:suite)` hooks in `spec_helper.rb` or `rails_helper.rb`. These files should be loaded before any test files so that the hook is registered by RSpec.
|
96
|
+
|
97
|
+
The `before(:suite)` hook is executed first. After that, test files are dynamically loaded in multiple batches from the Knapsack Pro Queue API. __The `before(:suite)` hooks defined in test files won't be executed because it is too late!__
|
98
|
+
|
99
|
+
If you need to have something that is similar to `before(:suite)` and you want to define it in a test file, then you can use this:
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
RSpec.configure do |config|
|
103
|
+
config.before(:context) do
|
104
|
+
unless ENV['MY_HOOK_NAME']
|
105
|
+
# your code to run in the hook
|
106
|
+
end
|
107
|
+
ENV['MY_HOOK_NAME'] = 'hook_called'
|
108
|
+
end
|
109
|
+
end
|
110
|
+
```
|
111
|
+
|
112
|
+
Alternatively, if you need to [load code only once for a specific type of specs you can check this](https://docs.knapsackpro.com/ruby/rspec/#load-code-only-once-for-a-specific-type-of-specs).
|
113
|
+
|
50
114
|
* The `KnapsackPro::Hooks::Queue.after_queue` hook change:
|
51
115
|
|
52
116
|
__Before:__<br>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KnapsackPro
|
4
|
+
class Batch
|
5
|
+
attr_reader :test_file_paths, :status
|
6
|
+
|
7
|
+
def initialize(test_file_paths)
|
8
|
+
@test_file_paths = test_file_paths
|
9
|
+
@status = :not_executed
|
10
|
+
end
|
11
|
+
|
12
|
+
def _passed
|
13
|
+
@status = :passed
|
14
|
+
end
|
15
|
+
|
16
|
+
def _failed
|
17
|
+
@status = :failed
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -90,7 +90,7 @@ module KnapsackPro
|
|
90
90
|
|
91
91
|
configuration.reporter.report(_expected_example_count = 0) do |reporter|
|
92
92
|
configuration.with_suite_hooks do
|
93
|
-
queue_runner.with_batch do |test_file_paths|
|
93
|
+
queue_runner.with_batch do |test_file_paths, queue|
|
94
94
|
knapsack__load_spec_files_batch(test_file_paths)
|
95
95
|
|
96
96
|
examples_passed = ordering_strategy.order(world.example_groups).map do |example_group|
|
@@ -98,7 +98,12 @@ module KnapsackPro
|
|
98
98
|
example_group.run(reporter)
|
99
99
|
end.all?
|
100
100
|
|
101
|
-
|
101
|
+
if examples_passed
|
102
|
+
queue.mark_batch_passed
|
103
|
+
else
|
104
|
+
queue.mark_batch_failed
|
105
|
+
node_examples_passed = false
|
106
|
+
end
|
102
107
|
|
103
108
|
knapsack__persist_example_statuses
|
104
109
|
|
@@ -54,22 +54,25 @@ module KnapsackPro
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
-
|
57
|
+
# `queue` is always present for RSpec
|
58
|
+
def call_before_subset_queue(queue = nil)
|
58
59
|
return unless before_subset_queue_store
|
59
60
|
before_subset_queue_store.each do |block|
|
60
61
|
block.call(
|
61
62
|
KnapsackPro::Config::Env.queue_id,
|
62
|
-
KnapsackPro::Config::Env.subset_queue_id
|
63
|
+
KnapsackPro::Config::Env.subset_queue_id,
|
64
|
+
queue
|
63
65
|
)
|
64
66
|
end
|
65
67
|
end
|
66
68
|
|
67
|
-
def call_after_subset_queue
|
69
|
+
def call_after_subset_queue(queue = nil)
|
68
70
|
return unless after_subset_queue_store
|
69
71
|
after_subset_queue_store.each do |block|
|
70
72
|
block.call(
|
71
73
|
KnapsackPro::Config::Env.queue_id,
|
72
|
-
KnapsackPro::Config::Env.subset_queue_id
|
74
|
+
KnapsackPro::Config::Env.subset_queue_id,
|
75
|
+
queue
|
73
76
|
)
|
74
77
|
end
|
75
78
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KnapsackPro
|
4
|
+
class Queue
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@batches = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def each(&block)
|
12
|
+
@batches.each(&block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_batch_for(test_file_paths)
|
16
|
+
return if test_file_paths.empty?
|
17
|
+
@batches << KnapsackPro::Batch.new(test_file_paths)
|
18
|
+
end
|
19
|
+
|
20
|
+
def mark_batch_passed
|
21
|
+
current_batch._passed
|
22
|
+
end
|
23
|
+
|
24
|
+
def mark_batch_failed
|
25
|
+
current_batch._failed
|
26
|
+
end
|
27
|
+
|
28
|
+
def current_batch
|
29
|
+
@batches.last
|
30
|
+
end
|
31
|
+
|
32
|
+
def size
|
33
|
+
@batches.size
|
34
|
+
end
|
35
|
+
|
36
|
+
def [](index)
|
37
|
+
@batches[index]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -33,6 +33,7 @@ module KnapsackPro
|
|
33
33
|
@stream_out = stream_out
|
34
34
|
@node_test_file_paths = []
|
35
35
|
@rspec_runner = nil # RSpec::Core::Runner is lazy initialized
|
36
|
+
@queue = KnapsackPro::Queue.new
|
36
37
|
end
|
37
38
|
|
38
39
|
# Based on:
|
@@ -82,11 +83,13 @@ module KnapsackPro
|
|
82
83
|
subset_queue_id = KnapsackPro::Config::EnvGenerator.set_subset_queue_id
|
83
84
|
ENV['KNAPSACK_PRO_SUBSET_QUEUE_ID'] = subset_queue_id
|
84
85
|
|
85
|
-
|
86
|
+
@queue.add_batch_for(test_file_paths)
|
86
87
|
|
87
|
-
|
88
|
+
KnapsackPro::Hooks::Queue.call_before_subset_queue(@queue)
|
88
89
|
|
89
|
-
|
90
|
+
yield test_file_paths, @queue
|
91
|
+
|
92
|
+
KnapsackPro::Hooks::Queue.call_after_subset_queue(@queue)
|
90
93
|
|
91
94
|
if @rspec_runner.knapsack__wants_to_quit?
|
92
95
|
KnapsackPro.logger.warn('RSpec wants to quit.')
|
data/lib/knapsack_pro/version.rb
CHANGED
data/lib/knapsack_pro.rb
CHANGED
@@ -67,6 +67,8 @@ require_relative 'knapsack_pro/test_files_with_test_cases_composer'
|
|
67
67
|
require_relative 'knapsack_pro/base_allocator_builder'
|
68
68
|
require_relative 'knapsack_pro/allocator_builder'
|
69
69
|
require_relative 'knapsack_pro/queue_allocator_builder'
|
70
|
+
require_relative 'knapsack_pro/batch'
|
71
|
+
require_relative 'knapsack_pro/queue'
|
70
72
|
require_relative 'knapsack_pro/runners/base_runner'
|
71
73
|
require_relative 'knapsack_pro/runners/rspec_runner'
|
72
74
|
require_relative 'knapsack_pro/runners/cucumber_runner'
|
@@ -739,6 +739,139 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} - Integration tests", :cle
|
|
739
739
|
|
740
740
|
expect(actual.exit_code).to eq 0
|
741
741
|
end
|
742
|
+
|
743
|
+
it 'gives access to batch of tests in queue hooks' do
|
744
|
+
rspec_options = ''
|
745
|
+
|
746
|
+
spec_helper = <<~SPEC
|
747
|
+
require 'knapsack_pro'
|
748
|
+
KnapsackPro::Adapters::RSpecAdapter.bind
|
749
|
+
|
750
|
+
KnapsackPro::Hooks::Queue.before_subset_queue do |queue_id, subset_queue_id, queue|
|
751
|
+
print "Tests in batches in before_subset_queue: "
|
752
|
+
puts queue.map(&:test_file_paths).inspect
|
753
|
+
|
754
|
+
print "Batches' statuses in before_subset_queue: "
|
755
|
+
puts queue.map(&:status).inspect
|
756
|
+
end
|
757
|
+
|
758
|
+
KnapsackPro::Hooks::Queue.after_subset_queue do |queue_id, subset_queue_id, queue|
|
759
|
+
print "Tests in batches in after_subset_queue: "
|
760
|
+
puts queue.map(&:test_file_paths).inspect
|
761
|
+
print "Batches' statuses in after_subset_queue: "
|
762
|
+
puts queue.map(&:status).inspect
|
763
|
+
|
764
|
+
# call public API methods that must be backward compatible
|
765
|
+
print "Current batch tests: "
|
766
|
+
puts queue.current_batch.test_file_paths.inspect
|
767
|
+
print "Current batch status: "
|
768
|
+
puts queue.current_batch.status
|
769
|
+
end
|
770
|
+
SPEC
|
771
|
+
|
772
|
+
spec_a = Spec.new('a_spec.rb', <<~SPEC)
|
773
|
+
describe 'A_describe' do
|
774
|
+
it 'A1 test example' do
|
775
|
+
expect(1).to eq 1
|
776
|
+
end
|
777
|
+
end
|
778
|
+
SPEC
|
779
|
+
|
780
|
+
spec_b = Spec.new('b_spec.rb', <<~SPEC)
|
781
|
+
describe 'B_describe' do
|
782
|
+
it 'B1 test example' do
|
783
|
+
expect(1).to eq 1
|
784
|
+
end
|
785
|
+
end
|
786
|
+
SPEC
|
787
|
+
|
788
|
+
spec_c = Spec.new('c_spec.rb', <<~SPEC)
|
789
|
+
describe 'C_describe' do
|
790
|
+
it 'C1 test example' do
|
791
|
+
expect(1).to eq 1
|
792
|
+
end
|
793
|
+
end
|
794
|
+
SPEC
|
795
|
+
|
796
|
+
failing_spec_d = Spec.new('d_spec.rb', <<~SPEC)
|
797
|
+
describe 'D_describe' do
|
798
|
+
it 'D1 test example' do
|
799
|
+
expect(1).to eq 0
|
800
|
+
end
|
801
|
+
end
|
802
|
+
SPEC
|
803
|
+
|
804
|
+
spec_e = Spec.new('e_spec.rb', <<~SPEC)
|
805
|
+
describe 'E_describe' do
|
806
|
+
it 'E1 test example' do
|
807
|
+
expect(1).to eq 1
|
808
|
+
end
|
809
|
+
end
|
810
|
+
SPEC
|
811
|
+
|
812
|
+
spec_f = Spec.new('f_spec.rb', <<~SPEC)
|
813
|
+
describe 'F_describe' do
|
814
|
+
it 'F1 test example' do
|
815
|
+
expect(1).to eq 1
|
816
|
+
end
|
817
|
+
end
|
818
|
+
SPEC
|
819
|
+
|
820
|
+
failing_spec_g = Spec.new('g_spec.rb', <<~SPEC)
|
821
|
+
describe 'G_describe' do
|
822
|
+
it 'G1 test example' do
|
823
|
+
expect(1).to eq 0
|
824
|
+
end
|
825
|
+
end
|
826
|
+
SPEC
|
827
|
+
|
828
|
+
spec_h = Spec.new('h_spec.rb', <<~SPEC)
|
829
|
+
describe 'h_describe' do
|
830
|
+
it 'H1 test example' do
|
831
|
+
expect(1).to eq 1
|
832
|
+
end
|
833
|
+
end
|
834
|
+
SPEC
|
835
|
+
|
836
|
+
generate_specs(spec_helper, rspec_options, [
|
837
|
+
[spec_a, spec_b],
|
838
|
+
[spec_c, failing_spec_d],
|
839
|
+
[spec_e, spec_f],
|
840
|
+
[failing_spec_g, spec_h],
|
841
|
+
])
|
842
|
+
|
843
|
+
actual = subject
|
844
|
+
|
845
|
+
expect(actual.stdout).to include('Tests in batches in before_subset_queue: [["spec_integration/a_spec.rb", "spec_integration/b_spec.rb"]]')
|
846
|
+
expect(actual.stdout).to include('Tests in batches in before_subset_queue: [["spec_integration/a_spec.rb", "spec_integration/b_spec.rb"], ["spec_integration/c_spec.rb", "spec_integration/d_spec.rb"]]')
|
847
|
+
expect(actual.stdout).to include('Tests in batches in before_subset_queue: [["spec_integration/a_spec.rb", "spec_integration/b_spec.rb"], ["spec_integration/c_spec.rb", "spec_integration/d_spec.rb"], ["spec_integration/e_spec.rb", "spec_integration/f_spec.rb"]]')
|
848
|
+
expect(actual.stdout).to include('Tests in batches in before_subset_queue: [["spec_integration/a_spec.rb", "spec_integration/b_spec.rb"], ["spec_integration/c_spec.rb", "spec_integration/d_spec.rb"], ["spec_integration/e_spec.rb", "spec_integration/f_spec.rb"], ["spec_integration/g_spec.rb", "spec_integration/h_spec.rb"]]')
|
849
|
+
|
850
|
+
expect(actual.stdout).to include('Tests in batches in after_subset_queue: [["spec_integration/a_spec.rb", "spec_integration/b_spec.rb"]]')
|
851
|
+
expect(actual.stdout).to include('Tests in batches in after_subset_queue: [["spec_integration/a_spec.rb", "spec_integration/b_spec.rb"], ["spec_integration/c_spec.rb", "spec_integration/d_spec.rb"]]')
|
852
|
+
expect(actual.stdout).to include('Tests in batches in after_subset_queue: [["spec_integration/a_spec.rb", "spec_integration/b_spec.rb"], ["spec_integration/c_spec.rb", "spec_integration/d_spec.rb"], ["spec_integration/e_spec.rb", "spec_integration/f_spec.rb"]]')
|
853
|
+
expect(actual.stdout).to include('Tests in batches in after_subset_queue: [["spec_integration/a_spec.rb", "spec_integration/b_spec.rb"], ["spec_integration/c_spec.rb", "spec_integration/d_spec.rb"], ["spec_integration/e_spec.rb", "spec_integration/f_spec.rb"], ["spec_integration/g_spec.rb", "spec_integration/h_spec.rb"]]')
|
854
|
+
|
855
|
+
|
856
|
+
expect(actual.stdout).to include("Batches' statuses in before_subset_queue: [:not_executed]")
|
857
|
+
expect(actual.stdout).to include("Batches' statuses in before_subset_queue: [:passed, :not_executed]")
|
858
|
+
expect(actual.stdout).to include("Batches' statuses in before_subset_queue: [:passed, :failed, :not_executed]")
|
859
|
+
expect(actual.stdout).to include("Batches' statuses in before_subset_queue: [:passed, :failed, :passed, :not_executed]")
|
860
|
+
|
861
|
+
expect(actual.stdout).to include("Batches' statuses in after_subset_queue: [:passed]")
|
862
|
+
expect(actual.stdout).to include("Batches' statuses in after_subset_queue: [:passed, :failed]")
|
863
|
+
expect(actual.stdout).to include("Batches' statuses in after_subset_queue: [:passed, :failed, :passed]")
|
864
|
+
expect(actual.stdout).to include("Batches' statuses in after_subset_queue: [:passed, :failed, :passed, :failed]")
|
865
|
+
|
866
|
+
expect(actual.stdout).to include('Current batch tests: ["spec_integration/a_spec.rb", "spec_integration/b_spec.rb"]')
|
867
|
+
expect(actual.stdout).to include('Current batch tests: ["spec_integration/c_spec.rb", "spec_integration/d_spec.rb"]')
|
868
|
+
expect(actual.stdout).to include('Current batch tests: ["spec_integration/e_spec.rb", "spec_integration/f_spec.rb"]')
|
869
|
+
expect(actual.stdout).to include('Current batch tests: ["spec_integration/g_spec.rb", "spec_integration/h_spec.rb"]')
|
870
|
+
expect(actual.stdout).to include('Current batch status: passed').twice
|
871
|
+
expect(actual.stdout).to include('Current batch status: failed').twice
|
872
|
+
|
873
|
+
expect(actual.exit_code).to eq 1
|
874
|
+
end
|
742
875
|
end
|
743
876
|
|
744
877
|
context 'when the RSpec seed is used' do
|
@@ -2,34 +2,32 @@ describe KnapsackPro::Hooks::Queue do
|
|
2
2
|
describe '.call_before_queue' do
|
3
3
|
subject { described_class.call_before_queue }
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
5
|
+
before do
|
6
|
+
described_class.reset_before_queue
|
7
|
+
end
|
9
8
|
|
9
|
+
context 'when no callback is set' do
|
10
10
|
it { should be_nil }
|
11
11
|
end
|
12
12
|
|
13
|
-
context 'when
|
13
|
+
context 'when multiple callbacks are set' do
|
14
14
|
let(:queue_id) { double }
|
15
15
|
|
16
|
-
|
16
|
+
it 'calls each block' do
|
17
17
|
expect(KnapsackPro::Config::Env).to receive(:queue_id).twice.and_return(queue_id)
|
18
18
|
|
19
|
-
|
19
|
+
expected_called_blocks = []
|
20
20
|
|
21
21
|
described_class.before_queue do |q_id|
|
22
|
-
|
22
|
+
expected_called_blocks << [:block_1_called, q_id]
|
23
23
|
end
|
24
24
|
described_class.before_queue do |q_id|
|
25
|
-
|
25
|
+
expected_called_blocks << [:block_2_called, q_id]
|
26
26
|
end
|
27
|
-
end
|
28
27
|
|
29
|
-
it 'each block is called' do
|
30
28
|
subject
|
31
29
|
|
32
|
-
expect(
|
30
|
+
expect(expected_called_blocks).to eq([
|
33
31
|
[:block_1_called, queue_id],
|
34
32
|
[:block_2_called, queue_id],
|
35
33
|
])
|
@@ -40,114 +38,158 @@ describe KnapsackPro::Hooks::Queue do
|
|
40
38
|
describe '.call_before_subset_queue' do
|
41
39
|
subject { described_class.call_before_subset_queue }
|
42
40
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
end
|
41
|
+
before do
|
42
|
+
described_class.reset_before_subset_queue
|
43
|
+
end
|
47
44
|
|
45
|
+
context 'when no callback is set' do
|
48
46
|
it { should be_nil }
|
49
47
|
end
|
50
48
|
|
51
|
-
context 'when
|
49
|
+
context 'when multiple callbacks are set' do
|
52
50
|
let(:queue_id) { double }
|
53
51
|
let(:subset_queue_id) { double }
|
54
52
|
|
55
|
-
|
53
|
+
it 'calls each block' do
|
56
54
|
expect(KnapsackPro::Config::Env).to receive(:queue_id).twice.and_return(queue_id)
|
57
55
|
expect(KnapsackPro::Config::Env).to receive(:subset_queue_id).twice.and_return(subset_queue_id)
|
58
56
|
|
59
|
-
|
57
|
+
expected_called_blocks = []
|
60
58
|
|
61
59
|
described_class.before_subset_queue do |q_id, subset_q_id|
|
62
|
-
|
60
|
+
expected_called_blocks << [:block_1_called, q_id, subset_q_id]
|
63
61
|
end
|
64
62
|
described_class.before_subset_queue do |q_id, subset_q_id|
|
65
|
-
|
63
|
+
expected_called_blocks << [:block_2_called, q_id, subset_q_id]
|
66
64
|
end
|
67
|
-
end
|
68
65
|
|
69
|
-
it 'each block is called' do
|
70
66
|
subject
|
71
67
|
|
72
|
-
expect(
|
68
|
+
expect(expected_called_blocks).to eq([
|
73
69
|
[:block_1_called, queue_id, subset_queue_id],
|
74
70
|
[:block_2_called, queue_id, subset_queue_id],
|
75
71
|
])
|
76
72
|
end
|
77
73
|
end
|
74
|
+
|
75
|
+
context 'when a callback is set AND the queue is passed' do
|
76
|
+
let(:queue_id) { double }
|
77
|
+
let(:subset_queue_id) { double }
|
78
|
+
let(:queue) { instance_double(KnapsackPro::Queue) }
|
79
|
+
|
80
|
+
subject { described_class.call_before_subset_queue(queue) }
|
81
|
+
|
82
|
+
it 'calls each block' do
|
83
|
+
expect(KnapsackPro::Config::Env).to receive(:queue_id).and_return(queue_id)
|
84
|
+
expect(KnapsackPro::Config::Env).to receive(:subset_queue_id).and_return(subset_queue_id)
|
85
|
+
|
86
|
+
expected_called_blocks = []
|
87
|
+
|
88
|
+
described_class.before_subset_queue do |q_id, subset_q_id, queue|
|
89
|
+
expected_called_blocks << [:block_1_called, q_id, subset_q_id, queue]
|
90
|
+
end
|
91
|
+
|
92
|
+
subject
|
93
|
+
|
94
|
+
expect(expected_called_blocks).to eq([
|
95
|
+
[:block_1_called, queue_id, subset_queue_id, queue],
|
96
|
+
])
|
97
|
+
end
|
98
|
+
end
|
78
99
|
end
|
79
100
|
|
80
101
|
describe '.call_after_subset_queue' do
|
81
102
|
subject { described_class.call_after_subset_queue }
|
82
103
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
end
|
104
|
+
before do
|
105
|
+
described_class.reset_after_subset_queue
|
106
|
+
end
|
87
107
|
|
108
|
+
context 'when no callback is set' do
|
88
109
|
it { should be_nil }
|
89
110
|
end
|
90
111
|
|
91
|
-
context 'when
|
112
|
+
context 'when multiple callbacks are set' do
|
92
113
|
let(:queue_id) { double }
|
93
114
|
let(:subset_queue_id) { double }
|
94
115
|
|
95
|
-
|
116
|
+
it 'calls each block' do
|
96
117
|
expect(KnapsackPro::Config::Env).to receive(:queue_id).at_least(:once).and_return(queue_id)
|
97
118
|
expect(KnapsackPro::Config::Env).to receive(:subset_queue_id).at_least(:once).and_return(subset_queue_id)
|
98
119
|
|
99
|
-
|
120
|
+
expected_called_blocks = []
|
100
121
|
|
101
122
|
described_class.after_subset_queue do |q_id, subset_q_id|
|
102
|
-
|
123
|
+
expected_called_blocks << [:block_1_called, q_id, subset_q_id]
|
103
124
|
end
|
104
125
|
described_class.after_subset_queue do |q_id, subset_q_id|
|
105
|
-
|
126
|
+
expected_called_blocks << [:block_2_called, q_id, subset_q_id]
|
106
127
|
end
|
107
|
-
end
|
108
128
|
|
109
|
-
it 'each block is called' do
|
110
129
|
subject
|
111
130
|
|
112
|
-
expect(
|
131
|
+
expect(expected_called_blocks).to eq([
|
113
132
|
[:block_1_called, queue_id, subset_queue_id],
|
114
133
|
[:block_2_called, queue_id, subset_queue_id],
|
115
134
|
])
|
116
135
|
end
|
117
136
|
end
|
137
|
+
|
138
|
+
context 'when a callback is set AND the queue is passed' do
|
139
|
+
let(:queue_id) { double }
|
140
|
+
let(:subset_queue_id) { double }
|
141
|
+
let(:queue) { instance_double(KnapsackPro::Queue) }
|
142
|
+
|
143
|
+
subject { described_class.call_after_subset_queue(queue) }
|
144
|
+
|
145
|
+
it 'calls each block' do
|
146
|
+
expect(KnapsackPro::Config::Env).to receive(:queue_id).and_return(queue_id)
|
147
|
+
expect(KnapsackPro::Config::Env).to receive(:subset_queue_id).and_return(subset_queue_id)
|
148
|
+
|
149
|
+
expected_called_blocks = []
|
150
|
+
|
151
|
+
described_class.after_subset_queue do |q_id, subset_q_id, queue|
|
152
|
+
expected_called_blocks << [:block_1_called, q_id, subset_q_id, queue]
|
153
|
+
end
|
154
|
+
|
155
|
+
subject
|
156
|
+
|
157
|
+
expect(expected_called_blocks).to eq([
|
158
|
+
[:block_1_called, queue_id, subset_queue_id, queue],
|
159
|
+
])
|
160
|
+
end
|
161
|
+
end
|
118
162
|
end
|
119
163
|
|
120
164
|
describe '.call_after_queue' do
|
121
165
|
subject { described_class.call_after_queue }
|
122
166
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
end
|
167
|
+
before do
|
168
|
+
described_class.reset_after_queue
|
169
|
+
end
|
127
170
|
|
171
|
+
context 'when no callback is set' do
|
128
172
|
it { should be_nil }
|
129
173
|
end
|
130
174
|
|
131
|
-
context 'when
|
175
|
+
context 'when multiple callbacks are set' do
|
132
176
|
let(:queue_id) { double }
|
133
177
|
|
134
|
-
|
178
|
+
it 'calls each block' do
|
135
179
|
expect(KnapsackPro::Config::Env).to receive(:queue_id).twice.and_return(queue_id)
|
136
180
|
|
137
|
-
|
181
|
+
expected_called_blocks = []
|
138
182
|
|
139
183
|
described_class.after_queue do |q_id|
|
140
|
-
|
184
|
+
expected_called_blocks << [:block_1_called, q_id]
|
141
185
|
end
|
142
186
|
described_class.after_queue do |q_id|
|
143
|
-
|
187
|
+
expected_called_blocks << [:block_2_called, q_id]
|
144
188
|
end
|
145
|
-
end
|
146
189
|
|
147
|
-
it 'each block is called' do
|
148
190
|
subject
|
149
191
|
|
150
|
-
expect(
|
192
|
+
expect(expected_called_blocks).to eq([
|
151
193
|
[:block_1_called, queue_id],
|
152
194
|
[:block_2_called, queue_id],
|
153
195
|
])
|
@@ -0,0 +1,35 @@
|
|
1
|
+
describe KnapsackPro::Queue do
|
2
|
+
it 'simulates a Queue Mode build' do
|
3
|
+
queue = described_class.new
|
4
|
+
|
5
|
+
expect(queue.current_batch).to be_nil
|
6
|
+
|
7
|
+
# 1st batch
|
8
|
+
test_files_paths_1 = ['a_spec.rb', 'b_spec.rb']
|
9
|
+
queue.add_batch_for(test_files_paths_1)
|
10
|
+
|
11
|
+
expect(queue.current_batch.test_file_paths).to eq(['a_spec.rb', 'b_spec.rb'])
|
12
|
+
expect(queue.current_batch.status).to eq :not_executed
|
13
|
+
queue.mark_batch_passed
|
14
|
+
expect(queue.current_batch.status).to eq :passed
|
15
|
+
|
16
|
+
|
17
|
+
# 2nd batch
|
18
|
+
test_files_paths_2 = ['c_spec.rb', 'd_spec.rb']
|
19
|
+
queue.add_batch_for(test_files_paths_2)
|
20
|
+
|
21
|
+
expect(queue.current_batch.test_file_paths).to eq(['c_spec.rb', 'd_spec.rb'])
|
22
|
+
expect(queue.current_batch.status).to eq :not_executed
|
23
|
+
queue.mark_batch_failed
|
24
|
+
expect(queue.current_batch.status).to eq :failed
|
25
|
+
|
26
|
+
|
27
|
+
# last batch from the Queue API is always empty
|
28
|
+
test_files_paths_3 = []
|
29
|
+
queue.add_batch_for(test_files_paths_3)
|
30
|
+
|
31
|
+
expect(queue.size).to eq 2
|
32
|
+
expect(queue[0].status).to eq :passed
|
33
|
+
expect(queue[1].status).to eq :failed
|
34
|
+
end
|
35
|
+
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: 7.
|
4
|
+
version: 7.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ArturT
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-05-
|
11
|
+
date: 2024-05-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -214,6 +214,7 @@ files:
|
|
214
214
|
- lib/knapsack_pro/allocator.rb
|
215
215
|
- lib/knapsack_pro/allocator_builder.rb
|
216
216
|
- lib/knapsack_pro/base_allocator_builder.rb
|
217
|
+
- lib/knapsack_pro/batch.rb
|
217
218
|
- lib/knapsack_pro/build_distribution_fetcher.rb
|
218
219
|
- lib/knapsack_pro/client/api/action.rb
|
219
220
|
- lib/knapsack_pro/client/api/v1/base.rb
|
@@ -250,6 +251,7 @@ files:
|
|
250
251
|
- lib/knapsack_pro/mask_string.rb
|
251
252
|
- lib/knapsack_pro/presenter.rb
|
252
253
|
- lib/knapsack_pro/pure/queue/rspec_pure.rb
|
254
|
+
- lib/knapsack_pro/queue.rb
|
253
255
|
- lib/knapsack_pro/queue_allocator.rb
|
254
256
|
- lib/knapsack_pro/queue_allocator_builder.rb
|
255
257
|
- lib/knapsack_pro/railtie.rb
|
@@ -348,6 +350,7 @@ files:
|
|
348
350
|
- spec/knapsack_pro/pure/queue/rspec_pure_spec.rb
|
349
351
|
- spec/knapsack_pro/queue_allocator_builder_spec.rb
|
350
352
|
- spec/knapsack_pro/queue_allocator_spec.rb
|
353
|
+
- spec/knapsack_pro/queue_spec.rb
|
351
354
|
- spec/knapsack_pro/report_spec.rb
|
352
355
|
- spec/knapsack_pro/repository_adapter_initiator_spec.rb
|
353
356
|
- spec/knapsack_pro/repository_adapters/base_adapter_spec.rb
|
@@ -412,7 +415,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
412
415
|
- !ruby/object:Gem::Version
|
413
416
|
version: '0'
|
414
417
|
requirements: []
|
415
|
-
rubygems_version: 3.4.
|
418
|
+
rubygems_version: 3.4.19
|
416
419
|
signing_key:
|
417
420
|
specification_version: 4
|
418
421
|
summary: Knapsack Pro splits tests across parallel CI nodes and ensures each parallel
|
@@ -471,6 +474,7 @@ test_files:
|
|
471
474
|
- spec/knapsack_pro/pure/queue/rspec_pure_spec.rb
|
472
475
|
- spec/knapsack_pro/queue_allocator_builder_spec.rb
|
473
476
|
- spec/knapsack_pro/queue_allocator_spec.rb
|
477
|
+
- spec/knapsack_pro/queue_spec.rb
|
474
478
|
- spec/knapsack_pro/report_spec.rb
|
475
479
|
- spec/knapsack_pro/repository_adapter_initiator_spec.rb
|
476
480
|
- spec/knapsack_pro/repository_adapters/base_adapter_spec.rb
|