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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7b9017e6211e870280789b77926d157894d6ea0a
4
- data.tar.gz: 72749308b9dcc9737efb3a210853c7c69d17669d
3
+ metadata.gz: a530e320acebeb3933454ddac789a2efa10c2f16
4
+ data.tar.gz: ba2fdacf747a217b3e9c69d43639f30035c73b0a
5
5
  SHA512:
6
- metadata.gz: 5a83dd2ef1307dd014a8ec3151e959e2806551a11f238a4f7d06bb80c3b6422a33b88b0f13b1c8e92c4ec86a5b8605a74b5f76c83ad644d7d5eb8f58954c5171
7
- data.tar.gz: 2fa61c851548c36e23dd31888d1bffcaa2226eaf56893e92bba7bec4d4547b6a6f47477a219fde05f698b28b524d618f96a7836428b3ce30327dc1681a422f82
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: https://github.com/KnapsackPro/knapsack_pro-ruby/issues/15
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: 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::TestFilePresenter.paths(response['test_files'])
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,11 @@
1
+ module KnapsackPro
2
+ module Crypto
3
+ class Digestor
4
+ def self.salt_hexdigest(path)
5
+ salt = KnapsackPro::Config::Env.salt
6
+ str = salt + path
7
+ Digest::SHA2.hexdigest(str)
8
+ end
9
+ end
10
+ end
11
+ 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
@@ -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: test_files,
19
+ test_files: encrypted_test_files,
18
20
  )
19
21
  connection = KnapsackPro::Client::Connection.new(action)
20
22
  response = connection.call
@@ -0,0 +1,7 @@
1
+ module KnapsackPro
2
+ class Utils
3
+ def self.unsymbolize(obj)
4
+ JSON.parse(obj.to_json)
5
+ end
6
+ end
7
+ end
@@ -1,3 +1,3 @@
1
1
  module KnapsackPro
2
- VERSION = '0.10.0'
2
+ VERSION = '0.11.0'
3
3
  end
@@ -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
@@ -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: 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: 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.10.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-06-28 00:00:00.000000000 Z
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