wavefront-cli 8.3.0 → 8.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/release.yml +37 -0
- data/.github/workflows/test.yml +23 -0
- data/.rubocop.yml +10 -6
- data/HISTORY.md +21 -1
- data/lib/wavefront-cli/base.rb +3 -0
- data/lib/wavefront-cli/commands/.rubocop.yml +2 -13
- data/lib/wavefront-cli/commands/event.rb +8 -6
- data/lib/wavefront-cli/commands/serviceaccount.rb +6 -4
- data/lib/wavefront-cli/controller.rb +9 -0
- data/lib/wavefront-cli/display/base.rb +3 -2
- data/lib/wavefront-cli/display/printer/sparkline.rb +1 -1
- data/lib/wavefront-cli/display/serviceaccount.rb +12 -4
- data/lib/wavefront-cli/event.rb +50 -166
- data/lib/wavefront-cli/event_store.rb +177 -0
- data/lib/wavefront-cli/exception.rb +21 -0
- data/lib/wavefront-cli/exception_handler.rb +4 -0
- data/lib/wavefront-cli/opt_handler.rb +1 -1
- data/lib/wavefront-cli/query.rb +1 -1
- data/lib/wavefront-cli/serviceaccount.rb +16 -6
- data/lib/wavefront-cli/settings.rb +3 -4
- data/lib/wavefront-cli/stdlib/string.rb +1 -1
- data/lib/wavefront-cli/version.rb +1 -1
- data/lib/wavefront-cli/write.rb +1 -1
- data/spec/.rubocop.yml +2 -17
- data/spec/spec_helper.rb +0 -1
- data/spec/support/minitest_assertions.rb +2 -2
- data/spec/wavefront-cli/commands/base_spec.rb +2 -2
- data/spec/wavefront-cli/commands/config_spec.rb +1 -1
- data/spec/wavefront-cli/controller_spec.rb +14 -0
- data/spec/wavefront-cli/event_spec.rb +69 -109
- data/spec/wavefront-cli/event_store_spec.rb +186 -0
- data/spec/wavefront-cli/opt_handler_spec.rb +3 -3
- data/spec/wavefront-cli/serviceaccount_spec.rb +53 -21
- data/wavefront-cli.gemspec +5 -2
- metadata +62 -10
- data/.travis.yml +0 -20
@@ -22,6 +22,18 @@ class WavefrontCliHelpTest < MiniTest::Test
|
|
22
22
|
assert_match(/^ \w+ --help$/, e.message)
|
23
23
|
end
|
24
24
|
|
25
|
+
def test_commands_no_args
|
26
|
+
SupportedCommands.new.all.each do |cmd|
|
27
|
+
_test_command_no_args(cmd)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def _test_command_no_args(cmd)
|
32
|
+
capture_io { WavefrontCliController.new([cmd]) }
|
33
|
+
rescue SystemExit => e
|
34
|
+
assert e.message.end_with?("wf #{cmd} --help")
|
35
|
+
end
|
36
|
+
|
25
37
|
def test_version
|
26
38
|
capture_io { WavefrontCliController.new(%w[--version]) }
|
27
39
|
rescue SystemExit => e
|
@@ -40,6 +52,7 @@ class WavefrontCliHelpTest < MiniTest::Test
|
|
40
52
|
end
|
41
53
|
end
|
42
54
|
|
55
|
+
# rubocop:disable Style/RedundantBegin
|
43
56
|
def test_command_help
|
44
57
|
SupportedCommands.new.all.each do |cmd|
|
45
58
|
begin
|
@@ -54,6 +67,7 @@ class WavefrontCliHelpTest < MiniTest::Test
|
|
54
67
|
end
|
55
68
|
end
|
56
69
|
end
|
70
|
+
# rubocop:enable Style/RedundantBegin
|
57
71
|
|
58
72
|
def test_malformed_config
|
59
73
|
capture_io do
|
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
require 'tmpdir'
|
5
5
|
require_relative '../support/command_base'
|
6
|
+
require_relative '../test_mixins/tag'
|
6
7
|
require_relative '../../lib/wavefront-cli/event'
|
7
8
|
require 'wavefront-sdk/support/mixins'
|
8
9
|
|
@@ -15,12 +16,11 @@ class EventEndToEndTest < EndToEndTest
|
|
15
16
|
attr_reader :test_state_dir
|
16
17
|
|
17
18
|
include Wavefront::Mixins
|
18
|
-
include WavefrontCliTest::Describe
|
19
|
-
include WavefrontCliTest::Delete
|
20
|
-
# Ones above work, ones below don't
|
19
|
+
# include WavefrontCliTest::Describe
|
20
|
+
# include WavefrontCliTest::Delete
|
21
21
|
# include WavefrontCliTest::Search
|
22
|
-
# include WavefrontCliTest::Set
|
23
|
-
# include WavefrontCliTest::
|
22
|
+
# #include WavefrontCliTest::Set
|
23
|
+
# include WavefrontCliTest::Tag
|
24
24
|
|
25
25
|
def before_setup
|
26
26
|
@test_state_dir = Pathname.new(Dir.mktmpdir)
|
@@ -31,11 +31,6 @@ class EventEndToEndTest < EndToEndTest
|
|
31
31
|
FileUtils.rm_r(test_state_dir)
|
32
32
|
end
|
33
33
|
|
34
|
-
def cmd_instance
|
35
|
-
cmd_class.new(event_state_dir: TEST_EVENT_DIR)
|
36
|
-
puts cmd_class
|
37
|
-
end
|
38
|
-
|
39
34
|
def test_list_no_options
|
40
35
|
str = '/api/v2/event\?' \
|
41
36
|
'earliestStartTimeEpochMillis=\d{13}+&' \
|
@@ -65,6 +60,22 @@ class EventEndToEndTest < EndToEndTest
|
|
65
60
|
end
|
66
61
|
end
|
67
62
|
|
63
|
+
def test_show_with_no_local_events
|
64
|
+
assert_exits_with('No locally recorded events.', 'show')
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_show
|
68
|
+
setup_test_state_dir
|
69
|
+
|
70
|
+
out, err = capture_io do
|
71
|
+
assert_raises(SystemExit) { wf.new("event show -c #{CF}".split) }
|
72
|
+
end
|
73
|
+
|
74
|
+
assert_empty(err)
|
75
|
+
assert_equal("1568133440530:ev3:0\n1568133440520:ev2:0\n" \
|
76
|
+
"1568133440515:ev1:1\n1568133440510:ev1:0\n", out)
|
77
|
+
end
|
78
|
+
|
68
79
|
def test_create
|
69
80
|
mock_id = "#{start_time}:#{event_name}:1"
|
70
81
|
state_file = state_dir + mock_id
|
@@ -100,8 +111,8 @@ class EventEndToEndTest < EndToEndTest
|
|
100
111
|
refute state_file.exist?
|
101
112
|
|
102
113
|
out, err = capture_io do
|
103
|
-
assert_cmd_posts('create -d reason -H host1 -H host2 -g ' \
|
104
|
-
"
|
114
|
+
assert_cmd_posts('create -d reason -H host1 -H host2 -g mytag ' \
|
115
|
+
"#{event_name}",
|
105
116
|
'/api/v2/event',
|
106
117
|
{ name: event_name,
|
107
118
|
startTime: a_ms_timestamp,
|
@@ -148,15 +159,6 @@ class EventEndToEndTest < EndToEndTest
|
|
148
159
|
assert_match(/\ntags tag1\n tag2\n/, out)
|
149
160
|
end
|
150
161
|
|
151
|
-
def test_close_named_event
|
152
|
-
quietly do
|
153
|
-
assert_cmd_posts('close 1568133440520:ev2:0',
|
154
|
-
'/api/v2/event/1568133440520:ev2:0/close')
|
155
|
-
end
|
156
|
-
|
157
|
-
assert_abort_on_missing_creds("close #{id}")
|
158
|
-
end
|
159
|
-
|
160
162
|
def test_close_with_no_local_events
|
161
163
|
quietly { assert_cmd_posts("close #{id}", "/api/v2/event/#{id}/close") }
|
162
164
|
assert_exits_with('No locally recorded events.', 'close')
|
@@ -212,26 +214,47 @@ class EventEndToEndTest < EndToEndTest
|
|
212
214
|
end
|
213
215
|
end
|
214
216
|
|
215
|
-
def
|
216
|
-
|
217
|
+
def test_window_start
|
218
|
+
wfse = WavefrontCli::Event.new(start: wall_time[0], end: wall_time[1])
|
219
|
+
assert_kind_of(Numeric, wfse.window_start)
|
220
|
+
assert_equal(epoch_ms_time[0], wfse.window_start)
|
221
|
+
end
|
217
222
|
|
218
|
-
|
219
|
-
|
220
|
-
|
223
|
+
def test_window_end
|
224
|
+
wfse = WavefrontCli::Event.new(start: wall_time[0], end: wall_time[1])
|
225
|
+
assert_kind_of(Numeric, wfse.window_end)
|
226
|
+
assert_equal(epoch_ms_time[1], wfse.window_end)
|
227
|
+
end
|
221
228
|
|
222
|
-
|
223
|
-
|
224
|
-
|
229
|
+
def test_list_args_defaults
|
230
|
+
wfe = WavefrontCli::Event.new({})
|
231
|
+
x = wfe.list_args
|
232
|
+
assert_instance_of(Array, x)
|
233
|
+
assert_equal(4, x.size)
|
234
|
+
assert_in_delta(((Time.now - 600).to_i * 1000), x[0], 1000)
|
235
|
+
assert_in_delta((Time.now.to_i * 1000), x[1], 1000)
|
236
|
+
assert_equal(100, x[2])
|
237
|
+
assert_nil(x[3])
|
238
|
+
end
|
239
|
+
|
240
|
+
def test_list_args_options
|
241
|
+
wfse = WavefrontCli::Event.new(limit: 55,
|
242
|
+
start: wall_time[0],
|
243
|
+
cursor: id,
|
244
|
+
end: wall_time[1])
|
245
|
+
x = wfse.list_args
|
246
|
+
assert_instance_of(Array, x)
|
247
|
+
assert_equal(4, x.size)
|
248
|
+
assert_equal(epoch_ms_time[0], x[0])
|
249
|
+
assert_equal(epoch_ms_time[1], x[1])
|
250
|
+
assert_equal(55, x[2])
|
251
|
+
assert_equal(id, x[3])
|
225
252
|
end
|
226
253
|
|
227
254
|
private
|
228
255
|
|
229
256
|
def id
|
230
|
-
'1481553823153:testev'
|
231
|
-
end
|
232
|
-
|
233
|
-
def event_name
|
234
|
-
'test_event'
|
257
|
+
'1481553823153:testev:0'
|
235
258
|
end
|
236
259
|
|
237
260
|
def invalid_id
|
@@ -242,18 +265,24 @@ class EventEndToEndTest < EndToEndTest
|
|
242
265
|
'event'
|
243
266
|
end
|
244
267
|
|
268
|
+
def event_name
|
269
|
+
'test_event'
|
270
|
+
end
|
271
|
+
|
245
272
|
def start_time
|
246
273
|
1_481_553_823_153
|
247
274
|
end
|
248
275
|
|
249
|
-
def
|
250
|
-
|
276
|
+
def epoch_ms_time
|
277
|
+
wall_time.map { |t| (t.to_i * 1000) }
|
251
278
|
end
|
252
279
|
|
253
280
|
def state_dir
|
254
281
|
test_state_dir + (Etc.getlogin || 'notty')
|
255
282
|
end
|
256
283
|
|
284
|
+
# Puts some test events in the state directory
|
285
|
+
#
|
257
286
|
def setup_test_state_dir
|
258
287
|
FileUtils.mkdir_p(state_dir)
|
259
288
|
|
@@ -285,79 +314,10 @@ class EventEndToEndTest < EndToEndTest
|
|
285
314
|
"https://#{perm[:endpoint]}/api/v2/event/#{mock_id}/close")
|
286
315
|
.with(body: 'null')
|
287
316
|
end
|
288
|
-
end
|
289
|
-
|
290
|
-
# Unit tests for class methods
|
291
|
-
#
|
292
|
-
class EventMethodTests < Minitest::Test
|
293
|
-
attr_reader :wf, :wfse
|
294
|
-
|
295
|
-
def setup
|
296
|
-
@wf = WavefrontCli::Event.new({})
|
297
|
-
@wfse = WavefrontCli::Event.new(start: wall_time[0],
|
298
|
-
end: wall_time[1],
|
299
|
-
limit: 55,
|
300
|
-
cursor: '1481553823153:testev')
|
301
|
-
end
|
302
|
-
|
303
|
-
def test_create_dir_ok
|
304
|
-
base = Pathname.new(Dir.mktmpdir)
|
305
|
-
dir = base + 'testdir'
|
306
|
-
refute dir.exist?
|
307
|
-
wf.create_dir(dir)
|
308
|
-
assert dir.exist?
|
309
|
-
dir.unlink
|
310
|
-
base.unlink
|
311
|
-
end
|
312
|
-
|
313
|
-
def test_create_dir_fail
|
314
|
-
spy = Spy.on(FileUtils, :mkdir_p).and_return(false)
|
315
|
-
|
316
|
-
assert_raises(WavefrontCli::Exception::SystemError) do
|
317
|
-
wf.create_dir(Pathname.new('/any/old/directory'))
|
318
|
-
end
|
319
|
-
|
320
|
-
assert spy.has_been_called?
|
321
|
-
spy.unhook
|
322
|
-
end
|
323
|
-
|
324
|
-
def test_list_args_defaults
|
325
|
-
x = wf.list_args
|
326
|
-
assert_instance_of(Array, x)
|
327
|
-
assert_equal(4, x.size)
|
328
|
-
assert_in_delta(((Time.now - 600).to_i * 1000), x[0], 1000)
|
329
|
-
assert_in_delta((Time.now.to_i * 1000), x[1], 1000)
|
330
|
-
assert_equal(100, x[2])
|
331
|
-
assert_nil(x[3])
|
332
|
-
end
|
333
|
-
|
334
|
-
def test_list_args_options
|
335
|
-
x = wfse.list_args
|
336
|
-
assert_instance_of(Array, x)
|
337
|
-
assert_equal(4, x.size)
|
338
|
-
assert_equal(epoch_ms_time[0], x[0])
|
339
|
-
assert_equal(epoch_ms_time[1], x[1])
|
340
|
-
assert_equal(55, x[2])
|
341
|
-
assert_equal('1481553823153:testev', x[3])
|
342
|
-
end
|
343
|
-
|
344
|
-
def test_window_start
|
345
|
-
assert_kind_of(Numeric, wf.window_start)
|
346
|
-
assert_equal(epoch_ms_time[0], wfse.window_start)
|
347
|
-
end
|
348
|
-
|
349
|
-
def test_window_end
|
350
|
-
assert_kind_of(Numeric, wf.window_end)
|
351
|
-
assert_equal(epoch_ms_time[1], wfse.window_end)
|
352
|
-
end
|
353
317
|
|
354
|
-
|
355
|
-
|
356
|
-
def
|
357
|
-
|
358
|
-
end
|
359
|
-
|
360
|
-
def epoch_ms_time
|
361
|
-
wall_time.map { |t| (t.to_i * 1000) }
|
318
|
+
# Event searching uses a cursor, not an offset
|
319
|
+
#
|
320
|
+
def cannot_handle_offsets
|
321
|
+
true
|
362
322
|
end
|
363
323
|
end
|
@@ -0,0 +1,186 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'pathname'
|
5
|
+
require 'spy'
|
6
|
+
require 'minitest/autorun'
|
7
|
+
require_relative '../../lib/wavefront-cli/event_store'
|
8
|
+
|
9
|
+
TEST_EVENT_STORE_DIR = Pathname.new(Dir.mktmpdir)
|
10
|
+
|
11
|
+
# Tests for event store class. This is tested well via the interface of the
|
12
|
+
# events CLI class.
|
13
|
+
#
|
14
|
+
class Test < MiniTest::Test
|
15
|
+
attr_reader :wf
|
16
|
+
|
17
|
+
include WavefrontCli::Constants
|
18
|
+
|
19
|
+
def before_setup
|
20
|
+
FileUtils.mkdir_p(TEST_EVENT_STORE_DIR)
|
21
|
+
end
|
22
|
+
|
23
|
+
def setup
|
24
|
+
@wf = WavefrontCli::EventStore.new({}, TEST_EVENT_STORE_DIR)
|
25
|
+
end
|
26
|
+
|
27
|
+
def teardown
|
28
|
+
FileUtils.rm_r(TEST_EVENT_STORE_DIR)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_state_file_needed?
|
32
|
+
wf1 = WavefrontCli::EventStore.new({}, TEST_EVENT_STORE_DIR)
|
33
|
+
assert wf1.state_file_needed?
|
34
|
+
|
35
|
+
wf2 = WavefrontCli::EventStore.new({ nostate: true }, TEST_EVENT_STORE_DIR)
|
36
|
+
refute wf2.state_file_needed?
|
37
|
+
|
38
|
+
wf3 = WavefrontCli::EventStore.new({ instant: true }, TEST_EVENT_STORE_DIR)
|
39
|
+
refute wf3.state_file_needed?
|
40
|
+
|
41
|
+
wf4 = WavefrontCli::EventStore.new({ start: Time.now - 20, end: Time.now },
|
42
|
+
TEST_EVENT_STORE_DIR)
|
43
|
+
refute wf4.state_file_needed?
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_event_file
|
47
|
+
x = wf.event_file(id)
|
48
|
+
assert_instance_of(Pathname, x)
|
49
|
+
assert_equal(wf.dir, x.dirname)
|
50
|
+
assert_equal(id, x.basename.to_s)
|
51
|
+
|
52
|
+
assert_nil(wf.event_file('not_a_valid_id'))
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_create_dir_ok
|
56
|
+
dir = TEST_EVENT_STORE_DIR + 'testdir'
|
57
|
+
refute dir.exist?
|
58
|
+
wf.create_dir(dir)
|
59
|
+
assert dir.exist?
|
60
|
+
dir.unlink
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_list
|
64
|
+
setup_test_state_dir
|
65
|
+
|
66
|
+
x = wf.list
|
67
|
+
assert(x.all? { |e| e.is_a?(Pathname) })
|
68
|
+
assert_equal(4, x.size)
|
69
|
+
|
70
|
+
empty_test_state_dir
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_list_empty_stack
|
74
|
+
out, err = capture_io { assert_raises(SystemExit) { wf.list } }
|
75
|
+
assert_empty(out)
|
76
|
+
assert_equal("No locally recorded events.\n", err)
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_pop_event
|
80
|
+
setup_test_state_dir
|
81
|
+
|
82
|
+
assert (wf.dir + '1568133440530:ev3:0').exist?
|
83
|
+
assert_equal('1568133440530:ev3:0', wf.pop_event!)
|
84
|
+
refute (wf.dir + '1568133440530:ev3:0').exist?
|
85
|
+
|
86
|
+
empty_test_state_dir
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_pop_event_named
|
90
|
+
setup_test_state_dir
|
91
|
+
|
92
|
+
assert (wf.dir + '1568133440515:ev1:1').exist?
|
93
|
+
assert_equal('1568133440515:ev1:1', wf.pop_event!('ev1'))
|
94
|
+
refute (wf.dir + '1568133440515:ev1:1').exist?
|
95
|
+
|
96
|
+
empty_test_state_dir
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_event_specific
|
100
|
+
setup_test_state_dir
|
101
|
+
|
102
|
+
assert (wf.dir + '1568133440515:ev1:1').exist?
|
103
|
+
assert_equal('1568133440515:ev1:1', wf.event('1568133440515:ev1:1'))
|
104
|
+
assert (wf.dir + '1568133440515:ev1:1').exist?
|
105
|
+
|
106
|
+
empty_test_state_dir
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_pop_event_empty_stack
|
110
|
+
out, err = capture_io { assert_raises(SystemExit) { wf.pop_event! } }
|
111
|
+
assert_empty(out)
|
112
|
+
assert_equal("No locally recorded events.\n", err)
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_event_state_dir
|
116
|
+
ENV['WF_EVENT_STATE_DIR'] = nil
|
117
|
+
assert_equal(EVENT_STATE_DIR, wf.event_state_dir)
|
118
|
+
|
119
|
+
ENV['WF_EVENT_STATE_DIR'] = '/tmp/tester'
|
120
|
+
assert_equal(Pathname.new('/tmp/tester'), wf.event_state_dir)
|
121
|
+
ENV['WF_EVENT_STATE_DIR'] = nil
|
122
|
+
|
123
|
+
assert_equal(Pathname.new('/tmp/mydir'), wf.event_state_dir('/tmp/mydir'))
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_create_dir_fail
|
127
|
+
spy = Spy.on(FileUtils, :mkdir_p).and_return(false)
|
128
|
+
|
129
|
+
assert_raises(WavefrontCli::Exception::SystemError) do
|
130
|
+
wf.create_dir(Pathname.new('/any/old/directory'))
|
131
|
+
end
|
132
|
+
|
133
|
+
assert spy.has_been_called?
|
134
|
+
spy.unhook
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_event_file_data
|
138
|
+
wf = WavefrontCli::EventStore.new({ desc: 'test event' },
|
139
|
+
TEST_EVENT_STORE_DIR)
|
140
|
+
x = wf.event_file_data
|
141
|
+
assert_instance_of(String, x)
|
142
|
+
y = JSON.parse(x, symbolize_names: true)
|
143
|
+
assert_equal('test event', y[:description])
|
144
|
+
assert_equal(%i[hosts description severity tags], y.keys)
|
145
|
+
assert_nil(y[:tags])
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_create
|
149
|
+
refute (wf.dir + id).exist?
|
150
|
+
out, err = capture_io { wf.create!(id) }
|
151
|
+
assert_match(/Event state recorded at .*1481553823153:testev:0./, out)
|
152
|
+
assert_empty(err)
|
153
|
+
assert (wf.dir + id).exist?
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_create_with_nostate
|
157
|
+
wf1 = WavefrontCli::EventStore.new(nostate: true)
|
158
|
+
assert_nil wf1.create!(id)
|
159
|
+
end
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
def id
|
164
|
+
'1481553823153:testev:0'
|
165
|
+
end
|
166
|
+
|
167
|
+
def dummy_event_files
|
168
|
+
%w[1568133440510:ev1:0
|
169
|
+
1568133440515:ev1:1
|
170
|
+
1568133440520:ev2:0
|
171
|
+
1568133440530:ev3:0]
|
172
|
+
end
|
173
|
+
|
174
|
+
def setup_test_state_dir
|
175
|
+
dummy_event_files.each do |f|
|
176
|
+
File.open(wf.dir + f, 'w') { |fh| fh.puts('dummy_data') }
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def empty_test_state_dir
|
181
|
+
dummy_event_files.each do |f|
|
182
|
+
file = wf.dir + f
|
183
|
+
FileUtils.rm(file) if file.exist?
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|