wavefront-client 3.4.0 → 3.5.1
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 +5 -13
- data/.gitignore +2 -0
- data/.travis.yml +3 -3
- data/README-cli.md +100 -0
- data/README.md +17 -3
- data/Rakefile +6 -1
- data/bin/wavefront +34 -3
- data/lib/wavefront/alerting.rb +27 -21
- data/lib/wavefront/batch_writer.rb +3 -36
- data/lib/wavefront/cli/events.rb +4 -5
- data/lib/wavefront/cli/sources.rb +193 -0
- data/lib/wavefront/cli/write.rb +8 -9
- data/lib/wavefront/cli.rb +3 -10
- data/lib/wavefront/client/version.rb +1 -1
- data/lib/wavefront/events.rb +2 -8
- data/lib/wavefront/exception.rb +2 -0
- data/lib/wavefront/metadata.rb +154 -29
- data/lib/wavefront/mixins.rb +18 -4
- data/lib/wavefront/response.rb +2 -0
- data/lib/wavefront/validators.rb +61 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/wavefront/batch_writer_spec.rb +0 -112
- data/spec/wavefront/cli/sources_spec.rb +40 -0
- data/spec/wavefront/cli_spec.rb +2 -2
- data/spec/wavefront/events_spec.rb +0 -10
- data/spec/wavefront/metadata_spec.rb +150 -2
- data/spec/wavefront/mixins_spec.rb +7 -0
- data/spec/wavefront/validators_spec.rb +109 -0
- data/wavefront-client.gemspec +1 -0
- metadata +39 -19
data/lib/wavefront/cli/write.rb
CHANGED
@@ -9,7 +9,6 @@ require 'socket'
|
|
9
9
|
# backward compatibility.
|
10
10
|
#
|
11
11
|
class Wavefront::Cli::Write < Wavefront::Cli
|
12
|
-
|
13
12
|
include Wavefront::Constants
|
14
13
|
include Wavefront::Mixins
|
15
14
|
|
@@ -19,7 +18,7 @@ class Wavefront::Cli::Write < Wavefront::Cli
|
|
19
18
|
ts = options[:time] ? parse_time(options[:time]) : false
|
20
19
|
|
21
20
|
[:proxy, :host].each do |h|
|
22
|
-
|
21
|
+
fail Wavefront::Exception::InvalidHostname unless valid_host?(h)
|
23
22
|
end
|
24
23
|
|
25
24
|
write_opts = {
|
@@ -28,7 +27,7 @@ class Wavefront::Cli::Write < Wavefront::Cli
|
|
28
27
|
metric_name: options[:'<metric>'],
|
29
28
|
point_tags: prep_tags(options[:tag]),
|
30
29
|
timestamp: ts,
|
31
|
-
noop: options[:noop]
|
30
|
+
noop: options[:noop]
|
32
31
|
}
|
33
32
|
|
34
33
|
write_metric(options[:'<value>'].to_i, options[:'<metric>'], write_opts)
|
@@ -54,7 +53,7 @@ class Wavefront::Cli::Write < Wavefront::Cli
|
|
54
53
|
#
|
55
54
|
unless value.is_a?(Numeric) || value.match(/^-?\d*\.?\d*$/) ||
|
56
55
|
value.match(/^-?\d*\.?\d*e\d+$/)
|
57
|
-
|
56
|
+
fail Wavefront::Exception::InvalidMetricValue
|
58
57
|
end
|
59
58
|
true
|
60
59
|
end
|
@@ -66,12 +65,12 @@ class Wavefront::Cli::Write < Wavefront::Cli
|
|
66
65
|
# through odd characters or whitespace.
|
67
66
|
#
|
68
67
|
begin
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
68
|
+
fail unless metric.is_a?(String) &&
|
69
|
+
metric.split('.').length > 1 &&
|
70
|
+
metric.match(/^[\w\-\._]+$/) &&
|
71
|
+
metric.length < 1024
|
73
72
|
rescue
|
74
|
-
|
73
|
+
raise Wavefront::Exception::InvalidMetricName
|
75
74
|
end
|
76
75
|
true
|
77
76
|
end
|
data/lib/wavefront/cli.rb
CHANGED
@@ -35,24 +35,17 @@ module Wavefront
|
|
35
35
|
#
|
36
36
|
# Load in configuration options from the (optionally) given
|
37
37
|
# section of an ini-style configuration file. If the file's
|
38
|
-
# not there, we don't consider that an error
|
39
|
-
# entirely reasonable to demand the user has one. Options
|
40
|
-
# passed on the command-line trump the same values in the
|
41
|
-
# file.
|
38
|
+
# not there, we don't consider that an error.
|
42
39
|
#
|
43
40
|
return unless options[:config].is_a?(String)
|
44
41
|
cf = Pathname.new(options[:config])
|
45
42
|
return unless cf.exist?
|
46
43
|
|
47
44
|
pf = options[:profile] || 'default'
|
48
|
-
raw = IniFile.load(cf)
|
49
|
-
profile = raw[pf]
|
50
|
-
|
51
45
|
puts "using #{pf} profile from #{cf}" if options[:debug]
|
52
46
|
|
53
|
-
|
54
|
-
k =
|
55
|
-
memo[k] = (options.include?(k) && options[k]) ? options[k] : v
|
47
|
+
IniFile.load(cf)[pf].each_with_object({}) do |(k, v), memo|
|
48
|
+
memo[k.to_sym] = v
|
56
49
|
end
|
57
50
|
end
|
58
51
|
end
|
data/lib/wavefront/events.rb
CHANGED
@@ -4,6 +4,7 @@ require 'rest_client'
|
|
4
4
|
require 'uri'
|
5
5
|
require 'logger'
|
6
6
|
require 'wavefront/constants'
|
7
|
+
require 'wavefront/mixins'
|
7
8
|
#
|
8
9
|
# Add basic support to cover Wavefront's events API. I have followed
|
9
10
|
# the standards and conventions established in the files already in
|
@@ -19,6 +20,7 @@ module Wavefront
|
|
19
20
|
#
|
20
21
|
class Events
|
21
22
|
include Wavefront::Constants
|
23
|
+
include Wavefront::Mixins
|
22
24
|
DEFAULT_PATH = '/api/events/'
|
23
25
|
|
24
26
|
attr_reader :headers
|
@@ -95,14 +97,6 @@ module Wavefront
|
|
95
97
|
RestClient.post(uri.to_s, query, headers)
|
96
98
|
end
|
97
99
|
|
98
|
-
def hash_to_qs(payload)
|
99
|
-
#
|
100
|
-
# Make a properly escaped query string out of a key: value
|
101
|
-
# hash.
|
102
|
-
#
|
103
|
-
URI.escape(payload.map { |k, v| [k, v].join('=') }.join('&'))
|
104
|
-
end
|
105
|
-
|
106
100
|
def debug(enabled)
|
107
101
|
RestClient.log = 'stdout' if enabled
|
108
102
|
end
|
data/lib/wavefront/exception.rb
CHANGED
data/lib/wavefront/metadata.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
=begin
|
1
|
+
=begin
|
2
2
|
Copyright 2015 Wavefront Inc.
|
3
3
|
Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
you may not use this file except in compliance with the License.
|
@@ -17,26 +17,48 @@ See the License for the specific language governing permissions and
|
|
17
17
|
require "wavefront/client/version"
|
18
18
|
require "wavefront/constants"
|
19
19
|
require "wavefront/exception"
|
20
|
+
require 'wavefront/validators'
|
20
21
|
require 'rest_client'
|
21
22
|
require 'uri'
|
22
23
|
require 'logger'
|
23
24
|
|
24
25
|
module Wavefront
|
26
|
+
#
|
27
|
+
# Because of the way the 'manage' API is laid out, this class doesn't
|
28
|
+
# reflect it as clearly as, say the 'alerts' class. There is a small
|
29
|
+
# amount of duplication in method names too, as it merges a new class
|
30
|
+
# and an old one.
|
31
|
+
#
|
32
|
+
# Note that the following methods do not do any exception handling. It
|
33
|
+
# is up to your client code to decide how to deal with, for example, a
|
34
|
+
# RestClient::ResourceNotFound exception.
|
35
|
+
#
|
25
36
|
class Metadata
|
26
37
|
include Wavefront::Constants
|
27
|
-
|
38
|
+
include Wavefront::Mixins
|
39
|
+
include Wavefront::Validators
|
40
|
+
DEFAULT_PATH = '/api/manage/source/'.freeze
|
28
41
|
|
29
|
-
attr_reader :headers, :
|
42
|
+
attr_reader :headers, :host
|
30
43
|
|
31
44
|
def initialize(token, host=DEFAULT_HOST, debug=false)
|
45
|
+
#
|
46
|
+
# 'host' is the Wavefront API endpoint
|
47
|
+
#
|
32
48
|
@headers = {'X-AUTH-TOKEN' => token}
|
33
49
|
@base_uri = URI::HTTPS.build(:host => host, :path => DEFAULT_PATH)
|
34
50
|
debug(debug)
|
35
51
|
end
|
36
52
|
|
37
53
|
def get_tags(hostname='', limit=100)
|
54
|
+
#
|
55
|
+
# This method is capable of making two distinct API calls,
|
56
|
+
# depending on the arguments. It is left here for backward
|
57
|
+
# compatibility, but you are recommended to use show_source() and
|
58
|
+
# show_sources() instead.
|
59
|
+
#
|
38
60
|
uri = @base_uri
|
39
|
-
|
61
|
+
|
40
62
|
unless hostname.empty?
|
41
63
|
uri = URI.join(@base_uri.to_s, hostname)
|
42
64
|
end
|
@@ -44,54 +66,157 @@ module Wavefront
|
|
44
66
|
if limit > 10000
|
45
67
|
limit = 10000
|
46
68
|
end
|
47
|
-
|
69
|
+
|
48
70
|
args = {:params => {:limit => limit}}.merge(@headers)
|
49
|
-
|
71
|
+
|
50
72
|
begin
|
51
73
|
response = RestClient.get(uri.to_s, args)
|
52
74
|
rescue RestClient::ResourceNotFound
|
53
75
|
# If a 404 is returned, we return an empty JSON as this is the expected behaviour for untagged hosts
|
54
|
-
response = {}
|
76
|
+
response = {}
|
55
77
|
end
|
56
78
|
|
57
|
-
|
58
|
-
|
79
|
+
response
|
59
80
|
end
|
60
81
|
|
61
82
|
def add_tags(hostnames, tags)
|
62
|
-
|
63
|
-
# Build and call tagging URI for each host and tag.
|
83
|
+
|
84
|
+
# Build and call tagging URI for each host and tag. A
|
85
|
+
# backward-compatibility wrapper for set_tag()
|
86
|
+
#
|
64
87
|
hostnames.each do |hostname|
|
65
|
-
|
66
|
-
extended_uri = URI.join(host_uri.to_s,"tags/")
|
67
|
-
tags.each do |tag|
|
68
|
-
final_uri = URI.join(extended_uri.to_s,tag)
|
69
|
-
RestClient.post(final_uri.to_s, {}, @headers)
|
70
|
-
end
|
88
|
+
tags.each { |tag| set_tag(hostname, tag) }
|
71
89
|
end
|
72
|
-
|
73
90
|
end
|
74
91
|
|
75
|
-
def remove_tags(hostnames, tags,
|
76
|
-
|
92
|
+
def remove_tags(hostnames, tags, _options = {})
|
93
|
+
#
|
94
|
+
# A backward-compatibilty wrapper to delete_tag().
|
95
|
+
#
|
77
96
|
hostnames.each do |hostname|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
97
|
+
tags.each { |tag| delete_tag(hostname, tag) }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def delete_tags(source)
|
102
|
+
#
|
103
|
+
# Delete all tags from a source. Maps to
|
104
|
+
# DELETE /api/manage/source/{source}/tags
|
105
|
+
#
|
106
|
+
fail Wavefront::Exception::InvalidSource unless valid_source?(source)
|
107
|
+
call_delete(build_uri(uri_concat(source, 'tags')))
|
108
|
+
end
|
109
|
+
|
110
|
+
def delete_tag(source, tag)
|
111
|
+
#
|
112
|
+
# Delete a given tag from a source. Maps to
|
113
|
+
# DELETE /api/manage/source/{source}/tags/{tag}
|
114
|
+
#
|
115
|
+
fail Wavefront::Exception::InvalidSource unless valid_source?(source)
|
116
|
+
fail Wavefront::Exception::InvalidString unless valid_string?(tag)
|
117
|
+
call_delete(build_uri(uri_concat(source, 'tags', tag)))
|
118
|
+
end
|
119
|
+
|
120
|
+
def show_sources(params = {})
|
121
|
+
#
|
122
|
+
# return a list of sources. Maps to
|
123
|
+
# GET /api/manage/source
|
124
|
+
# call it with a hash as described in the Wavefront API docs.
|
125
|
+
#
|
126
|
+
# At the time of writing, supported paramaters are:
|
127
|
+
# lastEntityId (string)
|
128
|
+
# desc (bool)
|
129
|
+
# limit (int)
|
130
|
+
# pattern (string)
|
131
|
+
#
|
132
|
+
# Hash keys should be symbols.
|
133
|
+
#
|
134
|
+
if params.key?(:lastEntityId) &&
|
135
|
+
!params[:lastEntityId].is_a?(String)
|
136
|
+
fail TypeError
|
137
|
+
end
|
138
|
+
|
139
|
+
if params.key?(:pattern) && !params[:pattern].is_a?(String)
|
140
|
+
fail TypeError
|
141
|
+
end
|
142
|
+
|
143
|
+
if params.key?(:desc) && ! (params[:desc] == !!params[:desc])
|
144
|
+
fail TypeError
|
145
|
+
end
|
146
|
+
|
147
|
+
if params.key?(:limit)
|
148
|
+
fail TypeError unless params[:limit].is_a?(Numeric)
|
149
|
+
|
150
|
+
if params[:limit] < 0 || params[:limit] >= 10000
|
151
|
+
fail Wavefront::Exception::ValueOutOfRange
|
83
152
|
end
|
84
153
|
end
|
85
154
|
|
155
|
+
call_get(build_uri(nil, query: hash_to_qs(params)))
|
156
|
+
end
|
157
|
+
|
158
|
+
def show_source(source)
|
159
|
+
#
|
160
|
+
# return information about a single source. Maps to
|
161
|
+
# GET /api/manage/source/{source}
|
162
|
+
#
|
163
|
+
fail Wavefront::Exception::InvalidSource unless valid_source?(source)
|
164
|
+
call_get(build_uri(source))
|
165
|
+
end
|
166
|
+
|
167
|
+
def set_description(source, desc)
|
168
|
+
#
|
169
|
+
# set the description field for a source. Maps to
|
170
|
+
# POST /api/manage/source/{source}/description
|
171
|
+
#
|
172
|
+
fail Wavefront::Exception::InvalidSource unless valid_source?(source)
|
173
|
+
fail Wavefront::Exception::InvalidString unless valid_string?(desc)
|
174
|
+
call_post(build_uri(uri_concat(source, 'description')), desc)
|
175
|
+
end
|
176
|
+
|
177
|
+
def set_tag(source, tag)
|
178
|
+
#
|
179
|
+
# set a tag on a source. Maps to
|
180
|
+
# POST /api/manage/source/{source}/tags/{tag}
|
181
|
+
#
|
182
|
+
fail Wavefront::Exception::InvalidSource unless valid_source?(source)
|
183
|
+
fail Wavefront::Exception::InvalidString unless valid_string?(tag)
|
184
|
+
call_post(build_uri(uri_concat(source, 'tags', tag)))
|
86
185
|
end
|
87
186
|
|
88
187
|
private
|
89
188
|
|
90
|
-
def
|
91
|
-
|
92
|
-
|
93
|
-
|
189
|
+
def build_uri(path_ext = '', options = {})
|
190
|
+
options[:host] ||= DEFAULT_HOST
|
191
|
+
options[:path] ||= DEFAULT_PATH
|
192
|
+
|
193
|
+
URI::HTTPS.build(
|
194
|
+
host: options[:host],
|
195
|
+
path: uri_concat(options[:path], path_ext),
|
196
|
+
query: options[:query]
|
197
|
+
)
|
94
198
|
end
|
95
199
|
|
200
|
+
def call_get(uri)
|
201
|
+
RestClient.get(uri.to_s, headers)
|
202
|
+
end
|
203
|
+
|
204
|
+
def call_delete(uri)
|
205
|
+
RestClient.delete(uri.to_s, headers)
|
206
|
+
end
|
207
|
+
|
208
|
+
def call_post(uri, query = nil)
|
209
|
+
h = headers
|
210
|
+
|
211
|
+
RestClient.post(uri.to_s, query,
|
212
|
+
h.merge(:'Content-Type' => 'text/plain',
|
213
|
+
:Accept => 'application/json'
|
214
|
+
)
|
215
|
+
)
|
216
|
+
end
|
217
|
+
|
218
|
+
def debug(enabled)
|
219
|
+
RestClient.log = 'stdout' if enabled
|
220
|
+
end
|
96
221
|
end
|
97
222
|
end
|
data/lib/wavefront/mixins.rb
CHANGED
@@ -15,15 +15,18 @@ See the License for the specific language governing permissions and
|
|
15
15
|
=end
|
16
16
|
|
17
17
|
module Wavefront
|
18
|
+
#
|
19
|
+
# Various things which help around the place
|
20
|
+
#
|
18
21
|
module Mixins
|
19
22
|
def interpolate_schema(label, host, prefix_length)
|
20
23
|
label_parts = label.split('.')
|
21
|
-
interpolated =
|
24
|
+
interpolated = []
|
22
25
|
interpolated << label_parts.shift(prefix_length)
|
23
26
|
interpolated << host
|
24
27
|
interpolated << label_parts
|
25
28
|
interpolated.flatten!
|
26
|
-
|
29
|
+
interpolated.join('.')
|
27
30
|
end
|
28
31
|
|
29
32
|
def parse_time(t)
|
@@ -34,8 +37,7 @@ module Wavefront
|
|
34
37
|
return t if t.is_a?(Integer)
|
35
38
|
return t.to_i if t.is_a?(Time)
|
36
39
|
return t.to_i if t.is_a?(String) && t.match(/^\d+$/)
|
37
|
-
|
38
|
-
to_time.utc.to_i
|
40
|
+
DateTime.parse("#{t} #{Time.now.getlocal.zone}").to_time.utc.to_i
|
39
41
|
rescue
|
40
42
|
raise "cannot parse timestamp '#{t}'."
|
41
43
|
end
|
@@ -48,5 +50,17 @@ module Wavefront
|
|
48
50
|
return false unless t.is_a?(Integer)
|
49
51
|
(t.to_f * 1000).round
|
50
52
|
end
|
53
|
+
|
54
|
+
def hash_to_qs(payload)
|
55
|
+
#
|
56
|
+
# Make a properly escaped query string out of a key: value
|
57
|
+
# hash.
|
58
|
+
#
|
59
|
+
URI.escape(payload.map { |k, v| [k, v].join('=') }.join('&'))
|
60
|
+
end
|
61
|
+
|
62
|
+
def uri_concat(*args)
|
63
|
+
args.join('/').squeeze('/')
|
64
|
+
end
|
51
65
|
end
|
52
66
|
end
|
data/lib/wavefront/response.rb
CHANGED
@@ -0,0 +1,61 @@
|
|
1
|
+
module Wavefront
|
2
|
+
#
|
3
|
+
# A module of mixins to validate input. The Wavefront documentation
|
4
|
+
# lays down restrictions on types and sizes of various inputs, which
|
5
|
+
# we will check on the user's behalf. Most of the information used in
|
6
|
+
# this file comes from https://community.wavefront.com/docs/DOC-1031
|
7
|
+
# some comes from the Swagger API documentation.
|
8
|
+
#
|
9
|
+
module Validators
|
10
|
+
def valid_source?(source)
|
11
|
+
#
|
12
|
+
# Check a source, according to
|
13
|
+
#
|
14
|
+
unless source.is_a?(String) && source.match(/^[a-z0-9\-_\.]+$/) &&
|
15
|
+
source.length < 1024
|
16
|
+
fail Wavefront::Exception::InvalidSource
|
17
|
+
end
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
def valid_string?(string)
|
22
|
+
#
|
23
|
+
# Only allows PCRE "word" characters, spaces, full-stops and
|
24
|
+
# commas in tags and descriptions. This might be too restrictive,
|
25
|
+
# but if it is, this is the only place we need to change it.
|
26
|
+
#
|
27
|
+
string.match(/^[\-\w \.,]*$/)
|
28
|
+
end
|
29
|
+
|
30
|
+
def valid_path?(path)
|
31
|
+
fail Wavefront::Exception::InvalidMetricName unless \
|
32
|
+
path.is_a?(String) && path.match(/^[a-z0-9\-_\.]+$/) &&
|
33
|
+
path.length < 1024
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def valid_value?(value)
|
38
|
+
fail Wavefront::Exception::InvalidMetricValue unless value.is_a?(Numeric)
|
39
|
+
true
|
40
|
+
end
|
41
|
+
|
42
|
+
def valid_ts?(ts)
|
43
|
+
unless ts.is_a?(Time) || ts.is_a?(Date)
|
44
|
+
fail Wavefront::Exception::InvalidTimestamp
|
45
|
+
end
|
46
|
+
true
|
47
|
+
end
|
48
|
+
|
49
|
+
def valid_tags?(tags)
|
50
|
+
#
|
51
|
+
# Operates on a hash of key-value point tags. These are
|
52
|
+
# different from source tags.
|
53
|
+
#
|
54
|
+
tags.each do |k, v|
|
55
|
+
fail Wavefront::Exception::InvalidTag unless (k.length +
|
56
|
+
v.length < 254) && k.match(/^[a-z0-9\-_\.]+$/)
|
57
|
+
end
|
58
|
+
true
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -21,11 +21,13 @@ require 'wavefront/metadata'
|
|
21
21
|
require 'wavefront/alerting'
|
22
22
|
require 'wavefront/events'
|
23
23
|
require 'wavefront/batch_writer'
|
24
|
+
require 'wavefront/validators'
|
24
25
|
require 'wavefront/cli'
|
25
26
|
require 'wavefront/cli/alerts'
|
26
27
|
require 'wavefront/cli/events'
|
27
28
|
require 'wavefront/cli/batch_write'
|
28
29
|
require 'wavefront/cli/write'
|
30
|
+
require 'wavefront/cli/sources'
|
29
31
|
|
30
32
|
TEST_TOKEN = "test"
|
31
33
|
TEST_HOST = "metrics.wavefront.com"
|
@@ -73,3 +75,7 @@ class Mocket
|
|
73
75
|
return true
|
74
76
|
end
|
75
77
|
end
|
78
|
+
|
79
|
+
def concat_url(*args)
|
80
|
+
'https://' + args.join('/').squeeze('/')
|
81
|
+
end
|
@@ -408,116 +408,4 @@ describe Wavefront::BatchWriter do
|
|
408
408
|
|
409
409
|
describe '#close_socket' do
|
410
410
|
end
|
411
|
-
|
412
|
-
describe '#valid_path?' do
|
413
|
-
k = Wavefront::BatchWriter.new(opts)
|
414
|
-
|
415
|
-
it 'accepts a-z, 0-9, _ and -' do
|
416
|
-
expect(k.valid_path?('a.l33t.metric_path-passes')).to be(true)
|
417
|
-
end
|
418
|
-
|
419
|
-
it 'accepts nearly very long paths' do
|
420
|
-
expect(k.valid_path?('a' * 1023)).to be(true)
|
421
|
-
end
|
422
|
-
|
423
|
-
it 'rejects very long paths' do
|
424
|
-
expect{k.valid_path?('a' * 1024)}.to raise_exception(
|
425
|
-
Wavefront::Exception::InvalidMetricName)
|
426
|
-
end
|
427
|
-
|
428
|
-
it 'rejects upper-case letters' do
|
429
|
-
expect{k.valid_path?('NO.NEED.TO.SHOUT')}.to raise_exception(
|
430
|
-
Wavefront::Exception::InvalidMetricName)
|
431
|
-
end
|
432
|
-
|
433
|
-
it 'rejects odd characters' do
|
434
|
-
expect{k.valid_path?('metric.is.(>_<)')}.to raise_exception(
|
435
|
-
Wavefront::Exception::InvalidMetricName)
|
436
|
-
end
|
437
|
-
end
|
438
|
-
|
439
|
-
describe '#valid_value?' do
|
440
|
-
k = Wavefront::BatchWriter.new(opts)
|
441
|
-
|
442
|
-
it 'accepts integers' do
|
443
|
-
expect(k.valid_value?(123456)).to be(true)
|
444
|
-
end
|
445
|
-
|
446
|
-
it 'accepts 0' do
|
447
|
-
expect(k.valid_value?(0)).to be(true)
|
448
|
-
end
|
449
|
-
|
450
|
-
it 'accepts negative integers' do
|
451
|
-
expect(k.valid_value?(-10)).to be(true)
|
452
|
-
end
|
453
|
-
|
454
|
-
it 'accepts decimals' do
|
455
|
-
expect(k.valid_value?(1.2345678)).to be(true)
|
456
|
-
end
|
457
|
-
|
458
|
-
it 'accepts exponential notation' do
|
459
|
-
expect(k.valid_value?(1.23e04)).to be(true)
|
460
|
-
end
|
461
|
-
|
462
|
-
it 'rejects strings which look like numbers' do
|
463
|
-
expect { k.valid_value?('1.23')}.to raise_exception(
|
464
|
-
Wavefront::Exception::InvalidMetricValue)
|
465
|
-
end
|
466
|
-
end
|
467
|
-
|
468
|
-
describe '#valid_ts?' do
|
469
|
-
k = Wavefront::BatchWriter.new(opts)
|
470
|
-
|
471
|
-
it 'rejects integers' do
|
472
|
-
expect { k.valid_ts?(Time.now.to_i) }.to raise_exception(
|
473
|
-
Wavefront::Exception::InvalidTimestamp)
|
474
|
-
end
|
475
|
-
|
476
|
-
it 'accepts Times' do
|
477
|
-
expect(k.valid_ts?(Time.now)).to be(true)
|
478
|
-
end
|
479
|
-
|
480
|
-
it 'accepts DateTimes' do
|
481
|
-
expect(k.valid_ts?(DateTime.now)).to be(true)
|
482
|
-
end
|
483
|
-
|
484
|
-
it 'accepts Dates' do
|
485
|
-
expect(k.valid_ts?(Date.today)).to be(true)
|
486
|
-
end
|
487
|
-
end
|
488
|
-
|
489
|
-
describe '#valid_tags?' do
|
490
|
-
k = Wavefront::BatchWriter.new(opts)
|
491
|
-
|
492
|
-
it 'accepts zero tags' do
|
493
|
-
expect(k.valid_tags?({})).to be(true)
|
494
|
-
end
|
495
|
-
|
496
|
-
it 'accepts nice sensible tags' do
|
497
|
-
expect(k.valid_tags?({tag1: 'val1', tag2: 'val2'})).to be(true)
|
498
|
-
end
|
499
|
-
|
500
|
-
it 'accepts spaces and symbols in values' do
|
501
|
-
expect(k.valid_tags?({tag1: 'val 1', tag2: 'val 2'})).to be(true)
|
502
|
-
expect(k.valid_tags?({tag1: '(>_<)', tag2: '^_^'})).to be(true)
|
503
|
-
end
|
504
|
-
|
505
|
-
it 'rejects spaces and symbols in keys' do
|
506
|
-
expect { k.valid_tags?({'tag 1' => 'val1',
|
507
|
-
'tag 2' => 'val2'}) }.to raise_exception(
|
508
|
-
Wavefront::Exception::InvalidTag)
|
509
|
-
expect { k.valid_tags?({'(>_<)' => 'val1',
|
510
|
-
'^_^' => 'val2'}) }.to raise_exception(
|
511
|
-
Wavefront::Exception::InvalidTag)
|
512
|
-
end
|
513
|
-
|
514
|
-
it 'rejects long keys and/or values' do
|
515
|
-
expect { k.valid_tags?({tag1: 'v' * 255}) }.to raise_exception(
|
516
|
-
Wavefront::Exception::InvalidTag)
|
517
|
-
expect { k.valid_tags?({'k' * 255 => 'val1'}) }.to raise_exception(
|
518
|
-
Wavefront::Exception::InvalidTag)
|
519
|
-
expect { k.valid_tags?({'k' * 130 => 'v' * 130}) }.to raise_exception(
|
520
|
-
Wavefront::Exception::InvalidTag)
|
521
|
-
end
|
522
|
-
end
|
523
411
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#
|
2
|
+
# Due to dependency requirements, webmock does not work with Ruby
|
3
|
+
# 1.9.3. For as long as we have to support that, it's off the table.
|
4
|
+
#
|
5
|
+
require 'spec_helper'
|
6
|
+
#require 'webmock/rspec'
|
7
|
+
|
8
|
+
opts = {
|
9
|
+
token: TEST_TOKEN,
|
10
|
+
}
|
11
|
+
|
12
|
+
describe Wavefront::Cli::Sources do
|
13
|
+
attr_reader :wf, :host, :path, :headers, :post_headers
|
14
|
+
|
15
|
+
before do
|
16
|
+
@wf = Wavefront::Cli::Sources.new(opts, nil)
|
17
|
+
@wf.setup_wf
|
18
|
+
@host = Wavefront::Metadata::DEFAULT_HOST
|
19
|
+
@path = Wavefront::Metadata::DEFAULT_PATH
|
20
|
+
@headers = { :'X-AUTH-TOKEN' => TEST_TOKEN }
|
21
|
+
@post_headers =headers.merge(
|
22
|
+
{ :'Content-Type' => 'text/plain', :Accept => 'application/json' })
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
#describe '#list_source_handler' do
|
27
|
+
#it 'makes API request with default options' do
|
28
|
+
#stub_request(:get, "https://metrics.wavefront.com/api/manage/source/?desc=false&limit=100&pattern=mysource").
|
29
|
+
#with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'User-Agent'=>'Ruby', 'X-Auth-Token'=>'test'}).
|
30
|
+
#to_return(:status => 200, :body => "{}", :headers => {})
|
31
|
+
#wf.list_source_handler('mysource',)
|
32
|
+
#expect(wf).to receive(:display_data).with('list_source', '')
|
33
|
+
#end
|
34
|
+
|
35
|
+
#it 'handles an invalid source' do
|
36
|
+
#expect{wf.show_source('!INVALID!')}.
|
37
|
+
#to raise_exception(Wavefront::Exception::InvalidSource)
|
38
|
+
#end
|
39
|
+
#end
|
40
|
+
end
|
data/spec/wavefront/cli_spec.rb
CHANGED
@@ -59,10 +59,10 @@ describe Wavefront::Cli do
|
|
59
59
|
expect(pf[:token]).to eq('12345678-abcd-1234-abcd-123456789012')
|
60
60
|
end
|
61
61
|
|
62
|
-
it 'prefers command-line options
|
62
|
+
it 'prefers config file values to command-line options' do
|
63
63
|
k = Wavefront::Cli.new({config: cf, format: 'graphite'}, false)
|
64
64
|
pf = k.load_profile
|
65
|
-
expect(pf[:format]).to eq('
|
65
|
+
expect(pf[:format]).to eq('human')
|
66
66
|
expect(pf[:token]).to eq('12345678-abcd-1234-abcd-123456789012')
|
67
67
|
end
|
68
68
|
end
|