wavefront-sdk 3.3.2 → 3.3.3

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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/HISTORY.md +42 -35
  3. data/README.md +5 -5
  4. data/lib/wavefront-sdk/alert.rb +2 -0
  5. data/lib/wavefront-sdk/core/api_caller.rb +6 -3
  6. data/lib/wavefront-sdk/defs/version.rb +2 -2
  7. data/lib/wavefront-sdk/derivedmetric.rb +7 -0
  8. data/lib/wavefront-sdk/externallink.rb +2 -2
  9. data/lib/wavefront-sdk/maintenancewindow.rb +6 -2
  10. data/lib/wavefront-sdk/notificant.rb +7 -0
  11. data/lib/wavefront-sdk/paginator/base.rb +8 -0
  12. data/lib/wavefront-sdk/search.rb +11 -2
  13. data/lib/wavefront-sdk/user.rb +39 -8
  14. data/lib/wavefront-sdk/webhook.rb +1 -1
  15. data/spec/constants.rb +30 -0
  16. data/spec/spec_helper.rb +12 -237
  17. data/spec/support/bad_mocket.rb +15 -0
  18. data/spec/support/hash.rb +9 -0
  19. data/spec/support/minitest_assertions.rb +110 -0
  20. data/spec/support/mocket.rb +19 -0
  21. data/spec/test_mixins/acl.rb +78 -0
  22. data/spec/test_mixins/general.rb +120 -0
  23. data/spec/test_mixins/tag.rb +55 -0
  24. data/spec/test_mixins/update_keys.rb +11 -0
  25. data/spec/wavefront-sdk/alert_spec.rb +88 -136
  26. data/spec/wavefront-sdk/apitoken_spec.rb +26 -13
  27. data/spec/wavefront-sdk/cloudintegration_spec.rb +42 -44
  28. data/spec/wavefront-sdk/dashboard_spec.rb +53 -72
  29. data/spec/wavefront-sdk/derivedmetric_spec.rb +23 -49
  30. data/spec/wavefront-sdk/distribution_spec.rb +14 -14
  31. data/spec/wavefront-sdk/event_spec.rb +39 -48
  32. data/spec/wavefront-sdk/externallink_spec.rb +19 -50
  33. data/spec/wavefront-sdk/integration_spec.rb +33 -38
  34. data/spec/wavefront-sdk/maintenancewindow_spec.rb +18 -33
  35. data/spec/wavefront-sdk/message_spec.rb +19 -4
  36. data/spec/wavefront-sdk/metric_spec.rb +13 -9
  37. data/spec/wavefront-sdk/notificant_spec.rb +16 -15
  38. data/spec/wavefront-sdk/proxy_spec.rb +20 -25
  39. data/spec/wavefront-sdk/query_spec.rb +50 -24
  40. data/spec/wavefront-sdk/report_spec.rb +3 -6
  41. data/spec/wavefront-sdk/resources/user_responses/add_user_groups.json +1 -0
  42. data/spec/wavefront-sdk/resources/user_responses/create.json +28 -0
  43. data/spec/wavefront-sdk/resources/user_responses/delete_multiple.json +1 -0
  44. data/spec/wavefront-sdk/resources/user_responses/describe.json +1 -0
  45. data/spec/wavefront-sdk/resources/user_responses/grant.json +1 -0
  46. data/spec/wavefront-sdk/resources/user_responses/list.json +1 -0
  47. data/spec/wavefront-sdk/savedsearch_spec.rb +41 -35
  48. data/spec/wavefront-sdk/search_spec.rb +35 -29
  49. data/spec/wavefront-sdk/settings_spec.rb +18 -12
  50. data/spec/wavefront-sdk/source_spec.rb +29 -32
  51. data/spec/wavefront-sdk/user_spec.rb +101 -74
  52. data/spec/wavefront-sdk/usergroup_spec.rb +56 -67
  53. data/spec/wavefront-sdk/webhook_spec.rb +22 -34
  54. data/spec/wavefront-sdk/write_spec.rb +2 -0
  55. data/spec/wavefront-sdk/writers/core_spec.rb +2 -0
  56. data/spec/wavefront-sdk/writers/summary_spec.rb +2 -0
  57. data/wavefront-sdk.gemspec +5 -5
  58. metadata +44 -13
@@ -0,0 +1,19 @@
1
+ # A mock socket
2
+ #
3
+ class Mocket
4
+ def puts(socket); end
5
+
6
+ def close; end
7
+
8
+ def ok?
9
+ true
10
+ end
11
+
12
+ def response
13
+ { sent: 1, rejected: 0, unsent: 0 }
14
+ end
15
+
16
+ def status
17
+ { result: 'OK', message: nil, code: nil }
18
+ end
19
+ end
@@ -0,0 +1,78 @@
1
+ module WavefrontTest
2
+ #
3
+ # require and include this module to get ACL tests
4
+ #
5
+ module Acl
6
+ def test_acls
7
+ assert_gets("/api/v2/#{api_class}/acl?id=#{id}&id=#{id.reverse}") do
8
+ wf.acls([id, id.reverse])
9
+ end
10
+ end
11
+
12
+ def test_acl_add
13
+ assert_posts("/api/v2/#{api_class}/acl/add",
14
+ acl_body(id, user_acls, group_acls)) do
15
+ wf.acl_add(id, user_acls, group_acls)
16
+ end
17
+
18
+ assert_posts("/api/v2/#{api_class}/acl/add",
19
+ acl_body(id, user_acls)) do
20
+ wf.acl_add(id, user_acls)
21
+ end
22
+
23
+ assert_raises(ArgumentError) { wf.acl_add(id, user_acls.first) }
24
+ assert_raises(ArgumentError) do
25
+ wf.acl_add(id, user_acls, group_acls.first)
26
+ end
27
+ end
28
+
29
+ def test_acl_delete
30
+ assert_posts("/api/v2/#{api_class}/acl/remove",
31
+ acl_body(id, user_acls, group_acls)) do
32
+ wf.acl_delete(id, user_acls, group_acls)
33
+ end
34
+
35
+ assert_posts("/api/v2/#{api_class}/acl/remove",
36
+ acl_body(id, user_acls)) do
37
+ wf.acl_delete(id, user_acls)
38
+ end
39
+
40
+ assert_raises(ArgumentError) { wf.acl_delete(id, U_ACL_1) }
41
+ end
42
+
43
+ def test_acl_set
44
+ assert_puts("/api/v2/#{api_class}/acl/set",
45
+ acl_body(id, user_acls, group_acls)) do
46
+ wf.acl_set(id, user_acls, group_acls)
47
+ end
48
+
49
+ assert_puts("/api/v2/#{api_class}/acl/set",
50
+ acl_body(id, user_acls)) do
51
+ wf.acl_set(id, user_acls)
52
+ end
53
+
54
+ assert_raises(ArgumentError) { wf.acl_set(id, U_ACL_1) }
55
+ end
56
+
57
+ private
58
+
59
+ # @return [Array[String]] list of user IDs for ACL testing
60
+ #
61
+ def user_acls
62
+ %w[someone@example.com other@elsewhere.com]
63
+ end
64
+
65
+ # @return [Array[String]] list of group IDs for ACL testing
66
+ #
67
+ def group_acls
68
+ %w[f8dc0c14-91a0-4ca9-8a2a-7d47f4db4672]
69
+ end
70
+
71
+ # @return [String] JSON representation of an ACL request
72
+ # payload
73
+ #
74
+ def acl_body(id, view = [], modify = [])
75
+ [{ entityId: id, viewAcl: view, modifyAcl: modify }].to_json
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,120 @@
1
+ module WavefrontTest
2
+ module List
3
+ def test_list
4
+ assert_gets("/api/v2/#{api_class}?offset=0&limit=100") do
5
+ wf.list
6
+ end
7
+
8
+ assert_gets("/api/v2/#{api_class}?offset=10&limit=100") do
9
+ wf.list(10)
10
+ end
11
+ end
12
+
13
+ def test_list_all
14
+ assert_gets("/api/v2/#{api_class}?limit=999&offset=0") do
15
+ wf.list(0, :all)
16
+ end
17
+
18
+ assert_gets("/api/v2/#{api_class}?limit=20&offset=0") do
19
+ wf.list(20, :all)
20
+ end
21
+ end
22
+ end
23
+
24
+ module Create
25
+ def test_create
26
+ [payload].flatten.each do |p|
27
+ assert_posts("/api/v2/#{api_class}", p) { wf.create(p) }
28
+ assert_raises(ArgumentError) { wf.create }
29
+ assert_raises(ArgumentError) { wf.create('test') }
30
+ end
31
+ end
32
+ end
33
+
34
+ module Describe
35
+ def test_describe
36
+ assert_gets("/api/v2/#{api_class}/#{id}") { wf.describe(id) }
37
+ assert_invalid_id { wf.describe(invalid_id) }
38
+ assert_raises(ArgumentError) { wf.describe }
39
+ end
40
+ end
41
+
42
+ module Delete
43
+ def test_delete
44
+ assert_deletes("/api/v2/#{api_class}/#{id}") { wf.delete(id) }
45
+ assert_invalid_id { wf.delete(invalid_id) }
46
+ assert_raises(ArgumentError) { wf.delete }
47
+ end
48
+ end
49
+
50
+ module DeleteUndelete
51
+ include Delete
52
+
53
+ def test_undelete
54
+ assert_posts("/api/v2/#{api_class}/#{id}/undelete") do
55
+ wf.undelete(id)
56
+ end
57
+
58
+ assert_invalid_id { wf.undelete(invalid_id) }
59
+ assert_raises(ArgumentError) { wf.undelete }
60
+ end
61
+ end
62
+
63
+ module Update
64
+ def test_update
65
+ [payload].flatten.each do |p|
66
+ assert_puts("/api/v2/#{api_class}/#{id}", p) do
67
+ wf.update(id, p, false)
68
+ end
69
+
70
+ assert_invalid_id { wf.update(invalid_id, p) }
71
+ assert_raises(ArgumentError) { wf.update }
72
+ end
73
+ end
74
+ end
75
+
76
+ module Clone
77
+ def test_clone
78
+ assert_posts("/api/v2/#{api_class}/#{id}/clone",
79
+ id: id, name: nil, v: nil) do
80
+ wf.clone(id)
81
+ end
82
+
83
+ assert_posts("/api/v2/#{api_class}/#{id}/clone",
84
+ id: id, name: nil, v: 4) do
85
+ wf.clone(id, 4)
86
+ end
87
+
88
+ assert_raises(ArgumentError) { wf.clone }
89
+ end
90
+ end
91
+
92
+ module InstallUninstall
93
+ def test_install
94
+ assert_posts("/api/v2/#{api_class}/#{id}/install") { wf.install(id) }
95
+ assert_invalid_id { wf.install(invalid_id) }
96
+ end
97
+
98
+ def test_uninstall
99
+ assert_posts("/api/v2/#{api_class}/#{id}/uninstall") do
100
+ wf.uninstall(id)
101
+ end
102
+
103
+ assert_invalid_id { wf.uninstall(invalid_id) }
104
+ end
105
+ end
106
+
107
+ module History
108
+ def test_describe_v
109
+ assert_gets("/api/v2/#{api_class}/#{id}/history/4") do
110
+ wf.describe(id, 4)
111
+ end
112
+ end
113
+
114
+ def test_history
115
+ assert_gets("/api/v2/#{api_class}/#{id}/history") { wf.history(id) }
116
+ assert_invalid_id { wf.history(invalid_id) }
117
+ assert_raises(ArgumentError) { wf.history }
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,55 @@
1
+ module WavefrontTest
2
+ #
3
+ # require and include this module to get tag tests
4
+ #
5
+ module Tag
6
+ def test_tags
7
+ assert_gets("/api/v2/#{api_class}/#{id}/tag") { wf.tags(id) }
8
+ assert_invalid_id { wf.tags(invalid_id) }
9
+ end
10
+
11
+ def test_tag_set
12
+ assert_posts("/api/v2/#{api_class}/#{id}/tag", '["mytag"]') do
13
+ wf.tag_set(id, 'mytag')
14
+ end
15
+
16
+ assert_posts("/api/v2/#{api_class}/#{id}/tag", '["tag1","tag2"]') do
17
+ wf.tag_set(id, %w[tag1 tag2])
18
+ end
19
+
20
+ assert_invalid_id { wf.tag_set(invalid_id, 'valid_tag') }
21
+
22
+ assert_raises(Wavefront::Exception::InvalidString) do
23
+ wf.tag_set(id, '<!!!>')
24
+ end
25
+ end
26
+
27
+ def test_tag_add
28
+ #
29
+ # We have to use a literal 'null' to trick assert_puts into
30
+ # checking for the right content-type
31
+ #
32
+ assert_puts("/api/v2/#{api_class}/#{id}/tag/mytag", 'null') do
33
+ wf.tag_add(id, 'mytag')
34
+ end
35
+
36
+ assert_invalid_id { wf.tag_add(invalid_id, 'valid_tag') }
37
+
38
+ assert_raises(Wavefront::Exception::InvalidString) do
39
+ wf.tag_add(id, '<!!!>')
40
+ end
41
+ end
42
+
43
+ def test_tag_delete
44
+ assert_deletes("/api/v2/#{api_class}/#{id}/tag/mytag") do
45
+ wf.tag_delete(id, 'mytag')
46
+ end
47
+
48
+ assert_invalid_id { wf.tag_delete(invalid_id, 'valid_tag') }
49
+
50
+ assert_raises(Wavefront::Exception::InvalidString) do
51
+ wf.tag_delete(id, '<!!!>')
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,11 @@
1
+ module WavefrontTest
2
+ #
3
+ # include this into any class which has update keys
4
+ #
5
+ module UpdateKeys
6
+ def test_update_keys
7
+ assert_instance_of Array, wf.update_keys
8
+ assert(wf.update_keys.all? { |k| k.is_a?(Symbol) })
9
+ end
10
+ end
11
+ end
@@ -1,191 +1,143 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require_relative '../spec_helper'
4
- require 'spy/integration'
5
-
6
- ALERT = '1481553823153'.freeze
7
- ALERT_BODY = {
8
- name: 'SDK test alert',
9
- target: 'user@example.com',
10
- condition: 'ts("app.errors") > 0',
11
- displayExpression: 'ts("app.errors")',
12
- minutes: 5,
13
- resolveAfterMinutes: 5,
14
- severity: 'INFO'
15
- }.freeze
16
-
17
- def search_body(val)
18
- { limit: 999,
19
- offset: 0,
20
- query: [
21
- { key: 'status',
22
- value: val,
23
- matchingMethod: 'EXACT' }
24
- ],
25
- sort: { field: 'status', ascending: true } }
26
- end
4
+ require_relative '../test_mixins/acl'
5
+ require_relative '../test_mixins/tag'
6
+ require_relative '../test_mixins/update_keys'
7
+ require_relative '../test_mixins/general'
27
8
 
28
9
  # Unit tests for Alert class
29
10
  #
30
11
  class WavefrontAlertTest < WavefrontTestBase
31
- def test_list
32
- should_work(:list, 10, '?offset=10&limit=100')
33
- end
34
-
35
- def test_list_all
36
- should_work(:list, [0, :all], '?limit=999&offset=0')
37
- should_work(:list, [20, :all], '?limit=20&offset=0')
38
- end
39
-
40
- def test_update_keys
41
- assert_instance_of(Array, wf.update_keys)
42
- wf.update_keys.each { |k| assert_instance_of(Symbol, k) }
43
- end
44
-
45
- def test_describe
46
- should_work(:describe, ALERT, ALERT)
47
- assert_raises(ArgumentError) { wf.describe }
48
- should_be_invalid(:describe)
49
- end
50
-
51
- def test_create
52
- should_work(:create, ALERT_BODY, '', :post, JSON_POST_HEADERS,
53
- ALERT_BODY.to_json)
54
- assert_raises(ArgumentError) { wf.create }
55
- assert_raises(ArgumentError) { wf.create('test') }
56
- end
57
-
58
- def test_clone
59
- should_work(:clone, [ALERT], [ALERT, :clone].uri_concat,
60
- :post, JSON_POST_HEADERS,
61
- { id: ALERT, name: nil, v: nil }.to_json)
62
- should_work(:clone, [ALERT, 4], [ALERT, :clone].uri_concat,
63
- :post, JSON_POST_HEADERS,
64
- { id: ALERT, name: nil, v: 4 }.to_json)
65
- assert_raises(ArgumentError) { wf.clone }
66
- end
67
-
68
- def test_describe_v
69
- should_work(:describe, [ALERT, 4], "#{ALERT}/history/4")
70
- end
71
-
72
- def test_delete
73
- should_work(:delete, ALERT, ALERT, :delete)
74
- should_be_invalid(:delete)
75
- end
76
-
77
- def test_history
78
- should_work(:history, ALERT, "#{ALERT}/history")
79
- should_be_invalid(:history)
80
- end
81
-
82
- def test_install
83
- should_work(:install, ALERT, "#{ALERT}/install", :post)
84
- should_be_invalid(:install)
85
- end
12
+ include WavefrontTest::Acl
13
+ include WavefrontTest::Clone
14
+ include WavefrontTest::Create
15
+ include WavefrontTest::DeleteUndelete
16
+ include WavefrontTest::Describe
17
+ include WavefrontTest::History
18
+ include WavefrontTest::InstallUninstall
19
+ include WavefrontTest::List
20
+ include WavefrontTest::Tag
21
+ include WavefrontTest::Update
22
+ include WavefrontTest::UpdateKeys
86
23
 
87
24
  def test_snooze
88
- should_work(:snooze, ALERT, "#{ALERT}/snooze", :post, POST_HEADERS)
89
- should_work(:snooze, [ALERT, 3600], "#{ALERT}/snooze?seconds=3600",
90
- :post, POST_HEADERS)
91
- should_be_invalid(:snooze)
92
- end
25
+ assert_posts("/api/v2/alert/#{id}/snooze") { wf.snooze(id) }
93
26
 
94
- def test_update
95
- should_work(:update, [ALERT, ALERT_BODY, false], ALERT, :put,
96
- JSON_POST_HEADERS, ALERT_BODY)
97
- should_be_invalid(:update, ['abcde', ALERT_BODY])
98
- assert_raises(ArgumentError) { wf.update }
99
- end
100
-
101
- def test_tags
102
- tag_tester(ALERT)
103
- end
27
+ assert_posts("/api/v2/alert/#{id}/snooze?seconds=3600") do
28
+ wf.snooze(id, 3600)
29
+ end
104
30
 
105
- def test_acls
106
- acl_tester(ALERT)
107
- end
108
-
109
- def test_undelete
110
- should_work(:undelete, ALERT, ["#{ALERT}/undelete", nil], :post,
111
- POST_HEADERS)
112
- should_be_invalid(:undelete)
113
- end
114
-
115
- def test_uninstall
116
- should_work(:uninstall, ALERT, "#{ALERT}/uninstall", :post)
117
- should_be_invalid(:uninstall)
31
+ assert_invalid_id { wf.snooze(invalid_id) }
118
32
  end
119
33
 
120
34
  def test_unsnooze
121
- should_work(:unsnooze, ALERT, ["#{ALERT}/unsnooze", nil], :post,
122
- POST_HEADERS)
123
- should_be_invalid(:unsnooze)
35
+ assert_posts("/api/v2/alert/#{id}/unsnooze") { wf.unsnooze(id) }
36
+ assert_invalid_id { wf.unsnooze(invalid_id) }
124
37
  end
125
38
 
126
39
  def test_summary
127
- should_work(:summary, nil, 'summary')
40
+ assert_gets('/api/v2/alert/summary') { wf.summary }
128
41
  end
129
42
 
130
43
  def test_alerts_in_state
131
- should_work(:alerts_in_state, 'some_state', '/api/v2/search/alert',
132
- :post, {}, search_body('some_state'))
44
+ assert_posts('/api/v2/search/alert', search_payload('state')) do
45
+ wf.alerts_in_state('state')
46
+ end
133
47
  end
134
48
 
135
49
  def test_firing
136
- should_work(:firing, nil, '/api/v2/search/alert', :post, {},
137
- search_body('firing'))
50
+ assert_posts('/api/v2/search/alert', search_payload('firing')) do
51
+ wf.firing
52
+ end
138
53
  end
139
54
 
140
55
  def test_active
141
- should_work(:firing, nil, '/api/v2/search/alert', :post, {},
142
- search_body('firing'))
56
+ assert_posts('/api/v2/search/alert', search_payload('firing')) do
57
+ wf.active
58
+ end
143
59
  end
144
60
 
145
61
  def test_affected_by_maintenance
146
- should_work(:affected_by_maintenance, nil, '/api/v2/search/alert',
147
- :post, {}, search_body('in_maintenance'))
62
+ assert_posts('/api/v2/search/alert',
63
+ search_payload('in_maintenance')) do
64
+ wf.affected_by_maintenance
65
+ end
148
66
  end
149
67
 
150
68
  def test_invalid
151
- should_work(:invalid, nil, '/api/v2/search/alert', :post, {},
152
- search_body('invalid'))
153
- end
154
-
155
- def test_in_maintenance
156
- should_work(:affected_by_maintenance, nil, '/api/v2/search/alert',
157
- :post, {}, search_body('in_maintenance'))
69
+ assert_posts('/api/v2/search/alert', search_payload('invalid')) do
70
+ wf.invalid
71
+ end
158
72
  end
159
73
 
160
74
  def test_none
161
- should_work(:none, nil, '/api/v2/search/alert', :post, {},
162
- search_body('none'))
75
+ assert_posts('/api/v2/search/alert', search_payload('none')) do
76
+ wf.none
77
+ end
163
78
  end
164
79
 
165
80
  def test_checking
166
- should_work(:checking, nil, '/api/v2/search/alert', :post, {},
167
- search_body('checking'))
81
+ assert_posts('/api/v2/search/alert', search_payload('checking')) do
82
+ wf.checking
83
+ end
168
84
  end
169
85
 
170
86
  def test_trash
171
- should_work(:trash, nil, '/api/v2/search/alert', :post, {},
172
- search_body('trash'))
87
+ assert_posts('/api/v2/search/alert', search_payload('trash')) do
88
+ wf.trash
89
+ end
173
90
  end
174
91
 
175
92
  def test_no_data
176
- should_work(:no_data, nil, '/api/v2/search/alert',
177
- :post, {}, search_body('no_data'))
93
+ assert_posts('/api/v2/search/alert', search_payload('no_data')) do
94
+ wf.no_data
95
+ end
178
96
  end
179
97
 
180
98
  def test_snoozed
181
- should_work(:snoozed, nil, '/api/v2/search/alert',
182
- :post, {}, search_body('snoozed'))
99
+ assert_posts('/api/v2/search/alert', search_payload('snoozed')) do
100
+ wf.snoozed
101
+ end
183
102
  end
184
103
 
185
104
  # Not a full test, because it's a recursive API call. Just test
186
105
  # the first API call is made correctly.
187
106
  #
188
107
  def test_all
189
- should_work(:all, nil, '?offset=0&limit=999')
108
+ assert_gets("/api/v2/#{api_class}?offset=0&limit=999") { wf.all }
109
+ end
110
+
111
+ private
112
+
113
+ # used by the things we #include
114
+ #
115
+ def api_class
116
+ 'alert'
117
+ end
118
+
119
+ def id
120
+ '1481553823153'
121
+ end
122
+
123
+ def invalid_id
124
+ 'invalid_alert'
125
+ end
126
+
127
+ def payload
128
+ { name: 'SDK test alert',
129
+ target: 'user@example.com',
130
+ condition: 'ts("app.errors") > 0',
131
+ displayExpression: 'ts("app.errors")',
132
+ minutes: 5,
133
+ resolveAfterMinutes: 5,
134
+ severity: 'INFO' }
135
+ end
136
+
137
+ def search_payload(value)
138
+ { limit: 999,
139
+ offset: 0,
140
+ query: [{ key: 'status', value: value, matchingMethod: 'EXACT' }],
141
+ sort: { field: 'status', ascending: true } }
190
142
  end
191
143
  end