Skip to content

Commit d8a23d5

Browse files
committed
Create testlib utility module and make a first pass at consoladating some utilities and a little cleanup. Also, remove feature that enabled passing Splunk args (eg: username, password, scheme, host, port, owner, app) on the command line.. could not find a reasonable way to reconcile the conflict in processing unittest and Splunk cmdline arguments, so I finally decided to punt the feature. The unit tests require that a .splunkrc file be present to provide Splunk args.
1 parent 23bc5fd commit d8a23d5

10 files changed

+293
-458
lines changed

tests/test_binding.py

Lines changed: 101 additions & 223 deletions
Large diffs are not rendered by default.

tests/test_client.py

Lines changed: 73 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -15,67 +15,36 @@
1515
# under the License.
1616

1717
from os import path
18-
import sys
1918
from time import sleep
20-
import unittest
2119

2220
import splunklib.client as client
2321
from splunklib.binding import HTTPError
2422
import splunklib.results as results
25-
from utils import parse
2623

27-
opts = None # Command line options
24+
import testlib
2825

2926
def create_app(service, name):
3027
service.apps.create(name)
31-
restart(service)
28+
testlib.restart(service)
3229

3330
def create_user(service, name, password="changeme", roles="power"):
3431
service.users.create(name, password=password, roles=roles)
3532

3633
def delete_app(service, name):
3734
if (service.apps.contains(name)):
3835
service.apps.delete(name)
39-
restart(service)
36+
testlib.restart(service)
4037

4138
def delete_user(service, name):
4239
if (service.users.contains(name)):
4340
service.users.delete(name)
4441

45-
def restart(service):
46-
"""Restart the given service and wait for it to wake back up."""
47-
service.restart()
48-
sleep(5) # Wait for service to notice restart
49-
wait_for_restart(service)
50-
51-
# When an event is submitted to an index it takes a while before the event
52-
# is registered by the index's totalEventCount.
53-
def wait_event_count(index, count, secs):
54-
"""Wait up to the given number of secs for the given index's
55-
totalEventCount to reach the given value."""
56-
done = False
57-
while not done and secs > 0:
58-
sleep(1)
59-
index.refresh()
60-
done = index['totalEventCount'] == count
61-
secs -= 1 # Approximate
62-
63-
def wait_for_restart(service):
64-
retry = 30
65-
while retry > 0:
66-
retry -= 1
67-
try:
68-
service.login() # Awake yet?
69-
return
70-
except:
71-
sleep(2)
72-
7342
# Verify that we can instantiate and connect to a service, test basic
7443
# interaction with the service and make sure we can connect and interact
7544
# with a variety of namespace configurations.
76-
class ServiceTestCase(unittest.TestCase):
45+
class ServiceTestCase(testlib.TestCase):
7746
def test(self):
78-
kwargs = opts.kwargs.copy()
47+
kwargs = self.opts.kwargs.copy()
7948

8049
# Verify connect with no namespace
8150
service = client.connect(**kwargs)
@@ -146,30 +115,9 @@ def test(self):
146115
self.assertFalse(service.apps.contains(app))
147116
self.assertFalse(service.users.contains(user))
148117

149-
class ClientTestCase(unittest.TestCase):
150-
def setUp(self):
151-
self.service = client.connect(**opts.kwargs)
152-
153-
def assertHttp(self, allowed_error_codes, fn, *args, **kwargs):
154-
# This is a special case of "assertRaises", where we want to check
155-
# that HTTP calls return the right status.
156-
try:
157-
returnVal = fn(*args, **kwargs)
158-
return returnVal
159-
except HTTPError as e:
160-
error_msg = "Unexpected error code: %d" % e.status
161-
if (isinstance(allowed_error_codes, list)):
162-
self.assertTrue(e.status in allowed_error_Codes, error_msg)
163-
else:
164-
self.assertTrue(e.status == allowed_error_codes, error_msg)
165-
except Exception as e:
166-
self.fail("HTTPError not raised, caught %s instead", str(type(e)))
167-
168-
def tearDown(self):
169-
pass
170-
118+
class ClientTestCase(testlib.TestCase):
171119
def test_apps(self):
172-
service = self.service
120+
service = client.connect(**self.opts.kwargs)
173121

174122
for app in service.apps: app.refresh()
175123

@@ -189,6 +137,8 @@ def test_apps(self):
189137
self.assertFalse(service.apps.contains('sdk-tests'))
190138

191139
def test_capabilities(self):
140+
service = client.connect(**self.opts.kwargs)
141+
192142
expected = [
193143
"admin_all_objects", "change_authentication",
194144
"change_own_password", "delete_by_keyword",
@@ -204,11 +154,12 @@ def test_capabilities(self):
204154
"rest_apps_view", "rest_properties_get", "rest_properties_set",
205155
"restart_splunkd", "rtsearch", "schedule_search", "search",
206156
"use_file_operator" ]
207-
capabilities = self.service.capabilities
157+
158+
capabilities = service.capabilities
208159
for item in expected: self.assertTrue(item in capabilities)
209160

210161
def test_confs(self):
211-
service = self.service
162+
service = client.connect(**self.opts.kwargs)
212163

213164
for conf in service.confs:
214165
for stanza in conf: stanza.refresh()
@@ -237,15 +188,17 @@ def test_confs(self):
237188
self.assertFalse(props.contains('sdk-tests'))
238189

239190
def test_info(self):
240-
info = self.service.info
191+
service = client.connect(**self.opts.kwargs)
192+
193+
info = service.info
241194
keys = [
242195
"build", "cpu_arch", "guid", "isFree", "isTrial", "licenseKeys",
243196
"licenseSignature", "licenseState", "master_guid", "mode",
244197
"os_build", "os_name", "os_version", "serverName", "version" ]
245198
for key in keys: self.assertTrue(key in info.keys())
246199

247200
def test_indexes(self):
248-
service = self.service
201+
service = client.connect(**self.opts.kwargs)
249202

250203
for index in service.indexes: index.refresh()
251204

@@ -290,35 +243,38 @@ def test_indexes(self):
290243
cn = index.attach()
291244
cn.write("Hello World!")
292245
cn.close()
293-
wait_event_count(index, '1', 30)
246+
testlib.wait(index, lambda index: index['totalEventCount'] == '1')
294247
self.assertEqual(index['totalEventCount'], '1')
295248

296249
index.submit("Hello again!!")
297-
wait_event_count(index, '2', 30)
250+
testlib.wait(index, lambda index: index['totalEventCount'] == '2')
298251
self.assertEqual(index['totalEventCount'], '2')
299252

300253
# The following test must run on machine where splunkd runs,
301254
# otherwise a failure is expected
302255
testpath = path.dirname(path.abspath(__file__))
303256
index.upload(path.join(testpath, "testfile.txt"))
304-
wait_event_count(index, '3', 30)
257+
testlib.wait(index, lambda index: index['totalEventCount'] == '3')
305258
self.assertEqual(index['totalEventCount'], '3')
306259

307260
index.clean()
308261
index.refresh()
309262
self.assertEqual(index['totalEventCount'], '0')
310263

311264
def test_indexes_metadata(self):
312-
metadata = self.service.indexes.itemmeta()
265+
service = client.connect(**self.opts.kwargs)
266+
267+
metadata = service.indexes.itemmeta()
313268
self.assertTrue(metadata.has_key('eai:acl'))
314269
self.assertTrue(metadata.has_key('eai:attributes'))
315-
for index in self.service.indexes:
270+
for index in service.indexes:
316271
metadata = index.metadata
317272
self.assertTrue(metadata.has_key('eai:acl'))
318273
self.assertTrue(metadata.has_key('eai:attributes'))
319274

320275
def test_inputs(self):
321-
inputs = self.service.inputs
276+
service = client.connect(**self.opts.kwargs)
277+
inputs = service.inputs
322278

323279
for input_ in inputs: input_.refresh()
324280

@@ -348,50 +304,35 @@ def test_inputs(self):
348304
inputs.delete('9999')
349305
self.assertFalse(inputs.contains('9999'))
350306

351-
def runjob(self, query, secs):
352-
"""Create a job to run the given search and wait up to (approximately)
353-
the given number of seconds for it to complete."""
354-
job = self.service.jobs.create(query)
355-
return self.wait_for_completion(job, secs=secs)
356-
357-
def wait_for_completion(self, job, secs = 30):
358-
done = False
359-
while not done and secs > 0:
360-
sleep(1)
361-
job.refresh()
362-
done = bool(int(job['isDone']))
363-
secs -= 1 # Approximate
364-
return job
365-
307+
# UNDONE: Shouldnt the following assert something on exit?
366308
def check_properties(self, job, properties, secs = 10):
367309
while secs > 0 and len(properties) > 0:
368-
read_props = job.refresh().content
369-
asserted = []
310+
content = job.refresh().content
370311

371312
# Try and check every property we specified. If we fail,
372313
# we'll try again later. If we succeed, delete it so we
373314
# don't check it again.
374-
for prop_name in properties.keys():
315+
for k, v in properties.items():
375316
try:
376-
expected_value = properties[prop_name]
377-
self.assertEqual(read_props[prop_name], expected_value)
317+
self.assertEqual(content[k], v)
378318

379319
# Since we succeeded, delete it
380-
del properties[prop_name]
320+
del properties[k]
381321
except:
382322
pass
383323

384324
secs -= 1
385325
sleep(1)
386326

387327
def test_jobs(self):
388-
jobs = self.service.jobs
328+
service = client.connect(**self.opts.kwargs)
389329

330+
jobs = service.jobs
390331
for job in jobs: job.refresh()
391332

392-
if not self.service.indexes.contains("sdk-tests"):
393-
self.service.indexes.create("sdk-tests")
394-
self.service.indexes['sdk-tests'].clean()
333+
if not service.indexes.contains("sdk-tests"):
334+
service.indexes.create("sdk-tests")
335+
service.indexes['sdk-tests'].clean()
395336

396337
# Make sure we can create a job
397338
job = jobs.create("search index=sdk-tests")
@@ -419,9 +360,10 @@ def test_jobs(self):
419360
self.assertFalse(jobs.contains(job.sid))
420361

421362
# Search for non-existant data
422-
job = self.runjob("search index=sdk-tests TERM_DOES_NOT_EXIST", 10)
423-
self.assertTrue(bool(int(job['isDone'])))
424-
self.assertEqual(int(job['eventCount']), 0)
363+
job = jobs.create("search index=sdk-tests TERM_DOES_NOT_EXIST")
364+
testlib.wait(job, lambda job: job['isDone'] == '1')
365+
self.assertEqual(job['isDone'], '1')
366+
self.assertEqual(job['eventCount'], '0')
425367
job.finalize()
426368

427369
# Create a new job
@@ -459,13 +401,15 @@ def test_jobs(self):
459401

460402
# Run a new job to get the results, but we also make
461403
# sure that there is at least one event in the index already
462-
index = self.service.indexes['sdk-tests']
404+
index = service.indexes['sdk-tests']
463405
old_event_count = int(index['totalEventCount'])
464406
if old_event_count == 0:
465407
index.submit("test event")
466-
wait_event_count(index, 1, 10)
408+
testlib.wait(index, lambda index: index['totalEventCount'] == '1')
467409

468-
job = self.runjob("search index=sdk-tests | head 1 | stats count", 10)
410+
job = jobs.create("search index=sdk-tests | head 1 | stats count")
411+
testlib.wait(job, lambda job: job['isDone'] == '1')
412+
self.assertEqual(job['isDone'], '1')
469413

470414
# Fetch the results
471415
reader = results.ResultsReader(job.results())
@@ -481,7 +425,7 @@ def test_jobs(self):
481425
self.assertEqual(int(result["count"]), 1)
482426

483427
def test_loggers(self):
484-
service = self.service
428+
service = client.connect(**self.opts.kwargs)
485429

486430
levels = ["INFO", "WARN", "ERROR", "DEBUG", "CRIT"]
487431
for logger in service.loggers:
@@ -500,16 +444,26 @@ def test_loggers(self):
500444
self.assertEqual(service.loggers['AuditLogger']['level'], saved)
501445

502446
def test_parse(self):
503-
response = self.service.parse("search *")
447+
service = client.connect(**self.opts.kwargs)
448+
449+
response = service.parse("search *")
504450
self.assertEqual(response.status, 200)
505451

506-
response = self.service.parse("search index=twitter status_count=* | stats count(status_source) as count by status_source | sort -count | head 20")
452+
response = service.parse("search index=twitter status_count=* | stats count(status_source) as count by status_source | sort -count | head 20")
507453
self.assertEqual(response.status, 200)
508454

509-
self.assertHttp(400, self.service.parse, "xyzzy")
455+
try:
456+
service.parse("xyzzy")
457+
self.fail()
458+
except HTTPError, e:
459+
self.assertEqual(e.status, 400)
460+
except:
461+
self.fail()
510462

511463
def test_messages(self):
512-
messages = self.service.messages
464+
service = client.connect(**self.opts.kwargs)
465+
466+
messages = service.messages
513467

514468
if messages.contains('sdk-test-message1'):
515469
messages.delete('sdk-test-message1')
@@ -545,16 +499,19 @@ def test_messages(self):
545499
with self.assertRaises(ValueError):
546500
messages.create(None, value="What?")
547501
messages.create(42, value="Who, me?")
548-
messages.create([1,2,3], value="Who, me?")
502+
messages.create([1, 2, 3], value="Who, me?")
549503

550504
def test_restart(self):
551-
restart(self.service)
552-
self.service.login() # Make sure we are awake
505+
service = client.connect(**self.opts.kwargs)
506+
testlib.restart(service)
507+
service.login() # Make sure we are awake
553508

554509
def test_roles(self):
555-
roles = self.service.roles
510+
service = client.connect(**self.opts.kwargs)
511+
512+
roles = service.roles
556513

557-
capabilities = self.service.capabilities
514+
capabilities = service.capabilities
558515
for role in roles:
559516
for capability in role.content.capabilities:
560517
self.assertTrue(capability in capabilities)
@@ -571,7 +528,8 @@ def test_roles(self):
571528
self.assertFalse(roles.contains("sdk-tester"))
572529

573530
def test_settings(self):
574-
settings = self.service.settings
531+
service = client.connect(**self.opts.kwargs)
532+
settings = service.settings
575533

576534
# Verify that settings contains the keys we expect
577535
keys = [
@@ -596,8 +554,9 @@ def test_settings(self):
596554
self.assertEqual(updated, original)
597555

598556
def test_users(self):
599-
users = self.service.users
600-
roles = self.service.roles
557+
service = client.connect(**self.opts.kwargs)
558+
users = service.users
559+
roles = service.roles
601560

602561
# Verify that we can read the users collection
603562
for user in users:
@@ -642,13 +601,5 @@ def test_users(self):
642601
self.assertFalse(users.contains("SDK-User"))
643602
self.assertFalse(users.contains("sdk-user"))
644603

645-
# Runs the given named test, useful for debugging.
646-
def runone(test):
647-
suite = unittest.TestSuite()
648-
suite.addTest(test)
649-
unittest.TextTestRunner().run(suite)
650-
651604
if __name__ == "__main__":
652-
opts = parse(sys.argv[1:], {}, ".splunkrc")
653-
#runone(ClientTestCase("test_users"))
654-
unittest.main(argv=sys.argv[:1])
605+
testlib.main()

0 commit comments

Comments
 (0)