knapsack_pro 0.17.0 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/README.md +151 -2
  4. data/bin/knapsack_pro +1 -0
  5. data/knapsack_pro.gemspec +1 -1
  6. data/lib/knapsack_pro.rb +8 -0
  7. data/lib/knapsack_pro/adapters/base_adapter.rb +10 -0
  8. data/lib/knapsack_pro/adapters/rspec_adapter.rb +8 -0
  9. data/lib/knapsack_pro/allocator.rb +28 -14
  10. data/lib/knapsack_pro/allocator_builder.rb +1 -29
  11. data/lib/knapsack_pro/base_allocator_builder.rb +35 -0
  12. data/lib/knapsack_pro/client/api/v1/queues.rb +27 -0
  13. data/lib/knapsack_pro/config/ci/base.rb +3 -0
  14. data/lib/knapsack_pro/config/ci/buildkite.rb +4 -0
  15. data/lib/knapsack_pro/config/ci/circle.rb +4 -1
  16. data/lib/knapsack_pro/config/ci/semaphore.rb +4 -0
  17. data/lib/knapsack_pro/config/ci/snap_ci.rb +4 -0
  18. data/lib/knapsack_pro/config/ci/travis.rb +4 -0
  19. data/lib/knapsack_pro/config/env.rb +22 -0
  20. data/lib/knapsack_pro/config/env_generator.rb +19 -0
  21. data/lib/knapsack_pro/queue_allocator.rb +52 -0
  22. data/lib/knapsack_pro/queue_allocator_builder.rb +13 -0
  23. data/lib/knapsack_pro/report.rb +35 -0
  24. data/lib/knapsack_pro/runners/queue/base_runner.rb +34 -0
  25. data/lib/knapsack_pro/runners/queue/rspec_runner.rb +42 -0
  26. data/lib/knapsack_pro/task_loader.rb +1 -1
  27. data/lib/knapsack_pro/version.rb +1 -1
  28. data/lib/tasks/queue/rspec.rake +9 -0
  29. data/lib/tasks/salt.rake +0 -2
  30. data/spec/knapsack_pro/adapters/base_adapter_spec.rb +39 -8
  31. data/spec/knapsack_pro/adapters/rspec_adapter_spec.rb +11 -0
  32. data/spec/knapsack_pro/allocator_builder_spec.rb +2 -12
  33. data/spec/knapsack_pro/base_allocator_builder_spec.rb +22 -0
  34. data/spec/knapsack_pro/client/api/v1/queues_spec.rb +42 -0
  35. data/spec/knapsack_pro/config/ci/base_spec.rb +1 -0
  36. data/spec/knapsack_pro/config/ci/buildkite_spec.rb +13 -0
  37. data/spec/knapsack_pro/config/ci/circle_spec.rb +13 -0
  38. data/spec/knapsack_pro/config/ci/semaphore_spec.rb +13 -0
  39. data/spec/knapsack_pro/config/ci/snap_ci_spec.rb +13 -0
  40. data/spec/knapsack_pro/config/ci/travis_spec.rb +13 -0
  41. data/spec/knapsack_pro/config/env_generator_spec.rb +52 -0
  42. data/spec/knapsack_pro/config/env_spec.rb +90 -0
  43. data/spec/knapsack_pro/queue_allocator_builder_spec.rb +38 -0
  44. data/spec/knapsack_pro/queue_allocator_spec.rb +85 -0
  45. data/spec/knapsack_pro/report_spec.rb +69 -0
  46. data/spec/knapsack_pro/runners/queue/base_runner_spec.rb +67 -0
  47. data/spec/knapsack_pro/runners/queue/rspec_runner_spec.rb +118 -0
  48. metadata +26 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 377525e667c4025224f3d6df9b10f7f474b49ceb
4
- data.tar.gz: 7787796cc41143405f662de7dbbe5d46c50489f8
3
+ metadata.gz: 776a8b23ab2904168e0045473328847f98cf33ba
4
+ data.tar.gz: de729e204e176211b212fcbcbcd9b1962cc5b753
5
5
  SHA512:
6
- metadata.gz: e83e3e9032c126c1e9551d195b4858ad176dca3618c8892f19f14ec5fb16a2326748ae8558cb6e7bd5f1748addab180d142af3c63eb8d5f0c9ec2c89f4ac1928
7
- data.tar.gz: ce99dbd6384e65ab7163ec8f35b3bc540a72f4fc59482b7b44b4d85e0163a58a837b291611efede2c75b21908f30ecb4994aa00ca834c1a1a8bce26cbec72302
6
+ metadata.gz: e6e5a91f7d9acd006da5c5b5b37039f3aaf7bc180be673fb764fb4859495cc839d0d78d4f146bfdfd515b0cca8ac8dddb275440909b6046d22e5c1b2dd775fee
7
+ data.tar.gz: d17eca6592fcaf86c104d42b88aae035fc3ad7b4dfb058f35d984f2452455a1811f2255c46ffe40bfa4a79455eef952d9e58494577a24e6f8e4e392dd64fa6af
data/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  * TODO
4
4
 
5
+ ### 0.18.0
6
+
7
+ * Add support for knapsack_pro queue mode
8
+
9
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/20
10
+
11
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v0.17.0...v0.18.0
12
+
5
13
  ### 0.17.0
6
14
 
7
15
  * Enable fallback mode for SocketError when failed to open TCP connection to http or https API endpoint.
data/README.md CHANGED
@@ -21,7 +21,7 @@ __Would you like to try knapsack_pro gem?__ You can [get API token here](http://
21
21
 
22
22
  * If your __project is open source__ then you can use Knapsack Pro for free. Just add a link back to the page http://knapsackpro.com and please let me know via email (arturtrzop@gmail.com). I will mark your account on KnapsackPro.com as open source.
23
23
 
24
- * If your __project is commercial__ then I'd like to get feedback from you and work closely together to validate if the solution I'm building provide a value for the users. Switching to paid plan is a good way to validate that and a way to get support from happy users. Currently, there is no hard limit when the free trial is ending. I'm more interested in getting feedback from users in order to improve the tool. As I saw in the past people want to support the project and are asking for paid plan. Maybe you will be the next one who will join and support the project. Thanks!
24
+ * If your __project is commercial__ then I'd like to get feedback from you and work closely together to validate if the solution I'm building provide a value for the users. Switching to paid plan is a good way to validate that and a way to get support from happy users. Maybe you will be the next one who will join and support the project. Thanks!
25
25
 
26
26
  # How knapsack_pro works?
27
27
 
@@ -33,7 +33,7 @@ Next time when you will run tests you will get proper test files for each CI nod
33
33
 
34
34
  ## Details
35
35
 
36
- For instance when you will run tests with rake knapsack_pro:rspec then:
36
+ For instance when you will run tests with `rake knapsack_pro:rspec` then:
37
37
 
38
38
  * information about all your existing test files are sent to API http://docs.knapsackpro.com/api/v1/#build_distributions_subset_post
39
39
  * API returns which files should be executed on particular CI node (example KNAPSACK_PRO_CI_NODE_INDEX=0)
@@ -41,6 +41,8 @@ For instance when you will run tests with rake knapsack_pro:rspec then:
41
41
  * knapsack_pro will run test files which got from API
42
42
  * after tests finished knapsack_pro will send information about time execution of each file to API http://docs.knapsackpro.com/api/v1/#build_subsets_post so data can be used for future test runs
43
43
 
44
+ The knapsack_pro has also [queue mode](#queue-mode) to get most optimal test suite split.
45
+
44
46
  # Requirements
45
47
 
46
48
  * >= Ruby 2.0.0
@@ -66,6 +68,11 @@ For instance when you will run tests with rake knapsack_pro:rspec then:
66
68
  - [Repository adapter (How to set up 3 of 3)](#repository-adapter-how-to-set-up-3-of-3)
67
69
  - [When you NOT set global variable `KNAPSACK_PRO_REPOSITORY_ADAPTER` (default)](#when-you-not-set-global-variable-knapsack_pro_repository_adapter-default)
68
70
  - [When you set global variable `KNAPSACK_PRO_REPOSITORY_ADAPTER=git` (required when CI provider is not supported)](#when-you-set-global-variable-knapsack_pro_repository_adaptergit-required-when-ci-provider-is-not-supported)
71
+ - [Queue Mode](#queue-mode)
72
+ - [How queue mode works?](#how-queue-mode-works)
73
+ - [How to use queue mode?](#how-to-use-queue-mode)
74
+ - [Additional info about queue mode](#additional-info-about-queue-mode)
75
+ - [Supported test runners in queue mode](#supported-test-runners-in-queue-mode)
69
76
  - [Extra configuration for CI server](#extra-configuration-for-ci-server)
70
77
  - [Info about ENV variables](#info-about-env-variables)
71
78
  - [KNAPSACK_PRO_FIXED_TEST_SUITE_SPLITE (test suite split based on seed)](#knapsack_pro_fixed_test_suite_splite-test-suite-split-based-on-seed)
@@ -89,6 +96,14 @@ For instance when you will run tests with rake knapsack_pro:rspec then:
89
96
  - [How to run tests for particular CI node in your development environment](#how-to-run-tests-for-particular-ci-node-in-your-development-environment)
90
97
  - [What happens when Knapsack Pro API is not available/not reachable temporarily?](#what-happens-when-knapsack-pro-api-is-not-availablenot-reachable-temporarily)
91
98
  - [How can I change log level?](#how-can-i-change-log-level)
99
+ - [How to split tests based on test level instead of test file level?](#how-to-split-tests-based-on-test-level-instead-of-test-file-level)
100
+ - [A. Create multiple small test files](#a-create-multiple-small-test-files)
101
+ - [B. Use tags to mark set of tests in particular test file](#b-use-tags-to-mark-set-of-tests-in-particular-test-file)
102
+ - [How to make knapsack_pro works for forked repositories of my project?](#how-to-make-knapsack_pro-works-for-forked-repositories-of-my-project)
103
+ - [Questions around data usage and security](#questions-around-data-usage-and-security)
104
+ - [What data is sent to your servers?](#what-data-is-sent-to-your-servers)
105
+ - [How is that data secured?](#how-is-that-data-secured)
106
+ - [Who has access to the data?](#who-has-access-to-the-data)
92
107
  - [Gem tests](#gem-tests)
93
108
  - [Spec](#spec)
94
109
  - [Contributing](#contributing)
@@ -271,6 +286,41 @@ You can also use git as repository adapter to determine branch and commit hash,
271
286
 
272
287
  `KNAPSACK_PRO_PROJECT_DIR` - Path to the project on CI node for instance `/home/ubuntu/my-app-repository`. It should be main directory of your repository.
273
288
 
289
+ ## Queue Mode
290
+
291
+ knapsack_pro has built in queue mode designed to solve problem with optimal test suite split in case of random time execution of test files caused by
292
+ CI node overload and a random decrease of performance that may affect how long the test files are executed.
293
+ The problem with random time execution of test files may be caused by many things like external requests done in tests.
294
+
295
+ ### How queue mode works?
296
+
297
+ On the Knapsack Pro API side, there is test files queue generated for your CI build. Each of CI node dynamically asks the Knapsack Pro API for test files
298
+ that should be executed. Thanks to that each CI node will finish tests at the same time.
299
+
300
+ ### How to use queue mode?
301
+
302
+ Please use this command to run queue mode:
303
+
304
+ bundle exec rake knapsack_pro:queue:rspec
305
+
306
+ If above command fails then you may need to explicitly pass an argument to require `rails_helper` file or `spec_helper` in case you are not doing this in some of your test files:
307
+
308
+ bundle exec rake "knapsack_pro:queue:rspec[--require rails_helper]"
309
+
310
+ Note if you will run queue mode command for the first time it might be slower.
311
+ The second build should have better optimal test suite split.
312
+
313
+ ### Additional info about queue mode
314
+
315
+ If you are not using one of supported CI providers then please note that knapsack_pro gem doesn't know what is CI build ID in order to generated queue for particular CI build. This may result in two different CI builds taking tests from the same queue when CI builds are running at the same time against the same git commit.
316
+ To avoid this you can specify unique `KNAPSACK_PRO_CI_NODE_BUILD_ID` environment variable for each CI build. This mean that each CI node that is part of particular CI build should have the same value for `KNAPSACK_PRO_CI_NODE_BUILD_ID`.
317
+
318
+ ### Supported test runners in queue mode
319
+
320
+ At this moment the queue mode works for:
321
+
322
+ * RSpec
323
+
274
324
  ## Extra configuration for CI server
275
325
 
276
326
  ### Info about ENV variables
@@ -359,6 +409,7 @@ Add arguments to knapsack_pro spinach task like this:
359
409
  You can install knapsack_pro globally and use binary. For instance:
360
410
 
361
411
  $ knapsack_pro rspec "--tag custom_tag_name --profile"
412
+ $ knapsack_pro queue:rspec "--tag custom_tag_name --profile"
362
413
  $ knapsack_pro cucumber "--name feature"
363
414
  $ knapsack_pro minitest "--verbose --pride"
364
415
  $ knapsack_pro spinach "--arg_name value"
@@ -564,6 +615,104 @@ You can change log level by specifying the `KNAPSACK_PRO_LOG_LEVEL` environment
564
615
 
565
616
  Available values are `debug`, `info`, and `warn`. The default log level is `info`.
566
617
 
618
+ ### How to split tests based on test level instead of test file level?
619
+
620
+ If you want to split one big test file (test file with long time execution) across multiple CI nodes then you can:
621
+
622
+ #### A. Create multiple small test files
623
+
624
+ Create multiple small test files instead of one long running test file with many test cases.
625
+ A lot of small test files will give you better test suite split results.
626
+
627
+ #### B. Use tags to mark set of tests in particular test file
628
+
629
+ Another way is to use tags to mark subset of tests in particular test file and then split tests based on tags.
630
+
631
+ Here is example of test file with specified tags for describe groups:
632
+
633
+ ```ruby
634
+ # spec/features/something_spec.rb
635
+ describe 'Feature' do
636
+ describe 'something A', :tagA do
637
+ it {}
638
+ it 'another test' {}
639
+ end
640
+
641
+ describe 'something B', :tagB do
642
+ it {}
643
+ end
644
+
645
+ describe 'something else' do
646
+ it {}
647
+ end
648
+ end
649
+ ```
650
+
651
+ You need to create multiple API tokens for different tags. In this example we need 3 different API tokens.
652
+
653
+ You need to run below commands for each CI node.
654
+
655
+ # run only tests with tagA
656
+ KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC=api_key_for_tagA bundle exec rake "knapsack_pro:rspec[--tag tagA]"
657
+
658
+ # run only tests with tagB
659
+ KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC=api_key_for_tagB bundle exec rake "knapsack_pro:rspec[--tag tagB]"
660
+
661
+ # run other tests without tag A & B
662
+ KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC=api_key_for_tests_without_tags_A_and_B bundle exec rake "knapsack_pro:rspec[--tag ~tagA --tag ~tagB]"
663
+
664
+ ### How to make knapsack_pro works for forked repositories of my project?
665
+
666
+ Imagine one of the scenarios, for this example I use the Travis-CI.
667
+
668
+ * We don’t want to have secrets like the `KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC` in `.travis.yml` in the codebase, because that code is also distributed to clients.
669
+ * Adding it as env variables to Travis itself is tricky: It has to work for pull requests from developer’s forks into our main fork; this conflicts with the way Travis handles secrets. We also need a fallback if the token is not provided (when developers do builds within their own fork).
670
+
671
+ The solution for this problem is to set `KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC` as env variables in Travis for our main project.
672
+ This won't be accessible on forked repositories so we will run knapsack_pro in fallback mode there.
673
+ This way forked repositories have working test suite but without optimal test suite split across CI nodes.
674
+
675
+ Create the file `bin/knapsack_pro_rspec` with executable chmod in your main project repository.
676
+ Below example is for rspec. You can change `$KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC` to `$KNAPSACK_PRO_TEST_SUITE_TOKEN_CUCUMBER` if you use cucumber etc.
677
+
678
+ ```
679
+ #!/bin/bash
680
+ if [ "$KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC" = "" ]; then
681
+ KNAPSACK_PRO_ENDPOINT=https://api-disabled-for-fork.knapsackpro.com \
682
+ KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC=disabled-for-fork \
683
+ bundle exec rake knapsack_pro:rspec
684
+ else
685
+ bundle exec rake knapsack_pro:rspec
686
+ fi
687
+ ```
688
+
689
+ Now you can use `bin/knapsack_pro_rspec` command instead of `bundle exec rake knapsack_pro:rspec`.
690
+ Remember to follow other steps required for your CI provider.
691
+
692
+ ### Questions around data usage and security
693
+
694
+ #### What data is sent to your servers?
695
+
696
+ The knapsack_pro gem sends branch name, commit hash, CI total node number, CI index node number, the test file paths like `spec/models/user_spec.rb` and the time execution of each test file path as a float.
697
+
698
+ Here is the [full specification of the API](http://docs.knapsackpro.com/api/v1/) used by knapsack_pro gem.
699
+
700
+ #### How is that data secured?
701
+
702
+ The test file paths can be [encrypted](#test-file-names-encryption) on your CI node with your salt and later send to knapsackpro.com API.
703
+ You generate salt locally and only you can decrypt the test file paths.
704
+
705
+ Connection with knapsackpro.com server is via https.
706
+
707
+ Regarding payments we use the BraintreePayments.com and they store credit cards and your private information.
708
+
709
+ #### Who has access to the data?
710
+
711
+ I’m the only admin so I can preview data in case you need help with debugging some problem etc. I’m not able to decrypt them without knowing the salt.
712
+
713
+ When you sign in to your user dashboard then you can preview data for recent 100 builds on CI. If the test file paths are encrypted then you only see hashes for test file paths.
714
+ You need to [decrypt](#how-to-debug-test-file-names) them locally on your machine to find out what each test file hash is.
715
+
567
716
  ## Gem tests
568
717
 
569
718
  ### Spec
data/bin/knapsack_pro CHANGED
@@ -7,6 +7,7 @@ arguments = ARGV[1]
7
7
 
8
8
  MAP = {
9
9
  'rspec' => KnapsackPro::Runners::RSpecRunner,
10
+ 'queue:rspec' => KnapsackPro::Runners::Queue::RSpecRunner,
10
11
  'cucumber' => KnapsackPro::Runners::CucumberRunner,
11
12
  'minitest' => KnapsackPro::Runners::MinitestRunner,
12
13
  'spinach' => KnapsackPro::Runners::SpinachRunner,
data/knapsack_pro.gemspec CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
  spec.summary = %q{Knapsack Pro splits tests across CI nodes and makes sure that tests will run comparable time on each node.}
12
12
  spec.description = %q{Parallel tests across CI server nodes based on each test file's time execution. It uses KnapsackPro.com API.}
13
13
  spec.homepage = "https://github.com/KnapsackPro/knapsack_pro-ruby"
14
- spec.license = "LGPLv3"
14
+ spec.license = "LGPL-3.0"
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
data/lib/knapsack_pro.rb CHANGED
@@ -6,6 +6,7 @@ require 'uri'
6
6
  require 'rake/testtask'
7
7
  require 'timecop'
8
8
  require 'digest'
9
+ require 'securerandom'
9
10
  require_relative 'knapsack_pro/version'
10
11
  require_relative 'knapsack_pro/utils'
11
12
  require_relative 'knapsack_pro/logger_wrapper'
@@ -16,10 +17,12 @@ require_relative 'knapsack_pro/config/ci/buildkite'
16
17
  require_relative 'knapsack_pro/config/ci/travis'
17
18
  require_relative 'knapsack_pro/config/ci/snap_ci'
18
19
  require_relative 'knapsack_pro/config/env'
20
+ require_relative 'knapsack_pro/config/env_generator'
19
21
  require_relative 'knapsack_pro/client/api/action'
20
22
  require_relative 'knapsack_pro/client/api/v1/base'
21
23
  require_relative 'knapsack_pro/client/api/v1/build_distributions'
22
24
  require_relative 'knapsack_pro/client/api/v1/build_subsets'
25
+ require_relative 'knapsack_pro/client/api/v1/queues'
23
26
  require_relative 'knapsack_pro/client/connection'
24
27
  require_relative 'knapsack_pro/repository_adapters/base_adapter'
25
28
  require_relative 'knapsack_pro/repository_adapters/env_adapter'
@@ -35,7 +38,10 @@ require_relative 'knapsack_pro/test_flat_distributor'
35
38
  require_relative 'knapsack_pro/task_loader'
36
39
  require_relative 'knapsack_pro/tracker'
37
40
  require_relative 'knapsack_pro/allocator'
41
+ require_relative 'knapsack_pro/queue_allocator'
42
+ require_relative 'knapsack_pro/base_allocator_builder'
38
43
  require_relative 'knapsack_pro/allocator_builder'
44
+ require_relative 'knapsack_pro/queue_allocator_builder'
39
45
  require_relative 'knapsack_pro/adapters/base_adapter'
40
46
  require_relative 'knapsack_pro/adapters/rspec_adapter'
41
47
  require_relative 'knapsack_pro/adapters/cucumber_adapter'
@@ -46,6 +52,8 @@ require_relative 'knapsack_pro/runners/rspec_runner'
46
52
  require_relative 'knapsack_pro/runners/cucumber_runner'
47
53
  require_relative 'knapsack_pro/runners/minitest_runner'
48
54
  require_relative 'knapsack_pro/runners/spinach_runner'
55
+ require_relative 'knapsack_pro/runners/queue/base_runner'
56
+ require_relative 'knapsack_pro/runners/queue/rspec_runner'
49
57
  require_relative 'knapsack_pro/crypto/encryptor'
50
58
  require_relative 'knapsack_pro/crypto/decryptor'
51
59
  require_relative 'knapsack_pro/crypto/digestor'
@@ -16,6 +16,12 @@ module KnapsackPro
16
16
  bind_time_tracker
17
17
  bind_save_report
18
18
  end
19
+
20
+ if KnapsackPro::Config::Env.queue_recording_enabled?
21
+ KnapsackPro.logger.info('Test suite time execution queue recording enabled.')
22
+ bind_time_tracker
23
+ bind_save_queue_report
24
+ end
19
25
  end
20
26
 
21
27
  def bind_time_tracker
@@ -25,6 +31,10 @@ module KnapsackPro
25
31
  def bind_save_report
26
32
  raise NotImplementedError
27
33
  end
34
+
35
+ def bind_save_queue_report
36
+ raise NotImplementedError
37
+ end
28
38
  end
29
39
  end
30
40
  end
@@ -49,6 +49,14 @@ module KnapsackPro
49
49
  end
50
50
  end
51
51
  end
52
+
53
+ def bind_save_queue_report
54
+ ::RSpec.configure do |config|
55
+ config.after(:suite) do
56
+ KnapsackPro::Report.save_subset_queue_to_file
57
+ end
58
+ end
59
+ end
52
60
  end
53
61
 
54
62
  # This is added to provide backwards compatibility
@@ -8,24 +8,13 @@ module KnapsackPro
8
8
  end
9
9
 
10
10
  def test_file_paths
11
- encrypted_test_files = KnapsackPro::Crypto::Encryptor.call(test_files)
12
- action = KnapsackPro::Client::API::V1::BuildDistributions.subset(
13
- commit_hash: repository_adapter.commit_hash,
14
- branch: repository_adapter.branch,
15
- node_total: ci_node_total,
16
- node_index: ci_node_index,
17
- test_files: encrypted_test_files,
18
- )
19
- connection = KnapsackPro::Client::Connection.new(action)
11
+ connection = KnapsackPro::Client::Connection.new(build_action)
20
12
  response = connection.call
21
13
  if connection.success?
22
14
  raise ArgumentError.new(response) if connection.errors?
23
- decrypted_test_files = KnapsackPro::Crypto::Decryptor.call(test_files, response['test_files'])
24
- KnapsackPro::TestFilePresenter.paths(decrypted_test_files)
15
+ prepare_test_files(response)
25
16
  else
26
- test_flat_distributor = KnapsackPro::TestFlatDistributor.new(test_files, ci_node_total)
27
- test_files_for_node_index = test_flat_distributor.test_files_for_node(ci_node_index)
28
- KnapsackPro::TestFilePresenter.paths(test_files_for_node_index)
17
+ fallback_test_files
29
18
  end
30
19
  end
31
20
 
@@ -35,5 +24,30 @@ module KnapsackPro
35
24
  :ci_node_total,
36
25
  :ci_node_index,
37
26
  :repository_adapter
27
+
28
+ def encrypted_test_files
29
+ KnapsackPro::Crypto::Encryptor.call(test_files)
30
+ end
31
+
32
+ def build_action
33
+ KnapsackPro::Client::API::V1::BuildDistributions.subset(
34
+ commit_hash: repository_adapter.commit_hash,
35
+ branch: repository_adapter.branch,
36
+ node_total: ci_node_total,
37
+ node_index: ci_node_index,
38
+ test_files: encrypted_test_files,
39
+ )
40
+ end
41
+
42
+ def prepare_test_files(response)
43
+ decrypted_test_files = KnapsackPro::Crypto::Decryptor.call(test_files, response['test_files'])
44
+ KnapsackPro::TestFilePresenter.paths(decrypted_test_files)
45
+ end
46
+
47
+ def fallback_test_files
48
+ test_flat_distributor = KnapsackPro::TestFlatDistributor.new(test_files, ci_node_total)
49
+ test_files_for_node_index = test_flat_distributor.test_files_for_node(ci_node_index)
50
+ KnapsackPro::TestFilePresenter.paths(test_files_for_node_index)
51
+ end
38
52
  end
39
53
  end
@@ -1,9 +1,5 @@
1
1
  module KnapsackPro
2
- class AllocatorBuilder
3
- def initialize(adapter_class)
4
- @adapter_class = adapter_class
5
- end
6
-
2
+ class AllocatorBuilder < BaseAllocatorBuilder
7
3
  def allocator
8
4
  KnapsackPro::Allocator.new(
9
5
  test_files: test_files,
@@ -12,29 +8,5 @@ module KnapsackPro
12
8
  repository_adapter: repository_adapter,
13
9
  )
14
10
  end
15
-
16
- def test_dir
17
- test_file_pattern.split('/').first
18
- end
19
-
20
- private
21
-
22
- attr_reader :adapter_class
23
-
24
- def env
25
- KnapsackPro::Config::Env
26
- end
27
-
28
- def repository_adapter
29
- KnapsackPro::RepositoryAdapterInitiator.call
30
- end
31
-
32
- def test_file_pattern
33
- TestFilePattern.call(adapter_class)
34
- end
35
-
36
- def test_files
37
- KnapsackPro::TestFileFinder.call(test_file_pattern)
38
- end
39
11
  end
40
12
  end
@@ -0,0 +1,35 @@
1
+ module KnapsackPro
2
+ class BaseAllocatorBuilder
3
+ def initialize(adapter_class)
4
+ @adapter_class = adapter_class
5
+ end
6
+
7
+ def allocator
8
+ raise NotImplementedError
9
+ end
10
+
11
+ def test_dir
12
+ test_file_pattern.split('/').first
13
+ end
14
+
15
+ private
16
+
17
+ attr_reader :adapter_class
18
+
19
+ def env
20
+ KnapsackPro::Config::Env
21
+ end
22
+
23
+ def repository_adapter
24
+ KnapsackPro::RepositoryAdapterInitiator.call
25
+ end
26
+
27
+ def test_file_pattern
28
+ TestFilePattern.call(adapter_class)
29
+ end
30
+
31
+ def test_files
32
+ KnapsackPro::TestFileFinder.call(test_file_pattern)
33
+ end
34
+ end
35
+ end