appsignal 3.7.0-java → 3.7.2-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.
data/lib/appsignal.rb CHANGED
@@ -5,7 +5,7 @@ require "securerandom"
5
5
  require "stringio"
6
6
 
7
7
  require "appsignal/logger"
8
- require "appsignal/utils/deprecation_message"
8
+ require "appsignal/utils/stdout_and_logger_message"
9
9
  require "appsignal/helpers/instrumentation"
10
10
  require "appsignal/helpers/metrics"
11
11
 
@@ -120,7 +120,7 @@ module Appsignal
120
120
  Appsignal::Environment.report_enabled("allocation_tracking")
121
121
  end
122
122
 
123
- Appsignal::Minutely.start if config[:enable_minutely_probes]
123
+ Appsignal::Probes.start if config[:enable_minutely_probes]
124
124
 
125
125
  collect_environment_metadata
126
126
  else
@@ -152,6 +152,7 @@ module Appsignal
152
152
  internal_logger.debug("Stopping appsignal")
153
153
  end
154
154
  Appsignal::Extension.stop
155
+ Appsignal::Probes.stop
155
156
  end
156
157
 
157
158
  def forked
@@ -218,7 +219,10 @@ module Appsignal
218
219
  else
219
220
  Appsignal::Config::DEFAULT_LOG_LEVEL
220
221
  end
221
- internal_logger << @in_memory_log.string if @in_memory_log
222
+ return unless @in_memory_log
223
+
224
+ internal_logger << @in_memory_log.string
225
+ @in_memory_log = nil
222
226
  end
223
227
 
224
228
  # Returns if the C-extension was loaded properly.
@@ -287,6 +291,22 @@ module Appsignal
287
291
  end
288
292
  Appsignal::Environment.report_supported_gems
289
293
  end
294
+
295
+ # Alias constants that have moved with a warning message that points to the
296
+ # place to update the reference.
297
+ def const_missing(name)
298
+ case name
299
+ when :Minutely
300
+ callers = caller
301
+ Appsignal::Utils::StdoutAndLoggerMessage.warning \
302
+ "The constant Appsignal::Minutely has been deprecated. " \
303
+ "Please update the constant name to Appsignal::Probes " \
304
+ "in the following file to remove this message.\n#{callers.first}"
305
+ Appsignal::Probes
306
+ else
307
+ super
308
+ end
309
+ end
290
310
  end
291
311
  end
292
312
 
@@ -300,7 +320,6 @@ require "appsignal/event_formatter"
300
320
  require "appsignal/hooks"
301
321
  require "appsignal/probes"
302
322
  require "appsignal/marker"
303
- require "appsignal/minutely"
304
323
  require "appsignal/garbage_collection"
305
324
  require "appsignal/integrations/railtie" if defined?(::Rails)
306
325
  require "appsignal/transaction"
@@ -757,7 +757,10 @@ describe Appsignal::Config do
757
757
  let(:out_stream) { std_stream }
758
758
  let(:output) { out_stream.read }
759
759
  let(:config) { project_fixture_config("production", :log_path => log_path) }
760
- subject { capture_stdout(out_stream) { config.log_file_path } }
760
+
761
+ def log_file_path
762
+ capture_stdout(out_stream) { config.log_file_path }
763
+ end
761
764
 
762
765
  context "when path is writable" do
763
766
  let(:log_path) { File.join(tmp_dir, "writable-path") }
@@ -765,11 +768,11 @@ describe Appsignal::Config do
765
768
  after { FileUtils.rm_rf(log_path) }
766
769
 
767
770
  it "returns log file path" do
768
- expect(subject).to eq File.join(log_path, "appsignal.log")
771
+ expect(log_file_path).to eq File.join(log_path, "appsignal.log")
769
772
  end
770
773
 
771
774
  it "prints no warning" do
772
- subject
775
+ log_file_path
773
776
  expect(output).to be_empty
774
777
  end
775
778
  end
@@ -783,28 +786,47 @@ describe Appsignal::Config do
783
786
  before { FileUtils.chmod(0o777, system_tmp_dir) }
784
787
 
785
788
  it "returns returns the tmp location" do
786
- expect(subject).to eq(File.join(system_tmp_dir, "appsignal.log"))
789
+ expect(log_file_path).to eq(File.join(system_tmp_dir, "appsignal.log"))
787
790
  end
788
791
 
789
792
  it "prints a warning" do
790
- subject
793
+ log_file_path
791
794
  expect(output).to include "appsignal: Unable to log to '#{log_path}'. " \
792
795
  "Logging to '#{system_tmp_dir}' instead."
793
796
  end
797
+
798
+ it "prints a warning once" do
799
+ capture_stdout(out_stream) do
800
+ log_file_path
801
+ log_file_path
802
+ end
803
+ message = "appsignal: Unable to log to '#{log_path}'. " \
804
+ "Logging to '#{system_tmp_dir}' instead."
805
+ expect(output.scan(message).count).to eq(1)
806
+ end
794
807
  end
795
808
 
796
809
  context "when the /tmp fallback path is not writable" do
797
810
  before { FileUtils.chmod(0o555, system_tmp_dir) }
798
811
 
799
812
  it "returns nil" do
800
- expect(subject).to be_nil
813
+ expect(log_file_path).to be_nil
801
814
  end
802
815
 
803
816
  it "prints a warning" do
804
- subject
817
+ log_file_path
805
818
  expect(output).to include "appsignal: Unable to log to '#{log_path}' " \
806
819
  "or the '#{system_tmp_dir}' fallback."
807
820
  end
821
+
822
+ it "prints a warning once" do
823
+ capture_stdout(out_stream) do
824
+ log_file_path
825
+ log_file_path
826
+ end
827
+ message = "appsignal: Unable to log to '#{log_path}' or the '#{system_tmp_dir}' fallback."
828
+ expect(output.scan(message).count).to eq(1)
829
+ end
808
830
  end
809
831
  end
810
832
 
@@ -819,11 +841,11 @@ describe Appsignal::Config do
819
841
 
820
842
  context "when root_path is set" do
821
843
  it "returns returns the project log location" do
822
- expect(subject).to eq File.join(config.root_path, "log/appsignal.log")
844
+ expect(log_file_path).to eq File.join(config.root_path, "log/appsignal.log")
823
845
  end
824
846
 
825
847
  it "prints no warning" do
826
- subject
848
+ log_file_path
827
849
  expect(output).to be_empty
828
850
  end
829
851
  end
@@ -883,7 +905,7 @@ describe Appsignal::Config do
883
905
  end
884
906
 
885
907
  it "returns real path of log path" do
886
- expect(subject).to eq(File.join(real_path, "appsignal.log"))
908
+ expect(log_file_path).to eq(File.join(real_path, "appsignal.log"))
887
909
  end
888
910
  end
889
911
  end
@@ -93,7 +93,7 @@ describe Appsignal::Hooks::GvlHook do
93
93
  it "is added to minutely probes" do
94
94
  Appsignal::Hooks.load_hooks
95
95
 
96
- expect(Appsignal::Minutely.probes[:gvl]).to be Appsignal::Probes::GvlProbe
96
+ expect(Appsignal::Probes.probes[:gvl]).to be Appsignal::Probes::GvlProbe
97
97
  end
98
98
  end
99
99
  end
@@ -16,7 +16,7 @@ describe Appsignal::Hooks::MriHook do
16
16
  end
17
17
 
18
18
  it "should be added to minutely probes" do
19
- expect(Appsignal::Minutely.probes[:mri]).to be Appsignal::Probes::MriProbe
19
+ expect(Appsignal::Probes.probes[:mri]).to be Appsignal::Probes::MriProbe
20
20
  end
21
21
  end
22
22
  end
@@ -27,7 +27,7 @@ describe Appsignal::Hooks::PumaHook do
27
27
  end
28
28
 
29
29
  describe "installation" do
30
- before { Appsignal::Minutely.probes.clear }
30
+ before { Appsignal::Probes.probes.clear }
31
31
 
32
32
  context "when not clustered mode" do
33
33
  it "does not add AppSignal stop behavior Puma::Cluster" do
@@ -1,11 +1,40 @@
1
- describe Appsignal::Minutely do
1
+ describe Appsignal::Probes do
2
2
  include WaitForHelper
3
3
 
4
- before { Appsignal::Minutely.probes.clear }
4
+ before { Appsignal::Probes.probes.clear }
5
+
6
+ context "Minutely constant" do
7
+ let(:err_stream) { std_stream }
8
+ let(:stderr) { err_stream.read }
9
+
10
+ it "returns the Probes constant calling the Minutely constant" do
11
+ silence { expect(Appsignal::Minutely).to be(Appsignal::Probes) }
12
+ end
13
+
14
+ it "prints a deprecation warning to STDERR" do
15
+ capture_std_streams(std_stream, err_stream) do
16
+ expect(Appsignal::Minutely).to be(Appsignal::Probes)
17
+ end
18
+
19
+ expect(stderr)
20
+ .to include("appsignal WARNING: The constant Appsignal::Minutely has been deprecated.")
21
+ end
22
+
23
+ it "logs a warning to STDERR" do
24
+ logs =
25
+ capture_logs do
26
+ silence do
27
+ expect(Appsignal::Minutely).to be(Appsignal::Probes)
28
+ end
29
+ end
30
+
31
+ expect(logs).to include("The constant Appsignal::Minutely has been deprecated.")
32
+ end
33
+ end
5
34
 
6
35
  it "returns a ProbeCollection" do
7
- expect(Appsignal::Minutely.probes)
8
- .to be_instance_of(Appsignal::Minutely::ProbeCollection)
36
+ expect(Appsignal::Probes.probes)
37
+ .to be_instance_of(Appsignal::Probes::ProbeCollection)
9
38
  end
10
39
 
11
40
  describe ".start" do
@@ -43,16 +72,31 @@ describe Appsignal::Minutely do
43
72
  let(:log) { log_contents(log_stream) }
44
73
  before do
45
74
  Appsignal.internal_logger = test_logger(log_stream)
46
- # Speed up test time
47
- allow(Appsignal::Minutely).to receive(:initial_wait_time).and_return(0.001)
48
- allow(Appsignal::Minutely).to receive(:wait_time).and_return(0.001)
75
+ speed_up_tests!
76
+ end
77
+
78
+ describe ".started?" do
79
+ it "returns true when the probes thread has been started" do
80
+ expect(Appsignal::Probes.started?).to be_falsy
81
+ Appsignal::Probes.register :my_probe, (lambda {})
82
+ Appsignal::Probes.start
83
+ expect(Appsignal::Probes.started?).to be_truthy
84
+ end
85
+
86
+ it "returns false when the probes thread has been stopped" do
87
+ Appsignal::Probes.register :my_probe, lambda {}
88
+ Appsignal::Probes.start
89
+ expect(Appsignal::Probes.started?).to be_truthy
90
+ Appsignal::Probes.stop
91
+ expect(Appsignal::Probes.started?).to be_falsy
92
+ end
49
93
  end
50
94
 
51
95
  context "with an instance of a class" do
52
96
  it "calls the probe every <wait_time>" do
53
97
  probe = MockProbe.new
54
- Appsignal::Minutely.probes.register :my_probe, probe
55
- Appsignal::Minutely.start
98
+ Appsignal::Probes.register :my_probe, probe
99
+ Appsignal::Probes.start
56
100
 
57
101
  wait_for("enough probe calls") { probe.calls >= 2 }
58
102
  expect(log).to contains_log(:debug, "Gathering minutely metrics with 1 probe")
@@ -63,11 +107,11 @@ describe Appsignal::Minutely do
63
107
  it "does not initialize the probe" do
64
108
  # Working probe which we can use to wait for X ticks
65
109
  working_probe = ProbeWithoutDependency.new
66
- Appsignal::Minutely.probes.register :probe_without_dep, working_probe
110
+ Appsignal::Probes.register :probe_without_dep, working_probe
67
111
 
68
112
  probe = ProbeWithMissingDependency.new
69
- Appsignal::Minutely.probes.register :probe_with_missing_dep, probe
70
- Appsignal::Minutely.start
113
+ Appsignal::Probes.register :probe_with_missing_dep, probe
114
+ Appsignal::Probes.start
71
115
 
72
116
  wait_for("enough probe calls") { working_probe.calls >= 2 }
73
117
  # Only counts initialized probes
@@ -83,8 +127,8 @@ describe Appsignal::Minutely do
83
127
  probe = MockProbe
84
128
  probe_instance = MockProbe.new
85
129
  expect(probe).to receive(:new).and_return(probe_instance)
86
- Appsignal::Minutely.probes.register :my_probe, probe
87
- Appsignal::Minutely.start
130
+ Appsignal::Probes.register :my_probe, probe
131
+ Appsignal::Probes.start
88
132
 
89
133
  wait_for("enough probe calls") { probe_instance.calls >= 2 }
90
134
  expect(log).to contains_log(:debug, "Gathering minutely metrics with 1 probe")
@@ -97,11 +141,11 @@ describe Appsignal::Minutely do
97
141
  working_probe = ProbeWithoutDependency
98
142
  working_probe_instance = working_probe.new
99
143
  expect(working_probe).to receive(:new).and_return(working_probe_instance)
100
- Appsignal::Minutely.probes.register :probe_without_dep, working_probe
144
+ Appsignal::Probes.register :probe_without_dep, working_probe
101
145
 
102
146
  probe = ProbeWithMissingDependency
103
- Appsignal::Minutely.probes.register :probe_with_missing_dep, probe
104
- Appsignal::Minutely.start
147
+ Appsignal::Probes.register :probe_with_missing_dep, probe
148
+ Appsignal::Probes.start
105
149
 
106
150
  wait_for("enough probe calls") { working_probe_instance.calls >= 2 }
107
151
  # Only counts initialized probes
@@ -117,11 +161,11 @@ describe Appsignal::Minutely do
117
161
  working_probe = ProbeWithoutDependency
118
162
  working_probe_instance = working_probe.new
119
163
  expect(working_probe).to receive(:new).and_return(working_probe_instance)
120
- Appsignal::Minutely.probes.register :probe_without_dep, working_probe
164
+ Appsignal::Probes.register :probe_without_dep, working_probe
121
165
 
122
166
  probe = BrokenProbeOnInitialize
123
- Appsignal::Minutely.probes.register :broken_probe_on_initialize, probe
124
- Appsignal::Minutely.start
167
+ Appsignal::Probes.register :broken_probe_on_initialize, probe
168
+ Appsignal::Probes.start
125
169
 
126
170
  wait_for("enough probe calls") { working_probe_instance.calls >= 2 }
127
171
  # Only counts initialized probes
@@ -142,8 +186,8 @@ describe Appsignal::Minutely do
142
186
  it "calls the lambda every <wait time>" do
143
187
  calls = 0
144
188
  probe = lambda { calls += 1 }
145
- Appsignal::Minutely.probes.register :my_probe, probe
146
- Appsignal::Minutely.start
189
+ Appsignal::Probes.register :my_probe, probe
190
+ Appsignal::Probes.start
147
191
 
148
192
  wait_for("enough probe calls") { calls >= 2 }
149
193
  expect(log).to contains_log(:debug, "Gathering minutely metrics with 1 probe")
@@ -155,9 +199,9 @@ describe Appsignal::Minutely do
155
199
  it "logs the error and continues calling the probes every <wait_time>" do
156
200
  probe = MockProbe.new
157
201
  broken_probe = BrokenProbe.new
158
- Appsignal::Minutely.probes.register :my_probe, probe
159
- Appsignal::Minutely.probes.register :broken_probe, broken_probe
160
- Appsignal::Minutely.start
202
+ Appsignal::Probes.register :my_probe, probe
203
+ Appsignal::Probes.register :broken_probe, broken_probe
204
+ Appsignal::Probes.start
161
205
 
162
206
  wait_for("enough probe calls") { probe.calls >= 2 }
163
207
  wait_for("enough broken_probe calls") { broken_probe.calls >= 2 }
@@ -174,53 +218,101 @@ describe Appsignal::Minutely do
174
218
  it "ensures only one minutely probes thread is active at a time" do
175
219
  alive_thread_counter = proc { Thread.list.reject { |t| t.status == "dead" }.length }
176
220
  probe = MockProbe.new
177
- Appsignal::Minutely.probes.register :my_probe, probe
221
+ Appsignal::Probes.register :my_probe, probe
178
222
  expect do
179
- Appsignal::Minutely.start
223
+ Appsignal::Probes.start
180
224
  end.to change { alive_thread_counter.call }.by(1)
181
225
 
182
226
  wait_for("enough probe calls") { probe.calls >= 2 }
183
- expect(Appsignal::Minutely).to have_received(:initial_wait_time).once
184
- expect(Appsignal::Minutely).to have_received(:wait_time).at_least(:once)
227
+ expect(Appsignal::Probes).to have_received(:initial_wait_time).once
228
+ expect(Appsignal::Probes).to have_received(:wait_time).at_least(:once)
185
229
  expect(log).to contains_log(:debug, "Gathering minutely metrics with 1 probe")
186
230
  expect(log).to contains_log(:debug, "Gathering minutely metrics with 'my_probe' probe")
187
231
 
188
232
  # Starting twice in this spec, so expecting it more than once
189
- expect(Appsignal::Minutely).to have_received(:initial_wait_time).once
233
+ expect(Appsignal::Probes).to have_received(:initial_wait_time).once
190
234
  expect do
191
235
  # Fetch old thread
192
- thread = Appsignal::Minutely.instance_variable_get(:@thread)
193
- Appsignal::Minutely.start
236
+ thread = Appsignal::Probes.instance_variable_get(:@thread)
237
+ Appsignal::Probes.start
194
238
  thread&.join # Wait for old thread to exit
195
239
  end.to_not(change { alive_thread_counter.call })
196
240
  end
241
+
242
+ context "with thread already started" do
243
+ before do
244
+ allow(Appsignal::Probes).to receive(:initial_wait_time).and_return(0.00001)
245
+ end
246
+
247
+ it "auto starts probes added after the thread is started" do
248
+ Appsignal::Probes.start
249
+ wait_for("Probes thread to start") { Appsignal::Probes.started? }
250
+
251
+ calls = 0
252
+ probe = lambda { calls += 1 }
253
+ Appsignal::Probes.register :late_probe, probe
254
+
255
+ wait_for("enough probe calls") { calls >= 2 }
256
+ expect(log).to contains_log(:debug, "Gathering minutely metrics with 1 probe")
257
+ expect(log).to contains_log(:debug, "Gathering minutely metrics with 'late_probe' probe")
258
+ end
259
+ end
260
+ end
261
+
262
+ describe ".unregister" do
263
+ let(:log_stream) { StringIO.new }
264
+ let(:log) { log_contents(log_stream) }
265
+ before do
266
+ Appsignal.internal_logger = test_logger(log_stream)
267
+ speed_up_tests!
268
+ end
269
+
270
+ it "does not call the initialized probe after unregistering" do
271
+ probe1_calls = 0
272
+ probe2_calls = 0
273
+ probe1 = lambda { probe1_calls += 1 }
274
+ probe2 = lambda { probe2_calls += 1 }
275
+ Appsignal::Probes.register :probe1, probe1
276
+ Appsignal::Probes.register :probe2, probe2
277
+ Appsignal::Probes.start
278
+ wait_for("enough probe1 calls") { probe1_calls >= 2 }
279
+ wait_for("enough probe2 calls") { probe2_calls >= 2 }
280
+
281
+ Appsignal::Probes.unregister :probe2
282
+ probe1_calls = 0
283
+ probe2_calls = 0
284
+ # Check the probe 1 calls to make sure the probes have been called before
285
+ # testing if the unregistered probe has not been called
286
+ wait_for("enough probe1 calls") { probe1_calls >= 2 }
287
+ expect(probe2_calls).to eq(0)
288
+ end
197
289
  end
198
290
 
199
291
  describe ".stop" do
200
292
  before do
201
- allow(Appsignal::Minutely).to receive(:initial_wait_time).and_return(0.001)
293
+ allow(Appsignal::Probes).to receive(:initial_wait_time).and_return(0.001)
202
294
  end
203
295
 
204
296
  it "stops the minutely thread" do
205
- Appsignal::Minutely.start
206
- thread = Appsignal::Minutely.instance_variable_get(:@thread)
297
+ Appsignal::Probes.start
298
+ thread = Appsignal::Probes.instance_variable_get(:@thread)
207
299
  expect(%w[sleep run]).to include(thread.status)
208
- Appsignal::Minutely.stop
300
+ Appsignal::Probes.stop
209
301
  thread.join
210
302
  expect(thread.status).to eql(false)
211
303
  end
212
304
 
213
305
  it "clears the probe instances array" do
214
- Appsignal::Minutely.probes.register :my_probe, lambda {}
215
- Appsignal::Minutely.start
216
- thread = Appsignal::Minutely.instance_variable_get(:@thread)
306
+ Appsignal::Probes.register :my_probe, lambda {}
307
+ Appsignal::Probes.start
308
+ thread = Appsignal::Probes.instance_variable_get(:@thread)
217
309
  wait_for("probes initialized") do
218
- !Appsignal::Minutely.send(:probe_instances).empty?
310
+ !Appsignal::Probes.send(:probe_instances).empty?
219
311
  end
220
- expect(Appsignal::Minutely.send(:probe_instances)).to_not be_empty
221
- Appsignal::Minutely.stop
312
+ expect(Appsignal::Probes.send(:probe_instances)).to_not be_empty
313
+ Appsignal::Probes.stop
222
314
  thread.join
223
- expect(Appsignal::Minutely.send(:probe_instances)).to be_empty
315
+ expect(Appsignal::Probes.send(:probe_instances)).to be_empty
224
316
  end
225
317
  end
226
318
 
@@ -228,7 +320,7 @@ describe Appsignal::Minutely do
228
320
  it "gets the time to the next minute" do
229
321
  time = Time.new(2019, 4, 9, 12, 0, 20)
230
322
  Timecop.freeze time do
231
- expect(Appsignal::Minutely.wait_time).to eq 40
323
+ expect(Appsignal::Probes.wait_time).to eq 40
232
324
  end
233
325
  end
234
326
  end
@@ -238,7 +330,7 @@ describe Appsignal::Minutely do
238
330
  it "waits for the number of seconds + 60" do
239
331
  time = Time.new(2019, 4, 9, 12, 0, 31)
240
332
  Timecop.freeze time do
241
- expect(Appsignal::Minutely.send(:initial_wait_time)).to eql(29 + 60)
333
+ expect(Appsignal::Probes.send(:initial_wait_time)).to eql(29 + 60)
242
334
  end
243
335
  end
244
336
  end
@@ -247,29 +339,29 @@ describe Appsignal::Minutely do
247
339
  it "waits the remaining seconds in the minute" do
248
340
  time = Time.new(2019, 4, 9, 12, 0, 29)
249
341
  Timecop.freeze time do
250
- expect(Appsignal::Minutely.send(:initial_wait_time)).to eql(31)
342
+ expect(Appsignal::Probes.send(:initial_wait_time)).to eql(31)
251
343
  end
252
344
  end
253
345
  end
254
346
  end
255
347
 
256
- describe Appsignal::Minutely::ProbeCollection do
348
+ describe Appsignal::Probes::ProbeCollection do
257
349
  let(:collection) { described_class.new }
258
350
 
259
351
  describe "#count" do
260
352
  it "returns how many probes are registered" do
261
353
  expect(collection.count).to eql(0)
262
- collection.register :my_probe_1, lambda {}
354
+ collection.internal_register :my_probe_1, lambda {}
263
355
  expect(collection.count).to eql(1)
264
- collection.register :my_probe_2, lambda {}
356
+ collection.internal_register :my_probe_2, lambda {}
265
357
  expect(collection.count).to eql(2)
266
358
  end
267
359
  end
268
360
 
269
361
  describe "#clear" do
270
362
  it "clears the list of probes" do
271
- collection.register :my_probe_1, lambda {}
272
- collection.register :my_probe_2, lambda {}
363
+ collection.internal_register :my_probe_1, lambda {}
364
+ collection.internal_register :my_probe_2, lambda {}
273
365
  expect(collection.count).to eql(2)
274
366
  collection.clear
275
367
  expect(collection.count).to eql(0)
@@ -279,27 +371,65 @@ describe Appsignal::Minutely do
279
371
  describe "#[]" do
280
372
  it "returns the probe for that name" do
281
373
  probe = lambda {}
282
- collection.register :my_probe, probe
374
+ collection.internal_register :my_probe, probe
283
375
  expect(collection[:my_probe]).to eql(probe)
284
376
  end
285
377
  end
286
378
 
287
379
  describe "#register" do
380
+ it "adds the probe by key" do
381
+ expect(Appsignal::Probes).to receive(:probes).and_return(collection)
382
+
383
+ probe = lambda {}
384
+ silence { collection.register :my_probe, probe }
385
+ expect(collection[:my_probe]).to eql(probe)
386
+ end
387
+
388
+ context "logger" do
389
+ let(:log_stream) { std_stream }
390
+ let(:log) { log_contents(log_stream) }
391
+
392
+ around { |example| use_logger_with(log_stream) { example.run } }
393
+ it "logs a deprecation message" do
394
+ silence { collection.register :my_probe, lambda {} }
395
+ expect(log).to contains_log :warn,
396
+ "The method 'Appsignal::Probes.probes.register' is deprecated. " \
397
+ "Use 'Appsignal::Probes.register' instead."
398
+ end
399
+ end
400
+
401
+ context "stderr" do
402
+ let(:err_stream) { std_stream }
403
+ let(:stderr) { err_stream.read }
404
+
405
+ it "prints a deprecation warning" do
406
+ capture_std_streams(std_stream, err_stream) do
407
+ collection.register :my_probe, lambda {}
408
+ end
409
+ deprecation_message =
410
+ "The method 'Appsignal::Probes.probes.register' is deprecated. " \
411
+ "Use 'Appsignal::Probes.register' instead."
412
+ expect(stderr).to include("appsignal WARNING: #{deprecation_message}")
413
+ end
414
+ end
415
+ end
416
+
417
+ describe "#internal_register" do
288
418
  let(:log_stream) { std_stream }
289
419
  let(:log) { log_contents(log_stream) }
290
420
  before { Appsignal.internal_logger = test_logger(log_stream) }
291
421
 
292
- it "adds the by key probe" do
422
+ it "adds the probe by key" do
293
423
  probe = lambda {}
294
- collection.register :my_probe, probe
424
+ collection.internal_register :my_probe, probe
295
425
  expect(collection[:my_probe]).to eql(probe)
296
426
  end
297
427
 
298
428
  context "when a probe is already registered with the same key" do
299
429
  it "logs a debug message" do
300
430
  probe = lambda {}
301
- collection.register :my_probe, probe
302
- collection.register :my_probe, probe
431
+ collection.internal_register :my_probe, probe
432
+ collection.internal_register :my_probe, probe
303
433
  expect(log).to contains_log :debug, "A probe with the name " \
304
434
  "`my_probe` is already registered. Overwriting the entry " \
305
435
  "with the new probe."
@@ -308,10 +438,23 @@ describe Appsignal::Minutely do
308
438
  end
309
439
  end
310
440
 
441
+ describe "#unregister" do
442
+ it "removes the probe from the collection" do
443
+ expect(Appsignal::Probes).to receive(:probes).and_return(collection)
444
+
445
+ probe = lambda {}
446
+ silence { collection.register :my_probe, probe }
447
+ expect(collection[:my_probe]).to eql(probe)
448
+
449
+ silence { collection.unregister :my_probe }
450
+ expect(collection[:my_probe]).to be_nil
451
+ end
452
+ end
453
+
311
454
  describe "#each" do
312
455
  it "loops over the registered probes" do
313
456
  probe = lambda {}
314
- collection.register :my_probe, probe
457
+ collection.internal_register :my_probe, probe
315
458
  list = []
316
459
  collection.each do |name, p|
317
460
  list << [name, p]
@@ -320,4 +463,10 @@ describe Appsignal::Minutely do
320
463
  end
321
464
  end
322
465
  end
466
+
467
+ # Speed up test time by decreasing wait times in the probes mechanism
468
+ def speed_up_tests!
469
+ allow(Appsignal::Probes).to receive(:initial_wait_time).and_return(0.001)
470
+ allow(Appsignal::Probes).to receive(:wait_time).and_return(0.001)
471
+ end
323
472
  end