Skip to content

Commit 1d45d5b

Browse files
committed
[config] Make "functions" setting in configuration file optional
1 parent 0a504f9 commit 1d45d5b

File tree

8 files changed

+199
-11
lines changed

8 files changed

+199
-11
lines changed

CHANGES.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ in progress
77
===========
88

99
- [prowl] Update service plugin to use "pyprowl" instead of "prowlpy"
10+
- [core] Make "functions" setting in configuration file optional
1011

1112
2021-06-08 0.23.1
1213
=================

mqttwarn/configuration.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -84,20 +84,23 @@ def __init__(self, configuration_file, defaults=None):
8484

8585
self.loglevelnumber = self.level2number(self.loglevel)
8686

87-
# Load function file as given (backward-compatibility).
88-
if os.path.isfile(self.functions):
89-
functions_file = self.functions
87+
if self.functions is not None and self.functions.strip() != "":
9088

91-
# Load function file as given if path is absolute.
92-
elif os.path.isabs(self.functions):
93-
functions_file = self.functions
89+
logger.info("Loading user-defined functions from %s" % self.functions)
9490

95-
# Load function file relative to path of configuration file if path is relative.
96-
else:
97-
functions_file = os.path.join(self.configuration_path, self.functions)
91+
# Load function file as given (backward-compatibility).
92+
if os.path.isfile(self.functions):
93+
functions_file = self.functions
9894

99-
self.functions = load_functions(functions_file)
95+
# Load function file as given if path is absolute.
96+
elif os.path.isabs(self.functions):
97+
functions_file = self.functions
10098

99+
# Load function file relative to path of configuration file if path is relative.
100+
else:
101+
functions_file = os.path.join(self.configuration_path, self.functions)
102+
103+
self.functions = load_functions(functions_file)
101104

102105
def level2number(self, level):
103106

mqttwarn/util.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ def import_module(name, path=None):
206206

207207

208208
def load_functions(filepath=None):
209+
209210
if not filepath:
210211
return None
211212

tests/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,8 @@
44
# Configuration- and function files used by the test harness
55
configfile = 'tests/selftest.ini'
66
configfile_v2 = 'tests/selftest_v2.ini'
7+
configfile_no_functions = 'tests/etc/no-functions.ini'
8+
configfile_empty_functions = 'tests/etc/empty-functions.ini'
9+
configfile_bad_functions = 'tests/etc/bad-functions.ini'
710
funcfile = 'tests/selftest.py'
811
bad_funcfile = 'tests/bad_funcs.py'

tests/etc/bad-functions.ini

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# -*- coding: utf-8 -*-
2+
# (c) 2014-2021 The mqttwarn developers
3+
#
4+
# mqttwarn configuration file for testing with invalid user defined functions.
5+
#
6+
7+
; ------------------------------------------
8+
; Base configuration
9+
; ------------------------------------------
10+
11+
[defaults]
12+
13+
14+
; --------
15+
; Services
16+
; --------
17+
18+
; This is an *invalid* `functions` setting.
19+
functions = 'UNKNOWN FILE REFERENCE'
20+
21+
; name the service providers you will be using.
22+
launch = log
23+
24+
25+
[config:log]
26+
targets = {
27+
'debug' : [ 'debug' ],
28+
'info' : [ 'info' ],
29+
'warn' : [ 'warn' ],
30+
'crit' : [ 'crit' ],
31+
'error' : [ 'error' ]
32+
}
33+
34+
35+
36+
; -------
37+
; Targets
38+
; -------
39+
40+
[test/log-1]
41+
; echo '{"name": "temperature", "value": 42.42}' | mosquitto_pub -h localhost -t test/log-1 -l
42+
targets = log:info
43+
format = {name}: {value}

tests/etc/empty-functions.ini

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# -*- coding: utf-8 -*-
2+
# (c) 2014-2021 The mqttwarn developers
3+
#
4+
# mqttwarn configuration file for testing with empty user defined functions.
5+
#
6+
7+
; ------------------------------------------
8+
; Base configuration
9+
; ------------------------------------------
10+
11+
[defaults]
12+
13+
14+
; --------
15+
; Services
16+
; --------
17+
18+
; This is an *empty* `functions` setting.
19+
functions =
20+
21+
; name the service providers you will be using.
22+
launch = log
23+
24+
25+
[config:log]
26+
targets = {
27+
'debug' : [ 'debug' ],
28+
'info' : [ 'info' ],
29+
'warn' : [ 'warn' ],
30+
'crit' : [ 'crit' ],
31+
'error' : [ 'error' ]
32+
}
33+
34+
35+
36+
; -------
37+
; Targets
38+
; -------
39+
40+
[test/log-1]
41+
; echo '{"name": "temperature", "value": 42.42}' | mosquitto_pub -h localhost -t test/log-1 -l
42+
targets = log:info
43+
format = {name}: {value}

tests/etc/no-functions.ini

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# -*- coding: utf-8 -*-
2+
# (c) 2014-2021 The mqttwarn developers
3+
#
4+
# mqttwarn configuration file for testing without user defined functions.
5+
#
6+
7+
; ------------------------------------------
8+
; Base configuration
9+
; ------------------------------------------
10+
11+
[defaults]
12+
13+
14+
; --------
15+
; Services
16+
; --------
17+
18+
; This is *without* a `functions` setting.
19+
;functions = 'DO NOT SET'
20+
21+
; name the service providers you will be using.
22+
launch = log
23+
24+
25+
[config:log]
26+
targets = {
27+
'debug' : [ 'debug' ],
28+
'info' : [ 'info' ],
29+
'warn' : [ 'warn' ],
30+
'crit' : [ 'crit' ],
31+
'error' : [ 'error' ]
32+
}
33+
34+
35+
36+
; -------
37+
; Targets
38+
; -------
39+
40+
[test/log-1]
41+
; echo '{"name": "temperature", "value": 42.42}' | mosquitto_pub -h localhost -t test/log-1 -l
42+
targets = log:info
43+
format = {name}: {value}

tests/test_core.py

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
import pytest
1212

1313
from mqttwarn.core import make_service, decode_payload
14-
from tests import configfile, configfile_v2
14+
from tests import configfile, configfile_v2, configfile_no_functions, configfile_bad_functions, \
15+
configfile_empty_functions
1516
from tests.util import core_bootstrap, send_message
1617

1718

@@ -227,3 +228,53 @@ def test_xform_func(caplog):
227228
# Proof that the message has been routed to the "log" plugin properly
228229
assert "'value': 42.42" in caplog.text, caplog.text
229230
assert "'datamap-key': 'datamap-value'" in caplog.text, caplog.text
231+
232+
233+
def test_config_no_functions(caplog):
234+
"""
235+
Test a configuration file which has no `functions` setting.
236+
"""
237+
238+
with caplog.at_level(logging.DEBUG):
239+
240+
# Bootstrap the core machinery without MQTT
241+
core_bootstrap(configfile=configfile_no_functions)
242+
243+
# Signal mocked MQTT message to the core machinery for processing
244+
send_message(topic='test/log-1', payload='{"name": "temperature", "value": 42.42}')
245+
246+
# Proof that the message has been routed to the "log" plugin properly
247+
assert "temperature: 42.42" in caplog.text, caplog.text
248+
249+
250+
def test_config_empty_functions(caplog):
251+
"""
252+
Test a configuration file which has an empty `functions` setting.
253+
"""
254+
255+
with caplog.at_level(logging.DEBUG):
256+
257+
# Bootstrap the core machinery without MQTT
258+
core_bootstrap(configfile=configfile_empty_functions)
259+
260+
# Signal mocked MQTT message to the core machinery for processing
261+
send_message(topic='test/log-1', payload='{"name": "temperature", "value": 42.42}')
262+
263+
# Proof that the message has been routed to the "log" plugin properly
264+
assert "temperature: 42.42" in caplog.text, caplog.text
265+
266+
267+
def test_config_bad_functions(caplog):
268+
"""
269+
Test a configuration file which has no `functions` setting.
270+
"""
271+
272+
with caplog.at_level(logging.DEBUG):
273+
274+
# Bootstrapping the machinery with invalid path to functions file should croak.
275+
with pytest.raises(OSError) as excinfo:
276+
core_bootstrap(configfile=configfile_bad_functions)
277+
278+
error_message = str(excinfo.value)
279+
assert "UNKNOWN FILE REFERENCE" in error_message
280+
assert "not found" in error_message

0 commit comments

Comments
 (0)