chef-handler-datadog-demo 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/.env.example +2 -0
  3. data/.gitignore +63 -0
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +44 -0
  6. data/.travis.yml +25 -0
  7. data/Appraisals +16 -0
  8. data/CHANGELOG.md +102 -0
  9. data/CONTRIBUTING.md +23 -0
  10. data/Gemfile +14 -0
  11. data/Guardfile +37 -0
  12. data/LICENSE.txt +20 -0
  13. data/README.md +40 -0
  14. data/Rakefile +23 -0
  15. data/chef-handler-datadog-demo.gemspec +33 -0
  16. data/gemfiles/chef_10.14.4.gemfile +17 -0
  17. data/gemfiles/chef_10.gemfile +16 -0
  18. data/gemfiles/chef_11.gemfile +16 -0
  19. data/gemfiles/chef_12.gemfile +16 -0
  20. data/lib/chef/handler/datadog_demo.rb +123 -0
  21. data/lib/chef/handler/datadog_demo_chef_events.rb +174 -0
  22. data/lib/chef/handler/datadog_demo_chef_metrics.rb +62 -0
  23. data/lib/chef/handler/datadog_demo_chef_tags.rb +140 -0
  24. data/lib/chef_handler_datadog_demo.rb +6 -0
  25. data/spec/datadog_spec.rb +495 -0
  26. data/spec/spec_helper.rb +47 -0
  27. data/spec/support/cassettes/Chef_Handler_Datadog/failed_Chef_run/sets_alert_handles_when_specified.yml +513 -0
  28. data/spec/support/cassettes/Chef_Handler_Datadog/failed_Chef_run/sets_event_title_correctly.yml +258 -0
  29. data/spec/support/cassettes/Chef_Handler_Datadog/failed_Chef_run/sets_priority_correctly.yml +258 -0
  30. data/spec/support/cassettes/Chef_Handler_Datadog/handles_no_application_key/fails_when_no_application_key_is_provided.yml +143 -0
  31. data/spec/support/cassettes/Chef_Handler_Datadog/hostname/uses_the_node_name_when_no_config_specified.yml +250 -0
  32. data/spec/support/cassettes/Chef_Handler_Datadog/hostname/uses_the_specified_hostname_when_provided.yml +250 -0
  33. data/spec/support/cassettes/Chef_Handler_Datadog/reports_correct_hostname_on_an_ec2_node/does_not_use_the_instance_id_when_config_specified_to_false.yml +250 -0
  34. data/spec/support/cassettes/Chef_Handler_Datadog/reports_correct_hostname_on_an_ec2_node/uses_the_instance_id_when_config_is_specified.yml +250 -0
  35. data/spec/support/cassettes/Chef_Handler_Datadog/reports_correct_hostname_on_an_ec2_node/uses_the_instance_id_when_no_config_specified.yml +250 -0
  36. data/spec/support/cassettes/Chef_Handler_Datadog/reports_metrics_event_and_sets_tags/emits_events/posts_an_event.yml +250 -0
  37. data/spec/support/cassettes/Chef_Handler_Datadog/reports_metrics_event_and_sets_tags/emits_events/sets_priority_correctly.yml +250 -0
  38. data/spec/support/cassettes/Chef_Handler_Datadog/reports_metrics_event_and_sets_tags/emits_metrics/reports_metrics.yml +250 -0
  39. data/spec/support/cassettes/Chef_Handler_Datadog/reports_metrics_event_and_sets_tags/sets_tags/puts_the_tags_for_the_current_node.yml +250 -0
  40. data/spec/support/cassettes/Chef_Handler_Datadog/resources/failure_during_compile_phase/does_not_emit_metrics.yml +82 -0
  41. data/spec/support/cassettes/Chef_Handler_Datadog/resources/failure_during_compile_phase/only_emits_a_failure_metric.yml +134 -0
  42. data/spec/support/cassettes/Chef_Handler_Datadog/resources/failure_during_compile_phase/posts_an_event.yml +134 -0
  43. data/spec/support/cassettes/Chef_Handler_Datadog/tags/when_specified/allows_for_empty_tag_prefix.yml +251 -0
  44. data/spec/support/cassettes/Chef_Handler_Datadog/tags/when_specified/allows_for_user-specified_tag_prefix.yml +251 -0
  45. data/spec/support/cassettes/Chef_Handler_Datadog/tags/when_specified/sets_the_role_and_env_and_tags.yml +251 -0
  46. data/spec/support/cassettes/Chef_Handler_Datadog/tags/when_unspecified/sets_role_env_and_nothing_else.yml +251 -0
  47. data/spec/support/cassettes/Chef_Handler_Datadog/tags_submission_retries/when_not_specified/does_not_retry_after_a_failed_submission.yml +241 -0
  48. data/spec/support/cassettes/Chef_Handler_Datadog/tags_submission_retries/when_specified_as_2_retries/retries_no_more_than_twice.yml +331 -0
  49. data/spec/support/cassettes/Chef_Handler_Datadog/tags_submission_retries/when_specified_as_2_retries/stops_retrying_once_submission_is_successful.yml +287 -0
  50. data/spec/support/cassettes/Chef_Handler_Datadog/updated_resources/posts_an_event.yml +250 -0
  51. metadata +285 -0
@@ -0,0 +1,6 @@
1
+ # encoding: utf-8
2
+ # Helper module for version number only.
3
+ # Real deal in 'chef/handler/datadog.rb'
4
+ module ChefHandlerDatadogDemo
5
+ VERSION = '0.1.0'
6
+ end
@@ -0,0 +1,495 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Chef::Handler::Datadog, :vcr => :new_episodes do
5
+ # The #report method currently long and clunky, and we need to simulate a
6
+ # Chef run to test all aspects of this, as well as push values into the test.
7
+ before(:all) do
8
+ # This is used in validating that requests have actually been made,
9
+ # as in a 'Fucntional test'. We've recorded the tests with VCR, and use
10
+ # these to assert that the final product is correct. This is also
11
+ # exercising the API client, which may be helpful as well.
12
+ # There is a fair amount of duplication in the repsonse returned.
13
+ BASE_URL = 'https://app.datadoghq.com'
14
+ EVENTS_ENDPOINT = BASE_URL + '/api/v1/events'
15
+ HOST_TAG_ENDPOINT = BASE_URL + '/api/v1/tags/hosts/'
16
+ METRICS_ENDPOINT = BASE_URL + '/api/v1/series'
17
+ end
18
+
19
+ before(:each) do
20
+ @handler = Chef::Handler::Datadog.new(
21
+ :api_key => API_KEY,
22
+ :application_key => APPLICATION_KEY,
23
+ )
24
+ end
25
+
26
+ describe 'initialize' do
27
+ it 'should allow config hash to have string keys' do
28
+ Chef::Handler::Datadog.new(
29
+ 'api_key' => API_KEY,
30
+ 'application_key' => APPLICATION_KEY,
31
+ 'tag_prefix' => 'tag',
32
+ )
33
+ end
34
+ end
35
+
36
+ describe 'reports metrics event and sets tags' do
37
+ # Construct a good run_status
38
+ before(:each) do
39
+ @node = Chef::Node.build('chef.handler.datadog.test')
40
+ @node.send(:chef_environment, 'testing')
41
+ @events = Chef::EventDispatch::Dispatcher.new
42
+ @run_context = Chef::RunContext.new(@node, {}, @events)
43
+ @run_status = Chef::RunStatus.new(@node, @events)
44
+
45
+ @expected_time = Time.now
46
+ allow(Time).to receive(:now).and_return(@expected_time, @expected_time + 5)
47
+ @run_status.start_clock
48
+ @run_status.stop_clock
49
+
50
+ @run_status.run_context = @run_context
51
+
52
+ # Run the report
53
+ @handler.run_report_unsafe(@run_status)
54
+ end
55
+
56
+ context 'emits metrics' do
57
+ it 'reports metrics' do
58
+ expect(a_request(:post, METRICS_ENDPOINT).with(
59
+ :query => { 'api_key' => @handler.config[:api_key] }
60
+ )).to have_been_made.times(4)
61
+ end
62
+ end
63
+
64
+ context 'emits events' do
65
+ it 'posts an event' do
66
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
67
+ :query => { 'api_key' => @handler.config[:api_key] },
68
+ :body => hash_including(:msg_text => 'Chef updated 0 resources out of 0 resources total.'),
69
+ :body => hash_including(:msg_title => "Chef completed in 5 seconds on #{@node.name} "),
70
+ :body => hash_including(:tags => ['env:testing']),
71
+ )).to have_been_made.times(1)
72
+ end
73
+
74
+ it 'sets priority correctly' do
75
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
76
+ :query => { 'api_key' => @handler.config[:api_key] },
77
+ :body => hash_including(:priority => 'low'),
78
+ )).to have_been_made.times(1)
79
+ end
80
+ end
81
+
82
+ context 'sets tags' do
83
+ it 'puts the tags for the current node' do
84
+ # We no longer need to query the tag api for current tags,
85
+ # rather udpate only the tags for the designated source type
86
+ expect(a_request(:get, HOST_TAG_ENDPOINT + @node.name).with(
87
+ :query => { 'api_key' => @handler.config[:api_key],
88
+ 'application_key' => @handler.config[:application_key] },
89
+ )).to have_been_made.times(0)
90
+
91
+ expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
92
+ :query => { 'api_key' => @handler.config[:api_key],
93
+ 'application_key' => @handler.config[:application_key],
94
+ 'source' => 'chef' },
95
+ :body => { 'tags' => ['env:testing'] },
96
+ )).to have_been_made.times(1)
97
+ end
98
+ end
99
+ end
100
+
101
+ describe 'reports correct hostname on an ec2 node' do
102
+ before(:each) do
103
+ @node = Chef::Node.build('chef.handler.datadog.test-ec2')
104
+ @node.send(:chef_environment, 'testing')
105
+
106
+ @node.automatic_attrs['ec2'] = { :instance_id => 'i-123456' }
107
+
108
+ @run_context = Chef::RunContext.new(@node, {}, @events)
109
+ @run_status = Chef::RunStatus.new(@node, @events)
110
+ @expected_time = Time.now
111
+ allow(Time).to receive(:now).and_return(@expected_time, @expected_time + 5)
112
+ @run_status.start_clock
113
+ @run_status.stop_clock
114
+ @run_status.run_context = @run_context
115
+ end
116
+
117
+ it 'uses the instance id when no config specified' do
118
+ @handler.run_report_unsafe(@run_status)
119
+
120
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
121
+ :query => { 'api_key' => @handler.config[:api_key] },
122
+ :body => hash_including(:msg_title => 'Chef completed in 5 seconds on i-123456 '),
123
+ :body => hash_including(:host => 'i-123456'),
124
+ )).to have_been_made.times(1)
125
+ end
126
+
127
+ it 'uses the instance id when config is specified' do
128
+ @handler.config[:use_ec2_instance_id] = true
129
+ @handler.run_report_unsafe(@run_status)
130
+
131
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
132
+ :query => { 'api_key' => @handler.config[:api_key] },
133
+ :body => hash_including(:msg_title => 'Chef completed in 5 seconds on i-123456 '),
134
+ :body => hash_including(:host => 'i-123456'),
135
+ )).to have_been_made.times(1)
136
+ end
137
+
138
+ it 'does not use the instance id when config specified to false' do
139
+ @handler.config[:use_ec2_instance_id] = false
140
+ @handler.run_report_unsafe(@run_status)
141
+
142
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
143
+ :query => { 'api_key' => @handler.config[:api_key] },
144
+ :body => hash_including(:msg_title => "Chef completed in 5 seconds on #{@node.name} "),
145
+ :body => hash_including(:host => @node.name),
146
+ )).to have_been_made.times(1)
147
+ end
148
+ end
149
+
150
+ context 'hostname' do
151
+ before(:each) do
152
+ @node = Chef::Node.build('chef.handler.datadog.test-hostname')
153
+ @node.send(:chef_environment, 'testing')
154
+
155
+ @run_context = Chef::RunContext.new(@node, {}, @events)
156
+ @run_status = Chef::RunStatus.new(@node, @events)
157
+ @expected_time = Time.now
158
+ allow(Time).to receive(:now).and_return(@expected_time, @expected_time + 5)
159
+ @run_status.start_clock
160
+ @run_status.stop_clock
161
+ @run_status.run_context = @run_context
162
+ end
163
+
164
+ it 'uses the node.name when no config specified' do
165
+ @handler.run_report_unsafe(@run_status)
166
+
167
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
168
+ :query => { 'api_key' => @handler.config[:api_key] },
169
+ :body => hash_including(:msg_title => "Chef completed in 5 seconds on #{@node.name}"),
170
+ :body => hash_including(:host => @node.name),
171
+ )).to have_been_made.times(1)
172
+ end
173
+
174
+ it 'uses the specified hostname when provided' do
175
+ @handler.config[:hostname] = 'my-imaginary-hostname.local'
176
+ @handler.run_report_unsafe(@run_status)
177
+
178
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
179
+ :query => { 'api_key' => @handler.config[:api_key] },
180
+ :body => hash_including(:msg_title => 'Chef completed in 5 seconds on my-imaginary-hostname.local'),
181
+ :body => hash_including(:host => 'my-imaginary-hostname.local'),
182
+ )).to have_been_made.times(1)
183
+ end
184
+ end
185
+
186
+ context 'tags' do
187
+ before(:each) do
188
+ @node = Chef::Node.build('chef.handler.datadog.test-tags')
189
+
190
+ @node.send(:chef_environment, 'hostile')
191
+ @node.send(:run_list, 'role[highlander]')
192
+
193
+ @events = Chef::EventDispatch::Dispatcher.new
194
+ @run_context = Chef::RunContext.new(@node, {}, @events)
195
+ @run_status = Chef::RunStatus.new(@node, @events)
196
+
197
+ @expected_time = Time.now
198
+ allow(Time).to receive(:now).and_return(@expected_time, @expected_time + 5)
199
+ @run_status.start_clock
200
+ @run_status.stop_clock
201
+
202
+ @run_status.run_context = @run_context
203
+ end
204
+
205
+ describe 'when specified' do
206
+ it 'sets the role and env and tags' do
207
+ @node.normal.tags = ['the_one_and_only', 'datacenter:my-cloud']
208
+ @handler.run_report_unsafe(@run_status)
209
+
210
+ expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
211
+ :query => { 'api_key' => @handler.config[:api_key],
212
+ 'application_key' => @handler.config[:application_key],
213
+ 'source' => 'chef' },
214
+ :body => hash_including(:tags => [
215
+ 'env:hostile', 'role:highlander', 'tag:the_one_and_only', 'tag:datacenter:my-cloud'
216
+ ]),
217
+ )).to have_been_made.times(1)
218
+ end
219
+
220
+ it 'allows for user-specified tag prefix' do
221
+ @node.normal.tags = ['the_one_and_only', 'datacenter:my-cloud']
222
+ @handler.config[:tag_prefix] = 'custom-prefix-'
223
+ @handler.run_report_unsafe(@run_status)
224
+
225
+ expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
226
+ :query => { 'api_key' => @handler.config[:api_key],
227
+ 'application_key' => @handler.config[:application_key],
228
+ 'source' => 'chef' },
229
+ :body => hash_including(:tags => [
230
+ 'env:hostile', 'role:highlander', 'custom-prefix-the_one_and_only', 'custom-prefix-datacenter:my-cloud'
231
+ ]),
232
+ )).to have_been_made.times(1)
233
+ end
234
+
235
+ it 'allows for empty tag prefix' do
236
+ @node.normal.tags = ['the_one_and_only', 'datacenter:my-cloud']
237
+ @handler.config[:tag_prefix] = ''
238
+ @handler.run_report_unsafe(@run_status)
239
+
240
+ expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
241
+ :query => { 'api_key' => @handler.config[:api_key],
242
+ 'application_key' => @handler.config[:application_key],
243
+ 'source' => 'chef' },
244
+ :body => hash_including(:tags => [
245
+ 'env:hostile', 'role:highlander', 'the_one_and_only', 'datacenter:my-cloud'
246
+ ]),
247
+ )).to have_been_made.times(1)
248
+ end
249
+ end
250
+
251
+ describe 'when unspecified' do
252
+ it 'sets role, env and nothing else' do
253
+ @handler.run_report_unsafe(@run_status)
254
+
255
+ expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
256
+ :query => { 'api_key' => @handler.config[:api_key],
257
+ 'application_key' => @handler.config[:application_key],
258
+ 'source' => 'chef' },
259
+ :body => hash_including(:tags => [
260
+ 'env:hostile', 'role:highlander'
261
+ ]),
262
+ )).to have_been_made.times(1)
263
+ end
264
+ end
265
+ end
266
+
267
+ context 'tags submission retries' do
268
+ before(:each) do
269
+ @node = Chef::Node.build('chef.handler.datadog.test-tags-retries')
270
+
271
+ @node.send(:chef_environment, 'hostile')
272
+ @node.send(:run_list, 'role[highlander]')
273
+ @node.normal.tags = ['the_one_and_only']
274
+
275
+ @events = Chef::EventDispatch::Dispatcher.new
276
+ @run_context = Chef::RunContext.new(@node, {}, @events)
277
+ @run_status = Chef::RunStatus.new(@node, @events)
278
+
279
+ @expected_time = Time.now
280
+ allow(Time).to receive(:now).and_return(@expected_time, @expected_time + 5)
281
+ @run_status.start_clock
282
+ @run_status.stop_clock
283
+
284
+ @run_status.run_context = @run_context
285
+ end
286
+
287
+ describe 'when specified as 2 retries' do
288
+ before(:each) do
289
+ @handler.config[:tags_submission_retries] = 2
290
+ # Stub `sleep` to avoid slowing down the execution
291
+ allow_any_instance_of(DatadogChefTags).to receive(:sleep)
292
+ end
293
+
294
+ it 'retries no more than twice' do
295
+ @handler.run_report_unsafe(@run_status)
296
+
297
+ expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
298
+ :query => { 'api_key' => @handler.config[:api_key],
299
+ 'application_key' => @handler.config[:application_key],
300
+ 'source' => 'chef' },
301
+ :body => hash_including(:tags => [
302
+ 'env:hostile', 'role:highlander', 'tag:the_one_and_only'
303
+ ]),
304
+ )).to have_been_made.times(3)
305
+ end
306
+
307
+ it 'stops retrying once submission is successful' do
308
+ @handler.run_report_unsafe(@run_status)
309
+
310
+ expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
311
+ :query => { 'api_key' => @handler.config[:api_key],
312
+ 'application_key' => @handler.config[:application_key],
313
+ 'source' => 'chef' },
314
+ :body => hash_including(:tags => [
315
+ 'env:hostile', 'role:highlander', 'tag:the_one_and_only'
316
+ ]),
317
+ )).to have_been_made.times(2)
318
+ end
319
+ end
320
+
321
+ describe 'when not specified' do
322
+ it 'does not retry after a failed submission' do
323
+ @handler.run_report_unsafe(@run_status)
324
+
325
+ expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
326
+ :query => { 'api_key' => @handler.config[:api_key],
327
+ 'application_key' => @handler.config[:application_key],
328
+ 'source' => 'chef' },
329
+ :body => hash_including(:tags => [
330
+ 'env:hostile', 'role:highlander', 'tag:the_one_and_only'
331
+ ]),
332
+ )).to have_been_made.times(1)
333
+ end
334
+ end
335
+ end
336
+
337
+ describe 'handles no application_key' do
338
+ before(:each) do
339
+ @node = Chef::Node.build('chef.handler.datadog.test-noapp')
340
+
341
+ @node.send(:chef_environment, 'hostile')
342
+ @node.send(:run_list, 'role[highlander]')
343
+ @node.normal.tags = ['the_one_and_only']
344
+
345
+ @events = Chef::EventDispatch::Dispatcher.new
346
+ @run_context = Chef::RunContext.new(@node, {}, @events)
347
+ @run_status = Chef::RunStatus.new(@node, @events)
348
+
349
+ @expected_time = Time.now
350
+ allow(Time).to receive(:now).and_return(@expected_time, @expected_time + 5)
351
+ @run_status.start_clock
352
+ @run_status.stop_clock
353
+
354
+ @run_status.run_context = @run_context
355
+ end
356
+
357
+ it 'fails when no application key is provided' do
358
+ @handler.config[:application_key] = nil
359
+
360
+ # TODO: figure out how to capture output of Chef::Log
361
+ # Run the report, catch the error
362
+ expect { @handler.run_report_unsafe(@run_status) }.to raise_error
363
+ end
364
+ end
365
+
366
+ describe 'failed Chef run' do
367
+ before(:each) do
368
+ @node = Chef::Node.build('chef.handler.datadog.test-failed')
369
+
370
+ @node.send(:chef_environment, 'hostile')
371
+ @node.send(:run_list, 'role[highlander]')
372
+ @node.normal.tags = ['the_one_and_only']
373
+
374
+ @events = Chef::EventDispatch::Dispatcher.new
375
+ @run_context = Chef::RunContext.new(@node, {}, @events)
376
+ @run_status = Chef::RunStatus.new(@node, @events)
377
+
378
+ all_resources = [
379
+ Chef::Resource.new('whiskers'),
380
+ Chef::Resource.new('paws'),
381
+ Chef::Resource.new('ears'),
382
+ Chef::Resource.new('nose'),
383
+ Chef::Resource.new('tail'),
384
+ Chef::Resource.new('fur')
385
+ ]
386
+ all_resources.map { |r| r.updated_by_last_action(true) }
387
+ @run_context.resource_collection.all_resources.replace(all_resources)
388
+
389
+ @expected_time = Time.now
390
+ allow(Time).to receive(:now).and_return(@expected_time, @expected_time + 2)
391
+ @run_status.start_clock
392
+ @run_status.stop_clock
393
+
394
+ @run_status.run_context = @run_context
395
+
396
+ # Construct an exception
397
+ exception = Chef::Exceptions::UnsupportedAction.new('Something awry.')
398
+ exception.set_backtrace(['whiskers.rb:2', 'paws.rb:1', 'file.rb:2', 'file.rb:1'])
399
+ @run_status.exception = exception
400
+
401
+ # Run the report
402
+ @handler.run_report_unsafe(@run_status)
403
+ end
404
+
405
+ it 'sets event title correctly' do
406
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
407
+ :query => { 'api_key' => @handler.config[:api_key] },
408
+ :body => hash_including(:msg_title => "Chef failed in 2 seconds on #{@node.name} "),
409
+ )).to have_been_made.times(1)
410
+ end
411
+
412
+ it 'sets priority correctly' do
413
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
414
+ :query => { 'api_key' => @handler.config[:api_key] },
415
+ :body => hash_including(:alert_type => 'success'),
416
+ :body => hash_including(:priority => 'normal'),
417
+ )).to have_been_made.times(1)
418
+ end
419
+
420
+ it 'sets alert handles when specified' do
421
+ @handler.config[:notify_on_failure] = ['@alice', '@bob']
422
+ @handler.run_report_unsafe(@run_status)
423
+
424
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
425
+ :query => { 'api_key' => @handler.config[:api_key] },
426
+ :body => /Alerting: @alice @bob/
427
+ )).to have_been_made.times(1)
428
+ end
429
+ end
430
+
431
+ describe 'updated resources' do
432
+ before(:each) do
433
+ @node = Chef::Node.build('chef.handler.datadog.test-resources')
434
+ @node.send(:chef_environment, 'resources')
435
+ @events = Chef::EventDispatch::Dispatcher.new
436
+ @run_context = Chef::RunContext.new(@node, {}, @events)
437
+ @run_status = Chef::RunStatus.new(@node, @events)
438
+
439
+ all_resources = [Chef::Resource.new('whiskers'), Chef::Resource.new('paws')]
440
+ all_resources.first.updated_by_last_action(true)
441
+ @run_context.resource_collection.all_resources.replace(all_resources)
442
+
443
+ @expected_time = Time.now
444
+ allow(Time).to receive(:now).and_return(@expected_time, @expected_time + 8)
445
+ @run_status.start_clock
446
+ @run_status.stop_clock
447
+
448
+ @run_status.run_context = @run_context
449
+
450
+ # Run the report
451
+ @handler.run_report_unsafe(@run_status)
452
+ end
453
+
454
+ it 'posts an event' do
455
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
456
+ :query => { 'api_key' => @handler.config[:api_key] },
457
+ :body => hash_including(:msg_text => 'Chef updated 1 resources out of 2 resources total.'),
458
+ :body => hash_including(:msg_title => "Chef completed in 8 seconds on #{@node.name} "),
459
+ )).to have_been_made.times(1)
460
+ end
461
+ end
462
+
463
+ describe 'resources' do
464
+ before(:each) do
465
+ @node = Chef::Node.build('chef.handler.datadog.test-resources')
466
+ @node.send(:chef_environment, 'resources')
467
+ @events = Chef::EventDispatch::Dispatcher.new
468
+ @run_context = Chef::RunContext.new(@node, {}, @events)
469
+ @run_status = Chef::RunStatus.new(@node, @events)
470
+ end
471
+
472
+ context 'failure during compile phase' do
473
+ before(:each) do
474
+ @handler.run_report_unsafe(@run_status)
475
+ end
476
+
477
+ it 'only emits a failure metric' do
478
+ expect(a_request(:post, METRICS_ENDPOINT).with(
479
+ :query => { 'api_key' => @handler.config[:api_key] }
480
+ )).to have_been_made.times(1)
481
+ end
482
+
483
+ it 'posts an event' do
484
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
485
+ :query => { 'api_key' => @handler.config[:api_key] },
486
+ :body => hash_including(:msg_text => 'Chef was unable to complete a run, an error during compilation may have occured.'),
487
+ :body => hash_including(:msg_title => "Chef failed during compile phase on #{@node.name} "),
488
+ )).to have_been_made.times(1)
489
+ end
490
+ end
491
+ end
492
+
493
+ # TODO: test failures:
494
+ # @run_status.exception = Exception.new('Boy howdy!')
495
+ end