splunk-sdk-ruby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. data/CHANGELOG.md +160 -0
  2. data/Gemfile +8 -0
  3. data/LICENSE +177 -0
  4. data/README.md +310 -0
  5. data/Rakefile +40 -0
  6. data/examples/1_connect.rb +51 -0
  7. data/examples/2_manage.rb +103 -0
  8. data/examples/3_blocking_searches.rb +82 -0
  9. data/examples/4_asynchronous_searches.rb +79 -0
  10. data/examples/5_stream_data_to_splunk.rb +79 -0
  11. data/lib/splunk-sdk-ruby.rb +47 -0
  12. data/lib/splunk-sdk-ruby/ambiguous_entity_reference.rb +28 -0
  13. data/lib/splunk-sdk-ruby/atomfeed.rb +323 -0
  14. data/lib/splunk-sdk-ruby/collection.rb +417 -0
  15. data/lib/splunk-sdk-ruby/collection/apps.rb +35 -0
  16. data/lib/splunk-sdk-ruby/collection/case_insensitive_collection.rb +58 -0
  17. data/lib/splunk-sdk-ruby/collection/configuration_file.rb +50 -0
  18. data/lib/splunk-sdk-ruby/collection/configurations.rb +80 -0
  19. data/lib/splunk-sdk-ruby/collection/jobs.rb +136 -0
  20. data/lib/splunk-sdk-ruby/collection/messages.rb +51 -0
  21. data/lib/splunk-sdk-ruby/context.rb +522 -0
  22. data/lib/splunk-sdk-ruby/entity.rb +260 -0
  23. data/lib/splunk-sdk-ruby/entity/index.rb +191 -0
  24. data/lib/splunk-sdk-ruby/entity/job.rb +339 -0
  25. data/lib/splunk-sdk-ruby/entity/message.rb +36 -0
  26. data/lib/splunk-sdk-ruby/entity/saved_search.rb +71 -0
  27. data/lib/splunk-sdk-ruby/entity/stanza.rb +45 -0
  28. data/lib/splunk-sdk-ruby/entity_not_ready.rb +26 -0
  29. data/lib/splunk-sdk-ruby/illegal_operation.rb +27 -0
  30. data/lib/splunk-sdk-ruby/namespace.rb +239 -0
  31. data/lib/splunk-sdk-ruby/resultsreader.rb +716 -0
  32. data/lib/splunk-sdk-ruby/service.rb +339 -0
  33. data/lib/splunk-sdk-ruby/splunk_http_error.rb +49 -0
  34. data/lib/splunk-sdk-ruby/synonyms.rb +50 -0
  35. data/lib/splunk-sdk-ruby/version.rb +27 -0
  36. data/lib/splunk-sdk-ruby/xml_shim.rb +117 -0
  37. data/splunk-sdk-ruby.gemspec +27 -0
  38. data/test/atom_test_data.rb +472 -0
  39. data/test/data/atom/atom_feed_with_message.xml +19 -0
  40. data/test/data/atom/atom_with_feed.xml +99 -0
  41. data/test/data/atom/atom_with_several_entries.xml +101 -0
  42. data/test/data/atom/atom_with_simple_entries.xml +30 -0
  43. data/test/data/atom/atom_without_feed.xml +248 -0
  44. data/test/data/export/4.2.5/export_results.xml +88 -0
  45. data/test/data/export/4.3.5/export_results.xml +87 -0
  46. data/test/data/export/5.0.1/export_results.xml +78 -0
  47. data/test/data/export/5.0.1/nonreporting.xml +232 -0
  48. data/test/data/results/4.2.5/results-empty.xml +0 -0
  49. data/test/data/results/4.2.5/results-preview.xml +255 -0
  50. data/test/data/results/4.2.5/results.xml +336 -0
  51. data/test/data/results/4.3.5/results-empty.xml +0 -0
  52. data/test/data/results/4.3.5/results-preview.xml +1057 -0
  53. data/test/data/results/4.3.5/results.xml +626 -0
  54. data/test/data/results/5.0.2/results-empty.xml +1 -0
  55. data/test/data/results/5.0.2/results-empty_preview.xml +1 -0
  56. data/test/data/results/5.0.2/results-preview.xml +448 -0
  57. data/test/data/results/5.0.2/results.xml +501 -0
  58. data/test/export_test_data.json +360 -0
  59. data/test/resultsreader_test_data.json +1119 -0
  60. data/test/services.server.info.xml +43 -0
  61. data/test/services.xml +111 -0
  62. data/test/test_atomfeed.rb +71 -0
  63. data/test/test_collection.rb +278 -0
  64. data/test/test_configuration_file.rb +124 -0
  65. data/test/test_context.rb +119 -0
  66. data/test/test_entity.rb +95 -0
  67. data/test/test_helper.rb +250 -0
  68. data/test/test_http_error.rb +52 -0
  69. data/test/test_index.rb +91 -0
  70. data/test/test_jobs.rb +319 -0
  71. data/test/test_messages.rb +17 -0
  72. data/test/test_namespace.rb +188 -0
  73. data/test/test_restarts.rb +49 -0
  74. data/test/test_resultsreader.rb +106 -0
  75. data/test/test_roles.rb +41 -0
  76. data/test/test_saved_searches.rb +119 -0
  77. data/test/test_service.rb +65 -0
  78. data/test/test_users.rb +33 -0
  79. data/test/test_xml_shim.rb +28 -0
  80. data/test/testfile.txt +1 -0
  81. metadata +200 -0
@@ -0,0 +1,52 @@
1
+ require_relative 'test_helper'
2
+
3
+ require 'splunk-sdk-ruby'
4
+
5
+ class MockResponse
6
+ include Enumerable
7
+
8
+ attr_reader :code, :message, :body
9
+
10
+ def initialize(code, message, headers, body)
11
+ @code = code
12
+ @message = message
13
+ @headers = headers
14
+ @body = body
15
+ end
16
+
17
+ def each(&block)
18
+ @headers.each(&block)
19
+ end
20
+ end
21
+
22
+ include Splunk
23
+
24
+ class TestHTTPError < TestCaseWithSplunkConnection
25
+ def test_error_with_empty_message
26
+ response = MockResponse.new(code=400, message="Meep",
27
+ headers={}, body="")
28
+ err = SplunkHTTPError.new(response)
29
+ assert_nil(err.detail)
30
+ assert_equal(response.code, err.code)
31
+ assert_equal(response.message, err.reason)
32
+ assert_equal("HTTP 400 Meep: ", err.message)
33
+ end
34
+
35
+ def test_error_with_message
36
+ response = MockResponse.new(
37
+ code=400, message="Index Error", headers={},
38
+ body = "<response><messages>" +
39
+ "<msg type=\"ERROR\">In handler &apos;indexes&apos;: " +
40
+ "Index name=boris already exists</msg></messages></response>")
41
+ err = SplunkHTTPError.new(response)
42
+ assert_equal("In handler 'indexes': Index name=boris already exists",
43
+ err.detail)
44
+ assert_equal(400, err.code)
45
+ assert_equal("Index Error", err.reason)
46
+ assert_equal([], err.headers)
47
+ assert_equal("HTTP 400 Index Error: In handler 'indexes': " +
48
+ "Index name=boris already exists",
49
+ err.message)
50
+ end
51
+
52
+ end
@@ -0,0 +1,91 @@
1
+ require_relative 'test_helper'
2
+ require 'splunk-sdk-ruby'
3
+
4
+ include Splunk
5
+
6
+ class IndexTestCase < TestCaseWithSplunkConnection
7
+ def setup
8
+ super
9
+
10
+ @index_name = temporary_name()
11
+ @index = @service.indexes.create(@index_name)
12
+ assert_eventually_true() do
13
+ @index.refresh()["disabled"] == "0"
14
+ end
15
+ end
16
+
17
+ def teardown
18
+ if @service.splunk_version[0] >= 5
19
+ @service.indexes.
20
+ select() { |index| index.name.start_with?("delete-me")}.
21
+ each() do |index|
22
+ if index.fetch("disabled") == "1"
23
+ index.enable()
24
+ end
25
+ index.delete()
26
+ end
27
+ end
28
+
29
+ super
30
+ end
31
+
32
+ def test_delete
33
+ if @service.splunk_version[0] < 5
34
+ return
35
+ end
36
+ assert_true(@service.indexes.has_key?(@index_name))
37
+ @service.indexes.delete(@index_name)
38
+ assert_eventually_true() do
39
+ !@service.indexes.has_key?(@index_name)
40
+ end
41
+ end
42
+
43
+ def test_disable_enable
44
+ @index.disable()
45
+ checked_restart(@service)
46
+ @index.refresh()
47
+ assert_equal('1', @index["disabled"])
48
+
49
+ @index.enable()
50
+ @index.refresh()
51
+ assert_equal("0", @index["disabled"])
52
+ end
53
+
54
+ def test_submit_via_attach
55
+ event_count = Integer(@index["totalEventCount"])
56
+ socket = @index.attach()
57
+ socket.write("Hello, Boris!\r\n")
58
+ socket.close()
59
+ assert_eventually_true(10) do
60
+ Integer(@index.refresh()["totalEventCount"]) == event_count+1
61
+ end
62
+ end
63
+
64
+ def test_submit_and_clean
65
+ original_count = Integer(@index.refresh()["totalEventCount"])
66
+ @index.submit("Boris 1", :sourcetype => "Boris", :host => "Meep")
67
+ @index.submit("Boris 2", :sourcetype => "Boris", :host => "Meep")
68
+ assert_eventually_true(100) do
69
+ Integer(@index.refresh()["totalEventCount"]) == original_count + 2
70
+ end
71
+
72
+ @index.clean(timeout=500)
73
+ assert_equal(0, Integer(@index.refresh()["totalEventCount"]))
74
+ end
75
+
76
+ def test_upload
77
+ if !has_app_collection?(@service)
78
+ print "Test requires sdk-app-collection. Skipping."
79
+ return
80
+ end
81
+
82
+ install_app_from_collection("file_to_upload")
83
+
84
+ original_count = Integer(@index.refresh().fetch("totalEventCount"))
85
+ @index.upload(path_in_app("file_to_upload", ["log.txt"]))
86
+
87
+ assert_eventually_true() do
88
+ Integer(@index.refresh()["totalEventCount"]) == original_count + 4
89
+ end
90
+ end
91
+ end
data/test/test_jobs.rb ADDED
@@ -0,0 +1,319 @@
1
+ require_relative 'test_helper'
2
+ require 'splunk-sdk-ruby'
3
+
4
+ include Splunk
5
+
6
+ QUERY = "search index=_internal | head 3"
7
+ JOB_ARGS = {:earliest_time => "-1m", :latest_time => "now",
8
+ :status_buckets => 10}
9
+
10
+ class JobsTestCase < TestCaseWithSplunkConnection
11
+ def test_create_with_garbage_fails
12
+ assert_raises(SplunkHTTPError) do
13
+ @service.jobs.create("aweaj;awfaw faf'adf")
14
+ end
15
+ end
16
+
17
+ def test_create_and_idempotent_cancel
18
+ jobs = @service.jobs
19
+ job = jobs.create(QUERY)
20
+ assert_true(jobs.has_key?(job.sid))
21
+ job.cancel()
22
+ assert_eventually_true() { !jobs.has_key?(job.sid) }
23
+ job.cancel() # Cancel twice should be a nop
24
+ end
25
+
26
+ ##
27
+ # There is a convenience method on service to create an asynchronous
28
+ # search job. Test it the same way.
29
+ #
30
+ def service_create_and_idempotent_cancel
31
+ jobs = @service.jobs
32
+ job = @service.create(QUERY)
33
+ assert_true(jobs.has_key?(job.sid))
34
+ job.cancel()
35
+ assert_eventually_true() { !jobs.has_key?(job.sid) }
36
+ job.cancel() # Cancel twice should be a nop
37
+ end
38
+
39
+ def test_create_with_exec_mode_fails
40
+ assert_raises(ArgumentError) do
41
+ @service.jobs.create(QUERY, :exec_mode => "oneshot")
42
+ end
43
+ end
44
+
45
+ def test_oneshot
46
+ jobs = @service.jobs
47
+ stream = jobs.create_oneshot(QUERY)
48
+ results = ResultsReader.new(stream)
49
+ assert_false(results.is_preview?)
50
+ events = results.to_a()
51
+ assert_equal(3, events.length())
52
+ end
53
+
54
+ ##
55
+ # Test that Service#create_oneshot properly creates a oneshot search.
56
+ #
57
+ def test_oneshot_on_service
58
+ jobs = @service.jobs
59
+ stream = @service.create_oneshot(QUERY)
60
+ results = ResultsReader.new(stream)
61
+ assert_false(results.is_preview?)
62
+ events = results.to_a()
63
+ assert_equal(3, events.length())
64
+ end
65
+
66
+ def test_oneshot_with_garbage_fails
67
+ assert_raises(SplunkHTTPError) do
68
+ @service.jobs.create_oneshot("abcwrawerafawf 'adfad'faw")
69
+ end
70
+ end
71
+
72
+ def test_export_with_garbage_fails
73
+ assert_raises(SplunkHTTPError) do
74
+ @service.jobs.create_export("abavadfa;ejwfawfasdfadf wfw").to_a()
75
+ end
76
+ end
77
+
78
+ def test_export
79
+ stream = @service.jobs.create_export(QUERY)
80
+ assert_true(stream.is_a?(ExportStream))
81
+ results = ResultsReader.new(stream).to_a()
82
+ assert_equal(3, results.length())
83
+ end
84
+
85
+ ##
86
+ # Test that the convenience method Service#create_export behaves the same
87
+ # way as Jobs#create_export.
88
+ #
89
+ def test_export_on_service
90
+ stream = @service.create_export(QUERY)
91
+ results = ResultsReader.new(stream).to_a()
92
+ assert_equal(3, results.length())
93
+ end
94
+
95
+ ##
96
+ # Test that ResultsReader parses reporting export searches correctly
97
+ # (by only returning the final, nonpreview results).
98
+ #
99
+ def test_export_on_reporting_search
100
+ stream = @service.create_export("search index=_internal earliest=-2d | stats count(_raw) by method")
101
+ results = ResultsReader.new(stream).to_a()
102
+ assert_true(3 >= results.length())
103
+ end
104
+
105
+ def test_each_and_values
106
+ jobs = Jobs.new(@service)
107
+
108
+ created_jobs = []
109
+
110
+ (1..3).each() do |i|
111
+ job = jobs.create("search index=_internal | head #{i}")
112
+ while !job.is_ready?
113
+ sleep(0.1)
114
+ end
115
+ created_jobs << job
116
+ end
117
+
118
+ each_jobs = []
119
+ jobs.each() do |job|
120
+ assert_false(job.name.empty?)
121
+ each_jobs << job.sid
122
+ end
123
+
124
+ values_jobs = jobs.values().map() { |j| j.sid }
125
+ assert_equal(each_jobs, values_jobs)
126
+
127
+ created_jobs.each do |job|
128
+ job.cancel()
129
+ end
130
+ end
131
+
132
+ def test_preview_and_events
133
+ job = @service.jobs.create(QUERY, JOB_ARGS)
134
+ assert_eventually_true() { job.is_done?() }
135
+ assert_true(Integer(job['eventCount']) <= 3)
136
+
137
+ preview_stream = job.preview()
138
+ preview_results = ResultsReader.new(preview_stream)
139
+ assert_false(preview_results.is_preview?)
140
+ preview_array = preview_results.to_a()
141
+
142
+ events_stream = job.events()
143
+ events_results = ResultsReader.new(events_stream)
144
+ assert_false(events_results.is_preview?)
145
+ events_array = events_results.to_a()
146
+
147
+ results_stream = job.results()
148
+ results_results = ResultsReader.new(results_stream)
149
+ assert_false(results_results.is_preview?)
150
+ results_array = results_results.to_a()
151
+
152
+ assert_equal(events_array, preview_array)
153
+ assert_equal(results_array, preview_array)
154
+
155
+ job.cancel()
156
+ end
157
+
158
+ def test_timeline
159
+ original_xml_library = $splunk_xml_library
160
+ job = @service.jobs.create(QUERY, JOB_ARGS)
161
+ assert_eventually_true() { job.is_done?() }
162
+
163
+ begin
164
+ Splunk::require_xml_library(:rexml)
165
+ timeline = job.timeline()
166
+ assert_true(timeline.is_a?(Array))
167
+
168
+ Splunk::require_xml_library(:nokogiri)
169
+ timeline = job.timeline()
170
+ assert_true(timeline.is_a?(Array))
171
+ ensure
172
+ # Have to reset the XML library or test_resultsreader gets unhappy.
173
+ Splunk::require_xml_library(original_xml_library)
174
+ job.cancel()
175
+ end
176
+ end
177
+
178
+ def test_enable_preview
179
+ begin
180
+ install_app_from_collection("sleep_command")
181
+ job = @service.jobs.create("search index=_internal | sleep 2 | join [sleep 2]")
182
+ while !job.is_ready?()
183
+ sleep(0.1)
184
+ end
185
+ assert_equal("0", job["isPreviewEnabled"])
186
+ job.enable_preview()
187
+ assert_eventually_true(1000) do
188
+ job.refresh()
189
+ fail("Job finished before preview enabled") if job.is_done?()
190
+ job["isPreviewEnabled"] == "1"
191
+ end
192
+ ensure
193
+ job.cancel()
194
+ assert_eventually_true do
195
+ !@service.jobs.contains?(job.sid)
196
+ end
197
+ # We have to wait for jobs to be properly killed or we can't delete
198
+ # the sleep_command app in teardown on Windows.
199
+ sleep(4)
200
+ end
201
+ end
202
+ end
203
+
204
+ class LongJobTestCase < JobsTestCase
205
+ def setup
206
+ super
207
+
208
+ install_app_from_collection("sleep_command")
209
+ @job = @service.jobs.create("search index=_internal | sleep 20")
210
+ while !@job.is_ready?()
211
+ sleep(0.1)
212
+ end
213
+ end
214
+
215
+ def teardown
216
+ if @job
217
+ @job.cancel()
218
+ assert_eventually_true(50) do
219
+ !@service.jobs.has_key?(@job.sid)
220
+ end
221
+ end
222
+
223
+ super
224
+ end
225
+
226
+ def test_setttl
227
+ old_ttl = Integer(@job["ttl"])
228
+ new_ttl = old_ttl + 1000
229
+
230
+ @job.set_ttl(new_ttl)
231
+ assert_eventually_true() do
232
+ @job.refresh()
233
+ ttl = Integer(@job["ttl"])
234
+ ttl <= new_ttl && ttl > old_ttl
235
+ end
236
+ end
237
+
238
+ def test_touch
239
+ i = 2
240
+ while i < 20
241
+ sleep(i)
242
+ old_ttl = Integer(@job.refresh()["ttl"])
243
+ @job.touch()
244
+ new_ttl = Integer(@job.refresh()["ttl"])
245
+ if new_ttl > old_ttl
246
+ break
247
+ else
248
+ i += 1
249
+ end
250
+ end
251
+ assert_true(new_ttl > old_ttl)
252
+ end
253
+ end
254
+
255
+ class RealTimeJobTestCase < JobsTestCase
256
+ def setup
257
+ super
258
+ query = "search index=_internal"
259
+ @job = @service.jobs.create(query,
260
+ :earliest_time => "rt-1d",
261
+ :latest_time => "rt",
262
+ :priority => 5)
263
+ while !@job.is_ready?
264
+ sleep(0.2)
265
+ end
266
+ end
267
+
268
+ def teardown
269
+ if @job
270
+ @job.cancel()
271
+ assert_eventually_true() do
272
+ !@service.jobs.has_key?(@job.sid)
273
+ end
274
+ end
275
+
276
+ super
277
+ end
278
+
279
+ def test_set_priority
280
+ assert_equal("5", @job["priority"])
281
+ sleep(1)
282
+ new_priority = 3
283
+ @job.set_priority(new_priority)
284
+ assert_eventually_true(50) do
285
+ @job.refresh()
286
+ fail("Job finished before priority was set.") if @job.is_done?()
287
+ @job["priority"] == "3"
288
+ end
289
+ end
290
+
291
+ def test_get_preview
292
+ assert_equal("1", @job["isPreviewEnabled"])
293
+ assert_eventually_true do
294
+ response = @job.preview()
295
+ results = Splunk::ResultsReader.new(response)
296
+ results.is_preview?
297
+ end
298
+ end
299
+
300
+ def test_pause_unpause_finalize
301
+ assert_equal("0", @job["isPaused"])
302
+
303
+ @job.pause()
304
+ assert_eventually_true() { @job.refresh()["isPaused"] == "1" }
305
+
306
+ @job.unpause()
307
+ assert_eventually_true() { @job.refresh()["isPaused"] == "0" }
308
+
309
+ assert_equal("0", @job["isFinalized"])
310
+
311
+ @job.finalize()
312
+ assert_eventually_true() { @job.refresh()["isFinalized"] == "1" }
313
+ end
314
+
315
+ def test_searchlog
316
+ log_stream = @job.searchlog
317
+ assert_false(log_stream.empty?)
318
+ end
319
+ end