instrumental_agent 0.12.7 → 0.13.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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -2
- data/CHANGELOG.md +5 -2
- data/Gemfile +2 -2
- data/README.md +2 -2
- data/Rakefile +1 -0
- data/certs/equifax.ca.pem +69 -0
- data/certs/geotrust.ca.pem +80 -0
- data/certs/rapidssl.ca.pem +94 -0
- data/instrumental_agent.gemspec +1 -7
- data/lib/instrumental/agent.rb +99 -16
- data/lib/instrumental/version.rb +1 -1
- data/spec/agent_spec.rb +417 -392
- data/spec/test.crt +16 -0
- data/spec/test.csr +12 -0
- data/spec/test.key +15 -0
- data/spec/test_server.rb +50 -14
- metadata +13 -60
data/lib/instrumental/version.rb
CHANGED
data/spec/agent_spec.rb
CHANGED
@@ -1,460 +1,485 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
def wait
|
4
|
-
sleep
|
3
|
+
def wait(n=0.2)
|
4
|
+
sleep n # FIXME: hack
|
5
5
|
end
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
FORK_SUPPORTED = begin
|
8
|
+
Process.wait(fork { true })
|
9
|
+
true
|
10
|
+
rescue Exception => e
|
11
|
+
false
|
12
|
+
end
|
13
13
|
|
14
|
-
after do
|
15
|
-
@agent.stop
|
16
|
-
@agent = nil
|
17
|
-
@server.stop
|
18
|
-
end
|
19
14
|
|
20
|
-
it "should not connect to the server" do
|
21
|
-
wait
|
22
|
-
@server.connect_count.should == 0
|
23
|
-
end
|
24
15
|
|
25
|
-
|
26
|
-
|
27
|
-
@agent.gauge('disabled_test', 1)
|
28
|
-
wait
|
29
|
-
@server.connect_count.should == 0
|
30
|
-
end
|
16
|
+
shared_examples "Instrumental Agent" do
|
17
|
+
context do
|
31
18
|
|
32
|
-
|
33
|
-
|
34
|
-
@agent.flush(false)
|
35
|
-
wait
|
36
|
-
@server.commands.should be_empty
|
37
|
-
end
|
19
|
+
# Inferred:
|
20
|
+
# secure? and verify_cert? are set
|
38
21
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
end
|
22
|
+
# Agent options
|
23
|
+
let(:enabled) { true }
|
24
|
+
let(:synchronous) { false }
|
25
|
+
let(:token) { 'test_token' }
|
26
|
+
let(:agent) { Instrumental::Agent.new(token, :collector => server.host_and_port, :synchronous => synchronous, :enabled => enabled, :secure => secure?, :verify_cert => verify_cert?) }
|
45
27
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
28
|
+
# Server options
|
29
|
+
let(:listen) { true }
|
30
|
+
let(:response) { true }
|
31
|
+
let(:authenticate) { true }
|
32
|
+
let(:server) { TestServer.new(:listen => listen, :authenticate => authenticate, :response => response, :secure => secure?) }
|
51
33
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
34
|
+
before do
|
35
|
+
Instrumental::Agent.logger.level = Logger::UNKNOWN
|
36
|
+
@server = server
|
37
|
+
wait
|
38
|
+
end
|
58
39
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
end
|
40
|
+
after do
|
41
|
+
agent.stop
|
42
|
+
server.stop
|
43
|
+
end
|
64
44
|
|
65
|
-
|
66
|
-
|
67
|
-
@agent = nil
|
68
|
-
@server.stop
|
69
|
-
end
|
45
|
+
describe Instrumental::Agent, "disabled" do
|
46
|
+
let(:enabled) { false }
|
70
47
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
end
|
48
|
+
it "should not connect to the server" do
|
49
|
+
server.connect_count.should == 0
|
50
|
+
end
|
75
51
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
52
|
+
it "should not connect to the server after receiving a metric" do
|
53
|
+
agent.gauge('disabled_test', 1)
|
54
|
+
wait
|
55
|
+
server.connect_count.should == 0
|
56
|
+
end
|
81
57
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
@server.commands[0].should =~ / pid /
|
89
|
-
@server.commands[0].should =~ / runtime /
|
90
|
-
@server.commands[0].should =~ / platform /
|
91
|
-
end
|
58
|
+
it "should no op on flush without reconnect" do
|
59
|
+
1.upto(100) { agent.gauge('disabled_test', 1) }
|
60
|
+
agent.flush(false)
|
61
|
+
wait
|
62
|
+
server.commands.should be_empty
|
63
|
+
end
|
92
64
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
65
|
+
it "should no op on flush with reconnect" do
|
66
|
+
1.upto(100) { agent.gauge('disabled_test', 1) }
|
67
|
+
agent.flush(true)
|
68
|
+
wait
|
69
|
+
server.commands.should be_empty
|
70
|
+
end
|
98
71
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
end
|
72
|
+
it "should no op on an empty flush" do
|
73
|
+
agent.flush(true)
|
74
|
+
wait
|
75
|
+
server.commands.should be_empty
|
76
|
+
end
|
105
77
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
@server.commands.last.should =~ /gauge time_value_test .* #{now.to_i}/
|
113
|
-
end
|
78
|
+
it "should send metrics to logger" do
|
79
|
+
now = Time.now
|
80
|
+
agent.logger.should_receive(:debug).with("gauge metric 1 #{now.to_i} 1")
|
81
|
+
agent.gauge("metric", 1)
|
82
|
+
end
|
83
|
+
end
|
114
84
|
|
115
|
-
|
116
|
-
now = Time.now
|
117
|
-
@agent.gauge('gauge_test', 123).should == 123
|
118
|
-
@agent.gauge('gauge_test', 989).should == 989
|
119
|
-
wait
|
120
|
-
end
|
85
|
+
describe Instrumental::Agent, "enabled" do
|
121
86
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
@server.commands.last.should == "gauge gauge_test 123 555 1"
|
126
|
-
end
|
87
|
+
it "should not connect to the server" do
|
88
|
+
server.connect_count.should == 0
|
89
|
+
end
|
127
90
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
91
|
+
it "should connect to the server after sending a metric" do
|
92
|
+
agent.increment("test.foo")
|
93
|
+
wait
|
94
|
+
server.connect_count.should == 1
|
95
|
+
end
|
133
96
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
97
|
+
it "should announce itself, and include version" do
|
98
|
+
agent.increment("test.foo")
|
99
|
+
wait
|
100
|
+
server.commands[0].should =~ /hello .*/
|
101
|
+
server.commands[0].should =~ / version /
|
102
|
+
server.commands[0].should =~ / hostname /
|
103
|
+
server.commands[0].should =~ / pid /
|
104
|
+
server.commands[0].should =~ / runtime /
|
105
|
+
server.commands[0].should =~ / platform /
|
106
|
+
end
|
140
107
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
end
|
108
|
+
it "should authenticate using the token" do
|
109
|
+
agent.increment("test.foo")
|
110
|
+
wait
|
111
|
+
server.commands[1].should == "authenticate test_token"
|
112
|
+
end
|
147
113
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
114
|
+
it "should report a gauge" do
|
115
|
+
now = Time.now
|
116
|
+
agent.gauge('gauge_test', 123)
|
117
|
+
wait
|
118
|
+
server.commands.last.should == "gauge gauge_test 123 #{now.to_i} 1"
|
119
|
+
end
|
154
120
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
121
|
+
it "should report a time as gauge and return the block result" do
|
122
|
+
now = Time.now
|
123
|
+
agent.time("time_value_test") do
|
124
|
+
1 + 1
|
125
|
+
end.should == 2
|
126
|
+
wait
|
127
|
+
server.commands.last.should =~ /gauge time_value_test .* #{now.to_i}/
|
128
|
+
end
|
160
129
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
130
|
+
it "should return the value gauged" do
|
131
|
+
now = Time.now
|
132
|
+
agent.gauge('gauge_test', 123).should == 123
|
133
|
+
agent.gauge('gauge_test', 989).should == 989
|
134
|
+
wait
|
135
|
+
end
|
166
136
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
137
|
+
it "should report a gauge with a set time" do
|
138
|
+
agent.gauge('gauge_test', 123, 555)
|
139
|
+
wait
|
140
|
+
server.commands.last.should == "gauge gauge_test 123 555 1"
|
171
141
|
end
|
172
|
-
wait
|
173
|
-
@server.commands.should include("increment overflow_test 1 300 1")
|
174
|
-
@server.commands.should include("increment overflow_test 2 300 1")
|
175
|
-
@server.commands.should include("increment overflow_test 3 300 1")
|
176
|
-
@server.commands.should_not include("increment overflow_test 4 300 1")
|
177
|
-
@server.commands.should_not include("increment overflow_test 5 300 1")
|
178
|
-
end
|
179
|
-
end
|
180
142
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
end
|
187
|
-
@agent.instance_variable_get(:@queue).size.should == 0
|
188
|
-
wait # let the server receive the commands
|
189
|
-
@server.commands.should include("increment overflow_test 1 300 1")
|
190
|
-
@server.commands.should include("increment overflow_test 2 300 1")
|
191
|
-
@server.commands.should include("increment overflow_test 3 300 1")
|
192
|
-
@server.commands.should include("increment overflow_test 4 300 1")
|
193
|
-
@server.commands.should include("increment overflow_test 5 300 1")
|
194
|
-
end
|
195
|
-
end
|
143
|
+
it "should report a gauge with a set time and count" do
|
144
|
+
agent.gauge('gauge_test', 123, 555, 111)
|
145
|
+
wait
|
146
|
+
server.commands.last.should == "gauge gauge_test 123 555 111"
|
147
|
+
end
|
196
148
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
wait
|
204
|
-
@agent.increment('fork_reconnect_test', 1, 4) # triggers reconnect
|
205
|
-
wait
|
206
|
-
@server.connect_count.should == 2
|
207
|
-
@server.commands.should include("increment fork_reconnect_test 1 2 1")
|
208
|
-
@server.commands.should include("increment fork_reconnect_test 1 3 1")
|
209
|
-
@server.commands.should include("increment fork_reconnect_test 1 4 1")
|
210
|
-
end
|
149
|
+
it "should report an increment" do
|
150
|
+
now = Time.now
|
151
|
+
agent.increment("increment_test")
|
152
|
+
wait
|
153
|
+
server.commands.last.should == "increment increment_test 1 #{now.to_i} 1"
|
154
|
+
end
|
211
155
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
end
|
156
|
+
it "should return the value incremented by" do
|
157
|
+
now = Time.now
|
158
|
+
agent.increment("increment_test").should == 1
|
159
|
+
agent.increment("increment_test", 5).should == 5
|
160
|
+
wait
|
161
|
+
end
|
219
162
|
|
220
|
-
|
221
|
-
|
222
|
-
|
163
|
+
it "should report an increment a value" do
|
164
|
+
now = Time.now
|
165
|
+
agent.increment("increment_test", 2)
|
166
|
+
wait
|
167
|
+
server.commands.last.should == "increment increment_test 2 #{now.to_i} 1"
|
168
|
+
end
|
223
169
|
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
end
|
230
|
-
@agent.increment("test").should be_nil
|
231
|
-
end
|
170
|
+
it "should report an increment with a set time" do
|
171
|
+
agent.increment('increment_test', 1, 555)
|
172
|
+
wait
|
173
|
+
server.commands.last.should == "increment increment_test 1 555 1"
|
174
|
+
end
|
232
175
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
end
|
176
|
+
it "should report an increment with a set time and count" do
|
177
|
+
agent.increment('increment_test', 1, 555, 111)
|
178
|
+
wait
|
179
|
+
server.commands.last.should == "increment increment_test 1 555 111"
|
180
|
+
end
|
239
181
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
182
|
+
it "should discard data that overflows the buffer" do
|
183
|
+
with_constants('Instrumental::Agent::MAX_BUFFER' => 3) do
|
184
|
+
5.times do |i|
|
185
|
+
agent.increment('overflow_test', i + 1, 300)
|
186
|
+
end
|
187
|
+
wait
|
188
|
+
server.commands.should include("increment overflow_test 1 300 1")
|
189
|
+
server.commands.should include("increment overflow_test 2 300 1")
|
190
|
+
server.commands.should include("increment overflow_test 3 300 1")
|
191
|
+
server.commands.should_not include("increment overflow_test 4 300 1")
|
192
|
+
server.commands.should_not include("increment overflow_test 5 300 1")
|
193
|
+
end
|
194
|
+
end
|
248
195
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
196
|
+
it "should send all data in synchronous mode" do
|
197
|
+
with_constants('Instrumental::Agent::MAX_BUFFER' => 3) do
|
198
|
+
agent.synchronous = true
|
199
|
+
5.times do |i|
|
200
|
+
agent.increment('overflow_test', i + 1, 300)
|
201
|
+
end
|
202
|
+
agent.instance_variable_get(:@queue).size.should == 0
|
203
|
+
wait # let the server receive the commands
|
204
|
+
server.commands.should include("increment overflow_test 1 300 1")
|
205
|
+
server.commands.should include("increment overflow_test 2 300 1")
|
206
|
+
server.commands.should include("increment overflow_test 3 300 1")
|
207
|
+
server.commands.should include("increment overflow_test 4 300 1")
|
208
|
+
server.commands.should include("increment overflow_test 5 300 1")
|
209
|
+
end
|
210
|
+
end
|
255
211
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
212
|
+
if FORK_SUPPORTED
|
213
|
+
it "should automatically reconnect when forked" do
|
214
|
+
agent.increment('fork_reconnect_test', 1, 2)
|
215
|
+
fork do
|
216
|
+
agent.increment('fork_reconnect_test', 1, 3) # triggers reconnect
|
217
|
+
end
|
218
|
+
wait(1)
|
219
|
+
agent.increment('fork_reconnect_test', 1, 4) # triggers reconnect
|
220
|
+
wait(1)
|
221
|
+
server.connect_count.should == 2
|
222
|
+
server.commands.should include("increment fork_reconnect_test 1 2 1")
|
223
|
+
server.commands.should include("increment fork_reconnect_test 1 3 1")
|
224
|
+
server.commands.should include("increment fork_reconnect_test 1 4 1")
|
225
|
+
end
|
226
|
+
end
|
268
227
|
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
228
|
+
it "should never let an exception reach the user" do
|
229
|
+
agent.stub(:send_command).and_raise(Exception.new("Test Exception"))
|
230
|
+
agent.increment('throws_exception', 2).should be_nil
|
231
|
+
wait
|
232
|
+
agent.gauge('throws_exception', 234).should be_nil
|
233
|
+
wait
|
234
|
+
end
|
275
235
|
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
@server.commands.join("\n").should_not include("notice Test note")
|
280
|
-
end
|
236
|
+
it "should let exceptions in time bubble up" do
|
237
|
+
expect { agent.time('za') { raise "fail" } }.to raise_error
|
238
|
+
end
|
281
239
|
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
@server.commands.join("\n").should_not include("increment foo.bar 1 #{tm.to_i}")
|
291
|
-
end
|
240
|
+
it "should return nil if the user overflows the MAX_BUFFER" do
|
241
|
+
1.upto(Instrumental::Agent::MAX_BUFFER) do
|
242
|
+
agent.increment("test").should == 1
|
243
|
+
thread = agent.instance_variable_get(:@thread)
|
244
|
+
thread.kill
|
245
|
+
end
|
246
|
+
agent.increment("test").should be_nil
|
247
|
+
end
|
292
248
|
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
@server.commands.grep(/^gauge a /).size.should == 100
|
300
|
-
end
|
249
|
+
it "should track invalid metrics" do
|
250
|
+
agent.logger.should_receive(:warn).with(/%%/)
|
251
|
+
agent.increment(' %% .!#@$%^&*', 1, 1)
|
252
|
+
wait
|
253
|
+
server.commands.join("\n").should include("increment agent.invalid_metric")
|
254
|
+
end
|
301
255
|
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
256
|
+
it "should allow reasonable metric names" do
|
257
|
+
agent.increment('a')
|
258
|
+
agent.increment('a.b')
|
259
|
+
agent.increment('hello.world')
|
260
|
+
agent.increment('ThisIsATest.Of.The.Emergency.Broadcast.System.12345')
|
261
|
+
wait
|
262
|
+
server.commands.join("\n").should_not include("increment agent.invalid_metric")
|
263
|
+
end
|
308
264
|
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
265
|
+
it "should track invalid values" do
|
266
|
+
agent.logger.should_receive(:warn).with(/hello.*testington/)
|
267
|
+
agent.increment('testington', 'hello')
|
268
|
+
wait
|
269
|
+
server.commands.join("\n").should include("increment agent.invalid_value")
|
270
|
+
end
|
314
271
|
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
272
|
+
it "should allow reasonable values" do
|
273
|
+
agent.increment('a', -333.333)
|
274
|
+
agent.increment('a', -2.2)
|
275
|
+
agent.increment('a', -1)
|
276
|
+
agent.increment('a', 0)
|
277
|
+
agent.increment('a', 1)
|
278
|
+
agent.increment('a', 2.2)
|
279
|
+
agent.increment('a', 333.333)
|
280
|
+
agent.increment('a', Float::EPSILON)
|
281
|
+
wait
|
282
|
+
server.commands.join("\n").should_not include("increment agent.invalid_value")
|
283
|
+
end
|
327
284
|
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
@agent.queue.pop(true).should include("increment reconnect_test 1 1234 1\n")
|
335
|
-
end
|
285
|
+
it "should send notices to the server" do
|
286
|
+
tm = Time.now
|
287
|
+
agent.notice("Test note", tm)
|
288
|
+
wait
|
289
|
+
server.commands.join("\n").should include("notice #{tm.to_i} 0 Test note")
|
290
|
+
end
|
336
291
|
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
wait
|
343
|
-
@agent.queue.pop(true).should include("increment reconnect_test 1 1234 1\n")
|
344
|
-
end
|
292
|
+
it "should prevent a note w/ newline characters from being sent to the server" do
|
293
|
+
agent.notice("Test note\n").should be_nil
|
294
|
+
wait
|
295
|
+
server.commands.join("\n").should_not include("notice Test note")
|
296
|
+
end
|
345
297
|
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
298
|
+
it "should allow outgoing metrics to be stopped" do
|
299
|
+
tm = Time.now
|
300
|
+
agent.increment("foo.bar", 1, tm)
|
301
|
+
agent.stop
|
302
|
+
wait
|
303
|
+
agent.increment("foo.baz", 1, tm)
|
304
|
+
wait
|
305
|
+
server.commands.join("\n").should include("increment foo.baz 1 #{tm.to_i}")
|
306
|
+
server.commands.join("\n").should_not include("increment foo.bar 1 #{tm.to_i}")
|
307
|
+
end
|
354
308
|
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
309
|
+
it "should allow flushing pending values to the server" do
|
310
|
+
1.upto(100) { agent.gauge('a', rand(50)) }
|
311
|
+
agent.instance_variable_get(:@queue).size.should > 0
|
312
|
+
agent.flush
|
313
|
+
agent.instance_variable_get(:@queue).size.should == 0
|
314
|
+
wait
|
315
|
+
server.commands.grep(/^gauge a /).size.should == 100
|
316
|
+
end
|
361
317
|
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
318
|
+
it "should no op on an empty flush" do
|
319
|
+
agent.flush(true)
|
320
|
+
wait
|
321
|
+
server.commands.should be_empty
|
322
|
+
end
|
367
323
|
end
|
368
|
-
end
|
369
324
|
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
325
|
+
describe Instrumental::Agent, "connection problems" do
|
326
|
+
it "should automatically reconnect on disconnect" do
|
327
|
+
agent.increment("reconnect_test", 1, 1234)
|
328
|
+
wait
|
329
|
+
server.disconnect_all
|
330
|
+
wait(1)
|
331
|
+
agent.increment('reconnect_test', 1, 5678) # triggers reconnect
|
332
|
+
wait(1)
|
333
|
+
server.connect_count.should == 2
|
334
|
+
server.commands.last.should == "increment reconnect_test 1 5678 1"
|
335
|
+
end
|
378
336
|
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
337
|
+
context 'not listening' do
|
338
|
+
let(:listen) { false }
|
339
|
+
|
340
|
+
it "should buffer commands when server is down" do
|
341
|
+
agent.increment('reconnect_test', 1, 1234)
|
342
|
+
wait
|
343
|
+
agent.queue.pop(true).should include("increment reconnect_test 1 1234 1\n")
|
344
|
+
end
|
345
|
+
|
346
|
+
it "should warn once when buffer is full" do
|
347
|
+
with_constants('Instrumental::Agent::MAX_BUFFER' => 3) do
|
348
|
+
wait
|
349
|
+
agent.logger.should_receive(:warn).with(/Queue full/).once
|
350
|
+
|
351
|
+
agent.increment('buffer_full_warn_test', 1, 1234)
|
352
|
+
agent.increment('buffer_full_warn_test', 1, 1234)
|
353
|
+
agent.increment('buffer_full_warn_test', 1, 1234)
|
354
|
+
agent.increment('buffer_full_warn_test', 1, 1234)
|
355
|
+
agent.increment('buffer_full_warn_test', 1, 1234)
|
356
|
+
end
|
357
|
+
end
|
358
|
+
end
|
387
359
|
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
diff = Time.now.to_f - tm
|
397
|
-
diff.should >= 3
|
398
|
-
diff.should < 5
|
360
|
+
context 'not responding' do
|
361
|
+
let(:response) { false }
|
362
|
+
|
363
|
+
it "should buffer commands when server is not responsive" do
|
364
|
+
agent.increment('reconnect_test', 1, 1234)
|
365
|
+
wait
|
366
|
+
agent.queue.pop(true).should include("increment reconnect_test 1 1234 1\n")
|
367
|
+
end
|
399
368
|
end
|
400
|
-
end
|
401
|
-
end
|
402
369
|
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
370
|
+
|
371
|
+
context 'not authenticating' do
|
372
|
+
let(:authenticate) { false }
|
373
|
+
|
374
|
+
it "should buffer commands when authentication fails" do
|
375
|
+
agent.increment('reconnect_test', 1, 1234)
|
376
|
+
wait
|
377
|
+
agent.queue.pop(true).should include("increment reconnect_test 1 1234 1\n")
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
if FORK_SUPPORTED
|
382
|
+
it "should send commands in a short-lived process" do
|
383
|
+
if pid = fork { agent.increment('foo', 1, 1234) }
|
384
|
+
Process.wait(pid)
|
385
|
+
server.commands.last.should == "increment foo 1 1234 1"
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
it "should send commands in a process that bypasses at_exit when using #cleanup" do
|
390
|
+
if pid = fork { agent.increment('foo', 1, 1234); agent.cleanup; exit! }
|
391
|
+
Process.wait(pid)
|
392
|
+
server.commands.last.should == "increment foo 1 1234 1"
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
it "should not wait longer than EXIT_FLUSH_TIMEOUT seconds to exit a process" do
|
397
|
+
agent.stub(:open_socket) { |*args, &block| sleep(5) && block.call }
|
398
|
+
with_constants('Instrumental::Agent::EXIT_FLUSH_TIMEOUT' => 3) do
|
399
|
+
if (pid = fork { agent.increment('foo', 1) })
|
400
|
+
tm = Time.now.to_f
|
401
|
+
Process.wait(pid)
|
402
|
+
diff = Time.now.to_f - tm
|
403
|
+
diff.abs.should >= 3
|
404
|
+
diff.abs.should < 5
|
405
|
+
end
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
it "should not wait to exit a process if there are no commands queued" do
|
410
|
+
agent.stub(:open_socket) { |*args, &block| sleep(5) && block.call }
|
411
|
+
with_constants('Instrumental::Agent::EXIT_FLUSH_TIMEOUT' => 3) do
|
412
|
+
if (pid = fork { agent.increment('foo', 1); agent.queue.clear })
|
413
|
+
tm = Time.now.to_f
|
414
|
+
Process.wait(pid)
|
415
|
+
diff = Time.now.to_f - tm
|
416
|
+
diff.should < 1
|
417
|
+
end
|
418
|
+
end
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
it "should not wait longer than EXIT_FLUSH_TIMEOUT to attempt flushing the socket when disconnecting" do
|
423
|
+
agent.increment('foo', 1)
|
424
|
+
wait
|
425
|
+
agent.should_receive(:flush_socket) do
|
426
|
+
r, w = IO.pipe
|
427
|
+
Thread.new do
|
428
|
+
IO.select([r]) # mimic an endless blocking select poll
|
429
|
+
end.join
|
430
|
+
end
|
431
|
+
with_constants('Instrumental::Agent::EXIT_FLUSH_TIMEOUT' => 3) do
|
432
|
+
tm = Time.now.to_f
|
433
|
+
agent.cleanup
|
434
|
+
diff = Time.now.to_f - tm
|
435
|
+
diff.should <= 3
|
436
|
+
end
|
413
437
|
end
|
414
438
|
end
|
415
|
-
end
|
416
439
|
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
440
|
+
describe Instrumental::Agent, "enabled with sync option" do
|
441
|
+
let(:synchronous) { true }
|
442
|
+
|
443
|
+
it "should send all data in synchronous mode" do
|
444
|
+
with_constants('Instrumental::Agent::MAX_BUFFER' => 3) do
|
445
|
+
5.times do |i|
|
446
|
+
agent.increment('overflow_test', i + 1, 300)
|
447
|
+
end
|
448
|
+
wait # let the server receive the commands
|
449
|
+
server.commands.should include("increment overflow_test 1 300 1")
|
450
|
+
server.commands.should include("increment overflow_test 2 300 1")
|
451
|
+
server.commands.should include("increment overflow_test 3 300 1")
|
452
|
+
server.commands.should include("increment overflow_test 4 300 1")
|
453
|
+
server.commands.should include("increment overflow_test 5 300 1")
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
431
457
|
end
|
432
458
|
end
|
433
459
|
end
|
434
460
|
|
435
|
-
describe
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
461
|
+
describe "Insecure" do
|
462
|
+
let(:secure?) { false }
|
463
|
+
let(:verify_cert?) { false }
|
464
|
+
it_behaves_like "Instrumental Agent"
|
465
|
+
end
|
440
466
|
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
467
|
+
describe "Secure without cert verify" do
|
468
|
+
let(:secure?) { true }
|
469
|
+
let(:verify_cert?) { false }
|
470
|
+
it_behaves_like "Instrumental Agent"
|
445
471
|
|
446
|
-
it "should
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
wait # let the server receive the commands
|
452
|
-
@server.commands.should include("increment overflow_test 1 300 1")
|
453
|
-
@server.commands.should include("increment overflow_test 2 300 1")
|
454
|
-
@server.commands.should include("increment overflow_test 3 300 1")
|
455
|
-
@server.commands.should include("increment overflow_test 4 300 1")
|
456
|
-
@server.commands.should include("increment overflow_test 5 300 1")
|
457
|
-
end
|
472
|
+
it "should be disabled if the system does not allow secure connections but the user specifically requested secure" do
|
473
|
+
Instrumental::Agent.any_instance.stub(:allows_secure?) { false }
|
474
|
+
agent = Instrumental::Agent.new('test-token', :enabled => true, :secure => true)
|
475
|
+
agent.secure.should == false
|
476
|
+
agent.enabled.should == false
|
458
477
|
end
|
459
478
|
|
479
|
+
it "should be fallback to insecure if the system does not allow secure connections but the user did not specifically request secure" do
|
480
|
+
Instrumental::Agent.any_instance.stub(:allows_secure?) { false }
|
481
|
+
agent = Instrumental::Agent.new('test-token', :enabled => true)
|
482
|
+
agent.secure.should == false
|
483
|
+
agent.enabled.should == true
|
484
|
+
end
|
460
485
|
end
|