dogtrainer 0.2.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 82d400dbf30520efe26fd2c8e35423766df31d70
4
- data.tar.gz: c49711ca30824470040e34c5010be7a2afee19d9
3
+ metadata.gz: 61ad47a205486a220109a1e79127f4c7e5d13724
4
+ data.tar.gz: 054eb39e28f43c41599d64840813da35d78210b3
5
5
  SHA512:
6
- metadata.gz: c0bb25a6a3c4119e67338aacdcdeb700b9ad2f4cce57152290f6f1b877af203c2b8e20fbcec1751deb84011df2dad4ebecea88d66b85a57479c4d70a604e4287
7
- data.tar.gz: ccd27b826a7ed42ee86c30882101c5e5515327196842b5c2b1a7aa98f00063870888c89236eb3f90275258c1c13a122567174b2c24bb61dafa0ba45d5702e808
6
+ metadata.gz: 81048ff88866c2439e90d0ff18d46ece9480a73c8b8358a4b975f4b59c38bf6415c9018502b82092ad240c8dc2dbd7a12f38afdda251098287b81a68f12fb84a
7
+ data.tar.gz: 0cd934673286968e9657102fc9f11c156e4ad8817e3d86ec4c2881601a43e0cbdebb135ebee3c7aeed6ec790abd4442e9795805a277583bdd04e5f6a205e0fd4
@@ -25,3 +25,6 @@ Style/AccessorMethodName:
25
25
  Style/PreferredHashMethods:
26
26
  Exclude:
27
27
  - 'lib/dogtrainer/api.rb'
28
+
29
+ Metrics/BlockLength:
30
+ Max: 2000
@@ -1,3 +1,12 @@
1
+ Version 0.3.0
2
+
3
+ - Added ``DogTrainer::DogApiException`` custom exception class, subclass of ``StandardError``.
4
+ - ``DogTrainer::API`` methods ``mute_monitor_by_id``, ``mute_monitor_by_name``,
5
+ ``mute_monitors_by_regex``, ``unmute_monitor_by_id``, ``unmute_monitor_by_name``,
6
+ ``unmute_monitors_by_regex``, ``upsert_timeboard`` and ``upsert_screenboard``
7
+ now raise an ``DogTrainer::DogApiException`` if the Datadog API response status
8
+ code indicates an error.
9
+
1
10
  Version 0.2.0
2
11
 
3
12
  - add support to mute and unmute monitors by id, name or regex
data/README.md CHANGED
@@ -4,9 +4,9 @@ Build of master branch: [![CircleCI](https://circleci.com/gh/manheim/dogtrainer.
4
4
 
5
5
  Documentation: [http://www.rubydoc.info/gems/dogtrainer/](http://www.rubydoc.info/gems/dogtrainer/)
6
6
 
7
- Wrapper around DataDog dogapi gem to simplify creation and management of Monitors and Boards.
7
+ Wrapper around Datadog dogapi gem to simplify creation and management of Monitors and Boards.
8
8
 
9
- This class provides methods to manage (upsert / ensure the existence and configuration of) DataDog
9
+ This class provides methods to manage (upsert / ensure the existence and configuration of) Datadog
10
10
  Monitors and TimeBoards/ScreenBoards.
11
11
 
12
12
  ## Installation
@@ -30,7 +30,7 @@ gem.add_runtime_dependency 'dogtrainer'
30
30
 
31
31
  ## Usage
32
32
 
33
- To use the DataDog helper, require the module and create an instance of the class,
33
+ To use the Datadog helper, require the module and create an instance of the class,
34
34
  passing it the required configuration information.
35
35
 
36
36
  ```ruby
@@ -47,13 +47,13 @@ require 'dogtrainer'
47
47
  dog = DogTrainer::API.new(api_key, app_key, notify_to, 'string describing where to update monitors or boards')
48
48
  ```
49
49
 
50
- * __api_key__ is your DataDog API Key, which you can find at https://app.datadoghq.com/account/settings#api
50
+ * __api_key__ is your Datadog API Key, which you can find at https://app.datadoghq.com/account/settings#api
51
51
  * __app_key__ is an application-specific key, which should be generated separately for every app or
52
52
  service that uses this class. These can be generated and seen at https://app.datadoghq.com/account/settings#api
53
- * __notify_to__ is the string specifying DataDog monitor recipients in "@" form. If you are only managing Timeboards or
53
+ * __notify_to__ is the string specifying Datadog monitor recipients in "@" form. If you are only managing Timeboards or
54
54
  Screenboards (not Monitors), this can be ``nil``.
55
55
  * __repo_path__ is a string that will be included in all Monitor notification messages and TimeBoard/ScreenBoard descriptions,
56
- telling users where to find the code that created the DataDog resource. This is intended to alert users to code-managed
56
+ telling users where to find the code that created the Datadog resource. This is intended to alert users to code-managed
57
57
  items that shouldn't be manually changed. If this parameter is not specified, it will be obtained from the first usable
58
58
  and present value of: the ``GIT_URL`` environment variable, the ``CIRCLE_REPOSITORY_URL`` or the first remote URL found
59
59
  by running ``git config --local -l`` in the directory that contains the code calling this constructor.
@@ -243,12 +243,12 @@ graphs = [
243
243
  "max:aws.elb.latency{host:#{elb_name}}"
244
244
  ]
245
245
  ),
246
- # Instance CPU Utilization from DataDog/EC2 integration
246
+ # Instance CPU Utilization from Datadog/EC2 integration
247
247
  dog.graphdef(
248
248
  "Instance EC2 CPU Utilization",
249
249
  "avg:aws.ec2.cpuutilization{name:#{instance_name}}"
250
250
  ),
251
- # Instance Free Memory from DataDog Agent on instance
251
+ # Instance Free Memory from Datadog Agent on instance
252
252
  dog.graphdef(
253
253
  "Instance Free Memory",
254
254
  "avg:system.mem.free{name:#{instance_name}}"
@@ -1,6 +1,7 @@
1
1
  require 'dogapi'
2
2
  require 'dogapi/v1'
3
3
  require 'dogtrainer/logging'
4
+ require 'dogtrainer/dogapiexception'
4
5
 
5
6
  module DogTrainer
6
7
  # Helper methods to upsert/ensure existence and configuration of DataDog
@@ -36,6 +37,20 @@ module DogTrainer
36
37
  end
37
38
  end
38
39
 
40
+ # Check the result of a Dogapi::Client call.
41
+ #
42
+ # Dogapi::Client returns responses as arrays, with the first element being
43
+ # the HTTP response code and the second element being the actual response.
44
+ #
45
+ # Check the specified
46
+ #
47
+ # @param r [Array] the Dogapi result/response
48
+ # @param accepted_codes [Array] Array of acceptable (success) HTTP codes
49
+ # @raise [DogApiException] if the response code indicates an error
50
+ def check_dog_result(r, accepted_codes = ['200'])
51
+ raise DogApiException, r unless accepted_codes.include?(r[0])
52
+ end
53
+
39
54
  # Return a human-usable string identifying where to make changes to the
40
55
  # resources created by this class. Returns the first of:
41
56
  #
@@ -195,8 +210,10 @@ module DogTrainer
195
210
  'no_data_timeframe' => 20
196
211
  }
197
212
  }
198
- monitor_data['options']['escalation_message'] = \
199
- options[:escalation_message] unless options[:escalation_message].nil?
213
+ unless options[:escalation_message].nil?
214
+ monitor_data['options']['escalation_message'] = \
215
+ options[:escalation_message]
216
+ end
200
217
  monitor_data
201
218
  end
202
219
 
@@ -303,7 +320,7 @@ module DogTrainer
303
320
 
304
321
  # Create a monitor that doesn't already exist; return its id
305
322
  #
306
- # @param mon_name [String] mane of the monitor to create
323
+ # @param _mon_name [String] mane of the monitor to create
307
324
  # @param mon_params [Hash] params to pass to the DataDog API call. Must
308
325
  # include "type" and "query" keys.
309
326
  def create_monitor(_mon_name, mon_params)
@@ -356,14 +373,15 @@ module DogTrainer
356
373
  # @param [Hash] options
357
374
  # @option options [Integer] :end_timestamp optional timestamp
358
375
  # for when the mute should end; Integer POSIX timestamp.
376
+ # @raise [DogApiException] if the Datadog API returns an error
359
377
  def mute_monitor_by_id(mon_id, options = { end_timestamp: nil })
360
378
  if options.fetch(:end_timestamp, nil).nil?
361
379
  logger.info "Muting monitor by ID #{mon_id}"
362
- @dog.mute_monitor(mon_id)
380
+ check_dog_result(@dog.mute_monitor(mon_id))
363
381
  else
364
382
  end_ts = options[:end_timestamp]
365
383
  logger.info "Muting monitor by ID #{mon_id} until #{end_ts}"
366
- @dog.mute_monitor(mon_id, end: end_ts)
384
+ check_dog_result(@dog.mute_monitor(mon_id, end: end_ts))
367
385
  end
368
386
  end
369
387
 
@@ -383,17 +401,18 @@ module DogTrainer
383
401
  # @option options [Integer] :end_timestamp optional timestamp
384
402
  # for when the mute should end; Integer POSIX timestamp.
385
403
  # @raise [RuntimeError] raised if the specified monitor name can't be found
404
+ # @raise [DogApiException] if the Datadog API returns an error
386
405
  def mute_monitor_by_name(mon_name, options = { end_timestamp: nil })
387
406
  mon = get_existing_monitor_by_name(mon_name)
388
407
  raise "ERROR: Could not find monitor with name #{mon_name}" if mon.nil?
389
408
  if options.fetch(:end_timestamp, nil).nil?
390
409
  logger.info "Muting monitor by name #{mon_name} (#{mon['id']})"
391
- @dog.mute_monitor(mon['id'])
410
+ check_dog_result(@dog.mute_monitor(mon['id']))
392
411
  else
393
412
  end_ts = options[:end_timestamp]
394
413
  logger.info "Muting monitor by name #{mon_name} (#{mon['id']}) " \
395
414
  "until #{end_ts}"
396
- @dog.mute_monitor(mon['id'], end: end_ts)
415
+ check_dog_result(@dog.mute_monitor(mon['id'], end: end_ts))
397
416
  end
398
417
  end
399
418
 
@@ -442,9 +461,10 @@ module DogTrainer
442
461
  # Unute the monitor identified by the specified unique ID.
443
462
  #
444
463
  # @param mon_id [Integer] ID of the monitor to mute
464
+ # @raise [DogApiException] if the Datadog API returns an error
445
465
  def unmute_monitor_by_id(mon_id)
446
466
  logger.info "Unmuting monitor by ID #{mon_id}"
447
- @dog.unmute_monitor(mon_id, all_scopes: true)
467
+ check_dog_result(@dog.unmute_monitor(mon_id, all_scopes: true))
448
468
  end
449
469
 
450
470
  # Unmute the monitor identified by the specified name.
@@ -522,12 +542,14 @@ module DogTrainer
522
542
  #
523
543
  # @param dash_name [String] Account-unique dashboard name
524
544
  # @param graphs [Array] Array of graphdefs to add to dashboard
545
+ # @raise [DogApiException] if the Datadog API returns an error
525
546
  def upsert_timeboard(dash_name, graphs)
526
547
  logger.info "Upserting timeboard: #{dash_name}"
527
548
  desc = "created by DogTrainer RubyGem via #{@repo_path}"
528
549
  dash = get_existing_timeboard_by_name(dash_name)
529
550
  if dash.nil?
530
551
  d = @dog.create_dashboard(dash_name, desc, graphs)
552
+ check_dog_result(d)
531
553
  logger.info "Created timeboard #{d[1]['dash']['id']}"
532
554
  return
533
555
  end
@@ -548,9 +570,10 @@ module DogTrainer
548
570
 
549
571
  if needs_update
550
572
  logger.info "\tUpdating timeboard #{dash['dash']['id']}"
551
- @dog.update_dashboard(
573
+ d = @dog.update_dashboard(
552
574
  dash['dash']['id'], dash_name, desc, graphs
553
575
  )
576
+ check_dog_result(d)
554
577
  logger.info "\tTimeboard updated."
555
578
  else
556
579
  logger.info "\tTimeboard is up-to-date"
@@ -566,6 +589,7 @@ module DogTrainer
566
589
  # @param widgets [Array] Array of Hash widget definitions to pass to
567
590
  # the DataDog API. For further information, see:
568
591
  # http://docs.datadoghq.com/api/screenboards/
592
+ # @raise [DogApiException] if the Datadog API returns an error
569
593
  def upsert_screenboard(dash_name, widgets)
570
594
  logger.info "Upserting screenboard: #{dash_name}"
571
595
  desc = "created by DogTrainer RubyGem via #{@repo_path}"
@@ -574,6 +598,7 @@ module DogTrainer
574
598
  d = @dog.create_screenboard(board_title: dash_name,
575
599
  description: desc,
576
600
  widgets: widgets)
601
+ check_dog_result(d)
577
602
  logger.info "Created screenboard #{d[1]['id']}"
578
603
  return
579
604
  end
@@ -594,9 +619,10 @@ module DogTrainer
594
619
 
595
620
  if needs_update
596
621
  logger.info "\tUpdating screenboard #{dash['id']}"
597
- @dog.update_screenboard(dash['id'], board_title: dash_name,
598
- description: desc,
599
- widgets: widgets)
622
+ d = @dog.update_screenboard(dash['id'], board_title: dash_name,
623
+ description: desc,
624
+ widgets: widgets)
625
+ check_dog_result(d)
600
626
  logger.info "\tScreenboard updated."
601
627
  else
602
628
  logger.info "\tScreenboard is up-to-date"
@@ -0,0 +1,26 @@
1
+ module DogTrainer
2
+ # Exception raised for Datadog API errors (non-200 status code)
3
+ class DogApiException < StandardError
4
+ attr_reader :statuscode
5
+ attr_reader :content
6
+
7
+ def initialize(response)
8
+ @statuscode = response[0]
9
+ @content = if response.length > 1
10
+ response[1]
11
+ else
12
+ {}
13
+ end
14
+ msg = "Datadog API call returned status #{@statuscode}"
15
+ if @content.include?('errors')
16
+ msg << ":\n"
17
+ if @content['errors'].is_a?(Array)
18
+ @content['errors'].each { |e| msg << "#{e}\n" }
19
+ else
20
+ msg << "#{content['errors']}\n"
21
+ end
22
+ end
23
+ super(msg)
24
+ end
25
+ end
26
+ end
@@ -1,4 +1,4 @@
1
1
  module DogTrainer
2
2
  # store the verson of the Gem/module; used in the gemspec and in messages
3
- VERSION = '0.2.0'.freeze
3
+ VERSION = '0.3.0'.freeze
4
4
  end
@@ -60,6 +60,39 @@ describe DogTrainer::API do
60
60
  expect(x.instance_variable_get('@repo_path')).to eq('foo/bar')
61
61
  end
62
62
  end
63
+ describe '#check_dog_result' do
64
+ let(:response) { { 'foo' => 'bar' } }
65
+ context 'with default accepted_codes' do
66
+ describe 'when code is in accepted array' do
67
+ it 'does not raise an exception' do
68
+ expect { subject.check_dog_result(['200', response]) }
69
+ .to_not raise_error
70
+ end
71
+ end
72
+ describe 'when code is not in accepted array' do
73
+ it 'raises an exception' do
74
+ expect { subject.check_dog_result(['400', response]) }
75
+ .to raise_error DogTrainer::DogApiException,
76
+ /Datadog API call returned status 400/
77
+ end
78
+ end
79
+ end
80
+ context 'with custom accepted_codes' do
81
+ describe 'when code is in accepted array' do
82
+ it 'does not raise an exception' do
83
+ expect { subject.check_dog_result(['404', response], %w(200 404)) }
84
+ .to_not raise_error
85
+ end
86
+ end
87
+ describe 'when code is not in accepted array' do
88
+ it 'raises an exception' do
89
+ expect { subject.check_dog_result(['400', response], %w(200 404)) }
90
+ .to raise_error DogTrainer::DogApiException,
91
+ /Datadog API call returned status 400/
92
+ end
93
+ end
94
+ end
95
+ end
63
96
  describe '#get_repo_path' do
64
97
  it 'calls #get_git_url_for_directory if ENV vars are not set' do
65
98
  allow(ENV).to receive(:has_key?).with('GIT_URL').and_return(false)
@@ -1000,19 +1033,25 @@ describe DogTrainer::API do
1000
1033
  describe '#mute_monitor_by_id' do
1001
1034
  it 'calls dog.mute_monitor with id' do
1002
1035
  dog = double(Dogapi::Client)
1003
- allow(dog).to receive(:mute_monitor).with(any_args)
1036
+ resp = double
1037
+ allow(dog).to receive(:mute_monitor).with(any_args).and_return(resp)
1038
+ allow(subject).to receive(:check_dog_result)
1004
1039
  subject.instance_variable_set('@dog', dog)
1005
1040
 
1006
1041
  expect(dog).to receive(:mute_monitor).once.with(12_345)
1042
+ expect(subject).to receive(:check_dog_result).once.with(resp)
1007
1043
  subject.mute_monitor_by_id(12_345)
1008
1044
  end
1009
1045
  it 'calls dog.mute_monitor with id and timestamp if specified' do
1010
1046
  dog = double(Dogapi::Client)
1011
- allow(dog).to receive(:mute_monitor).with(any_args)
1047
+ resp = double
1048
+ allow(dog).to receive(:mute_monitor).with(any_args).and_return(resp)
1049
+ allow(subject).to receive(:check_dog_result)
1012
1050
  subject.instance_variable_set('@dog', dog)
1013
1051
 
1014
1052
  expect(dog).to receive(:mute_monitor).once
1015
1053
  .with(12_345, end: 6_789)
1054
+ expect(subject).to receive(:check_dog_result).once.with(resp)
1016
1055
  subject.mute_monitor_by_id(12_345, end_timestamp: 6_789)
1017
1056
  end
1018
1057
  end
@@ -1020,39 +1059,48 @@ describe DogTrainer::API do
1020
1059
  it 'calls dog.mute_monitor with id' do
1021
1060
  monitor = { 'id' => 5_678 }
1022
1061
  dog = double(Dogapi::Client)
1023
- allow(dog).to receive(:mute_monitor).with(any_args)
1062
+ resp = double
1063
+ allow(dog).to receive(:mute_monitor).with(any_args).and_return(resp)
1024
1064
  allow(subject).to receive(:get_existing_monitor_by_name)
1025
1065
  .and_return(monitor)
1066
+ allow(subject).to receive(:check_dog_result)
1026
1067
  subject.instance_variable_set('@dog', dog)
1027
1068
 
1028
1069
  expect(subject).to receive(:get_existing_monitor_by_name).once
1029
1070
  .with('mymon')
1030
1071
  expect(dog).to receive(:mute_monitor).once.with(5_678)
1072
+ expect(subject).to receive(:check_dog_result).once.with(resp)
1031
1073
  subject.mute_monitor_by_name('mymon')
1032
1074
  end
1033
1075
  it 'calls dog.mute_monitor with id and timestamp if specified' do
1034
1076
  monitor = { 'id' => 5_678 }
1035
1077
  dog = double(Dogapi::Client)
1036
- allow(dog).to receive(:mute_monitor).with(any_args)
1078
+ resp = double
1079
+ allow(dog).to receive(:mute_monitor).with(any_args).and_return(resp)
1037
1080
  allow(subject).to receive(:get_existing_monitor_by_name)
1038
1081
  .and_return(monitor)
1082
+ allow(subject).to receive(:check_dog_result)
1039
1083
  subject.instance_variable_set('@dog', dog)
1040
1084
 
1041
1085
  expect(subject).to receive(:get_existing_monitor_by_name).once
1042
1086
  .with('mymon')
1043
1087
  expect(dog).to receive(:mute_monitor).once.with(5_678, end: 1_234)
1088
+ expect(subject).to receive(:check_dog_result).once.with(resp)
1044
1089
  subject.mute_monitor_by_name('mymon', end_timestamp: 1_234)
1045
1090
  end
1046
1091
  it 'raises error if monitor cannot be found' do
1047
1092
  dog = double(Dogapi::Client)
1048
- allow(dog).to receive(:mute_monitor).with(any_args)
1093
+ resp = double
1094
+ allow(dog).to receive(:mute_monitor).with(any_args).and_return(resp)
1049
1095
  allow(subject).to receive(:get_existing_monitor_by_name)
1050
1096
  .and_return(nil)
1097
+ allow(subject).to receive(:check_dog_result)
1051
1098
  subject.instance_variable_set('@dog', dog)
1052
1099
 
1053
1100
  expect(subject).to receive(:get_existing_monitor_by_name).once
1054
1101
  .with('mymon')
1055
1102
  expect(dog).to_not receive(:mute_monitor)
1103
+ expect(subject).to_not receive(:check_dog_result)
1056
1104
  expect { subject.mute_monitor_by_name('mymon') }
1057
1105
  .to raise_error(RuntimeError,
1058
1106
  'ERROR: Could not find monitor with name mymon')
@@ -1126,11 +1174,14 @@ describe DogTrainer::API do
1126
1174
  describe '#unmute_monitor_by_id' do
1127
1175
  it 'calls dog.unmute_monitor with id' do
1128
1176
  dog = double(Dogapi::Client)
1129
- allow(dog).to receive(:unmute_monitor).with(any_args)
1177
+ resp = double
1178
+ allow(dog).to receive(:unmute_monitor).with(any_args).and_return(resp)
1179
+ allow(subject).to receive(:check_dog_result)
1130
1180
  subject.instance_variable_set('@dog', dog)
1131
1181
 
1132
1182
  expect(dog).to receive(:unmute_monitor).once
1133
1183
  .with(12_345, all_scopes: true)
1184
+ expect(subject).to receive(:check_dog_result).once.with(resp)
1134
1185
  subject.unmute_monitor_by_id(12_345)
1135
1186
  end
1136
1187
  end
@@ -1326,6 +1377,7 @@ describe DogTrainer::API do
1326
1377
  allow(subject).to receive(:get_existing_timeboard_by_name).with(any_args)
1327
1378
  .and_return(nil)
1328
1379
  allow(subject.logger).to receive(:info).with(any_args)
1380
+ allow(subject).to receive(:check_dog_result)
1329
1381
 
1330
1382
  expect(subject).to receive(:get_existing_timeboard_by_name).once
1331
1383
  .with('t')
@@ -1337,6 +1389,7 @@ describe DogTrainer::API do
1337
1389
  )
1338
1390
  expect(dog).to_not receive(:update_dashboard)
1339
1391
  expect(subject.logger).to receive(:info).with('Created timeboard id1')
1392
+ expect(subject).to receive(:check_dog_result).once.with(res)
1340
1393
  subject.upsert_timeboard('t', [1, 2])
1341
1394
  end
1342
1395
  it 'does not update if params are current' do
@@ -1359,12 +1412,14 @@ describe DogTrainer::API do
1359
1412
  allow(subject).to receive(:get_existing_timeboard_by_name).with(any_args)
1360
1413
  .and_return(res[1])
1361
1414
  allow(subject.logger).to receive(:info).with(any_args)
1415
+ allow(subject).to receive(:check_dog_result)
1362
1416
 
1363
1417
  expect(subject).to receive(:get_existing_timeboard_by_name).once
1364
1418
  .with('t')
1365
1419
  expect(dog).to_not receive(:create_dashboard)
1366
1420
  expect(dog).to_not receive(:update_dashboard)
1367
1421
  expect(subject.logger).to receive(:info).with("\tTimeboard is up-to-date")
1422
+ expect(subject).to_not receive(:check_dog_result)
1368
1423
  subject.upsert_timeboard('t', [1, 2])
1369
1424
  end
1370
1425
  it 'updates if title changed' do
@@ -1382,11 +1437,12 @@ describe DogTrainer::API do
1382
1437
  ]
1383
1438
  dog = double(Dogapi::Client)
1384
1439
  allow(dog).to receive(:create_dashboard).with(any_args)
1385
- allow(dog).to receive(:update_dashboard).with(any_args)
1440
+ allow(dog).to receive(:update_dashboard).with(any_args).and_return(res)
1386
1441
  subject.instance_variable_set('@dog', dog)
1387
1442
  allow(subject).to receive(:get_existing_timeboard_by_name).with(any_args)
1388
1443
  .and_return(res[1])
1389
1444
  allow(subject.logger).to receive(:info).with(any_args)
1445
+ allow(subject).to receive(:check_dog_result)
1390
1446
 
1391
1447
  expect(subject).to receive(:get_existing_timeboard_by_name).once
1392
1448
  .with('t')
@@ -1399,6 +1455,7 @@ describe DogTrainer::API do
1399
1455
  )
1400
1456
  expect(subject.logger).to receive(:info).with("\tUpdating timeboard id1")
1401
1457
  expect(subject.logger).to receive(:info).with("\tTimeboard updated.")
1458
+ expect(subject).to receive(:check_dog_result).once.with(res)
1402
1459
  subject.upsert_timeboard('t', [1, 2])
1403
1460
  end
1404
1461
  it 'updates if repo_path changed' do
@@ -1416,11 +1473,12 @@ describe DogTrainer::API do
1416
1473
  ]
1417
1474
  dog = double(Dogapi::Client)
1418
1475
  allow(dog).to receive(:create_dashboard).with(any_args)
1419
- allow(dog).to receive(:update_dashboard).with(any_args)
1476
+ allow(dog).to receive(:update_dashboard).with(any_args).and_return(res)
1420
1477
  subject.instance_variable_set('@dog', dog)
1421
1478
  allow(subject).to receive(:get_existing_timeboard_by_name).with(any_args)
1422
1479
  .and_return(res[1])
1423
1480
  allow(subject.logger).to receive(:info).with(any_args)
1481
+ allow(subject).to receive(:check_dog_result)
1424
1482
 
1425
1483
  expect(subject).to receive(:get_existing_timeboard_by_name).once
1426
1484
  .with('t')
@@ -1433,6 +1491,7 @@ describe DogTrainer::API do
1433
1491
  )
1434
1492
  expect(subject.logger).to receive(:info).with("\tUpdating timeboard id1")
1435
1493
  expect(subject.logger).to receive(:info).with("\tTimeboard updated.")
1494
+ expect(subject).to receive(:check_dog_result).once.with(res)
1436
1495
  subject.upsert_timeboard('t', [1, 2])
1437
1496
  end
1438
1497
  it 'updates if graphs changed' do
@@ -1450,11 +1509,12 @@ describe DogTrainer::API do
1450
1509
  ]
1451
1510
  dog = double(Dogapi::Client)
1452
1511
  allow(dog).to receive(:create_dashboard).with(any_args)
1453
- allow(dog).to receive(:update_dashboard).with(any_args)
1512
+ allow(dog).to receive(:update_dashboard).with(any_args).and_return(res)
1454
1513
  subject.instance_variable_set('@dog', dog)
1455
1514
  allow(subject).to receive(:get_existing_timeboard_by_name).with(any_args)
1456
1515
  .and_return(res[1])
1457
1516
  allow(subject.logger).to receive(:info).with(any_args)
1517
+ allow(subject).to receive(:check_dog_result)
1458
1518
 
1459
1519
  expect(subject).to receive(:get_existing_timeboard_by_name).once
1460
1520
  .with('t')
@@ -1467,6 +1527,7 @@ describe DogTrainer::API do
1467
1527
  )
1468
1528
  expect(subject.logger).to receive(:info).with("\tUpdating timeboard id1")
1469
1529
  expect(subject.logger).to receive(:info).with("\tTimeboard updated.")
1530
+ expect(subject).to receive(:check_dog_result).once.with(res)
1470
1531
  subject.upsert_timeboard('t', [3, 4])
1471
1532
  end
1472
1533
  end
@@ -1487,6 +1548,7 @@ describe DogTrainer::API do
1487
1548
  subject.instance_variable_set('@dog', dog)
1488
1549
  allow(subject).to receive(:get_existing_screenboard_by_name)
1489
1550
  .with(any_args).and_return(nil)
1551
+ allow(subject).to receive(:check_dog_result)
1490
1552
  allow(subject.logger).to receive(:info).with(any_args)
1491
1553
 
1492
1554
  expect(subject).to receive(:get_existing_screenboard_by_name).once
@@ -1499,6 +1561,7 @@ describe DogTrainer::API do
1499
1561
  )
1500
1562
  expect(dog).to_not receive(:update_screenboard)
1501
1563
  expect(subject.logger).to receive(:info).with('Created screenboard id1')
1564
+ expect(subject).to receive(:check_dog_result).once.with(res)
1502
1565
  subject.upsert_screenboard('t', [1, 2])
1503
1566
  end
1504
1567
  it 'does nothing if it is up to date' do
@@ -1517,6 +1580,7 @@ describe DogTrainer::API do
1517
1580
  subject.instance_variable_set('@dog', dog)
1518
1581
  allow(subject).to receive(:get_existing_screenboard_by_name)
1519
1582
  .with(any_args).and_return(res[1])
1583
+ allow(subject).to receive(:check_dog_result)
1520
1584
  allow(subject.logger).to receive(:info).with(any_args)
1521
1585
 
1522
1586
  expect(subject).to receive(:get_existing_screenboard_by_name).once
@@ -1525,6 +1589,7 @@ describe DogTrainer::API do
1525
1589
  expect(dog).to_not receive(:update_screenboard)
1526
1590
  expect(subject.logger).to receive(:info)
1527
1591
  .with("\tScreenboard is up-to-date")
1592
+ expect(subject).to_not receive(:check_dog_result)
1528
1593
  subject.upsert_screenboard('t', [1, 2])
1529
1594
  end
1530
1595
  it 'updates if repo_path in description is different' do
@@ -1539,10 +1604,11 @@ describe DogTrainer::API do
1539
1604
  ]
1540
1605
  dog = double(Dogapi::Client)
1541
1606
  allow(dog).to receive(:create_screenboard).with(any_args)
1542
- allow(dog).to receive(:update_screenboard).with(any_args)
1607
+ allow(dog).to receive(:update_screenboard).with(any_args).and_return(res)
1543
1608
  subject.instance_variable_set('@dog', dog)
1544
1609
  allow(subject).to receive(:get_existing_screenboard_by_name)
1545
1610
  .with(any_args).and_return(res[1])
1611
+ allow(subject).to receive(:check_dog_result)
1546
1612
  allow(subject.logger).to receive(:info).with(any_args)
1547
1613
 
1548
1614
  expect(subject).to receive(:get_existing_screenboard_by_name).once
@@ -1555,6 +1621,8 @@ describe DogTrainer::API do
1555
1621
  description: 'created by DogTrainer RubyGem via my_repo_path',
1556
1622
  widgets: [1, 2]
1557
1623
  )
1624
+ expect(subject.logger).to receive(:info).with("\tScreenboard updated.")
1625
+ expect(subject).to receive(:check_dog_result).once.with(res)
1558
1626
  subject.upsert_screenboard('t', [1, 2])
1559
1627
  end
1560
1628
  it 'updates if title is different' do
@@ -1569,10 +1637,11 @@ describe DogTrainer::API do
1569
1637
  ]
1570
1638
  dog = double(Dogapi::Client)
1571
1639
  allow(dog).to receive(:create_screenboard).with(any_args)
1572
- allow(dog).to receive(:update_screenboard).with(any_args)
1640
+ allow(dog).to receive(:update_screenboard).with(any_args).and_return(res)
1573
1641
  subject.instance_variable_set('@dog', dog)
1574
1642
  allow(subject).to receive(:get_existing_screenboard_by_name)
1575
1643
  .with(any_args).and_return(res[1])
1644
+ allow(subject).to receive(:check_dog_result)
1576
1645
  allow(subject.logger).to receive(:info).with(any_args)
1577
1646
 
1578
1647
  expect(subject).to receive(:get_existing_screenboard_by_name).once
@@ -1585,6 +1654,8 @@ describe DogTrainer::API do
1585
1654
  description: 'created by DogTrainer RubyGem via my_repo_path',
1586
1655
  widgets: [1, 2]
1587
1656
  )
1657
+ expect(subject.logger).to receive(:info).with("\tScreenboard updated.")
1658
+ expect(subject).to receive(:check_dog_result).once.with(res)
1588
1659
  subject.upsert_screenboard('t', [1, 2])
1589
1660
  end
1590
1661
  it 'updates if widgets are different' do
@@ -1599,10 +1670,11 @@ describe DogTrainer::API do
1599
1670
  ]
1600
1671
  dog = double(Dogapi::Client)
1601
1672
  allow(dog).to receive(:create_screenboard).with(any_args)
1602
- allow(dog).to receive(:update_screenboard).with(any_args)
1673
+ allow(dog).to receive(:update_screenboard).with(any_args).and_return(res)
1603
1674
  subject.instance_variable_set('@dog', dog)
1604
1675
  allow(subject).to receive(:get_existing_screenboard_by_name)
1605
1676
  .with(any_args).and_return(res[1])
1677
+ allow(subject).to receive(:check_dog_result)
1606
1678
  allow(subject.logger).to receive(:info).with(any_args)
1607
1679
 
1608
1680
  expect(subject).to receive(:get_existing_screenboard_by_name).once
@@ -1615,6 +1687,8 @@ describe DogTrainer::API do
1615
1687
  description: 'created by DogTrainer RubyGem via my_repo_path',
1616
1688
  widgets: [1, 2]
1617
1689
  )
1690
+ expect(subject.logger).to receive(:info).with("\tScreenboard updated.")
1691
+ expect(subject).to receive(:check_dog_result).once.with(res)
1618
1692
  subject.upsert_screenboard('t', [1, 2])
1619
1693
  end
1620
1694
  end
@@ -0,0 +1,50 @@
1
+ require 'dogtrainer'
2
+
3
+ describe DogTrainer::DogApiException do
4
+ subject { DogTrainer::DogApiException }
5
+ describe 'attr_readers' do
6
+ it 'has statuscode attr_reader' do
7
+ expect(subject.new(['500', { 'errors' => ['foo'] }]).statuscode)
8
+ .to eq('500')
9
+ end
10
+ it 'has content attr_reader' do
11
+ expect(subject.new(['500', { 'errors' => ['foo'] }]).content)
12
+ .to eq('errors' => ['foo'])
13
+ end
14
+ end
15
+ describe 'when response is a single-element array' do
16
+ it 'sets content to an empty hash' do
17
+ expect(subject.new(['500']).content).to eq({})
18
+ end
19
+ end
20
+ describe 'with errors in content' do
21
+ context 'when errors is an Array' do
22
+ it 'includes errors in the message' do
23
+ # rubocop:disable Style/WordArray
24
+ x = subject.new(['500', { 'errors' => ['foo', "bar\nbaz"] }])
25
+ # rubocop:enable Style/WordArray
26
+ expect(x.to_s)
27
+ .to eq("Datadog API call returned status 500:\nfoo\nbar\nbaz\n")
28
+ end
29
+ end
30
+ context 'when errors is a String' do
31
+ it 'includes errors in the message' do
32
+ x = subject.new(['500', { 'errors' => 'foo' }])
33
+ expect(x.to_s)
34
+ .to eq("Datadog API call returned status 500:\nfoo\n")
35
+ end
36
+ end
37
+ end
38
+ describe 'without errors in content' do
39
+ it 'does not include errors in the message' do
40
+ x = subject.new(['500', {}])
41
+ expect(x.to_s).to eq('Datadog API call returned status 500')
42
+ end
43
+ end
44
+ describe 'with a nil content' do
45
+ it 'produces a correct message' do
46
+ x = subject.new(['404', {}])
47
+ expect(x.to_s).to eq('Datadog API call returned status 404')
48
+ end
49
+ end
50
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dogtrainer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - jantman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-19 00:00:00.000000000 Z
11
+ date: 2017-02-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dogapi
@@ -386,10 +386,12 @@ files:
386
386
  - dogtrainer.gemspec
387
387
  - lib/dogtrainer.rb
388
388
  - lib/dogtrainer/api.rb
389
+ - lib/dogtrainer/dogapiexception.rb
389
390
  - lib/dogtrainer/logging.rb
390
391
  - lib/dogtrainer/version.rb
391
392
  - spec/spec_helper.rb
392
393
  - spec/unit/api_spec.rb
394
+ - spec/unit/dogapiexception_spec.rb
393
395
  - spec/unit/logging_spec.rb
394
396
  homepage: http://github.com/Manheim/dogtrainer
395
397
  licenses:
@@ -420,4 +422,5 @@ summary: Wrapper around DataDog dogapi gem to simplify creation and management o
420
422
  test_files:
421
423
  - spec/spec_helper.rb
422
424
  - spec/unit/api_spec.rb
425
+ - spec/unit/dogapiexception_spec.rb
423
426
  - spec/unit/logging_spec.rb