Class: Datadog::CI::TestRetries::Component
- Inherits:
-
Object
- Object
- Datadog::CI::TestRetries::Component
- Defined in:
- lib/datadog/ci/test_retries/component.rb
Overview
Encapsulates the logic to enable test retries, including:
-
retrying failed tests - improve success rate of CI pipelines
-
retrying new tests - detect flaky tests as early as possible to prevent them from being merged
Direct Known Subclasses
Instance Attribute Summary collapse
-
#retry_failed_tests_count ⇒ Object
readonly
Returns the value of attribute retry_failed_tests_count.
-
#retry_failed_tests_enabled ⇒ Object
readonly
Returns the value of attribute retry_failed_tests_enabled.
-
#retry_failed_tests_max_attempts ⇒ Object
readonly
Returns the value of attribute retry_failed_tests_max_attempts.
-
#retry_failed_tests_total_limit ⇒ Object
readonly
Returns the value of attribute retry_failed_tests_total_limit.
Instance Method Summary collapse
- #build_strategy(test_span) ⇒ Object
- #configure(library_settings) ⇒ Object
-
#initialize(retry_failed_tests_enabled:, retry_failed_tests_max_attempts:, retry_failed_tests_total_limit:) ⇒ Component
constructor
A new instance of Component.
- #with_retries(&block) ⇒ Object
Constructor Details
#initialize(retry_failed_tests_enabled:, retry_failed_tests_max_attempts:, retry_failed_tests_total_limit:) ⇒ Component
Returns a new instance of Component.
16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/datadog/ci/test_retries/component.rb', line 16 def initialize( retry_failed_tests_enabled:, retry_failed_tests_max_attempts:, retry_failed_tests_total_limit: ) @retry_failed_tests_enabled = retry_failed_tests_enabled @retry_failed_tests_max_attempts = retry_failed_tests_max_attempts @retry_failed_tests_total_limit = retry_failed_tests_total_limit # counter that store the current number of failed tests retried @retry_failed_tests_count = 0 @mutex = Mutex.new end |
Instance Attribute Details
#retry_failed_tests_count ⇒ Object (readonly)
Returns the value of attribute retry_failed_tests_count.
13 14 15 |
# File 'lib/datadog/ci/test_retries/component.rb', line 13 def retry_failed_tests_count @retry_failed_tests_count end |
#retry_failed_tests_enabled ⇒ Object (readonly)
Returns the value of attribute retry_failed_tests_enabled.
13 14 15 |
# File 'lib/datadog/ci/test_retries/component.rb', line 13 def retry_failed_tests_enabled @retry_failed_tests_enabled end |
#retry_failed_tests_max_attempts ⇒ Object (readonly)
Returns the value of attribute retry_failed_tests_max_attempts.
13 14 15 |
# File 'lib/datadog/ci/test_retries/component.rb', line 13 def retry_failed_tests_max_attempts @retry_failed_tests_max_attempts end |
#retry_failed_tests_total_limit ⇒ Object (readonly)
Returns the value of attribute retry_failed_tests_total_limit.
13 14 15 |
# File 'lib/datadog/ci/test_retries/component.rb', line 13 def retry_failed_tests_total_limit @retry_failed_tests_total_limit end |
Instance Method Details
#build_strategy(test_span) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/datadog/ci/test_retries/component.rb', line 59 def build_strategy(test_span) @mutex.synchronize do if should_retry_failed_test?(test_span) Datadog.logger.debug("Failed test retry starts") @retry_failed_tests_count += 1 Strategy::RetryFailed.new(max_attempts: @retry_failed_tests_max_attempts) else Strategy::NoRetry.new end end end |
#configure(library_settings) ⇒ Object
30 31 32 |
# File 'lib/datadog/ci/test_retries/component.rb', line 30 def configure(library_settings) @retry_failed_tests_enabled &&= library_settings.flaky_test_retries_enabled? end |
#with_retries(&block) ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/datadog/ci/test_retries/component.rb', line 34 def with_retries(&block) # @type var retry_strategy: Strategy::Base retry_strategy = nil test_finished_callback = lambda do |test_span| if retry_strategy.nil? # we always run test at least once and after first pass create a correct retry strategy retry_strategy = build_strategy(test_span) else # after each retry we record the result, strategy will decide if we should retry again retry_strategy&.record_retry(test_span) end end test_visibility_component.set_test_finished_callback(test_finished_callback) loop do yield break unless retry_strategy&.should_retry? end ensure test_visibility_component.remove_test_finished_callback end |