Skip to content

Commit 7497951

Browse files
committed
Add modularinput e2e test
Currently, we only have unit tests that verify the generated XML output of modularinputs. This change adds E2E tests to confirm that our modularinput machinery works correctly with a Splunk instance.
1 parent 1aa5b20 commit 7497951

File tree

6 files changed

+156
-0
lines changed

6 files changed

+156
-0
lines changed

docker-compose.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ services:
2424
- "./tests/searchcommands/test_apps/generating_app:/opt/splunk/etc/apps/generating_app"
2525
- "./tests/searchcommands/test_apps/reporting_app:/opt/splunk/etc/apps/reporting_app"
2626
- "./tests/searchcommands/test_apps/streaming_app:/opt/splunk/etc/apps/streaming_app"
27+
- "./tests/modularinput/test_apps/modularinput:/opt/splunk/etc/apps/modularinput"
2728
- "./splunklib:/opt/splunk/etc/apps/eventing_app/lib/splunklib"
2829
- "./splunklib:/opt/splunk/etc/apps/generating_app/lib/splunklib"
2930
- "./splunklib:/opt/splunk/etc/apps/reporting_app/lib/splunklib"
3031
- "./splunklib:/opt/splunk/etc/apps/streaming_app/lib/splunklib"
32+
- "./splunklib:/opt/splunk/etc/apps/modularinput/lib/splunklib"

tests/modularinput/test_app.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/usr/bin/env python
2+
#
3+
# Copyright © 2011-2025 Splunk, Inc.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"): you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
from splunklib import results
18+
from tests import testlib
19+
from splunklib.binding import HTTPError
20+
21+
22+
class ModularInput(testlib.SDKTestCase):
23+
def setUp(self):
24+
super().setUp()
25+
self.assertIn(
26+
"modularinput", [kind.name for kind in self.service.modular_input_kinds]
27+
)
28+
if ("test", "modularinput") in [
29+
(input.name, input.kind) for input in self.service.inputs
30+
]:
31+
self.service.inputs.delete("test", "modularinput")
32+
if "test_modular_input" in [index.name for index in self.service.indexes]:
33+
self.service.indexes.delete("test_modular_input")
34+
35+
def test_modular_input(self):
36+
self.service.indexes.create("test_modular_input")
37+
38+
input = self.service.inputs.create(
39+
"test",
40+
"modularinput",
41+
endpoint="https://example.com/api/endpoint",
42+
index="test_modular_input",
43+
)
44+
45+
def query():
46+
stream = self.service.jobs.oneshot(
47+
'search index="test_modular_input"', output_mode="json"
48+
)
49+
reader = results.JSONResultsReader(stream)
50+
return list(reader)
51+
52+
# Wait until the modular input is executed by splunk.
53+
self.assertEventuallyTrue(lambda: len(query()) != 0, timeout=10)
54+
55+
items = query()
56+
self.assertTrue(len(items) == 1)
57+
self.assertIn("_raw", items[0])
58+
self.assertEqual(items[0]["_raw"], "example message")
59+
60+
input.delete()
61+
self.service.indexes.delete("test_modular_input")
62+
63+
def test_external_validator(self):
64+
def create():
65+
self.service.inputs.create(
66+
"test",
67+
"modularinput",
68+
endpoint="http://example.com/api/endpoint",
69+
index="test_modular_input",
70+
)
71+
72+
self.assertRaisesRegex(HTTPError, "non-supported scheme http", create)
73+
74+
75+
if __name__ == "__main__":
76+
import unittest
77+
78+
unittest.main()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[modularinput://<name>]
2+
3+
endpoint = <value>
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright © 2011-2025 Splunk, Inc.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"): you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
import sys
18+
import os
19+
from urllib import parse
20+
21+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib"))
22+
from splunklib.modularinput import Scheme, Argument, Script, Event
23+
24+
25+
# rename
26+
class ModularInput(Script):
27+
def get_scheme(self):
28+
scheme = Scheme("modularinput")
29+
30+
scheme.use_external_validation = True
31+
scheme.use_single_instance = True
32+
33+
endpoint = Argument("endpoint")
34+
endpoint.title = "endpoint"
35+
endpoint.data_type = Argument.data_type_string
36+
endpoint.description = "URL"
37+
endpoint.required_on_create = True
38+
scheme.add_argument(endpoint)
39+
40+
return scheme
41+
42+
def validate_input(self, definition):
43+
url = definition.parameters["endpoint"]
44+
parsed = parse.urlparse(url)
45+
if parsed.scheme != "https":
46+
raise ValueError(f"non-supported scheme {parsed.scheme}")
47+
48+
def stream_events(self, inputs, ew):
49+
for input_name, input_item in list(inputs.inputs.items()):
50+
event = Event()
51+
event.stanza = input_name
52+
event.data = "example message"
53+
ew.write_event(event)
54+
55+
56+
if __name__ == "__main__":
57+
sys.exit(ModularInput().run(sys.argv))
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[install]
2+
is_configured = 0
3+
4+
[ui]
5+
is_visible = 1
6+
label = Modular Input test app
7+
8+
[launcher]
9+
author=Splunk
10+
description=Modular input test app
11+
version = 1.0
12+
13+
[package]
14+
check_for_updates = false
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[modularinput]
2+
python.version = python3

0 commit comments

Comments
 (0)