diff --git a/benchmarks/profiler_sample_loop.rb b/benchmarks/profiler_sample_loop.rb index b0435ede734..1dfe606220d 100644 --- a/benchmarks/profiler_sample_loop.rb +++ b/benchmarks/profiler_sample_loop.rb @@ -21,6 +21,7 @@ def create_profiler c.profiling.enabled = true c.profiling.exporter.transport = MockProfilerTransport.new c.tracing.transport_options = proc { |t| t.adapter :test } + c.profiling.advanced.force_enable_legacy_profiler = true end # Stop background threads diff --git a/ext/ddtrace_profiling_native_extension/private_vm_api_access.c b/ext/ddtrace_profiling_native_extension/private_vm_api_access.c index 238b69efcb7..99f1646a830 100644 --- a/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +++ b/ext/ddtrace_profiling_native_extension/private_vm_api_access.c @@ -19,6 +19,8 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #pragma GCC diagnostic ignored "-Wattributes" + #pragma GCC diagnostic ignored "-Wpragmas" + #pragma GCC diagnostic ignored "-Wexpansion-to-defined" #include #pragma GCC diagnostic pop #include @@ -651,6 +653,7 @@ check_method_entry(VALUE obj, int can_be_svar) if (can_be_svar) { return check_method_entry(((struct vm_svar *)obj)->cref_or_me, FALSE); } + // fallthrough default: #if VM_CHECK_MODE > 0 rb_bug("check_method_entry: svar should not be there:"); diff --git a/integration/apps/rack/spec/integration/basic_spec.rb b/integration/apps/rack/spec/integration/basic_spec.rb index ef3b9fb1bde..a2b12c7d46e 100644 --- a/integration/apps/rack/spec/integration/basic_spec.rb +++ b/integration/apps/rack/spec/integration/basic_spec.rb @@ -14,7 +14,18 @@ let(:expected_profiler_available) { RUBY_VERSION >= '2.3' } let(:expected_profiler_threads) do - contain_exactly('Datadog::Profiling::Collectors::OldStack', 'Datadog::Profiling::Scheduler') unless RUBY_VERSION < '2.3' + if RUBY_VERSION >= '2.6.' + contain_exactly( + 'Datadog::Profiling::Collectors::IdleSamplingHelper', + 'Datadog::Profiling::Collectors::CpuAndWallTimeWorker', + 'Datadog::Profiling::Scheduler', + ) + elsif RUBY_VERSION >= '2.3' + contain_exactly( + 'Datadog::Profiling::Collectors::OldStack', + 'Datadog::Profiling::Scheduler', + ) + end end context 'component checks' do diff --git a/integration/apps/sinatra2-classic/spec/integration/basic_spec.rb b/integration/apps/sinatra2-classic/spec/integration/basic_spec.rb index 03e05e0a0d6..55f2346f612 100644 --- a/integration/apps/sinatra2-classic/spec/integration/basic_spec.rb +++ b/integration/apps/sinatra2-classic/spec/integration/basic_spec.rb @@ -14,7 +14,18 @@ let(:expected_profiler_available) { RUBY_VERSION >= '2.3' } let(:expected_profiler_threads) do - contain_exactly('Datadog::Profiling::Collectors::OldStack', 'Datadog::Profiling::Scheduler') unless RUBY_VERSION < '2.3' + if RUBY_VERSION >= '2.6.' + contain_exactly( + 'Datadog::Profiling::Collectors::IdleSamplingHelper', + 'Datadog::Profiling::Collectors::CpuAndWallTimeWorker', + 'Datadog::Profiling::Scheduler', + ) + elsif RUBY_VERSION >= '2.3' + contain_exactly( + 'Datadog::Profiling::Collectors::OldStack', + 'Datadog::Profiling::Scheduler', + ) + end end context 'component checks' do diff --git a/integration/apps/sinatra2-modular/spec/integration/basic_spec.rb b/integration/apps/sinatra2-modular/spec/integration/basic_spec.rb index 03e05e0a0d6..55f2346f612 100644 --- a/integration/apps/sinatra2-modular/spec/integration/basic_spec.rb +++ b/integration/apps/sinatra2-modular/spec/integration/basic_spec.rb @@ -14,7 +14,18 @@ let(:expected_profiler_available) { RUBY_VERSION >= '2.3' } let(:expected_profiler_threads) do - contain_exactly('Datadog::Profiling::Collectors::OldStack', 'Datadog::Profiling::Scheduler') unless RUBY_VERSION < '2.3' + if RUBY_VERSION >= '2.6.' + contain_exactly( + 'Datadog::Profiling::Collectors::IdleSamplingHelper', + 'Datadog::Profiling::Collectors::CpuAndWallTimeWorker', + 'Datadog::Profiling::Scheduler', + ) + elsif RUBY_VERSION >= '2.3' + contain_exactly( + 'Datadog::Profiling::Collectors::OldStack', + 'Datadog::Profiling::Scheduler', + ) + end end context 'component checks' do diff --git a/lib/datadog/core/configuration/settings.rb b/lib/datadog/core/configuration/settings.rb index 1fdc6dc3455..0b329b70cd6 100644 --- a/lib/datadog/core/configuration/settings.rb +++ b/lib/datadog/core/configuration/settings.rb @@ -202,10 +202,10 @@ def initialize(*_) # @public_api settings :advanced do # This should never be reduced, as it can cause the resulting profiles to become biased. - # The current default should be enough for most services, allowing 16 threads to be sampled around 30 times + # The default should be enough for most services, allowing 16 threads to be sampled around 30 times # per second for a 60 second period. # - # This setting is ignored when CPU Profiling 2.0 is in use. + # @deprecated This setting is ignored when CPU Profiling 2.0 is in use. option :max_events, default: 32768 # Controls the maximum number of frames for each thread sampled. Can be tuned to avoid omitted frames in the @@ -236,7 +236,7 @@ def initialize(*_) # grouping and categorization of stack traces. option :code_provenance_enabled, default: true - # No longer does anything, and will be removed on dd-trace-rb 2.0. + # @deprecated No longer does anything, and will be removed on dd-trace-rb 2.0. # # This was added as a temporary support option in case of issues with the new `Profiling::HttpTransport` class # but we're now confident it's working nicely so we've removed the old code path. @@ -252,8 +252,8 @@ def initialize(*_) # Forces enabling the new CPU Profiling 2.0 profiler (see ddtrace release notes for more details). # # Note that setting this to "false" (or not setting it) will not prevent the new profiler from - # being automatically used in the future. - # This option will be deprecated for removal once the new profiler gets enabled by default for all customers. + # being automatically used. + # This option will be deprecated for removal once the legacy profiler is removed. # # @default `DD_PROFILING_FORCE_ENABLE_NEW` environment variable, otherwise `false` option :force_enable_new_profiler do |o| @@ -261,19 +261,30 @@ def initialize(*_) o.lazy end + # Forces enabling the *legacy* (non-CPU Profiling 2.0 profiler) even when it would otherwise NOT be enabled. + # + # Temporarily added to ease migration to the new CPU Profiling 2.0 profiler, and will be removed soon. + # Do not use unless instructed to by support. + # This option will be deprecated for removal once the legacy profiler is removed. + # + # @default `DD_PROFILING_FORCE_ENABLE_LEGACY` environment variable, otherwise `false` + option :force_enable_legacy_profiler do |o| + o.default { env_to_bool('DD_PROFILING_FORCE_ENABLE_LEGACY', false) } + o.lazy + end + # Forces enabling of profiling of time/resources spent in Garbage Collection. # # Note that setting this to "false" (or not setting it) will not prevent the feature from being # being automatically enabled in the future. # - # This toggle was added because, although this feature is safe and enabled by default on Ruby 2.x, - # on Ruby 3.x it can break in applications that make use of Ractors due to two Ruby VM bugs: - # https://bugs.ruby-lang.org/issues/19112 AND https://bugs.ruby-lang.org/issues/18464. - # - # If you use Ruby 3.x and your application does not use Ractors (or if your Ruby has been patched), the - # feature is fully safe to enable and this toggle can be used to do so. - # - # Furthermore, currently this feature can add a lot of overhead for GC-heavy workloads. + # This feature defaults to off for two reasons: + # 1. Currently this feature can add a lot of overhead for GC-heavy workloads. + # 2. Although this feature is safe on Ruby 2.x, on Ruby 3.x it can break in applications that make use of + # Ractors due to two Ruby VM bugs: + # https://bugs.ruby-lang.org/issues/19112 AND https://bugs.ruby-lang.org/issues/18464. + # If you use Ruby 3.x and your application does not use Ractors (or if your Ruby has been patched), the + # feature is fully safe to enable and this toggle can be used to do so. # # We expect the once the above issues are overcome, we'll automatically enable the feature on fixed Ruby # versions. @@ -292,6 +303,8 @@ def initialize(*_) # # If you use Ruby 3.x and your application does not use Ractors (or if your Ruby has been patched), the # feature is fully safe to enable and this toggle can be used to do so. + # + # @default `true` on Ruby 2.x, `false` on Ruby 3.x option :allocation_counting_enabled, default: RUBY_VERSION.start_with?('2.') end diff --git a/lib/datadog/profiling/component.rb b/lib/datadog/profiling/component.rb index 0c3e09d082b..611ac66019f 100644 --- a/lib/datadog/profiling/component.rb +++ b/lib/datadog/profiling/component.rb @@ -64,7 +64,7 @@ def self.build_profiler_component(settings:, agent_settings:, optional_tracer:) # NOTE: Please update the Initialization section of ProfilingDevelopment.md with any changes to this method - if settings.profiling.advanced.force_enable_new_profiler + if enable_new_profiler?(settings) print_new_profiler_warnings recorder = Datadog::Profiling::StackRecorder.new( @@ -142,21 +142,43 @@ def self.build_profiler_component(settings:, agent_settings:, optional_tracer:) end private_class_method def self.print_new_profiler_warnings - if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.6') + return if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.6') + + # For more details on the issue, see the "BIG Issue" comment on `gvl_owner` function in + # `private_vm_api_access.c`. + Datadog.logger.warn( + 'The new CPU Profiling 2.0 profiler has been force-enabled on a legacy Ruby version (< 2.6). This is not ' \ + 'recommended in production environments, as due to limitations in Ruby APIs, we suspect it may lead to crashes ' \ + 'in very rare situations. Please report any issues you run into to Datadog support or ' \ + 'via !' + ) + end + + private_class_method def self.enable_new_profiler?(settings) + if settings.profiling.advanced.force_enable_legacy_profiler Datadog.logger.warn( - 'New Ruby profiler has been force-enabled. This is a beta feature. Please report any issues ' \ - 'you run into to Datadog support or via !' + 'Legacy profiler has been force-enabled via configuration. Do not use unless instructed to by support.' ) - else - # For more details on the issue, see the "BIG Issue" comment on `gvl_owner` function in - # `private_vm_api_access.c`. + return false + end + + return true if settings.profiling.advanced.force_enable_new_profiler + + return false if RUBY_VERSION.start_with?('2.3.', '2.4.', '2.5.') + + if Gem.loaded_specs['mysql2'] Datadog.logger.warn( - 'New Ruby profiler has been force-enabled on a legacy Ruby version (< 2.6). This is not recommended in ' \ - 'production environments, as due to limitations in Ruby APIs, we suspect it may lead to crashes in very ' \ - 'rare situations. Please report any issues you run into to Datadog support or ' \ - 'via !' + 'Falling back to legacy profiler because mysql2 gem is installed. Older versions of libmysqlclient (the C ' \ + 'library used by the mysql2 gem) have a bug in their signal handling code that the new profiler can trigger. ' \ + 'This bug (https://bugs.mysql.com/bug.php?id=83109) is fixed in libmysqlclient versions 8.0.0 and above. ' \ + 'If your Linux distribution provides a modern libmysqlclient, you can force-enable the new CPU Profiling 2.0 ' \ + 'profiler by using the `DD_PROFILING_FORCE_ENABLE_NEW` or `c.profiling.advanced.force_enable_new_profiler` ' \ + 'settings.' ) + return false end + + true end end end diff --git a/lib/datadog/profiling/tasks/setup.rb b/lib/datadog/profiling/tasks/setup.rb index 51192b275ab..625453bf9fe 100644 --- a/lib/datadog/profiling/tasks/setup.rb +++ b/lib/datadog/profiling/tasks/setup.rb @@ -11,7 +11,6 @@ class Setup def run ACTIVATE_EXTENSIONS_ONLY_ONCE.run do begin - check_if_cpu_time_profiling_is_supported activate_forking_extensions setup_at_fork_hooks rescue StandardError, ScriptError => e @@ -38,17 +37,6 @@ def activate_forking_extensions end end - def check_if_cpu_time_profiling_is_supported - unsupported = cpu_time_profiling_unsupported_reason - - if unsupported - Datadog.logger.info do - 'CPU time profiling skipped because native CPU time is not supported: ' \ - "#{unsupported}. Profiles containing 'Wall time' data will still be reported." - end - end - end - def setup_at_fork_hooks if Process.respond_to?(:at_fork) Process.at_fork(:child) do @@ -64,20 +52,6 @@ def setup_at_fork_hooks end end end - - def cpu_time_profiling_unsupported_reason - # NOTE: Only the first matching reason is returned, so try to keep a nice order on reasons - - if RUBY_ENGINE == 'jruby' - 'JRuby is not supported' - elsif RUBY_PLATFORM.include?('darwin') - 'Feature requires Linux; macOS is not supported' - elsif RUBY_PLATFORM =~ /(mswin|mingw)/ - 'Feature requires Linux; Windows is not supported' - elsif !RUBY_PLATFORM.include?('linux') - "Feature requires Linux; #{RUBY_PLATFORM} is not supported" - end - end end end end diff --git a/sig/datadog/profiling/component.rbs b/sig/datadog/profiling/component.rbs index a2df83544a1..da7883e1fa3 100644 --- a/sig/datadog/profiling/component.rbs +++ b/sig/datadog/profiling/component.rbs @@ -28,6 +28,8 @@ module Datadog def self.enable_gc_profiling?: (untyped settings) -> bool def self.print_new_profiler_warnings: () -> void + + def self.enable_new_profiler?: (untyped settings) -> bool end end end diff --git a/spec/datadog/core/configuration/settings_spec.rb b/spec/datadog/core/configuration/settings_spec.rb index d9f07958e98..e9c7510071e 100644 --- a/spec/datadog/core/configuration/settings_spec.rb +++ b/spec/datadog/core/configuration/settings_spec.rb @@ -460,6 +460,41 @@ end end + describe '#force_enable_legacy_profiler' do + subject(:force_enable_legacy_profiler) { settings.profiling.advanced.force_enable_legacy_profiler } + + context 'when DD_PROFILING_FORCE_ENABLE_LEGACY' do + around do |example| + ClimateControl.modify('DD_PROFILING_FORCE_ENABLE_LEGACY' => environment) do + example.run + end + end + + context 'is not defined' do + let(:environment) { nil } + + it { is_expected.to be false } + end + + { 'true' => true, 'false' => false }.each do |string, value| + context "is defined as #{string}" do + let(:environment) { string } + + it { is_expected.to be value } + end + end + end + end + + describe '#force_enable_legacy_profiler=' do + it 'updates the #force_enable_legacy_profiler setting' do + expect { settings.profiling.advanced.force_enable_legacy_profiler = true } + .to change { settings.profiling.advanced.force_enable_legacy_profiler } + .from(false) + .to(true) + end + end + describe '#force_enable_gc_profiling' do subject(:force_enable_gc_profiling) { settings.profiling.advanced.force_enable_gc_profiling } diff --git a/spec/datadog/profiling/component_spec.rb b/spec/datadog/profiling/component_spec.rb index 9ae41ba77fe..2fd52d47123 100644 --- a/spec/datadog/profiling/component_spec.rb +++ b/spec/datadog/profiling/component_spec.rb @@ -49,44 +49,62 @@ allow(profiler_setup_task).to receive(:run) end - it 'sets up the Profiler with the OldStack collector' do - expect(Datadog::Profiling::Profiler).to receive(:new).with( - [instance_of(Datadog::Profiling::Collectors::OldStack)], - anything, - ) + context 'when using the legacy profiler' do + before { expect(described_class).to receive(:enable_new_profiler?).with(settings).and_return(false) } - build_profiler_component - end + it 'sets up the Profiler with the OldStack collector' do + expect(Datadog::Profiling::Profiler).to receive(:new).with( + [instance_of(Datadog::Profiling::Collectors::OldStack)], + anything, + ) - it 'initializes the OldStack collector with the max_frames setting' do - expect(Datadog::Profiling::Collectors::OldStack).to receive(:new).with( - instance_of(Datadog::Profiling::OldRecorder), - hash_including(max_frames: settings.profiling.advanced.max_frames), - ) + build_profiler_component + end - build_profiler_component - end + it 'initializes the OldStack collector with the max_frames setting' do + expect(Datadog::Profiling::Collectors::OldStack).to receive(:new).with( + instance_of(Datadog::Profiling::OldRecorder), + hash_including(max_frames: settings.profiling.advanced.max_frames), + ) - it 'initializes the OldRecorder with the correct event classes and max_events setting' do - expect(Datadog::Profiling::OldRecorder) - .to receive(:new) - .with([Datadog::Profiling::Events::StackSample], settings.profiling.advanced.max_events) - .and_call_original + build_profiler_component + end - build_profiler_component - end + it 'initializes the OldRecorder with the correct event classes and max_events setting' do + expect(Datadog::Profiling::OldRecorder) + .to receive(:new) + .with([Datadog::Profiling::Events::StackSample], settings.profiling.advanced.max_events) + .and_call_original - it 'sets up the Exporter with the OldRecorder' do - expect(Datadog::Profiling::Exporter) - .to receive(:new).with(hash_including(pprof_recorder: instance_of(Datadog::Profiling::OldRecorder))) + build_profiler_component + end - build_profiler_component + it 'sets up the Exporter with the OldRecorder' do + expect(Datadog::Profiling::Exporter) + .to receive(:new).with(hash_including(pprof_recorder: instance_of(Datadog::Profiling::OldRecorder))) + + build_profiler_component + end + + [true, false].each do |value| + context "when endpoint_collection_enabled is #{value}" do + before { settings.profiling.advanced.endpoint.collection.enabled = value } + + it "initializes the TraceIdentifiers::Helper with endpoint_collection_enabled: #{value}" do + expect(Datadog::Profiling::TraceIdentifiers::Helper) + .to receive(:new).with(tracer: tracer, endpoint_collection_enabled: value) + + build_profiler_component + end + end + end end - context 'when force_enable_new_profiler is enabled' do + context 'when using the new CPU Profiling 2.0 profiler' do before do - settings.profiling.advanced.force_enable_new_profiler = true - allow(Datadog.logger).to receive(:warn) + expect(described_class).to receive(:enable_new_profiler?).with(settings).and_return(true) + # Silence warning spam about using the new profiler on legacy Rubies + allow(Datadog.logger).to receive(:warn) if RUBY_VERSION < '2.6.' end it 'does not initialize the OldStack collector' do @@ -114,24 +132,12 @@ build_profiler_component end - context 'on Ruby 2.6 and above' do - before { skip 'Behavior does not apply to current Ruby version' if RUBY_VERSION < '2.6.' } - - it 'logs a warning message mentioning that profiler has been force-enabled' do - expect(Datadog.logger).to receive(:warn).with( - /New Ruby profiler has been force-enabled. This is a beta feature/ - ) - - build_profiler_component - end - end - context 'on Ruby 2.5 and below' do before { skip 'Behavior does not apply to current Ruby version' if RUBY_VERSION >= '2.6.' } it 'logs a warning message mentioning that profiler has been force-enabled AND that it may cause issues' do expect(Datadog.logger).to receive(:warn).with( - /New Ruby profiler has been force-enabled on a legacy Ruby version \(< 2.6\). This is not recommended/ + /The new CPU Profiling 2.0 profiler has been force-enabled on a legacy Ruby version/ ) build_profiler_component @@ -293,19 +299,6 @@ build_profiler_component end - [true, false].each do |value| - context "when endpoint_collection_enabled is #{value}" do - before { settings.profiling.advanced.endpoint.collection.enabled = value } - - it "initializes the TraceIdentifiers::Helper with endpoint_collection_enabled: #{value}" do - expect(Datadog::Profiling::TraceIdentifiers::Helper) - .to receive(:new).with(tracer: tracer, endpoint_collection_enabled: value) - - build_profiler_component - end - end - end - it 'initializes the exporter with a code provenance collector' do expect(Datadog::Profiling::Exporter).to receive(:new) do |code_provenance_collector:, **_| expect(code_provenance_collector).to be_a_kind_of(Datadog::Profiling::Collectors::CodeProvenance) @@ -349,4 +342,72 @@ end end end + + describe '.enable_new_profiler?' do + subject(:enable_new_profiler?) { described_class.send(:enable_new_profiler?, settings) } + + before { skip_if_profiling_not_supported(self) } + + context 'when force_enable_legacy_profiler is enabled' do + before do + settings.profiling.advanced.force_enable_legacy_profiler = true + + allow(Datadog.logger).to receive(:warn) + end + + it { is_expected.to be false } + + it 'logs a warning message mentioning that the legacy profiler was enabled' do + expect(Datadog.logger).to receive(:warn).with(/Legacy profiler has been force-enabled/) + + enable_new_profiler? + end + end + + context 'when force_enable_legacy_profiler is not enabled' do + before { settings.profiling.advanced.force_enable_legacy_profiler = false } + + context 'on Ruby 2.5 and below' do + before { skip 'Behavior does not apply to current Ruby version' if RUBY_VERSION >= '2.6.' } + + it { is_expected.to be false } + + context 'when force_enable_new_profiler is enabled' do + before { settings.profiling.advanced.force_enable_new_profiler = true } + + it { is_expected.to be true } + end + end + + context 'on Ruby 2.6 and above' do + before { skip 'Behavior does not apply to current Ruby version' if RUBY_VERSION < '2.6.' } + + context 'when mysql2 gem is available' do + include_context 'loaded gems', :mysql2 => Gem::Version.new('0.5.5') + + before { allow(Datadog.logger).to receive(:warn) } + + it { is_expected.to be false } + + it 'logs a warning message mentioning that the legacy profiler is going to be used' do + expect(Datadog.logger).to receive(:warn).with(/Falling back to legacy profiler/) + + enable_new_profiler? + end + + context 'when force_enable_new_profiler is enabled' do + before { settings.profiling.advanced.force_enable_new_profiler = true } + + it { is_expected.to be true } + end + end + + context 'when mysql2 gem is not available' do + include_context 'loaded gems', :mysql2 => nil + + it { is_expected.to be true } + end + end + end + end end diff --git a/spec/datadog/profiling/tasks/setup_spec.rb b/spec/datadog/profiling/tasks/setup_spec.rb index a82f9e4f28c..4b33adc2771 100644 --- a/spec/datadog/profiling/tasks/setup_spec.rb +++ b/spec/datadog/profiling/tasks/setup_spec.rb @@ -13,8 +13,6 @@ before do described_class::ACTIVATE_EXTENSIONS_ONLY_ONCE.send(:reset_ran_once_state_for_tests) - - allow(task).to receive(:check_if_cpu_time_profiling_is_supported) end it 'actives the forking extension before setting up the at_fork hooks' do @@ -24,12 +22,6 @@ run end - it 'checks if CPU time profiling is available' do - expect(task).to receive(:check_if_cpu_time_profiling_is_supported) - - run - end - it 'only sets up the extensions and hooks once, even across different instances' do expect_any_instance_of(described_class).to receive(:activate_forking_extensions).once expect_any_instance_of(described_class).to receive(:setup_at_fork_hooks).once @@ -116,36 +108,6 @@ end end - describe '#check_if_cpu_time_profiling_is_supported' do - subject(:check_if_cpu_time_profiling_is_supported) { task.send(:check_if_cpu_time_profiling_is_supported) } - - before do - expect(task).to receive(:cpu_time_profiling_unsupported_reason).and_return(unsupported_reason) - end - - context 'when CPU time profiling is supported' do - let(:unsupported_reason) { nil } - - it 'does not log a message' do - expect(Datadog.logger).to_not receive(:info) - - check_if_cpu_time_profiling_is_supported - end - end - - context 'when CPU time profiling is not supported' do - let(:unsupported_reason) { 'Simulated failure' } - - it 'logs info message' do - expect(Datadog.logger).to receive(:info) do |&message| - expect(message.call).to include('CPU time profiling skipped') - end - - check_if_cpu_time_profiling_is_supported - end - end - end - describe '#setup_at_fork_hooks' do subject(:setup_at_fork_hooks) { task.send(:setup_at_fork_hooks) } @@ -213,42 +175,4 @@ end end end - - describe '#cpu_time_profiling_unsupported_reason' do - subject(:cpu_time_profiling_unsupported_reason) { task.send(:cpu_time_profiling_unsupported_reason) } - - context 'when JRuby is used' do - before { stub_const('RUBY_ENGINE', 'jruby') } - - it { is_expected.to include 'JRuby' } - end - - context 'when using MRI Ruby' do - before { stub_const('RUBY_ENGINE', 'ruby') } - - context 'when running on macOS' do - before { stub_const('RUBY_PLATFORM', 'x86_64-darwin19') } - - it { is_expected.to include 'macOS' } - end - - context 'when running on Windows' do - before { stub_const('RUBY_PLATFORM', 'mswin') } - - it { is_expected.to include 'Windows' } - end - - context 'when running on a non-Linux platform' do - before { stub_const('RUBY_PLATFORM', 'my-homegrown-os') } - - it { is_expected.to include 'my-homegrown-os' } - end - - context 'when running on Linux' do - before { stub_const('RUBY_PLATFORM', 'x86_64-linux-gnu') } - - it { is_expected.to be nil } - end - end - end end