Tests: Add feature guards

This allows test runners to set environment variables to let tests know which features are available. This is done by the cmake tests, but probably won't be extended to the make tests.
This commit is contained in:
Roger A. Light
2026-04-16 21:35:46 +01:00
committed by Roger Light
parent ada3184901
commit fe4343dac7
113 changed files with 494 additions and 201 deletions
+27 -19
View File
@@ -48,19 +48,26 @@ do_test(["-p"], 1, response="Error: -p argument given but no port specified.\n\n
do_test(["-p", "-1"], 1, response="Error: Invalid port given: -1\n")
do_test(["-p", "65536"], 1, response="Error: Invalid port given: 65536\n")
do_test(["-P"], 1, response="Error: -P argument given but no password specified.\n\n")
do_test(["--proxy"], 1, response="Error: --proxy argument given but no proxy url specified.\n\n")
do_test(["--proxy", "mqtt://localhost"], 1, response="Error: Unsupported proxy protocol: mqtt://localhost\n")
do_test(["--proxy", "socks5h://"], 1, response="Error: Invalid proxy.\n")
do_test(["--proxy", "socks5h://localhost:0"], 1, response="Error: Invalid proxy port 0\n")
do_test(["--proxy", "socks5h://localhost:65536"], 1, response="Error: Invalid proxy port 65536\n")
do_test(["--proxy", "socks5h://username%@localhost"], 1, response="Error: Invalid URL encoding in username.\n")
do_test(["--proxy", "socks5h://username%41@localhost"], 1, response="Error: Invalid URL encoding in username.\n")
do_test(["--proxy", "socks5h://username:password%@localhost"], 1, response="Error: Invalid URL encoding in password.\n")
do_test(["--proxy", "socks5h://username:password%41@localhost"], 1, response="Error: Invalid URL encoding in password.\n")
do_test(["--psk"], 1, response="Error: --psk argument given but no key specified.\n\n")
do_test(["--psk", "missing.psk"], 1, response="Error: --psk-identity required if --psk used.\n")
do_test(["--psk-identity"], 1, response="Error: --psk-identity argument given but no identity specified.\n\n")
do_test(["--cafile", ssl_dir / "all-ca.crt", "--psk", "missing.psk", "--psk-identity", "identity"], 1, response="Error: Only one of --psk or --cafile/--capath may be used at once.\n")
if mosq_test.check_features(["WITH_SOCKS"]):
do_test(["--proxy"], 1, response="Error: --proxy argument given but no proxy url specified.\n\n")
do_test(["--proxy", "mqtt://localhost"], 1, response="Error: Unsupported proxy protocol: mqtt://localhost\n")
do_test(["--proxy", "socks5h://"], 1, response="Error: Invalid proxy.\n")
do_test(["--proxy", "socks5h://localhost:0"], 1, response="Error: Invalid proxy port 0\n")
do_test(["--proxy", "socks5h://localhost:65536"], 1, response="Error: Invalid proxy port 65536\n")
do_test(["--proxy", "socks5h://username%@localhost"], 1, response="Error: Invalid URL encoding in username.\n")
do_test(["--proxy", "socks5h://username%41@localhost"], 1, response="Error: Invalid URL encoding in username.\n")
do_test(["--proxy", "socks5h://username:password%@localhost"], 1, response="Error: Invalid URL encoding in password.\n")
do_test(["--proxy", "socks5h://username:password%41@localhost"], 1, response="Error: Invalid URL encoding in password.\n")
else:
do_test(["--proxy", "socks5h://username:password%41@localhost"], 1, response="Error: Unknown option '--proxy'.\n")
if mosq_test.check_features(["WITH_TLS_PSK"]):
do_test(["--psk"], 1, response="Error: --psk argument given but no key specified.\n\n")
do_test(["--psk", "missing.psk"], 1, response="Error: --psk-identity required if --psk used.\n")
do_test(["--psk-identity"], 1, response="Error: --psk-identity argument given but no identity specified.\n\n")
do_test(["--cafile", ssl_dir / "all-ca.crt", "--psk", "missing.psk", "--psk-identity", "identity"], 1, response="Error: Only one of --psk or --cafile/--capath may be used at once.\n")
do_test(["-q"], 1, response="Error: -q argument given but no QoS specified.\n\n")
do_test(["-q", "-1"], 1, response="Error: Invalid QoS given: -1\n")
do_test(["-q", "3"], 1, response="Error: Invalid QoS given: 3\n")
@@ -126,12 +133,13 @@ do_test(["--version"], 1) # Gives generic help
# Broker
do_test(["broker", "unknown"], 13, response="Command 'unknown' not recognised.\n")
# Dynsec
do_test(["dynsec", "unknown"], 13, response="Command 'unknown' not recognised.\n")
do_test(["-f", "file", "dynsec", "setClientPassword", "admin", "admin", "-i"], 3, response="Error: -i argument given, but no iterations provided.\nError: Invalid input.\n")
do_test(["-f", "file", "dynsec", "setClientPassword", "admin", "admin", "-c"], 3, response="Error: Unknown argument: -c\nError: Invalid input.\n")
do_test(["dynsec", "createClient", "client", "-i"], 3, response="Error: -i argument given, but no clientid provided.\nError: Invalid input.\n")
do_test(["dynsec", "createClient", "client", "-p"], 3, response="Error: -p argument given, but no password provided.\nError: Invalid input.\n")
if mosq_test.check_features(["WITH_PLUGINS", "WITH_PLUGIN_DYNAMIC_SECURITY"]):
# Dynsec
do_test(["dynsec", "unknown"], 13, response="Command 'unknown' not recognised.\n")
do_test(["-f", "file", "dynsec", "setClientPassword", "admin", "admin", "-i"], 3, response="Error: -i argument given, but no iterations provided.\nError: Invalid input.\n")
do_test(["-f", "file", "dynsec", "setClientPassword", "admin", "admin", "-c"], 3, response="Error: Unknown argument: -c\nError: Invalid input.\n")
do_test(["dynsec", "createClient", "client", "-i"], 3, response="Error: -i argument given, but no clientid provided.\nError: Invalid input.\n")
do_test(["dynsec", "createClient", "client", "-p"], 3, response="Error: -p argument given, but no password provided.\nError: Invalid input.\n")
# Env modification
+11 -3
View File
@@ -6,6 +6,8 @@ from mosq_test_helper import *
import json
import shutil
mosq_test.require_features(["WITH_CONTROL", "WITH_PLUGINS", "WITH_PLUGIN_DYNAMIC_SECURITY"])
def write_config(filename, ports):
with open(filename, 'w') as f:
f.write("enable_control_api true\n")
@@ -14,8 +16,9 @@ def write_config(filename, ports):
f.write("allow_anonymous false\n")
f.write(f"listener {ports[0]}\n")
f.write(f"listener {ports[1]}\n")
f.write(f"certfile {ssl_dir}/server.crt\n")
f.write(f"keyfile {ssl_dir}/server.key\n")
if mosq_test.check_features(["WITH_TLS"]):
f.write(f"certfile {ssl_dir}/server.crt\n")
f.write(f"keyfile {ssl_dir}/server.key\n")
def ctrl_cmd(cmd, args, ports, response=None):
opts = ["-u", "admin",
@@ -67,7 +70,12 @@ try:
ctrl_cmd("dynsec", ["addRoleACL", "admin", "publishClientReceive", "$CONTROL/#", "allow"], ports)
ctrl_cmd("dynsec", ["addRoleACL", "admin", "subscribePattern", "$CONTROL/#", "allow"], ports)
ctrl_cmd("broker", ["listListeners"], ports, response=f"Listener 1:\n Port: {ports[0]}\n Protocol: mqtt\n TLS: false\n\nListener 2:\n Port: {ports[1]}\n Protocol: mqtt\n TLS: true\n\n")
if mosq_test.check_features(["WITH_TLS"]):
tls = "true"
else:
tls = "false"
ctrl_cmd("broker", ["listListeners"], ports, response=f"Listener 1:\n Port: {ports[0]}\n Protocol: mqtt\n TLS: false\n\nListener 2:\n Port: {ports[1]}\n Protocol: mqtt\n TLS: {tls}\n\n")
ctrl_cmd("broker", ["listPlugins"], ports, response="Plugin: dynamic-security\nControl endpoints: $CONTROL/dynamic-security/v1\n")
+7 -3
View File
@@ -5,6 +5,8 @@ import json
import os
import shutil
mosq_test.require_features(["WITH_CONTROL", "WITH_PLUGINS", "WITH_PLUGIN_DYNAMIC_SECURITY"])
def write_config(filename, ports):
with open(filename, 'w') as f:
f.write(f"global_plugin {mosq_test.get_build_root()}/plugins/dynamic-security/mosquitto_dynamic_security.so\n")
@@ -12,8 +14,9 @@ def write_config(filename, ports):
f.write("allow_anonymous false\n")
f.write(f"listener {ports[0]}\n")
f.write(f"listener {ports[1]}\n")
f.write(f"certfile {ssl_dir}/server.crt\n")
f.write(f"keyfile {ssl_dir}/server.key\n")
if mosq_test.check_features(["WITH_TLS"]):
f.write(f"certfile {ssl_dir}/server.crt\n")
f.write(f"keyfile {ssl_dir}/server.key\n")
def ctrl_dynsec_cmd(args, ports, response=None, input=None):
opts = ["-u", "admin",
@@ -26,7 +29,8 @@ def ctrl_dynsec_cmd(args, ports, response=None, input=None):
]
else:
opts += ["-p", str(ports[1])]
opts += ["--cafile", f"{ssl_dir}/all-ca.crt"]
if mosq_test.check_features(["WITH_TLS"]):
opts += ["--cafile", f"{ssl_dir}/all-ca.crt"]
proc = subprocess.run([mosq_test.get_build_root()+"/apps/mosquitto_ctrl/mosquitto_ctrl"]
+ opts + ["dynsec"] + args,
+2 -1
View File
@@ -5,6 +5,8 @@
from mosq_test_helper import *
import shutil
mosq_test.require_features(["WITH_CLIENTS", "WITH_PERSISTENCE"])
def write_config(conf_file, port):
with open(conf_file, 'w') as f:
f.write(f"listener {port}\n")
@@ -85,7 +87,6 @@ def do_test(counts):
print(e)
finally:
os.remove(conf_file)
os.remove(f"{port}/mosquitto.db")
shutil.rmtree(str(port))
if broker is not None:
broker.terminate()
+2
View File
@@ -4,6 +4,8 @@
from mosq_test_helper import *
mosq_test.require_features(["WITH_UNIX_SOCKETS"])
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener 0 %d.sock\n" % (port))
@@ -5,6 +5,8 @@
from mosq_test_helper import *
mosq_test.require_features(["WITH_PLUGINS", "WITH_PLUGIN_PASSWORD_FILE"])
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
@@ -6,6 +6,8 @@ from mosq_test_helper import *
import os.path
import signal
mosq_test.require_features(["WITH_PERSISTENCE"])
def write_config(filename, port1, port2, per_listener):
with open(filename, 'w') as f:
f.write("per_listener_settings %s\n" % (per_listener))
@@ -5,6 +5,8 @@
from mosq_test_helper import *
import signal
mosq_test.require_features(["WITH_PERSISTENCE"])
def write_config(filename, port, per_listener):
with open(filename, 'w') as f:
f.write("per_listener_settings %s\n" % (per_listener))
@@ -4,6 +4,8 @@
from mosq_test_helper import *
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
def write_config(filename, port1, port2, protocol_version):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port2))
@@ -4,6 +4,8 @@
from mosq_test_helper import *
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
def write_config(filename, port1, port2, protocol_version):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port2))
@@ -4,6 +4,8 @@
from mosq_test_helper import *
mosq_test.require_features(["INC_BRIDGE_SUPPORT", "WITH_PERSISTENCE"])
def write_config1(filename, persistence_file, port1, port2):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port2))
@@ -4,6 +4,8 @@
from mosq_test_helper import *
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
def write_config(filename, port1, port2, protocol_version):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port2))
+2
View File
@@ -4,6 +4,8 @@
from mosq_test_helper import *
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
def write_config(filename, port1, port2, protocol_version):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port2))
@@ -4,6 +4,8 @@
from mosq_test_helper import *
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
def write_config(filename, port1, port2, protocol_version):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port2))
@@ -4,6 +4,8 @@
from mosq_test_helper import *
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
def write_config(filename, port1, port2, protocol_version):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port2))
+2
View File
@@ -4,6 +4,8 @@
from mosq_test_helper import *
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
def write_config(filename, port1, port2, protocol_version):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port2))
@@ -5,5 +5,7 @@ from collections import namedtuple
from mosq_test_helper import *
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
(port_a_listen, port_b_listen) = mosq_test.get_port(2)
subprocess.run([f'{Path(__file__).resolve().parent}/06-bridge-clean-session-core.py', str(port_a_listen), str(port_b_listen), "False", "False"])
@@ -4,6 +4,8 @@
from mosq_test_helper import *
from collections import namedtuple
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
(port_a_listen, port_b_listen) = mosq_test.get_port(2)
subprocess.run([f'{Path(__file__).resolve().parent}/06-bridge-clean-session-core.py', str(port_a_listen), str(port_b_listen), "False", "None"])
@@ -4,6 +4,8 @@
from mosq_test_helper import *
from collections import namedtuple
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
(port_a_listen, port_b_listen) = mosq_test.get_port(2)
subprocess.run([f'{Path(__file__).resolve().parent}/06-bridge-clean-session-core.py', str(port_a_listen), str(port_b_listen), "False", "True"])
@@ -4,6 +4,8 @@
from mosq_test_helper import *
from collections import namedtuple
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
(port_a_listen, port_b_listen) = mosq_test.get_port(2)
subprocess.run([f'{Path(__file__).resolve().parent}/06-bridge-clean-session-core.py', str(port_a_listen), str(port_b_listen), "True", "False"])
@@ -4,6 +4,8 @@
from mosq_test_helper import *
from collections import namedtuple
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
(port_a_listen, port_b_listen) = mosq_test.get_port(2)
subprocess.run([f'{Path(__file__).resolve().parent}/06-bridge-clean-session-core.py', str(port_a_listen), str(port_b_listen), "True", "None"])
@@ -4,6 +4,8 @@
from mosq_test_helper import *
from collections import namedtuple
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
(port_a_listen, port_b_listen) = mosq_test.get_port(2)
subprocess.run([f'{Path(__file__).resolve().parent}/06-bridge-clean-session-core.py', str(port_a_listen), str(port_b_listen), "True", "True"])
+1
View File
@@ -5,6 +5,7 @@
from mosq_test_helper import *
import signal
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
def write_config(filename, port1, port2, subtopic, reload_immediate=False):
with open(filename, 'w') as f:
@@ -4,6 +4,8 @@
from mosq_test_helper import *
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
def write_config(filename, port1, port2, protocol_version):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port2))
@@ -4,6 +4,8 @@
from mosq_test_helper import *
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
def write_config(filename, port1, port2, protocol_version):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port2))
+2
View File
@@ -5,6 +5,8 @@
from mosq_test_helper import *
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
def do_test(start_broker, proto_ver_connect, proto_ver_msgs, sub_opts):
rc = 1
connect_packet = mosq_test.gen_connect("bridge-test", proto_ver=proto_ver_connect)
+2
View File
@@ -5,6 +5,8 @@
from mosq_test_helper import *
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
def write_config(filename, port1, port2, protocol_version, outgoing_retain):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port2))
@@ -4,6 +4,8 @@
from mosq_test_helper import *
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
def write_config(filename, port1, port2, protocol_version):
with open(filename, 'w') as f:
f.write("per_listener_settings true\n")
@@ -5,6 +5,8 @@
from mosq_test_helper import *
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
def write_config(filename, port1, port2, protocol_version):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port2))
@@ -4,6 +4,8 @@
from mosq_test_helper import *
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
def write_config(filename, port1, port2):
with open(filename, 'w') as f:
f.write(f"listener {port2}\n")
+2
View File
@@ -5,6 +5,8 @@
from mosq_test_helper import *
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
def write_config(filename, port1, port2, protocol_version):
with open(filename, 'w') as f:
f.write("log_type all\n")
+2
View File
@@ -2,6 +2,8 @@
from mosq_test_helper import *
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
source_dir = Path(__file__).resolve().parent
ssl_dir = source_dir.parent / "ssl"
+2
View File
@@ -6,6 +6,8 @@ if sys.version < '2.7':
print("WARNING: SSL not supported on Python 2.6")
exit(0)
mosq_test.require_features(["INC_BRIDGE_SUPPORT"])
def write_config1(filename, port1, port2):
with open(filename, 'w') as f:
f.write("allow_anonymous true\n")
+1
View File
@@ -6,6 +6,7 @@ if sys.version < '2.7':
print("WARNING: SSL not supported on Python 2.6")
exit(0)
mosq_test.require_features(["WITH_TLS_PSK"])
def write_config(filename, port1, port2):
with open(filename, 'w') as f:
@@ -4,6 +4,8 @@
from mosq_test_helper import *
mosq_test.require_features(["WITH_PLUGINS", "WITH_PLUGIN_ACL_FILE"])
def write_config(filename, port, per_listener):
with open(filename, 'w') as f:
f.write("per_listener_settings %s\n" % (per_listener))
+1
View File
@@ -4,6 +4,7 @@
from mosq_test_helper import *
mosq_test.require_features(["WITH_CLIENTS", "WITH_TLS_PSK"])
def write_config(filename, port, per_listener_settings="false"):
with open(filename, "w") as f:
+2
View File
@@ -11,6 +11,8 @@
from mosq_test_helper import *
mosq_test.require_features(["WITH_PERSISTENCE"])
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
@@ -4,6 +4,8 @@
from mosq_test_helper import *
mosq_test.require_features(["WITH_PERSISTENCE"])
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
@@ -5,6 +5,8 @@
from mosq_test_helper import *
mosq_test.require_features(["WITH_PERSISTENCE"])
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
@@ -4,6 +4,8 @@
from mosq_test_helper import *
mosq_test.require_features(["WITH_PERSISTENCE"])
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
+2
View File
@@ -4,6 +4,8 @@
from mosq_test_helper import *
mosq_test.require_features(["WITH_PERSISTENCE"])
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
+2
View File
@@ -4,6 +4,8 @@
from mosq_test_helper import *
mosq_test.require_features(["WITH_PERSISTENCE"])
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
+2
View File
@@ -4,6 +4,8 @@ from mosq_test_helper import *
rc = 1
mosq_test.require_features(["WITH_WEBSOCKETS"])
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
+2
View File
@@ -7,6 +7,8 @@ from dynsec_helper import *
import json
import shutil
mosq_test.require_features(["WITH_CONTROL", "WITH_PLUGINS", "WITH_PLUGIN_DYNAMIC_SECURITY"])
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
+2
View File
@@ -7,6 +7,8 @@ from dynsec_helper import *
import json
import shutil
mosq_test.require_features(["WITH_CONTROL", "WITH_PLUGINS", "WITH_PLUGIN_DYNAMIC_SECURITY"])
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
+2
View File
@@ -6,6 +6,8 @@ from dynsec_helper import *
import json
import shutil
mosq_test.require_features(["WITH_CONTROL", "WITH_PLUGINS", "WITH_PLUGIN_DYNAMIC_SECURITY"])
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
+2
View File
@@ -5,6 +5,8 @@ from dynsec_helper import *
import json
import shutil
mosq_test.require_features(["WITH_CONTROL", "WITH_PLUGINS", "WITH_PLUGIN_DYNAMIC_SECURITY"])
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
+2
View File
@@ -7,6 +7,8 @@ from dynsec_helper import *
import json
import shutil
mosq_test.require_features(["WITH_CONTROL", "WITH_PLUGINS", "WITH_PLUGIN_DYNAMIC_SECURITY"])
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
+2
View File
@@ -5,6 +5,8 @@ from dynsec_helper import *
import json
import shutil
mosq_test.require_features(["WITH_CONTROL", "WITH_PLUGINS", "WITH_PLUGIN_DYNAMIC_SECURITY"])
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
+2
View File
@@ -4,6 +4,8 @@ from mosq_test_helper import *
import json
import shutil
mosq_test.require_features(["WITH_CONTROL", "WITH_PLUGINS", "WITH_PLUGIN_DYNAMIC_SECURITY"])
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))

Some files were not shown because too many files have changed in this diff Show More