Skip to content

Commit ba37215

Browse files
committed
Improve unit for fired alerts.
1 parent 9ffe067 commit ba37215

File tree

3 files changed

+115
-7
lines changed

3 files changed

+115
-7
lines changed

splunklib/client.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,7 @@ def update(self, search=None, **kwargs):
695695
# provided by the caller.
696696
if search is None: search = self.content.search
697697
Entity.update(self, search=search, **kwargs)
698+
return self
698699

699700
class SavedSearches(Collection):
700701
def __init__(self, service):

tests/test_examples.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ def check_commands(self, *args):
7373
def setUp(self):
7474
# Ignore result, it might already exist
7575
run("index.py create sdk-tests")
76-
run("index.py create sdk-tests-two")
7776

7877
def test_async(self):
7978
result = run("async/async.py sync")
@@ -152,10 +151,10 @@ def test_index(self):
152151
"index.py --help",
153152
"index.py",
154153
"index.py list",
155-
"index.py list sdk-tests-two",
156-
"index.py disable sdk-tests-two",
157-
"index.py enable sdk-tests-two",
158-
"index.py clean sdk-tests-two")
154+
"index.py list sdk-tests",
155+
"index.py disable sdk-tests",
156+
"index.py enable sdk-tests",
157+
"index.py clean sdk-tests")
159158

160159
def test_info(self):
161160
self.check_commands(

tests/test_fired_alert.py

Lines changed: 110 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,124 @@
1515
# under the License.
1616

1717
import sys
18+
from time import sleep
1819
import unittest
1920

2021
import splunklib.client as client
2122
from utils import parse
2223

2324
opts = None # Command line options
2425

26+
def event_count(index):
27+
return int(index.content.totalEventCount)
28+
29+
def alert_count(search):
30+
return int(search.content.get('triggered_alert_count', 0))
31+
32+
# UNDONE: move the following (duplicated) routine into utility module
33+
def wait(entity, predicate, timeout=60):
34+
secs = 0
35+
while not predicate(entity):
36+
if secs > timeout:
37+
raise Exception, "Operation timed out."
38+
sleep(1)
39+
secs += 1
40+
entity.refresh()
41+
return entity
42+
2543
class TestCase(unittest.TestCase):
26-
def test(self):
27-
fired_alerts = client.connect(**opts.kwargs).fired_alerts
44+
def test_crud(self):
45+
service = client.connect(**opts.kwargs)
46+
47+
searches = service.saved_searches
48+
fired_alerts = service.fired_alerts
49+
50+
# Clean out the test index
51+
index = service.indexes['sdk-tests']
52+
index.clean()
53+
index.refresh()
54+
self.assertEqual(event_count(index), 0)
55+
56+
# Delete any leftover test search
57+
search_name = "sdk-test-search"
58+
if search_name in searches: searches.delete(search_name)
59+
self.assertFalse(search_name in searches)
60+
61+
# Create a saved search that will register an alert for any event
62+
# submitted to the `sdk-tests` index. Note that the search is not
63+
# yet scheduled - we wil schedule after doing a little more cleanup.
64+
query = "index=sdk-tests"
65+
kwargs = {
66+
'actions': "rss",
67+
'alert_type': "always",
68+
'alert_comparator': "greater than",
69+
'alert_threshold': "0",
70+
'alert.severity': "5",
71+
'alert.suppress': "0",
72+
'alert.track': "1",
73+
'dispatch.earliest_time': "rt",
74+
'dispatch.latest_time': "rt",
75+
'is_scheduled': "0",
76+
'realtime_schedule': "1",
77+
'cron_schedule': "* * * * *"
78+
}
79+
search = searches.create(search_name, query, **kwargs)
80+
self.assertEqual(search.name, search_name)
81+
self.assertEqual(search.content.is_scheduled, "0")
82+
83+
# Clear out any search history that may have matched due to reuse of
84+
# the saved search name.
85+
for job in search.history(): job.cancel()
86+
wait(search, lambda search: len(search.history()) == 0)
87+
self.assertEqual(len(search.history()), 0)
88+
89+
# Now schedule the saved search
90+
search.update(is_scheduled=1)
91+
search.refresh()
92+
self.assertEqual(search.content.is_scheduled, "1")
93+
self.assertEqual(alert_count(search), 0)
94+
95+
# Wait for the saved search to run. When it runs we will see a new job
96+
# show up in the search's history.
97+
wait(search, lambda search: len(search.history()) == 1)
98+
self.assertEqual(len(search.history()), 1)
99+
100+
# When it first runs the alert count should be zero.
101+
search.refresh()
102+
self.assertEqual(alert_count(search), 0)
103+
104+
# And the fired alerts category should not exist
105+
self.assertFalse(search_name in fired_alerts)
106+
107+
# Submit events and verify that they each trigger the expected alert
108+
for count in xrange(1, 6):
109+
# Submit an event that the search is expected to match, and wait
110+
# for the indexer to process.
111+
self.assertTrue(event_count(index) <= count)
112+
index.submit("Hello #%d!!!" % count)
113+
wait(index, lambda index: event_count(index) == count)
114+
115+
# Wait for the saved search to register the triggered alert
116+
self.assertTrue(alert_count(search) <= count)
117+
wait(search, lambda search: alert_count(search) == count)
118+
self.assertEqual(alert_count(search), count)
119+
120+
# And now .. after all that trouble, verify that we see the
121+
# expected alerts!
122+
self.assertTrue(search_name in fired_alerts)
123+
alerts = fired_alerts[search_name]
124+
self.assertEqual(alerts.name, search_name)
125+
actual = int(alerts.content.triggered_alert_count)
126+
self.assertEqual(actual, count)
127+
128+
# Cleanup
129+
searches.delete(search_name)
130+
self.assertFalse(search_name in searches)
131+
self.assertFalse(search_name in fired_alerts)
132+
133+
def test_read(self):
134+
service = client.connect(**opts.kwargs)
135+
fired_alerts = service.fired_alerts
28136

29137
for fired_alert in fired_alerts:
30138
fired_alert.content

0 commit comments

Comments
 (0)