Crude random client testing
This needs a lot of improvement, but is a reasonable start.pull/1239/head
parent
638ab2f969
commit
969885d967
@ -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
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
|||||||
|
test:$6$cBP7e6sUriMSh8yf$+Z3E9P1g+Hui8zDJA+XJpTHl6+0eym0MtWokmOY4j1svAR5RtjZoXB4OQuHYzrGrdp1e8gXoqcKlcP+1lmepmg==
|
@ -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
|
@ -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()
|
@ -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