knapsack 0.2.0 → 0.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 +4 -0
- data/README.md +72 -5
- data/docs/images/logos/knapsack-@2.png +0 -0
- data/docs/images/logos/knapsack-logo-@2.png +0 -0
- data/docs/images/logos/knapsack-logo.png +0 -0
- data/docs/images/logos/knapsack.png +0 -0
- data/knapsack.gemspec +1 -1
- data/lib/knapsack/config.rb +9 -2
- data/lib/knapsack/distributors/base_distributor.rb +0 -6
- data/lib/knapsack/distributors/leftover_distributor.rb +4 -2
- data/lib/knapsack/distributors/report_distributor.rb +9 -8
- data/lib/knapsack/version.rb +1 -1
- data/spec/knapsack/config_spec.rb +10 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 181f987c696d1bc19a140cf92e482790f7b1c2ce
|
4
|
+
data.tar.gz: 92a9cb85bb6a341ddd9dd572a8324875fd30ef4d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9b0a1761048c7c9bd0dcd019e871bf98ac7f0551d10c3b9078f6f6d3dad25748a0450576cb5ae5d7d2be5f2748c8d3f71ab32034b289dddf6e7bc6b6b0b9091
|
7
|
+
data.tar.gz: a976683e07452a987816f8036afdaa97db0254268d2cd503f462da0e2fa91c049553a670412d88e2fcc4d4a0f653f11a0d5ae616e8665ea43603beabd76e22a8
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Knapsack
|
1
|
+
# 
|
2
2
|
|
3
3
|
[][gem_version]
|
4
4
|
[][travis]
|
@@ -10,7 +10,7 @@
|
|
10
10
|
[codeclimate]: https://codeclimate.com/github/ArturT/knapsack
|
11
11
|
[coverage]: https://codeclimate.com/github/ArturT/knapsack
|
12
12
|
|
13
|
-
Parallel specs across CI server nodes based on each spec file's time execution. It generates spec time execution report and uses it for
|
13
|
+
Parallel specs across CI server nodes based on each spec file's time execution. It generates a spec time execution report and uses it for future test runs.
|
14
14
|
|
15
15
|
Short [presentation](http://slides.com/arturt/knapsack) about gem.
|
16
16
|
|
@@ -62,13 +62,13 @@ Add in your `Rakefile` this lines:
|
|
62
62
|
require 'knapsack'
|
63
63
|
Knapsack.load_tasks
|
64
64
|
|
65
|
-
Generate time execution report for your spec files. Run
|
65
|
+
Generate time execution report for your spec files. Run below command on one of your CI nodes.
|
66
66
|
|
67
67
|
$ KNAPSACK_GENERATE_REPORT=true bundle exec rspec spec
|
68
68
|
|
69
69
|
Commit generated report `knapsack_report.json` into your repository.
|
70
70
|
|
71
|
-
|
71
|
+
This report should be updated only after you add a lot of new slow tests or you change existing ones which causes a big time execution difference between CI nodes. Either way, you will get time offset warning at the end of the rspec results which reminds you when it’s a good time to regenerate the knapsack report.
|
72
72
|
|
73
73
|
## Setup your CI server
|
74
74
|
|
@@ -94,7 +94,9 @@ You can set `KNAPSACK_REPORT_PATH` if your knapsack report was saved in non defa
|
|
94
94
|
|
95
95
|
If you are using circleci.com you can omit `CI_NODE_TOTAL` and `CI_NODE_INDEX`. Knapsack will use `CIRCLE_NODE_TOTAL` and `CIRCLE_NODE_INDEX` provided by CircleCI.
|
96
96
|
|
97
|
-
Here is example for test configuration in your `circleci.yml` file.
|
97
|
+
Here is an example for test configuration in your `circleci.yml` file.
|
98
|
+
|
99
|
+
#### Step 1
|
98
100
|
|
99
101
|
For the first time run all specs on a single CI node with enabled report generator.
|
100
102
|
|
@@ -104,6 +106,8 @@ For the first time run all specs on a single CI node with enabled report generat
|
|
104
106
|
|
105
107
|
After tests pass on your CircleCI machine your should copy knapsack json report which is rendered at the end of rspec results. Save it into your repository as `knapsack_report.json` file and commit.
|
106
108
|
|
109
|
+
#### Step 2
|
110
|
+
|
107
111
|
Now you should update test command and enable parallel. Please remember to add additional containers for your project in CircleCI settings.
|
108
112
|
|
109
113
|
test:
|
@@ -113,6 +117,65 @@ Now you should update test command and enable parallel. Please remember to add a
|
|
113
117
|
|
114
118
|
Now everything should works. You will get warning at the end of rspec results if time execution will take too much.
|
115
119
|
|
120
|
+
### Info for Travis users
|
121
|
+
|
122
|
+
#### Step 1
|
123
|
+
|
124
|
+
For the first time run all specs at once with enabled report generator. Edit `.travis.yml`
|
125
|
+
|
126
|
+
script: "KNAPSACK_GENERATE_REPORT=true bundle exec rspec spec"
|
127
|
+
|
128
|
+
After tests pass your should copy knapsack json report which is rendered at the end of rspec results. Save it into your repository as `knapsack_report.json` file and commit.
|
129
|
+
|
130
|
+
#### Step 2
|
131
|
+
|
132
|
+
You can parallel your builds across virtual machines with [travis matrix feature](http://docs.travis-ci.com/user/speeding-up-the-build/#Parallelizing-your-builds-across-virtual-machines). Edit `.travis.yml`
|
133
|
+
|
134
|
+
script: "bundle exec rake knapsack:rspec"
|
135
|
+
env:
|
136
|
+
- CI_NODE_TOTAL=2 CI_NODE_INDEX=0
|
137
|
+
- CI_NODE_TOTAL=2 CI_NODE_INDEX=1
|
138
|
+
|
139
|
+
If you want to have some global ENVs and matrix of ENVs then do it like this:
|
140
|
+
|
141
|
+
script: "bundle exec rake knapsack:rspec"
|
142
|
+
env:
|
143
|
+
global:
|
144
|
+
- RAILS_ENV=test
|
145
|
+
- MY_GLOBAL_VAR=123
|
146
|
+
matrix:
|
147
|
+
- CI_NODE_TOTAL=2 CI_NODE_INDEX=0
|
148
|
+
- CI_NODE_TOTAL=2 CI_NODE_INDEX=1
|
149
|
+
|
150
|
+
Such configuration will generate matrix with 2 following ENV rows:
|
151
|
+
|
152
|
+
CI_NODE_TOTAL=2 CI_NODE_INDEX=0 RAILS_ENV=test MY_GLOBAL_VAR=123
|
153
|
+
CI_NODE_TOTAL=2 CI_NODE_INDEX=1 RAILS_ENV=test MY_GLOBAL_VAR=123
|
154
|
+
|
155
|
+
More info about global and matrix ENV configuration in [travis docs](http://docs.travis-ci.com/user/build-configuration/#Environment-variables).
|
156
|
+
|
157
|
+
### Info for semaphoreapp.com users
|
158
|
+
|
159
|
+
#### Step 1
|
160
|
+
|
161
|
+
For the first time run all specs at once with enabled report generator. Set up your build command:
|
162
|
+
|
163
|
+
KNAPSACK_GENERATE_REPORT=true bundle exec rspec spec
|
164
|
+
|
165
|
+
After tests pass your should copy knapsack json report which is rendered at the end of rspec results. Save it into your repository as `knapsack_report.json` file and commit.
|
166
|
+
|
167
|
+
#### Step 2
|
168
|
+
|
169
|
+
Knapsack supports semaphoreapp ENVs `SEMAPHORE_THREAD_COUNT` and `SEMAPHORE_CURRENT_THREAD`. The only thing you need to do is set up knapsack rspec command for as many threads as you need. Here is an example:
|
170
|
+
|
171
|
+
# thread 1
|
172
|
+
bundle exec rake knapsack:rspec
|
173
|
+
|
174
|
+
# thread 2
|
175
|
+
bundle exec rake knapsack:rspec
|
176
|
+
|
177
|
+
Tests will be split across threads.
|
178
|
+
|
116
179
|
## Tests
|
117
180
|
|
118
181
|
### Spec
|
@@ -146,3 +209,7 @@ Specs in `spec_examples/leftover` take more than 3 seconds. This should cause a
|
|
146
209
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
147
210
|
4. Push to the branch (`git push origin my-new-feature`)
|
148
211
|
5. Create a new Pull Request
|
212
|
+
|
213
|
+
## Acknowledgements
|
214
|
+
|
215
|
+
Many thanks to [Małgorzata Nowak](https://github.com/informatykgosia) for beautiful logo.
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/knapsack.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["ArturT"]
|
10
10
|
spec.email = ["arturtrzop@gmail.com"]
|
11
11
|
spec.summary = %q{Parallel specs across CI server nodes based on each spec file's time execution.}
|
12
|
-
spec.description = %q{Parallel specs across CI server nodes based on each spec file's time execution. It generates spec time execution report and uses it for
|
12
|
+
spec.description = %q{Parallel specs across CI server nodes based on each spec file's time execution. It generates a spec time execution report and uses it for future test runs.}
|
13
13
|
spec.homepage = "https://github.com/ArturT/knapsack"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
data/lib/knapsack/config.rb
CHANGED
@@ -6,11 +6,11 @@ module Knapsack
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def ci_node_total
|
9
|
-
ENV['CI_NODE_TOTAL'] || ENV['CIRCLE_NODE_TOTAL'] || 1
|
9
|
+
ENV['CI_NODE_TOTAL'] || ENV['CIRCLE_NODE_TOTAL'] || ENV['SEMAPHORE_THREAD_COUNT'] || 1
|
10
10
|
end
|
11
11
|
|
12
12
|
def ci_node_index
|
13
|
-
ENV['CI_NODE_INDEX'] || ENV['CIRCLE_NODE_INDEX'] || 0
|
13
|
+
ENV['CI_NODE_INDEX'] || ENV['CIRCLE_NODE_INDEX'] || semaphore_current_thread || 0
|
14
14
|
end
|
15
15
|
|
16
16
|
def spec_pattern
|
@@ -28,6 +28,13 @@ module Knapsack
|
|
28
28
|
def generate_report
|
29
29
|
ENV['KNAPSACK_GENERATE_REPORT'] || false
|
30
30
|
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def semaphore_current_thread
|
35
|
+
index = ENV['SEMAPHORE_CURRENT_THREAD']
|
36
|
+
index.to_i - 1 if index
|
37
|
+
end
|
31
38
|
end
|
32
39
|
end
|
33
40
|
end
|
@@ -29,7 +29,6 @@ module Knapsack
|
|
29
29
|
|
30
30
|
def assign_spec_files_to_node
|
31
31
|
default_node_specs
|
32
|
-
@node_index = 0
|
33
32
|
post_assign_spec_files_to_node
|
34
33
|
end
|
35
34
|
|
@@ -60,11 +59,6 @@ module Knapsack
|
|
60
59
|
def default_report
|
61
60
|
Knapsack.report.open
|
62
61
|
end
|
63
|
-
|
64
|
-
def update_node_index
|
65
|
-
@node_index += 1
|
66
|
-
@node_index = 0 if @node_index == ci_node_total
|
67
|
-
end
|
68
62
|
end
|
69
63
|
end
|
70
64
|
end
|
@@ -12,9 +12,11 @@ module Knapsack
|
|
12
12
|
private
|
13
13
|
|
14
14
|
def post_assign_spec_files_to_node
|
15
|
+
node_index = 0
|
15
16
|
leftover_specs.each do |spec_file|
|
16
|
-
node_specs[
|
17
|
-
|
17
|
+
node_specs[node_index] << spec_file
|
18
|
+
node_index += 1
|
19
|
+
node_index %= ci_node_total
|
18
20
|
end
|
19
21
|
end
|
20
22
|
|
@@ -43,20 +43,21 @@ module Knapsack
|
|
43
43
|
|
44
44
|
def assign_slow_spec_files
|
45
45
|
@not_assigned_spec_files = []
|
46
|
-
|
46
|
+
node_index = 0
|
47
47
|
sorted_report_with_existing_specs.each do |spec_file_with_time|
|
48
|
-
assign_slow_spec_file(spec_file_with_time)
|
49
|
-
|
48
|
+
assign_slow_spec_file(node_index, spec_file_with_time)
|
49
|
+
node_index += 1
|
50
|
+
node_index %= ci_node_total
|
50
51
|
end
|
51
52
|
end
|
52
53
|
|
53
|
-
def assign_slow_spec_file(spec_file_with_time)
|
54
|
+
def assign_slow_spec_file(node_index, spec_file_with_time)
|
54
55
|
time = spec_file_with_time[1]
|
55
|
-
time_left = node_specs[
|
56
|
+
time_left = node_specs[node_index][:time_left] - time
|
56
57
|
|
57
|
-
if time_left >= 0 or node_specs[
|
58
|
-
node_specs[
|
59
|
-
node_specs[
|
58
|
+
if time_left >= 0 or node_specs[node_index][:spec_files_with_time].empty?
|
59
|
+
node_specs[node_index][:time_left] -= time
|
60
|
+
node_specs[node_index][:spec_files_with_time] << spec_file_with_time
|
60
61
|
else
|
61
62
|
@not_assigned_spec_files << spec_file_with_time
|
62
63
|
end
|
data/lib/knapsack/version.rb
CHANGED
@@ -26,6 +26,11 @@ describe Knapsack::Config do
|
|
26
26
|
before { stub_const("ENV", { 'CIRCLE_NODE_TOTAL' => 4 }) }
|
27
27
|
it { should eql 4 }
|
28
28
|
end
|
29
|
+
|
30
|
+
context 'when SEMAPHORE_THREAD_COUNT has value' do
|
31
|
+
before { stub_const("ENV", { 'SEMAPHORE_THREAD_COUNT' => 3 }) }
|
32
|
+
it { should eql 3 }
|
33
|
+
end
|
29
34
|
end
|
30
35
|
|
31
36
|
context "when ENV doesn't exist" do
|
@@ -46,6 +51,11 @@ describe Knapsack::Config do
|
|
46
51
|
before { stub_const("ENV", { 'CIRCLE_NODE_INDEX' => 2 }) }
|
47
52
|
it { should eql 2 }
|
48
53
|
end
|
54
|
+
|
55
|
+
context 'when SEMAPHORE_CURRENT_THREAD has value' do
|
56
|
+
before { stub_const("ENV", { 'SEMAPHORE_CURRENT_THREAD' => 1 }) }
|
57
|
+
it { should eql 0 }
|
58
|
+
end
|
49
59
|
end
|
50
60
|
|
51
61
|
context "when ENV doesn't exist" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knapsack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.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: 2014-
|
11
|
+
date: 2014-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
- !ruby/object:Gem::Version
|
88
88
|
version: '0'
|
89
89
|
description: Parallel specs across CI server nodes based on each spec file's time
|
90
|
-
execution. It generates spec time execution report and uses it for
|
90
|
+
execution. It generates a spec time execution report and uses it for future test
|
91
91
|
runs.
|
92
92
|
email:
|
93
93
|
- arturtrzop@gmail.com
|
@@ -104,6 +104,10 @@ files:
|
|
104
104
|
- README.md
|
105
105
|
- Rakefile
|
106
106
|
- TODO.md
|
107
|
+
- docs/images/logos/knapsack-@2.png
|
108
|
+
- docs/images/logos/knapsack-logo-@2.png
|
109
|
+
- docs/images/logos/knapsack-logo.png
|
110
|
+
- docs/images/logos/knapsack.png
|
107
111
|
- docs/images/with_knapsack.png
|
108
112
|
- docs/images/without_knapsack.png
|
109
113
|
- knapsack.gemspec
|