knapsack_pro 1.20.2 → 1.21.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -0
  3. data/README.md +24 -12
  4. data/lib/knapsack_pro.rb +6 -0
  5. data/lib/knapsack_pro/adapters/base_adapter.rb +16 -0
  6. data/lib/knapsack_pro/adapters/rspec_adapter.rb +11 -9
  7. data/lib/knapsack_pro/allocator.rb +7 -5
  8. data/lib/knapsack_pro/allocator_builder.rb +2 -1
  9. data/lib/knapsack_pro/base_allocator_builder.rb +41 -10
  10. data/lib/knapsack_pro/build_distribution_fetcher.rb +57 -0
  11. data/lib/knapsack_pro/client/api/v1/build_distributions.rb +13 -0
  12. data/lib/knapsack_pro/client/connection.rb +30 -12
  13. data/lib/knapsack_pro/config/env.rb +4 -0
  14. data/lib/knapsack_pro/queue_allocator.rb +7 -5
  15. data/lib/knapsack_pro/queue_allocator_builder.rb +2 -1
  16. data/lib/knapsack_pro/runners/queue/rspec_runner.rb +7 -0
  17. data/lib/knapsack_pro/runners/rspec_runner.rb +5 -2
  18. data/lib/knapsack_pro/slow_test_file_determiner.rb +28 -0
  19. data/lib/knapsack_pro/slow_test_file_finder.rb +27 -0
  20. data/lib/knapsack_pro/test_case_detectors/rspec_test_example_detector.rb +18 -2
  21. data/lib/knapsack_pro/test_case_mergers/base_merger.rb +29 -0
  22. data/lib/knapsack_pro/test_case_mergers/rspec_merger.rb +34 -0
  23. data/lib/knapsack_pro/test_file_finder.rb +43 -5
  24. data/lib/knapsack_pro/test_files_with_test_cases_composer.rb +22 -0
  25. data/lib/knapsack_pro/version.rb +1 -1
  26. data/spec/knapsack_pro/adapters/base_adapter_spec.rb +55 -0
  27. data/spec/knapsack_pro/adapters/rspec_adapter_spec.rb +61 -25
  28. data/spec/knapsack_pro/allocator_builder_spec.rb +7 -3
  29. data/spec/knapsack_pro/allocator_spec.rb +7 -5
  30. data/spec/knapsack_pro/base_allocator_builder_spec.rb +79 -27
  31. data/spec/knapsack_pro/build_distribution_fetcher_spec.rb +89 -0
  32. data/spec/knapsack_pro/client/api/v1/build_distributions_spec.rb +31 -0
  33. data/spec/knapsack_pro/client/connection_spec.rb +165 -103
  34. data/spec/knapsack_pro/config/env_spec.rb +14 -0
  35. data/spec/knapsack_pro/queue_allocator_builder_spec.rb +7 -3
  36. data/spec/knapsack_pro/queue_allocator_spec.rb +7 -5
  37. data/spec/knapsack_pro/runners/rspec_runner_spec.rb +4 -4
  38. data/spec/knapsack_pro/slow_test_file_determiner_spec.rb +74 -0
  39. data/spec/knapsack_pro/slow_test_file_finder_spec.rb +43 -0
  40. data/spec/knapsack_pro/test_case_detectors/rspec_test_example_detector_spec.rb +81 -35
  41. data/spec/knapsack_pro/test_case_mergers/base_merger_spec.rb +27 -0
  42. data/spec/knapsack_pro/test_case_mergers/rspec_merger_spec.rb +59 -0
  43. data/spec/knapsack_pro/test_file_finder_spec.rb +105 -29
  44. data/spec/knapsack_pro/test_files_with_test_cases_composer_spec.rb +41 -0
  45. metadata +27 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6bbc828d338c810094114953894489db0696b70f013beac451b1c45602c323cd
4
- data.tar.gz: ae287454ad0658666d1d0cd85c4eaf91eabe009ee95b05b3a76d719a245395ae
3
+ metadata.gz: 59df1c0c620e9c92fb18e3963029fd02df6f04754ffe1b5c590cd7ca45159f55
4
+ data.tar.gz: 5cf6b36b8f908d8dbb9788918f7586c3b0334ec91a3a79afd768fbde3a8088b2
5
5
  SHA512:
6
- metadata.gz: f70aca52cc3808f0028d036dd8b5057130cf6610ede948075a293c3165ddf46e44e8fdf922e7457808dca8f390ded887adb5f4c95146a5b925535621b1de7a93
7
- data.tar.gz: 32e5fb5098e39fdb93694184b16c26603ca1edcdc193ab1c513ab9cd55800fa2c54157b28b365260d2e2231bd3bea6ffcc5b2b1921c9076ab75e37095433e5ef
6
+ metadata.gz: ae228667bbd897ad31512140d6c6382aefe2fce977748f909b3da7cca7a39495731cde4e079cd8a0247bd2d332fe8809aecf69fe773c34f864e74febc0a4dbbc
7
+ data.tar.gz: fc8255bc114f010a6a85a14aa98dab171767769e8476c3c422fd92e17198588e767f08bdb1072ca36c5038aef23af4396a8b44fa271b720845f26bd16fbae32b
@@ -1,5 +1,15 @@
1
1
  # Change Log
2
2
 
3
+ ### 1.21.0
4
+
5
+ * Automatically detect slow test files for RSpec and split them by test examples when `KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES=true`
6
+ * Add slow test file pattern `KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN` to define RSpec slow test files that should be split by test examples
7
+ * Start sending API token in header `KNAPSACK-PRO-TEST-SUITE-TOKEN` instead of a key `test_suite_token` in JSON payload.
8
+
9
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/106
10
+
11
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v1.20.2...v1.21.0
12
+
3
13
  ### 1.20.2
4
14
 
5
15
  * Raise an error when running Cucumber in Queue Mode and Cucumber system process doesn't finish execution correctly (for instance Cucumber process was killed by CI server due to lack of memory)
data/README.md CHANGED
@@ -83,7 +83,8 @@ We keep this old FAQ in README to not break old links spread across the web. You
83
83
  - [KNAPSACK_PRO_MODIFY_DEFAULT_RSPEC_FORMATTERS (hide duplicated summary of pending and failed tests)](#knapsack_pro_modify_default_rspec_formatters-hide-duplicated-summary-of-pending-and-failed-tests)
84
84
  - [Supported test runners in queue mode](#supported-test-runners-in-queue-mode)
85
85
  - [Split test files by test cases](#split-test-files-by-test-cases)
86
- - [RSpec split test files by test examples (individual `it`)](#rspec-split-test-files-by-test-examples-individual-it)
86
+ - [RSpec split test files by test examples (by individual `it`s)](#rspec-split-test-files-by-test-examples-by-individual-its)
87
+ - [How to manually define a list of slow test files to be split by test cases](#how-to-manually-define-a-list-of-slow-test-files-to-be-split-by-test-cases)
87
88
  - [Extra configuration for CI server](#extra-configuration-for-ci-server)
88
89
  - [Info about ENV variables](#info-about-env-variables)
89
90
  - [KNAPSACK_PRO_FIXED_TEST_SUITE_SPLIT (test suite split based on seed)](#knapsack_pro_fixed_test_suite_split-test-suite-split-based-on-seed)
@@ -597,33 +598,44 @@ At this moment the queue mode works for:
597
598
 
598
599
  ## Split test files by test cases
599
600
 
600
- > __Note:__ this is an experimental feature. It works for Regular Mode and Queue Mode. For large test suite with a few thousand test files, it may generate too many RSpec test example paths that may lead to too large JSON payload in request to Knapsack Pro API and this could trigger the API timeout.
601
- >
602
- > Please give us feedback so we could improve the feature.
603
- > https://knapsackpro.com/contact
601
+ __How it works__: You can split slow test file by test cases. Thanks to that the slow test file can be split across parallel CI nodes because test cases from the test file will run on different CI nodes.
602
+
603
+ This is helpful when you have one or a few very slow test files that are a bottleneck for CI build speed and you don't want to manually create a few smaller test files from the slow test files. Instead, you can tell `knapsack_pro` gem to split your slow test files by test cases across parallel CI nodes.
604
604
 
605
- __How it works__: You can split slow test file by test cases. Thanks to that the test file can be split across parallel CI nodes because test cases from the test file will run on different CI nodes.
605
+ Knapsack Pro API provides recorded timing of test files from your previously recorded CI builds and `knapsack_pro` gem will use this suggestion to determine slow test files. `knapsack_pro` gem splits only slow test files by test cases. Test files that are fast won't be split by test cases because it is not needed.
606
606
 
607
- This is helpful when you have one or a few very slow test files that are a bottleneck for CI build speed and you don't want to manually create a few smaller test files from the slow test files. Instead, you can tell `knapsack_pro` gem to split your test files by test cases across parallel CI nodes.
607
+ > __Note:__ This feature works for below test runners in Knapsack Pro Regular Mode and Queue Mode.
608
608
 
609
609
  ### RSpec split test files by test examples (by individual `it`s)
610
610
 
611
- > ❗ __WARNING (known issues):__ This is an experimental feature. We detected edge cases for Queue Mode when test examples might be ignored by RSpec and won't run test. Do not use this feature for production yet. We'll appreciate your [feedback](https://knapsackpro.com/contact) how it works while you test it on a separate branch. We work on improvements.
611
+ > ❗ __RSpec requirement:__ You need `RSpec >= 3.3.0` in order to use this feature.
612
612
 
613
- In order to split RSpec test files by test examples across parallel CI nodes you need to set environment variable:
613
+ In order to split RSpec slow test files by test examples across parallel CI nodes you need to set environment variable:
614
614
 
615
615
  ```
616
616
  KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES=true
617
617
  ```
618
618
 
619
- Thanks to that your CI build speed can be faster. We recommend using this feature with Queue Mode to ensure parallel CI nodes finish work at a similar time which gives you the shortest CI build time.
619
+ Thanks to that your CI build speed can be faster. We recommend using this feature with [Queue Mode](https://youtu.be/hUEB1XDKEFY) to ensure parallel CI nodes finish work at a similar time which gives you the shortest CI build time.
620
620
 
621
- Doing tests split by test examples can generate a lot of logs by `knapsack_pro` gem in Queue Mode. We recommend to set log level to:
621
+ ### How to manually define a list of slow test files to be split by test cases
622
+
623
+ If you don't want to rely on a list of test files from Knapsack Pro API to determine slow test files that should be split by test cases then you can define your own list of slow test files.
622
624
 
623
625
  ```
624
- KNAPSACK_PRO_LOG_LEVEL=warn
626
+ # enable split by test cases for RSpec
627
+ KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES=true
628
+
629
+ # example slow test files pattern for RSpec
630
+ KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN="{spec/models/user_spec.rb,spec/controllers/**/*_spec.rb}"
625
631
  ```
626
632
 
633
+ `KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN` must be subset of `KNAPSACK_PRO_TEST_FILE_PATTERN` (example default pattern for RSpec is `KNAPSACK_PRO_TEST_FILE_PATTERN="spec/**{,/*/**}/*_spec.rb"`).
634
+
635
+ > __Warning:__ `KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN` pattern is mostly useful for debugging purposes by developers of `knapsack_pro` gem. If you want to use it then __it is recommended to provide a shortlist of slow test files__ with the pattern.
636
+ >
637
+ > If you use a too broad list of slow test files then you may end up slowing your test suite, especially for RSpec it may result in a slow generating list of test examples in your project. The long list of test file example paths won't be accepted by Knapsack Pro API due to API timeout. CI providers like CircleCI may exceed server memory when running too many RSpec test examples.
638
+
627
639
  ## Extra configuration for CI server
628
640
 
629
641
  ### Info about ENV variables
@@ -55,6 +55,12 @@ require_relative 'knapsack_pro/adapters/test_unit_adapter'
55
55
  require_relative 'knapsack_pro/adapters/spinach_adapter'
56
56
  require_relative 'knapsack_pro/allocator'
57
57
  require_relative 'knapsack_pro/queue_allocator'
58
+ require_relative 'knapsack_pro/test_case_mergers/base_merger'
59
+ require_relative 'knapsack_pro/test_case_mergers/rspec_merger'
60
+ require_relative 'knapsack_pro/build_distribution_fetcher'
61
+ require_relative 'knapsack_pro/slow_test_file_determiner'
62
+ require_relative 'knapsack_pro/slow_test_file_finder'
63
+ require_relative 'knapsack_pro/test_files_with_test_cases_composer'
58
64
  require_relative 'knapsack_pro/base_allocator_builder'
59
65
  require_relative 'knapsack_pro/allocator_builder'
60
66
  require_relative 'knapsack_pro/queue_allocator_builder'
@@ -4,6 +4,22 @@ module KnapsackPro
4
4
  # Just example, please overwrite constant in subclass
5
5
  TEST_DIR_PATTERN = 'test/**{,/*/**}/*_test.rb'
6
6
 
7
+ def self.slow_test_file?(adapter_class, test_file_path)
8
+ @slow_test_file_paths ||=
9
+ begin
10
+ slow_test_files =
11
+ if KnapsackPro::Config::Env.slow_test_file_pattern
12
+ KnapsackPro::TestFileFinder.slow_test_files_by_pattern(adapter_class)
13
+ else
14
+ # get slow test files from JSON file based on data from API
15
+ KnapsackPro::SlowTestFileDeterminer.read_from_json_report
16
+ end
17
+ KnapsackPro::TestFilePresenter.paths(slow_test_files)
18
+ end
19
+ clean_path = KnapsackPro::TestFileCleaner.clean(test_file_path)
20
+ @slow_test_file_paths.include?(clean_path)
21
+ end
22
+
7
23
  def self.bind
8
24
  adapter = new
9
25
  adapter.bind
@@ -22,18 +22,20 @@ module KnapsackPro
22
22
  def bind_time_tracker
23
23
  ::RSpec.configure do |config|
24
24
  config.around(:each) do |example|
25
+ current_example_group =
26
+ if ::RSpec.respond_to?(:current_example)
27
+ ::RSpec.current_example.metadata[:example_group]
28
+ else
29
+ example.metadata
30
+ end
31
+
32
+ current_test_path = KnapsackPro::Adapters::RSpecAdapter.test_path(current_example_group)
33
+
25
34
  KnapsackPro.tracker.current_test_path =
26
- if KnapsackPro::Config::Env.rspec_split_by_test_examples?
35
+ if KnapsackPro::Config::Env.rspec_split_by_test_examples? && KnapsackPro::Adapters::RSpecAdapter.slow_test_file?(RSpecAdapter, current_test_path)
27
36
  example.id
28
37
  else
29
- current_example_group =
30
- if ::RSpec.respond_to?(:current_example)
31
- ::RSpec.current_example.metadata[:example_group]
32
- else
33
- example.metadata
34
- end
35
-
36
- KnapsackPro::Adapters::RSpecAdapter.test_path(current_example_group)
38
+ current_test_path
37
39
  end
38
40
 
39
41
  KnapsackPro.tracker.start_timer
@@ -1,7 +1,8 @@
1
1
  module KnapsackPro
2
2
  class Allocator
3
3
  def initialize(args)
4
- @test_files = args.fetch(:test_files)
4
+ @fast_and_slow_test_files_to_run = args.fetch(:fast_and_slow_test_files_to_run)
5
+ @fallback_mode_test_files = args.fetch(:fallback_mode_test_files)
5
6
  @ci_node_total = args.fetch(:ci_node_total)
6
7
  @ci_node_index = args.fetch(:ci_node_index)
7
8
  @repository_adapter = args.fetch(:repository_adapter)
@@ -32,13 +33,14 @@ module KnapsackPro
32
33
 
33
34
  private
34
35
 
35
- attr_reader :test_files,
36
+ attr_reader :fast_and_slow_test_files_to_run,
37
+ :fallback_mode_test_files,
36
38
  :ci_node_total,
37
39
  :ci_node_index,
38
40
  :repository_adapter
39
41
 
40
42
  def encrypted_test_files
41
- KnapsackPro::Crypto::Encryptor.call(test_files)
43
+ KnapsackPro::Crypto::Encryptor.call(fast_and_slow_test_files_to_run)
42
44
  end
43
45
 
44
46
  def encrypted_branch
@@ -56,12 +58,12 @@ module KnapsackPro
56
58
  end
57
59
 
58
60
  def prepare_test_files(response)
59
- decrypted_test_files = KnapsackPro::Crypto::Decryptor.call(test_files, response['test_files'])
61
+ decrypted_test_files = KnapsackPro::Crypto::Decryptor.call(fast_and_slow_test_files_to_run, response['test_files'])
60
62
  KnapsackPro::TestFilePresenter.paths(decrypted_test_files)
61
63
  end
62
64
 
63
65
  def fallback_test_files
64
- test_flat_distributor = KnapsackPro::TestFlatDistributor.new(test_files, ci_node_total)
66
+ test_flat_distributor = KnapsackPro::TestFlatDistributor.new(fallback_mode_test_files, ci_node_total)
65
67
  test_files_for_node_index = test_flat_distributor.test_files_for_node(ci_node_index)
66
68
  KnapsackPro::TestFilePresenter.paths(test_files_for_node_index)
67
69
  end
@@ -2,7 +2,8 @@ module KnapsackPro
2
2
  class AllocatorBuilder < BaseAllocatorBuilder
3
3
  def allocator
4
4
  KnapsackPro::Allocator.new(
5
- test_files: test_files,
5
+ fast_and_slow_test_files_to_run: fast_and_slow_test_files_to_run,
6
+ fallback_mode_test_files: fallback_mode_test_files,
6
7
  ci_node_total: env.ci_node_total,
7
8
  ci_node_index: env.ci_node_index,
8
9
  repository_adapter: repository_adapter,
@@ -21,29 +21,40 @@ module KnapsackPro
21
21
  KnapsackPro::Config::Env.test_dir || TestFilePattern.test_dir(adapter_class)
22
22
  end
23
23
 
24
- def test_files
25
- found_test_files = KnapsackPro::TestFileFinder.call(test_file_pattern)
24
+ # in fallback mode we always want to run the whole test files
25
+ # (not split by test cases) to guarantee that each test will be executed
26
+ # at least once across parallel CI nodes
27
+ def fallback_mode_test_files
28
+ all_test_files_to_run
29
+ end
30
+
31
+ # detect test files present on the disk that should be run
32
+ # this may include some fast test files + slow test files split by test cases
33
+ def fast_and_slow_test_files_to_run
34
+ test_files_to_run = all_test_files_to_run
26
35
 
27
36
  if adapter_class == KnapsackPro::Adapters::RSpecAdapter && KnapsackPro::Config::Env.rspec_split_by_test_examples?
28
- test_files_count = found_test_files.size
37
+ unless Gem::Version.new(RSpec::Core::Version::STRING) >= Gem::Version.new('3.3.0')
38
+ raise 'RSpec >= 3.3.0 is required to split test files by test examples. Learn more: https://github.com/KnapsackPro/knapsack_pro-ruby#split-test-files-by-test-cases'
39
+ end
29
40
 
30
- KnapsackPro.logger.warn("Generating RSpec test examples JSON report to prepare your test suite to be split by test examples (by individual 'it's. Thanks to that a single test file can be split across parallel CI nodes). Analyzing #{test_files_count} test files.")
41
+ slow_test_files = get_slow_test_files
31
42
 
32
- if test_files_count > 1000
33
- KnapsackPro.logger.warn("You have more than 1000 test files, it may take longer to generate test examples. Please wait...")
34
- end
43
+ KnapsackPro.logger.info("Generating RSpec test examples JSON report for slow test files to prepare it to be split by test examples (by individual 'it's. Thanks to that a single slow test file can be split across parallel CI nodes). Analyzing #{slow_test_files.size} slow test files.")
35
44
 
36
45
  # generate RSpec JSON report in separate process to not pollute RSpec state
37
- cmd = 'bundle exec rake knapsack_pro:rspec_test_example_detector'
46
+ cmd = 'RACK_ENV=test RAILS_ENV=test bundle exec rake knapsack_pro:rspec_test_example_detector'
38
47
  unless Kernel.system(cmd)
39
48
  raise "Could not generate JSON report for RSpec. Rake task failed when running #{cmd}"
40
49
  end
41
50
 
42
51
  # read JSON report
43
52
  detector = KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector.new
44
- detector.test_file_example_paths
53
+ test_file_example_paths = detector.test_file_example_paths
54
+
55
+ KnapsackPro::TestFilesWithTestCasesComposer.call(test_files_to_run, slow_test_files, test_file_example_paths)
45
56
  else
46
- found_test_files
57
+ test_files_to_run
47
58
  end
48
59
  end
49
60
 
@@ -62,5 +73,25 @@ module KnapsackPro
62
73
  def test_file_pattern
63
74
  TestFilePattern.call(adapter_class)
64
75
  end
76
+
77
+ def all_test_files_to_run
78
+ KnapsackPro::TestFileFinder.call(test_file_pattern)
79
+ end
80
+
81
+ def slow_test_file_pattern
82
+ KnapsackPro::Config::Env.slow_test_file_pattern
83
+ end
84
+
85
+ def get_slow_test_files
86
+ slow_test_files =
87
+ if slow_test_file_pattern
88
+ KnapsackPro::TestFileFinder.slow_test_files_by_pattern(adapter_class)
89
+ else
90
+ # get slow test files from API and ensure they exist on disk
91
+ KnapsackPro::SlowTestFileFinder.call(adapter_class)
92
+ end
93
+ KnapsackPro.logger.debug("Detected #{slow_test_files.size} slow test files: #{slow_test_files.inspect}")
94
+ slow_test_files
95
+ end
65
96
  end
66
97
  end
@@ -0,0 +1,57 @@
1
+ module KnapsackPro
2
+ class BuildDistributionFetcher
3
+ class BuildDistributionEntity
4
+ def initialize(response)
5
+ @response = response
6
+ end
7
+
8
+ def time_execution
9
+ response.fetch('time_execution')
10
+ end
11
+
12
+ def test_files
13
+ response.fetch('test_files')
14
+ end
15
+
16
+ private
17
+
18
+ attr_reader :response
19
+ end
20
+
21
+ def self.call
22
+ new.call
23
+ end
24
+
25
+ # get test files and time execution for last build distribution matching:
26
+ # branch, node_total, node_index
27
+ def call
28
+ connection = KnapsackPro::Client::Connection.new(build_action)
29
+ response = connection.call
30
+ if connection.success?
31
+ raise ArgumentError.new(response) if connection.errors?
32
+ BuildDistributionEntity.new(response)
33
+ else
34
+ KnapsackPro.logger.warn("Slow test files fallback behaviour started. We could not connect with Knapsack Pro API to fetch last CI build test files that are needed to determine slow test files. No test files will be split by test cases. It means all test files will be split by the whole test files as if split by test cases would be disabled https://github.com/KnapsackPro/knapsack_pro-ruby#split-test-files-by-test-cases")
35
+ BuildDistributionEntity.new({
36
+ 'time_execution' => 0.0,
37
+ 'test_files' => [],
38
+ })
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def repository_adapter
45
+ @repository_adapter ||= KnapsackPro::RepositoryAdapterInitiator.call
46
+ end
47
+
48
+ def build_action
49
+ KnapsackPro::Client::API::V1::BuildDistributions.last(
50
+ commit_hash: repository_adapter.commit_hash,
51
+ branch: repository_adapter.branch,
52
+ node_total: KnapsackPro::Config::Env.ci_node_total,
53
+ node_index: KnapsackPro::Config::Env.ci_node_index,
54
+ )
55
+ end
56
+ end
57
+ end
@@ -18,6 +18,19 @@ module KnapsackPro
18
18
  }
19
19
  )
20
20
  end
21
+
22
+ def last(args)
23
+ action_class.new(
24
+ endpoint_path: '/v1/build_distributions/last',
25
+ http_method: :get,
26
+ request_hash: {
27
+ :commit_hash => args.fetch(:commit_hash),
28
+ :branch => args.fetch(:branch),
29
+ :node_total => args.fetch(:node_total),
30
+ :node_index => args.fetch(:node_index),
31
+ }
32
+ )
33
+ end
21
34
  end
22
35
  end
23
36
  end
@@ -48,11 +48,7 @@ module KnapsackPro
48
48
  end
49
49
 
50
50
  def request_hash
51
- action
52
- .request_hash
53
- .merge({
54
- test_suite_token: test_suite_token
55
- })
51
+ action.request_hash
56
52
  end
57
53
 
58
54
  def request_body
@@ -69,6 +65,7 @@ module KnapsackPro
69
65
  'Accept' => 'application/json',
70
66
  'KNAPSACK-PRO-CLIENT-NAME' => client_name,
71
67
  'KNAPSACK-PRO-CLIENT-VERSION' => KnapsackPro::VERSION,
68
+ 'KNAPSACK-PRO-TEST-SUITE-TOKEN' => test_suite_token,
72
69
  }
73
70
  end
74
71
 
@@ -95,19 +92,15 @@ module KnapsackPro
95
92
  !seed.nil?
96
93
  end
97
94
 
98
- def post
95
+ def make_request(&block)
99
96
  retries ||= 0
100
- uri = URI.parse(endpoint_url)
101
- http = Net::HTTP.new(uri.host, uri.port)
102
- http.use_ssl = (uri.scheme == 'https')
103
- http.open_timeout = TIMEOUT
104
- http.read_timeout = TIMEOUT
105
97
 
106
- @http_response = http.post(uri.path, request_body, json_headers)
98
+ @http_response = block.call
107
99
  @response_body = parse_response_body(http_response.body)
108
100
 
109
101
  request_uuid = http_response.header['X-Request-Id'] || 'N/A'
110
102
 
103
+ logger.debug("#{action.http_method.to_s.upcase} #{endpoint_url}")
111
104
  logger.debug("API request UUID: #{request_uuid}")
112
105
  logger.debug("Test suite split seed: #{seed}") if has_seed?
113
106
  logger.debug('API response:')
@@ -134,6 +127,31 @@ module KnapsackPro
134
127
  response_body
135
128
  end
136
129
  end
130
+
131
+ def build_http(uri)
132
+ http = Net::HTTP.new(uri.host, uri.port)
133
+ http.use_ssl = (uri.scheme == 'https')
134
+ http.open_timeout = TIMEOUT
135
+ http.read_timeout = TIMEOUT
136
+ http
137
+ end
138
+
139
+ def post
140
+ uri = URI.parse(endpoint_url)
141
+ http = build_http(uri)
142
+ make_request do
143
+ http.post(uri.path, request_body, json_headers)
144
+ end
145
+ end
146
+
147
+ def get
148
+ uri = URI.parse(endpoint_url)
149
+ uri.query = URI.encode_www_form(request_hash)
150
+ http = build_http(uri)
151
+ make_request do
152
+ http.get(uri, json_headers)
153
+ end
154
+ end
137
155
  end
138
156
  end
139
157
  end
@@ -55,6 +55,10 @@ module KnapsackPro
55
55
  ENV['KNAPSACK_PRO_TEST_FILE_PATTERN']
56
56
  end
57
57
 
58
+ def slow_test_file_pattern
59
+ ENV['KNAPSACK_PRO_SLOW_TEST_FILE_PATTERN']
60
+ end
61
+
58
62
  def test_file_exclude_pattern
59
63
  ENV['KNAPSACK_PRO_TEST_FILE_EXCLUDE_PATTERN']
60
64
  end