wavefront-cli 8.5.1 → 9.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/release.yml +4 -4
  3. data/.github/workflows/test.yml +2 -2
  4. data/.rubocop.yml +1 -4
  5. data/HISTORY.md +12 -0
  6. data/README.md +4 -2
  7. data/lib/wavefront-cli/base.rb +2 -2
  8. data/lib/wavefront-cli/commands/base.rb +10 -9
  9. data/lib/wavefront-cli/commands/derivedmetric.rb +1 -1
  10. data/lib/wavefront-cli/commands/metric.rb +3 -3
  11. data/lib/wavefront-cli/commands/metricspolicy.rb +33 -0
  12. data/lib/wavefront-cli/commands/query.rb +5 -5
  13. data/lib/wavefront-cli/commands/write.rb +12 -12
  14. data/lib/wavefront-cli/config.rb +4 -4
  15. data/lib/wavefront-cli/constants.rb +2 -1
  16. data/lib/wavefront-cli/controller.rb +19 -15
  17. data/lib/wavefront-cli/display/metricspolicy.rb +15 -0
  18. data/lib/wavefront-cli/display/printer/long.rb +11 -13
  19. data/lib/wavefront-cli/display/printer/sparkline.rb +3 -3
  20. data/lib/wavefront-cli/display/query.rb +1 -1
  21. data/lib/wavefront-cli/display/write.rb +2 -1
  22. data/lib/wavefront-cli/event.rb +2 -2
  23. data/lib/wavefront-cli/exception_handler.rb +4 -1
  24. data/lib/wavefront-cli/helpers/load_file.rb +2 -2
  25. data/lib/wavefront-cli/maintenancewindow.rb +1 -1
  26. data/lib/wavefront-cli/metricspolicy.rb +42 -0
  27. data/lib/wavefront-cli/opt_handler.rb +2 -3
  28. data/lib/wavefront-cli/output/csv/query.rb +2 -2
  29. data/lib/wavefront-cli/output/hcl/dashboard.rb +6 -6
  30. data/lib/wavefront-cli/output/hcl/stdlib/array.rb +1 -1
  31. data/lib/wavefront-cli/output/wavefront/query.rb +7 -7
  32. data/lib/wavefront-cli/stdlib/string.rb +4 -4
  33. data/lib/wavefront-cli/usage.rb +1 -1
  34. data/lib/wavefront-cli/version.rb +1 -1
  35. data/lib/wavefront-cli/write.rb +13 -17
  36. data/spec/constants.rb +4 -5
  37. data/spec/support/command_base.rb +12 -0
  38. data/spec/support/minitest_assertions.rb +14 -10
  39. data/spec/support/output_tester.rb +2 -2
  40. data/spec/support/supported_commands.rb +3 -1
  41. data/spec/test_mixins/import.rb +2 -2
  42. data/spec/test_mixins/search.rb +9 -7
  43. data/spec/test_mixins/set.rb +1 -1
  44. data/spec/wavefront-cli/account_spec.rb +6 -4
  45. data/spec/wavefront-cli/alert_spec.rb +29 -6
  46. data/spec/wavefront-cli/commands/base_spec.rb +2 -2
  47. data/spec/wavefront-cli/commands/config_spec.rb +2 -2
  48. data/spec/wavefront-cli/config_spec.rb +3 -3
  49. data/spec/wavefront-cli/controller_spec.rb +2 -0
  50. data/spec/wavefront-cli/dashboard_spec.rb +1 -1
  51. data/spec/wavefront-cli/derivedmetric_spec.rb +9 -7
  52. data/spec/wavefront-cli/display/printer/long_spec.rb +5 -3
  53. data/spec/wavefront-cli/display/printer/terse_spec.rb +1 -1
  54. data/spec/wavefront-cli/event_spec.rb +14 -11
  55. data/spec/wavefront-cli/event_store_spec.rb +16 -12
  56. data/spec/wavefront-cli/externallink_spec.rb +5 -3
  57. data/spec/wavefront-cli/maintenancewindow_spec.rb +25 -19
  58. data/spec/wavefront-cli/message_spec.rb +3 -3
  59. data/spec/wavefront-cli/metricspolicy_spec.rb +30 -0
  60. data/spec/wavefront-cli/opt_handler_spec.rb +1 -1
  61. data/spec/wavefront-cli/output/helpers.rb +1 -1
  62. data/spec/wavefront-cli/proxy_spec.rb +1 -1
  63. data/spec/wavefront-cli/query_spec.rb +1 -1
  64. data/spec/wavefront-cli/role_spec.rb +4 -3
  65. data/spec/wavefront-cli/serviceaccount_spec.rb +7 -5
  66. data/spec/wavefront-cli/stdlib/string_spec.rb +3 -1
  67. data/spec/wavefront-cli/usage_spec.rb +1 -1
  68. data/spec/wavefront-cli/{write_spec.rb → write_class_spec.rb} +1 -14
  69. data/wavefront-cli.gemspec +13 -15
  70. metadata +32 -149
  71. data/spec/spec_helper.rb +0 -113
@@ -27,7 +27,7 @@ module WavefrontCli
27
27
 
28
28
  [%i[CustomerTags atag], %i[HostTags htag],
29
29
  %i[HostNames host]].each do |key, opt|
30
- k = ('relevant' + key.to_s).to_sym
30
+ k = "relevant#{key}".to_sym
31
31
  body[k] = options[opt] unless options[opt].empty?
32
32
  end
33
33
 
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'wavefront-sdk/support/mixins'
4
+ require_relative 'base'
5
+ require_relative 'helpers/load_file'
6
+
7
+ module WavefrontCli
8
+ #
9
+ # CLI coverage for the metricspolicy part of the v2 'usage' API.
10
+ #
11
+ class MetricsPolicy < WavefrontCli::Base
12
+ def do_describe
13
+ wf.describe(options[:version])
14
+ end
15
+
16
+ def do_history
17
+ wf.history(options[:offset] || 0, options[:limit] || 100)
18
+ end
19
+
20
+ def do_revert
21
+ wf.revert(options[:'<version>'])
22
+ end
23
+
24
+ def do_update
25
+ raw = WavefrontCli::Helper::LoadFile.new(options[:'<file>']).load
26
+ rules = process_update(raw)
27
+ wf.update(policyRules: rules)
28
+ end
29
+
30
+ # It looks like the API expects arrays of ID strings for accounts, groups,
31
+ # and roles, but when you export one, those fields are objects with name
32
+ # and ID.
33
+ #
34
+ def process_update(raw)
35
+ raw[:policyRules].tap do |rule|
36
+ rule[:accounts] = rule[:accounts].map { |r| r[:id] }
37
+ rule[:userGroups] = rule[:userGroups].map { |r| r[:id] }
38
+ rule[:roles] = rule[:roles].map { |r| r[:id] }
39
+ end
40
+ end
41
+ end
42
+ end
@@ -43,11 +43,10 @@ module WavefrontCli
43
43
  # constructor.
44
44
  # @param cli_opts [Hash] options from docopt, which may include
45
45
  # the location of the config file and the stanza within it
46
- # @return [Hash] keys are none, one, or both of :file and
47
- # :profile
46
+ # @return [Hash] keys are none, one, or both of :file and :profile
48
47
  #
49
48
  def setup_cred_opts(cli_opts)
50
- cred_opts = { raise_on_no_profile: true }
49
+ cred_opts = cli_opts[:config] ? { raise_on_no_profile: true } : {}
51
50
 
52
51
  if cli_opts[:config]
53
52
  cred_opts[:file] = Pathname.new(cli_opts[:config])
@@ -32,7 +32,7 @@ module WavefrontCsvOutput
32
32
  def raw_output
33
33
  resp.each_with_object([]) do |point, a|
34
34
  point[:points].each do |p|
35
- a.<< csv_format(options[:'<metric>'],
35
+ a << csv_format(options[:'<metric>'],
36
36
  p[:value],
37
37
  p[:timestamp],
38
38
  options[:host],
@@ -48,7 +48,7 @@ module WavefrontCsvOutput
48
48
 
49
49
  resp[:timeseries].each_with_object([]) do |ts, a|
50
50
  ts[:data].each do |point|
51
- a.<< csv_format(ts[:label],
51
+ a << csv_format(ts[:label],
52
52
  point[1],
53
53
  point[0],
54
54
  ts[:host],
@@ -32,19 +32,19 @@ module WavefrontHclOutput
32
32
  # @return [String] HCL list of vals
33
33
  #
34
34
  def listmaker(vals, method)
35
- vals.each_with_object([]) { |v, a| a.<< send(method, v) }.to_hcl_list
35
+ vals.each_with_object([]) { |v, a| a << send(method, v) }.to_hcl_list
36
36
  end
37
37
 
38
38
  def vhandle_sections(vals)
39
39
  vals.each_with_object([]) do |section, a|
40
- a.<< ("name = \"#{section[:name]}\"\n row = " +
40
+ a << ("name = \"#{section[:name]}\"\n row = " +
41
41
  handle_rows(section[:rows])).braced(4)
42
42
  end.to_hcl_list
43
43
  end
44
44
 
45
45
  def handle_rows(rows)
46
46
  rows.each_with_object([]) do |row, a|
47
- a.<< ('chart = ' + handle_charts(row[:charts]).to_s).braced(8)
47
+ a << "chart = #{handle_charts(row[:charts])}".braced(8)
48
48
  end.to_hcl_list
49
49
  end
50
50
 
@@ -58,10 +58,10 @@ module WavefrontHclOutput
58
58
  lines = chart.each_with_object([]) do |(k, v), a|
59
59
  next unless fields.include?(k)
60
60
 
61
- a.<< format('%<key>s = %<value>s', key: k, value: quote_value(v))
61
+ a << format('%<key>s = %<value>s', key: k, value: quote_value(v))
62
62
  end
63
63
 
64
- lines.<< "source = #{handle_sources(chart[:sources])}"
64
+ lines << "source = #{handle_sources(chart[:sources])}"
65
65
  lines.to_hcl_obj(10)
66
66
  end
67
67
 
@@ -75,7 +75,7 @@ module WavefrontHclOutput
75
75
 
76
76
  k = 'queryBuilderEnabled' if k == 'querybuilderEnabled'
77
77
 
78
- a.<< format('%<key>s = %<value>s',
78
+ a << format('%<key>s = %<value>s',
79
79
  key: k.to_snake,
80
80
  value: quote_value(v))
81
81
  end.to_hcl_obj(14)
@@ -9,7 +9,7 @@ class Array
9
9
  # @return [String]
10
10
  #
11
11
  def to_hcl_list
12
- '[' + join(',') + ']'
12
+ "[#{join(',')}]"
13
13
  end
14
14
 
15
15
  # Turn an array into a string which represents an HCL object
@@ -20,11 +20,11 @@ module WavefrontWavefrontOutput
20
20
  def raw_output
21
21
  resp.each_with_object('') do |point, a|
22
22
  point[:points].each do |p|
23
- a.<< wavefront_format(options[:'<metric>'],
24
- p[:value],
25
- p[:timestamp],
26
- options[:host],
27
- point[:tags]) + "\n"
23
+ a << "#{wavefront_format(options[:'<metric>'],
24
+ p[:value],
25
+ p[:timestamp],
26
+ options[:host],
27
+ point[:tags])}\n"
28
28
  end
29
29
  end
30
30
  end
@@ -34,7 +34,7 @@ module WavefrontWavefrontOutput
34
34
 
35
35
  resp[:timeseries].each_with_object([]) do |ts, a|
36
36
  ts[:data].each do |point|
37
- a.<< wavefront_format(ts[:label],
37
+ a << wavefront_format(ts[:label],
38
38
  point[1],
39
39
  point[0],
40
40
  ts[:host],
@@ -46,7 +46,7 @@ module WavefrontWavefrontOutput
46
46
  def wavefront_format(path, value, timestamp, source, tags = nil)
47
47
  arr = [path, value, timestamp, format('source=%<source>s',
48
48
  source: source)]
49
- arr.<< tags.to_wf_tag if tags && !tags.empty?
49
+ arr << tags.to_wf_tag if tags && !tags.empty?
50
50
  arr.join(' ')
51
51
  end
52
52
  end
@@ -10,7 +10,7 @@ class String
10
10
  # @param indent [Integer] size of hanging indent, in chars
11
11
  #
12
12
  def cmd_fold(twidth = TW, indent = 10)
13
- gsub(/(-\w) /, '\\1^').scan_line(twidth - 12).join("\n" + ' ' * indent)
13
+ gsub(/(-\w) /, '\\1^').scan_line(twidth - 12).join("\n#{' ' * indent}")
14
14
  .restored
15
15
  end
16
16
 
@@ -58,7 +58,7 @@ class String
58
58
  #
59
59
  def value_fold(indent = 0, twidth = TW)
60
60
  max_line_length = twidth - indent - 4
61
- scan_line(max_line_length).join("\n" + ' ' * indent)
61
+ scan_line(max_line_length).join("\n#{' ' * indent}")
62
62
  end
63
63
 
64
64
  # @param width [Integer] length of longest string (width of
@@ -94,7 +94,7 @@ class String
94
94
  #
95
95
  def to_snake
96
96
  gsub(/(.)([A-Z])/) do
97
- Regexp.last_match[1] + '_' + Regexp.last_match[2].downcase
97
+ "#{Regexp.last_match[1]}_#{Regexp.last_match[2].downcase}"
98
98
  end
99
99
  end
100
100
 
@@ -102,7 +102,7 @@ class String
102
102
 
103
103
  def indent_folded_lines(chunks, twidth, indent, prefix)
104
104
  chunks.join(' ').scan_line(twidth - indent - 5).map do |line|
105
- prefix + ' ' * indent + line
105
+ "#{prefix}#{' ' * indent}#{line}"
106
106
  end
107
107
  end
108
108
  end
@@ -18,7 +18,7 @@ module WavefrontCli
18
18
  end
19
19
 
20
20
  def default_start
21
- parse_time(Time.now - 60 * 60 * 24)
21
+ parse_time(Time.now - 86_400)
22
22
  end
23
23
  end
24
24
  end
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- WF_CLI_VERSION = '8.5.1'
3
+ WF_CLI_VERSION = '9.0.0'
@@ -74,8 +74,8 @@ module WavefrontCli
74
74
  end
75
75
  # rubocop:enable Metrics/AbcSize
76
76
 
77
- # Turn our user's representation of a distribution into one
78
- # which suits Wavefront. The SDK can do this for us.
77
+ # Turn our user's representation of a distribution into one which suits
78
+ # Wavefront. The SDK can do this for us.
79
79
  #
80
80
  def mk_dist
81
81
  xpanded = expand_dist(options[:'<val>'])
@@ -83,7 +83,11 @@ module WavefrontCli
83
83
  end
84
84
 
85
85
  def extra_options
86
- options[:using] ? { writer: options[:using] } : {}
86
+ if options[:using]
87
+ { writer: options[:using] }
88
+ else
89
+ { writer: :http }
90
+ end
87
91
  end
88
92
 
89
93
  # I chose to prioritise UI consistency over internal elegance
@@ -108,6 +112,7 @@ module WavefrontCli
108
112
  port: options[:port] || default_port,
109
113
  socket: options[:socket],
110
114
  endpoint: options[:endpoint],
115
+ agent: "wavefront-cli-#{WF_CLI_VERSION}",
111
116
  token: options[:token] }
112
117
  end
113
118
 
@@ -115,18 +120,9 @@ module WavefrontCli
115
120
  distribution? ? 40_000 : 2878
116
121
  end
117
122
 
123
+ # The SDK writer plugins validate the credentials they need
118
124
  def validate_opts
119
125
  validate_opts_file if options[:file]
120
-
121
- if options[:using] == 'unix'
122
- return true if options[:socket]
123
-
124
- raise(WavefrontCli::Exception::CredentialError, 'No socket path.')
125
- end
126
-
127
- return true if options[:proxy]
128
-
129
- raise(WavefrontCli::Exception::CredentialError, 'No proxy address.')
130
126
  end
131
127
 
132
128
  def validate_opts_file
@@ -167,7 +163,7 @@ module WavefrontCli
167
163
  #
168
164
  def process_input_file(data)
169
165
  data.each_with_object([]) do |l, a|
170
- a.<< process_line(l)
166
+ a << process_line(l)
171
167
  rescue WavefrontCli::Exception::UnparseableInput => e
172
168
  puts "Bad input. #{e.message}."
173
169
  next
@@ -426,17 +422,17 @@ module WavefrontCli
426
422
  #
427
423
  def valid_timestamp?(timestamp)
428
424
  (timestamp.is_a?(Integer) ||
429
- timestamp.is_a?(String) && timestamp.match(/^\d+$/)) &&
425
+ (timestamp.is_a?(String) && timestamp.match(/^\d+$/))) &&
430
426
  timestamp.to_i > 946_684_800 &&
431
427
  timestamp.to_i < (Time.now.to_i + 31_557_600)
432
428
  end
433
429
 
434
430
  def setup_fmt(fmt)
435
- @fmt = fmt.split('')
431
+ @fmt = fmt.chars
436
432
  end
437
433
 
438
434
  def load_data(file)
439
- IO.read(file)
435
+ File.read(file)
440
436
  rescue StandardError
441
437
  raise WavefrontCli::Exception::FileNotFound
442
438
  end
data/spec/constants.rb CHANGED
@@ -12,10 +12,9 @@ TW = 80
12
12
 
13
13
  ENDPOINT = 'metrics.wavefront.com'
14
14
  TOKEN = '0123456789-ABCDEF'
15
- RES_DIR = ROOT + 'spec' + 'wavefront-cli' + 'resources'
16
- CF = RES_DIR + 'wavefront.conf'
15
+ RES_DIR = ROOT.join('spec', 'wavefront-cli', 'resources')
16
+ CF = RES_DIR.join('wavefront.conf')
17
17
  CF_VAL = IniFile.load(CF)
18
- JSON_POST_HEADERS = {
19
- 'Content-Type': 'application/json', Accept: 'application/json'
20
- }.freeze
18
+ JSON_POST_HEADERS = { 'Content-Type': 'application/json',
19
+ Accept: 'application/json' }.freeze
21
20
  TEE_ZERO = Time.now.freeze
@@ -9,11 +9,13 @@ require_relative '../../lib/wavefront-cli/controller'
9
9
  # commands.
10
10
  #
11
11
  class EndToEndTest < MiniTest::Test
12
+ attr_accessor :single_perm
12
13
  attr_reader :wf
13
14
 
14
15
  def setup
15
16
  before_setup if respond_to?(:before_setup)
16
17
  @wf = WavefrontCliController
18
+ @single_perm = false
17
19
  end
18
20
 
19
21
  def api_path
@@ -79,4 +81,14 @@ class EndToEndTest < MiniTest::Test
79
81
  { status: { result: 'OK', message: '', code: 200 },
80
82
  items: [] }.to_json
81
83
  end
84
+
85
+ def blank_envvars
86
+ %w[WAVEFRONT_ENDPOINT WAVEFRONT_PROXY WAVEFRONT_TOKEN].each do |v|
87
+ ENV[v] = nil
88
+ end
89
+ end
90
+
91
+ def config?
92
+ Pathname.new(Dir.home).join('.wavefront').exist?
93
+ end
82
94
  end
@@ -147,10 +147,13 @@ module Minitest
147
147
  end
148
148
 
149
149
  def assert_cmd_posts(command, api_path, payload = 'null',
150
- response = dummy_response)
150
+ response = nil, extra_headers = {})
151
+ response ||= dummy_response
151
152
  all_permutations do |p|
152
153
  assert_posts("https://#{p[:endpoint]}#{api_path}",
153
- mk_headers(p[:token]), payload, response) do
154
+ mk_headers(p[:token], extra_headers),
155
+ payload,
156
+ response) do
154
157
  wf.new("#{cmd_word} #{command} #{p[:cmdline]}".split)
155
158
  end
156
159
  end
@@ -166,7 +169,7 @@ module Minitest
166
169
  end
167
170
 
168
171
  def assert_cmd_deletes(command, api_path, response = dummy_response)
169
- permutations.each do |p|
172
+ all_permutations do |p|
170
173
  assert_deletes("https://#{p[:endpoint]}#{api_path}",
171
174
  mk_headers(p[:token]), response) do
172
175
  wf.new("#{cmd_word} #{command} #{p[:cmdline]}".split)
@@ -188,13 +191,14 @@ module Minitest
188
191
  assert_empty(err)
189
192
  end
190
193
 
191
- # Run tests with all available permutations. We'll always need
192
- # to mock out display, unless we don't, when even if we do, it
193
- # won't matter.
194
+ # Run tests with all available permutations, unless the single_perm class
195
+ # variable is set. This lets us run tests faster by running fewer (but
196
+ # still a good random selection) and lets us run tests which must only be
197
+ # run once, like tests which pop stuff off the event stack.
194
198
  #
195
199
  def all_permutations
196
200
  perms = permutations
197
- perms = [perms[2]]
201
+ perms = perms.shuffle.take(1) if @single_perm || ENV['FAST_TESTS']
198
202
 
199
203
  perms.each do |p|
200
204
  yield(p)
@@ -213,11 +217,11 @@ module Minitest
213
217
 
214
218
  private
215
219
 
216
- def mk_headers(token = nil)
220
+ def mk_headers(token = nil, extra_headers = {})
217
221
  { Accept: /.*/,
218
222
  'Accept-Encoding': /.*/,
219
- Authorization: 'Bearer ' + (token || '0123456789-ABCDEF'),
220
- 'User-Agent': "wavefront-cli-#{WF_CLI_VERSION}" }
223
+ Authorization: "Bearer #{token || '0123456789-ABCDEF'}",
224
+ 'User-Agent': "wavefront-cli-#{WF_CLI_VERSION}" }.merge(extra_headers)
221
225
  end
222
226
 
223
227
  # Every command we simulate running is done under the following
@@ -14,7 +14,7 @@ class OutputTester
14
14
  # @return [Object] canned raw responses used to test outputs
15
15
  #
16
16
  def load_input(file, only_items = true)
17
- ret = JSON.parse(IO.read(RES_DIR + 'display' + file),
17
+ ret = JSON.parse(File.read(RES_DIR.join('display', file)),
18
18
  symbolize_names: true)
19
19
  only_items ? ret[:items] : ret
20
20
  end
@@ -23,7 +23,7 @@ class OutputTester
23
23
  # @return [String]
24
24
  #
25
25
  def load_expected(file)
26
- IO.read(RES_DIR + 'display' + file)
26
+ File.read(RES_DIR.join('display', file))
27
27
  end
28
28
 
29
29
  def in_and_out(input, expected, only_items = true)
@@ -2,11 +2,13 @@
2
2
 
3
3
  require_relative '../constants'
4
4
 
5
+ # Produces a list of wf's commands
6
+ #
5
7
  class SupportedCommands
6
8
  attr_reader :cmd_dir
7
9
 
8
10
  def initialize
9
- @cmd_dir = ROOT + 'lib' + 'wavefront-cli' + 'commands'
11
+ @cmd_dir = ROOT.join('lib', 'wavefront-cli', 'commands')
10
12
  end
11
13
 
12
14
  def all
@@ -61,11 +61,11 @@ module WavefrontCliTest
61
61
  private
62
62
 
63
63
  def import_file
64
- RES_DIR + 'imports' + "#{api_path}.json"
64
+ RES_DIR.join('imports', "#{api_path}.json")
65
65
  end
66
66
 
67
67
  def update_file
68
- RES_DIR + 'updates' + "#{api_path}.json"
68
+ RES_DIR.join('updates', "#{api_path}.json")
69
69
  end
70
70
  end
71
71
  end
@@ -18,17 +18,19 @@ module WavefrontCliTest
18
18
  sort: { field: 'id', ascending: true })
19
19
  end
20
20
 
21
+ json_body = { limit: 10,
22
+ offset: 0,
23
+ query: [{ key: 'id',
24
+ value: id,
25
+ matchingMethod: 'EXACT',
26
+ negated: false }],
27
+ sort: { field: 'id', ascending: true } }.to_json
28
+
21
29
  assert_noop(
22
30
  "search id=#{id}",
23
31
  'uri: POST https://default.wavefront.com/api/v2/search/' \
24
32
  "#{search_api_path}",
25
- 'body: ' + { limit: 10,
26
- offset: 0,
27
- query: [{ key: 'id',
28
- value: id,
29
- matchingMethod: 'EXACT',
30
- negated: false }],
31
- sort: { field: 'id', ascending: true } }.to_json
33
+ "body: #{json_body}"
32
34
  )
33
35
  assert_abort_on_missing_creds("search id=#{id}")
34
36
  assert_usage('search')
@@ -23,7 +23,7 @@ module WavefrontCliTest
23
23
 
24
24
  def run_command(perm)
25
25
  wf.new("#{cmd_word} set #{set_key}=new_value #{id} " \
26
- "#{perm[:cmdline]}".split)
26
+ "#{perm[:cmdline]}".split)
27
27
  rescue SystemExit => e
28
28
  p e
29
29
  end
@@ -228,10 +228,12 @@ class AccountEndToEndTest < EndToEndTest
228
228
  cmd = "validate #{user_list.join(' ')}"
229
229
 
230
230
  quietly do
231
- assert_cmd_posts(cmd,
232
- '/api/v2/account/validateAccounts',
233
- user_list.to_json,
234
- IO.read(RES_DIR + 'responses' + 'user-validate.json'))
231
+ assert_cmd_posts(
232
+ cmd,
233
+ '/api/v2/account/validateAccounts',
234
+ user_list.to_json,
235
+ File.read(RES_DIR.join('responses', 'user-validate.json'))
236
+ )
235
237
  end
236
238
 
237
239
  assert_noop(cmd,
@@ -21,6 +21,25 @@ class AlertEndToEndTest < EndToEndTest
21
21
  include WavefrontCliTest::History
22
22
  include WavefrontCliTest::Acl
23
23
 
24
+ # This test isn't run if whoever runs it has a config file, because it tests
25
+ # wf's behaviour only if that file does not exist. CI will never have that
26
+ # file.
27
+ #
28
+ def test_no_config_no_envvars
29
+ skip if config?
30
+
31
+ blank_envvars
32
+ wf = WavefrontCliController
33
+
34
+ out, err = capture_io do
35
+ assert_raises(SystemExit) { wf.new(%w[alert list]) }
36
+ end
37
+
38
+ assert_empty(err)
39
+ assert out.start_with?('Credential error. Missing api token.')
40
+ assert_match(/You may also run 'wf config setup'/, out)
41
+ end
42
+
24
43
  def test_latest
25
44
  quietly do
26
45
  assert_cmd_gets("latest #{id}", "/api/v2/alert/#{id}/history")
@@ -48,10 +67,12 @@ class AlertEndToEndTest < EndToEndTest
48
67
  id: id, v: nil, name: nil)
49
68
  end
50
69
 
70
+ json_body = { id: id, name: nil, v: nil }.to_json
71
+
51
72
  assert_noop("clone #{id}",
52
73
  'uri: POST https://default.wavefront.com/api/v2/' \
53
74
  "alert/#{id}/clone",
54
- 'body: ' + { id: id, name: nil, v: nil }.to_json)
75
+ "body: #{json_body}")
55
76
 
56
77
  assert_invalid_id("clone #{invalid_id}")
57
78
  assert_usage('clone')
@@ -65,10 +86,12 @@ class AlertEndToEndTest < EndToEndTest
65
86
  id: id, v: 5, name: nil)
66
87
  end
67
88
 
89
+ json_body = { id: id, name: nil, v: 5 }.to_json
90
+
68
91
  assert_noop("clone #{id} --version 5",
69
92
  'uri: POST https://default.wavefront.com/api/v2/' \
70
93
  "alert/#{id}/clone",
71
- 'body: ' + { id: id, name: nil, v: 5 }.to_json)
94
+ "body: #{json_body}")
72
95
 
73
96
  assert_invalid_id("clone -v 10 #{invalid_id}")
74
97
  assert_usage('clone -v')
@@ -173,7 +196,7 @@ class AlertEndToEndTest < EndToEndTest
173
196
  assert_noop('snoozed',
174
197
  'uri: POST https://default.wavefront.com/api/v2/' \
175
198
  'search/alert',
176
- 'body: ' + state_search('snoozed').to_json)
199
+ "body: #{state_search('snoozed').to_json}")
177
200
 
178
201
  assert_abort_on_missing_creds('snoozed')
179
202
  end
@@ -193,7 +216,7 @@ class AlertEndToEndTest < EndToEndTest
193
216
  assert_noop('firing',
194
217
  'uri: POST https://default.wavefront.com/api/v2/' \
195
218
  'search/alert',
196
- 'body: ' + state_search('firing').to_json)
219
+ "body: #{state_search('firing').to_json}")
197
220
 
198
221
  assert_abort_on_missing_creds('firing')
199
222
  end
@@ -213,7 +236,7 @@ class AlertEndToEndTest < EndToEndTest
213
236
  assert_noop('currently firing',
214
237
  'uri: POST https://default.wavefront.com/api/v2/' \
215
238
  'search/alert',
216
- 'body: ' + state_search('firing').to_json)
239
+ "body: #{state_search('firing').to_json}")
217
240
 
218
241
  assert_abort_on_missing_creds('currently firing')
219
242
  end
@@ -233,7 +256,7 @@ class AlertEndToEndTest < EndToEndTest
233
256
  assert_noop('currently in_maintenance',
234
257
  'uri: POST https://default.wavefront.com/api/v2/' \
235
258
  'search/alert',
236
- 'body: ' + state_search('in_maintenance').to_json)
259
+ "body: #{state_search('in_maintenance').to_json}")
237
260
 
238
261
  assert_abort_on_missing_creds('currently in_maintenance')
239
262
  end
@@ -68,7 +68,7 @@ class WavefrontCommmandBaseTest < MiniTest::Test
68
68
  assert wf.commands.start_with?("Usage:\n")
69
69
  assert wf.commands.match(/ --help$/)
70
70
 
71
- wf.commands(600).split("\n")[1..-1].each do |c|
71
+ wf.commands(600).split("\n")[1..].each do |c|
72
72
  next if skip_cmd && c.match(skip_cmd)
73
73
 
74
74
  assert_match(/^ \w+/, c)
@@ -80,7 +80,7 @@ class WavefrontCommmandBaseTest < MiniTest::Test
80
80
  assert wf.options(600).start_with?("Global options:\n")
81
81
  assert_match(/\nOptions:/, wf.options)
82
82
 
83
- wf.options(600).split("\n")[1..-1].each do |o|
83
+ wf.options(600).split("\n")[1..].each do |o|
84
84
  next if o == 'Global options:' || o == 'Options:' || o.empty?
85
85
 
86
86
  assert_instance_of(String, o)
@@ -20,7 +20,7 @@ class WavefrontCommmandConfigTest < WavefrontCommmandBaseTest
20
20
  refute wf.options(600).start_with?("Global options:\n")
21
21
  assert_match(/Options:\n/, wf.options)
22
22
 
23
- wf.options(600).split("\n")[1..-1].each do |o|
23
+ wf.options(600).split("\n")[1..].each do |o|
24
24
  next if o == 'Global options:' || o == 'Options:' || o.empty?
25
25
 
26
26
  assert_instance_of(String, o)
@@ -35,7 +35,7 @@ class WavefrontCommmandConfigTest < WavefrontCommmandBaseTest
35
35
  assert wf.commands.start_with?("Usage:\n")
36
36
  assert wf.commands.match(/ --help$/)
37
37
 
38
- wf.commands(600).split("\n")[1..-1].each do |c|
38
+ wf.commands(600).split("\n")[1..].each do |c|
39
39
  next if skip_cmd && c.match(skip_cmd)
40
40
 
41
41
  assert_match(/^ \w+/, c)