knapsack_pro 9.2.1 → 9.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c214021f95c75ade998199d051fde0a287ae357174f82fb9193833a70792ae76
4
- data.tar.gz: 5987335be91251d6dba92a1656d981932172897bca175525db2e3421ad718775
3
+ metadata.gz: 53d7f0f50c7114a8e5cefd993a8ef8cb5fa05a6d36dd78cf8f9784884a6ac5d9
4
+ data.tar.gz: 56366ca74436f87208e2a297941d00ec403589e0e6d0ed3759862d059b8b16bb
5
5
  SHA512:
6
- metadata.gz: a47a53fb26eb3aba28c60045d13fda33fb00c6ea46321adb63986e662b74bc7b011097c2fbf90ec68a5be236cf06986a901b6ffef524864352d06d053dcbd962
7
- data.tar.gz: f3210244a10fbd129649586d8ed09441bbb63202bfde66ca3bd1f997c235772cdb4891681b0b8a3918d204f18b4ad3c2522a25ed445bdb830a69423c09b695c2
6
+ metadata.gz: 315e0df100e135cdd2646b546ce331291514c24d40f0ff88ea0a69f0d60842623cc35cb8f390a07b725c6b89ecbbebe61cf587a067728c2d2c59c99f531df4f0
7
+ data.tar.gz: 8d51be76e65fce53d2cdae3c45359ad5ce1dcdfab0a48c6ccacef0fe4d85636879c2586d1f937853f7d3d7b4652846e182af4fa2a548d9e2405399a538695599
@@ -30,10 +30,8 @@ module KnapsackPro
30
30
  if File.exist?(adapter_bind_method_called_file)
31
31
  File.delete(adapter_bind_method_called_file)
32
32
  else
33
- puts "\n\n"
34
- KnapsackPro.logger.error('-'*10 + ' Configuration error ' + '-'*50)
35
- KnapsackPro.logger.error("You forgot to call #{self}.bind method in your test runner configuration file. It is needed to record test files time execution. Please follow the installation guide to configure your project properly #{KnapsackPro::Urls::INSTALLATION_GUIDE}")
36
- KnapsackPro.logger.error("If you already have #{self}.bind method added and you still see this error then one of your tests must have deleted the .knapsack_pro directory from the disk accidentally. Please ensure you do not remove the .knapsack_pro directory: #{KnapsackPro::Urls::DASHBOARD__ZEROISH_TEST_EXECUTION_TIMES}")
33
+ KnapsackPro.logger.error("The `#{self}.bind` method was not called in the test runner configuration. See: #{KnapsackPro::Urls::INSTALLATION_GUIDE}")
34
+ KnapsackPro.logger.error("If `#{self}.bind` was called and you still see this error, ensure the `.knapsack_pro` directory (or its contents) were not removed during the run: #{KnapsackPro::Urls::DASHBOARD__ZEROISH_TEST_EXECUTION_TIMES}")
37
35
  Kernel.exit(1)
38
36
  end
39
37
  end
@@ -11,6 +11,10 @@ module KnapsackPro
11
11
  response.fetch('test_files')
12
12
  end
13
13
 
14
+ def test_queue_url # Can be present only when using the initialize command
15
+ response.fetch('test_queue_url', nil)
16
+ end
17
+
14
18
  private
15
19
 
16
20
  attr_reader :response
@@ -63,6 +63,32 @@ module KnapsackPro
63
63
  request_hash: request_hash
64
64
  )
65
65
  end
66
+
67
+ def connect
68
+ git_adapter = KnapsackPro::RepositoryAdapters::GitAdapter.new
69
+ repository_adapter = KnapsackPro::RepositoryAdapterInitiator.call
70
+
71
+ request_hash = {
72
+ attempt_connect_to_queue: true,
73
+ branch: KnapsackPro::Crypto::BranchEncryptor.call(repository_adapter.branch),
74
+ build_author: git_adapter.build_author,
75
+ can_initialize_queue: true,
76
+ commit_authors: git_adapter.commit_authors,
77
+ commit_hash: repository_adapter.commit_hash,
78
+ fixed_queue_split: KnapsackPro::Config::Env.fixed_queue_split,
79
+ node_build_id: KnapsackPro::Config::Env.ci_node_build_id,
80
+ node_index: KnapsackPro::Config::Env.ci_node_index,
81
+ node_total: KnapsackPro::Config::Env.ci_node_total,
82
+ skip_pull: true,
83
+ user_seat: KnapsackPro::Config::Env.masked_user_seat,
84
+ }
85
+
86
+ action_class.new(
87
+ endpoint_path: '/v1/queues/queue',
88
+ http_method: :post,
89
+ request_hash: request_hash
90
+ )
91
+ end
66
92
  end
67
93
  end
68
94
  end
@@ -51,10 +51,10 @@ module KnapsackPro
51
51
  .select { |time_execution| time_execution != KnapsackPro::Tracker::DEFAULT_TEST_FILE_TIME }
52
52
 
53
53
  if test_files.size > 0 && measured_test_files.size == 0
54
- KnapsackPro.logger.warn("#{test_files.size} test files were executed on this CI node but the recorded time was lost due to:")
55
- KnapsackPro.logger.warn("1. Please ensure you do not remove the contents of the .knapsack_pro directory between tests run.")
56
- KnapsackPro.logger.warn("2. Ensure you've added Knapsack::Adapters::RSpecAdapter.bind in your rails_helper.rb or spec_helper.rb. Please follow the installation guide again: #{KnapsackPro::Urls::INSTALLATION_GUIDE}")
57
- KnapsackPro.logger.warn("3. Another potential reason for this warning is that all your tests are empty test files, pending tests, or they have syntax errors, and the time execution was not recorded for them.")
54
+ KnapsackPro.logger.warn("#{test_files.size} test files were executed, but their execution time could not be recorded. This usually happens when one of the following is true:")
55
+ KnapsackPro.logger.warn('- The `.knapsack_pro` directory (or its contents) were removed during the run.')
56
+ KnapsackPro.logger.warn("- The `bind` method was not called in the test runner configuration. See: #{KnapsackPro::Urls::INSTALLATION_GUIDE}")
57
+ KnapsackPro.logger.warn('- The test files did not run any tests because they are empty, contain only pending tests, or have syntax errors.')
58
58
  end
59
59
 
60
60
  create_build_subset(test_files)
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KnapsackPro
4
+ module RSpec
5
+ class TestQueueInitializer
6
+ def call(args)
7
+ test_queue_url, slow_id_paths = KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector
8
+ .new
9
+ .calculate_slow_id_paths(args.to_s)
10
+ .values_at(:test_queue_url, :slow_id_paths)
11
+
12
+ unless test_queue_url.nil? # The test queue already existed when calculating the slow id paths.
13
+ KnapsackPro.logger.info "Test Queue URL: #{test_queue_url}"
14
+ exit 0
15
+ end
16
+
17
+ # The test queue was created by another node while this one calculated the slow id paths via the RSpec dry-run.
18
+ exit 0 if test_queue_exists?
19
+
20
+ initialize_test_queue(slow_id_paths)
21
+ end
22
+
23
+ private
24
+
25
+ def test_queue_exists?
26
+ action = KnapsackPro::Client::API::V1::Queues.connect
27
+ connection = KnapsackPro::Client::Connection.new(action)
28
+ response = connection.call
29
+
30
+ unless connection.success?
31
+ KnapsackPro.logger.error "Failed to initialize the test queue."
32
+ exit 1
33
+ end
34
+
35
+ if connection.errors?
36
+ KnapsackPro.logger.error "Failed to initialize the test queue."
37
+ KnapsackPro.logger.error response.inspect
38
+ exit 1
39
+ end
40
+
41
+ return false unless response.key?('url')
42
+
43
+ KnapsackPro.logger.info "Test Queue URL: #{response.fetch('url')}"
44
+ true
45
+ end
46
+
47
+ def initialize_test_queue(slow_id_paths)
48
+ all_test_files_to_run = KnapsackPro::TestSuite.new(KnapsackPro::Adapters::RSpecAdapter).all_test_files_to_run
49
+ paths = KnapsackPro::Adapters::RSpecAdapter.concat_paths(all_test_files_to_run, slow_id_paths)
50
+
51
+ if paths.empty?
52
+ KnapsackPro.logger.error "No paths to run."
53
+ exit 1
54
+ end
55
+
56
+ action = KnapsackPro::Client::API::V1::Queues.initialize(paths)
57
+ connection = KnapsackPro::Client::Connection.new(action)
58
+ response = connection.call
59
+
60
+ unless connection.success?
61
+ KnapsackPro.logger.error "Failed to initialize the test queue."
62
+ exit 1
63
+ end
64
+
65
+ if connection.errors?
66
+ KnapsackPro.logger.error "Failed to initialize the test queue."
67
+ KnapsackPro.logger.error response.inspect
68
+ exit 1
69
+ end
70
+
71
+ if response.key?('url')
72
+ KnapsackPro.logger.info "Test Queue URL: #{response.fetch('url')}"
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -3,7 +3,7 @@
3
3
  module KnapsackPro
4
4
  module TestCaseDetectors
5
5
  class RSpecTestExampleDetector
6
- def dry_run_to_file(rspec_args, slow_test_files = slow_test_files(KnapsackPro::BuildDistributionFetcher.new))
6
+ def dry_run_to_file(rspec_args, slow_test_files = fetch_slow_file_paths.fetch(:slow_file_paths))
7
7
  KnapsackPro::Config::TempFiles.ensure_temp_directory_exists!
8
8
  FileUtils.mkdir_p(File.dirname(report_path))
9
9
  File.delete(report_path) if File.exist?(report_path)
@@ -27,8 +27,11 @@ module KnapsackPro
27
27
  end
28
28
 
29
29
  def calculate_slow_id_paths(rspec_args)
30
- dry_run_to_file(rspec_args, slow_test_files(KnapsackPro::OptimizedBuildDistributionFetcher.new))
31
- slow_id_paths!
30
+ result = fetch_slow_file_paths(KnapsackPro::OptimizedBuildDistributionFetcher.new)
31
+ return { slow_id_paths: [], test_queue_url: result.fetch(:test_queue_url) } unless result.fetch(:test_queue_url).nil?
32
+
33
+ dry_run_to_file(rspec_args, result.fetch(:slow_file_paths))
34
+ { slow_id_paths: slow_id_paths!, test_queue_url: nil }
32
35
  end
33
36
 
34
37
  def slow_id_paths!
@@ -66,12 +69,27 @@ module KnapsackPro
66
69
  "#{KnapsackPro::Config::TempFiles::TEMP_DIRECTORY_PATH}/test_case_detectors/rspec/rspec_dry_run_json_report_node_#{KnapsackPro::Config::Env.ci_node_index}.json"
67
70
  end
68
71
 
69
- def slow_test_files(build_distribution_fetcher)
72
+ def fetch_slow_file_paths(build_distribution_fetcher = KnapsackPro::BuildDistributionFetcher.new)
70
73
  if KnapsackPro::Config::Env.slow_test_file_pattern
71
- KnapsackPro::TestFileFinder.slow_test_files_by_pattern(adapter_class)
74
+ slow_file_paths = KnapsackPro::TestFileFinder.slow_test_files_by_pattern(adapter_class)
75
+ { slow_file_paths: slow_file_paths, test_queue_url: nil }
72
76
  else
73
- KnapsackPro::RSpecSlowTestFileFinder.new(build_distribution_fetcher).call
77
+ determine_slow_file_paths(build_distribution_fetcher)
78
+ end
79
+ end
80
+
81
+ def determine_slow_file_paths(build_distribution_fetcher)
82
+ if KnapsackPro::Config::Env.test_files_encrypted?
83
+ raise "Split by test cases is not possible when you have enabled test file names encryption ( #{KnapsackPro::Urls::ENCRYPTION} ). You need to disable encryption with KNAPSACK_PRO_TEST_FILES_ENCRYPTED=false in order to use split by test cases #{KnapsackPro::Urls::SPLIT_BY_TEST_EXAMPLES}"
74
84
  end
85
+
86
+ build_distribution = build_distribution_fetcher.call
87
+ return { slow_file_paths: [], test_queue_url: build_distribution.test_queue_url } unless build_distribution.test_queue_url.nil?
88
+
89
+ merged_test_files_from_api = KnapsackPro::TestCaseMergers::RSpecMerger.new(build_distribution.test_files).call
90
+ test_files_existing_on_disk = KnapsackPro::TestFileFinder.select_test_files_that_can_be_run(KnapsackPro::Adapters::RSpecAdapter, merged_test_files_from_api)
91
+ slow_file_paths = KnapsackPro::SlowTestFileDeterminer.call(test_files_existing_on_disk)
92
+ { slow_file_paths: slow_file_paths, test_queue_url: nil }
75
93
  end
76
94
 
77
95
  def report
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KnapsackPro
4
- VERSION = '9.2.1'
4
+ VERSION = '9.2.2'
5
5
  end
data/lib/knapsack_pro.rb CHANGED
@@ -61,7 +61,6 @@ require_relative 'knapsack_pro/test_suite'
61
61
  require_relative 'knapsack_pro/test_case_mergers/rspec_merger'
62
62
  require_relative 'knapsack_pro/build_distribution_fetcher'
63
63
  require_relative 'knapsack_pro/slow_test_file_determiner'
64
- require_relative 'knapsack_pro/rspec_slow_test_file_finder'
65
64
  require_relative 'knapsack_pro/base_allocator_builder'
66
65
  require_relative 'knapsack_pro/regular_allocator_builder'
67
66
  require_relative 'knapsack_pro/queue_allocator_builder'
@@ -16,12 +16,12 @@ namespace :knapsack_pro do
16
16
  namespace :rspec do
17
17
  desc 'Initialize the test queue to be consumed later.'
18
18
  task :initialize, [:rspec_args] do |_, args|
19
- require_relative '../../knapsack_pro/queue_initializer'
19
+ require_relative '../../knapsack_pro/rspec/test_queue_initializer'
20
20
 
21
21
  ENV.delete('SPEC_OPTS') # Ignore `SPEC_OPTS` to not affect the RSpec execution within this rake task
22
22
  ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN'] = KnapsackPro::Config::Env.test_suite_token_rspec
23
23
 
24
- KnapsackPro::RSpec::QueueInitializer.new.call(args[:rspec_args].to_s)
24
+ KnapsackPro::RSpec::TestQueueInitializer.new.call(args[:rspec_args].to_s)
25
25
  end
26
26
  end
27
27
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knapsack_pro
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.2.1
4
+ version: 9.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - ArturT
@@ -250,7 +250,6 @@ files:
250
250
  - lib/knapsack_pro/queue.rb
251
251
  - lib/knapsack_pro/queue_allocator.rb
252
252
  - lib/knapsack_pro/queue_allocator_builder.rb
253
- - lib/knapsack_pro/queue_initializer.rb
254
253
  - lib/knapsack_pro/railtie.rb
255
254
  - lib/knapsack_pro/regular_allocator.rb
256
255
  - lib/knapsack_pro/regular_allocator_builder.rb
@@ -259,7 +258,7 @@ files:
259
258
  - lib/knapsack_pro/repository_adapters/base_adapter.rb
260
259
  - lib/knapsack_pro/repository_adapters/env_adapter.rb
261
260
  - lib/knapsack_pro/repository_adapters/git_adapter.rb
262
- - lib/knapsack_pro/rspec_slow_test_file_finder.rb
261
+ - lib/knapsack_pro/rspec/test_queue_initializer.rb
263
262
  - lib/knapsack_pro/runners/base_runner.rb
264
263
  - lib/knapsack_pro/runners/cucumber_runner.rb
265
264
  - lib/knapsack_pro/runners/minitest_runner.rb
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module KnapsackPro
4
- module RSpec
5
- class QueueInitializer
6
- def call(args)
7
- slow_id_paths = KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector.new.calculate_slow_id_paths(args.to_s)
8
- all_test_files_to_run = KnapsackPro::TestSuite.new(KnapsackPro::Adapters::RSpecAdapter).all_test_files_to_run
9
- paths = KnapsackPro::Adapters::RSpecAdapter.concat_paths(all_test_files_to_run, slow_id_paths)
10
-
11
- raise 'No paths to run' if paths.empty?
12
- action = KnapsackPro::Client::API::V1::Queues.initialize(paths)
13
- connection = KnapsackPro::Client::Connection.new(action)
14
- response = connection.call
15
- return unless response.key?('url') # Race to initialize lost to another parallel node
16
-
17
- KnapsackPro.logger.info "Build URL: #{response.fetch('url')}"
18
- end
19
- end
20
- end
21
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module KnapsackPro
4
- class RSpecSlowTestFileFinder
5
- def initialize(build_distribution_fetcher)
6
- @build_distribution_fetcher = build_distribution_fetcher
7
- end
8
-
9
- def call
10
- if KnapsackPro::Config::Env.test_files_encrypted?
11
- raise "Split by test cases is not possible when you have enabled test file names encryption ( #{KnapsackPro::Urls::ENCRYPTION} ). You need to disable encryption with KNAPSACK_PRO_TEST_FILES_ENCRYPTED=false in order to use split by test cases #{KnapsackPro::Urls::SPLIT_BY_TEST_EXAMPLES}"
12
- end
13
-
14
- test_files_from_api = @build_distribution_fetcher.call.test_files
15
- merged_test_files_from_api = KnapsackPro::TestCaseMergers::RSpecMerger.new(test_files_from_api).call
16
- test_files_existing_on_disk = KnapsackPro::TestFileFinder.select_test_files_that_can_be_run(KnapsackPro::Adapters::RSpecAdapter, merged_test_files_from_api)
17
- KnapsackPro::SlowTestFileDeterminer.call(test_files_existing_on_disk)
18
- end
19
- end
20
- end