appsignal 4.0.5-java → 4.0.6-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,29 +5,26 @@ describe Appsignal::CheckIn::Scheduler do
5
5
  let(:log_stream) { std_stream }
6
6
  let(:logs) { log_contents(log_stream) }
7
7
  let(:appsignal_options) { {} }
8
- let(:transmitter) { Appsignal::Transmitter.new("http://checkin-endpoint.invalid") }
8
+ let(:scheduler) { Appsignal::CheckIn.scheduler }
9
9
 
10
10
  before do
11
11
  start_agent(:options => appsignal_options, :internal_logger => test_logger(log_stream))
12
- allow(transmitter).to receive(:transmit).and_return(Net::HTTPSuccess.new("1.1", 200, "OK"))
13
- allow(Appsignal::CheckIn).to receive(:transmitter).and_return(transmitter)
14
- allow(Appsignal::CheckIn).to receive(:scheduler).and_return(subject)
15
12
  # Shorten debounce intervals to make the tests run faster.
16
13
  stub_const("Appsignal::CheckIn::Scheduler::INITIAL_DEBOUNCE_SECONDS", 0.1)
17
14
  stub_const("Appsignal::CheckIn::Scheduler::BETWEEN_TRANSMISSIONS_DEBOUNCE_SECONDS", 0.1)
18
15
  end
19
16
 
20
17
  after do
21
- subject.stop
18
+ scheduler.stop
22
19
  end
23
20
 
24
21
  describe "when no event is sent" do
25
22
  it "does not start a thread" do
26
- expect(subject.thread).to be_nil
23
+ expect(scheduler.thread).to be_nil
27
24
  end
28
25
 
29
26
  it "does not schedule a debounce" do
30
- expect(subject.waker).to be_nil
27
+ expect(scheduler.waker).to be_nil
31
28
  end
32
29
 
33
30
  it "can be stopped" do
@@ -38,7 +35,7 @@ describe Appsignal::CheckIn::Scheduler do
38
35
  stub_const("Appsignal::CheckIn::Scheduler::BETWEEN_TRANSMISSIONS_DEBOUNCE_SECONDS", 10)
39
36
 
40
37
  take_at_most(0.1) do
41
- expect { subject.stop }.not_to raise_error
38
+ expect { scheduler.stop }.not_to raise_error
42
39
  end
43
40
  end
44
41
 
@@ -50,44 +47,60 @@ describe Appsignal::CheckIn::Scheduler do
50
47
  stub_const("Appsignal::CheckIn::Scheduler::BETWEEN_TRANSMISSIONS_DEBOUNCE_SECONDS", 10)
51
48
 
52
49
  take_at_most(0.1) do
53
- expect { subject.stop }.not_to raise_error
54
- expect { subject.stop }.not_to raise_error
50
+ expect { scheduler.stop }.not_to raise_error
51
+ expect { scheduler.stop }.not_to raise_error
55
52
  end
56
53
  end
57
54
 
58
55
  it "closes the queue when stopped" do
59
- subject.stop
60
- expect(subject.queue.closed?).to be(true)
56
+ scheduler.stop
57
+ expect(scheduler.queue.closed?).to be(true)
61
58
  end
62
59
  end
63
60
 
64
61
  describe "when an event is sent" do
65
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
+ )
66
70
  Appsignal::CheckIn.cron("test")
67
- expect(subject.thread).to be_a(Thread)
71
+ expect(scheduler.thread).to be_a(Thread)
68
72
  end
69
73
 
70
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
+ )
71
82
  Appsignal::CheckIn.cron("test")
72
- expect(subject.waker).to be_a(Thread)
83
+ expect(scheduler.waker).to be_a(Thread)
73
84
  end
74
85
 
75
86
  it "schedules the event to be transmitted" do
76
- expect(transmitter).to receive(:transmit).with([hash_including(
77
- :identifier => "test",
78
- :check_in_type => "cron",
79
- :kind => "finish"
80
- )], :format => :ndjson)
87
+ stub_check_in_request(
88
+ :events => [
89
+ "identifier" => "test",
90
+ "kind" => "finish",
91
+ "check_in_type" => "cron"
92
+ ]
93
+ )
81
94
 
82
- expect(subject.events).to be_empty
95
+ expect(scheduler.events).to be_empty
83
96
 
84
97
  Appsignal::CheckIn.cron("test")
85
98
 
86
- expect(subject.events).not_to be_empty
99
+ expect(scheduler.events).not_to be_empty
87
100
 
88
- wait_for("the event to be transmitted") { subject.transmitted == 1 }
101
+ wait_for("the event to be transmitted") { scheduler.transmitted == 1 }
89
102
 
90
- expect(subject.events).to be_empty
103
+ expect(scheduler.events).to be_empty
91
104
 
92
105
  expect(logs).to contains_log(:debug, "Scheduling cron check-in `test` finish event")
93
106
  expect(logs).to contains_log(:debug, "Transmitted cron check-in `test` finish event")
@@ -101,25 +114,27 @@ describe Appsignal::CheckIn::Scheduler do
101
114
  stub_const("Appsignal::CheckIn::Scheduler::INITIAL_DEBOUNCE_SECONDS", 10)
102
115
  stub_const("Appsignal::CheckIn::Scheduler::BETWEEN_TRANSMISSIONS_DEBOUNCE_SECONDS", 10)
103
116
 
104
- expect(transmitter).to receive(:transmit).with([hash_including(
105
- :identifier => "test",
106
- :check_in_type => "cron",
107
- :kind => "finish"
108
- )], :format => :ndjson)
117
+ stub_check_in_request(
118
+ :events => [
119
+ "identifier" => "test",
120
+ "kind" => "finish",
121
+ "check_in_type" => "cron"
122
+ ]
123
+ )
109
124
 
110
125
  Appsignal::CheckIn.cron("test")
111
126
 
112
- expect(subject.events).not_to be_empty
127
+ expect(scheduler.events).not_to be_empty
113
128
 
114
129
  take_at_most(0.1) do
115
- expect { subject.stop }.not_to raise_error
130
+ expect { scheduler.stop }.not_to raise_error
116
131
  end
117
132
 
118
133
  # Check that the thread wasn't killed before the transmission was
119
134
  # completed.
120
- expect(subject.transmitted).to eq(1)
135
+ expect(scheduler.transmitted).to eq(1)
121
136
 
122
- expect(subject.events).to be_empty
137
+ expect(scheduler.events).to be_empty
123
138
 
124
139
  expect(logs).to contains_log(:debug, "Scheduling cron check-in `test` finish event")
125
140
  expect(logs).to contains_log(:debug, "Transmitted cron check-in `test` finish event")
@@ -133,59 +148,87 @@ describe Appsignal::CheckIn::Scheduler do
133
148
  stub_const("Appsignal::CheckIn::Scheduler::INITIAL_DEBOUNCE_SECONDS", 10)
134
149
  stub_const("Appsignal::CheckIn::Scheduler::BETWEEN_TRANSMISSIONS_DEBOUNCE_SECONDS", 10)
135
150
 
151
+ stub_check_in_request(
152
+ :events => [
153
+ "identifier" => "test",
154
+ "kind" => "finish",
155
+ "check_in_type" => "cron"
156
+ ]
157
+ )
136
158
  Appsignal::CheckIn.cron("test")
137
159
  take_at_most(0.1) do
138
- expect { subject.stop }.not_to raise_error
160
+ expect { scheduler.stop }.not_to raise_error
139
161
  end
140
162
 
141
163
  # Check that the thread wasn't killed before the transmission was
142
164
  # completed.
143
- expect(subject.transmitted).to eq(1)
165
+ expect(scheduler.transmitted).to eq(1)
144
166
 
145
167
  take_at_most(0.1) do
146
- expect { subject.stop }.not_to raise_error
168
+ expect { scheduler.stop }.not_to raise_error
147
169
  end
148
170
  end
149
171
 
150
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
+ )
151
180
  Appsignal::CheckIn.cron("test")
152
- subject.stop
153
- expect(subject.queue.closed?).to be(true)
181
+ scheduler.stop
182
+ expect(scheduler.queue.closed?).to be(true)
154
183
  end
155
184
 
156
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
+ )
157
193
  Appsignal::CheckIn.cron("test")
158
- subject.stop
159
- expect(subject.thread.alive?).to be(false)
194
+ scheduler.stop
195
+ expect(scheduler.thread.alive?).to be(false)
160
196
  end
161
197
 
162
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
+ )
163
206
  Appsignal::CheckIn.cron("test")
164
- waker = subject.waker
165
- subject.stop
207
+ waker = scheduler.waker
208
+ scheduler.stop
166
209
  expect(waker.alive?).to be(false)
167
- expect(subject.waker).to be_nil
210
+ expect(scheduler.waker).to be_nil
168
211
  end
169
212
  end
170
213
 
171
214
  describe "when many events are sent" do
172
215
  describe "within the short debounce interval" do
173
216
  it "transmits all events at once" do
174
- expect(transmitter).to receive(:transmit).with(
175
- ["first", "second", "third"].map do |identifier|
176
- hash_including(
177
- :identifier => identifier,
178
- :check_in_type => "cron",
179
- :kind => "finish"
180
- )
181
- end, :format => :ndjson
182
- )
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
183
226
 
184
227
  Appsignal::CheckIn.cron("first")
185
228
  Appsignal::CheckIn.cron("second")
186
229
  Appsignal::CheckIn.cron("third")
187
230
 
188
- wait_for("the events to be transmitted") { subject.transmitted == 1 }
231
+ wait_for("the events to be transmitted") { scheduler.transmitted == 1 }
189
232
  end
190
233
 
191
234
  it "transmits all events at once when stopped" do
@@ -195,42 +238,58 @@ describe Appsignal::CheckIn::Scheduler do
195
238
  # stopped.
196
239
  stub_const("Appsignal::CheckIn::Scheduler::INITIAL_DEBOUNCE_SECONDS", 10)
197
240
 
198
- expect(transmitter).to receive(:transmit).with(
199
- ["first", "second", "third"].map do |identifier|
200
- hash_including(
201
- :identifier => identifier,
202
- :check_in_type => "cron",
203
- :kind => "finish"
204
- )
205
- end, :format => :ndjson
206
- )
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
207
250
 
208
251
  Appsignal::CheckIn.cron("first")
209
252
  Appsignal::CheckIn.cron("second")
210
253
  Appsignal::CheckIn.cron("third")
211
254
 
212
- subject.stop
255
+ scheduler.stop
213
256
 
214
- wait_for("the events to be transmitted") { subject.transmitted == 1 }
257
+ wait_for("the events to be transmitted") { scheduler.transmitted == 1 }
215
258
  end
216
259
  end
217
260
 
218
261
  describe "further apart than the short debounce interval" do
219
262
  it "transmits the first event and enqueues future events" do
220
- expect(transmitter).to receive(:transmit).with([hash_including(
221
- :identifier => "first",
222
- :check_in_type => "cron",
223
- :kind => "finish"
224
- )], :format => :ndjson)
263
+ stub_check_in_request(
264
+ :events => [
265
+ "identifier" => "first",
266
+ "kind" => "finish",
267
+ "check_in_type" => "cron"
268
+ ]
269
+ )
225
270
 
226
271
  Appsignal::CheckIn.cron("first")
227
272
 
228
- wait_for("the first event to be transmitted") { subject.transmitted == 1 }
229
-
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
+ )
230
289
  Appsignal::CheckIn.cron("second")
231
290
  Appsignal::CheckIn.cron("third")
232
291
 
233
- expect(subject.events).to match(["second", "third"].map do |identifier|
292
+ expect(scheduler.events).to match(["second", "third"].map do |identifier|
234
293
  hash_including({
235
294
  :identifier => identifier,
236
295
  :check_in_type => "cron",
@@ -240,30 +299,40 @@ describe Appsignal::CheckIn::Scheduler do
240
299
  end
241
300
 
242
301
  it "transmits the other events after the debounce interval" do
243
- expect(transmitter).to receive(:transmit)
244
-
302
+ stub_check_in_request(
303
+ :events => [
304
+ "identifier" => "first",
305
+ "kind" => "finish",
306
+ "check_in_type" => "cron"
307
+ ]
308
+ )
245
309
  Appsignal::CheckIn.cron("first")
246
310
 
247
- wait_for("the first event to be transmitted") { subject.transmitted == 1 }
248
-
249
- expect(transmitter).to receive(:transmit).with(
250
- ["second", "third"].map do |identifier|
251
- hash_including(
252
- :identifier => identifier,
253
- :check_in_type => "cron",
254
- :kind => "finish"
255
- )
256
- end, :format => :ndjson
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
+ ]
257
326
  )
258
327
 
259
328
  Appsignal::CheckIn.cron("second")
260
329
  Appsignal::CheckIn.cron("third")
261
330
 
262
- expect(subject.events).to_not be_empty
331
+ expect(scheduler.events).to_not be_empty
263
332
 
264
- wait_for("the other events to be transmitted") { subject.transmitted == 2 }
333
+ wait_for("the other events to be transmitted") { scheduler.transmitted == 2 }
265
334
 
266
- expect(subject.events).to be_empty
335
+ expect(scheduler.events).to be_empty
267
336
 
268
337
  expect(logs).to contains_log(:debug, "Scheduling cron check-in `first` finish event")
269
338
  expect(logs).to contains_log(:debug, "Transmitted cron check-in `first` finish event")
@@ -279,32 +348,42 @@ describe Appsignal::CheckIn::Scheduler do
279
348
  # immediately when the scheduler is stopped.
280
349
  stub_const("Appsignal::CheckIn::Scheduler::BETWEEN_TRANSMISSIONS_DEBOUNCE_SECONDS", 10)
281
350
 
282
- expect(transmitter).to receive(:transmit)
283
-
351
+ stub_check_in_request(
352
+ :events => [
353
+ "identifier" => "first",
354
+ "kind" => "finish",
355
+ "check_in_type" => "cron"
356
+ ]
357
+ )
284
358
  Appsignal::CheckIn.cron("first")
285
359
 
286
- wait_for("the event to be transmitted") { subject.transmitted == 1 }
287
-
288
- expect(transmitter).to receive(:transmit).with(
289
- ["second", "third"].map do |identifier|
290
- hash_including(
291
- :identifier => identifier,
292
- :check_in_type => "cron",
293
- :kind => "finish"
294
- )
295
- end, :format => :ndjson
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
+ ]
296
375
  )
297
376
 
298
377
  Appsignal::CheckIn.cron("second")
299
378
  Appsignal::CheckIn.cron("third")
300
379
 
301
- expect(subject.events).to_not be_empty
380
+ expect(scheduler.events).to_not be_empty
302
381
 
303
- subject.stop
382
+ scheduler.stop
304
383
 
305
- wait_for("the other events to be transmitted") { subject.transmitted == 2 }
384
+ wait_for("the other events to be transmitted") { scheduler.transmitted == 2 }
306
385
 
307
- expect(subject.events).to be_empty
386
+ expect(scheduler.events).to be_empty
308
387
 
309
388
  expect(logs).to contains_log(:debug, "Scheduling cron check-in `first` finish event")
310
389
  expect(logs).to contains_log(:debug, "Transmitted cron check-in `first` finish event")
@@ -321,16 +400,18 @@ describe Appsignal::CheckIn::Scheduler do
321
400
  # `.cron` helper would use a different digest for each invocation.
322
401
  cron = Appsignal::CheckIn::Cron.new(:identifier => "test")
323
402
 
324
- expect(transmitter).to receive(:transmit).with([hash_including(
325
- :identifier => "test",
326
- :check_in_type => "cron",
327
- :kind => "start"
328
- )], :format => :ndjson)
403
+ stub_check_in_request(
404
+ :events => [
405
+ "identifier" => "test",
406
+ "kind" => "start",
407
+ "check_in_type" => "cron"
408
+ ]
409
+ )
329
410
 
330
411
  cron.start
331
412
  cron.start
332
413
 
333
- wait_for("the event to be transmitted") { subject.transmitted == 1 }
414
+ wait_for("the event to be transmitted") { scheduler.transmitted == 1 }
334
415
 
335
416
  expect(logs).to contains_log(
336
417
  :debug,
@@ -353,13 +434,11 @@ describe Appsignal::CheckIn::Scheduler do
353
434
 
354
435
  describe "when the scheduler is stopped" do
355
436
  it "does not schedule any events to be transmitted" do
356
- expect(transmitter).not_to receive(:transmit)
357
-
358
- subject.stop
437
+ scheduler.stop
359
438
 
360
439
  Appsignal::CheckIn.cron("test")
361
440
 
362
- expect(subject.events).to be_empty
441
+ expect(scheduler.events).to be_empty
363
442
 
364
443
  expect(logs).to contains_log(
365
444
  :debug,
@@ -372,11 +451,11 @@ describe Appsignal::CheckIn::Scheduler do
372
451
  let(:appsignal_options) { { :active => false } }
373
452
 
374
453
  it "does not schedule any events to be transmitted" do
375
- subject.stop
454
+ scheduler.stop
376
455
 
377
456
  Appsignal::CheckIn.cron("test")
378
457
 
379
- expect(subject.events).to be_empty
458
+ expect(scheduler.events).to be_empty
380
459
 
381
460
  expect(logs).to contains_log(
382
461
  :debug,
@@ -387,21 +466,45 @@ describe Appsignal::CheckIn::Scheduler do
387
466
 
388
467
  describe "when transmitting returns a non-success response code" do
389
468
  it "logs the error and continues" do
390
- expect(transmitter).to receive(:transmit).and_return(
391
- Net::HTTPNotFound.new("1.1", 404, "Not Found")
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 }
392
484
  )
393
485
 
394
486
  Appsignal::CheckIn.cron("first")
395
487
 
396
- wait_for("the first event to be transmitted") { subject.transmitted == 1 }
488
+ wait_for("the first event to be transmitted") { scheduler.transmitted == 1 }
397
489
 
398
- expect(transmitter).to receive(:transmit).and_return(
399
- Net::HTTPSuccess.new("1.1", 200, "OK")
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
+ ]
400
503
  )
401
504
 
402
505
  Appsignal::CheckIn.cron("second")
403
506
 
404
- wait_for("the second event to be transmitted") { subject.transmitted == 2 }
507
+ wait_for("the second event to be transmitted") { scheduler.transmitted == 2 }
405
508
 
406
509
  expect(logs).to contains_log(
407
510
  :error,
@@ -416,23 +519,34 @@ describe Appsignal::CheckIn::Scheduler do
416
519
 
417
520
  describe "when transmitting throws an error" do
418
521
  it "logs the error and continues" do
419
- expect(transmitter).to receive(:transmit).and_raise("Something went wrong")
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
+ )
420
530
 
421
531
  Appsignal::CheckIn.cron("first")
422
532
 
423
- wait_for("the first event to be transmitted") { subject.transmitted == 1 }
533
+ wait_for("the first event to be transmitted") { scheduler.transmitted == 1 }
424
534
 
425
- expect(transmitter).to receive(:transmit).and_return(
426
- Net::HTTPSuccess.new("1.1", 200, "OK")
535
+ stub_check_in_request(
536
+ :events => [
537
+ "identifier" => "second",
538
+ "kind" => "finish",
539
+ "check_in_type" => "cron"
540
+ ]
427
541
  )
428
542
 
429
543
  Appsignal::CheckIn.cron("second")
430
544
 
431
- wait_for("the second event to be transmitted") { subject.transmitted == 2 }
545
+ wait_for("the second event to be transmitted") { scheduler.transmitted == 2 }
432
546
 
433
547
  expect(logs).to contains_log(
434
548
  :error,
435
- /Failed to transmit cron check-in `first` finish event .+: Something went wrong/
549
+ /Failed to transmit cron check-in `first` finish event .+: ExampleStandardError: Something went wrong/ # rubocop:disable Layout/LineLength
436
550
  )
437
551
  expect(logs).to contains_log(
438
552
  :debug,