appsignal 4.0.4 → 4.0.6
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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +151 -16
- data/CHANGELOG.md +42 -0
- data/build_matrix.yml +2 -1
- data/ext/agent.rb +27 -27
- data/gemfiles/que-1.gemfile +5 -0
- data/gemfiles/que-2.gemfile +5 -0
- data/lib/appsignal/check_in/scheduler.rb +3 -4
- data/lib/appsignal/config.rb +7 -0
- data/lib/appsignal/hooks/at_exit.rb +1 -0
- data/lib/appsignal/hooks/puma.rb +5 -1
- data/lib/appsignal/integrations/puma.rb +45 -0
- data/lib/appsignal/integrations/que.rb +8 -2
- data/lib/appsignal/rack/abstract_middleware.rb +3 -47
- data/lib/appsignal/rack/event_handler.rb +2 -0
- data/lib/appsignal/rack/hanami_middleware.rb +5 -1
- data/lib/appsignal/rack.rb +68 -0
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/check_in/cron_spec.rb +134 -134
- data/spec/lib/appsignal/check_in/scheduler_spec.rb +297 -224
- data/spec/lib/appsignal/config_spec.rb +13 -0
- data/spec/lib/appsignal/hooks/at_exit_spec.rb +11 -0
- data/spec/lib/appsignal/hooks/puma_spec.rb +31 -23
- data/spec/lib/appsignal/integrations/puma_spec.rb +150 -0
- data/spec/lib/appsignal/integrations/que_spec.rb +56 -21
- data/spec/lib/appsignal/probes_spec.rb +4 -6
- data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +41 -122
- data/spec/lib/appsignal/rack_spec.rb +180 -0
- data/spec/lib/appsignal/transaction_spec.rb +96 -92
- data/spec/spec_helper.rb +6 -7
- data/spec/support/helpers/api_request_helper.rb +40 -0
- data/spec/support/helpers/config_helpers.rb +2 -1
- data/spec/support/helpers/dependency_helper.rb +5 -0
- data/spec/support/matchers/contains_log.rb +10 -3
- data/spec/support/mocks/hash_like.rb +10 -0
- data/spec/support/mocks/puma_mock.rb +43 -0
- data/spec/support/testing.rb +9 -0
- metadata +8 -3
- data/gemfiles/que.gemfile +0 -5
@@ -2,29 +2,29 @@ describe Appsignal::CheckIn::Scheduler do
|
|
2
2
|
include WaitForHelper
|
3
3
|
include TakeAtMostHelper
|
4
4
|
|
5
|
-
let(:
|
5
|
+
let(:log_stream) { std_stream }
|
6
|
+
let(:logs) { log_contents(log_stream) }
|
7
|
+
let(:appsignal_options) { {} }
|
8
|
+
let(:scheduler) { Appsignal::CheckIn.scheduler }
|
6
9
|
|
7
10
|
before do
|
8
|
-
|
9
|
-
allow(transmitter).to receive(:transmit).and_return(Net::HTTPSuccess.new("1.1", 200, "OK"))
|
10
|
-
allow(Appsignal::CheckIn).to receive(:transmitter).and_return(transmitter)
|
11
|
-
allow(Appsignal::CheckIn).to receive(:scheduler).and_return(subject)
|
11
|
+
start_agent(:options => appsignal_options, :internal_logger => test_logger(log_stream))
|
12
12
|
# Shorten debounce intervals to make the tests run faster.
|
13
13
|
stub_const("Appsignal::CheckIn::Scheduler::INITIAL_DEBOUNCE_SECONDS", 0.1)
|
14
14
|
stub_const("Appsignal::CheckIn::Scheduler::BETWEEN_TRANSMISSIONS_DEBOUNCE_SECONDS", 0.1)
|
15
15
|
end
|
16
16
|
|
17
17
|
after do
|
18
|
-
|
18
|
+
scheduler.stop
|
19
19
|
end
|
20
20
|
|
21
21
|
describe "when no event is sent" do
|
22
22
|
it "does not start a thread" do
|
23
|
-
expect(
|
23
|
+
expect(scheduler.thread).to be_nil
|
24
24
|
end
|
25
25
|
|
26
26
|
it "does not schedule a debounce" do
|
27
|
-
expect(
|
27
|
+
expect(scheduler.waker).to be_nil
|
28
28
|
end
|
29
29
|
|
30
30
|
it "can be stopped" do
|
@@ -35,7 +35,7 @@ describe Appsignal::CheckIn::Scheduler do
|
|
35
35
|
stub_const("Appsignal::CheckIn::Scheduler::BETWEEN_TRANSMISSIONS_DEBOUNCE_SECONDS", 10)
|
36
36
|
|
37
37
|
take_at_most(0.1) do
|
38
|
-
expect {
|
38
|
+
expect { scheduler.stop }.not_to raise_error
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -47,52 +47,63 @@ describe Appsignal::CheckIn::Scheduler do
|
|
47
47
|
stub_const("Appsignal::CheckIn::Scheduler::BETWEEN_TRANSMISSIONS_DEBOUNCE_SECONDS", 10)
|
48
48
|
|
49
49
|
take_at_most(0.1) do
|
50
|
-
expect {
|
51
|
-
expect {
|
50
|
+
expect { scheduler.stop }.not_to raise_error
|
51
|
+
expect { scheduler.stop }.not_to raise_error
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
55
|
it "closes the queue when stopped" do
|
56
|
-
|
57
|
-
expect(
|
56
|
+
scheduler.stop
|
57
|
+
expect(scheduler.queue.closed?).to be(true)
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
61
|
describe "when an event is sent" do
|
62
62
|
it "starts a thread" do
|
63
|
+
stub_check_in_request(
|
64
|
+
:events => [
|
65
|
+
"identifier" => "test",
|
66
|
+
"kind" => "finish",
|
67
|
+
"check_in_type" => "cron"
|
68
|
+
]
|
69
|
+
)
|
63
70
|
Appsignal::CheckIn.cron("test")
|
64
|
-
expect(
|
71
|
+
expect(scheduler.thread).to be_a(Thread)
|
65
72
|
end
|
66
73
|
|
67
74
|
it "schedules a debounce" do
|
75
|
+
stub_check_in_request(
|
76
|
+
:events => [
|
77
|
+
"identifier" => "test",
|
78
|
+
"kind" => "finish",
|
79
|
+
"check_in_type" => "cron"
|
80
|
+
]
|
81
|
+
)
|
68
82
|
Appsignal::CheckIn.cron("test")
|
69
|
-
expect(
|
83
|
+
expect(scheduler.waker).to be_a(Thread)
|
70
84
|
end
|
71
85
|
|
72
86
|
it "schedules the event to be transmitted" do
|
73
|
-
|
74
|
-
:
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
message.include?("Scheduling cron check-in `test` finish event")
|
81
|
-
end)
|
87
|
+
stub_check_in_request(
|
88
|
+
:events => [
|
89
|
+
"identifier" => "test",
|
90
|
+
"kind" => "finish",
|
91
|
+
"check_in_type" => "cron"
|
92
|
+
]
|
93
|
+
)
|
82
94
|
|
83
|
-
expect(
|
95
|
+
expect(scheduler.events).to be_empty
|
84
96
|
|
85
97
|
Appsignal::CheckIn.cron("test")
|
86
98
|
|
87
|
-
expect(
|
99
|
+
expect(scheduler.events).not_to be_empty
|
88
100
|
|
89
|
-
|
90
|
-
message.include?("Transmitted cron check-in `test` finish event")
|
91
|
-
end)
|
101
|
+
wait_for("the event to be transmitted") { scheduler.transmitted == 1 }
|
92
102
|
|
93
|
-
|
103
|
+
expect(scheduler.events).to be_empty
|
94
104
|
|
95
|
-
expect(
|
105
|
+
expect(logs).to contains_log(:debug, "Scheduling cron check-in `test` finish event")
|
106
|
+
expect(logs).to contains_log(:debug, "Transmitted cron check-in `test` finish event")
|
96
107
|
end
|
97
108
|
|
98
109
|
it "waits for the event to be transmitted when stopped" do
|
@@ -103,33 +114,30 @@ describe Appsignal::CheckIn::Scheduler do
|
|
103
114
|
stub_const("Appsignal::CheckIn::Scheduler::INITIAL_DEBOUNCE_SECONDS", 10)
|
104
115
|
stub_const("Appsignal::CheckIn::Scheduler::BETWEEN_TRANSMISSIONS_DEBOUNCE_SECONDS", 10)
|
105
116
|
|
106
|
-
|
107
|
-
:
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
message.include?("Scheduling cron check-in `test` finish event")
|
114
|
-
end)
|
117
|
+
stub_check_in_request(
|
118
|
+
:events => [
|
119
|
+
"identifier" => "test",
|
120
|
+
"kind" => "finish",
|
121
|
+
"check_in_type" => "cron"
|
122
|
+
]
|
123
|
+
)
|
115
124
|
|
116
125
|
Appsignal::CheckIn.cron("test")
|
117
126
|
|
118
|
-
expect(
|
119
|
-
message.include?("Transmitted cron check-in `test` finish event")
|
120
|
-
end)
|
121
|
-
|
122
|
-
expect(subject.events).not_to be_empty
|
127
|
+
expect(scheduler.events).not_to be_empty
|
123
128
|
|
124
129
|
take_at_most(0.1) do
|
125
|
-
expect {
|
130
|
+
expect { scheduler.stop }.not_to raise_error
|
126
131
|
end
|
127
132
|
|
128
133
|
# Check that the thread wasn't killed before the transmission was
|
129
134
|
# completed.
|
130
|
-
expect(
|
135
|
+
expect(scheduler.transmitted).to eq(1)
|
136
|
+
|
137
|
+
expect(scheduler.events).to be_empty
|
131
138
|
|
132
|
-
expect(
|
139
|
+
expect(logs).to contains_log(:debug, "Scheduling cron check-in `test` finish event")
|
140
|
+
expect(logs).to contains_log(:debug, "Transmitted cron check-in `test` finish event")
|
133
141
|
end
|
134
142
|
|
135
143
|
it "can be stopped more than once" do
|
@@ -140,59 +148,87 @@ describe Appsignal::CheckIn::Scheduler do
|
|
140
148
|
stub_const("Appsignal::CheckIn::Scheduler::INITIAL_DEBOUNCE_SECONDS", 10)
|
141
149
|
stub_const("Appsignal::CheckIn::Scheduler::BETWEEN_TRANSMISSIONS_DEBOUNCE_SECONDS", 10)
|
142
150
|
|
151
|
+
stub_check_in_request(
|
152
|
+
:events => [
|
153
|
+
"identifier" => "test",
|
154
|
+
"kind" => "finish",
|
155
|
+
"check_in_type" => "cron"
|
156
|
+
]
|
157
|
+
)
|
143
158
|
Appsignal::CheckIn.cron("test")
|
144
159
|
take_at_most(0.1) do
|
145
|
-
expect {
|
160
|
+
expect { scheduler.stop }.not_to raise_error
|
146
161
|
end
|
147
162
|
|
148
163
|
# Check that the thread wasn't killed before the transmission was
|
149
164
|
# completed.
|
150
|
-
expect(
|
165
|
+
expect(scheduler.transmitted).to eq(1)
|
151
166
|
|
152
167
|
take_at_most(0.1) do
|
153
|
-
expect {
|
168
|
+
expect { scheduler.stop }.not_to raise_error
|
154
169
|
end
|
155
170
|
end
|
156
171
|
|
157
172
|
it "closes the queue when stopped" do
|
173
|
+
stub_check_in_request(
|
174
|
+
:events => [
|
175
|
+
"identifier" => "test",
|
176
|
+
"kind" => "finish",
|
177
|
+
"check_in_type" => "cron"
|
178
|
+
]
|
179
|
+
)
|
158
180
|
Appsignal::CheckIn.cron("test")
|
159
|
-
|
160
|
-
expect(
|
181
|
+
scheduler.stop
|
182
|
+
expect(scheduler.queue.closed?).to be(true)
|
161
183
|
end
|
162
184
|
|
163
185
|
it "kills the thread when stopped" do
|
186
|
+
stub_check_in_request(
|
187
|
+
:events => [
|
188
|
+
"identifier" => "test",
|
189
|
+
"kind" => "finish",
|
190
|
+
"check_in_type" => "cron"
|
191
|
+
]
|
192
|
+
)
|
164
193
|
Appsignal::CheckIn.cron("test")
|
165
|
-
|
166
|
-
expect(
|
194
|
+
scheduler.stop
|
195
|
+
expect(scheduler.thread.alive?).to be(false)
|
167
196
|
end
|
168
197
|
|
169
198
|
it "unschedules the debounce when stopped" do
|
199
|
+
stub_check_in_request(
|
200
|
+
:events => [
|
201
|
+
"identifier" => "test",
|
202
|
+
"kind" => "finish",
|
203
|
+
"check_in_type" => "cron"
|
204
|
+
]
|
205
|
+
)
|
170
206
|
Appsignal::CheckIn.cron("test")
|
171
|
-
waker =
|
172
|
-
|
207
|
+
waker = scheduler.waker
|
208
|
+
scheduler.stop
|
173
209
|
expect(waker.alive?).to be(false)
|
174
|
-
expect(
|
210
|
+
expect(scheduler.waker).to be_nil
|
175
211
|
end
|
176
212
|
end
|
177
213
|
|
178
214
|
describe "when many events are sent" do
|
179
215
|
describe "within the short debounce interval" do
|
180
216
|
it "transmits all events at once" do
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
217
|
+
["first", "second", "third"].map do |identifier|
|
218
|
+
stub_check_in_request(
|
219
|
+
:events => [
|
220
|
+
"identifier" => identifier,
|
221
|
+
"kind" => "finish",
|
222
|
+
"check_in_type" => "cron"
|
223
|
+
]
|
224
|
+
)
|
225
|
+
end
|
190
226
|
|
191
227
|
Appsignal::CheckIn.cron("first")
|
192
228
|
Appsignal::CheckIn.cron("second")
|
193
229
|
Appsignal::CheckIn.cron("third")
|
194
230
|
|
195
|
-
wait_for("the events to be transmitted") {
|
231
|
+
wait_for("the events to be transmitted") { scheduler.transmitted == 1 }
|
196
232
|
end
|
197
233
|
|
198
234
|
it "transmits all events at once when stopped" do
|
@@ -202,42 +238,58 @@ describe Appsignal::CheckIn::Scheduler do
|
|
202
238
|
# stopped.
|
203
239
|
stub_const("Appsignal::CheckIn::Scheduler::INITIAL_DEBOUNCE_SECONDS", 10)
|
204
240
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
241
|
+
["first", "second", "third"].map do |identifier|
|
242
|
+
stub_check_in_request(
|
243
|
+
:events => [
|
244
|
+
"identifier" => identifier,
|
245
|
+
"kind" => "finish",
|
246
|
+
"check_in_type" => "cron"
|
247
|
+
]
|
248
|
+
)
|
249
|
+
end
|
214
250
|
|
215
251
|
Appsignal::CheckIn.cron("first")
|
216
252
|
Appsignal::CheckIn.cron("second")
|
217
253
|
Appsignal::CheckIn.cron("third")
|
218
254
|
|
219
|
-
|
255
|
+
scheduler.stop
|
220
256
|
|
221
|
-
wait_for("the events to be transmitted") {
|
257
|
+
wait_for("the events to be transmitted") { scheduler.transmitted == 1 }
|
222
258
|
end
|
223
259
|
end
|
224
260
|
|
225
261
|
describe "further apart than the short debounce interval" do
|
226
262
|
it "transmits the first event and enqueues future events" do
|
227
|
-
|
228
|
-
:
|
229
|
-
|
230
|
-
|
231
|
-
|
263
|
+
stub_check_in_request(
|
264
|
+
:events => [
|
265
|
+
"identifier" => "first",
|
266
|
+
"kind" => "finish",
|
267
|
+
"check_in_type" => "cron"
|
268
|
+
]
|
269
|
+
)
|
232
270
|
|
233
271
|
Appsignal::CheckIn.cron("first")
|
234
272
|
|
235
|
-
wait_for("the first event to be transmitted") {
|
236
|
-
|
273
|
+
wait_for("the first event to be transmitted") { scheduler.transmitted == 1 }
|
274
|
+
|
275
|
+
stub_check_in_request(
|
276
|
+
:events => [
|
277
|
+
{
|
278
|
+
"identifier" => "second",
|
279
|
+
"kind" => "finish",
|
280
|
+
"check_in_type" => "cron"
|
281
|
+
},
|
282
|
+
{
|
283
|
+
"identifier" => "third",
|
284
|
+
"kind" => "finish",
|
285
|
+
"check_in_type" => "cron"
|
286
|
+
}
|
287
|
+
]
|
288
|
+
)
|
237
289
|
Appsignal::CheckIn.cron("second")
|
238
290
|
Appsignal::CheckIn.cron("third")
|
239
291
|
|
240
|
-
expect(
|
292
|
+
expect(scheduler.events).to match(["second", "third"].map do |identifier|
|
241
293
|
hash_including({
|
242
294
|
:identifier => identifier,
|
243
295
|
:check_in_type => "cron",
|
@@ -247,51 +299,46 @@ describe Appsignal::CheckIn::Scheduler do
|
|
247
299
|
end
|
248
300
|
|
249
301
|
it "transmits the other events after the debounce interval" do
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
302
|
+
stub_check_in_request(
|
303
|
+
:events => [
|
304
|
+
"identifier" => "first",
|
305
|
+
"kind" => "finish",
|
306
|
+
"check_in_type" => "cron"
|
307
|
+
]
|
308
|
+
)
|
256
309
|
Appsignal::CheckIn.cron("first")
|
257
310
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
311
|
+
wait_for("the first event to be transmitted") { scheduler.transmitted == 1 }
|
312
|
+
|
313
|
+
stub_check_in_request(
|
314
|
+
:events => [
|
315
|
+
{
|
316
|
+
"identifier" => "second",
|
317
|
+
"kind" => "finish",
|
318
|
+
"check_in_type" => "cron"
|
319
|
+
},
|
320
|
+
{
|
321
|
+
"identifier" => "third",
|
322
|
+
"kind" => "finish",
|
323
|
+
"check_in_type" => "cron"
|
324
|
+
}
|
325
|
+
]
|
272
326
|
)
|
273
327
|
|
274
|
-
expect(Appsignal.internal_logger).to receive(:debug).with(satisfy do |message|
|
275
|
-
message.include?("Scheduling cron check-in `second` finish event")
|
276
|
-
end)
|
277
|
-
|
278
328
|
Appsignal::CheckIn.cron("second")
|
279
|
-
|
280
|
-
expect(Appsignal.internal_logger).to receive(:debug).with(satisfy do |message|
|
281
|
-
message.include?("Scheduling cron check-in `third` finish event")
|
282
|
-
end)
|
283
|
-
|
284
329
|
Appsignal::CheckIn.cron("third")
|
285
330
|
|
286
|
-
expect(
|
331
|
+
expect(scheduler.events).to_not be_empty
|
287
332
|
|
288
|
-
|
289
|
-
"Transmitted 2 check-in events"
|
290
|
-
)
|
333
|
+
wait_for("the other events to be transmitted") { scheduler.transmitted == 2 }
|
291
334
|
|
292
|
-
|
335
|
+
expect(scheduler.events).to be_empty
|
293
336
|
|
294
|
-
expect(
|
337
|
+
expect(logs).to contains_log(:debug, "Scheduling cron check-in `first` finish event")
|
338
|
+
expect(logs).to contains_log(:debug, "Transmitted cron check-in `first` finish event")
|
339
|
+
expect(logs).to contains_log(:debug, "Scheduling cron check-in `second` finish event")
|
340
|
+
expect(logs).to contains_log(:debug, "Scheduling cron check-in `third` finish event")
|
341
|
+
expect(logs).to contains_log(:debug, "Transmitted 2 check-in events")
|
295
342
|
end
|
296
343
|
|
297
344
|
it "transmits the other events when stopped" do
|
@@ -301,53 +348,48 @@ describe Appsignal::CheckIn::Scheduler do
|
|
301
348
|
# immediately when the scheduler is stopped.
|
302
349
|
stub_const("Appsignal::CheckIn::Scheduler::BETWEEN_TRANSMISSIONS_DEBOUNCE_SECONDS", 10)
|
303
350
|
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
351
|
+
stub_check_in_request(
|
352
|
+
:events => [
|
353
|
+
"identifier" => "first",
|
354
|
+
"kind" => "finish",
|
355
|
+
"check_in_type" => "cron"
|
356
|
+
]
|
357
|
+
)
|
310
358
|
Appsignal::CheckIn.cron("first")
|
311
359
|
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
360
|
+
wait_for("the event to be transmitted") { scheduler.transmitted == 1 }
|
361
|
+
|
362
|
+
stub_check_in_request(
|
363
|
+
:events => [
|
364
|
+
{
|
365
|
+
"identifier" => "second",
|
366
|
+
"kind" => "finish",
|
367
|
+
"check_in_type" => "cron"
|
368
|
+
},
|
369
|
+
{
|
370
|
+
"identifier" => "third",
|
371
|
+
"kind" => "finish",
|
372
|
+
"check_in_type" => "cron"
|
373
|
+
}
|
374
|
+
]
|
326
375
|
)
|
327
376
|
|
328
|
-
expect(Appsignal.internal_logger).to receive(:debug).with(satisfy do |message|
|
329
|
-
message.include?("Scheduling cron check-in `second` finish event")
|
330
|
-
end)
|
331
|
-
|
332
377
|
Appsignal::CheckIn.cron("second")
|
333
|
-
|
334
|
-
expect(Appsignal.internal_logger).to receive(:debug).with(satisfy do |message|
|
335
|
-
message.include?("Scheduling cron check-in `third` finish event")
|
336
|
-
end)
|
337
|
-
|
338
378
|
Appsignal::CheckIn.cron("third")
|
339
379
|
|
340
|
-
expect(
|
380
|
+
expect(scheduler.events).to_not be_empty
|
341
381
|
|
342
|
-
|
343
|
-
"Transmitted 2 check-in events"
|
344
|
-
)
|
382
|
+
scheduler.stop
|
345
383
|
|
346
|
-
|
384
|
+
wait_for("the other events to be transmitted") { scheduler.transmitted == 2 }
|
347
385
|
|
348
|
-
|
386
|
+
expect(scheduler.events).to be_empty
|
349
387
|
|
350
|
-
expect(
|
388
|
+
expect(logs).to contains_log(:debug, "Scheduling cron check-in `first` finish event")
|
389
|
+
expect(logs).to contains_log(:debug, "Transmitted cron check-in `first` finish event")
|
390
|
+
expect(logs).to contains_log(:debug, "Scheduling cron check-in `second` finish event")
|
391
|
+
expect(logs).to contains_log(:debug, "Scheduling cron check-in `third` finish event")
|
392
|
+
expect(logs).to contains_log(:debug, "Transmitted 2 check-in events")
|
351
393
|
end
|
352
394
|
end
|
353
395
|
end
|
@@ -358,127 +400,158 @@ describe Appsignal::CheckIn::Scheduler do
|
|
358
400
|
# `.cron` helper would use a different digest for each invocation.
|
359
401
|
cron = Appsignal::CheckIn::Cron.new(:identifier => "test")
|
360
402
|
|
361
|
-
|
362
|
-
:
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
expect(Appsignal.internal_logger).to receive(:debug).with(
|
368
|
-
"Scheduling cron check-in `test` start event (digest #{cron.digest}) to be transmitted"
|
403
|
+
stub_check_in_request(
|
404
|
+
:events => [
|
405
|
+
"identifier" => "test",
|
406
|
+
"kind" => "start",
|
407
|
+
"check_in_type" => "cron"
|
408
|
+
]
|
369
409
|
)
|
370
410
|
|
371
411
|
cron.start
|
412
|
+
cron.start
|
413
|
+
|
414
|
+
wait_for("the event to be transmitted") { scheduler.transmitted == 1 }
|
372
415
|
|
373
|
-
expect(
|
416
|
+
expect(logs).to contains_log(
|
417
|
+
:debug,
|
374
418
|
"Scheduling cron check-in `test` start event (digest #{cron.digest}) to be transmitted"
|
375
419
|
)
|
376
|
-
|
377
|
-
|
420
|
+
expect(logs).to contains_log(
|
421
|
+
:debug,
|
422
|
+
"Scheduling cron check-in `test` start event (digest #{cron.digest}) to be transmitted"
|
423
|
+
)
|
424
|
+
expect(logs).to contains_log(
|
425
|
+
:debug,
|
378
426
|
"Replacing previously scheduled cron check-in `test` start event (digest #{cron.digest})"
|
379
427
|
)
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
expect(Appsignal.internal_logger).to receive(:debug).with(
|
428
|
+
expect(logs).to contains_log(
|
429
|
+
:debug,
|
384
430
|
"Transmitted cron check-in `test` start event (digest #{cron.digest})"
|
385
431
|
)
|
386
|
-
|
387
|
-
wait_for("the event to be transmitted") { subject.transmitted == 1 }
|
388
432
|
end
|
389
433
|
end
|
390
434
|
|
391
435
|
describe "when the scheduler is stopped" do
|
392
436
|
it "does not schedule any events to be transmitted" do
|
393
|
-
|
394
|
-
|
395
|
-
subject.stop
|
396
|
-
|
397
|
-
expect(Appsignal.internal_logger).to receive(:debug).with(satisfy do |message|
|
398
|
-
message.include?("Cannot transmit cron check-in `test` finish event") &&
|
399
|
-
message.include?("AppSignal is stopped")
|
400
|
-
end)
|
437
|
+
scheduler.stop
|
401
438
|
|
402
439
|
Appsignal::CheckIn.cron("test")
|
403
440
|
|
404
|
-
expect(
|
441
|
+
expect(scheduler.events).to be_empty
|
442
|
+
|
443
|
+
expect(logs).to contains_log(
|
444
|
+
:debug,
|
445
|
+
/Cannot transmit cron check-in `test` finish event .+: AppSignal is stopped/
|
446
|
+
)
|
405
447
|
end
|
406
448
|
end
|
407
449
|
|
408
450
|
describe "when AppSignal is not active" do
|
409
|
-
|
410
|
-
allow(Appsignal).to receive(:active?).and_return(false)
|
451
|
+
let(:appsignal_options) { { :active => false } }
|
411
452
|
|
412
|
-
|
413
|
-
|
414
|
-
expect(Appsignal.internal_logger).to receive(:debug).with(satisfy do |message|
|
415
|
-
message.include?("Cannot transmit cron check-in `test` finish event") &&
|
416
|
-
message.include?("AppSignal is not active")
|
417
|
-
end)
|
453
|
+
it "does not schedule any events to be transmitted" do
|
454
|
+
scheduler.stop
|
418
455
|
|
419
456
|
Appsignal::CheckIn.cron("test")
|
420
457
|
|
421
|
-
expect(
|
458
|
+
expect(scheduler.events).to be_empty
|
459
|
+
|
460
|
+
expect(logs).to contains_log(
|
461
|
+
:debug,
|
462
|
+
/Cannot transmit cron check-in `test` finish event .+: AppSignal is not active/
|
463
|
+
)
|
422
464
|
end
|
423
465
|
end
|
424
466
|
|
425
467
|
describe "when transmitting returns a non-success response code" do
|
426
468
|
it "logs the error and continues" do
|
427
|
-
|
428
|
-
|
469
|
+
stub_check_in_request(
|
470
|
+
:events => [
|
471
|
+
"identifier" => "first",
|
472
|
+
"kind" => "start",
|
473
|
+
"check_in_type" => "cron"
|
474
|
+
],
|
475
|
+
:response => { :status => 404 }
|
476
|
+
)
|
477
|
+
stub_check_in_request(
|
478
|
+
:events => [
|
479
|
+
"identifier" => "first",
|
480
|
+
"kind" => "finish",
|
481
|
+
"check_in_type" => "cron"
|
482
|
+
],
|
483
|
+
:response => { :status => 404 }
|
429
484
|
)
|
430
485
|
|
431
486
|
Appsignal::CheckIn.cron("first")
|
432
487
|
|
433
|
-
|
434
|
-
message.include?("Failed to transmit cron check-in `first` finish event") &&
|
435
|
-
message.include?("404 status code")
|
436
|
-
end)
|
437
|
-
|
438
|
-
wait_for("the first event to be transmitted") { subject.transmitted == 1 }
|
488
|
+
wait_for("the first event to be transmitted") { scheduler.transmitted == 1 }
|
439
489
|
|
440
|
-
|
441
|
-
|
490
|
+
stub_check_in_request(
|
491
|
+
:events => [
|
492
|
+
"identifier" => "second",
|
493
|
+
"kind" => "start",
|
494
|
+
"check_in_type" => "cron"
|
495
|
+
]
|
496
|
+
)
|
497
|
+
stub_check_in_request(
|
498
|
+
:events => [
|
499
|
+
"identifier" => "second",
|
500
|
+
"kind" => "finish",
|
501
|
+
"check_in_type" => "cron"
|
502
|
+
]
|
442
503
|
)
|
443
504
|
|
444
505
|
Appsignal::CheckIn.cron("second")
|
445
506
|
|
446
|
-
|
447
|
-
|
448
|
-
expect(Appsignal.internal_logger).to receive(:debug).with(satisfy do |message|
|
449
|
-
message.include?("Transmitted cron check-in `second` finish event")
|
450
|
-
end)
|
507
|
+
wait_for("the second event to be transmitted") { scheduler.transmitted == 2 }
|
451
508
|
|
452
|
-
|
509
|
+
expect(logs).to contains_log(
|
510
|
+
:error,
|
511
|
+
/Failed to transmit cron check-in `first` finish event .+: 404 status code/
|
512
|
+
)
|
513
|
+
expect(logs).to contains_log(
|
514
|
+
:debug,
|
515
|
+
"Transmitted cron check-in `second` finish event"
|
516
|
+
)
|
453
517
|
end
|
454
518
|
end
|
455
519
|
|
456
520
|
describe "when transmitting throws an error" do
|
457
521
|
it "logs the error and continues" do
|
458
|
-
|
522
|
+
stub_check_in_request(
|
523
|
+
:events => [
|
524
|
+
"identifier" => "first",
|
525
|
+
"kind" => "finish",
|
526
|
+
"check_in_type" => "cron"
|
527
|
+
],
|
528
|
+
:response => ExampleStandardError.new("Something went wrong")
|
529
|
+
)
|
459
530
|
|
460
531
|
Appsignal::CheckIn.cron("first")
|
461
532
|
|
462
|
-
|
463
|
-
message.include?("Failed to transmit cron check-in `first` finish event") &&
|
464
|
-
message.include?("Something went wrong")
|
465
|
-
end)
|
533
|
+
wait_for("the first event to be transmitted") { scheduler.transmitted == 1 }
|
466
534
|
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
535
|
+
stub_check_in_request(
|
536
|
+
:events => [
|
537
|
+
"identifier" => "second",
|
538
|
+
"kind" => "finish",
|
539
|
+
"check_in_type" => "cron"
|
540
|
+
]
|
471
541
|
)
|
472
542
|
|
473
543
|
Appsignal::CheckIn.cron("second")
|
474
544
|
|
475
|
-
|
476
|
-
|
477
|
-
expect(Appsignal.internal_logger).to receive(:debug).with(satisfy do |message|
|
478
|
-
message.include?("Transmitted cron check-in `second` finish event")
|
479
|
-
end)
|
545
|
+
wait_for("the second event to be transmitted") { scheduler.transmitted == 2 }
|
480
546
|
|
481
|
-
|
547
|
+
expect(logs).to contains_log(
|
548
|
+
:error,
|
549
|
+
/Failed to transmit cron check-in `first` finish event .+: ExampleStandardError: Something went wrong/ # rubocop:disable Layout/LineLength
|
550
|
+
)
|
551
|
+
expect(logs).to contains_log(
|
552
|
+
:debug,
|
553
|
+
"Transmitted cron check-in `second` finish event"
|
554
|
+
)
|
482
555
|
end
|
483
556
|
end
|
484
557
|
end
|