Skip to content

Fix 'load core only and configure library with no settings' spec when run locally#5555

Open
eregon wants to merge 1 commit intomasterfrom
bd/fix-load-core-only
Open

Fix 'load core only and configure library with no settings' spec when run locally#5555
eregon wants to merge 1 commit intomasterfrom
bd/fix-load-core-only

Conversation

@eregon
Copy link
Copy Markdown
Member

@eregon eregon commented Apr 2, 2026

What does this PR do?

Fix a spec failing when running the test suite locally:

RSpec.describe 'load core only and configure library with no settings' do
let(:code) do
<<-E
if defined?(Datadog)
unless Datadog.constants == [:VERSION]
exit 1
end
end
require 'datadog/core'
Datadog.configure do
end
E
end
it 'configures successfully' do
rv = system("ruby -e #{Shellwords.shellescape(code)}")
expect(rv).to be true
end
end

Motivation:

Be green.

Change log entry

None.

Additional Notes:

How to test the change?

@eregon eregon requested a review from ivoanjo April 2, 2026 15:46
@eregon eregon requested a review from a team as a code owner April 2, 2026 15:46
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 2, 2026

Thank you for updating Change log entry section 👏

Visited at: 2026-04-02 15:49:37 UTC

@github-actions github-actions bot added the core Involves Datadog core libraries label Apr 2, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 2, 2026

Typing analysis

Note: Ignored files are excluded from the next sections.

steep:ignore comments

This PR introduces 4 steep:ignore comments, and clears 4 steep:ignore comments.

steep:ignore comments (+4-4)Introduced:
lib/datadog/core/telemetry/event/app_started.rb:141
lib/datadog/core/telemetry/event/app_started.rb:147
lib/datadog/core/telemetry/event/app_started.rb:158
lib/datadog/core/telemetry/event/app_started.rb:168
Cleared:
lib/datadog/core/telemetry/event/app_started.rb:139
lib/datadog/core/telemetry/event/app_started.rb:145
lib/datadog/core/telemetry/event/app_started.rb:156
lib/datadog/core/telemetry/event/app_started.rb:166

@eregon
Copy link
Copy Markdown
Member Author

eregon commented Apr 2, 2026

The fix is suggested by Cursor, maybe there is a better fix?
Also how much is require 'datadog/core' really supported?

Comment on lines +66 to +67
# Profiling is not loaded when disabled (see Profiling::Component.build_profiler_component); skip error payload
if Datadog::Profiling.respond_to?(:unsupported_reason) && (unsupported_reason = Datadog::Profiling.unsupported_reason)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look right? lib/datadog/profiling.rb is loaded even when disabled -- so if the module is loaded, the unsupported_reason method is expected to be here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See

require_relative "../profiling"
which seems the likely cause.

I checked and I indeed get the NoMethodError when undoing this change.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, you're right. It's because of the big comment above it -- we delay requiring profiling to break the potential require cycle.

Yeaaaah this whole thing needs a bit of a clean-up. Thanks for spotting it. I think this is indeed the correct interim fix for now.

@@ -52,7 +52,8 @@ def products(components)
products = {
appsec: {
# TODO take appsec status out of component tree?
Copy link
Copy Markdown
Member Author

@eregon eregon Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To address this at the same time maybe it should be components.appsec&.enabled? or so, but I'm not sure what kind of object is components.appsec when not nil.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Welcome to some of our legacy issues haha! The configuration system... is weird... and some things monkey patch themselves in there for reasons that made sense at the time when we wrote them but no longer make sense in 2026+

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried and it doesn't work:

  1) Datadog::Core::Telemetry::Event::AppStarted.payload with stable config with config id reports config id
     Failure/Error: enabled: !!components.appsec&.enabled?,
     
     NoMethodError:
       undefined method 'enabled?' for an instance of Datadog::AppSec::Component
     # ./lib/datadog/core/telemetry/event/app_started.rb:54:in 'Datadog::Core::Telemetry::Event::AppStarted#products'
     # ./lib/datadog/core/telemetry/event/app_started.rb:22:in 'Datadog::Core::Telemetry::Event::AppStarted#initialize'
     # ./spec/datadog/core/telemetry/event/app_started_spec.rb:7:in 'Class#new'
     # ./spec/datadog/core/telemetry/event/app_started_spec.rb:7:in 'block (2 levels) in <top (required)>'
     # ./spec/datadog/core/telemetry/event/app_started_spec.rb:256:in 'block (5 levels) in <top (required)>'
     # ./spec/spec_helper.rb:274:in 'block (2 levels) in <top (required)>'
     # ./spec/spec_helper.rb:154:in 'block (2 levels) in <top (required)>'
     # ./spec/support/execute_in_fork.rb:32:in 'ForkableExample#run'

  2) Datadog::Core::Telemetry::Event::AppStarted.payload with stable config with config id without config id does not report config id
     Failure/Error: enabled: !!components.appsec&.enabled?,
     
     NoMethodError:
       undefined method 'enabled?' for an instance of Datadog::AppSec::Component
     # ./lib/datadog/core/telemetry/event/app_started.rb:54:in 'Datadog::Core::Telemetry::Event::AppStarted#products'
     # ./lib/datadog/core/telemetry/event/app_started.rb:22:in 'Datadog::Core::Telemetry::Event::AppStarted#initialize'
     # ./spec/datadog/core/telemetry/event/app_started_spec.rb:7:in 'Class#new'
     # ./spec/datadog/core/telemetry/event/app_started_spec.rb:7:in 'block (2 levels) in <top (required)>'
     # ./spec/datadog/core/telemetry/event/app_started_spec.rb:273:in 'block (6 levels) in <top (required)>'
     # ./spec/spec_helper.rb:274:in 'block (2 levels) in <top (required)>'
     # ./spec/spec_helper.rb:154:in 'block (2 levels) in <top (required)>'
     # ./spec/support/execute_in_fork.rb:32:in 'ForkableExample#run'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/DataDog/dd-trace-rb/blob/master/lib/datadog/appsec/extensions.rb is where the appsec settings "show up" -- TBH we should just eagerly load all the settings instead of doing this but maybe not for this PR yet?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about lib/datadog/appsec/component.rb defining an enabled? method when build_appsec_component doesn't return nil?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that would work as well, but to me is slightly more weird than the settings.respond_to?(:appsec) as usually we don't ask the components about things being enabled -- that's usually the job of the settings.

(But no strong feelings on it, I think that one would work too for now)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI I worked on this in #5075, maybe you will find it helpful.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I think our old "modularization" efforts mostly failed, so I'm of the opinion that in the future (not in this PR) we should just clean up the wish-it-was-modular code.

(Not for this PR :P) Once we're ready/need to be modular, then we can actually do the work end-to-end, I don't think we're saving ourselves any work from keeping the half-broken migration as-is.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the direction #5075 is going, this PR feels too hacky for me.
What's the reason it was closed?

@datadog-official
Copy link
Copy Markdown

datadog-official bot commented Apr 2, 2026

✅ Tests

🎉 All green!

❄️ No new flaky tests detected
🧪 All tests passed

🎯 Code Coverage (details)
Patch Coverage: 100.00%
Overall Coverage: 95.35% (-0.02%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 711390a | Docs | Datadog PR Page | Was this helpful? React with 👍/👎 or give us feedback!

@eregon eregon force-pushed the bd/fix-load-core-only branch from e83c1f1 to 711390a Compare April 3, 2026 12:48
@pr-commenter
Copy link
Copy Markdown

pr-commenter bot commented Apr 3, 2026

Benchmarks

Benchmark execution time: 2026-04-03 13:16:22

Comparing candidate commit 711390a in PR branch bd/fix-load-core-only with baseline commit 716872e in branch master.

Found 0 performance improvements and 0 performance regressions! Performance is the same for 45 metrics, 1 unstable metrics.

Explanation

This is an A/B test comparing a candidate commit's performance against that of a baseline commit. Performance changes are noted in the tables below as:

  • 🟩 = significantly better candidate vs. baseline
  • 🟥 = significantly worse candidate vs. baseline

We compute a confidence interval (CI) over the relative difference of means between metrics from the candidate and baseline commits, considering the baseline as the reference.

If the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD), the change is considered significant.

Feel free to reach out to #apm-benchmarking-platform on Slack if you have any questions.

More details about the CI and significant changes

You can imagine this CI as a range of values that is likely to contain the true difference of means between the candidate and baseline commits.

CIs of the difference of means are often centered around 0%, because often changes are not that big:

---------------------------------(------|---^--------)-------------------------------->
                              -0.6%    0%  0.3%     +1.2%
                                 |          |        |
         lower bound of the CI --'          |        |
sample mean (center of the CI) -------------'        |
         upper bound of the CI ----------------------'

As described above, a change is considered significant if the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD).

For instance, for an execution time metric, this confidence interval indicates a significantly worse performance:

----------------------------------------|---------|---(---------^---------)---------->
                                       0%        1%  1.3%      2.2%      3.1%
                                                  |   |         |         |
       significant impact threshold --------------'   |         |         |
                      lower bound of CI --------------'         |         |
       sample mean (center of the CI) --------------------------'         |
                      upper bound of CI ----------------------------------'

Copy link
Copy Markdown
Member

@ivoanjo ivoanjo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 LGTM, thanks for catching this one!

Comment on lines +66 to +67
# Profiling is not loaded when disabled (see Profiling::Component.build_profiler_component); skip error payload
if Datadog::Profiling.respond_to?(:unsupported_reason) && (unsupported_reason = Datadog::Profiling.unsupported_reason)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, you're right. It's because of the big comment above it -- we delay requiring profiling to break the potential require cycle.

Yeaaaah this whole thing needs a bit of a clean-up. Thanks for spotting it. I think this is indeed the correct interim fix for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core Involves Datadog core libraries

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants