wavefront-cli 2.8.0 → 2.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +11 -0
  3. data/HISTORY.md +17 -0
  4. data/Rakefile +1 -1
  5. data/bin/wf +1 -1
  6. data/lib/wavefront-cli/base.rb +46 -18
  7. data/lib/wavefront-cli/base_write.rb +49 -33
  8. data/lib/wavefront-cli/commands/.rubocop.yml +7 -0
  9. data/lib/wavefront-cli/commands/alert.rb +0 -1
  10. data/lib/wavefront-cli/commands/base.rb +1 -1
  11. data/lib/wavefront-cli/commands/link.rb +5 -0
  12. data/lib/wavefront-cli/commands/window.rb +1 -0
  13. data/lib/wavefront-cli/commands/write.rb +1 -1
  14. data/lib/wavefront-cli/controller.rb +51 -21
  15. data/lib/wavefront-cli/derivedmetric.rb +4 -0
  16. data/lib/wavefront-cli/display/alert.rb +2 -0
  17. data/lib/wavefront-cli/display/base.rb +18 -11
  18. data/lib/wavefront-cli/display/metric.rb +13 -5
  19. data/lib/wavefront-cli/display/printer/long.rb +12 -8
  20. data/lib/wavefront-cli/display/printer/sparkline.rb +2 -2
  21. data/lib/wavefront-cli/display/printer/terse.rb +3 -1
  22. data/lib/wavefront-cli/display/query.rb +7 -3
  23. data/lib/wavefront-cli/display/write.rb +2 -0
  24. data/lib/wavefront-cli/event.rb +27 -16
  25. data/lib/wavefront-cli/exception.rb +8 -0
  26. data/lib/wavefront-cli/externallink.rb +30 -0
  27. data/lib/wavefront-cli/maintenancewindow.rb +2 -2
  28. data/lib/wavefront-cli/output/hcl/base.rb +21 -18
  29. data/lib/wavefront-cli/output/hcl/dashboard.rb +13 -38
  30. data/lib/wavefront-cli/output/hcl/notificant.rb +4 -2
  31. data/lib/wavefront-cli/output/hcl/stdlib/array.rb +22 -0
  32. data/lib/wavefront-cli/output/hcl/stdlib/string.rb +9 -0
  33. data/lib/wavefront-cli/output/wavefront/base.rb +3 -0
  34. data/lib/wavefront-cli/output/wavefront/query.rb +2 -2
  35. data/lib/wavefront-cli/query.rb +2 -0
  36. data/lib/wavefront-cli/report.rb +5 -2
  37. data/lib/wavefront-cli/{string.rb → stdlib/string.rb} +16 -12
  38. data/lib/wavefront-cli/version.rb +1 -1
  39. data/lib/wavefront-cli/write.rb +12 -4
  40. data/spec/spec_helper.rb +41 -24
  41. data/spec/wavefront-cli/commands/link_spec.rb +1 -1
  42. data/spec/wavefront-cli/derivedmetric_spec.rb +2 -2
  43. data/spec/wavefront-cli/display/base_spec.rb +2 -0
  44. data/spec/wavefront-cli/display/printer/long_spec.rb +1 -0
  45. data/spec/wavefront-cli/externallink_spec.rb +52 -4
  46. data/spec/wavefront-cli/output/hcl_spec.rb +3 -1
  47. data/spec/wavefront-cli/output/ruby_spec.rb +5 -5
  48. data/spec/wavefront-cli/output/wavefront/query_spec.rb +14 -9
  49. data/spec/wavefront-cli/output/wavefront_spec.rb +3 -1
  50. data/spec/wavefront-cli/query_spec.rb +2 -0
  51. data/spec/wavefront-cli/{string_spec.rb → stdlib/string_spec.rb} +3 -3
  52. data/wavefront-cli.gemspec +7 -7
  53. metadata +34 -30
@@ -1,6 +1,14 @@
1
1
  module WavefrontCli
2
2
  class Exception
3
+ class CredentialError < RuntimeError; end
4
+ class FileNotFound < IOError; end
5
+ class InsufficientData < RuntimeError; end
6
+ class InvalidInput < RuntimeError; end
7
+ class SystemError < RuntimeError; end
3
8
  class UnhandledCommand < RuntimeError; end
9
+ class UnparseableInput < RuntimeError; end
10
+ class UnsupportedFileFormat < RuntimeError; end
11
+ class UnsupportedOperation < RuntimeError; end
4
12
  class UnsupportedOutput < RuntimeError; end
5
13
  end
6
14
  end
@@ -12,5 +12,35 @@ module WavefrontCli
12
12
  def validator_exception
13
13
  Wavefront::Exception::InvalidExternalLinkId
14
14
  end
15
+
16
+ def do_create
17
+ body = { name: options[:'<name>'],
18
+ template: options[:'<template>'],
19
+ description: options[:'<description>'],
20
+ metricFilterRegex: options[:metricregex],
21
+ sourceFilterRegex: options[:sourceregex],
22
+ pointFilterRegex: point_filter_regexes }
23
+
24
+ wf.create(body.select { |_k, v| v })
25
+ end
26
+
27
+ def search_key
28
+ :extlink
29
+ end
30
+
31
+ private
32
+
33
+ def point_filter_regexes
34
+ ret = options[:pointregex].each_with_object({}) do |r, a|
35
+ begin
36
+ k, v = r.split('=', 2)
37
+ a[k.to_sym] = v
38
+ rescue StandardError
39
+ puts "cannot parse point regex '#{r}'. Skipping."
40
+ end
41
+ end
42
+
43
+ ret.empty? ? nil : ret
44
+ end
15
45
  end
16
46
  end
@@ -78,8 +78,8 @@ module WavefrontCli
78
78
  change_end_time(Time.now.to_i)
79
79
  end
80
80
 
81
- def change_end_time(ts)
82
- wf.update(options[:'<id>'], endTimeInSeconds: ts)
81
+ def change_end_time(timestamp)
82
+ wf.update(options[:'<id>'], endTimeInSeconds: timestamp)
83
83
  end
84
84
  end
85
85
  end
@@ -2,6 +2,9 @@ require 'securerandom'
2
2
  require 'json'
3
3
 
4
4
  module WavefrontHclOutput
5
+ #
6
+ # Output stuff for Hashicorp Configuration Language
7
+ #
5
8
  class Base
6
9
  attr_reader :resp, :options
7
10
 
@@ -49,43 +52,43 @@ module WavefrontHclOutput
49
52
  end
50
53
 
51
54
  # Format each key-value pair
52
- # @param k [String] key
53
- # @param v [Any] value
55
+ # @param key [String] key
56
+ # @param val [Any] value
54
57
  # @return [String]
55
58
  #
56
- def handler(k, v)
57
- key_handler = "khandle_#{k}".to_sym
58
- value_handler = "vhandle_#{k}".to_sym
59
- quote_handler = "qhandle_#{k}".to_sym
60
- k = send(key_handler) if respond_to?(key_handler)
61
- v = send(value_handler, v) if respond_to?(value_handler)
59
+ def handler(key, val)
60
+ key_handler = "khandle_#{key}".to_sym
61
+ value_handler = "vhandle_#{key}".to_sym
62
+ quote_handler = "qhandle_#{key}".to_sym
63
+ key = send(key_handler) if respond_to?(key_handler)
64
+ val = send(value_handler, val) if respond_to?(value_handler)
62
65
 
63
66
  quote_handler = :quote_value unless respond_to?(quote_handler)
64
67
 
65
- format(' %s = %s', k.to_snake, send(quote_handler, v))
68
+ format(' %s = %s', key.to_snake, send(quote_handler, val))
66
69
  end
67
70
 
68
71
  # Tags need to be in an array. They aren't always called "tags"
69
72
  # by the API.
70
- # @param v [Array,Hash,String] tags
73
+ # @param val [Array,Hash,String] tags
71
74
  # @return [Array] of soft-quoted tags
72
75
  #
73
- def vhandle_tags(v)
74
- v = v.values if v.is_a?(Hash)
75
- Array(v).flatten
76
+ def vhandle_tags(val)
77
+ val = val.values if val.is_a?(Hash)
78
+ Array(val).flatten
76
79
  end
77
80
 
78
81
  # Some values need to be quoted, some need to be escaped etc
79
82
  # etc.
80
- # @param v [Object] value
83
+ # @param val [Object] value
81
84
  # @return [String]
82
85
  #
83
- def quote_value(v)
84
- case v.class.to_s.to_sym
86
+ def quote_value(val)
87
+ case val.class.to_s.to_sym
85
88
  when :String
86
- format('"%s"', v.gsub(/\"/, '\"'))
89
+ format('"%s"', val.gsub(/\"/, '\"'))
87
90
  else
88
- v
91
+ val
89
92
  end
90
93
  end
91
94
  end
@@ -1,4 +1,6 @@
1
1
  require_relative 'base'
2
+ require_relative 'stdlib/string'
3
+ require_relative 'stdlib/array'
2
4
 
3
5
  module WavefrontHclOutput
4
6
  #
@@ -11,7 +13,7 @@ module WavefrontHclOutput
11
13
  # in https://github.com/spaceapegames/terraform-provider-wavefront/blob/master/wavefront/resource_dashboard.go
12
14
  #
13
15
  class Dashboard < Base
14
-
16
+ #
15
17
  # Top-level fields
16
18
  #
17
19
  def hcl_fields
@@ -23,16 +25,16 @@ module WavefrontHclOutput
23
25
  end
24
26
 
25
27
  # @param vals [Array] an array of objects
26
- # @param fn [Symbol] a method which knows how to deal with one
28
+ # @param method [Symbol] a method which knows how to deal with one
27
29
  # of the objects in vals
28
30
  # @return [String] HCL list of vals
29
31
  #
30
- def listmaker(vals, fn)
31
- vals.each_with_object([]) { |v, a| a.<< send(fn, v) }.to_hcl_list
32
+ def listmaker(vals, method)
33
+ vals.each_with_object([]) { |v, a| a.<< send(method, v) }.to_hcl_list
32
34
  end
33
35
 
34
- def vhandle_sections(v)
35
- v.each_with_object([]) do |section, a|
36
+ def vhandle_sections(vals)
37
+ vals.each_with_object([]) do |section, a|
36
38
  a.<< ("name = \"#{section[:name]}\"\n row = " +
37
39
  handle_rows(section[:rows])).braced(4)
38
40
  end.to_hcl_list
@@ -40,7 +42,7 @@ module WavefrontHclOutput
40
42
 
41
43
  def handle_rows(rows)
42
44
  rows.each_with_object([]) do |row, a|
43
- a.<< ("chart = " + handle_charts(row[:charts]).to_s).braced(8)
45
+ a.<< ('chart = ' + handle_charts(row[:charts]).to_s).braced(8)
44
46
  end.to_hcl_list
45
47
  end
46
48
 
@@ -75,40 +77,13 @@ module WavefrontHclOutput
75
77
  end.to_hcl_obj(14)
76
78
  end
77
79
 
78
- def qhandle_sections(v)
79
- v
80
+ def qhandle_sections(val)
81
+ val
80
82
  end
81
83
 
82
- def quote_value(v)
83
- v.gsub!(/\$/, '$$') if v.is_a?(String)
84
+ def quote_value(val)
85
+ val.gsub!(/\$/, '$$') if v.is_a?(String)
84
86
  super
85
87
  end
86
88
  end
87
89
  end
88
-
89
- class String
90
- def braced(indent = 0)
91
- pad = ' ' * indent
92
- "\n#{pad}{#{self}\n#{pad}}"
93
- end
94
- end
95
-
96
- class Array
97
- #
98
- # Turn an array into a string which represents an HCL list
99
- # @return [String]
100
- #
101
- def to_hcl_list
102
- '[' + self.join(',') + ']'
103
- end
104
-
105
- # Turn an array into a string which represents an HCL object
106
- # @return [String]
107
- #
108
- def to_hcl_obj(indent = 0)
109
- outpad = ' ' * indent
110
- inpad = ' ' * (indent + 2)
111
-
112
- "\n#{outpad}{\n#{inpad}" + self.join("\n#{inpad}") + "\n#{outpad}}"
113
- end
114
- end
@@ -11,8 +11,8 @@ module WavefrontHclOutput
11
11
  contentType customHttpHeaders]
12
12
  end
13
13
 
14
- def vhandle_template(v)
15
- v.gsub(/\s*\n/, '')
14
+ def vhandle_template(val)
15
+ val.gsub(/\s*\n/, '')
16
16
  end
17
17
 
18
18
  def resource_name
@@ -23,8 +23,10 @@ module WavefrontHclOutput
23
23
  'name'
24
24
  end
25
25
 
26
+ # rubocop:disable Naming/MethodName
26
27
  def khandle_customHttpHeaders
27
28
  'custom_headers'
28
29
  end
30
+ # rubocop:enable Naming/MethodName
29
31
  end
30
32
  end
@@ -0,0 +1,22 @@
1
+ #
2
+ # Extensions to stdlib Array
3
+ #
4
+ class Array
5
+ #
6
+ # Turn an array into a string which represents an HCL list
7
+ # @return [String]
8
+ #
9
+ def to_hcl_list
10
+ '[' + join(',') + ']'
11
+ end
12
+
13
+ # Turn an array into a string which represents an HCL object
14
+ # @return [String]
15
+ #
16
+ def to_hcl_obj(indent = 0)
17
+ outpad = ' ' * indent
18
+ inpad = ' ' * (indent + 2)
19
+
20
+ "\n#{outpad}{\n#{inpad}" + join("\n#{inpad}") + "\n#{outpad}}"
21
+ end
22
+ end
@@ -0,0 +1,9 @@
1
+ #
2
+ # Extensions to stdlib String
3
+ #
4
+ class String
5
+ def braced(indent = 0)
6
+ pad = ' ' * indent
7
+ "\n#{pad}{#{self}\n#{pad}}"
8
+ end
9
+ end
@@ -1,4 +1,7 @@
1
1
  module WavefrontWavefrontOutput
2
+ #
3
+ # Standard output template
4
+ #
2
5
  class Base
3
6
  attr_reader :resp, :options
4
7
 
@@ -39,8 +39,8 @@ module WavefrontWavefrontOutput
39
39
  end
40
40
  end
41
41
 
42
- def wavefront_format(path, value, ts, source, tags = nil)
43
- arr = [path, value, ts, format('source=%s', source)]
42
+ def wavefront_format(path, value, timestamp, source, tags = nil)
43
+ arr = [path, value, timestamp, format('source=%s', source)]
44
44
  arr.<< tags.to_wf_tag if tags && !tags.empty?
45
45
  arr.join(' ')
46
46
  end
@@ -51,6 +51,7 @@ module WavefrontCli
51
51
 
52
52
  # @return [Hash] options for the SDK query method
53
53
  #
54
+ # rubocop:disable Metrics/AbcSize
54
55
  def q_opts
55
56
  ret = { autoEvents: options[:events],
56
57
  i: options[:inclusive],
@@ -64,6 +65,7 @@ module WavefrontCli
64
65
  ret[:p] = options[:points] if options[:points]
65
66
  ret
66
67
  end
68
+ # rubocop:enable Metrics/AbcSize
67
69
 
68
70
  # @return [Integer] start of query window. If one has been
69
71
  # given, that; if not, ten minutes ago
@@ -1,9 +1,12 @@
1
1
  require_relative 'base_write'
2
2
 
3
3
  module WavefrontCli
4
+ #
5
+ # Write metrics direct to Wavefront. Sister of WavefrontCli::Write
6
+ #
4
7
  class Report < BaseWrite
5
- def send_point(p)
6
- call_write(p)
8
+ def send_point(point)
9
+ call_write(point)
7
10
  rescue Wavefront::Exception::InvalidEndpoint
8
11
  abort 'could not speak to API'
9
12
  end
@@ -4,22 +4,22 @@ class String
4
4
  # Fold long command lines. We can't break on a space after an
5
5
  # option or it confuses docopt.
6
6
  #
7
- # @param tw [Integer] terminal width
7
+ # @param twidth [Integer] terminal width
8
8
  # @param indent [Integer] size of hanging indent, in chars
9
9
  #
10
- def cmd_fold(tw = TW, indent = 10)
11
- gsub(/(-\w) /, '\\1^').scan_line(tw - 12).join("\n" + ' ' * indent)
10
+ def cmd_fold(twidth = TW, indent = 10)
11
+ gsub(/(-\w) /, '\\1^').scan_line(twidth - 12).join("\n" + ' ' * indent)
12
12
  .restored
13
13
  end
14
14
 
15
15
  # Wrapper around #fold()
16
16
  #
17
- # @param tw [Integer] width of terminal, in chars
17
+ # @param twidth [Integer] width of terminal, in chars
18
18
  # @param indent [Integer] hanging indent of following lines
19
19
  # @return [String] folded and indented string
20
20
  #
21
- def opt_fold(tw = TW, indent = 10)
22
- fold(tw, indent, ' ')
21
+ def opt_fold(twidth = TW, indent = 10)
22
+ fold(twidth, indent, ' ')
23
23
  end
24
24
 
25
25
  # Fold long lines with a hanging indent. Originally a special case
@@ -27,23 +27,25 @@ class String
27
27
  # more general. Don't line-break default values, because it also
28
28
  # breaks docopt.
29
29
  #
30
- # @param tw [Integer] terminal width
30
+ # @param twidth [Integer] terminal width
31
31
  # @param indent [Integer] size of hanging indent, in chars
32
32
  # @param prefix [String] prepended to every line
33
33
  # @return [String] the folded line
34
34
  #
35
- def fold(tw = TW, indent = 10, prefix = '')
36
- chunks = gsub(/default: /, 'default:^').scan_line(tw - 8)
35
+ # rubocop:disable Metrics/AbcSize
36
+ def fold(twidth = TW, indent = 10, prefix = '')
37
+ chunks = gsub(/default: /, 'default:^').scan_line(twidth - 8)
37
38
  first_line = format("%s%s\n", prefix, chunks.shift)
38
39
 
39
40
  return first_line.restored if chunks.empty?
40
41
 
41
- rest = chunks.join(' ').scan_line(tw - indent - 5).map do |l|
42
+ rest = chunks.join(' ').scan_line(twidth - indent - 5).map do |l|
42
43
  prefix + ' ' * indent + l
43
44
  end
44
45
 
45
46
  (first_line + rest.join("\n") + "\n").restored
46
47
  end
48
+ # rubocop:enable Metrics/AbcSize
47
49
 
48
50
  # We use a carat as a temporary whitespace character to avoid
49
51
  # undesirable line breaking. This puts it back
@@ -84,7 +86,9 @@ class String
84
86
  # @return [String]
85
87
  #
86
88
  def to_snake
87
- self.gsub(/(.)([A-Z])/) { Regexp.last_match[1] + '_' +
88
- Regexp.last_match[2].downcase }
89
+ gsub(/(.)([A-Z])/) do
90
+ Regexp.last_match[1] + '_' +
91
+ Regexp.last_match[2].downcase
92
+ end
89
93
  end
90
94
  end
@@ -1 +1 @@
1
- WF_CLI_VERSION = '2.8.0'.freeze
1
+ WF_CLI_VERSION = '2.9.0'.freeze
@@ -12,11 +12,19 @@ module WavefrontCli
12
12
  end
13
13
 
14
14
  def validate_opts
15
- unless options[:metric] || options[:format].include?('m')
16
- abort "Supply a metric path in the file or with '-m'."
17
- end
15
+ validate_opts_file if options[:file]
16
+
17
+ return true if options[:proxy]
18
+ raise(WavefrontCli::Exception::CredentialError,
19
+ 'Missing proxy address.')
20
+ end
18
21
 
19
- raise 'Please supply a proxy address.' unless options[:proxy]
22
+ def validate_opts_file
23
+ unless options[:metric] || (options.key?(:infileformat) &&
24
+ options[:infileformat].include?('m'))
25
+ raise(WavefrontCli::Exception::InsufficientData,
26
+ "Supply a metric path in the file or with '-m'.")
27
+ end
20
28
  end
21
29
 
22
30
  def open_connection
@@ -8,13 +8,17 @@ require 'pathname'
8
8
  require_relative '../lib/wavefront-cli/controller'
9
9
 
10
10
  def all_commands
11
- (Pathname.new(__FILE__).dirname.parent + 'lib' + 'wavefront-cli' +
12
- 'commands').children.each.with_object([]) do |c, a|
13
- a.<< c.basename.to_s.chomp('.rb') unless c.basename.to_s == 'base.rb'
11
+ cmd_dir = ROOT + 'lib' + 'wavefront-cli' + 'commands'
12
+
13
+ files = cmd_dir.children.select do |f|
14
+ f.extname == '.rb' && f.basename.to_s != 'base.rb'
14
15
  end
16
+
17
+ files.each.with_object([]) { |c, a| a.<< c.basename.to_s.chomp('.rb') }
15
18
  end
16
19
 
17
20
  unless defined?(CMD)
21
+ ROOT = Pathname.new(__FILE__).dirname.parent
18
22
  CMD = 'wavefront'.freeze
19
23
  ENDPOINT = 'metrics.wavefront.com'.freeze
20
24
  TOKEN = '0123456789-ABCDEF'.freeze
@@ -75,10 +79,12 @@ def cmd_to_call(word, args, call, sdk_class = nil)
75
79
  it "runs #{cmd} and makes the correct API call" do
76
80
  if call.key?(:body)
77
81
  stub_request(method, uri).with(headers: h, body: call[:body])
78
- .to_return(body: {}.to_json, status: 200)
82
+ .to_return(body: {}.to_json,
83
+ status: 200)
79
84
  else
80
85
  stub_request(method, uri).with(headers: h)
81
- .to_return(body: {}.to_json, status: 200)
86
+ .to_return(body: {}.to_json,
87
+ status: 200)
82
88
  end
83
89
 
84
90
  require "wavefront-sdk/#{sdk_class.name.split('::').last.downcase}"
@@ -88,6 +94,7 @@ def cmd_to_call(word, args, call, sdk_class = nil)
88
94
  ),
89
95
  :respond
90
96
  ).and_return({})
97
+
91
98
  d = Spy.on_instance_method(sdk_class, :display)
92
99
  WavefrontCliController.new(cmd.split)
93
100
  assert d.has_been_called?
@@ -98,6 +105,7 @@ def cmd_to_call(word, args, call, sdk_class = nil)
98
105
  end
99
106
  end
100
107
  end
108
+ # rubocop:enable Metrics/AbcSize
101
109
 
102
110
  # Run a command we expect to fail, returning stdout and stderr
103
111
  #
@@ -124,7 +132,7 @@ def invalid_tags(cmd, subcmds)
124
132
  subcmds.each do |sc|
125
133
  it "fails '#{sc}' because of an invalid tag" do
126
134
  _out, err = fail_command("#{cmd} #{sc}")
127
- assert_equal(err, "'#{BAD_TAG}' is not a valid tag.\n")
135
+ assert_equal(err, "Invalid input. '#{BAD_TAG}' is not a valid tag.\n")
128
136
  end
129
137
  end
130
138
  end
@@ -146,7 +154,7 @@ def missing_creds(cmd, subcmds)
146
154
  subcmds.each do |subcmd|
147
155
  it "'#{subcmd}' errors and tells the user to use a token" do
148
156
  out, err = fail_command("#{cmd} #{subcmd} -c /f")
149
- assert_match(/supply an API token/, err)
157
+ assert_equal("Credential error. Missing API token.\n", err)
150
158
  assert_match(%r{config file '/f' not found.}, out)
151
159
  end
152
160
  end
@@ -155,41 +163,50 @@ end
155
163
 
156
164
  # Generic list tests, needed by most commands
157
165
  #
158
- def list_tests(cmd, pth = nil, k = nil)
166
+ def list_tests(cmd, pth = nil, klass = nil)
159
167
  pth ||= cmd
160
- cmd_to_call(cmd, 'list', { path: "/api/v2/#{pth}?limit=100&offset=0" }, k)
161
- cmd_to_call(cmd, 'list -L 50', { path: "/api/v2/#{pth}?limit=50&offset=0" },
162
- k)
168
+ cmd_to_call(cmd, 'list', { path: "/api/v2/#{pth}?limit=100&offset=0" },
169
+ klass)
170
+ cmd_to_call(cmd, 'list -L 50',
171
+ { path: "/api/v2/#{pth}?limit=50&offset=0" },
172
+ klass)
163
173
  cmd_to_call(cmd, 'list -L 20 -o 8',
164
- { path: "/api/v2/#{pth}?limit=20&offset=8" }, k)
165
- cmd_to_call(cmd, 'list -o 60', { path: "/api/v2/#{pth}?limit=100&offset=60" },
166
- k)
174
+ { path: "/api/v2/#{pth}?limit=20&offset=8" }, klass)
175
+ cmd_to_call(cmd, 'list -o 60',
176
+ { path: "/api/v2/#{pth}?limit=100&offset=60" },
177
+ klass)
167
178
  end
168
179
 
169
- def tag_tests(cmd, id, bad_id, pth = nil, k = nil)
180
+ def tag_tests(cmd, id, bad_id, pth = nil, klass = nil)
170
181
  pth ||= cmd
171
- cmd_to_call(cmd, "tags #{id}", { path: "/api/v2/#{pth}/#{id}/tag" }, k)
182
+ cmd_to_call(cmd, "tags #{id}", { path: "/api/v2/#{pth}/#{id}/tag" },
183
+ klass)
172
184
  cmd_to_call(cmd, "tag set #{id} mytag",
173
185
  { method: :post,
174
186
  path: "/api/v2/#{pth}/#{id}/tag",
175
187
  body: %w[mytag].to_json,
176
- headers: JSON_POST_HEADERS }, k)
188
+ headers: JSON_POST_HEADERS }, klass)
177
189
  cmd_to_call(cmd, "tag set #{id} mytag1 mytag2",
178
190
  { method: :post,
179
191
  path: "/api/v2/#{pth}/#{id}/tag",
180
192
  body: %w[mytag1 mytag2].to_json,
181
- headers: JSON_POST_HEADERS }, k)
193
+ headers: JSON_POST_HEADERS }, klass)
182
194
  cmd_to_call(cmd, "tag add #{id} mytag",
183
- { method: :put, path: "/api/v2/#{pth}/#{id}/tag/mytag" }, k)
195
+ { method: :put, path: "/api/v2/#{pth}/#{id}/tag/mytag" },
196
+ klass)
184
197
  cmd_to_call(cmd, "tag delete #{id} mytag",
185
- { method: :delete, path: "/api/v2/#{pth}/#{id}/tag/mytag" }, k)
198
+ { method: :delete, path: "/api/v2/#{pth}/#{id}/tag/mytag" },
199
+ klass)
186
200
  cmd_to_call(cmd, "tag clear #{id}", { method: :post,
187
201
  path: "/api/v2/#{pth}/#{id}/tag",
188
202
  body: [].to_json,
189
- headers: JSON_POST_HEADERS }, k)
190
- invalid_ids(cmd, ["tags #{bad_id}", "tag clear #{bad_id}",
191
- "tag add #{bad_id} mytag", "tag delete #{bad_id} mytag"])
192
- invalid_tags(cmd, ["tag add #{id} #{BAD_TAG}", "tag delete #{id} #{BAD_TAG}"])
203
+ headers: JSON_POST_HEADERS }, klass)
204
+ invalid_ids(cmd, ["tags #{bad_id}",
205
+ "tag clear #{bad_id}",
206
+ "tag add #{bad_id} mytag",
207
+ "tag delete #{bad_id} mytag"])
208
+ invalid_tags(cmd, ["tag add #{id} #{BAD_TAG}",
209
+ "tag delete #{id} #{BAD_TAG}"])
193
210
  end
194
211
 
195
212
  # Load in a canned query response