knapsack_pro 3.8.0 → 7.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +377 -23
- data/.github/dependabot.yml +11 -0
- data/.github/pull_request_template.md +22 -0
- data/.gitignore +4 -0
- data/CHANGELOG.md +325 -1
- data/Gemfile +9 -0
- data/README.md +3 -10
- data/bin/test +15 -0
- data/knapsack_pro.gemspec +7 -6
- data/lib/knapsack_pro/adapters/base_adapter.rb +17 -2
- data/lib/knapsack_pro/adapters/cucumber_adapter.rb +3 -3
- data/lib/knapsack_pro/adapters/minitest_adapter.rb +2 -0
- data/lib/knapsack_pro/adapters/rspec_adapter.rb +88 -49
- data/lib/knapsack_pro/adapters/spinach_adapter.rb +2 -0
- data/lib/knapsack_pro/adapters/test_unit_adapter.rb +2 -0
- data/lib/knapsack_pro/allocator.rb +2 -0
- data/lib/knapsack_pro/allocator_builder.rb +2 -0
- data/lib/knapsack_pro/base_allocator_builder.rb +8 -25
- data/lib/knapsack_pro/build_distribution_fetcher.rb +2 -0
- data/lib/knapsack_pro/client/api/action.rb +2 -0
- data/lib/knapsack_pro/client/api/v1/base.rb +2 -0
- data/lib/knapsack_pro/client/api/v1/build_distributions.rb +5 -0
- data/lib/knapsack_pro/client/api/v1/build_subsets.rb +2 -0
- data/lib/knapsack_pro/client/api/v1/queues.rb +6 -1
- data/lib/knapsack_pro/client/connection.rb +5 -6
- data/lib/knapsack_pro/config/ci/app_veyor.rb +18 -0
- data/lib/knapsack_pro/config/ci/base.rb +27 -0
- data/lib/knapsack_pro/config/ci/buildkite.rb +18 -0
- data/lib/knapsack_pro/config/ci/circle.rb +18 -0
- data/lib/knapsack_pro/config/ci/cirrus_ci.rb +18 -0
- data/lib/knapsack_pro/config/ci/codefresh.rb +18 -0
- data/lib/knapsack_pro/config/ci/codeship.rb +18 -0
- data/lib/knapsack_pro/config/ci/github_actions.rb +26 -0
- data/lib/knapsack_pro/config/ci/gitlab_ci.rb +20 -1
- data/lib/knapsack_pro/config/ci/heroku.rb +18 -0
- data/lib/knapsack_pro/config/ci/semaphore.rb +16 -0
- data/lib/knapsack_pro/config/ci/semaphore2.rb +19 -0
- data/lib/knapsack_pro/config/ci/travis.rb +18 -0
- data/lib/knapsack_pro/config/env.rb +46 -22
- data/lib/knapsack_pro/config/env_generator.rb +2 -0
- data/lib/knapsack_pro/config/temp_files.rb +8 -4
- data/lib/knapsack_pro/crypto/branch_encryptor.rb +2 -0
- data/lib/knapsack_pro/crypto/decryptor.rb +2 -0
- data/lib/knapsack_pro/crypto/digestor.rb +2 -0
- data/lib/knapsack_pro/crypto/encryptor.rb +2 -0
- data/lib/knapsack_pro/extensions/rspec_extension.rb +137 -0
- data/lib/knapsack_pro/formatters/rspec_json_formatter.rb +2 -0
- data/lib/knapsack_pro/formatters/time_tracker.rb +152 -0
- data/lib/knapsack_pro/formatters/time_tracker_fetcher.rb +20 -0
- data/lib/knapsack_pro/hooks/queue.rb +2 -0
- data/lib/knapsack_pro/logger_wrapper.rb +2 -0
- data/lib/knapsack_pro/mask_string.rb +9 -0
- data/lib/knapsack_pro/presenter.rb +6 -3
- data/lib/knapsack_pro/pure/queue/rspec_pure.rb +92 -0
- data/lib/knapsack_pro/queue_allocator.rb +2 -0
- data/lib/knapsack_pro/queue_allocator_builder.rb +2 -0
- data/lib/knapsack_pro/railtie.rb +2 -0
- data/lib/knapsack_pro/report.rb +15 -9
- data/lib/knapsack_pro/repository_adapter_initiator.rb +2 -0
- data/lib/knapsack_pro/repository_adapters/base_adapter.rb +2 -0
- data/lib/knapsack_pro/repository_adapters/env_adapter.rb +2 -0
- data/lib/knapsack_pro/repository_adapters/git_adapter.rb +50 -0
- data/lib/knapsack_pro/runners/base_runner.rb +2 -0
- data/lib/knapsack_pro/runners/cucumber_runner.rb +2 -0
- data/lib/knapsack_pro/runners/minitest_runner.rb +2 -0
- data/lib/knapsack_pro/runners/queue/base_runner.rb +29 -0
- data/lib/knapsack_pro/runners/queue/cucumber_runner.rb +9 -6
- data/lib/knapsack_pro/runners/queue/minitest_runner.rb +13 -6
- data/lib/knapsack_pro/runners/queue/rspec_runner.rb +128 -135
- data/lib/knapsack_pro/runners/rspec_runner.rb +22 -3
- data/lib/knapsack_pro/runners/spinach_runner.rb +2 -0
- data/lib/knapsack_pro/runners/test_unit_runner.rb +2 -0
- data/lib/knapsack_pro/slow_test_file_determiner.rb +2 -0
- data/lib/knapsack_pro/slow_test_file_finder.rb +2 -0
- data/lib/knapsack_pro/task_loader.rb +2 -0
- data/lib/knapsack_pro/test_case_detectors/rspec_test_example_detector.rb +2 -0
- data/lib/knapsack_pro/test_case_mergers/base_merger.rb +2 -0
- data/lib/knapsack_pro/test_case_mergers/rspec_merger.rb +2 -0
- data/lib/knapsack_pro/test_file_cleaner.rb +2 -0
- data/lib/knapsack_pro/test_file_finder.rb +2 -0
- data/lib/knapsack_pro/test_file_pattern.rb +2 -0
- data/lib/knapsack_pro/test_file_presenter.rb +2 -0
- data/lib/knapsack_pro/test_files_with_test_cases_composer.rb +2 -0
- data/lib/knapsack_pro/test_flat_distributor.rb +2 -0
- data/lib/knapsack_pro/tracker.rb +3 -3
- data/lib/knapsack_pro/urls.rb +4 -0
- data/lib/knapsack_pro/utils.rb +2 -0
- data/lib/knapsack_pro/version.rb +3 -1
- data/lib/knapsack_pro.rb +5 -3
- data/lib/tasks/cucumber.rake +2 -0
- data/lib/tasks/encrypted_branch_names.rake +2 -0
- data/lib/tasks/encrypted_test_file_names.rake +2 -0
- data/lib/tasks/minitest.rake +2 -0
- data/lib/tasks/queue/cucumber.rake +13 -0
- data/lib/tasks/queue/minitest.rake +13 -0
- data/lib/tasks/queue/rspec.rake +13 -0
- data/lib/tasks/rspec.rake +5 -0
- data/lib/tasks/salt.rake +2 -0
- data/lib/tasks/spinach.rake +2 -0
- data/lib/tasks/test_unit.rake +2 -0
- data/spec/integration/api/build_distributions_subset_spec.rb +1 -0
- data/spec/integration/runners/queue/rspec_runner.rb +80 -0
- data/spec/integration/runners/queue/rspec_runner_spec.rb +2232 -0
- data/spec/knapsack_pro/adapters/base_adapter_spec.rb +30 -11
- data/spec/knapsack_pro/adapters/cucumber_adapter_spec.rb +2 -5
- data/spec/knapsack_pro/adapters/rspec_adapter_spec.rb +146 -174
- data/spec/knapsack_pro/base_allocator_builder_spec.rb +22 -48
- data/spec/knapsack_pro/client/api/v1/build_distributions_spec.rb +19 -27
- data/spec/knapsack_pro/client/api/v1/queues_spec.rb +23 -43
- data/spec/knapsack_pro/client/connection_spec.rb +59 -7
- data/spec/knapsack_pro/config/ci/app_veyor_spec.rb +22 -8
- data/spec/knapsack_pro/config/ci/base_spec.rb +1 -0
- data/spec/knapsack_pro/config/ci/buildkite_spec.rb +51 -16
- data/spec/knapsack_pro/config/ci/circle_spec.rb +48 -13
- data/spec/knapsack_pro/config/ci/cirrus_ci_spec.rb +12 -12
- data/spec/knapsack_pro/config/ci/codefresh_spec.rb +21 -6
- data/spec/knapsack_pro/config/ci/codeship_spec.rb +20 -6
- data/spec/knapsack_pro/config/ci/github_actions_spec.rb +37 -10
- data/spec/knapsack_pro/config/ci/gitlab_ci_spec.rb +48 -13
- data/spec/knapsack_pro/config/ci/heroku_spec.rb +12 -12
- data/spec/knapsack_pro/config/ci/semaphore2_spec.rb +11 -11
- data/spec/knapsack_pro/config/ci/semaphore_spec.rb +12 -12
- data/spec/knapsack_pro/config/ci/travis_spec.rb +8 -8
- data/spec/knapsack_pro/config/env_spec.rb +204 -124
- data/spec/knapsack_pro/formatters/time_tracker_specs.rb +424 -0
- data/spec/knapsack_pro/hooks/queue_spec.rb +2 -2
- data/spec/knapsack_pro/presenter_spec.rb +1 -1
- data/spec/knapsack_pro/pure/queue/rspec_pure_spec.rb +224 -0
- data/spec/knapsack_pro/repository_adapters/git_adapter_spec.rb +72 -0
- data/spec/knapsack_pro/runners/queue/cucumber_runner_spec.rb +18 -16
- data/spec/knapsack_pro/runners/queue/minitest_runner_spec.rb +17 -14
- data/spec/knapsack_pro/runners/rspec_runner_spec.rb +40 -23
- data/spec/knapsack_pro/test_case_detectors/rspec_test_example_detector_spec.rb +1 -0
- data/spec/knapsack_pro/tracker_spec.rb +0 -4
- data/spec/knapsack_pro_spec.rb +3 -3
- data/spec/spec_helper.rb +0 -1
- metadata +26 -23
- data/lib/knapsack_pro/config/ci/snap_ci.rb +0 -35
- data/lib/knapsack_pro/config/ci/solano_ci.rb +0 -32
- data/lib/knapsack_pro/extensions/time.rb +0 -7
- data/lib/knapsack_pro/formatters/rspec_queue_profile_formatter_extension.rb +0 -56
- data/lib/knapsack_pro/formatters/rspec_queue_summary_formatter.rb +0 -112
- data/spec/knapsack_pro/config/ci/snap_ci_spec.rb +0 -104
- data/spec/knapsack_pro/config/ci/solano_ci_spec.rb +0 -73
- data/spec/knapsack_pro/extensions/time_spec.rb +0 -5
- data/spec/knapsack_pro/runners/queue/rspec_runner_spec.rb +0 -342
@@ -1,184 +1,177 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module KnapsackPro
|
2
4
|
module Runners
|
3
5
|
module Queue
|
4
6
|
class RSpecRunner < BaseRunner
|
5
|
-
|
6
|
-
|
7
|
-
def self.run(args)
|
7
|
+
def self.run(args, stream_error = $stderr, stream_out = $stdout)
|
8
8
|
require 'rspec/core'
|
9
|
-
require_relative '../../
|
10
|
-
require_relative '../../formatters/
|
9
|
+
require_relative '../../extensions/rspec_extension'
|
10
|
+
require_relative '../../formatters/time_tracker'
|
11
|
+
require_relative '../../formatters/time_tracker_fetcher'
|
12
|
+
|
13
|
+
KnapsackPro::Extensions::RSpecExtension.setup!
|
11
14
|
|
12
15
|
ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN'] = KnapsackPro::Config::Env.test_suite_token_rspec
|
13
|
-
ENV['KNAPSACK_PRO_QUEUE_RECORDING_ENABLED'] = 'true'
|
14
|
-
ENV['KNAPSACK_PRO_QUEUE_ID'] = KnapsackPro::Config::EnvGenerator.set_queue_id
|
15
16
|
|
16
|
-
KnapsackPro::
|
17
|
-
runner = new(adapter_class)
|
18
|
-
|
19
|
-
cli_args = (args || '').split
|
20
|
-
adapter_class.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!(cli_args)
|
21
|
-
|
22
|
-
# when format option is not defined by user then use progress formatter to show tests execution progress
|
23
|
-
cli_args += ['--format', 'progress'] unless adapter_class.has_format_option?(cli_args)
|
24
|
-
|
25
|
-
cli_args += [
|
26
|
-
# shows summary of all tests executed in Queue Mode at the very end
|
27
|
-
'--format', KnapsackPro::Formatters::RSpecQueueSummaryFormatter.to_s,
|
28
|
-
'--default-path', runner.test_dir,
|
29
|
-
]
|
30
|
-
|
31
|
-
accumulator = {
|
32
|
-
status: :next,
|
33
|
-
runner: runner,
|
34
|
-
can_initialize_queue: true,
|
35
|
-
args: cli_args,
|
36
|
-
exitstatus: 0,
|
37
|
-
all_test_file_paths: [],
|
38
|
-
}
|
39
|
-
while accumulator[:status] == :next
|
40
|
-
accumulator = run_tests(accumulator)
|
41
|
-
end
|
17
|
+
rspec_pure = KnapsackPro::Pure::Queue::RSpecPure.new
|
42
18
|
|
43
|
-
|
19
|
+
queue_runner = new(KnapsackPro::Adapters::RSpecAdapter, rspec_pure, args, stream_error, stream_out)
|
20
|
+
queue_runner.run
|
44
21
|
end
|
45
22
|
|
46
|
-
def
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
23
|
+
def initialize(adapter_class, rspec_pure, args, stream_error, stream_out)
|
24
|
+
super(adapter_class)
|
25
|
+
@adapter_class = adapter_class
|
26
|
+
@rspec_pure = rspec_pure
|
27
|
+
has_format_option = @adapter_class.has_format_option?((args || '').split)
|
28
|
+
@cli_args = rspec_pure.prepare_cli_args(args, has_format_option, test_dir)
|
29
|
+
@stream_error = stream_error
|
30
|
+
@stream_out = stream_out
|
31
|
+
@node_test_file_paths = []
|
32
|
+
@rspec_runner = nil # RSpec::Core::Runner is lazy initialized
|
33
|
+
end
|
52
34
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
35
|
+
# Based on:
|
36
|
+
# https://github.com/rspec/rspec-core/blob/f8c8880dabd8f0544a6f91d8d4c857c1bd8df903/lib/rspec/core/runner.rb#L85
|
37
|
+
#
|
38
|
+
# @return [Fixnum] exit status code.
|
39
|
+
# 0 if all specs passed,
|
40
|
+
# or the configured failure exit code (1 by default) if specs failed.
|
41
|
+
def run
|
42
|
+
pre_run_setup
|
43
|
+
|
44
|
+
if @rspec_runner.knapsack__wants_to_quit?
|
45
|
+
exit_code = @rspec_runner.knapsack__exit_early
|
46
|
+
Kernel.exit(exit_code)
|
47
|
+
end
|
48
|
+
|
49
|
+
begin
|
50
|
+
exit_code = @rspec_runner.knapsack__run_specs(self)
|
51
|
+
rescue KnapsackPro::Runners::Queue::BaseRunner::TerminationError
|
52
|
+
exit_code = @rspec_pure.error_exit_code(@rspec_runner.knapsack__error_exit_code)
|
53
|
+
Kernel.exit(exit_code)
|
54
|
+
rescue Exception => exception
|
55
|
+
KnapsackPro.logger.error("An unexpected exception happened. RSpec cannot handle it. The exception: #{exception.inspect}")
|
57
56
|
|
58
|
-
|
59
|
-
|
60
|
-
KnapsackPro::Adapters::RSpecAdapter.verify_bind_method_called
|
57
|
+
message = @rspec_pure.exit_summary(unexecuted_test_files)
|
58
|
+
KnapsackPro.logger.warn(message) if message
|
61
59
|
|
62
|
-
|
63
|
-
|
60
|
+
exit_code = @rspec_pure.error_exit_code(@rspec_runner.knapsack__error_exit_code)
|
61
|
+
Kernel.exit(exit_code)
|
62
|
+
end
|
64
63
|
|
65
|
-
|
64
|
+
post_run_tasks(exit_code)
|
65
|
+
end
|
66
66
|
|
67
|
-
|
68
|
-
|
67
|
+
def with_batch
|
68
|
+
can_initialize_queue = true
|
69
69
|
|
70
|
-
|
70
|
+
loop do
|
71
|
+
handle_signal!
|
72
|
+
test_file_paths = pull_tests_from_queue(can_initialize_queue: can_initialize_queue)
|
73
|
+
can_initialize_queue = false
|
71
74
|
|
72
|
-
|
75
|
+
break if test_file_paths.empty?
|
73
76
|
|
74
|
-
return {
|
75
|
-
status: :completed,
|
76
|
-
exitstatus: exitstatus,
|
77
|
-
}
|
78
|
-
else
|
79
77
|
subset_queue_id = KnapsackPro::Config::EnvGenerator.set_subset_queue_id
|
80
78
|
ENV['KNAPSACK_PRO_SUBSET_QUEUE_ID'] = subset_queue_id
|
81
79
|
|
82
|
-
KnapsackPro.tracker.reset!
|
83
|
-
KnapsackPro.tracker.set_prerun_tests(test_file_paths)
|
84
|
-
|
85
80
|
KnapsackPro::Hooks::Queue.call_before_subset_queue
|
86
81
|
|
87
|
-
|
88
|
-
cli_args = args + test_file_paths
|
89
|
-
|
90
|
-
options = ::RSpec::Core::ConfigurationOptions.new(cli_args)
|
91
|
-
rspec_runner = ::RSpec::Core::Runner.new(options)
|
92
|
-
|
93
|
-
exit_code = rspec_runner.run($stderr, $stdout)
|
94
|
-
exitstatus = exit_code if exit_code != 0
|
95
|
-
|
96
|
-
printable_args = args_with_seed_option_added_when_viable(args, rspec_runner)
|
97
|
-
log_rspec_command(printable_args, test_file_paths, :subset_queue)
|
98
|
-
|
99
|
-
rspec_clear_examples
|
82
|
+
yield test_file_paths
|
100
83
|
|
101
84
|
KnapsackPro::Hooks::Queue.call_after_subset_queue
|
102
85
|
|
103
|
-
|
86
|
+
if @rspec_runner.knapsack__wants_to_quit?
|
87
|
+
KnapsackPro.logger.warn('RSpec wants to quit.')
|
88
|
+
set_terminate_process
|
89
|
+
end
|
90
|
+
if @rspec_runner.knapsack__rspec_is_quitting?
|
91
|
+
KnapsackPro.logger.warn('RSpec is quitting.')
|
92
|
+
set_terminate_process
|
93
|
+
end
|
104
94
|
|
105
|
-
|
106
|
-
status: :next,
|
107
|
-
runner: runner,
|
108
|
-
can_initialize_queue: false,
|
109
|
-
args: args,
|
110
|
-
exitstatus: exitstatus,
|
111
|
-
all_test_file_paths: all_test_file_paths,
|
112
|
-
}
|
95
|
+
log_rspec_batch_command(test_file_paths)
|
113
96
|
end
|
114
97
|
end
|
115
98
|
|
99
|
+
def handle_signal!
|
100
|
+
self.class.handle_signal!
|
101
|
+
end
|
102
|
+
|
103
|
+
def log_fail_fast_limit_met
|
104
|
+
KnapsackPro.logger.warn('Test execution has been canceled because the RSpec --fail-fast option is enabled. It will cause other CI nodes to run tests longer because they need to consume more tests from the Knapsack Pro Queue API.')
|
105
|
+
end
|
106
|
+
|
116
107
|
private
|
117
108
|
|
118
|
-
def
|
119
|
-
|
109
|
+
def pre_run_setup
|
110
|
+
ENV['KNAPSACK_PRO_QUEUE_RECORDING_ENABLED'] = 'true'
|
111
|
+
ENV['KNAPSACK_PRO_QUEUE_ID'] = KnapsackPro::Config::EnvGenerator.set_queue_id
|
112
|
+
|
113
|
+
KnapsackPro::Config::Env.set_test_runner_adapter(@adapter_class)
|
114
|
+
|
115
|
+
ENV['SPEC_OPTS'] = @rspec_pure.add_knapsack_pro_formatters_to(ENV['SPEC_OPTS'])
|
116
|
+
@adapter_class.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!(@cli_args)
|
117
|
+
|
118
|
+
rspec_configuration_options = ::RSpec::Core::ConfigurationOptions.new(@cli_args)
|
119
|
+
@rspec_runner = ::RSpec::Core::Runner.new(rspec_configuration_options)
|
120
|
+
@rspec_runner.knapsack__setup(@stream_error, @stream_out)
|
121
|
+
|
122
|
+
ensure_no_deprecated_run_all_when_everything_filtered_option!
|
120
123
|
end
|
121
124
|
|
122
|
-
def
|
123
|
-
|
124
|
-
when :subset_queue
|
125
|
-
KnapsackPro.logger.info("To retry the last batch of tests fetched from the API Queue, please run the following command on your machine:")
|
126
|
-
when :end_of_queue
|
127
|
-
KnapsackPro.logger.info("To retry all the tests assigned to this CI node, please run the following command on your machine:")
|
128
|
-
end
|
125
|
+
def post_run_tasks(exit_code)
|
126
|
+
@adapter_class.verify_bind_method_called
|
129
127
|
|
130
|
-
|
128
|
+
log_rspec_queue_command
|
131
129
|
|
132
|
-
KnapsackPro.
|
133
|
-
|
134
|
-
|
135
|
-
)
|
130
|
+
time_tracker = KnapsackPro::Formatters::TimeTrackerFetcher.call
|
131
|
+
KnapsackPro::Report.save_node_queue_to_api(time_tracker&.queue(@node_test_file_paths))
|
132
|
+
|
133
|
+
Kernel.exit(exit_code)
|
136
134
|
end
|
137
135
|
|
138
|
-
|
139
|
-
|
140
|
-
#
|
141
|
-
# Keep formatters and report to accumulate info about failed/pending tests
|
142
|
-
def self.rspec_clear_examples
|
143
|
-
if ::RSpec::ExampleGroups.respond_to?(:remove_all_constants)
|
144
|
-
::RSpec::ExampleGroups.remove_all_constants
|
145
|
-
else
|
146
|
-
::RSpec::ExampleGroups.constants.each do |constant|
|
147
|
-
::RSpec::ExampleGroups.__send__(:remove_const, constant)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
::RSpec.world.example_groups.clear
|
151
|
-
::RSpec.configuration.start_time = ::RSpec::Core::Time.now
|
152
|
-
|
153
|
-
if KnapsackPro::Config::Env.rspec_split_by_test_examples?
|
154
|
-
# Reset example group counts to ensure scoped example ids in metadata
|
155
|
-
# have correct index (not increased by each subsequent run).
|
156
|
-
# Solves this problem: https://github.com/rspec/rspec-core/issues/2721
|
157
|
-
::RSpec.world.instance_variable_set(:@example_group_counts_by_spec_file, Hash.new(0))
|
158
|
-
end
|
136
|
+
def ensure_no_deprecated_run_all_when_everything_filtered_option!
|
137
|
+
return unless @rspec_runner.knapsack__deprecated_run_all_when_everything_filtered_enabled?
|
159
138
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
end
|
139
|
+
error_message = "The run_all_when_everything_filtered option is deprecated. See: #{KnapsackPro::Urls::RSPEC__DEPRECATED_RUN_ALL_WHEN_EVERYTHING_FILTERED}"
|
140
|
+
KnapsackPro.logger.error(error_message)
|
141
|
+
raise error_message
|
164
142
|
end
|
165
143
|
|
166
|
-
def
|
167
|
-
|
144
|
+
def pull_tests_from_queue(can_initialize_queue: false)
|
145
|
+
test_file_paths = test_file_paths(
|
146
|
+
can_initialize_queue: can_initialize_queue,
|
147
|
+
executed_test_files: @node_test_file_paths
|
148
|
+
)
|
149
|
+
@node_test_file_paths += test_file_paths
|
150
|
+
test_file_paths
|
151
|
+
end
|
168
152
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
153
|
+
def log_rspec_batch_command(test_file_paths)
|
154
|
+
order_option = @adapter_class.order_option(@cli_args)
|
155
|
+
printable_args = @rspec_pure.args_with_seed_option_added_when_viable(order_option, @rspec_runner.knapsack__seed, @cli_args)
|
156
|
+
messages = @rspec_pure.rspec_command(printable_args, test_file_paths, :batch_finished)
|
157
|
+
log_info_messages(messages)
|
158
|
+
end
|
175
159
|
|
176
|
-
|
177
|
-
|
160
|
+
def log_rspec_queue_command
|
161
|
+
order_option = @adapter_class.order_option(@cli_args)
|
162
|
+
printable_args = @rspec_pure.args_with_seed_option_added_when_viable(order_option, @rspec_runner.knapsack__seed, @cli_args)
|
163
|
+
messages = @rspec_pure.rspec_command(printable_args, @node_test_file_paths, :queue_finished)
|
164
|
+
log_info_messages(messages)
|
165
|
+
end
|
178
166
|
|
179
|
-
|
167
|
+
def log_info_messages(messages)
|
168
|
+
messages.each do |message|
|
169
|
+
KnapsackPro.logger.info(message)
|
170
|
+
end
|
171
|
+
end
|
180
172
|
|
181
|
-
|
173
|
+
def unexecuted_test_files
|
174
|
+
KnapsackPro::Formatters::TimeTrackerFetcher.unexecuted_test_files(@node_test_file_paths)
|
182
175
|
end
|
183
176
|
end
|
184
177
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module KnapsackPro
|
2
4
|
module Runners
|
3
5
|
class RSpecRunner < BaseRunner
|
@@ -17,8 +19,6 @@ module KnapsackPro
|
|
17
19
|
cli_args = (args || '').split
|
18
20
|
adapter_class.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!(cli_args)
|
19
21
|
|
20
|
-
KnapsackPro.tracker.set_prerun_tests(runner.test_file_paths)
|
21
|
-
|
22
22
|
require 'rspec/core/rake_task'
|
23
23
|
|
24
24
|
task_name = 'knapsack_pro:rspec_run'
|
@@ -31,11 +31,30 @@ module KnapsackPro
|
|
31
31
|
# because pattern does not accept test example path like spec/a_spec.rb[1:2]
|
32
32
|
# instead we pass test files and test example paths to t.rspec_opts
|
33
33
|
t.pattern = []
|
34
|
-
t.rspec_opts = "#{args} --default-path #{runner.test_dir} #{runner.stringify_test_file_paths}"
|
34
|
+
t.rspec_opts = "#{args} #{self.formatters} --default-path #{runner.test_dir} #{runner.stringify_test_file_paths}"
|
35
|
+
t.verbose = KnapsackPro::Config::Env.log_level < ::Logger::WARN
|
35
36
|
end
|
36
37
|
Rake::Task[task_name].invoke
|
37
38
|
end
|
38
39
|
end
|
40
|
+
|
41
|
+
# Use RSpec::Core::ConfigurationOptions to respect external configurations like .rspec
|
42
|
+
def self.formatters
|
43
|
+
require_relative '../formatters/time_tracker'
|
44
|
+
|
45
|
+
formatters = ::RSpec::Core::ConfigurationOptions
|
46
|
+
.new([])
|
47
|
+
.options
|
48
|
+
.fetch(:formatters, [])
|
49
|
+
.map do |formatter, output|
|
50
|
+
arg = "--format #{formatter}"
|
51
|
+
arg += " --out #{output}" if output
|
52
|
+
arg
|
53
|
+
end
|
54
|
+
formatters = ['--format progress'] if formatters.empty?
|
55
|
+
formatters += ["--format #{KnapsackPro::Formatters::TimeTracker}"]
|
56
|
+
formatters.join(' ')
|
57
|
+
end
|
39
58
|
end
|
40
59
|
end
|
41
60
|
end
|
data/lib/knapsack_pro/tracker.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module KnapsackPro
|
2
4
|
class Tracker
|
3
5
|
include Singleton
|
@@ -6,11 +8,10 @@ module KnapsackPro
|
|
6
8
|
# to better allocate it in Queue Mode for future CI build runs
|
7
9
|
DEFAULT_TEST_FILE_TIME = 0.0 # seconds
|
8
10
|
|
9
|
-
attr_reader :
|
11
|
+
attr_reader :global_time, :test_files_with_time, :prerun_tests_loaded
|
10
12
|
attr_writer :current_test_path
|
11
13
|
|
12
14
|
def initialize
|
13
|
-
@global_time_since_beginning = 0
|
14
15
|
KnapsackPro::Config::TempFiles.ensure_temp_directory_exists!
|
15
16
|
FileUtils.mkdir_p(tracker_dir_path)
|
16
17
|
set_defaults
|
@@ -133,7 +134,6 @@ module KnapsackPro
|
|
133
134
|
|
134
135
|
def update_global_time(execution_time)
|
135
136
|
@global_time += execution_time
|
136
|
-
@global_time_since_beginning += execution_time
|
137
137
|
end
|
138
138
|
|
139
139
|
def update_test_file_time(execution_time)
|
data/lib/knapsack_pro/urls.rb
CHANGED
@@ -18,6 +18,8 @@ module KnapsackPro
|
|
18
18
|
|
19
19
|
INSTALLATION_GUIDE = "#{HOST}/perma/ruby/installation-guide"
|
20
20
|
|
21
|
+
KNAPSACK_PRO_CI_NODE_BUILD_ID= "#{HOST}/perma/ruby/knapsack-pro-ci-node-build-id"
|
22
|
+
|
21
23
|
QUEUE_MODE__CONNECTION_ERROR_WITH_FALLBACK_ENABLED_FALSE = "#{HOST}/perma/ruby/queue-mode-connection-error-with-fallback-enabled-false"
|
22
24
|
|
23
25
|
QUEUE_MODE__CONNECTION_ERROR_WITH_FALLBACK_ENABLED_TRUE_AND_POSITIVE_RETRY_COUNT = "#{HOST}/perma/ruby/queue-mode-connection-error-with-fallback-enabled-true-and-positive-retry-count"
|
@@ -26,6 +28,8 @@ module KnapsackPro
|
|
26
28
|
|
27
29
|
REGULAR_MODE__CONNECTION_ERROR_WITH_FALLBACK_ENABLED_TRUE_AND_POSITIVE_RETRY_COUNT = "#{HOST}/perma/ruby/regular-mode-connection-error-with-fallback-enabled-true-and-positive-retry-count"
|
28
30
|
|
31
|
+
RSPEC__DEPRECATED_RUN_ALL_WHEN_EVERYTHING_FILTERED = "#{HOST}/perma/ruby/rspec-deprecated-run-all-when-everything-filtered"
|
32
|
+
|
29
33
|
RSPEC__SKIPS_TESTS = "#{HOST}/perma/ruby/rspec-skips-tests"
|
30
34
|
|
31
35
|
RSPEC__SPLIT_BY_TEST_EXAMPLES__TAG = "#{HOST}/perma/ruby/rspec-split-by-test-examples-tag"
|
data/lib/knapsack_pro/utils.rb
CHANGED
data/lib/knapsack_pro/version.rb
CHANGED
data/lib/knapsack_pro.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'logger'
|
2
4
|
require 'singleton'
|
3
5
|
require 'net/http'
|
@@ -6,9 +8,9 @@ require 'uri'
|
|
6
8
|
require 'rake/testtask'
|
7
9
|
require 'digest'
|
8
10
|
require 'securerandom'
|
11
|
+
require 'timeout'
|
9
12
|
require_relative 'knapsack_pro/urls'
|
10
13
|
require_relative 'knapsack_pro/version'
|
11
|
-
require_relative 'knapsack_pro/extensions/time'
|
12
14
|
require_relative 'knapsack_pro/hooks/queue'
|
13
15
|
require_relative 'knapsack_pro/utils'
|
14
16
|
require_relative 'knapsack_pro/config/ci/base'
|
@@ -21,8 +23,6 @@ require_relative 'knapsack_pro/config/ci/semaphore'
|
|
21
23
|
require_relative 'knapsack_pro/config/ci/semaphore2'
|
22
24
|
require_relative 'knapsack_pro/config/ci/buildkite'
|
23
25
|
require_relative 'knapsack_pro/config/ci/travis'
|
24
|
-
require_relative 'knapsack_pro/config/ci/snap_ci'
|
25
|
-
require_relative 'knapsack_pro/config/ci/solano_ci'
|
26
26
|
require_relative 'knapsack_pro/config/ci/codeship'
|
27
27
|
require_relative 'knapsack_pro/config/ci/github_actions'
|
28
28
|
require_relative 'knapsack_pro/config/ci/heroku'
|
@@ -57,6 +57,7 @@ require_relative 'knapsack_pro/adapters/test_unit_adapter'
|
|
57
57
|
require_relative 'knapsack_pro/adapters/spinach_adapter'
|
58
58
|
require_relative 'knapsack_pro/allocator'
|
59
59
|
require_relative 'knapsack_pro/queue_allocator'
|
60
|
+
require_relative 'knapsack_pro/mask_string'
|
60
61
|
require_relative 'knapsack_pro/test_case_mergers/base_merger'
|
61
62
|
require_relative 'knapsack_pro/test_case_mergers/rspec_merger'
|
62
63
|
require_relative 'knapsack_pro/build_distribution_fetcher'
|
@@ -81,6 +82,7 @@ require_relative 'knapsack_pro/crypto/encryptor'
|
|
81
82
|
require_relative 'knapsack_pro/crypto/branch_encryptor'
|
82
83
|
require_relative 'knapsack_pro/crypto/decryptor'
|
83
84
|
require_relative 'knapsack_pro/crypto/digestor'
|
85
|
+
require_relative 'knapsack_pro/pure/queue/rspec_pure'
|
84
86
|
|
85
87
|
require 'knapsack_pro/railtie' if defined?(Rails::Railtie)
|
86
88
|
|
data/lib/tasks/cucumber.rake
CHANGED
data/lib/tasks/minitest.rake
CHANGED
@@ -1,8 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'knapsack_pro'
|
2
4
|
|
3
5
|
namespace :knapsack_pro do
|
4
6
|
namespace :queue do
|
5
7
|
task :cucumber, [:cucumber_args] do |_, args|
|
8
|
+
Kernel.system("RAILS_ENV=test RACK_ENV=test #{$PROGRAM_NAME} 'knapsack_pro:queue:cucumber_go[#{args[:cucumber_args]}]'")
|
9
|
+
exitstatus = $?.exitstatus
|
10
|
+
if exitstatus.nil?
|
11
|
+
puts 'Something went wrong. Most likely, the process has been killed. Knapsack Pro has been terminated.'
|
12
|
+
Kernel.exit(1)
|
13
|
+
else
|
14
|
+
Kernel.exit(exitstatus)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
task :cucumber_go, [:cucumber_args] do |_, args|
|
6
19
|
KnapsackPro::Runners::Queue::CucumberRunner.run(args[:cucumber_args])
|
7
20
|
end
|
8
21
|
end
|
@@ -1,8 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'knapsack_pro'
|
2
4
|
|
3
5
|
namespace :knapsack_pro do
|
4
6
|
namespace :queue do
|
5
7
|
task :minitest, [:minitest_args] do |_, args|
|
8
|
+
Kernel.system("RAILS_ENV=test RACK_ENV=test #{$PROGRAM_NAME} 'knapsack_pro:queue:minitest_go[#{args[:minitest_args]}]'")
|
9
|
+
exitstatus = $?.exitstatus
|
10
|
+
if exitstatus.nil?
|
11
|
+
puts 'Something went wrong. Most likely, the process has been killed. Knapsack Pro has been terminated.'
|
12
|
+
Kernel.exit(1)
|
13
|
+
else
|
14
|
+
Kernel.exit(exitstatus)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
task :minitest_go, [:minitest_args] do |_, args|
|
6
19
|
KnapsackPro::Runners::Queue::MinitestRunner.run(args[:minitest_args])
|
7
20
|
end
|
8
21
|
end
|
data/lib/tasks/queue/rspec.rake
CHANGED
@@ -1,8 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'knapsack_pro'
|
2
4
|
|
3
5
|
namespace :knapsack_pro do
|
4
6
|
namespace :queue do
|
5
7
|
task :rspec, [:rspec_args] do |_, args|
|
8
|
+
Kernel.system("RAILS_ENV=test RACK_ENV=test #{$PROGRAM_NAME} 'knapsack_pro:queue:rspec_go[#{args[:rspec_args]}]'")
|
9
|
+
exitstatus = $?.exitstatus
|
10
|
+
if exitstatus.nil?
|
11
|
+
puts 'Something went wrong. Most likely, the process has been killed. Knapsack Pro has been terminated.'
|
12
|
+
Kernel.exit(1)
|
13
|
+
else
|
14
|
+
Kernel.exit(exitstatus)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
task :rspec_go, [:rspec_args] do |_, args|
|
6
19
|
KnapsackPro::Runners::Queue::RSpecRunner.run(args[:rspec_args])
|
7
20
|
end
|
8
21
|
end
|