wavefront-cli 4.2.1 → 4.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +1 -0
- data/.rubocop.yml +1 -14
- data/.travis.yml +4 -4
- data/Gemfile +2 -0
- data/HISTORY.md +82 -60
- data/Rakefile +2 -0
- data/bin/wf +1 -0
- data/lib/wavefront-cli/alert.rb +13 -5
- data/lib/wavefront-cli/apitoken.rb +2 -0
- data/lib/wavefront-cli/base.rb +95 -47
- data/lib/wavefront-cli/cloudintegration.rb +6 -0
- data/lib/wavefront-cli/command_mixins/acl.rb +6 -1
- data/lib/wavefront-cli/command_mixins/tag.rb +2 -0
- data/lib/wavefront-cli/commands/.rubocop.yml +3 -4
- data/lib/wavefront-cli/commands/alert.rb +2 -1
- data/lib/wavefront-cli/commands/apitoken.rb +6 -0
- data/lib/wavefront-cli/commands/base.rb +30 -21
- data/lib/wavefront-cli/commands/cloudintegration.rb +2 -0
- data/lib/wavefront-cli/commands/config.rb +2 -0
- data/lib/wavefront-cli/commands/dashboard.rb +2 -0
- data/lib/wavefront-cli/commands/derivedmetric.rb +2 -0
- data/lib/wavefront-cli/commands/event.rb +3 -1
- data/lib/wavefront-cli/commands/integration.rb +2 -1
- data/lib/wavefront-cli/commands/link.rb +2 -0
- data/lib/wavefront-cli/commands/message.rb +2 -0
- data/lib/wavefront-cli/commands/metric.rb +2 -0
- data/lib/wavefront-cli/commands/notificant.rb +2 -0
- data/lib/wavefront-cli/commands/proxy.rb +2 -0
- data/lib/wavefront-cli/commands/query.rb +2 -0
- data/lib/wavefront-cli/commands/savedsearch.rb +2 -0
- data/lib/wavefront-cli/commands/serviceaccount.rb +58 -0
- data/lib/wavefront-cli/commands/settings.rb +2 -0
- data/lib/wavefront-cli/commands/source.rb +3 -1
- data/lib/wavefront-cli/commands/user.rb +4 -1
- data/lib/wavefront-cli/commands/usergroup.rb +3 -0
- data/lib/wavefront-cli/commands/webhook.rb +2 -0
- data/lib/wavefront-cli/commands/window.rb +2 -0
- data/lib/wavefront-cli/commands/write.rb +2 -0
- data/lib/wavefront-cli/config.rb +23 -12
- data/lib/wavefront-cli/constants.rb +10 -4
- data/lib/wavefront-cli/controller.rb +53 -22
- data/lib/wavefront-cli/dashboard.rb +3 -0
- data/lib/wavefront-cli/derivedmetric.rb +12 -11
- data/lib/wavefront-cli/display/alert.rb +7 -4
- data/lib/wavefront-cli/display/apitoken.rb +2 -0
- data/lib/wavefront-cli/display/base.rb +34 -8
- data/lib/wavefront-cli/display/cloudintegration.rb +4 -2
- data/lib/wavefront-cli/display/dashboard.rb +2 -0
- data/lib/wavefront-cli/display/derivedmetric.rb +2 -0
- data/lib/wavefront-cli/display/distribution.rb +2 -0
- data/lib/wavefront-cli/display/event.rb +2 -0
- data/lib/wavefront-cli/display/externallink.rb +2 -0
- data/lib/wavefront-cli/display/integration.rb +2 -0
- data/lib/wavefront-cli/display/maintenancewindow.rb +2 -0
- data/lib/wavefront-cli/display/message.rb +7 -3
- data/lib/wavefront-cli/display/metric.rb +3 -1
- data/lib/wavefront-cli/display/notificant.rb +3 -1
- data/lib/wavefront-cli/display/printer/long.rb +36 -11
- data/lib/wavefront-cli/display/printer/sparkline.rb +3 -0
- data/lib/wavefront-cli/display/printer/terse.rb +6 -1
- data/lib/wavefront-cli/display/proxy.rb +2 -0
- data/lib/wavefront-cli/display/query.rb +35 -24
- data/lib/wavefront-cli/display/savedsearch.rb +2 -0
- data/lib/wavefront-cli/display/serviceaccount.rb +60 -0
- data/lib/wavefront-cli/display/settings.rb +2 -0
- data/lib/wavefront-cli/display/source.rb +18 -4
- data/lib/wavefront-cli/display/user.rb +56 -10
- data/lib/wavefront-cli/display/usergroup.rb +25 -19
- data/lib/wavefront-cli/display/webhook.rb +2 -0
- data/lib/wavefront-cli/display/write.rb +6 -2
- data/lib/wavefront-cli/event.rb +83 -62
- data/lib/wavefront-cli/exception.rb +3 -0
- data/lib/wavefront-cli/externallink.rb +6 -4
- data/lib/wavefront-cli/integration.rb +2 -0
- data/lib/wavefront-cli/maintenancewindow.rb +28 -17
- data/lib/wavefront-cli/message.rb +4 -0
- data/lib/wavefront-cli/metric.rb +4 -1
- data/lib/wavefront-cli/notificant.rb +2 -0
- data/lib/wavefront-cli/opt_handler.rb +2 -0
- data/lib/wavefront-cli/output/base.rb +8 -3
- data/lib/wavefront-cli/output/csv.rb +2 -0
- data/lib/wavefront-cli/output/csv/base.rb +2 -0
- data/lib/wavefront-cli/output/csv/query.rb +14 -7
- data/lib/wavefront-cli/output/hcl.rb +2 -0
- data/lib/wavefront-cli/output/hcl/alert.rb +2 -0
- data/lib/wavefront-cli/output/hcl/base.rb +10 -4
- data/lib/wavefront-cli/output/hcl/dashboard.rb +17 -8
- data/lib/wavefront-cli/output/hcl/notificant.rb +2 -0
- data/lib/wavefront-cli/output/hcl/stdlib/array.rb +2 -0
- data/lib/wavefront-cli/output/hcl/stdlib/string.rb +2 -0
- data/lib/wavefront-cli/output/json.rb +2 -0
- data/lib/wavefront-cli/output/ruby.rb +2 -0
- data/lib/wavefront-cli/output/wavefront.rb +2 -0
- data/lib/wavefront-cli/output/wavefront/query.rb +7 -4
- data/lib/wavefront-cli/output/yaml.rb +2 -0
- data/lib/wavefront-cli/proxy.rb +15 -3
- data/lib/wavefront-cli/query.rb +14 -12
- data/lib/wavefront-cli/savedsearch.rb +2 -0
- data/lib/wavefront-cli/serviceaccount.rb +179 -0
- data/lib/wavefront-cli/settings.rb +2 -0
- data/lib/wavefront-cli/source.rb +2 -0
- data/lib/wavefront-cli/stdlib/array.rb +3 -0
- data/lib/wavefront-cli/stdlib/string.rb +17 -11
- data/lib/wavefront-cli/user.rb +10 -4
- data/lib/wavefront-cli/usergroup.rb +4 -2
- data/lib/wavefront-cli/version.rb +3 -1
- data/lib/wavefront-cli/webhook.rb +2 -0
- data/lib/wavefront-cli/write.rb +80 -46
- data/spec/.rubocop.yml +3 -16
- data/spec/constants.rb +21 -0
- data/spec/spec_helper.rb +8 -422
- data/spec/support/command_base.rb +82 -0
- data/spec/support/minitest_assertions.rb +262 -0
- data/spec/support/output_tester.rb +32 -0
- data/spec/support/supported_commands.rb +19 -0
- data/spec/test_mixins/acl.rb +169 -0
- data/spec/test_mixins/delete.rb +25 -0
- data/spec/test_mixins/deleteundelete.rb +106 -0
- data/spec/test_mixins/describe.rb +24 -0
- data/spec/test_mixins/dump.rb +43 -0
- data/spec/test_mixins/general.rb +11 -0
- data/spec/test_mixins/history.rb +35 -0
- data/spec/test_mixins/import.rb +65 -0
- data/spec/test_mixins/list.rb +29 -0
- data/spec/test_mixins/search.rb +98 -0
- data/spec/test_mixins/set.rb +47 -0
- data/spec/test_mixins/tag.rb +99 -0
- data/spec/wavefront-cli/alert_spec.rb +288 -111
- data/spec/wavefront-cli/apitoken_spec.rb +53 -24
- data/spec/wavefront-cli/base_spec.rb +9 -27
- data/spec/wavefront-cli/cloudintegration_spec.rb +65 -29
- data/spec/wavefront-cli/commands/alert_spec.rb +1 -0
- data/spec/wavefront-cli/commands/base_spec.rb +15 -13
- data/spec/wavefront-cli/commands/cloudintegration_spec.rb +1 -0
- data/spec/wavefront-cli/commands/config_spec.rb +3 -0
- data/spec/wavefront-cli/commands/dashboard_spec.rb +1 -0
- data/spec/wavefront-cli/commands/derivedmetric_spec.rb +1 -0
- data/spec/wavefront-cli/commands/event_spec.rb +1 -0
- data/spec/wavefront-cli/commands/link_spec.rb +1 -0
- data/spec/wavefront-cli/commands/message_spec.rb +1 -0
- data/spec/wavefront-cli/commands/metric_spec.rb +1 -0
- data/spec/wavefront-cli/commands/proxy_spec.rb +1 -0
- data/spec/wavefront-cli/commands/query_spec.rb +1 -0
- data/spec/wavefront-cli/commands/webhook_spec.rb +1 -0
- data/spec/wavefront-cli/commands/window_spec.rb +1 -0
- data/spec/wavefront-cli/commands/write_spec.rb +1 -0
- data/spec/wavefront-cli/config_spec.rb +25 -14
- data/spec/wavefront-cli/controller_spec.rb +13 -3
- data/spec/wavefront-cli/dashboard_spec.rb +125 -76
- data/spec/wavefront-cli/derivedmetric_spec.rb +83 -67
- data/spec/wavefront-cli/display/base_spec.rb +5 -7
- data/spec/wavefront-cli/display/printer/long_spec.rb +20 -16
- data/spec/wavefront-cli/display/printer/terse_spec.rb +5 -4
- data/spec/wavefront-cli/event_spec.rb +360 -18
- data/spec/wavefront-cli/externallink_spec.rb +92 -58
- data/spec/wavefront-cli/integration_spec.rb +129 -31
- data/spec/wavefront-cli/maintenancewindow_spec.rb +270 -32
- data/spec/wavefront-cli/message_spec.rb +73 -30
- data/spec/wavefront-cli/metric_spec.rb +60 -22
- data/spec/wavefront-cli/notificant_spec.rb +45 -32
- data/spec/wavefront-cli/opt_handler_spec.rb +4 -1
- data/spec/wavefront-cli/output/csv/query_spec.rb +21 -19
- data/spec/wavefront-cli/output/csv_spec.rb +5 -2
- data/spec/wavefront-cli/output/hcl_spec.rb +5 -2
- data/spec/wavefront-cli/output/helpers.rb +18 -0
- data/spec/wavefront-cli/output/json_spec.rb +3 -1
- data/spec/wavefront-cli/output/ruby_spec.rb +3 -1
- data/spec/wavefront-cli/output/wavefront/query_spec.rb +3 -1
- data/spec/wavefront-cli/output/wavefront_spec.rb +6 -4
- data/spec/wavefront-cli/output/yaml_spec.rb +3 -1
- data/spec/wavefront-cli/proxy_spec.rb +49 -27
- data/spec/wavefront-cli/query_spec.rb +174 -92
- data/spec/wavefront-cli/resources/responses/query.json +1 -0
- data/spec/wavefront-cli/resources/updates/alert.json +15 -0
- data/spec/wavefront-cli/resources/updates/dashboard.json +1 -0
- data/spec/wavefront-cli/savedsearch_spec.rb +35 -18
- data/spec/wavefront-cli/serviceaccount_spec.rb +399 -0
- data/spec/wavefront-cli/settings_spec.rb +42 -11
- data/spec/wavefront-cli/source_spec.rb +120 -23
- data/spec/wavefront-cli/stdlib/array_spec.rb +2 -1
- data/spec/wavefront-cli/stdlib/string_spec.rb +9 -6
- data/spec/wavefront-cli/user_spec.rb +278 -108
- data/spec/wavefront-cli/usergroup_spec.rb +152 -102
- data/spec/wavefront-cli/webhook_spec.rb +30 -15
- data/spec/wavefront-cli/write_spec.rb +25 -1
- data/wavefront-cli.gemspec +5 -3
- metadata +65 -21
- data/spec/wavefront-cli/commands/spec_helper.rb +0 -3
- data/spec/wavefront-cli/display/spec_helper.rb +0 -3
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require_relative '../support/minitest_assertions'
|
5
|
+
require_relative '../test_mixins/general'
|
6
|
+
require_relative '../../lib/wavefront-cli/controller'
|
7
|
+
|
8
|
+
# An abstract class which facilitates "end-to-end" testing of
|
9
|
+
# commands.
|
10
|
+
#
|
11
|
+
class EndToEndTest < MiniTest::Test
|
12
|
+
attr_reader :wf
|
13
|
+
|
14
|
+
def setup
|
15
|
+
before_setup if respond_to?(:before_setup)
|
16
|
+
@wf = WavefrontCliController
|
17
|
+
end
|
18
|
+
|
19
|
+
def api_path
|
20
|
+
cmd_word
|
21
|
+
end
|
22
|
+
|
23
|
+
def search_api_path
|
24
|
+
api_path
|
25
|
+
end
|
26
|
+
|
27
|
+
def cmd_class
|
28
|
+
Object.const_get("WavefrontCli::#{sdk_class_name}")
|
29
|
+
end
|
30
|
+
|
31
|
+
def cmd_instance
|
32
|
+
cmd_class.new({})
|
33
|
+
end
|
34
|
+
|
35
|
+
def sdk_class_name
|
36
|
+
api_path.capitalize
|
37
|
+
end
|
38
|
+
|
39
|
+
# Fields which must not be in import objects
|
40
|
+
#
|
41
|
+
def blocked_import_fields
|
42
|
+
%i[id]
|
43
|
+
end
|
44
|
+
|
45
|
+
# the key to use when testing the 'set' command. The value is
|
46
|
+
# always 'new_value'
|
47
|
+
#
|
48
|
+
def set_key
|
49
|
+
'name'
|
50
|
+
end
|
51
|
+
|
52
|
+
def friendly_name
|
53
|
+
cmd_word
|
54
|
+
end
|
55
|
+
|
56
|
+
def wall_time
|
57
|
+
half_an_hour_ago = TEE_ZERO - (30 * 60)
|
58
|
+
start_time = Time.at(half_an_hour_ago.to_i - half_an_hour_ago.sec)
|
59
|
+
[start_time, Time.at(start_time + (10 * 60))]
|
60
|
+
end
|
61
|
+
|
62
|
+
def epoch_time
|
63
|
+
wall_time.map { |t| parse_time(t, true) }
|
64
|
+
end
|
65
|
+
|
66
|
+
def start_and_end_opts
|
67
|
+
format('-s %<start_time>s -e %<end_time>s',
|
68
|
+
start_time: wall_time[0].strftime('%H:%M'),
|
69
|
+
end_time: wall_time[1].strftime('%H:%M'))
|
70
|
+
end
|
71
|
+
|
72
|
+
# Set this to true for things that use cursors rather than offsets
|
73
|
+
#
|
74
|
+
def cannot_handle_offsets
|
75
|
+
false
|
76
|
+
end
|
77
|
+
|
78
|
+
def dummy_response
|
79
|
+
{ status: { result: 'OK', message: '', code: 200 },
|
80
|
+
items: [] }.to_json
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,262 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spy'
|
4
|
+
require 'webmock/minitest'
|
5
|
+
require_relative '../constants'
|
6
|
+
|
7
|
+
# rubocop:disable Metrics/ModuleLength
|
8
|
+
module Minitest
|
9
|
+
#
|
10
|
+
# Custom assertions to facilitate CLI command testing
|
11
|
+
#
|
12
|
+
module Assertions
|
13
|
+
def assert_gets(api_path, headers, response, &block)
|
14
|
+
stub = stub_request(:get, api_path)
|
15
|
+
.with(headers: headers)
|
16
|
+
.to_return(body: response, status: 200)
|
17
|
+
yield block
|
18
|
+
assert_requested(stub)
|
19
|
+
end
|
20
|
+
|
21
|
+
def assert_gets_with_params(api_path, params, headers, response, &block)
|
22
|
+
stub = stub_request(:get, api_path)
|
23
|
+
.with(query: hash_including(params),
|
24
|
+
headers: headers)
|
25
|
+
.to_return(body: response, status: 200)
|
26
|
+
yield block
|
27
|
+
assert_requested(stub)
|
28
|
+
end
|
29
|
+
|
30
|
+
def assert_posts(api_path, headers, payload, response, &block)
|
31
|
+
stub = stub_request(:post, api_path)
|
32
|
+
.with(body: payload, headers: headers)
|
33
|
+
.to_return(body: response, status: 200)
|
34
|
+
yield block
|
35
|
+
assert_requested(stub)
|
36
|
+
end
|
37
|
+
|
38
|
+
def assert_puts(api_path, headers, _payload, response, &block)
|
39
|
+
stub = stub_request(:put, api_path)
|
40
|
+
.with(headers: headers)
|
41
|
+
.to_return(body: response, status: 200)
|
42
|
+
yield block
|
43
|
+
assert_requested(stub)
|
44
|
+
end
|
45
|
+
|
46
|
+
def assert_deletes(api_path, headers, response, &block)
|
47
|
+
stub = stub_request(:delete, api_path)
|
48
|
+
.with(headers: headers)
|
49
|
+
.to_return(body: response, status: 200)
|
50
|
+
yield block
|
51
|
+
assert_requested(stub)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Don't bother testing permutations for this
|
55
|
+
#
|
56
|
+
def assert_invalid_id(command)
|
57
|
+
out, err = capture_io do
|
58
|
+
assert_raises(SystemExit) { wf.new("#{cmd_word} #{command}".split) }
|
59
|
+
end
|
60
|
+
|
61
|
+
assert_empty(out)
|
62
|
+
assert_match(/is not a valid \w+ ID.$/, err)
|
63
|
+
end
|
64
|
+
|
65
|
+
def assert_usage(command)
|
66
|
+
out, err = capture_io do
|
67
|
+
assert_raises(SystemExit) { wf.new("#{cmd_word} #{command}".split) }
|
68
|
+
end
|
69
|
+
|
70
|
+
assert_empty(out)
|
71
|
+
assert_match(/^Usage:\n wf #{cmd_word}/, err)
|
72
|
+
end
|
73
|
+
|
74
|
+
def assert_abort_on_missing_creds(command)
|
75
|
+
out, err = capture_io do
|
76
|
+
assert_raises(SystemExit) do
|
77
|
+
wf.new("#{cmd_word} #{command} --config /nofile".split)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
assert_empty(out)
|
82
|
+
assert_equal("Configuration file '/nofile' not found.\n", err)
|
83
|
+
end
|
84
|
+
|
85
|
+
def assert_exits_with(message, command)
|
86
|
+
out, err = capture_io do
|
87
|
+
assert_raises(SystemExit) do
|
88
|
+
wf.new("#{cmd_word} #{command} --config #{CF}".split)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
assert_empty(out)
|
93
|
+
assert_equal(message, err.strip)
|
94
|
+
end
|
95
|
+
|
96
|
+
def assert_cannot_noop(command)
|
97
|
+
out, err = capture_io do
|
98
|
+
assert_raises(SystemExit) do
|
99
|
+
wf.new("#{cmd_word} #{command} --noop --config #{CF}".split)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
assert_empty(out)
|
104
|
+
assert_equal('Multiple API call operations cannot be ' \
|
105
|
+
"performed as no-ops.\n", err)
|
106
|
+
end
|
107
|
+
|
108
|
+
def assert_repeated_output(msg)
|
109
|
+
begin
|
110
|
+
out, err = capture_io do
|
111
|
+
yield
|
112
|
+
end
|
113
|
+
rescue SystemExit => e
|
114
|
+
puts e.backtrace
|
115
|
+
p e
|
116
|
+
end
|
117
|
+
|
118
|
+
assert_empty(err)
|
119
|
+
out.each_line { |l| assert_equal(msg, l.rstrip) }
|
120
|
+
end
|
121
|
+
|
122
|
+
def assert_cmd_gets(command, api_path, response = dummy_response)
|
123
|
+
all_permutations do |p|
|
124
|
+
assert_gets(full_uri(p[:endpoint], api_path),
|
125
|
+
mk_headers(p[:token]), response) do
|
126
|
+
wf.new("#{cmd_word} #{command} #{p[:cmdline]}".split)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def full_uri(host, api_path)
|
132
|
+
if api_path.is_a?(Regexp)
|
133
|
+
%r{^https://#{host}#{api_path.source}$}
|
134
|
+
else
|
135
|
+
"https://#{host}#{api_path}"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def assert_cmd_gets_with_params(command, api_path, params,
|
140
|
+
response = dummy_response)
|
141
|
+
all_permutations do |p|
|
142
|
+
assert_gets_with_params("https://#{p[:endpoint]}#{api_path}",
|
143
|
+
params,
|
144
|
+
mk_headers(p[:token]),
|
145
|
+
response) do
|
146
|
+
wf.new("#{cmd_word} #{command} #{p[:cmdline]}".split)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def assert_cmd_posts(command, api_path, payload = 'null',
|
152
|
+
response = dummy_response)
|
153
|
+
all_permutations do |p|
|
154
|
+
assert_posts("https://#{p[:endpoint]}#{api_path}",
|
155
|
+
mk_headers(p[:token]), payload, response) do
|
156
|
+
wf.new("#{cmd_word} #{command} #{p[:cmdline]}".split)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def assert_cmd_puts(command, api_path, payload, response = dummy_response)
|
162
|
+
all_permutations do |p|
|
163
|
+
assert_puts("https://#{p[:endpoint]}#{api_path}",
|
164
|
+
mk_headers(p[:token]), payload, response) do
|
165
|
+
wf.new("#{cmd_word} #{command} #{p[:cmdline]}".split)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def assert_cmd_deletes(command, api_path, response = dummy_response)
|
171
|
+
permutations.each do |p|
|
172
|
+
assert_deletes("https://#{p[:endpoint]}#{api_path}",
|
173
|
+
mk_headers(p[:token]), response) do
|
174
|
+
wf.new("#{cmd_word} #{command} #{p[:cmdline]}".split)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def assert_noop(command, *expected)
|
180
|
+
out, err = capture_io do
|
181
|
+
assert_raises(SystemExit) do
|
182
|
+
wf.new("#{cmd_word} #{command} -c #{CF} --noop".split)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
out.strip.split("\n").each.with_index do |l, i|
|
187
|
+
assert_equal("SDK INFO: #{expected[i]}", l)
|
188
|
+
end
|
189
|
+
|
190
|
+
assert_empty(err)
|
191
|
+
end
|
192
|
+
|
193
|
+
# Run tests with all available permutations. We'll always need
|
194
|
+
# to mock out display, unless we don't, when even if we do, it
|
195
|
+
# won't matter.
|
196
|
+
#
|
197
|
+
def all_permutations
|
198
|
+
perms = permutations
|
199
|
+
perms = [perms[2]]
|
200
|
+
|
201
|
+
perms.each do |p|
|
202
|
+
yield(p)
|
203
|
+
WebMock.reset!
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
# Helper to avoid dealing with our display methods
|
208
|
+
#
|
209
|
+
def quietly
|
210
|
+
d = Spy.on_instance_method(cmd_class, :display)
|
211
|
+
yield
|
212
|
+
assert d.has_been_called?
|
213
|
+
d.unhook
|
214
|
+
end
|
215
|
+
|
216
|
+
private
|
217
|
+
|
218
|
+
def mk_headers(token = nil)
|
219
|
+
{ 'Accept': /.*/,
|
220
|
+
'Accept-Encoding': /.*/,
|
221
|
+
'Authorization': 'Bearer ' + (token || '0123456789-ABCDEF'),
|
222
|
+
'User-Agent': "wavefront-cli-#{WF_CLI_VERSION}" }
|
223
|
+
end
|
224
|
+
|
225
|
+
# Every command we simulate running is done under the following
|
226
|
+
# permutations
|
227
|
+
#
|
228
|
+
def permutations
|
229
|
+
[{ cmdline: "-t #{TOKEN} -E #{ENDPOINT}",
|
230
|
+
token: TOKEN,
|
231
|
+
endpoint: ENDPOINT },
|
232
|
+
|
233
|
+
{ cmdline: "-c #{CF}",
|
234
|
+
token: CF_VAL['default']['token'],
|
235
|
+
endpoint: CF_VAL['default']['endpoint'] },
|
236
|
+
|
237
|
+
{ cmdline: "-c #{CF} -P other",
|
238
|
+
token: CF_VAL['other']['token'],
|
239
|
+
endpoint: CF_VAL['other']['endpoint'] },
|
240
|
+
|
241
|
+
{ cmdline: "-c #{CF} --profile other -t #{TOKEN}",
|
242
|
+
token: TOKEN,
|
243
|
+
endpoint: CF_VAL['other']['endpoint'] },
|
244
|
+
|
245
|
+
{ cmdline: "--config #{CF} -E #{ENDPOINT}",
|
246
|
+
token: CF_VAL['default']['token'],
|
247
|
+
endpoint: ENDPOINT }]
|
248
|
+
end
|
249
|
+
|
250
|
+
# Drop this into bodies when you need to check a non-specific
|
251
|
+
# timestamp is there
|
252
|
+
#
|
253
|
+
def a_timestamp
|
254
|
+
proc { |t| t.to_s =~ /^\d{10}$/ }
|
255
|
+
end
|
256
|
+
|
257
|
+
def a_ms_timestamp
|
258
|
+
proc { |t| t.to_s =~ /^\d{13}$/ }
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
# rubocop:enable Metrics/ModuleLength
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require_relative '../constants'
|
5
|
+
|
6
|
+
# We keep a bunch of Wavefront API responses as text files alongside
|
7
|
+
# canned responses in various formats. This class groups helpers for
|
8
|
+
# consuming those files.
|
9
|
+
#
|
10
|
+
class OutputTester
|
11
|
+
# @param file [String] filename to load
|
12
|
+
# @param only_items [Bool] true for the items hash, false for the
|
13
|
+
# whole loadedobject
|
14
|
+
# @return [Object] canned raw responses used to test outputs
|
15
|
+
#
|
16
|
+
def load_input(file, only_items = true)
|
17
|
+
ret = JSON.parse(IO.read(RES_DIR + 'display' + file),
|
18
|
+
symbolize_names: true)
|
19
|
+
only_items ? ret[:items] : ret
|
20
|
+
end
|
21
|
+
|
22
|
+
# @param file [String] file to load
|
23
|
+
# @return [String]
|
24
|
+
#
|
25
|
+
def load_expected(file)
|
26
|
+
IO.read(RES_DIR + 'display' + file)
|
27
|
+
end
|
28
|
+
|
29
|
+
def in_and_out(input, expected, only_items = true)
|
30
|
+
[load_input(input, only_items), load_expected(expected)]
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../constants'
|
4
|
+
|
5
|
+
class SupportedCommands
|
6
|
+
attr_reader :cmd_dir
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@cmd_dir = ROOT + 'lib' + 'wavefront-cli' + 'commands'
|
10
|
+
end
|
11
|
+
|
12
|
+
def all
|
13
|
+
files = cmd_dir.children.select do |f|
|
14
|
+
f.extname == '.rb' && f.basename.to_s != 'base.rb'
|
15
|
+
end
|
16
|
+
|
17
|
+
files.map { |f| f.basename.to_s.chomp('.rb') }
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable Metrics/ModuleLength
|
4
|
+
module WavefrontCliTest
|
5
|
+
#
|
6
|
+
# Include this module to get full ACL tests
|
7
|
+
#
|
8
|
+
module Acl
|
9
|
+
def test_acl
|
10
|
+
assert_repeated_output('No data.') do
|
11
|
+
assert_cmd_gets("acls #{id}", "/api/v2/#{api_path}/acl?id=#{id}")
|
12
|
+
end
|
13
|
+
|
14
|
+
assert_noop("acls #{id}",
|
15
|
+
'uri: GET https://default.wavefront.com/api/v2/' \
|
16
|
+
"#{api_path}/acl")
|
17
|
+
|
18
|
+
assert_invalid_id("acls #{invalid_id}")
|
19
|
+
assert_usage('acls')
|
20
|
+
assert_abort_on_missing_creds("acls #{id}")
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_acl_clear
|
24
|
+
acl_stub = stub_do_acls
|
25
|
+
id_stub = stub_everyone_id
|
26
|
+
|
27
|
+
quietly do
|
28
|
+
assert_cmd_puts("acl clear #{id}",
|
29
|
+
"/api/v2/#{api_path}/acl/set",
|
30
|
+
[{ entityId: id,
|
31
|
+
viewAcl: [],
|
32
|
+
modifyAcl: [everyone_id] }].to_json)
|
33
|
+
end
|
34
|
+
|
35
|
+
assert_cannot_noop("acl clear #{id}")
|
36
|
+
|
37
|
+
assert_invalid_id("acl clear #{invalid_id}")
|
38
|
+
assert_usage('acl clear')
|
39
|
+
assert_abort_on_missing_creds("acl clear #{id}")
|
40
|
+
acl_stub.unhook
|
41
|
+
id_stub.unhook
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_acl_grant_view_to_users
|
45
|
+
stub = stub_do_acls
|
46
|
+
|
47
|
+
quietly do
|
48
|
+
assert_cmd_posts("acl grant view on #{id} to #{user_acl_names}",
|
49
|
+
"/api/v2/#{api_path}/acl/add",
|
50
|
+
acl_body(id, user_acls, []))
|
51
|
+
end
|
52
|
+
|
53
|
+
assert_noop("acl grant view on #{id} to #{user_acl_names}",
|
54
|
+
'uri: POST https://default.wavefront.com/api/v2/' \
|
55
|
+
"#{api_path}/acl/add",
|
56
|
+
"body: #{acl_body(id, user_acls, [])}")
|
57
|
+
|
58
|
+
assert_invalid_id("acl grant view on #{invalid_id} to user")
|
59
|
+
assert_usage("acl grant view on #{id}")
|
60
|
+
assert_abort_on_missing_creds(
|
61
|
+
"acl grant view on #{invalid_id} to user"
|
62
|
+
)
|
63
|
+
stub.unhook
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_acl_grant_modify_to_group
|
67
|
+
stub = stub_do_acls
|
68
|
+
|
69
|
+
quietly do
|
70
|
+
assert_cmd_posts("acl grant modify on #{id} to #{group_acls.first}",
|
71
|
+
"/api/v2/#{api_path}/acl/add",
|
72
|
+
acl_body(id, [], group_acls))
|
73
|
+
end
|
74
|
+
|
75
|
+
assert_noop("acl grant modify on #{id} to #{group_acls.first}",
|
76
|
+
'uri: POST https://default.wavefront.com/api/v2/' \
|
77
|
+
"#{api_path}/acl/add",
|
78
|
+
"body: #{acl_body(id, [], group_acls)}")
|
79
|
+
|
80
|
+
assert_invalid_id("acl grant modify on #{invalid_id} to user")
|
81
|
+
assert_usage("acl grant modify on #{id}")
|
82
|
+
assert_abort_on_missing_creds(
|
83
|
+
"acl grant modify on #{invalid_id} to user"
|
84
|
+
)
|
85
|
+
stub.unhook
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_acl_revoke_view_from_group
|
89
|
+
stub = stub_do_acls
|
90
|
+
|
91
|
+
quietly do
|
92
|
+
assert_cmd_posts("acl revoke view on #{id} from #{group_acls.first}",
|
93
|
+
"/api/v2/#{api_path}/acl/remove",
|
94
|
+
acl_body(id, group_acls, []))
|
95
|
+
end
|
96
|
+
|
97
|
+
assert_noop("acl revoke view on #{id} from #{group_acls.first}",
|
98
|
+
'uri: POST https://default.wavefront.com/api/v2/' \
|
99
|
+
"#{api_path}/acl/remove",
|
100
|
+
"body: #{acl_body(id, group_acls, [])}")
|
101
|
+
|
102
|
+
assert_invalid_id("acl revoke view on #{invalid_id} from user")
|
103
|
+
assert_usage("acl revoke view on #{id}")
|
104
|
+
assert_abort_on_missing_creds(
|
105
|
+
"acl revoke view on #{invalid_id} from user"
|
106
|
+
)
|
107
|
+
stub.unhook
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_acl_revoke_modify_from_user
|
111
|
+
stub = stub_do_acls
|
112
|
+
|
113
|
+
quietly do
|
114
|
+
assert_cmd_posts("acl revoke modify on #{id} from #{user_acls.first}",
|
115
|
+
"/api/v2/#{api_path}/acl/remove",
|
116
|
+
acl_body(id, [], user_acls.take(1)))
|
117
|
+
end
|
118
|
+
|
119
|
+
assert_noop("acl revoke modify on #{id} from #{user_acls.first}",
|
120
|
+
'uri: POST https://default.wavefront.com/api/v2/' \
|
121
|
+
"#{api_path}/acl/remove",
|
122
|
+
"body: #{acl_body(id, [], user_acls.take(1))}")
|
123
|
+
|
124
|
+
assert_invalid_id("acl revoke modify on #{invalid_id} from user")
|
125
|
+
assert_usage("acl revoke modify on #{id}")
|
126
|
+
assert_abort_on_missing_creds(
|
127
|
+
"acl revoke modify on #{invalid_id} from user"
|
128
|
+
)
|
129
|
+
stub.unhook
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
|
134
|
+
def stub_everyone_id
|
135
|
+
Spy.on_instance_method(cmd_class, :everyone_id)
|
136
|
+
.and_return(everyone_id)
|
137
|
+
end
|
138
|
+
|
139
|
+
def stub_do_acls
|
140
|
+
Spy.on_instance_method(cmd_class, :do_acls).and_return('')
|
141
|
+
end
|
142
|
+
|
143
|
+
def everyone_id
|
144
|
+
'abcd-1234'
|
145
|
+
end
|
146
|
+
|
147
|
+
def user_acls
|
148
|
+
%w[someone@example.com other@elsewhere.com]
|
149
|
+
end
|
150
|
+
|
151
|
+
def user_acl_names
|
152
|
+
user_acls.join(' ')
|
153
|
+
end
|
154
|
+
|
155
|
+
# @return [Array[String]] list of group IDs for ACL testing
|
156
|
+
#
|
157
|
+
def group_acls
|
158
|
+
%w[f8dc0c14-91a0-4ca9-8a2a-7d47f4db4672]
|
159
|
+
end
|
160
|
+
|
161
|
+
# @return [String] JSON representation of an ACL request
|
162
|
+
# payload
|
163
|
+
#
|
164
|
+
def acl_body(id, view = [], modify = [])
|
165
|
+
[{ entityId: id, viewAcl: view, modifyAcl: modify }].to_json
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
# rubocop:enable Metrics/ModuleLength
|