knapsack_pro 0.10.0 → 0.11.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 +6 -0
- data/README.md +52 -3
- data/lib/knapsack_pro.rb +5 -0
- data/lib/knapsack_pro/allocator.rb +4 -2
- data/lib/knapsack_pro/config/env.rb +12 -0
- data/lib/knapsack_pro/crypto/decryptor.rb +56 -0
- data/lib/knapsack_pro/crypto/digestor.rb +11 -0
- data/lib/knapsack_pro/crypto/encryptor.rb +33 -0
- data/lib/knapsack_pro/report.rb +3 -1
- data/lib/knapsack_pro/utils.rb +7 -0
- data/lib/knapsack_pro/version.rb +1 -1
- data/lib/tasks/encrypted_test_file_names.rake +39 -0
- data/lib/tasks/salt.rake +20 -0
- data/spec/knapsack_pro/allocator_spec.rb +8 -1
- data/spec/knapsack_pro/config/env_spec.rb +50 -0
- data/spec/knapsack_pro/crypto/decryptor_spec.rb +81 -0
- data/spec/knapsack_pro/crypto/digestor_spec.rb +13 -0
- data/spec/knapsack_pro/crypto/encryptor_spec.rb +58 -0
- data/spec/knapsack_pro/report_spec.rb +7 -1
- data/spec/knapsack_pro/utils_spec.rb +19 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a530e320acebeb3933454ddac789a2efa10c2f16
|
4
|
+
data.tar.gz: ba2fdacf747a217b3e9c69d43639f30035c73b0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b102cd1ba0c0e1e4e600f87eb2726731b5b327f34c34f6cc968e951a9b0f88dcfc07445a64e5faca3051285a7966d1e656f8b14b756393bc8f696b1c17275996
|
7
|
+
data.tar.gz: ef75c12a4f12ba7e1d9be5a3d00e537f51d6c00d59eec785db9c10d0a36177932a1569fa7e8687707470dbb5533a46430e4e90ac9786a0ff7369e103653402a4
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
|
3
3
|
* TODO
|
4
4
|
|
5
|
+
### 0.11.0
|
6
|
+
|
7
|
+
* Add test file names encryption
|
8
|
+
|
9
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v0.10.0...v0.11.0
|
10
|
+
|
5
11
|
### 0.10.0
|
6
12
|
|
7
13
|
* Add new environment variable `KNAPSACK_PRO_FIXED_TEST_SUITE_SPLIT`. The default value is true.
|
data/README.md
CHANGED
@@ -76,12 +76,17 @@ For instance when you will run tests with rake knapsack_pro:rspec then:
|
|
76
76
|
- [Passing arguments to minitest](#passing-arguments-to-minitest)
|
77
77
|
- [Passing arguments to spinach](#passing-arguments-to-spinach)
|
78
78
|
- [Knapsack Pro binary](#knapsack-pro-binary)
|
79
|
+
- [Test file names encryption](#test-file-names-encryption)
|
80
|
+
- [How to enable test file names encryption?](#how-to-enable-test-file-names-encryption)
|
81
|
+
- [How to debug test file names?](#how-to-debug-test-file-names)
|
79
82
|
- [Supported CI providers](#supported-ci-providers)
|
80
83
|
- [Info for CircleCI users](#info-for-circleci-users)
|
81
84
|
- [Info for Travis users](#info-for-travis-users)
|
82
85
|
- [Info for semaphoreapp.com users](#info-for-semaphoreappcom-users)
|
83
86
|
- [Info for buildkite.com users](#info-for-buildkitecom-users)
|
84
87
|
- [Info for snap-ci.com users](#info-for-snap-cicom-users)
|
88
|
+
- [FAQ](#faq)
|
89
|
+
- [How to run tests for particular CI node in your development environment](#how-to-run-tests-for-particular-ci-node-in-your-development-environment)
|
85
90
|
- [Gem tests](#gem-tests)
|
86
91
|
- [Spec](#spec)
|
87
92
|
- [Contributing](#contributing)
|
@@ -295,12 +300,12 @@ In case when you use other CI provider for instance [Jenkins](https://jenkins-ci
|
|
295
300
|
|
296
301
|
* you expect to run the same subset of test suite multiple times for the same node (for instance your would like to retry only single CI node that failed)
|
297
302
|
|
298
|
-
Example of issue:
|
303
|
+
Example of issue:
|
304
|
+
* https://github.com/KnapsackPro/knapsack_pro-ruby/issues/15
|
305
|
+
* https://github.com/KnapsackPro/knapsack_pro-ruby/issues/12
|
299
306
|
|
300
307
|
* you start your tests not at the same time across your CI nodes. For instance, one of the CI node finished faster than the other CI node started. This would change the seed for the second CI node that started later.
|
301
308
|
|
302
|
-
Example of issue: https://github.com/KnapsackPro/knapsack_pro-ruby/issues/12
|
303
|
-
|
304
309
|
#### Environment variables for debugging gem
|
305
310
|
|
306
311
|
`KNAPSACK_PRO_ENDPOINT` - Default value is `http://api.knapsackpro.com` which is endpoint for [Knapsack Pro API](http://docs.knapsackpro.com).
|
@@ -352,6 +357,34 @@ You can install knapsack_pro globally and use binary. For instance:
|
|
352
357
|
|
353
358
|
This is optional way of using knapsack_pro when you don't want to add it to `Gemfile`.
|
354
359
|
|
360
|
+
### Test file names encryption
|
361
|
+
|
362
|
+
knapsack_pro gem collects information about you test file names and time execution. Those data are stored on KnapsackPro.com server.
|
363
|
+
If your test file names are sensitive data then you can encrypt the names before sending them to KnapsackPro.com API.
|
364
|
+
|
365
|
+
By default, encryption is disabled because knapsack_pro can use your test files names to prepare better test suite split when the time execution data are not yet collected on KnapsackPro.com server.
|
366
|
+
When you will enable test file names encryption then your first test suite split may be less optimal than it could be.
|
367
|
+
|
368
|
+
Each test file name is generated with `Digest::SHA2.hexdigest` method and 64 chars salt.
|
369
|
+
|
370
|
+
#### How to enable test file names encryption?
|
371
|
+
|
372
|
+
First you need to add environment variable `KNAPSACK_PRO_TEST_FILES_ENCRYPTED=true` to your CI server.
|
373
|
+
|
374
|
+
Next step is to generate salt which will be used to encrypt test file names.
|
375
|
+
|
376
|
+
$ bundle exec rake knapsack_pro:salt
|
377
|
+
|
378
|
+
Add to your CI server generated environment variable `KNAPSACK_PRO_SALT`.
|
379
|
+
|
380
|
+
#### How to debug test file names?
|
381
|
+
|
382
|
+
If you need to check what is the encryption hash for particular test file your can check that with the rake task:
|
383
|
+
|
384
|
+
$ KNAPSACK_PRO_SALT=xxx bundle exec rake knapsack_pro:encrypted_test_file_names[rspec]
|
385
|
+
|
386
|
+
You can pass the name of test runner like rspec, minitest, cucumber, spinach as argument to rake task.
|
387
|
+
|
355
388
|
### Supported CI providers
|
356
389
|
|
357
390
|
#### Info for CircleCI users
|
@@ -492,6 +525,22 @@ Knapsack Pro supports snap-ci.com ENVs `SNAP_WORKER_TOTAL` and `SNAP_WORKER_INDE
|
|
492
525
|
|
493
526
|
Please remember to set up token like `KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC` as global environment.
|
494
527
|
|
528
|
+
## FAQ
|
529
|
+
|
530
|
+
### How to run tests for particular CI node in your development environment
|
531
|
+
|
532
|
+
In your development environment you can debug tests that were run on the particular CI node.
|
533
|
+
For instance to run subset of tests for the first CI node with specified seed you can do.
|
534
|
+
|
535
|
+
KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC=token \
|
536
|
+
KNAPSACK_PRO_REPOSITORY_ADAPTER=git \
|
537
|
+
KNAPSACK_PRO_PROJECT_DIR=~/projects/rails-app \
|
538
|
+
KNAPSACK_PRO_CI_NODE_TOTAL=2 \
|
539
|
+
KNAPSACK_PRO_CI_NODE_INDEX=0 \
|
540
|
+
bundle exec rake "knapsack_pro:rspec[--seed 123]"
|
541
|
+
|
542
|
+
Above example is for RSpec. You can use respectively rake task name and token environment variable when you want to run tests for minitest, cucumber or spinach.
|
543
|
+
|
495
544
|
## Gem tests
|
496
545
|
|
497
546
|
### Spec
|
data/lib/knapsack_pro.rb
CHANGED
@@ -5,7 +5,9 @@ require 'json'
|
|
5
5
|
require 'uri'
|
6
6
|
require 'rake/testtask'
|
7
7
|
require 'timecop'
|
8
|
+
require 'digest'
|
8
9
|
require_relative 'knapsack_pro/version'
|
10
|
+
require_relative 'knapsack_pro/utils'
|
9
11
|
require_relative 'knapsack_pro/logger_wrapper'
|
10
12
|
require_relative 'knapsack_pro/config/ci/base'
|
11
13
|
require_relative 'knapsack_pro/config/ci/circle'
|
@@ -44,6 +46,9 @@ require_relative 'knapsack_pro/runners/rspec_runner'
|
|
44
46
|
require_relative 'knapsack_pro/runners/cucumber_runner'
|
45
47
|
require_relative 'knapsack_pro/runners/minitest_runner'
|
46
48
|
require_relative 'knapsack_pro/runners/spinach_runner'
|
49
|
+
require_relative 'knapsack_pro/crypto/encryptor'
|
50
|
+
require_relative 'knapsack_pro/crypto/decryptor'
|
51
|
+
require_relative 'knapsack_pro/crypto/digestor'
|
47
52
|
|
48
53
|
module KnapsackPro
|
49
54
|
class << self
|
@@ -8,18 +8,20 @@ module KnapsackPro
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def test_file_paths
|
11
|
+
encrypted_test_files = KnapsackPro::Crypto::Encryptor.call(test_files)
|
11
12
|
action = KnapsackPro::Client::API::V1::BuildDistributions.subset(
|
12
13
|
commit_hash: repository_adapter.commit_hash,
|
13
14
|
branch: repository_adapter.branch,
|
14
15
|
node_total: ci_node_total,
|
15
16
|
node_index: ci_node_index,
|
16
|
-
test_files:
|
17
|
+
test_files: encrypted_test_files,
|
17
18
|
)
|
18
19
|
connection = KnapsackPro::Client::Connection.new(action)
|
19
20
|
response = connection.call
|
20
21
|
if connection.success?
|
21
22
|
raise ArgumentError.new(response) if connection.errors?
|
22
|
-
KnapsackPro::
|
23
|
+
decrypted_test_files = KnapsackPro::Crypto::Decryptor.call(test_files, response['test_files'])
|
24
|
+
KnapsackPro::TestFilePresenter.paths(decrypted_test_files)
|
23
25
|
else
|
24
26
|
test_flat_distributor = KnapsackPro::TestFlatDistributor.new(test_files, ci_node_total)
|
25
27
|
test_files_for_node_index = test_flat_distributor.test_files_for_node(ci_node_index)
|
@@ -45,6 +45,18 @@ module KnapsackPro
|
|
45
45
|
recording_enabled == 'true'
|
46
46
|
end
|
47
47
|
|
48
|
+
def test_files_encrypted
|
49
|
+
ENV['KNAPSACK_PRO_TEST_FILES_ENCRYPTED']
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_files_encrypted?
|
53
|
+
test_files_encrypted == 'true'
|
54
|
+
end
|
55
|
+
|
56
|
+
def salt
|
57
|
+
required_env('KNAPSACK_PRO_SALT')
|
58
|
+
end
|
59
|
+
|
48
60
|
def endpoint
|
49
61
|
env_name = 'KNAPSACK_PRO_ENDPOINT'
|
50
62
|
return ENV[env_name] if ENV[env_name]
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module KnapsackPro
|
2
|
+
module Crypto
|
3
|
+
class Decryptor
|
4
|
+
class MissingEncryptedTestFileError < StandardError; end
|
5
|
+
class TooManyEncryptedTestFilesError < StandardError; end
|
6
|
+
|
7
|
+
def self.call(test_files, encrypted_test_files)
|
8
|
+
if KnapsackPro::Config::Env.test_files_encrypted?
|
9
|
+
new(test_files, encrypted_test_files).call
|
10
|
+
else
|
11
|
+
# those test files are not encrypted
|
12
|
+
encrypted_test_files
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(test_files, encrypted_test_files)
|
17
|
+
@test_files = test_files
|
18
|
+
@encrypted_test_files = encrypted_test_files
|
19
|
+
end
|
20
|
+
|
21
|
+
def call
|
22
|
+
decrypted_test_files = []
|
23
|
+
|
24
|
+
test_files.each do |test_file|
|
25
|
+
encrypted_path = Digestor.salt_hexdigest(test_file['path'])
|
26
|
+
encrypted_test_file = find_encrypted_test_file(encrypted_path)
|
27
|
+
next if encrypted_test_file.nil?
|
28
|
+
|
29
|
+
decrypted_test_file = encrypted_test_file.dup
|
30
|
+
decrypted_test_file['path'] = test_file['path']
|
31
|
+
|
32
|
+
decrypted_test_files << decrypted_test_file
|
33
|
+
end
|
34
|
+
|
35
|
+
decrypted_test_files
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
attr_reader :test_files,
|
41
|
+
:encrypted_test_files
|
42
|
+
|
43
|
+
def find_encrypted_test_file(encrypted_path)
|
44
|
+
test_files = encrypted_test_files.select do |t|
|
45
|
+
t['path'] == encrypted_path
|
46
|
+
end
|
47
|
+
|
48
|
+
if test_files.size == 1
|
49
|
+
test_files.first
|
50
|
+
elsif test_files.size > 1
|
51
|
+
raise TooManyEncryptedTestFilesError.new("Found more than one encrypted test file for encrypted path #{encrypted_path}")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module KnapsackPro
|
2
|
+
module Crypto
|
3
|
+
class Encryptor
|
4
|
+
def self.call(test_files)
|
5
|
+
if KnapsackPro::Config::Env.test_files_encrypted?
|
6
|
+
new(test_files).call
|
7
|
+
else
|
8
|
+
test_files
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(test_files)
|
13
|
+
@test_files = test_files
|
14
|
+
end
|
15
|
+
|
16
|
+
def call
|
17
|
+
encrypted_test_files = []
|
18
|
+
|
19
|
+
test_files.each do |test_file|
|
20
|
+
test_file_dup = test_file.dup
|
21
|
+
test_file_dup['path'] = Digestor.salt_hexdigest(test_file['path'])
|
22
|
+
encrypted_test_files << test_file_dup
|
23
|
+
end
|
24
|
+
|
25
|
+
encrypted_test_files
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
attr_reader :test_files
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/knapsack_pro/report.rb
CHANGED
@@ -9,12 +9,14 @@ module KnapsackPro
|
|
9
9
|
end
|
10
10
|
|
11
11
|
repository_adapter = KnapsackPro::RepositoryAdapterInitiator.call
|
12
|
+
test_files = KnapsackPro::Utils.unsymbolize(test_files)
|
13
|
+
encrypted_test_files = KnapsackPro::Crypto::Encryptor.call(test_files)
|
12
14
|
action = KnapsackPro::Client::API::V1::BuildSubsets.create(
|
13
15
|
commit_hash: repository_adapter.commit_hash,
|
14
16
|
branch: repository_adapter.branch,
|
15
17
|
node_total: KnapsackPro::Config::Env.ci_node_total,
|
16
18
|
node_index: KnapsackPro::Config::Env.ci_node_index,
|
17
|
-
test_files:
|
19
|
+
test_files: encrypted_test_files,
|
18
20
|
)
|
19
21
|
connection = KnapsackPro::Client::Connection.new(action)
|
20
22
|
response = connection.call
|
data/lib/knapsack_pro/version.rb
CHANGED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'knapsack_pro'
|
2
|
+
|
3
|
+
namespace :knapsack_pro do
|
4
|
+
task :encrypted_test_file_names, [:adapter] do |_, args|
|
5
|
+
adapter = args[:adapter]
|
6
|
+
|
7
|
+
adapter_class = case adapter
|
8
|
+
when 'rspec'
|
9
|
+
KnapsackPro::Adapters::RSpecAdapter
|
10
|
+
when 'minitest'
|
11
|
+
KnapsackPro::Adapters::MinitestAdapter
|
12
|
+
when 'cucumber'
|
13
|
+
KnapsackPro::Adapters::CucumberAdapter
|
14
|
+
when 'spinach'
|
15
|
+
KnapsackPro::Adapters::SpinachAdapter
|
16
|
+
else
|
17
|
+
raise('Provide adapter name like rspec, minitest, cucumber, spinach')
|
18
|
+
end
|
19
|
+
|
20
|
+
test_file_pattern = KnapsackPro::TestFilePattern.call(adapter_class)
|
21
|
+
test_files = KnapsackPro::TestFileFinder.call(test_file_pattern)
|
22
|
+
|
23
|
+
test_file_names = []
|
24
|
+
test_files.each do |t|
|
25
|
+
test_file_names << {
|
26
|
+
'path' => t['path'],
|
27
|
+
'decrypted_path' => t['path'],
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
encrypted_test_files = KnapsackPro::Crypto::Encryptor.new(test_file_names).call
|
32
|
+
|
33
|
+
encrypted_test_files.each do |t|
|
34
|
+
puts "path: #{t['decrypted_path']}"
|
35
|
+
puts "encrypted path: #{t['path']}"
|
36
|
+
puts
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/tasks/salt.rake
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
namespace :knapsack_pro do
|
4
|
+
task :salt, [:size] do |_, args|
|
5
|
+
default_size = 32
|
6
|
+
size = (args[:size] || default_size).to_i
|
7
|
+
|
8
|
+
if size >= default_size
|
9
|
+
salt = SecureRandom.hex(size)
|
10
|
+
puts 'Set environment variable on your CI server:'
|
11
|
+
puts "KNAPSACK_PRO_SALT=#{salt}"
|
12
|
+
puts
|
13
|
+
puts "If you need longer salt you can provide the size:"
|
14
|
+
puts "$ bundle exec rake knapsack_pro:salt[32]"
|
15
|
+
puts "Default size 32 generates 64 chars."
|
16
|
+
else
|
17
|
+
puts "Salt must have at least 64 chars! You provided size #{size} which generates #{size*2} chars."
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -19,13 +19,16 @@ describe KnapsackPro::Allocator do
|
|
19
19
|
subject { allocator.test_file_paths }
|
20
20
|
|
21
21
|
before do
|
22
|
+
encrypted_test_files = double
|
23
|
+
expect(KnapsackPro::Crypto::Encryptor).to receive(:call).with(test_files).and_return(encrypted_test_files)
|
24
|
+
|
22
25
|
action = double
|
23
26
|
expect(KnapsackPro::Client::API::V1::BuildDistributions).to receive(:subset).with({
|
24
27
|
commit_hash: repository_adapter.commit_hash,
|
25
28
|
branch: repository_adapter.branch,
|
26
29
|
node_total: ci_node_total,
|
27
30
|
node_index: ci_node_index,
|
28
|
-
test_files:
|
31
|
+
test_files: encrypted_test_files,
|
29
32
|
}).and_return(action)
|
30
33
|
|
31
34
|
connection = instance_double(KnapsackPro::Client::Connection,
|
@@ -57,6 +60,10 @@ describe KnapsackPro::Allocator do
|
|
57
60
|
}
|
58
61
|
end
|
59
62
|
|
63
|
+
before do
|
64
|
+
expect(KnapsackPro::Crypto::Decryptor).to receive(:call).with(test_files, response['test_files']).and_call_original
|
65
|
+
end
|
66
|
+
|
60
67
|
it { should eq ['a_spec.rb', 'b_spec.rb'] }
|
61
68
|
end
|
62
69
|
end
|
@@ -178,6 +178,56 @@ describe KnapsackPro::Config::Env do
|
|
178
178
|
end
|
179
179
|
end
|
180
180
|
|
181
|
+
describe '.test_files_encrypted' do
|
182
|
+
subject { described_class.test_files_encrypted }
|
183
|
+
|
184
|
+
context 'when ENV exists' do
|
185
|
+
let(:test_files_encrypted) { 'true' }
|
186
|
+
before { stub_const("ENV", { 'KNAPSACK_PRO_TEST_FILES_ENCRYPTED' => test_files_encrypted }) }
|
187
|
+
it { should eq test_files_encrypted }
|
188
|
+
end
|
189
|
+
|
190
|
+
context "when ENV doesn't exist" do
|
191
|
+
it { should be_nil }
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
describe '.test_files_encrypted?' do
|
196
|
+
subject { described_class.test_files_encrypted? }
|
197
|
+
|
198
|
+
before do
|
199
|
+
expect(described_class).to receive(:test_files_encrypted).and_return(test_files_encrypted)
|
200
|
+
end
|
201
|
+
|
202
|
+
context 'when enabled' do
|
203
|
+
let(:test_files_encrypted) { 'true' }
|
204
|
+
|
205
|
+
it { should be true }
|
206
|
+
end
|
207
|
+
|
208
|
+
context 'when disabled' do
|
209
|
+
let(:test_files_encrypted) { nil }
|
210
|
+
|
211
|
+
it { should be false }
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
describe '.salt' do
|
216
|
+
subject { described_class.salt }
|
217
|
+
|
218
|
+
context 'when ENV exists' do
|
219
|
+
let(:salt) { '123' }
|
220
|
+
before { stub_const("ENV", { 'KNAPSACK_PRO_SALT' => salt }) }
|
221
|
+
it { should eq salt }
|
222
|
+
end
|
223
|
+
|
224
|
+
context "when ENV doesn't exist" do
|
225
|
+
it do
|
226
|
+
expect { subject }.to raise_error('Missing environment variable KNAPSACK_PRO_SALT')
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
181
231
|
describe '.endpoint' do
|
182
232
|
subject { described_class.endpoint }
|
183
233
|
|
@@ -0,0 +1,81 @@
|
|
1
|
+
describe KnapsackPro::Crypto::Decryptor do
|
2
|
+
let(:test_files) do
|
3
|
+
[
|
4
|
+
{ 'path' => 'a_spec.rb' },
|
5
|
+
{ 'path' => 'b_spec.rb' },
|
6
|
+
]
|
7
|
+
end
|
8
|
+
let(:encrypted_test_files) do
|
9
|
+
[
|
10
|
+
{ 'path' => '93131469d5aee8158473f9945847cd411ba975644b617897b7c33164adc55038', 'time_execution' => 1.2 },
|
11
|
+
{ 'path' => '716143a50194e2d2173b757b3418564f5efd12ce3c52332c02db60bb70c240bc', 'time_execution' => 2.3 },
|
12
|
+
]
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:decryptor) { described_class.new(test_files, encrypted_test_files) }
|
16
|
+
|
17
|
+
describe '.call' do
|
18
|
+
subject { described_class.call(test_files, encrypted_test_files) }
|
19
|
+
|
20
|
+
before do
|
21
|
+
expect(KnapsackPro::Config::Env).to receive(:test_files_encrypted?).and_return(test_files_encrypted?)
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when test files encrypted flag enabled' do
|
25
|
+
let(:test_files_encrypted?) { true }
|
26
|
+
let(:decryptor) { instance_double(described_class) }
|
27
|
+
|
28
|
+
it do
|
29
|
+
expect(described_class).to receive(:new).with(test_files, encrypted_test_files).and_return(decryptor)
|
30
|
+
result = double
|
31
|
+
expect(decryptor).to receive(:call).and_return(result)
|
32
|
+
|
33
|
+
expect(subject).to eq result
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'when test files encrypted flag disabled' do
|
38
|
+
let(:test_files_encrypted?) { false }
|
39
|
+
let(:encrypted_test_files) { double }
|
40
|
+
|
41
|
+
it { should eq encrypted_test_files }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#call' do
|
46
|
+
subject { decryptor.call }
|
47
|
+
|
48
|
+
before do
|
49
|
+
expect(KnapsackPro::Config::Env).to receive(:salt).at_least(1).and_return('123')
|
50
|
+
end
|
51
|
+
|
52
|
+
it do
|
53
|
+
should eq([
|
54
|
+
{ 'path' => 'a_spec.rb', 'time_execution' => 1.2 },
|
55
|
+
{ 'path' => 'b_spec.rb', 'time_execution' => 2.3 },
|
56
|
+
])
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'when missing encrypted test file' do
|
60
|
+
let(:encrypted_test_files) { [] }
|
61
|
+
|
62
|
+
it do
|
63
|
+
expect(subject).to eq []
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'when too many encrypted test files with the same encrypted path' do
|
68
|
+
let(:encrypted_test_files) do
|
69
|
+
[
|
70
|
+
{ 'path' => '93131469d5aee8158473f9945847cd411ba975644b617897b7c33164adc55038', 'time_execution' => 1.2 },
|
71
|
+
{ 'path' => '716143a50194e2d2173b757b3418564f5efd12ce3c52332c02db60bb70c240bc', 'time_execution' => 2.3 },
|
72
|
+
{ 'path' => '716143a50194e2d2173b757b3418564f5efd12ce3c52332c02db60bb70c240bc', 'time_execution' => 2.4 }, # duplicate
|
73
|
+
]
|
74
|
+
end
|
75
|
+
|
76
|
+
it do
|
77
|
+
expect { subject }.to raise_error(KnapsackPro::Crypto::Decryptor::TooManyEncryptedTestFilesError)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
describe KnapsackPro::Crypto::Digestor do
|
2
|
+
describe '.salt_hexdigest' do
|
3
|
+
let(:path) { 'a_spec.rb' }
|
4
|
+
|
5
|
+
subject { described_class.salt_hexdigest(path) }
|
6
|
+
|
7
|
+
before do
|
8
|
+
expect(KnapsackPro::Config::Env).to receive(:salt).at_least(1).and_return('123')
|
9
|
+
end
|
10
|
+
|
11
|
+
it { should eq '93131469d5aee8158473f9945847cd411ba975644b617897b7c33164adc55038' }
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
describe KnapsackPro::Crypto::Encryptor do
|
2
|
+
let(:test_files) do
|
3
|
+
[
|
4
|
+
{ 'path' => 'a_spec.rb', 'time_execution' => 1.2 },
|
5
|
+
{ 'path' => 'b_spec.rb', 'time_execution' => 2.3 },
|
6
|
+
]
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:encryptor) { described_class.new(test_files) }
|
10
|
+
|
11
|
+
describe '.call' do
|
12
|
+
subject { described_class.call(test_files) }
|
13
|
+
|
14
|
+
before do
|
15
|
+
expect(KnapsackPro::Config::Env).to receive(:test_files_encrypted?).and_return(test_files_encrypted?)
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when test files encrypted flag enabled' do
|
19
|
+
let(:test_files_encrypted?) { true }
|
20
|
+
let(:encryptor) { instance_double(described_class) }
|
21
|
+
|
22
|
+
it do
|
23
|
+
expect(described_class).to receive(:new).with(test_files).and_return(encryptor)
|
24
|
+
result = double
|
25
|
+
expect(encryptor).to receive(:call).and_return(result)
|
26
|
+
|
27
|
+
expect(subject).to eq result
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when test files encrypted flag disabled' do
|
32
|
+
let(:test_files_encrypted?) { false }
|
33
|
+
|
34
|
+
it { should eq test_files }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#call' do
|
39
|
+
subject { encryptor.call }
|
40
|
+
|
41
|
+
before do
|
42
|
+
expect(KnapsackPro::Config::Env).to receive(:salt).at_least(1).and_return('123')
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should not modify input test files array" do
|
46
|
+
test_files_original = Marshal.load(Marshal.dump(test_files))
|
47
|
+
subject
|
48
|
+
expect(test_files).to eq test_files_original
|
49
|
+
end
|
50
|
+
|
51
|
+
it do
|
52
|
+
should eq([
|
53
|
+
{ 'path' => '93131469d5aee8158473f9945847cd411ba975644b617897b7c33164adc55038', 'time_execution' => 1.2 },
|
54
|
+
{ 'path' => '716143a50194e2d2173b757b3418564f5efd12ce3c52332c02db60bb70c240bc', 'time_execution' => 2.3 },
|
55
|
+
])
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -27,6 +27,12 @@ describe KnapsackPro::Report do
|
|
27
27
|
repository_adapter = instance_double(KnapsackPro::RepositoryAdapters::EnvAdapter, commit_hash: commit_hash, branch: branch)
|
28
28
|
expect(KnapsackPro::RepositoryAdapterInitiator).to receive(:call).and_return(repository_adapter)
|
29
29
|
|
30
|
+
unsymbolize_test_files = double
|
31
|
+
expect(KnapsackPro::Utils).to receive(:unsymbolize).with(test_files).and_return(unsymbolize_test_files)
|
32
|
+
|
33
|
+
encrypted_test_files = double
|
34
|
+
expect(KnapsackPro::Crypto::Encryptor).to receive(:call).with(unsymbolize_test_files).and_return(encrypted_test_files)
|
35
|
+
|
30
36
|
node_total = double
|
31
37
|
node_index = double
|
32
38
|
expect(KnapsackPro::Config::Env).to receive(:ci_node_total).and_return(node_total)
|
@@ -38,7 +44,7 @@ describe KnapsackPro::Report do
|
|
38
44
|
branch: branch,
|
39
45
|
node_total: node_total,
|
40
46
|
node_index: node_index,
|
41
|
-
test_files:
|
47
|
+
test_files: encrypted_test_files,
|
42
48
|
}).and_return(action)
|
43
49
|
|
44
50
|
connection = instance_double(KnapsackPro::Client::Connection, success?: success?, errors?: errors?)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
describe KnapsackPro::Utils do
|
2
|
+
describe '.unsymbolize' do
|
3
|
+
let(:test_files) do
|
4
|
+
[
|
5
|
+
{ path: 'a_spec.rb', time_execution: 0.1 },
|
6
|
+
{ path: 'b_spec.rb', time_execution: 0.2 },
|
7
|
+
]
|
8
|
+
end
|
9
|
+
|
10
|
+
subject { described_class.unsymbolize(test_files) }
|
11
|
+
|
12
|
+
it do
|
13
|
+
should eq([
|
14
|
+
{ 'path' => 'a_spec.rb', 'time_execution' => 0.1 },
|
15
|
+
{ 'path' => 'b_spec.rb', 'time_execution' => 0.2 },
|
16
|
+
])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
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: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ArturT
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -223,6 +223,9 @@ files:
|
|
223
223
|
- lib/knapsack_pro/config/ci/snap_ci.rb
|
224
224
|
- lib/knapsack_pro/config/ci/travis.rb
|
225
225
|
- lib/knapsack_pro/config/env.rb
|
226
|
+
- lib/knapsack_pro/crypto/decryptor.rb
|
227
|
+
- lib/knapsack_pro/crypto/digestor.rb
|
228
|
+
- lib/knapsack_pro/crypto/encryptor.rb
|
226
229
|
- lib/knapsack_pro/logger_wrapper.rb
|
227
230
|
- lib/knapsack_pro/presenter.rb
|
228
231
|
- lib/knapsack_pro/report.rb
|
@@ -242,10 +245,13 @@ files:
|
|
242
245
|
- lib/knapsack_pro/test_file_presenter.rb
|
243
246
|
- lib/knapsack_pro/test_flat_distributor.rb
|
244
247
|
- lib/knapsack_pro/tracker.rb
|
248
|
+
- lib/knapsack_pro/utils.rb
|
245
249
|
- lib/knapsack_pro/version.rb
|
246
250
|
- lib/tasks/cucumber.rake
|
251
|
+
- lib/tasks/encrypted_test_file_names.rake
|
247
252
|
- lib/tasks/minitest.rake
|
248
253
|
- lib/tasks/rspec.rake
|
254
|
+
- lib/tasks/salt.rake
|
249
255
|
- lib/tasks/spinach.rake
|
250
256
|
- spec/fixtures/vcr_cassettes/api/v1/build_distributions/subset/invalid_test_suite_token.yml
|
251
257
|
- spec/fixtures/vcr_cassettes/api/v1/build_distributions/subset/success.yml
|
@@ -272,6 +278,9 @@ files:
|
|
272
278
|
- spec/knapsack_pro/config/ci/snap_ci_spec.rb
|
273
279
|
- spec/knapsack_pro/config/ci/travis_spec.rb
|
274
280
|
- spec/knapsack_pro/config/env_spec.rb
|
281
|
+
- spec/knapsack_pro/crypto/decryptor_spec.rb
|
282
|
+
- spec/knapsack_pro/crypto/digestor_spec.rb
|
283
|
+
- spec/knapsack_pro/crypto/encryptor_spec.rb
|
275
284
|
- spec/knapsack_pro/logger_wrapper_spec.rb
|
276
285
|
- spec/knapsack_pro/presenter_spec.rb
|
277
286
|
- spec/knapsack_pro/report_spec.rb
|
@@ -291,6 +300,7 @@ files:
|
|
291
300
|
- spec/knapsack_pro/test_file_presenter_spec.rb
|
292
301
|
- spec/knapsack_pro/test_flat_distributor_spec.rb
|
293
302
|
- spec/knapsack_pro/tracker_spec.rb
|
303
|
+
- spec/knapsack_pro/utils_spec.rb
|
294
304
|
- spec/knapsack_pro_spec.rb
|
295
305
|
- spec/spec_helper.rb
|
296
306
|
- spec/support/.gitkeep
|
@@ -354,6 +364,9 @@ test_files:
|
|
354
364
|
- spec/knapsack_pro/config/ci/snap_ci_spec.rb
|
355
365
|
- spec/knapsack_pro/config/ci/travis_spec.rb
|
356
366
|
- spec/knapsack_pro/config/env_spec.rb
|
367
|
+
- spec/knapsack_pro/crypto/decryptor_spec.rb
|
368
|
+
- spec/knapsack_pro/crypto/digestor_spec.rb
|
369
|
+
- spec/knapsack_pro/crypto/encryptor_spec.rb
|
357
370
|
- spec/knapsack_pro/logger_wrapper_spec.rb
|
358
371
|
- spec/knapsack_pro/presenter_spec.rb
|
359
372
|
- spec/knapsack_pro/report_spec.rb
|
@@ -373,6 +386,7 @@ test_files:
|
|
373
386
|
- spec/knapsack_pro/test_file_presenter_spec.rb
|
374
387
|
- spec/knapsack_pro/test_flat_distributor_spec.rb
|
375
388
|
- spec/knapsack_pro/tracker_spec.rb
|
389
|
+
- spec/knapsack_pro/utils_spec.rb
|
376
390
|
- spec/knapsack_pro_spec.rb
|
377
391
|
- spec/spec_helper.rb
|
378
392
|
- spec/support/.gitkeep
|