Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions sentry-rails/spec/isolated/rails_exit_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# frozen_string_literal: true

RSpec.describe Sentry::Rails, type: :request do
context "at exit" do
before do
make_basic_app
Rails.application.load_runner
end

it "captures exception if exit code is non-zero" do
skip('fork not supported in jruby') if RUBY_PLATFORM == 'java'
captured_message = capture_in_separate_process(exit_code: 1) do |pipe_out|
allow(Sentry::Rails).to receive(:capture_exception) do |event|
pipe_out.puts event
end

# silence process
$stderr.reopen('/dev/null', 'w')
$stdout.reopen('/dev/null', 'w')
end
captured_message = captured_message.split("\n").last

expect(captured_message).to eq('exit')
end

it "does not capture exception if exit code is zero" do
skip('fork not supported in jruby') if RUBY_PLATFORM == 'java'
captured_message = capture_in_separate_process(exit_code: 0) do |pipe_out|
allow(Sentry::Rails).to receive(:capture_exception) do |event|
pipe_out.puts event
end

# silence process
$stderr.reopen('/dev/null', 'w')
$stdout.reopen('/dev/null', 'w')
end
captured_message = captured_message.split("\n").last

expect(captured_message).to be_nil
end
end
end
39 changes: 0 additions & 39 deletions sentry-rails/spec/sentry/rails_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -140,45 +140,6 @@
end
end

context "at exit" do
before do
make_basic_app
Rails.application.load_runner
end

it "captures exception if exit code is non-zero" do
skip('fork not supported in jruby') if RUBY_PLATFORM == 'java'
captured_message = capture_in_separate_process(exit_code: 1) do |pipe_out|
allow(Sentry::Rails).to receive(:capture_exception) do |event|
pipe_out.puts event
end

# silence process
$stderr.reopen('/dev/null', 'w')
$stdout.reopen('/dev/null', 'w')
end
captured_message = captured_message.split("\n").last

expect(captured_message).to eq('exit')
end

it "does not capture exception if exit code is zero" do
skip('fork not supported in jruby') if RUBY_PLATFORM == 'java'
captured_message = capture_in_separate_process(exit_code: 0) do |pipe_out|
allow(Sentry::Rails).to receive(:capture_exception) do |event|
pipe_out.puts event
end

# silence process
$stderr.reopen('/dev/null', 'w')
$stdout.reopen('/dev/null', 'w')
end
captured_message = captured_message.split("\n").last

expect(captured_message).to be_nil
end
end

RSpec.shared_examples "report_rescued_exceptions" do
context "with report_rescued_exceptions = true" do
before do
Expand Down
97 changes: 97 additions & 0 deletions sentry-ruby/spec/isolated/forked_workers_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# frozen_string_literal: true

RSpec.describe Sentry::SessionFlusher, when: { ruby_engine?: "ruby" } do
subject { Sentry.session_flusher }

let(:session) do
session = Sentry::Session.new
session.close
session
end

before do
perform_basic_setup do |config|
config.release = "test-release"
config.environment = "test"
config.background_worker_threads = 0
end
end

after do
subject.kill
subject.thread&.join
end

it "discards aggregates inherited from the parent after a fork" do
subject.add_session(session)

result = capture_in_separate_process do |writer|
subject.add_session(session)
aggregate = subject.instance_variable_get(:@pending_aggregates).values.first
writer.puts aggregate[:exited]
end

expect(result.to_i).to eq(1)
expect(subject.instance_variable_get(:@pending_aggregates).values.first[:exited]).to eq(1)
end
end

RSpec.shared_examples "forked telemetry buffer" do |event_factory:, max_items_config:|
let(:event) { event_factory.call }

before do
perform_basic_setup do |config|
config.background_worker_threads = 0
config.public_send(:"#{max_items_config}=", 3)
end
end

after do
subject.kill
subject.thread&.join
Sentry.background_worker = Class.new { def shutdown; end }.new
end

it "resets inherited worker state before adding telemetry" do
subject.add_item(event)
subject.wait_until_idle
expect(subject.size).to eq(1)

result = capture_in_separate_process do |writer|
subject.add_item(event)
subject.flush
item_count = sentry_envelopes.first.items.first.headers[:item_count]
writer.puts [subject.size, sentry_envelopes.size, item_count].join(",")
end

child_size, child_envelopes, child_item_count = result.split(",").map(&:to_i)
expect(child_size).to eq(0)
expect(child_envelopes).to eq(1)
expect(child_item_count).to eq(1)
expect(subject.size).to eq(1)
expect(sentry_envelopes).to be_empty

subject.flush
expect(sentry_envelopes.size).to eq(1)

subject.add_item(event)
subject.flush
expect(sentry_envelopes.size).to eq(2)
end
end

RSpec.describe Sentry::LogEventBuffer, when: { ruby_engine?: "ruby" } do
subject { described_class.new(Sentry.configuration, Sentry.get_current_client) }

include_examples "forked telemetry buffer",
event_factory: -> { Sentry::LogEvent.new(level: :info, body: "Test message") },
max_items_config: :max_log_events
end

RSpec.describe Sentry::MetricEventBuffer, when: { ruby_engine?: "ruby" } do
subject { described_class.new(Sentry.configuration, Sentry.get_current_client) }

include_examples "forked telemetry buffer",
event_factory: -> { Sentry::MetricEvent.new(name: "test.metric", type: :counter, value: 1) },
max_items_config: :max_metric_events
end
2 changes: 2 additions & 0 deletions sentry-ruby/spec/sentry/sequel_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@

after do
db.drop_table?(:posts)
ensure
db.disconnect
end

context "with tracing enabled" do
Expand Down
15 changes: 0 additions & 15 deletions sentry-ruby/spec/sentry/session_flusher_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,21 +128,6 @@
expect(pending_aggregates.values.first).to include({ errored: 0, exited: 1 })
end

context "when a child adds a session after a fork", when: { ruby_engine?: "ruby" } do
it "discards aggregates inherited from the parent" do
subject.add_session(session)

result = capture_in_separate_process do |writer|
subject.add_session(session)
aggregate = subject.instance_variable_get(:@pending_aggregates).values.first
writer.puts aggregate[:exited]
end

expect(result.to_i).to eq(1)
expect(subject.instance_variable_get(:@pending_aggregates).values.first[:exited]).to eq(1)
end
end

context "when thread creation fails" do
before do
allow(Thread).to receive(:new).and_raise(ThreadError)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,37 +324,6 @@
end
end

context "when a child adds telemetry after a fork", when: { ruby_engine?: "ruby" } do
let(:max_items) { 3 }

it "resets inherited worker state before adding telemetry" do
subject.add_item(event)
subject.wait_until_idle
expect(subject.size).to eq(1)

result = capture_in_separate_process do |writer|
subject.add_item(event)
subject.flush
item_count = sentry_envelopes.first.items.first.headers[:item_count]
writer.puts [subject.size, sentry_envelopes.size, item_count].join(",")
end

child_size, child_envelopes, child_item_count = result.split(",").map(&:to_i)
expect(child_size).to eq(0)
expect(child_envelopes).to eq(1)
expect(child_item_count).to eq(1)
expect(subject.size).to eq(1)
expect(sentry_envelopes).to be_empty

subject.flush
expect(sentry_envelopes.size).to eq(1)

subject.add_item(event)
subject.flush
expect(sentry_envelopes.size).to eq(2)
end
end

describe "error handling" do
let(:max_items) { 3 }

Expand Down
2 changes: 1 addition & 1 deletion spec/support/fork_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def read_from_child(reader)
loop do
remaining = deadline - Process.clock_gettime(Process::CLOCK_MONOTONIC)
raise "child did not respond" if remaining <= 0
raise "child did not respond" unless IO.select([reader], nil, nil, remaining)
raise "child did not respond: IO.select timed out" unless IO.select([reader], nil, nil, remaining)

begin
output << reader.read_nonblock(4096)
Expand Down
Loading