appsignal 3.11.0-java → 3.12.1-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +115 -0
  3. data/Rakefile +1 -1
  4. data/lib/appsignal/cli/diagnose.rb +1 -1
  5. data/lib/appsignal/config.rb +150 -32
  6. data/lib/appsignal/demo.rb +1 -6
  7. data/lib/appsignal/helpers/instrumentation.rb +2 -2
  8. data/lib/appsignal/integrations/grape.rb +7 -0
  9. data/lib/appsignal/integrations/hanami.rb +8 -43
  10. data/lib/appsignal/integrations/padrino.rb +8 -73
  11. data/lib/appsignal/integrations/railtie.rb +35 -13
  12. data/lib/appsignal/integrations/sinatra.rb +8 -19
  13. data/lib/appsignal/loaders/grape.rb +13 -0
  14. data/lib/appsignal/loaders/hanami.rb +40 -0
  15. data/lib/appsignal/loaders/padrino.rb +68 -0
  16. data/lib/appsignal/loaders/sinatra.rb +24 -0
  17. data/lib/appsignal/loaders.rb +92 -0
  18. data/lib/appsignal/rack/abstract_middleware.rb +2 -1
  19. data/lib/appsignal/rack/event_handler.rb +5 -5
  20. data/lib/appsignal/rack.rb +6 -0
  21. data/lib/appsignal/version.rb +1 -1
  22. data/lib/appsignal.rb +163 -9
  23. data/spec/lib/appsignal/cli/demo_spec.rb +0 -1
  24. data/spec/lib/appsignal/cli/diagnose/paths_spec.rb +1 -1
  25. data/spec/lib/appsignal/cli/diagnose_spec.rb +0 -1
  26. data/spec/lib/appsignal/config_spec.rb +153 -1
  27. data/spec/lib/appsignal/demo_spec.rb +1 -2
  28. data/spec/lib/appsignal/environment_spec.rb +4 -2
  29. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +3 -6
  30. data/spec/lib/appsignal/hooks/activejob_spec.rb +3 -3
  31. data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +4 -7
  32. data/spec/lib/appsignal/hooks/excon_spec.rb +3 -6
  33. data/spec/lib/appsignal/hooks/gvl_spec.rb +2 -2
  34. data/spec/lib/appsignal/hooks/http_spec.rb +1 -3
  35. data/spec/lib/appsignal/hooks/net_http_spec.rb +1 -1
  36. data/spec/lib/appsignal/hooks/redis_client_spec.rb +5 -8
  37. data/spec/lib/appsignal/hooks/redis_spec.rb +3 -6
  38. data/spec/lib/appsignal/hooks/resque_spec.rb +1 -1
  39. data/spec/lib/appsignal/hooks/sequel_spec.rb +3 -5
  40. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +1 -1
  41. data/spec/lib/appsignal/hooks/webmachine_spec.rb +1 -1
  42. data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +2 -2
  43. data/spec/lib/appsignal/integrations/grape_spec.rb +36 -0
  44. data/spec/lib/appsignal/integrations/hanami_spec.rb +9 -178
  45. data/spec/lib/appsignal/integrations/http_spec.rb +1 -5
  46. data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +4 -2
  47. data/spec/lib/appsignal/integrations/net_http_spec.rb +1 -1
  48. data/spec/lib/appsignal/integrations/object_spec.rb +1 -3
  49. data/spec/lib/appsignal/integrations/padrino_spec.rb +8 -330
  50. data/spec/lib/appsignal/integrations/railtie_spec.rb +275 -191
  51. data/spec/lib/appsignal/integrations/shoryuken_spec.rb +1 -1
  52. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +11 -9
  53. data/spec/lib/appsignal/integrations/sinatra_spec.rb +9 -104
  54. data/spec/lib/appsignal/loaders/grape_spec.rb +12 -0
  55. data/spec/lib/appsignal/loaders/hanami_spec.rb +95 -0
  56. data/spec/lib/appsignal/loaders/padrino_spec.rb +277 -0
  57. data/spec/lib/appsignal/loaders/sinatra_spec.rb +47 -0
  58. data/spec/lib/appsignal/loaders_spec.rb +137 -0
  59. data/spec/lib/appsignal/probes/sidekiq_spec.rb +1 -1
  60. data/spec/lib/appsignal/probes_spec.rb +6 -5
  61. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +3 -2
  62. data/spec/lib/appsignal/rack/event_handler_spec.rb +33 -0
  63. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +1 -1
  64. data/spec/lib/appsignal/rack/grape_middleware_spec.rb +2 -35
  65. data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +1 -1
  66. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +3 -3
  67. data/spec/lib/appsignal/span_spec.rb +1 -3
  68. data/spec/lib/appsignal/transaction_spec.rb +61 -70
  69. data/spec/lib/appsignal_spec.rb +284 -26
  70. data/spec/lib/puma/appsignal_spec.rb +0 -3
  71. data/spec/spec_helper.rb +5 -4
  72. data/spec/support/helpers/config_helpers.rb +2 -1
  73. data/spec/support/helpers/loader_helper.rb +21 -0
  74. data/spec/support/matchers/transaction.rb +3 -2
  75. data/spec/support/stubs/appsignal/loaders/loader_stub.rb +7 -0
  76. data/spec/support/testing.rb +46 -0
  77. metadata +15 -2
@@ -2,22 +2,226 @@ describe Appsignal do
2
2
  include EnvironmentMetadataHelper
3
3
  around { |example| keep_transactions { example.run } }
4
4
 
5
- before do
6
- # Make sure we have a clean state because we want to test
7
- # initialization here.
8
- Appsignal.config = nil
9
- end
10
-
11
5
  let(:transaction) { http_request_transaction }
12
6
 
13
7
  describe ".config=" do
14
- it "should set the config" do
8
+ it "sets the config" do
15
9
  config = project_fixture_config
16
10
  expect(Appsignal.internal_logger).to_not receive(:level=)
17
11
 
18
- Appsignal.config = config
12
+ silence { Appsignal.config = config }
19
13
  expect(Appsignal.config).to eq config
20
14
  end
15
+
16
+ it "prints a deprecation warning" do
17
+ err_stream = std_stream
18
+ capture_std_streams(std_stream, err_stream) do
19
+ Appsignal.config = project_fixture_config
20
+ end
21
+ expect(err_stream.read).to include(
22
+ "appsignal WARNING: Configuring AppSignal with `Appsignal.config=` is deprecated."
23
+ )
24
+ end
25
+
26
+ it "logs a deprecation warning" do
27
+ logs = capture_logs { silence { Appsignal.config = project_fixture_config } }
28
+ expect(logs).to contains_log(
29
+ :warn,
30
+ "Configuring AppSignal with `Appsignal.config=` is deprecated."
31
+ )
32
+ end
33
+ end
34
+
35
+ describe ".configure" do
36
+ context "when active" do
37
+ it "doesn't update the config" do
38
+ start_agent
39
+ Appsignal::Testing.store[:config_called] = false
40
+ expect do
41
+ Appsignal.configure do |_config|
42
+ Appsignal::Testing.store[:config_called] = true
43
+ end
44
+ end.to_not(change { [Appsignal.config, Appsignal.active?] })
45
+ expect(Appsignal::Testing.store[:config_called]).to be(false)
46
+ end
47
+
48
+ it "logs a warning" do
49
+ start_agent
50
+ logs =
51
+ capture_logs do
52
+ Appsignal.configure do |_config|
53
+ # Do something
54
+ end
55
+ end
56
+ expect(logs).to contains_log(
57
+ :warn,
58
+ "AppSignal is already started. Ignoring `Appsignal.configure` call."
59
+ )
60
+ end
61
+ end
62
+
63
+ context "with config but not started" do
64
+ it "reuses the already loaded config if the env is the same" do
65
+ Appsignal._config = Appsignal::Config.new(
66
+ project_fixture_path,
67
+ :my_env,
68
+ :ignore_actions => ["My action"]
69
+ )
70
+
71
+ Appsignal.configure(:my_env) do |config|
72
+ expect(config.ignore_actions).to eq(["My action"])
73
+ config.active = true
74
+ config.name = "My app"
75
+ config.push_api_key = "key"
76
+ end
77
+ expect(Appsignal.config.valid?).to be(true)
78
+ expect(Appsignal.config.env).to eq("my_env")
79
+ expect(Appsignal.config[:active]).to be(true)
80
+ expect(Appsignal.config[:name]).to eq("My app")
81
+ expect(Appsignal.config[:push_api_key]).to eq("key")
82
+ end
83
+
84
+ it "loads a new config if the env is not the same" do
85
+ Appsignal._config = Appsignal::Config.new(
86
+ project_fixture_path,
87
+ :my_env,
88
+ :name => "Some name",
89
+ :push_api_key => "Some key",
90
+ :ignore_actions => ["My action"]
91
+ )
92
+
93
+ Appsignal.configure(:my_env2) do |config|
94
+ expect(config.ignore_actions).to be_empty
95
+ config.active = true
96
+ config.name = "My app"
97
+ config.push_api_key = "key"
98
+ end
99
+ expect(Appsignal.config.valid?).to be(true)
100
+ expect(Appsignal.config.env).to eq("my_env2")
101
+ expect(Appsignal.config[:active]).to be(true)
102
+ expect(Appsignal.config[:name]).to eq("My app")
103
+ expect(Appsignal.config[:push_api_key]).to eq("key")
104
+ end
105
+
106
+ it "calls configure if not started yet" do
107
+ Appsignal.configure(:my_env) do |config|
108
+ config.active = false
109
+ config.name = "Some name"
110
+ end
111
+ Appsignal.start
112
+ expect(Appsignal.started?).to be_falsy
113
+
114
+ Appsignal.configure(:my_env) do |config|
115
+ expect(config.ignore_actions).to be_empty
116
+ config.active = true
117
+ config.name = "My app"
118
+ config.push_api_key = "key"
119
+ end
120
+ expect(Appsignal.config.valid?).to be(true)
121
+ expect(Appsignal.config.env).to eq("my_env")
122
+ expect(Appsignal.config[:active]).to be(true)
123
+ expect(Appsignal.config[:name]).to eq("My app")
124
+ expect(Appsignal.config[:push_api_key]).to eq("key")
125
+ end
126
+ end
127
+
128
+ context "when not active" do
129
+ it "starts with the configured config" do
130
+ Appsignal.configure(:test) do |config|
131
+ config.push_api_key = "key"
132
+ end
133
+
134
+ Appsignal.start
135
+ expect(Appsignal.config[:push_api_key]).to eq("key")
136
+ end
137
+
138
+ it "uses the given env" do
139
+ ENV["APPSIGNAL_APP_ENV"] = "env_env"
140
+ Appsignal.configure(:env_arg)
141
+
142
+ Appsignal.start
143
+ expect(Appsignal.config.env).to eq("env_arg")
144
+ end
145
+
146
+ it "loads the config without a block being given" do
147
+ Dir.chdir project_fixture_path do
148
+ Appsignal.configure(:test)
149
+ end
150
+
151
+ expect(Appsignal.config.env).to eq("test")
152
+ expect(Appsignal.config[:push_api_key]).to eq("abc")
153
+ end
154
+
155
+ it "allows customization of config in the block" do
156
+ Appsignal.configure(:test) do |config|
157
+ config.push_api_key = "key"
158
+ end
159
+
160
+ expect(Appsignal.config.valid?).to be(true)
161
+ expect(Appsignal.config.env).to eq("test")
162
+ expect(Appsignal.config[:push_api_key]).to eq("key")
163
+ end
164
+
165
+ it "loads the default config" do
166
+ Appsignal.configure do |config|
167
+ Appsignal::Config::DEFAULT_CONFIG.each do |option, value|
168
+ expect(config.send(option)).to eq(value)
169
+ end
170
+ end
171
+ end
172
+
173
+ it "loads the config from the YAML file" do
174
+ Dir.chdir project_fixture_path do
175
+ Appsignal.configure(:test) do |config|
176
+ expect(config.name).to eq("TestApp")
177
+ end
178
+ end
179
+ end
180
+
181
+ it "recognizes valid config" do
182
+ Appsignal.configure(:my_env) do |config|
183
+ config.push_api_key = "key"
184
+ end
185
+
186
+ expect(Appsignal.config.valid?).to be(true)
187
+ end
188
+
189
+ it "recognizes invalid config" do
190
+ Appsignal.configure(:my_env) do |config|
191
+ config.push_api_key = ""
192
+ end
193
+
194
+ expect(Appsignal.config.valid?).to be(false)
195
+ end
196
+
197
+ it "sets the environment when given as an argument" do
198
+ Appsignal.configure(:my_env)
199
+
200
+ expect(Appsignal.config.env).to eq("my_env")
201
+ end
202
+
203
+ it "reads the environment from the environment" do
204
+ ENV["APPSIGNAL_APP_ENV"] = "env_env"
205
+ Appsignal.configure do |config|
206
+ expect(config.env).to eq("env_env")
207
+ end
208
+
209
+ expect(Appsignal.config.env).to eq("env_env")
210
+ end
211
+
212
+ it "allows modification of previously unset config options" do
213
+ expect do
214
+ Appsignal.configure do |config|
215
+ config.ignore_actions << "My action"
216
+ config.request_headers << "My allowed header"
217
+ end
218
+ end.to_not(change { Appsignal::Config::DEFAULT_CONFIG })
219
+
220
+ expect(Appsignal.config[:ignore_actions]).to eq(["My action"])
221
+ expect(Appsignal.config[:request_headers])
222
+ .to eq(Appsignal::Config::DEFAULT_CONFIG[:request_headers] + ["My allowed header"])
223
+ end
224
+ end
21
225
  end
22
226
 
23
227
  describe ".start" do
@@ -50,7 +254,7 @@ describe Appsignal do
50
254
  end
51
255
 
52
256
  context "when config is loaded" do
53
- before { Appsignal.config = project_fixture_config }
257
+ before { Appsignal._config = project_fixture_config }
54
258
 
55
259
  it "should initialize logging" do
56
260
  Appsignal.start
@@ -113,6 +317,27 @@ describe Appsignal do
113
317
  end
114
318
  end
115
319
 
320
+ describe "loaders" do
321
+ it "starts loaded loaders" do
322
+ Appsignal::Testing.store[:loader_loaded] = 0
323
+ Appsignal::Testing.store[:loader_started] = 0
324
+ define_loader(:start_loader) do
325
+ def on_load
326
+ Appsignal::Testing.store[:loader_loaded] += 1
327
+ end
328
+
329
+ def on_start
330
+ Appsignal::Testing.store[:loader_started] += 1
331
+ end
332
+ end
333
+ Appsignal::Loaders.load(:start_loader)
334
+ Appsignal::Loaders.start
335
+
336
+ expect(Appsignal::Testing.store[:loader_loaded]).to eq(1)
337
+ expect(Appsignal::Testing.store[:loader_started]).to eq(1)
338
+ end
339
+ end
340
+
116
341
  describe "environment metadata" do
117
342
  before { capture_environment_metadata_report_calls }
118
343
 
@@ -128,7 +353,7 @@ describe Appsignal do
128
353
  end
129
354
 
130
355
  context "with debug logging" do
131
- before { Appsignal.config = project_fixture_config("test") }
356
+ before { Appsignal._config = project_fixture_config("test") }
132
357
 
133
358
  it "should change the log level" do
134
359
  Appsignal.start
@@ -137,6 +362,22 @@ describe Appsignal do
137
362
  end
138
363
  end
139
364
 
365
+ describe ".load" do
366
+ before do
367
+ TestLoader = define_loader(:appsignal_loader)
368
+ end
369
+ after do
370
+ Object.send(:remove_const, :TestLoader)
371
+ end
372
+
373
+ it "loads a loader" do
374
+ expect(Appsignal::Loaders.instances).to be_empty
375
+ Appsignal.load(:appsignal_loader)
376
+ expect(Appsignal::Loaders.instances)
377
+ .to include(:appsignal_loader => instance_of(TestLoader))
378
+ end
379
+ end
380
+
140
381
  describe ".forked" do
141
382
  context "when not active" do
142
383
  it "does nothing" do
@@ -148,7 +389,7 @@ describe Appsignal do
148
389
 
149
390
  context "when active" do
150
391
  before do
151
- Appsignal.config = project_fixture_config
392
+ Appsignal._config = project_fixture_config
152
393
  end
153
394
 
154
395
  it "starts the logger and extension" do
@@ -162,7 +403,7 @@ describe Appsignal do
162
403
 
163
404
  describe ".stop" do
164
405
  it "calls stop on the extension" do
165
- expect(Appsignal.internal_logger).to receive(:debug).with("Stopping appsignal")
406
+ expect(Appsignal.internal_logger).to receive(:debug).with("Stopping AppSignal")
166
407
  expect(Appsignal::Extension).to receive(:stop)
167
408
  Appsignal.stop
168
409
  expect(Appsignal.active?).to be_falsy
@@ -177,7 +418,7 @@ describe Appsignal do
177
418
 
178
419
  context "with context specified" do
179
420
  it "should log the context" do
180
- expect(Appsignal.internal_logger).to receive(:debug).with("Stopping appsignal (something)")
421
+ expect(Appsignal.internal_logger).to receive(:debug).with("Stopping AppSignal (something)")
181
422
  expect(Appsignal::Extension).to receive(:stop)
182
423
  Appsignal.stop("something")
183
424
  expect(Appsignal.active?).to be_falsy
@@ -185,20 +426,34 @@ describe Appsignal do
185
426
  end
186
427
  end
187
428
 
188
- describe ".active?" do
189
- subject { Appsignal.active? }
429
+ describe ".started?" do
430
+ subject { Appsignal.started? }
190
431
 
191
- context "without config" do
432
+ context "when started with active config" do
433
+ before { start_agent }
434
+
435
+ it { is_expected.to be_truthy }
436
+ end
437
+
438
+ context "when started with inactive config" do
192
439
  before do
193
- Appsignal.config = nil
440
+ Appsignal._config = project_fixture_config("nonsense")
194
441
  end
195
442
 
196
443
  it { is_expected.to be_falsy }
197
444
  end
445
+ end
446
+
447
+ describe ".active?" do
448
+ subject { Appsignal.active? }
449
+
450
+ context "without config" do
451
+ it { is_expected.to be_falsy }
452
+ end
198
453
 
199
454
  context "with inactive config" do
200
455
  before do
201
- Appsignal.config = project_fixture_config("nonsense")
456
+ Appsignal._config = project_fixture_config("nonsense")
202
457
  end
203
458
 
204
459
  it { is_expected.to be_falsy }
@@ -206,7 +461,7 @@ describe Appsignal do
206
461
 
207
462
  context "with active config" do
208
463
  before do
209
- Appsignal.config = project_fixture_config
464
+ Appsignal._config = project_fixture_config
210
465
  end
211
466
 
212
467
  it { is_expected.to be_truthy }
@@ -232,7 +487,7 @@ describe Appsignal do
232
487
  end
233
488
 
234
489
  context "not active" do
235
- before { Appsignal.config = project_fixture_config("not_active") }
490
+ before { Appsignal._config = project_fixture_config("not_active") }
236
491
 
237
492
  describe ".monitor_transaction" do
238
493
  it "does not create a transaction" do
@@ -490,6 +745,12 @@ describe Appsignal do
490
745
 
491
746
  expect(Appsignal).to have_received(:stop).with("monitor_and_stop")
492
747
  end
748
+
749
+ it "passes the block to Appsignal.monitor" do
750
+ expect do |blk|
751
+ Appsignal.monitor_and_stop(:action => "My action", &blk)
752
+ end.to yield_control
753
+ end
493
754
  end
494
755
 
495
756
  describe ".monitor_transaction" do
@@ -883,13 +1144,11 @@ describe Appsignal do
883
1144
  end
884
1145
 
885
1146
  describe ".add_breadcrumb" do
886
- around do |example|
887
- start_agent
888
- with_current_transaction(transaction) { example.run }
889
- end
1147
+ before { start_agent }
890
1148
 
891
1149
  context "with transaction" do
892
1150
  let(:transaction) { http_request_transaction }
1151
+ before { set_current_transaction(transaction) }
893
1152
 
894
1153
  it "adds the breadcrumb to the transaction" do
895
1154
  Appsignal.add_breadcrumb(
@@ -1648,7 +1907,7 @@ describe Appsignal do
1648
1907
  after { FileUtils.rm_rf(log_path) }
1649
1908
 
1650
1909
  def initialize_config
1651
- Appsignal.config = project_fixture_config(
1910
+ Appsignal._config = project_fixture_config(
1652
1911
  "production",
1653
1912
  :log_path => log_path,
1654
1913
  :log_level => log_level
@@ -1795,7 +2054,6 @@ describe Appsignal do
1795
2054
 
1796
2055
  context "when there is no config" do
1797
2056
  before do
1798
- Appsignal.config = nil
1799
2057
  capture_stdout(out_stream) do
1800
2058
  Appsignal._start_logger
1801
2059
  end
@@ -76,9 +76,6 @@ RSpec.describe "Puma plugin" do
76
76
  let(:hostname) { Socket.gethostname }
77
77
  let(:expected_default_tags) { { "hostname" => hostname } }
78
78
  let(:stats_data) { { :backlog => 1 } }
79
- before :context do
80
- Appsignal.stop
81
- end
82
79
  before do
83
80
  module Puma
84
81
  def self.stats
data/spec/spec_helper.rb CHANGED
@@ -66,6 +66,7 @@ RSpec.configure do |config|
66
66
  config.include ApiRequestHelper
67
67
  config.include SystemHelpers
68
68
  config.include LogHelpers
69
+ config.include LoaderHelper
69
70
  config.extend DependencyHelper
70
71
 
71
72
  config.example_status_persistence_file_path = "spec/examples.txt"
@@ -92,6 +93,10 @@ RSpec.configure do |config|
92
93
  end
93
94
 
94
95
  config.before do
96
+ Appsignal.clear!
97
+ Appsignal::Testing.clear!
98
+ Appsignal::Loaders.clear!
99
+ clear_current_transaction!
95
100
  stop_minutely_probes
96
101
  ENV["RAILS_ENV"] ||= "test"
97
102
  ENV["RACK_ENV"] ||= "test"
@@ -157,15 +162,11 @@ RSpec.configure do |config|
157
162
  end
158
163
 
159
164
  config.after do
160
- Appsignal::Testing.clear!
161
- clear_current_transaction!
162
165
  stop_minutely_probes
163
166
  end
164
167
 
165
168
  config.after :context do
166
169
  FileUtils.rm_f(File.join(project_fixture_path, "log/appsignal.log"))
167
- Appsignal.config = nil
168
- Appsignal.internal_logger = nil
169
170
  end
170
171
 
171
172
  def stop_minutely_probes
@@ -4,6 +4,7 @@ module ConfigHelpers
4
4
  File.join(File.dirname(__FILE__), "../fixtures/projects/valid")
5
5
  )
6
6
  end
7
+ module_function :project_fixture_path
7
8
 
8
9
  def project_fixture_config( # rubocop:disable Metrics/ParameterLists
9
10
  env = "production",
@@ -22,7 +23,7 @@ module ConfigHelpers
22
23
  module_function :project_fixture_config, :project_fixture_path
23
24
 
24
25
  def start_agent(env = "production")
25
- Appsignal.config = project_fixture_config(env)
26
+ Appsignal._config = project_fixture_config(env)
26
27
  Appsignal.start
27
28
  end
28
29
  end
@@ -0,0 +1,21 @@
1
+ module LoaderHelper
2
+ def load_loader(name)
3
+ Appsignal.load(name)
4
+ end
5
+
6
+ def start_loader(name)
7
+ Appsignal::Loaders.instances.fetch(name).on_start
8
+ end
9
+
10
+ def unregister_loader(name)
11
+ Appsignal::Loaders.unregister(name)
12
+ end
13
+
14
+ def define_loader(name, &block)
15
+ Appsignal::Testing.registered_loaders << name
16
+ Class.new(Appsignal::Loaders::Loader) do
17
+ register name
18
+ class_eval(&block) if block_given?
19
+ end
20
+ end
21
+ end
@@ -59,6 +59,7 @@ define_transaction_sample_matcher_for(:environment)
59
59
  define_transaction_sample_matcher_for(:session_data)
60
60
  define_transaction_sample_matcher_for(:tags)
61
61
  define_transaction_sample_matcher_for(:custom_data)
62
+ define_transaction_sample_matcher_for(:error_causes)
62
63
 
63
64
  RSpec::Matchers.define :be_completed do
64
65
  match(:notify_expectation_failures => true) do |transaction|
@@ -66,14 +67,14 @@ RSpec::Matchers.define :be_completed do
66
67
  end
67
68
  end
68
69
 
69
- RSpec::Matchers.define :have_error do |error_class, error_message|
70
+ RSpec::Matchers.define :have_error do |error_class, error_message, error_backtrace|
70
71
  match(:notify_expectation_failures => true) do |transaction|
71
72
  transaction_error = transaction.to_h["error"]
72
73
  if error_class && error_message
73
74
  expect(transaction_error).to include(
74
75
  "name" => error_class,
75
76
  "message" => error_message,
76
- "backtrace" => kind_of(String)
77
+ "backtrace" => error_backtrace ? JSON.dump(error_backtrace) : kind_of(String)
77
78
  )
78
79
  else
79
80
  expect(transaction_error).to be_any
@@ -0,0 +1,7 @@
1
+ module Appsignal
2
+ module Loaders
3
+ class LoaderStub < Loader
4
+ register :loader_stub
5
+ end
6
+ end
7
+ end
@@ -9,11 +9,55 @@ module Appsignal
9
9
  @testing = true unless defined?(@testing)
10
10
  @testing
11
11
  end
12
+
13
+ # @api private
14
+ def clear_started!
15
+ return unless instance_variable_defined?(:@started)
16
+
17
+ remove_instance_variable(:@started)
18
+ end
19
+
20
+ # @api private
21
+ def clear_config!
22
+ @config = nil
23
+ end
24
+
25
+ # @api private
26
+ def clear!
27
+ Appsignal.internal_logger = nil
28
+
29
+ clear_started!
30
+ clear_config!
31
+ end
32
+ end
33
+
34
+ class Config
35
+ def self.clear_loader_defaults!
36
+ @loader_defaults = nil
37
+ end
38
+ end
39
+
40
+ module Loaders
41
+ def self.clear!
42
+ Appsignal::Config.clear_loader_defaults!
43
+ loaders.reject! do |key, _value|
44
+ Appsignal::Testing.registered_loaders.include?(key)
45
+ end
46
+ @instances = nil
47
+ end
12
48
  end
13
49
 
14
50
  # @api private
15
51
  module Testing
16
52
  class << self
53
+ def store
54
+ @store ||= {}
55
+ end
56
+
57
+ def registered_loaders
58
+ @registered_loaders ||= Set.new
59
+ end
60
+
17
61
  def without_testing
18
62
  original_testing = Appsignal.testing?
19
63
  Appsignal.testing = false
@@ -27,7 +71,9 @@ module Appsignal
27
71
  end
28
72
 
29
73
  def clear!
74
+ store.clear
30
75
  transactions.clear
76
+ registered_loaders.clear
31
77
  end
32
78
 
33
79
  attr_writer :keep_transactions, :sample_transactions
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appsignal
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.11.0
4
+ version: 3.12.1
5
5
  platform: java
6
6
  authors:
7
7
  - Robert Beekman
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-07-15 00:00:00.000000000 Z
13
+ date: 2024-07-25 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rack
@@ -280,6 +280,11 @@ files:
280
280
  - lib/appsignal/integrations/sinatra.rb
281
281
  - lib/appsignal/integrations/unicorn.rb
282
282
  - lib/appsignal/integrations/webmachine.rb
283
+ - lib/appsignal/loaders.rb
284
+ - lib/appsignal/loaders/grape.rb
285
+ - lib/appsignal/loaders/hanami.rb
286
+ - lib/appsignal/loaders/padrino.rb
287
+ - lib/appsignal/loaders/sinatra.rb
283
288
  - lib/appsignal/logger.rb
284
289
  - lib/appsignal/marker.rb
285
290
  - lib/appsignal/probes.rb
@@ -378,6 +383,7 @@ files:
378
383
  - spec/lib/appsignal/hooks_spec.rb
379
384
  - spec/lib/appsignal/integrations/data_mapper_spec.rb
380
385
  - spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb
386
+ - spec/lib/appsignal/integrations/grape_spec.rb
381
387
  - spec/lib/appsignal/integrations/hanami_spec.rb
382
388
  - spec/lib/appsignal/integrations/http_spec.rb
383
389
  - spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb
@@ -390,6 +396,11 @@ files:
390
396
  - spec/lib/appsignal/integrations/sidekiq_spec.rb
391
397
  - spec/lib/appsignal/integrations/sinatra_spec.rb
392
398
  - spec/lib/appsignal/integrations/webmachine_spec.rb
399
+ - spec/lib/appsignal/loaders/grape_spec.rb
400
+ - spec/lib/appsignal/loaders/hanami_spec.rb
401
+ - spec/lib/appsignal/loaders/padrino_spec.rb
402
+ - spec/lib/appsignal/loaders/sinatra_spec.rb
403
+ - spec/lib/appsignal/loaders_spec.rb
393
404
  - spec/lib/appsignal/logger_spec.rb
394
405
  - spec/lib/appsignal/marker_spec.rb
395
406
  - spec/lib/appsignal/probes/gvl_spec.rb
@@ -441,6 +452,7 @@ files:
441
452
  - spec/support/helpers/environment_metdata_helper.rb
442
453
  - spec/support/helpers/example_exception.rb
443
454
  - spec/support/helpers/example_standard_error.rb
455
+ - spec/support/helpers/loader_helper.rb
444
456
  - spec/support/helpers/log_helpers.rb
445
457
  - spec/support/helpers/rails_helper.rb
446
458
  - spec/support/helpers/std_streams_helper.rb
@@ -458,6 +470,7 @@ files:
458
470
  - spec/support/mocks/mock_probe.rb
459
471
  - spec/support/rails/my_app.rb
460
472
  - spec/support/shared_examples/instrument.rb
473
+ - spec/support/stubs/appsignal/loaders/loader_stub.rb
461
474
  - spec/support/stubs/delayed_job.rb
462
475
  - spec/support/stubs/sidekiq/api.rb
463
476
  - spec/support/testing.rb