Skip to content

Commit

Permalink
refactor library config and components building
Browse files Browse the repository at this point in the history
  • Loading branch information
anmarchenko committed Jul 2, 2024
1 parent fea0ea2 commit 2e7f0ff
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 69 deletions.
151 changes: 83 additions & 68 deletions lib/datadog/ci/configuration/components.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ module Components
attr_reader :ci_recorder, :itr

def initialize(settings)
@itr = nil
@ci_recorder = TestVisibility::NullRecorder.new

# Activate CI mode if enabled
if settings.ci.enabled
activate_ci!(settings)
else
@itr = nil
@ci_recorder = TestVisibility::NullRecorder.new
end

super
Expand All @@ -53,22 +53,21 @@ def activate_ci!(settings)
return
end

# Configure ddtrace library for CI visibility mode
# Builds test visibility API layer in agentless or EvP proxy mode
test_visibility_api = build_test_visibility_api(settings)
# bail out early if api is misconfigured
return unless settings.ci.enabled

# Configure datadog gem for test visibility mode

# Deactivate telemetry
settings.telemetry.enabled = false

# Deactivate remote configuration
# Test visibility uses its own remote settings
settings.remote.enabled = false

# do not use 128-bit trace ids for CI visibility
# they are used for OTEL compatibility in Datadog tracer
settings.tracing.trace_id_128_bit_generation_enabled = false

# Activate underlying tracing test mode
settings.tracing.test_mode.enabled = true

# Choose user defined TraceFlush or default to CI TraceFlush
settings.tracing.test_mode.trace_flush = settings.ci.trace_flush || CI::TestVisibility::Flush::Partial.new
# startup logs are useless for test visibility and create noise
settings.diagnostics.startup_logs.enabled = false

# When timecop is present, Time.now is mocked and .now_without_mock_time is added on Time to
# get the current time without the mock.
Expand All @@ -81,76 +80,43 @@ def activate_ci!(settings)
end
end

# startup logs are useless for CI visibility and create noise
settings.diagnostics.startup_logs.enabled = false

# transport creation
writer_options = settings.ci.writer_options
coverage_writer = nil
test_visibility_api = build_test_visibility_api(settings)
# Configure Datadog::Tracing module

if test_visibility_api
# setup writer for code coverage payloads
coverage_writer = ITR::Coverage::Writer.new(
transport: ITR::Coverage::Transport.new(api: test_visibility_api)
)

# configure tracing writer to send traces to CI visibility backend
writer_options[:transport] = TestVisibility::Transport.new(
api: test_visibility_api,
serializers_factory: serializers_factory(settings),
dd_env: settings.env
)
writer_options[:shutdown_timeout] = 60
writer_options[:buffer_size] = 10_000

settings.tracing.test_mode.async = true
else
# only legacy APM protocol is supported, so no test suite level visibility
settings.ci.force_test_level_visibility = true

# ITR is not supported with APM protocol
settings.ci.itr_enabled = false
end
# No need not use 128-bit trace ids for test visibility,
# they are used for OTEL compatibility in Datadog tracer
settings.tracing.trace_id_128_bit_generation_enabled = false

settings.tracing.test_mode.writer_options = writer_options
# Activate underlying tracing test mode with async worker
settings.tracing.test_mode.enabled = true
settings.tracing.test_mode.async = true
settings.tracing.test_mode.trace_flush = settings.ci.trace_flush || CI::TestVisibility::Flush::Partial.new

custom_configuration_tags = Utils::TestRun.custom_configuration(settings.tags)
trace_writer_options = settings.ci.writer_options
trace_writer_options[:shutdown_timeout] = 60
trace_writer_options[:buffer_size] = 10_000
tracing_transport = build_tracing_transport(settings, test_visibility_api)
trace_writer_options[:transport] = tracing_transport if tracing_transport

remote_settings_api = Transport::RemoteSettingsApi.new(
api: test_visibility_api,
dd_env: settings.env,
config_tags: custom_configuration_tags
)
settings.tracing.test_mode.writer_options = trace_writer_options

itr = ITR::Runner.new(
# @type ivar @itr: Datadog::CI::ITR::Runner
@itr = ITR::Runner.new(
api: test_visibility_api,
dd_env: settings.env,
config_tags: custom_configuration_tags,
coverage_writer: coverage_writer,
config_tags: custom_configuration(settings),
coverage_writer: build_coverage_writer(settings, test_visibility_api),
enabled: settings.ci.enabled && settings.ci.itr_enabled,
bundle_location: settings.ci.itr_code_coverage_excluded_bundle_path,
use_single_threaded_coverage: settings.ci.itr_code_coverage_use_single_threaded_mode
)

git_tree_uploader = Git::TreeUploader.new(api: test_visibility_api)
git_tree_upload_worker = if settings.ci.git_metadata_upload_enabled
Worker.new do |repository_url|
git_tree_uploader.call(repository_url)
end
else
DummyWorker.new
end

# CI visibility recorder global instance
@ci_recorder = TestVisibility::Recorder.new(
test_suite_level_visibility_enabled: !settings.ci.force_test_level_visibility,
itr: itr,
remote_settings_api: remote_settings_api,
git_tree_upload_worker: git_tree_upload_worker
itr: @itr,
remote_settings_api: build_remote_settings_client(settings, test_visibility_api),
git_tree_upload_worker: build_git_upload_worker(settings, test_visibility_api)
)

@itr = itr
end

def build_test_visibility_api(settings)
Expand Down Expand Up @@ -179,12 +145,61 @@ def build_test_visibility_api(settings)
Datadog.logger.debug(
"Old agent version detected, no evp_proxy support. Forcing test level visibility mode"
)

# only legacy APM protocol is supported, so no test suite level visibility
settings.ci.force_test_level_visibility = true

# ITR is not supported with APM protocol
settings.ci.itr_enabled = false
end
end

api
end

def build_tracing_transport(settings, api)
return nil if api.nil?

TestVisibility::Transport.new(
api: api,
serializers_factory: serializers_factory(settings),
dd_env: settings.env
)
end

def build_coverage_writer(settings, api)
return nil if api.nil?

ITR::Coverage::Writer.new(
transport: ITR::Coverage::Transport.new(api: api)
)
end

def build_git_upload_worker(settings, api)
if settings.ci.git_metadata_upload_enabled
git_tree_uploader = Git::TreeUploader.new(api: api)
Worker.new do |repository_url|
git_tree_uploader.call(repository_url)
end
else
DummyWorker.new
end
end

def build_remote_settings_client(settings, api)
Transport::RemoteSettingsApi.new(
api: api,
dd_env: settings.env,
config_tags: custom_configuration(settings)
)
end

# fetch custom tags provided by the user in DD_TAGS env var
# with prefix test.configuration.
def custom_configuration(settings)
@custom_configuration ||= Utils::TestRun.custom_configuration(settings.tags)
end

def serializers_factory(settings)
if settings.ci.force_test_level_visibility
TestVisibility::Serializers::Factories::TestLevel
Expand Down
4 changes: 4 additions & 0 deletions lib/datadog/ci/test_visibility/null_recorder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ def active_test_suite(test_suite_name)
def shutdown!
end

def itr_enabled?
false
end

private

def skip_tracing(block = nil)
Expand Down
13 changes: 12 additions & 1 deletion sig/datadog/ci/configuration/components.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module Datadog
module Components : Datadog::Core::Configuration::Components
@ci_recorder: Datadog::CI::TestVisibility::Recorder | Datadog::CI::TestVisibility::NullRecorder
@itr: Datadog::CI::ITR::Runner?
@custom_configuration: Hash[String, String]

attr_reader ci_recorder: Datadog::CI::TestVisibility::Recorder | Datadog::CI::TestVisibility::NullRecorder
attr_reader itr: Datadog::CI::ITR::Runner?
Expand All @@ -18,8 +19,18 @@ module Datadog

def check_dd_site: (untyped settings) -> void

def build_tracing_transport: (untyped settings, Datadog::CI::Transport::Api::Base? api) -> Datadog::CI::TestVisibility::Transport?

def build_coverage_writer: (untyped settings, Datadog::CI::Transport::Api::Base? api) -> Datadog::CI::ITR::Coverage::Writer?

def build_git_upload_worker: (untyped settings, Datadog::CI::Transport::Api::Base? api) -> Datadog::CI::Worker

def build_remote_settings_client: (untyped settings, Datadog::CI::Transport::Api::Base? api) -> Datadog::CI::Transport::RemoteSettingsApi

def custom_configuration: (untyped settings) -> Hash[String, String]

def timecop?: () -> bool
end
end
end
end
end

0 comments on commit 2e7f0ff

Please sign in to comment.