Skip to content

Commit

Permalink
parse early_flake_detection_enabled? from remote library settings
Browse files Browse the repository at this point in the history
  • Loading branch information
anmarchenko committed Aug 29, 2024
1 parent c8cb890 commit f0d2445
Show file tree
Hide file tree
Showing 12 changed files with 111 additions and 46 deletions.
1 change: 1 addition & 0 deletions lib/datadog/ci/ext/telemetry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ module Telemetry
TAG_COMMAND = "command"
TAG_COVERAGE_ENABLED = "coverage_enabled"
TAG_ITR_SKIP_ENABLED = "itrskip_enabled"
TAG_EARLY_FLAKE_DETECTION_ENABLED = "early_flake_detection_enabled"
TAG_PROVIDER = "provider"
TAG_AUTO_INJECTED = "auto_injected"

Expand Down
1 change: 1 addition & 0 deletions lib/datadog/ci/ext/transport.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ module Transport
DD_API_SETTINGS_RESPONSE_TESTS_SKIPPING_KEY = "tests_skipping"
DD_API_SETTINGS_RESPONSE_REQUIRE_GIT_KEY = "require_git"
DD_API_SETTINGS_RESPONSE_FLAKY_TEST_RETRIES_KEY = "flaky_test_retries_enabled"
DD_API_SETTINGS_RESPONSE_EARLY_FLAKE_DETECTION_KEY = "early_flake_detection"
DD_API_SETTINGS_RESPONSE_DEFAULT = {DD_API_SETTINGS_RESPONSE_ITR_ENABLED_KEY => false}.freeze

DD_API_GIT_SEARCH_COMMITS_PATH = "/api/v2/git/repository/search_commits"
Expand Down
35 changes: 27 additions & 8 deletions lib/datadog/ci/remote/library_settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,39 +49,58 @@ def payload
def require_git?
return @require_git if defined?(@require_git)

@require_git = bool(Ext::Transport::DD_API_SETTINGS_RESPONSE_REQUIRE_GIT_KEY)
@require_git = Utils::Parsing.convert_to_bool(
payload.fetch(Ext::Transport::DD_API_SETTINGS_RESPONSE_REQUIRE_GIT_KEY, false)
)
end

def itr_enabled?
return @itr_enabled if defined?(@itr_enabled)

@itr_enabled = bool(Ext::Transport::DD_API_SETTINGS_RESPONSE_ITR_ENABLED_KEY)
@itr_enabled = Utils::Parsing.convert_to_bool(
payload.fetch(Ext::Transport::DD_API_SETTINGS_RESPONSE_ITR_ENABLED_KEY, false)
)
end

def code_coverage_enabled?
return @code_coverage_enabled if defined?(@code_coverage_enabled)

@code_coverage_enabled = bool(Ext::Transport::DD_API_SETTINGS_RESPONSE_CODE_COVERAGE_KEY)
@code_coverage_enabled = Utils::Parsing.convert_to_bool(
payload.fetch(Ext::Transport::DD_API_SETTINGS_RESPONSE_CODE_COVERAGE_KEY, false)
)
end

def tests_skipping_enabled?
return @tests_skipping_enabled if defined?(@tests_skipping_enabled)

@tests_skipping_enabled = bool(Ext::Transport::DD_API_SETTINGS_RESPONSE_TESTS_SKIPPING_KEY)
@tests_skipping_enabled = Utils::Parsing.convert_to_bool(
payload.fetch(Ext::Transport::DD_API_SETTINGS_RESPONSE_TESTS_SKIPPING_KEY, false)
)
end

def flaky_test_retries_enabled?
return @flaky_test_retries_enabled if defined?(@flaky_test_retries_enabled)

@flaky_test_retries_enabled = bool(Ext::Transport::DD_API_SETTINGS_RESPONSE_FLAKY_TEST_RETRIES_KEY)
@flaky_test_retries_enabled = Utils::Parsing.convert_to_bool(
payload.fetch(
Ext::Transport::DD_API_SETTINGS_RESPONSE_FLAKY_TEST_RETRIES_KEY, false
)
)
end

private
def early_flake_detection_enabled?
return @early_flake_detection_enabled if defined?(@early_flake_detection_enabled)

def bool(key)
Utils::Parsing.convert_to_bool(payload.fetch(key, false))
@early_flake_detection_enabled = Utils::Parsing.convert_to_bool(
payload.fetch(
Ext::Transport::DD_API_SETTINGS_RESPONSE_EARLY_FLAKE_DETECTION_KEY,
{}
).fetch("enabled", false)
)
end

private

def default_payload
Ext::Transport::DD_API_SETTINGS_RESPONSE_DEFAULT
end
Expand Down
3 changes: 2 additions & 1 deletion lib/datadog/ci/remote/library_settings_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ def fetch(test_session)
1,
{
Ext::Telemetry::TAG_COVERAGE_ENABLED => library_settings.code_coverage_enabled?.to_s,
Ext::Telemetry::TAG_ITR_SKIP_ENABLED => library_settings.tests_skipping_enabled?.to_s
Ext::Telemetry::TAG_ITR_SKIP_ENABLED => library_settings.tests_skipping_enabled?.to_s,
Ext::Telemetry::TAG_EARLY_FLAKE_DETECTION_ENABLED => library_settings.early_flake_detection_enabled?.to_s
}
)

Expand Down
6 changes: 5 additions & 1 deletion lib/datadog/ci/test_retries/component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ module TestRetries
# - retrying new tests - detect flaky tests as early as possible to prevent them from being merged
class Component
attr_reader :retry_failed_tests_enabled, :retry_failed_tests_max_attempts,
:retry_failed_tests_total_limit, :retry_failed_tests_count
:retry_failed_tests_total_limit, :retry_failed_tests_count,
:retry_new_tests_enabled

def initialize(
retry_failed_tests_enabled:,
Expand All @@ -24,11 +25,14 @@ def initialize(
# counter that store the current number of failed tests retried
@retry_failed_tests_count = 0

@retry_new_tests_enabled = true

@mutex = Mutex.new
end

def configure(library_settings)
@retry_failed_tests_enabled &&= library_settings.flaky_test_retries_enabled?
@retry_new_tests_enabled &&= library_settings.early_flake_detection_enabled?
end

def with_retries(&block)
Expand Down
2 changes: 2 additions & 0 deletions sig/datadog/ci/ext/telemetry.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ module Datadog

TAG_ITR_SKIP_ENABLED: "itrskip_enabled"

TAG_EARLY_FLAKE_DETECTION_ENABLED: "early_flake_detection_enabled"

TAG_PROVIDER: "provider"

TAG_AUTO_INJECTED: "auto_injected"
Expand Down
2 changes: 2 additions & 0 deletions sig/datadog/ci/ext/transport.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ module Datadog

DD_API_SETTINGS_RESPONSE_FLAKY_TEST_RETRIES_KEY: "flaky_test_retries_enabled"

DD_API_SETTINGS_RESPONSE_EARLY_FLAKE_DETECTION_KEY: "early_flake_detection"

DD_API_SETTINGS_RESPONSE_DEFAULT: Hash[String, untyped]

DD_API_GIT_SEARCH_COMMITS_PATH: "/api/v2/git/repository/search_commits"
Expand Down
5 changes: 3 additions & 2 deletions sig/datadog/ci/remote/library_settings.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module Datadog
@code_coverage_enabled: bool
@tests_skipping_enabled: bool
@flaky_test_retries_enabled: bool
@early_flake_detection_enabled: bool

def initialize: (Datadog::CI::Transport::Adapters::Net::Response? http_response) -> void

Expand All @@ -27,9 +28,9 @@ module Datadog

def flaky_test_retries_enabled?: () -> bool

private
def early_flake_detection_enabled?: () -> bool

def bool: (String key) -> bool
private

def default_payload: () -> Hash[String, untyped]
end
Expand Down
2 changes: 2 additions & 0 deletions sig/datadog/ci/test_retries/component.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ module Datadog

attr_reader retry_failed_tests_count: Integer

attr_reader retry_new_tests_enabled: bool

@mutex: Thread::Mutex

def initialize: (retry_failed_tests_enabled: bool, retry_failed_tests_max_attempts: Integer, retry_failed_tests_total_limit: Integer) -> void
Expand Down
41 changes: 26 additions & 15 deletions spec/datadog/ci/remote/library_settings_client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,26 @@
end

context "when response is OK" do
let(:attributes) do
{
"code_coverage" => "1",
"tests_skipping" => "false",
"itr_enabled" => "True",
"require_git" => require_git,
"flaky_test_retries_enabled" => "true",
"early_flake_detection" => {
"enabled" => "true",
"slow_test_retries" => {
"5s" => 10,
"10s" => 5,
"30s" => 3,
"5m" => 2
},
"faulty_session_threshold" => 30
}
}
end

let(:http_response) do
double(
"http_response",
Expand All @@ -78,13 +98,7 @@
"data" => {
"id" => "123",
"type" => Datadog::CI::Ext::Transport::DD_API_SETTINGS_TYPE,
"attributes" => {
"code_coverage" => "1",
"tests_skipping" => "false",
"itr_enabled" => "True",
"require_git" => require_git,
"flaky_test_retries_enabled" => "true"
}
"attributes" => attributes
}
}.to_json,
request_compressed: false,
Expand All @@ -95,21 +109,18 @@

it "parses the response" do
expect(response.ok?).to be true
expect(response.payload).to eq({
"code_coverage" => "1",
"tests_skipping" => "false",
"itr_enabled" => "True",
"require_git" => require_git,
"flaky_test_retries_enabled" => "true"
})
expect(response.payload).to eq(attributes)
expect(response.require_git?).to be false
expect(response.itr_enabled?).to be true
expect(response.code_coverage_enabled?).to be true
expect(response.tests_skipping_enabled?).to be false
expect(response.flaky_test_retries_enabled?).to be true
expect(response.early_flake_detection_enabled?).to be true

metric = telemetry_metric(:inc, "git_requests.settings_response")
expect(metric.tags).to eq("coverage_enabled" => "true", "itrskip_enabled" => "false")
expect(metric.tags).to eq(
"coverage_enabled" => "true", "itrskip_enabled" => "false", "early_flake_detection_enabled" => "true"
)
end

it_behaves_like "emits telemetry metric", :inc, "git_requests.settings", 1
Expand Down
52 changes: 35 additions & 17 deletions spec/datadog/ci/test_retries/component_spec.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
require_relative "../../../../lib/datadog/ci/test_retries/component"

RSpec.describe Datadog::CI::TestRetries::Component do
let(:library_settings) { instance_double(Datadog::CI::Remote::LibrarySettings) }
let(:library_settings) do
instance_double(
Datadog::CI::Remote::LibrarySettings,
flaky_test_retries_enabled?: remote_flaky_test_retries_enabled,
early_flake_detection_enabled?: remote_early_flake_detection_enabled
)
end

let(:retry_failed_tests_enabled) { true }
let(:retry_failed_tests_max_attempts) { 1 }
let(:retry_failed_tests_total_limit) { 12 }

let(:remote_flaky_test_retries_enabled) { false }
let(:remote_early_flake_detection_enabled) { false }

subject(:component) do
described_class.new(
retry_failed_tests_enabled: retry_failed_tests_enabled,
Expand All @@ -19,9 +28,7 @@
subject { component.configure(library_settings) }

context "when flaky test retries are enabled" do
before do
allow(library_settings).to receive(:flaky_test_retries_enabled?).and_return(true)
end
let(:remote_flaky_test_retries_enabled) { true }

it "enables retrying failed tests" do
subject
Expand All @@ -31,9 +38,7 @@
end

context "when flaky test retries are disabled" do
before do
allow(library_settings).to receive(:flaky_test_retries_enabled?).and_return(false)
end
let(:remote_flaky_test_retries_enabled) { false }

it "disables retrying failed tests" do
subject
Expand All @@ -44,17 +49,34 @@

context "when flaky test retries are disabled in local settings" do
let(:retry_failed_tests_enabled) { false }

before do
allow(library_settings).to receive(:flaky_test_retries_enabled?).and_return(true)
end
let(:remote_flaky_test_retries_enabled) { true }

it "disables retrying failed tests even if it's enabled remotely" do
subject

expect(component.retry_failed_tests_enabled).to be false
end
end

context "when early flake detecion is enabled" do
let(:remote_early_flake_detection_enabled) { true }

it "enables retrying failed tests" do
subject

expect(component.retry_new_tests_enabled).to be true
end
end

context "when early flake detecion is disabled" do
let(:remote_early_flake_detection_enabled) { false }

it "disables retrying failed tests" do
subject

expect(component.retry_new_tests_enabled).to be false
end
end
end

describe "#retry_failed_tests_max_attempts" do
Expand All @@ -80,7 +102,7 @@
end

context "when retry failed tests is enabled" do
let(:library_settings) { instance_double(Datadog::CI::Remote::LibrarySettings, flaky_test_retries_enabled?: true) }
let(:remote_flaky_test_retries_enabled) { true }

context "when test span is failed" do
let(:test_failed) { true }
Expand Down Expand Up @@ -130,8 +152,6 @@
end

context "when retry failed tests is disabled" do
let(:library_settings) { instance_double(Datadog::CI::Remote::LibrarySettings, flaky_test_retries_enabled?: false) }

it { is_expected.to be_a(Datadog::CI::TestRetries::Strategy::NoRetry) }
end
end
Expand Down Expand Up @@ -171,13 +191,11 @@
end

context "when no retries strategy is used" do
let(:library_settings) { instance_double(Datadog::CI::Remote::LibrarySettings, flaky_test_retries_enabled?: false) }

it { is_expected.to eq(1) }
end

context "when retried failed tests strategy is used" do
let(:library_settings) { instance_double(Datadog::CI::Remote::LibrarySettings, flaky_test_retries_enabled?: true) }
let(:remote_flaky_test_retries_enabled) { true }

context "when test span is failed" do
let(:test_failed) { true }
Expand Down
7 changes: 5 additions & 2 deletions spec/support/contexts/ci_mode.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
let(:bundle_path) { nil }
let(:use_single_threaded_coverage) { false }
let(:flaky_test_retries_enabled) { false }
let(:early_flake_detection_enabled) { false }

let(:retry_failed_tests_max_attempts) { 5 }
let(:retry_failed_tests_total_limit) { 100 }
Expand Down Expand Up @@ -66,7 +67,8 @@
itr_enabled?: itr_enabled,
code_coverage_enabled?: code_coverage_enabled,
tests_skipping_enabled?: tests_skipping_enabled,
flaky_test_retries_enabled?: flaky_test_retries_enabled
flaky_test_retries_enabled?: flaky_test_retries_enabled,
early_flake_detection_enabled?: early_flake_detection_enabled
),
# This is for the second call to fetch_library_settings
instance_double(
Expand All @@ -80,7 +82,8 @@
itr_enabled?: itr_enabled,
code_coverage_enabled?: !code_coverage_enabled,
tests_skipping_enabled?: !tests_skipping_enabled,
flaky_test_retries_enabled?: flaky_test_retries_enabled
flaky_test_retries_enabled?: flaky_test_retries_enabled,
early_flake_detection_enabled?: early_flake_detection_enabled
)
)
allow_any_instance_of(Datadog::CI::TestOptimisation::Skippable).to receive(:fetch_skippable_tests).and_return(skippable_tests_response)
Expand Down

0 comments on commit f0d2445

Please sign in to comment.