appsignal 3.11.0 → 3.12.0

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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +109 -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/integrations/grape.rb +7 -0
  8. data/lib/appsignal/integrations/hanami.rb +8 -43
  9. data/lib/appsignal/integrations/padrino.rb +8 -73
  10. data/lib/appsignal/integrations/railtie.rb +35 -13
  11. data/lib/appsignal/integrations/sinatra.rb +8 -19
  12. data/lib/appsignal/loaders/grape.rb +13 -0
  13. data/lib/appsignal/loaders/hanami.rb +40 -0
  14. data/lib/appsignal/loaders/padrino.rb +68 -0
  15. data/lib/appsignal/loaders/sinatra.rb +24 -0
  16. data/lib/appsignal/loaders.rb +92 -0
  17. data/lib/appsignal/rack/abstract_middleware.rb +2 -1
  18. data/lib/appsignal/rack/event_handler.rb +5 -5
  19. data/lib/appsignal/rack.rb +6 -0
  20. data/lib/appsignal/version.rb +1 -1
  21. data/lib/appsignal.rb +163 -9
  22. data/spec/lib/appsignal/cli/demo_spec.rb +0 -1
  23. data/spec/lib/appsignal/cli/diagnose/paths_spec.rb +1 -1
  24. data/spec/lib/appsignal/cli/diagnose_spec.rb +0 -1
  25. data/spec/lib/appsignal/config_spec.rb +153 -1
  26. data/spec/lib/appsignal/demo_spec.rb +1 -2
  27. data/spec/lib/appsignal/environment_spec.rb +4 -2
  28. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +3 -6
  29. data/spec/lib/appsignal/hooks/activejob_spec.rb +3 -3
  30. data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +4 -7
  31. data/spec/lib/appsignal/hooks/excon_spec.rb +3 -6
  32. data/spec/lib/appsignal/hooks/gvl_spec.rb +2 -2
  33. data/spec/lib/appsignal/hooks/http_spec.rb +1 -3
  34. data/spec/lib/appsignal/hooks/net_http_spec.rb +1 -1
  35. data/spec/lib/appsignal/hooks/redis_client_spec.rb +5 -8
  36. data/spec/lib/appsignal/hooks/redis_spec.rb +3 -6
  37. data/spec/lib/appsignal/hooks/resque_spec.rb +1 -1
  38. data/spec/lib/appsignal/hooks/sequel_spec.rb +3 -5
  39. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +1 -1
  40. data/spec/lib/appsignal/hooks/webmachine_spec.rb +1 -1
  41. data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +2 -2
  42. data/spec/lib/appsignal/integrations/grape_spec.rb +36 -0
  43. data/spec/lib/appsignal/integrations/hanami_spec.rb +9 -178
  44. data/spec/lib/appsignal/integrations/http_spec.rb +1 -5
  45. data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +4 -2
  46. data/spec/lib/appsignal/integrations/net_http_spec.rb +1 -1
  47. data/spec/lib/appsignal/integrations/object_spec.rb +1 -3
  48. data/spec/lib/appsignal/integrations/padrino_spec.rb +8 -330
  49. data/spec/lib/appsignal/integrations/railtie_spec.rb +275 -191
  50. data/spec/lib/appsignal/integrations/shoryuken_spec.rb +1 -1
  51. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +11 -9
  52. data/spec/lib/appsignal/integrations/sinatra_spec.rb +9 -104
  53. data/spec/lib/appsignal/loaders/grape_spec.rb +12 -0
  54. data/spec/lib/appsignal/loaders/hanami_spec.rb +95 -0
  55. data/spec/lib/appsignal/loaders/padrino_spec.rb +277 -0
  56. data/spec/lib/appsignal/loaders/sinatra_spec.rb +47 -0
  57. data/spec/lib/appsignal/loaders_spec.rb +137 -0
  58. data/spec/lib/appsignal/probes/sidekiq_spec.rb +1 -1
  59. data/spec/lib/appsignal/probes_spec.rb +6 -5
  60. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +3 -2
  61. data/spec/lib/appsignal/rack/event_handler_spec.rb +33 -0
  62. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +1 -1
  63. data/spec/lib/appsignal/rack/grape_middleware_spec.rb +2 -35
  64. data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +1 -1
  65. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +3 -3
  66. data/spec/lib/appsignal/span_spec.rb +1 -3
  67. data/spec/lib/appsignal/transaction_spec.rb +4 -2
  68. data/spec/lib/appsignal_spec.rb +278 -26
  69. data/spec/lib/puma/appsignal_spec.rb +0 -3
  70. data/spec/spec_helper.rb +5 -4
  71. data/spec/support/helpers/config_helpers.rb +2 -1
  72. data/spec/support/helpers/loader_helper.rb +21 -0
  73. data/spec/support/stubs/appsignal/loaders/loader_stub.rb +7 -0
  74. data/spec/support/testing.rb +46 -0
  75. metadata +15 -2
@@ -408,13 +408,14 @@ describe Appsignal::Probes do
408
408
  end
409
409
 
410
410
  context "logger" do
411
- let(:log_stream) { std_stream }
412
- let(:log) { log_contents(log_stream) }
411
+ before { start_agent }
413
412
 
414
- around { |example| use_logger_with(log_stream) { example.run } }
415
413
  it "logs a deprecation message" do
416
- silence { collection.register :my_probe, lambda {} }
417
- expect(log).to contains_log :warn,
414
+ logs =
415
+ capture_logs do
416
+ silence { collection.register :my_probe, lambda {} }
417
+ end
418
+ expect(logs).to contains_log :warn,
418
419
  "The method 'Appsignal::Probes.probes.register' is deprecated. " \
419
420
  "Use 'Appsignal::Probes.register' instead."
420
421
  end
@@ -12,7 +12,7 @@ describe Appsignal::Rack::AbstractMiddleware do
12
12
  let(:options) { {} }
13
13
  let(:middleware) { described_class.new(app, options) }
14
14
 
15
- before(:context) { start_agent }
15
+ before { start_agent }
16
16
  around { |example| keep_transactions { example.run } }
17
17
 
18
18
  def make_request
@@ -400,11 +400,12 @@ describe Appsignal::Rack::AbstractMiddleware do
400
400
  expect(response_events).to eq(1)
401
401
  end
402
402
 
403
- context "when response body is already a BodyWrapper subclass" do
403
+ context "when the response body is already instrumented" do
404
404
  let(:body) { Appsignal::Rack::BodyWrapper.wrap(["hello!"], transaction) }
405
405
  let(:app) { DummyApp.new { [200, {}, body] } }
406
406
 
407
407
  it "doesn't wrap the body again" do
408
+ env[Appsignal::Rack::APPSIGNAL_RESPONSE_INSTRUMENTED] = true
408
409
  _status, _headers, body = make_request
409
410
  expect(body).to eq(body)
410
411
 
@@ -40,6 +40,14 @@ describe Appsignal::Rack::EventHandler do
40
40
  expect(Appsignal::Transaction.current).to eq(transaction)
41
41
  end
42
42
 
43
+ context "when not active" do
44
+ it "does not create a new transaction" do
45
+ allow(Appsignal).to receive(:active?).and_return(false)
46
+
47
+ expect { on_start }.to_not(change { created_transactions.length })
48
+ end
49
+ end
50
+
43
51
  context "when the handler is nested in another EventHandler" do
44
52
  it "does not create a new transaction in the nested EventHandler" do
45
53
  on_start
@@ -131,6 +139,17 @@ describe Appsignal::Rack::EventHandler do
131
139
  expect(last_transaction).to have_error("ExampleStandardError", "the error")
132
140
  end
133
141
 
142
+ context "when not active" do
143
+ it "does not report the transaction" do
144
+ allow(Appsignal).to receive(:active?).and_return(false)
145
+
146
+ on_start
147
+ on_error(ExampleStandardError.new("the error"))
148
+
149
+ expect(last_transaction).to_not have_error
150
+ end
151
+ end
152
+
134
153
  context "when the handler is nested in another EventHandler" do
135
154
  it "does not report the error on the transaction" do
136
155
  on_start
@@ -175,6 +194,20 @@ describe Appsignal::Rack::EventHandler do
175
194
  expect(last_transaction).to_not be_completed
176
195
  end
177
196
 
197
+ context "when not active" do
198
+ it "doesn't do anything" do
199
+ allow(Appsignal).to receive(:active?).and_return(false)
200
+
201
+ request.env[Appsignal::Rack::APPSIGNAL_TRANSACTION] = http_request_transaction
202
+ on_finish
203
+
204
+ expect(last_transaction).to_not have_action
205
+ expect(last_transaction).to_not include_events
206
+ expect(last_transaction).to include("sample_data" => {})
207
+ expect(last_transaction).to_not be_completed
208
+ end
209
+ end
210
+
178
211
  it "sets params on the transaction" do
179
212
  on_start
180
213
  on_finish
@@ -46,7 +46,7 @@ describe "Appsignal::Rack::GenericInstrumentation" do
46
46
  let(:env) { Rack::MockRequest.env_for("/some/path") }
47
47
  let(:middleware) { Appsignal::Rack::GenericInstrumentation.new(app, {}) }
48
48
 
49
- before(:context) { start_agent }
49
+ before { start_agent }
50
50
  around { |example| keep_transactions { example.run } }
51
51
 
52
52
  def make_request(env)
@@ -1,38 +1,5 @@
1
1
  if DependencyHelper.grape_present?
2
- require "appsignal/integrations/grape"
3
-
4
- context "Appsignal::Grape::Middleware constant" do
5
- let(:err_stream) { std_stream }
6
- let(:stderr) { err_stream.read }
7
-
8
- it "returns the Rack::GrapeMiddleware constant calling the Grape::Middleware constant" do
9
- silence { expect(Appsignal::Grape::Middleware).to be(Appsignal::Rack::GrapeMiddleware) }
10
- end
11
-
12
- it "prints a deprecation warning to STDERR" do
13
- capture_std_streams(std_stream, err_stream) do
14
- expect(Appsignal::Grape::Middleware).to be(Appsignal::Rack::GrapeMiddleware)
15
- end
16
-
17
- expect(stderr).to include(
18
- "appsignal WARNING: The constant Appsignal::Grape::Middleware has been deprecated."
19
- )
20
- end
21
-
22
- it "logs a warning" do
23
- logs =
24
- capture_logs do
25
- silence do
26
- expect(Appsignal::Grape::Middleware).to be(Appsignal::Rack::GrapeMiddleware)
27
- end
28
- end
29
-
30
- expect(logs).to contains_log(
31
- :warn,
32
- "The constant Appsignal::Grape::Middleware has been deprecated."
33
- )
34
- end
35
- end
2
+ require "appsignal/rack/grape_middleware"
36
3
 
37
4
  describe Appsignal::Rack::GrapeMiddleware do
38
5
  let(:app) do
@@ -52,7 +19,7 @@ if DependencyHelper.grape_present?
52
19
  end
53
20
  let(:middleware) { Appsignal::Rack::GrapeMiddleware.new(api_endpoint) }
54
21
  let(:transaction) { http_request_transaction }
55
- before(:context) { start_agent }
22
+ before { start_agent }
56
23
  around do |example|
57
24
  GrapeExample = Module.new
58
25
  GrapeExample.send(:const_set, :Api, app)
@@ -12,7 +12,7 @@ if DependencyHelper.hanami2_present?
12
12
  end
13
13
  let(:middleware) { Appsignal::Rack::HanamiMiddleware.new(app, {}) }
14
14
 
15
- before(:context) { start_agent }
15
+ before { start_agent }
16
16
  around { |example| keep_transactions { example.run } }
17
17
 
18
18
  def make_request(env)
@@ -1,5 +1,5 @@
1
1
  if DependencyHelper.sinatra_present?
2
- require "appsignal/integrations/sinatra"
2
+ require "appsignal/rack/sinatra_instrumentation"
3
3
 
4
4
  module SinatraRequestHelpers
5
5
  def make_request
@@ -21,7 +21,7 @@ if DependencyHelper.sinatra_present?
21
21
  end
22
22
  let(:middleware) { Appsignal::Rack::SinatraInstrumentation.new(app) }
23
23
 
24
- before(:context) { start_agent }
24
+ before { start_agent }
25
25
  around do |example|
26
26
  keep_transactions { example.run }
27
27
  end
@@ -54,7 +54,7 @@ if DependencyHelper.sinatra_present?
54
54
  let(:options) { {} }
55
55
  let(:middleware) { Appsignal::Rack::SinatraBaseInstrumentation.new(app, options) }
56
56
 
57
- before(:context) { start_agent }
57
+ before { start_agent }
58
58
  around do |example|
59
59
  keep_transactions { example.run }
60
60
  end
@@ -1,9 +1,7 @@
1
1
  require "appsignal/span"
2
2
 
3
3
  describe Appsignal::Span do
4
- before :context do
5
- start_agent
6
- end
4
+ before { start_agent }
7
5
 
8
6
  let(:namespace) { "web" }
9
7
  let(:root) { Appsignal::Span.new(namespace) }
@@ -1,10 +1,12 @@
1
1
  describe Appsignal::Transaction do
2
2
  let(:time) { Time.at(fixed_time) }
3
3
 
4
- before { Timecop.freeze(time) }
4
+ before do
5
+ start_agent
6
+ Timecop.freeze(time)
7
+ end
5
8
  after { Timecop.return }
6
9
  around do |example|
7
- start_agent
8
10
  keep_transactions do
9
11
  example.run
10
12
  end
@@ -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
@@ -883,13 +1138,11 @@ describe Appsignal do
883
1138
  end
884
1139
 
885
1140
  describe ".add_breadcrumb" do
886
- around do |example|
887
- start_agent
888
- with_current_transaction(transaction) { example.run }
889
- end
1141
+ before { start_agent }
890
1142
 
891
1143
  context "with transaction" do
892
1144
  let(:transaction) { http_request_transaction }
1145
+ before { set_current_transaction(transaction) }
893
1146
 
894
1147
  it "adds the breadcrumb to the transaction" do
895
1148
  Appsignal.add_breadcrumb(
@@ -1648,7 +1901,7 @@ describe Appsignal do
1648
1901
  after { FileUtils.rm_rf(log_path) }
1649
1902
 
1650
1903
  def initialize_config
1651
- Appsignal.config = project_fixture_config(
1904
+ Appsignal._config = project_fixture_config(
1652
1905
  "production",
1653
1906
  :log_path => log_path,
1654
1907
  :log_level => log_level
@@ -1795,7 +2048,6 @@ describe Appsignal do
1795
2048
 
1796
2049
  context "when there is no config" do
1797
2050
  before do
1798
- Appsignal.config = nil
1799
2051
  capture_stdout(out_stream) do
1800
2052
  Appsignal._start_logger
1801
2053
  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