Skip to content

Commit c9c658e

Browse files
committed
Add more e2e coverage for DSC
1 parent 6957541 commit c9c658e

File tree

3 files changed

+126
-40
lines changed

3 files changed

+126
-40
lines changed

spec/apps/rails-mini/app.rb

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ class RailsMiniApp < Rails::Application
1717
config.api_only = true
1818
config.force_ssl = false
1919

20+
def debug_log_path
21+
@log_path ||= begin
22+
path = Pathname(__dir__).join("../../../log")
23+
FileUtils.mkdir_p(path) unless path.exist?
24+
path.realpath
25+
end
26+
end
27+
2028
initializer :configure_sentry do
2129
Sentry.init do |config|
2230
config.dsn = ENV["SENTRY_DSN"]
@@ -28,9 +36,8 @@ class RailsMiniApp < Rails::Application
2836
config.debug = true
2937
config.include_local_variables = true
3038
config.release = "sentry-ruby-rails-mini-#{Time.now.utc}"
31-
3239
config.transport.transport_class = Sentry::DebugTransport
33-
config.sdk_debug_transport_log_file = "/workspace/sentry/log/sentry_debug_events.log"
40+
config.sdk_debug_transport_log_file = debug_log_path.join("sentry_debug_events.log")
3441
config.background_worker_threads = 0
3542
end
3643
end
@@ -57,11 +64,22 @@ class EventsController < ActionController::Base
5764
before_action :set_cors_headers
5865

5966
def health
67+
sentry_initialized = Sentry.initialized?
68+
sentry_dsn = ENV["SENTRY_DSN"]
69+
6070
render json: {
6171
status: "ok",
6272
timestamp: Time.now.utc.iso8601,
63-
sentry_initialized: Sentry.initialized?,
64-
log_file_writable: check_log_file_writable
73+
sentry_initialized: sentry_initialized,
74+
sentry_dsn_configured: !sentry_dsn.nil? && !sentry_dsn.empty?,
75+
sentry_dsn: sentry_dsn,
76+
sentry_environment: sentry_initialized ? Sentry.configuration.environment : nil,
77+
debug_info: {
78+
sentry_loaded: defined?(Sentry),
79+
configuration_present: Sentry.respond_to?(:configuration),
80+
dsn_configured: Sentry.respond_to?(:configuration) && Sentry.configuration&.dsn.present?,
81+
env_dsn_value: sentry_dsn
82+
}
6583
}
6684
end
6785

@@ -72,14 +90,6 @@ def trace_headers
7290

7391
private
7492

75-
def check_log_file_writable
76-
log_file_path = "/workspace/sentry/log/sentry_debug_events.log"
77-
File.writable?(File.dirname(log_file_path)) &&
78-
(!File.exist?(log_file_path) || File.writable?(log_file_path))
79-
rescue
80-
false
81-
end
82-
8393
def set_cors_headers
8494
response.headers['Access-Control-Allow-Origin'] = '*'
8595
response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'
@@ -94,7 +104,6 @@ def set_cors_headers
94104
get '/error', to: 'error#error'
95105
get '/trace_headers', to: 'events#trace_headers'
96106

97-
# Add CORS headers for cross-origin requests from JS app
98107
match '*path', to: proc { |env|
99108
[200, {
100109
'Access-Control-Allow-Origin' => '*',

spec/features/tracing_spec.rb

Lines changed: 103 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,51 @@
11
# frozen_string_literal: true
22

3-
RSpec.describe "Tracing", type: :feature do
4-
it "works" do
3+
RSpec.describe "Tracing", type: :e2e do
4+
def expect_valid_sample_rand(sample_rand)
5+
expect(sample_rand).not_to be_nil
6+
expect(sample_rand).to match(/^\d+\.\d{1,6}$/)
7+
sample_rand_value = sample_rand.to_f
8+
expect(sample_rand_value).to be >= 0.0
9+
expect(sample_rand_value).to be < 1.0
10+
end
11+
12+
def expect_dsc_in_envelope_headers
13+
envelopes_with_dsc = logged_events[:envelopes].select do |envelope|
14+
envelope["headers"] && envelope["headers"]["trace"]
15+
end
16+
17+
expect(envelopes_with_dsc).not_to be_empty
18+
19+
dsc_metadata = envelopes_with_dsc.map { |envelope| envelope["headers"]["trace"] }
20+
21+
envelopes_with_sample_rand = dsc_metadata.select { |dsc| dsc["sample_rand"] }
22+
expect(envelopes_with_sample_rand).not_to be_empty
23+
24+
envelopes_with_sample_rand.each do |dsc|
25+
expect_valid_sample_rand(dsc["sample_rand"])
26+
end
27+
28+
dsc_metadata
29+
end
30+
31+
def get_http_server_transactions_with_headers
32+
transaction_events = logged_events[:events].select { |event| event["type"] == "transaction" }
33+
expect(transaction_events).not_to be_empty
34+
35+
http_server_transactions = transaction_events.select { |event|
36+
event.dig("contexts", "trace", "op") == "http.server"
37+
}
38+
expect(http_server_transactions).not_to be_empty
39+
40+
transactions_with_headers = http_server_transactions.select { |transaction|
41+
headers = transaction.dig("request", "headers")
42+
headers && (headers["Sentry-Trace"] || headers["sentry-trace"])
43+
}
44+
expect(transactions_with_headers).not_to be_empty
45+
46+
transactions_with_headers
47+
end
48+
it "validates basic tracing functionality" do
549
visit "/error"
650

751
expect(page).to have_content("Svelte Mini App")
@@ -16,46 +60,79 @@
1660
error_events = logged_events[:events].select { |event| event["exception"] }
1761
expect(error_events).not_to be_empty
1862

19-
error_event = error_events.first
63+
error_event = error_events.last
2064
exception_values = error_event.dig("exception", "values")
2165
expect(exception_values).not_to be_empty
2266
expect(exception_values.first["type"]).to eq("ZeroDivisionError")
2367

24-
transaction_events = logged_events[:events].select { |event| event["type"] == "transaction" }
25-
2668
expect(error_event.dig("contexts", "trace")).not_to be_nil
2769
error_trace_id = error_event.dig("contexts", "trace", "trace_id")
28-
expect(error_trace_id).to_not be(nil)
70+
expect(error_trace_id).not_to be_nil
71+
72+
transaction_events = logged_events[:events].select { |event| event["type"] == "transaction" }
73+
expect(transaction_events).not_to be_empty
74+
75+
transactions_with_dsc = transaction_events.select { |event|
76+
event.dig("_meta", "dsc", "sample_rand")
77+
}
78+
79+
transactions_with_dsc.each do |transaction|
80+
expect_valid_sample_rand(transaction.dig("_meta", "dsc", "sample_rand"))
81+
end
82+
end
83+
84+
describe "propagated sample_rand behavior" do
85+
it "validates DSC metadata is properly generated and included in envelope headers" do
86+
visit "/error"
87+
88+
expect(page).to have_content("Svelte Mini App")
89+
expect(page).to have_button("Trigger Error")
2990

30-
if transaction_events.any?
31-
transaction_event = transaction_events.first
32-
trace_context = transaction_event.dig("contexts", "trace")
91+
click_button "trigger-error-btn"
3392

34-
expect(trace_context).not_to be_nil
93+
expect(page).to have_content("Error:")
3594

36-
transaction_trace_id = trace_context["trace_id"]
95+
dsc_envelopes = expect_dsc_in_envelope_headers
3796

38-
expect(transaction_trace_id).to_not be(nil)
39-
expect(error_trace_id).to eq(transaction_trace_id)
97+
dsc_envelopes.each do |dsc|
98+
expect(dsc["trace_id"]).not_to be_nil
99+
expect(dsc["trace_id"]).to match(/^[a-f0-9]{32}$/)
40100

41-
if transaction_event["_meta"] && transaction_event["_meta"]["dsc"]
42-
dsc = transaction_event["_meta"]["dsc"]
43-
expect(dsc).to include("sample_rand")
101+
expect(dsc["sample_rate"]).not_to be_nil
102+
expect(dsc["sample_rate"].to_f).to be > 0.0
44103

45-
sample_rand = dsc["sample_rand"]
46-
expect(sample_rand).to_not be(nil)
104+
expect(dsc["sample_rand"]).not_to be_nil
105+
expect_valid_sample_rand(dsc["sample_rand"])
106+
107+
expect(dsc["sampled"]).to eq("true")
108+
expect(dsc["environment"]).to eq("development")
109+
expect(dsc["public_key"]).to eq("user")
47110
end
48111
end
49112

50-
logged_events[:envelopes].each do |envelope|
51-
envelope["items"].each do |item|
52-
if item["payload"] && item["payload"]["_meta"] && item["payload"]["_meta"]["dsc"]
53-
dsc = item["payload"]["_meta"]["dsc"]
113+
it "validates DSC sample_rand generation across multiple requests" do
114+
visit "/error"
115+
116+
expect(page).to have_content("Svelte Mini App")
117+
118+
3.times do |i|
119+
click_button "trigger-error-btn"
120+
sleep 0.1
121+
end
122+
123+
expect(page).to have_content("Error:")
124+
125+
dsc_envelopes = expect_dsc_in_envelope_headers
126+
expect(dsc_envelopes.length).to be >= 2
127+
128+
trace_ids = dsc_envelopes.map { |dsc| dsc["trace_id"] }.uniq
129+
sample_rands = dsc_envelopes.map { |dsc| dsc["sample_rand"] }.uniq
130+
131+
expect(trace_ids.length).to be >= 2
132+
expect(sample_rands.length).to be >= 2
54133

55-
if dsc["sample_rand"]
56-
expect(dsc["sample_rand"]).to_not be(nil)
57-
end
58-
end
134+
sample_rands.each do |sample_rand|
135+
expect_valid_sample_rand(sample_rand)
59136
end
60137
end
61138
end

spec/support/test_helper.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def logged_events
1616
}
1717

1818
event_data["items"].each do |item|
19-
if item["headers"]["type"] == "event"
19+
if ["event", "transaction"].include?(item["headers"]["type"])
2020
extracted_events << item["payload"]
2121
end
2222
end

0 commit comments

Comments
 (0)