Crude random client testing
This needs a lot of improvement, but is a reasonable start.
This commit is contained in:
parent
638ab2f969
commit
969885d967
26
test/random/Makefile
Normal file
26
test/random/Makefile
Normal file
@ -0,0 +1,26 @@
|
||||
include ../../config.mk
|
||||
|
||||
.PHONY: all test
|
||||
|
||||
ifeq ($(WITH_SHARED_LIBRARIES),yes)
|
||||
LIB_DEP:=../../lib/libmosquitto.so.${SOVERSION}
|
||||
else
|
||||
LIB_DEP:=../../lib/libmosquitto.a
|
||||
endif
|
||||
|
||||
all : auth_plugin.so
|
||||
|
||||
auth_plugin.so : auth_plugin.c
|
||||
$(CC) ${CFLAGS} -fPIC -shared $< -o $@ -I../../lib -I../../src
|
||||
|
||||
../lib/libmosquitto.so.${SOVERSION} :
|
||||
$(MAKE) -C ../../lib
|
||||
|
||||
../lib/libmosquitto.a :
|
||||
$(MAKE) -C ../../lib libmosquitto.a
|
||||
|
||||
clean :
|
||||
-rm -f *.o random_client *.gcda *.gcno
|
||||
|
||||
test : all
|
||||
./test.py
|
56
test/random/auth_plugin.c
Normal file
56
test/random/auth_plugin.c
Normal file
@ -0,0 +1,56 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <mosquitto.h>
|
||||
#include <mosquitto_broker.h>
|
||||
#include <mosquitto_plugin.h>
|
||||
|
||||
int mosquitto_auth_plugin_version(void)
|
||||
{
|
||||
return MOSQ_AUTH_PLUGIN_VERSION;
|
||||
}
|
||||
|
||||
int mosquitto_auth_plugin_init(void **user_data, struct mosquitto_opt *auth_opts, int auth_opt_count)
|
||||
{
|
||||
srandom(time(NULL));
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
int mosquitto_auth_plugin_cleanup(void *user_data, struct mosquitto_opt *auth_opts, int auth_opt_count)
|
||||
{
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
int mosquitto_auth_security_init(void *user_data, struct mosquitto_opt *auth_opts, int auth_opt_count, bool reload)
|
||||
{
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
int mosquitto_auth_security_cleanup(void *user_data, struct mosquitto_opt *auth_opts, int auth_opt_count, bool reload)
|
||||
{
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
int mosquitto_auth_acl_check(void *user_data, int access, struct mosquitto *client, const struct mosquitto_acl_msg *msg)
|
||||
{
|
||||
if(random() % 2 == 0){
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}else{
|
||||
return MOSQ_ERR_ACL_DENIED;
|
||||
}
|
||||
}
|
||||
|
||||
int mosquitto_auth_unpwd_check(void *user_data, struct mosquitto *client, const char *username, const char *password)
|
||||
{
|
||||
if(random() % 2 == 0){
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}else{
|
||||
return MOSQ_ERR_AUTH;
|
||||
}
|
||||
}
|
||||
|
||||
int mosquitto_auth_psk_key_get(void *user_data, struct mosquitto *client, const char *hint, const char *identity, char *key, int max_key_len)
|
||||
{
|
||||
return MOSQ_ERR_AUTH;
|
||||
}
|
||||
|
1
test/random/pwfile
Normal file
1
test/random/pwfile
Normal file
@ -0,0 +1 @@
|
||||
test:$6$cBP7e6sUriMSh8yf$+Z3E9P1g+Hui8zDJA+XJpTHl6+0eym0MtWokmOY4j1svAR5RtjZoXB4OQuHYzrGrdp1e8gXoqcKlcP+1lmepmg==
|
92
test/random/random.conf
Normal file
92
test/random/random.conf
Normal file
@ -0,0 +1,92 @@
|
||||
per_listener_settings true
|
||||
|
||||
# Unencrypted MQTT over TCP
|
||||
listener 1883
|
||||
|
||||
listener 1884
|
||||
password_file pwfile
|
||||
|
||||
listener 1885
|
||||
auth_plugin ./auth_plugin.so
|
||||
|
||||
listener 1886
|
||||
password_file pwfile
|
||||
auth_plugin ./auth_plugin.so
|
||||
|
||||
|
||||
# Encrypted MQTT over TCP
|
||||
listener 8883
|
||||
cafile ../ssl/all-ca.crt
|
||||
certfile ../ssl/server.crt
|
||||
keyfile ../ssl/server.key
|
||||
|
||||
listener 8884
|
||||
cafile ../ssl/all-ca.crt
|
||||
certfile ../ssl/server.crt
|
||||
keyfile ../ssl/server.key
|
||||
password_file pwfile
|
||||
|
||||
listener 8885
|
||||
cafile ../ssl/all-ca.crt
|
||||
certfile ../ssl/server.crt
|
||||
keyfile ../ssl/server.key
|
||||
auth_plugin ./auth_plugin.so
|
||||
|
||||
listener 8886
|
||||
cafile ../ssl/all-ca.crt
|
||||
certfile ../ssl/server.crt
|
||||
keyfile ../ssl/server.key
|
||||
password_file pwfile
|
||||
auth_plugin ./auth_plugin.so
|
||||
|
||||
|
||||
# Unencrypted MQTT over WebSockets
|
||||
listener 8000
|
||||
protocol websockets
|
||||
|
||||
listener 8001
|
||||
protocol websockets
|
||||
password_file pwfile
|
||||
|
||||
listener 8002
|
||||
protocol websockets
|
||||
auth_plugin ./auth_plugin.so
|
||||
|
||||
listener 8003
|
||||
protocol websockets
|
||||
password_file pwfile
|
||||
auth_plugin ./auth_plugin.so
|
||||
|
||||
|
||||
# Encrypted MQTT over WebSockets
|
||||
listener 4430
|
||||
protocol websockets
|
||||
cafile ../ssl/all-ca.crt
|
||||
certfile ../ssl/server.crt
|
||||
keyfile ../ssl/server.key
|
||||
|
||||
listener 4431
|
||||
protocol websockets
|
||||
cafile ../ssl/all-ca.crt
|
||||
certfile ../ssl/server.crt
|
||||
keyfile ../ssl/server.key
|
||||
password_file pwfile
|
||||
|
||||
listener 4432
|
||||
protocol websockets
|
||||
cafile ../ssl/all-ca.crt
|
||||
certfile ../ssl/server.crt
|
||||
keyfile ../ssl/server.key
|
||||
auth_plugin ./auth_plugin.so
|
||||
|
||||
listener 4433
|
||||
protocol websockets
|
||||
cafile ../ssl/all-ca.crt
|
||||
certfile ../ssl/server.crt
|
||||
keyfile ../ssl/server.key
|
||||
password_file pwfile
|
||||
auth_plugin ./auth_plugin.so
|
||||
|
||||
|
||||
#log_dest file mosquitto.log
|
||||
#log_type all
|
150
test/random/random_client.py
Executable file
150
test/random/random_client.py
Executable file
@ -0,0 +1,150 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import paho.mqtt.client as paho
|
||||
import random
|
||||
import sys
|
||||
import time
|
||||
|
||||
# This is a client that carries out randomised behaviour. It is intended for
|
||||
# use with the local config file. This file has multiple listeners configured:
|
||||
# * 1883 - unencrypted MQTT over TCP with no authentication
|
||||
# * 1884 - unencrypted MQTT over TCP with password authentication
|
||||
# * 1885 - unencrypted MQTT over TCP with plugin authentication
|
||||
# * 1886 - unencrypted MQTT over TCP with password and plugin authentication
|
||||
#
|
||||
# * 8883 - encrypted MQTT over TCP with no authentication
|
||||
# * 8884 - encrypted MQTT over TCP with password authentication
|
||||
# * 8885 - encrypted MQTT over TCP with plugin authentication
|
||||
# * 8886 - encrypted MQTT over TCP with password and plugin authentication
|
||||
#
|
||||
# * 8000 - unencrypted MQTT over WebSockets with no authentication
|
||||
# * 8001 - unencrypted MQTT over WebSockets with password authentication
|
||||
# * 8002 - unencrypted MQTT over WebSockets with plugin authentication
|
||||
# * 8003 - unencrypted MQTT over WebSockets with password and plugin authentication
|
||||
#
|
||||
# * 4430 - encrypted MQTT over WebSockets with no authentication
|
||||
# * 4431 - encrypted MQTT over WebSockets with password authentication
|
||||
# * 4432 - encrypted MQTT over WebSockets with plugin authentication
|
||||
# * 4433 - encrypted MQTT over WebSockets with password and plugin authentication
|
||||
#
|
||||
# The client randomly picks:
|
||||
# * A port out of the list
|
||||
# * Whether to use encryption
|
||||
# * Whether to use WebSockets
|
||||
# * Clean start or not
|
||||
# * Session expiry interval or not
|
||||
# * QoS to use when subscribing - topics "outgoing/[client id]/message" and "response/#"
|
||||
# * Lifetime of connection
|
||||
# On a per publish message basis it chooses:
|
||||
# * QoS of message
|
||||
# * Topic of message "outgoing/[0-max client]/message"
|
||||
# * Retain
|
||||
# * Interval until next outgoing message
|
||||
|
||||
ports = [
|
||||
{"port":1883, "tls":False, "transport":"tcp", "auth":False},
|
||||
{"port":1884, "tls":False, "transport":"tcp", "auth":True},
|
||||
{"port":1885, "tls":False, "transport":"tcp", "auth":True},
|
||||
{"port":1886, "tls":False, "transport":"tcp", "auth":True},
|
||||
|
||||
{"port":8883, "tls":True, "transport":"tcp", "auth":False},
|
||||
{"port":8884, "tls":True, "transport":"tcp", "auth":True},
|
||||
{"port":8885, "tls":True, "transport":"tcp", "auth":True},
|
||||
{"port":8886, "tls":True, "transport":"tcp", "auth":True},
|
||||
|
||||
{"port":8000, "tls":False, "transport":"websockets", "auth":False},
|
||||
{"port":8001, "tls":False, "transport":"websockets", "auth":True},
|
||||
{"port":8002, "tls":False, "transport":"websockets", "auth":True},
|
||||
{"port":8003, "tls":False, "transport":"websockets", "auth":True},
|
||||
|
||||
{"port":4430, "tls":True, "transport":"websockets", "auth":False},
|
||||
{"port":4431, "tls":True, "transport":"websockets", "auth":True},
|
||||
{"port":4432, "tls":True, "transport":"websockets", "auth":True},
|
||||
{"port":4433, "tls":True, "transport":"websockets", "auth":True},
|
||||
]
|
||||
|
||||
booleans = [True, False]
|
||||
qos_values = [0, 1, 2]
|
||||
|
||||
|
||||
def on_connect(client, userdata, flags, rc):
|
||||
global running
|
||||
if rc == 0:
|
||||
client.subscribe("response/#", subscribe_qos)
|
||||
client.subscribe("outgoing/%s/message" % (client_id), subscribe_qos)
|
||||
else:
|
||||
running = False
|
||||
|
||||
|
||||
def on_message(client, userdata, msg):
|
||||
pass
|
||||
|
||||
|
||||
def on_publish(client, userdata, mid):
|
||||
pass
|
||||
|
||||
|
||||
def on_disconnect(client, userdata, rc):
|
||||
running = False
|
||||
|
||||
|
||||
def do_publish(client):
|
||||
retain = random.choice(booleans)
|
||||
qos = random.choice(qos_values)
|
||||
topic = "outgoing/%d/message" % (random.uniform(1, 1000))
|
||||
payload = "message"
|
||||
|
||||
client.publish(topic, payload, qos, retain)
|
||||
|
||||
next_publish_time = time.time() + random.uniform(0.1, 2.0)
|
||||
|
||||
|
||||
def main():
|
||||
global running
|
||||
global lifetime
|
||||
|
||||
mqttc = paho.Client(client_id, clean_session=clean_start, protocol=protocol, transport=transport)
|
||||
mqttc.on_message = on_message
|
||||
mqttc.on_publish = on_publish
|
||||
mqttc.on_connect = on_connect
|
||||
mqttc.on_disconnect = on_disconnect
|
||||
if auth and random.choice(booleans):
|
||||
if random.choice(booleans):
|
||||
mqttc.username_pw_set("test", "password")
|
||||
else:
|
||||
mqttc.username_pw_set("bad", "bad")
|
||||
|
||||
if use_tls:
|
||||
mqttc.tls_set(ca_certs="../ssl/all-ca.crt")
|
||||
|
||||
mqttc.connect("localhost", port)
|
||||
mqttc.loop_start()
|
||||
|
||||
while running:
|
||||
time.sleep(0.1)
|
||||
now = time.time()
|
||||
if now > next_publish_time:
|
||||
do_publish(mqttc)
|
||||
if now > lifetime:
|
||||
if random.choice(booleans):
|
||||
mqttc.disconnect()
|
||||
lifetime += 5.0
|
||||
else:
|
||||
running = False
|
||||
|
||||
|
||||
p = random.choice(ports)
|
||||
port = p["port"]
|
||||
use_tls = p["tls"]
|
||||
transport = p["transport"]
|
||||
auth = p["auth"]
|
||||
|
||||
client_id = "cid"+sys.argv[1]
|
||||
clean_start = random.choice(booleans)
|
||||
subscribe_qos = random.choice(qos_values)
|
||||
protocol = paho.MQTTv311
|
||||
next_publish_time = time.time() + random.uniform(0.1, 2.0)
|
||||
lifetime = time.time() + random.uniform(5.0, 10.0)
|
||||
running = True
|
||||
|
||||
main()
|
46
test/random/test.py
Executable file
46
test/random/test.py
Executable file
@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import subprocess
|
||||
import time
|
||||
import sys
|
||||
|
||||
def next_client(clients):
|
||||
if len(clients) == 0:
|
||||
return
|
||||
|
||||
c = clients.pop()
|
||||
args = ["./random_client.py", str(c)]
|
||||
|
||||
proc = subprocess.Popen(args, stderr=subprocess.DEVNULL)
|
||||
proc.cid = c
|
||||
return proc
|
||||
|
||||
|
||||
def run_clients(max_clients):
|
||||
clients = list(range(1, max_clients))
|
||||
start_time = time.time()
|
||||
|
||||
running_clients = []
|
||||
while True:
|
||||
print(len(running_clients))
|
||||
if len(running_clients) < max_clients:
|
||||
c = next_client(clients)
|
||||
if c is not None:
|
||||
running_clients.append(c)
|
||||
else:
|
||||
time.sleep(0.1)
|
||||
|
||||
for c in running_clients:
|
||||
c.poll()
|
||||
if c.returncode is not None:
|
||||
running_clients.remove(c)
|
||||
clients.append(c.cid)
|
||||
c.terminate()
|
||||
c.wait()
|
||||
|
||||
|
||||
env = {}
|
||||
env["LD_LIBRARY_PATH"] = "../../lib"
|
||||
|
||||
#broker = subprocess.Popen(["../../src/mosquitto", "-c", "random.conf"], env=env)
|
||||
run_clients(1000)
|
Loading…
Reference in New Issue
Block a user