mirror of
https://github.com/eclipse-mosquitto/mosquitto.git
synced 2026-02-06 02:52:07 +08:00
Formatting: Apply to C++ files
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "temperature_conversion.h"
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
class mqtt_tempconv *tempconv;
|
||||
|
||||
@@ -17,6 +17,7 @@ mqtt_tempconv::~mqtt_tempconv()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void mqtt_tempconv::on_connect(int rc)
|
||||
{
|
||||
printf("Connected with code %d.\n", rc);
|
||||
@@ -26,6 +27,7 @@ void mqtt_tempconv::on_connect(int rc)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mqtt_tempconv::on_message(const struct mosquitto_message *message)
|
||||
{
|
||||
double temp_celsius, temp_fahrenheit;
|
||||
@@ -42,6 +44,7 @@ void mqtt_tempconv::on_message(const struct mosquitto_message *message)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mqtt_tempconv::on_subscribe(int mid, int qos_count, const int *granted_qos)
|
||||
{
|
||||
printf("Subscription succeeded.\n");
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
class mqtt_tempconv : public mosqpp::mosquittopp
|
||||
{
|
||||
public:
|
||||
mqtt_tempconv(const char *id, const char *host, int port);
|
||||
~mqtt_tempconv();
|
||||
public:
|
||||
mqtt_tempconv(const char *id, const char *host, int port);
|
||||
~mqtt_tempconv();
|
||||
|
||||
void on_connect(int rc);
|
||||
void on_message(const struct mosquitto_message *message);
|
||||
void on_subscribe(int mid, int qos_count, const int *granted_qos);
|
||||
void on_connect(int rc);
|
||||
void on_message(const struct mosquitto_message *message);
|
||||
void on_subscribe(int mid, int qos_count, const int *granted_qos);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,6 +31,7 @@ Contributors:
|
||||
/* The fuzz-only main function. */
|
||||
extern "C" int db_dump_fuzz_main(int argc, char *argv[]);
|
||||
|
||||
|
||||
void run_db_dump(char *filename)
|
||||
{
|
||||
char *argv[2];
|
||||
@@ -44,6 +45,7 @@ void run_db_dump(char *filename)
|
||||
free(argv[0]);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
char filename[100];
|
||||
@@ -53,7 +55,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
|
||||
snprintf(filename, sizeof(filename), "db_dump_%d.db", getpid());
|
||||
fptr = fopen(filename, "wb");
|
||||
if(!fptr) return 1;
|
||||
if(!fptr){
|
||||
return 1;
|
||||
}
|
||||
fwrite(data, 1, size, fptr);
|
||||
fclose(fptr);
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ Contributors:
|
||||
/* The fuzz-only main function. */
|
||||
extern "C" int db_dump_fuzz_main(int argc, char *argv[]);
|
||||
|
||||
|
||||
void run_db_dump(char *filename)
|
||||
{
|
||||
char *argv[3];
|
||||
@@ -46,6 +47,7 @@ void run_db_dump(char *filename)
|
||||
free(argv[1]);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
char filename[100];
|
||||
@@ -55,7 +57,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
|
||||
snprintf(filename, sizeof(filename), "db_dump_client_stats_%d.db", getpid());
|
||||
fptr = fopen(filename, "wb");
|
||||
if(!fptr) return 1;
|
||||
if(!fptr){
|
||||
return 1;
|
||||
}
|
||||
fwrite(data, 1, size, fptr);
|
||||
fclose(fptr);
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ Contributors:
|
||||
/* The fuzz-only main function. */
|
||||
extern "C" int db_dump_fuzz_main(int argc, char *argv[]);
|
||||
|
||||
|
||||
void run_db_dump(char *filename)
|
||||
{
|
||||
char *argv[3];
|
||||
@@ -46,6 +47,7 @@ void run_db_dump(char *filename)
|
||||
free(argv[1]);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
char filename[100];
|
||||
@@ -55,7 +57,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
|
||||
snprintf(filename, sizeof(filename), "db_dump_stats_%d.db", getpid());
|
||||
fptr = fopen(filename, "wb");
|
||||
if(!fptr) return 1;
|
||||
if(!fptr){
|
||||
return 1;
|
||||
}
|
||||
fwrite(data, 1, size, fptr);
|
||||
fclose(fptr);
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ Contributors:
|
||||
/* The fuzz-only main function. */
|
||||
extern "C" int mosquitto_passwd_fuzz_main(int argc, char *argv[]);
|
||||
|
||||
|
||||
void run_mosquitto_passwd(char *filename)
|
||||
{
|
||||
char *argv[5];
|
||||
@@ -50,6 +51,7 @@ void run_mosquitto_passwd(char *filename)
|
||||
free(argv[4]);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
char filename[100];
|
||||
@@ -59,7 +61,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
|
||||
snprintf(filename, sizeof(filename), "mosquitto_passwd_%d", getpid());
|
||||
fptr = fopen(filename, "wb");
|
||||
if(!fptr) return 1;
|
||||
if(!fptr){
|
||||
return 1;
|
||||
}
|
||||
fwrite(data, 1, size, fptr);
|
||||
fclose(fptr);
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ Contributors:
|
||||
/* The broker fuzz-only main function. */
|
||||
extern "C" int mosquitto_fuzz_main(int argc, char *argv[]);
|
||||
|
||||
|
||||
void *run_broker(void *args)
|
||||
{
|
||||
char *argv[4];
|
||||
@@ -64,6 +65,7 @@ void recv_timeout(int sock, void *buf, size_t len, int timeout_us)
|
||||
(void)recv(sock, buf, len, 0);
|
||||
}
|
||||
|
||||
|
||||
int connect_retrying(int port)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
@@ -91,6 +93,7 @@ int connect_retrying(int port)
|
||||
return sock;
|
||||
}
|
||||
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
struct fuzz_data fuzz;
|
||||
|
||||
@@ -45,7 +45,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
|
||||
snprintf(filename, sizeof(filename), "/tmp/acl_file_%d", getpid());
|
||||
fptr = fopen(filename, "wb");
|
||||
if(!fptr) return 1;
|
||||
if(!fptr){
|
||||
return 1;
|
||||
}
|
||||
fwrite(data, 1, size, fptr);
|
||||
fclose(fptr);
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ Contributors:
|
||||
#define kMaxInputLength 100000
|
||||
#include "fuzz_packet_read_base.h"
|
||||
|
||||
|
||||
extern "C" int fuzz_packet_read_init(struct mosquitto *context)
|
||||
{
|
||||
context->protocol = mosq_p_mqtt5;
|
||||
@@ -26,12 +27,14 @@ extern "C" int fuzz_packet_read_init(struct mosquitto *context)
|
||||
return !context->auth_method;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void fuzz_packet_read_cleanup(struct mosquitto *context)
|
||||
{
|
||||
free(context->auth_method);
|
||||
context->auth_method = NULL;
|
||||
}
|
||||
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
int rc = fuzz_packet_read_base(data, size, handle__auth);
|
||||
|
||||
@@ -19,6 +19,7 @@ Contributors:
|
||||
#define kMaxInputLength 100000
|
||||
#include "fuzz_packet_read_base.h"
|
||||
|
||||
|
||||
extern "C" int fuzz_basic_auth(int event, void *event_data, void *userdata)
|
||||
{
|
||||
struct mosquitto_evt_basic_auth *ed = (struct mosquitto_evt_basic_auth *)event_data;
|
||||
@@ -33,6 +34,7 @@ extern "C" int fuzz_basic_auth(int event, void *event_data, void *userdata)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C" int fuzz_packet_read_init(struct mosquitto *context)
|
||||
{
|
||||
context->listener->security_options->pid = (mosquitto_plugin_id_t *)calloc(1, sizeof(mosquitto_plugin_id_t));
|
||||
@@ -45,6 +47,7 @@ extern "C" int fuzz_packet_read_init(struct mosquitto *context)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void fuzz_packet_read_cleanup(struct mosquitto *context)
|
||||
{
|
||||
mosquitto_callback_unregister(context->listener->security_options->pid,
|
||||
@@ -54,6 +57,7 @@ extern "C" void fuzz_packet_read_cleanup(struct mosquitto *context)
|
||||
context->listener->security_options->pid = NULL;
|
||||
}
|
||||
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
return fuzz_packet_read_base(data, size, handle__connect);
|
||||
|
||||
@@ -18,6 +18,7 @@ Contributors:
|
||||
|
||||
#include "fuzz_packet_read_base.h"
|
||||
|
||||
|
||||
extern "C" int fuzz_acl_check(int event, void *event_data, void *userdata)
|
||||
{
|
||||
struct mosquitto_evt_acl_check *ed = (struct mosquitto_evt_acl_check *)event_data;
|
||||
@@ -32,6 +33,7 @@ extern "C" int fuzz_acl_check(int event, void *event_data, void *userdata)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C" int fuzz_packet_read_init(struct mosquitto *context)
|
||||
{
|
||||
context->listener->security_options->pid = (mosquitto_plugin_id_t *)calloc(1, sizeof(mosquitto_plugin_id_t));
|
||||
@@ -44,6 +46,7 @@ extern "C" int fuzz_packet_read_init(struct mosquitto *context)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void fuzz_packet_read_cleanup(struct mosquitto *context)
|
||||
{
|
||||
mosquitto_callback_unregister(context->listener->security_options->pid,
|
||||
@@ -53,6 +56,7 @@ extern "C" void fuzz_packet_read_cleanup(struct mosquitto *context)
|
||||
context->listener->security_options->pid = NULL;
|
||||
}
|
||||
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
return fuzz_packet_read_base(data, size, handle__publish);
|
||||
|
||||
@@ -19,6 +19,7 @@ Contributors:
|
||||
#define kMaxInputLength 100000
|
||||
#include "fuzz_packet_read_base.h"
|
||||
|
||||
|
||||
extern "C" int fuzz_acl_check(int event, void *event_data, void *userdata)
|
||||
{
|
||||
struct mosquitto_evt_acl_check *ed = (struct mosquitto_evt_acl_check *)event_data;
|
||||
@@ -33,6 +34,7 @@ extern "C" int fuzz_acl_check(int event, void *event_data, void *userdata)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C" int fuzz_packet_read_init(struct mosquitto *context)
|
||||
{
|
||||
context->listener->security_options->pid = (mosquitto_plugin_id_t *)calloc(1, sizeof(mosquitto_plugin_id_t));
|
||||
@@ -45,6 +47,7 @@ extern "C" int fuzz_packet_read_init(struct mosquitto *context)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void fuzz_packet_read_cleanup(struct mosquitto *context)
|
||||
{
|
||||
mosquitto_callback_unregister(context->listener->security_options->pid,
|
||||
@@ -54,6 +57,7 @@ extern "C" void fuzz_packet_read_cleanup(struct mosquitto *context)
|
||||
context->listener->security_options->pid = NULL;
|
||||
}
|
||||
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
return fuzz_packet_read_base(data, size, handle__subscribe);
|
||||
|
||||
@@ -19,6 +19,7 @@ Contributors:
|
||||
#define kMaxInputLength 100000
|
||||
#include "fuzz_packet_read_base.h"
|
||||
|
||||
|
||||
extern "C" int fuzz_acl_check(int event, void *event_data, void *userdata)
|
||||
{
|
||||
struct mosquitto_evt_acl_check *ed = (struct mosquitto_evt_acl_check *)event_data;
|
||||
@@ -33,6 +34,7 @@ extern "C" int fuzz_acl_check(int event, void *event_data, void *userdata)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C" int fuzz_packet_read_init(struct mosquitto *context)
|
||||
{
|
||||
context->listener->security_options->pid = (mosquitto_plugin_id_t *)calloc(1, sizeof(mosquitto_plugin_id_t));
|
||||
@@ -45,6 +47,7 @@ extern "C" int fuzz_packet_read_init(struct mosquitto *context)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void fuzz_packet_read_cleanup(struct mosquitto *context)
|
||||
{
|
||||
mosquitto_callback_unregister(context->listener->security_options->pid,
|
||||
@@ -54,6 +57,7 @@ extern "C" void fuzz_packet_read_cleanup(struct mosquitto *context)
|
||||
context->listener->security_options->pid = NULL;
|
||||
}
|
||||
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
return fuzz_packet_read_base(data, size, handle__unsubscribe);
|
||||
|
||||
@@ -45,7 +45,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
|
||||
snprintf(filename, sizeof(filename), "/tmp/password_file_%d", getpid());
|
||||
fptr = fopen(filename, "wb");
|
||||
if(!fptr) return 1;
|
||||
if(!fptr){
|
||||
return 1;
|
||||
}
|
||||
fwrite(data, 1, size, fptr);
|
||||
fclose(fptr);
|
||||
|
||||
|
||||
@@ -45,7 +45,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
|
||||
snprintf(filename, sizeof(filename), "/tmp/psk_file_%d", getpid());
|
||||
fptr = fopen(filename, "wb");
|
||||
if(!fptr) return 1;
|
||||
if(!fptr){
|
||||
return 1;
|
||||
}
|
||||
fwrite(data, 1, size, fptr);
|
||||
fclose(fptr);
|
||||
|
||||
|
||||
@@ -30,8 +30,10 @@ extern "C" {
|
||||
#include "mosquitto_broker_internal.h"
|
||||
}
|
||||
|
||||
|
||||
//int sub__messages_queue(const char *source_id, const char *topic, uint8_t qos, int retain, struct mosquitto__base_msg **stored)
|
||||
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
struct mosquitto__config config = {0};
|
||||
|
||||
@@ -18,15 +18,18 @@ Contributors:
|
||||
|
||||
#include "fuzz_packet_read_base.h"
|
||||
|
||||
|
||||
extern "C" int fuzz_packet_read_init(struct mosquitto *context)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void fuzz_packet_read_cleanup(struct mosquitto *context)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
return fuzz_packet_read_base(data, size, handle__packet);
|
||||
|
||||
@@ -32,6 +32,7 @@ Contributors:
|
||||
/* The broker fuzz-only main function. */
|
||||
extern "C" int mosquitto_fuzz_main(int argc, char *argv[]);
|
||||
|
||||
|
||||
void run_broker(char *filename)
|
||||
{
|
||||
char *argv[5];
|
||||
@@ -51,7 +52,6 @@ void run_broker(char *filename)
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
char filename[100];
|
||||
@@ -65,7 +65,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
|
||||
snprintf(filename, sizeof(filename), "/tmp/mosquitto_%d.conf", getpid());
|
||||
fptr = fopen(filename, "wb");
|
||||
if(!fptr) return 1;
|
||||
if(!fptr){
|
||||
return 1;
|
||||
}
|
||||
fwrite(data, 1, size, fptr);
|
||||
fclose(fptr);
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ Contributors:
|
||||
/* The broker fuzz-only main function. */
|
||||
extern "C" int mosquitto_fuzz_main(int argc, char *argv[]);
|
||||
|
||||
|
||||
void *run_broker(void *args)
|
||||
{
|
||||
char *argv[4];
|
||||
@@ -64,6 +65,7 @@ void recv_timeout(int sock, void *buf, size_t len, int timeout_us)
|
||||
(void)recv(sock, buf, len, 0);
|
||||
}
|
||||
|
||||
|
||||
int connect_retrying(int port)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
@@ -91,6 +93,7 @@ int connect_retrying(int port)
|
||||
return sock;
|
||||
}
|
||||
|
||||
|
||||
static bool initialise(pthread_t *thread)
|
||||
{
|
||||
FILE *fptr;
|
||||
@@ -113,6 +116,7 @@ static bool initialise(pthread_t *thread)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void deinitialise(pthread_t *thread)
|
||||
{
|
||||
pthread_join(*thread, NULL);
|
||||
|
||||
@@ -17,6 +17,7 @@ Contributors:
|
||||
*/
|
||||
#include <mosquitto.h>
|
||||
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
mosquitto_pub_topic_check2((const char *)data, size);
|
||||
|
||||
@@ -17,6 +17,7 @@ Contributors:
|
||||
*/
|
||||
#include <mosquitto.h>
|
||||
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
mosquitto_sub_topic_check2((const char *)data, size);
|
||||
|
||||
@@ -19,6 +19,7 @@ Contributors:
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
char *buf;
|
||||
|
||||
@@ -17,6 +17,7 @@ Contributors:
|
||||
*/
|
||||
#include <mosquitto.h>
|
||||
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
mosquitto_validate_utf8((const char *)data, (int)size);
|
||||
|
||||
@@ -40,6 +40,7 @@ extern "C" {
|
||||
|
||||
extern struct mosquitto_db db;
|
||||
|
||||
|
||||
void run_dynsec(char *filename)
|
||||
{
|
||||
struct mosquitto_plugin_id_t identifier;
|
||||
@@ -63,6 +64,7 @@ void run_dynsec(char *filename)
|
||||
db.config = NULL;
|
||||
}
|
||||
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
char filename[100];
|
||||
@@ -72,7 +74,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
|
||||
snprintf(filename, sizeof(filename), "/tmp/dynsec%d.conf", getpid());
|
||||
fptr = fopen(filename, "wb");
|
||||
if(!fptr) return 1;
|
||||
if(!fptr){
|
||||
return 1;
|
||||
}
|
||||
fwrite(data, 1, size, fptr);
|
||||
fclose(fptr);
|
||||
|
||||
|
||||
@@ -88,76 +88,126 @@ mosqpp_EXPORT int property_check_all(int command, const mosquitto_property *prop
|
||||
* library. Please see mosquitto.h for details of the functions.
|
||||
*/
|
||||
class mosqpp_EXPORT mosquittopp {
|
||||
private:
|
||||
struct mosquitto *m_mosq;
|
||||
public:
|
||||
mosquittopp(const char *id=NULL, bool clean_session=true);
|
||||
virtual ~mosquittopp();
|
||||
private:
|
||||
struct mosquitto *m_mosq;
|
||||
public:
|
||||
mosquittopp(const char *id=NULL, bool clean_session=true);
|
||||
virtual ~mosquittopp();
|
||||
|
||||
int reinitialise(const char *id, bool clean_session);
|
||||
int socket();
|
||||
int will_set(const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false);
|
||||
int will_set_v5(const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false, mosquitto_property *properties=NULL);
|
||||
int will_clear();
|
||||
int username_pw_set(const char *username, const char *password=NULL);
|
||||
int connect(const char *host, int port=1883, int keepalive=60);
|
||||
int connect(const char *host, int port, int keepalive, const char *bind_address);
|
||||
int connect_v5(const char *host, int port, int keepalive, const char *bind_address, const mosquitto_property *properties);
|
||||
int connect_async(const char *host, int port=1883, int keepalive=60);
|
||||
int connect_async(const char *host, int port, int keepalive, const char *bind_address);
|
||||
int reconnect();
|
||||
int reconnect_async();
|
||||
int disconnect();
|
||||
int disconnect_v5(int reason_code, const mosquitto_property *properties);
|
||||
int publish(int *mid, const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false);
|
||||
int publish_v5(int *mid, const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false, const mosquitto_property *properties=NULL);
|
||||
int subscribe(int *mid, const char *sub, int qos=0);
|
||||
int subscribe_v5(int *mid, const char *sub, int qos=0, int options=0, const mosquitto_property *properties=NULL);
|
||||
int unsubscribe(int *mid, const char *sub);
|
||||
int unsubscribe_v5(int *mid, const char *sub, const mosquitto_property *properties);
|
||||
void reconnect_delay_set(unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff);
|
||||
int max_inflight_messages_set(unsigned int max_inflight_messages);
|
||||
void message_retry_set(unsigned int message_retry);
|
||||
void user_data_set(void *userdata);
|
||||
int tls_set(const char *cafile, const char *capath=NULL, const char *certfile=NULL, const char *keyfile=NULL, int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)=NULL);
|
||||
int ext_auth_continue(const char *auth_method, uint16_t auth_data_len=0, const void *auth_data=NULL, const mosquitto_property *properties=NULL);
|
||||
int tls_opts_set(int cert_reqs, const char *tls_version=NULL, const char *ciphers=NULL);
|
||||
int tls_insecure_set(bool value);
|
||||
int tls_psk_set(const char *psk, const char *identity, const char *ciphers=NULL);
|
||||
int opts_set(enum mosq_opt_t option, void *value);
|
||||
int int_option(enum mosq_opt_t option, int value);
|
||||
int string_option(enum mosq_opt_t option, const char *value);
|
||||
int void_option(enum mosq_opt_t option, void *value);
|
||||
int reinitialise(const char *id, bool clean_session);
|
||||
int socket();
|
||||
int will_set(const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false);
|
||||
int will_set_v5(const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false, mosquitto_property *properties=NULL);
|
||||
int will_clear();
|
||||
int username_pw_set(const char *username, const char *password=NULL);
|
||||
int connect(const char *host, int port=1883, int keepalive=60);
|
||||
int connect(const char *host, int port, int keepalive, const char *bind_address);
|
||||
int connect_v5(const char *host, int port, int keepalive, const char *bind_address, const mosquitto_property *properties);
|
||||
int connect_async(const char *host, int port=1883, int keepalive=60);
|
||||
int connect_async(const char *host, int port, int keepalive, const char *bind_address);
|
||||
int reconnect();
|
||||
int reconnect_async();
|
||||
int disconnect();
|
||||
int disconnect_v5(int reason_code, const mosquitto_property *properties);
|
||||
int publish(int *mid, const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false);
|
||||
int publish_v5(int *mid, const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false, const mosquitto_property *properties=NULL);
|
||||
int subscribe(int *mid, const char *sub, int qos=0);
|
||||
int subscribe_v5(int *mid, const char *sub, int qos=0, int options=0, const mosquitto_property *properties=NULL);
|
||||
int unsubscribe(int *mid, const char *sub);
|
||||
int unsubscribe_v5(int *mid, const char *sub, const mosquitto_property *properties);
|
||||
void reconnect_delay_set(unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff);
|
||||
int max_inflight_messages_set(unsigned int max_inflight_messages);
|
||||
void message_retry_set(unsigned int message_retry);
|
||||
void user_data_set(void *userdata);
|
||||
int tls_set(const char *cafile, const char *capath=NULL, const char *certfile=NULL, const char *keyfile=NULL, int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)=NULL);
|
||||
int ext_auth_continue(const char *auth_method, uint16_t auth_data_len=0, const void *auth_data=NULL, const mosquitto_property *properties=NULL);
|
||||
int tls_opts_set(int cert_reqs, const char *tls_version=NULL, const char *ciphers=NULL);
|
||||
int tls_insecure_set(bool value);
|
||||
int tls_psk_set(const char *psk, const char *identity, const char *ciphers=NULL);
|
||||
int opts_set(enum mosq_opt_t option, void *value);
|
||||
int int_option(enum mosq_opt_t option, int value);
|
||||
int string_option(enum mosq_opt_t option, const char *value);
|
||||
int void_option(enum mosq_opt_t option, void *value);
|
||||
|
||||
int loop(int timeout=-1, int max_packets=1);
|
||||
int loop_misc();
|
||||
int loop_read(int max_packets=1);
|
||||
int loop_write(int max_packets=1);
|
||||
int loop_forever(int timeout=-1, int max_packets=1);
|
||||
int loop_start();
|
||||
int loop_stop(bool force=false);
|
||||
bool want_write();
|
||||
int threaded_set(bool threaded=true);
|
||||
int socks5_set(const char *host, int port=1080, const char *username=NULL, const char *password=NULL);
|
||||
int loop(int timeout=-1, int max_packets=1);
|
||||
int loop_misc();
|
||||
int loop_read(int max_packets=1);
|
||||
int loop_write(int max_packets=1);
|
||||
int loop_forever(int timeout=-1, int max_packets=1);
|
||||
int loop_start();
|
||||
int loop_stop(bool force=false);
|
||||
bool want_write();
|
||||
int threaded_set(bool threaded=true);
|
||||
int socks5_set(const char *host, int port=1080, const char *username=NULL, const char *password=NULL);
|
||||
|
||||
// names in the functions commented to prevent unused parameter warning
|
||||
virtual void MOSQ_USED on_pre_connect() {return;}
|
||||
virtual void MOSQ_USED on_connect(int /*rc*/) {return;}
|
||||
virtual void MOSQ_USED on_connect_with_flags(int /*rc*/, int /*flags*/) {return;}
|
||||
virtual void MOSQ_USED on_connect_v5(int /*rc*/, int /*flags*/, const mosquitto_property * /*props*/) {return;}
|
||||
virtual void MOSQ_USED on_disconnect(int /*rc*/) {return;}
|
||||
virtual void MOSQ_USED on_disconnect_v5(int /*rc*/, const mosquitto_property * /*props*/) {return;}
|
||||
virtual void MOSQ_USED on_publish(int /*mid*/) {return;}
|
||||
virtual void MOSQ_USED on_publish_v5(int /*mid*/, int /*reason_code*/, const mosquitto_property * /*props*/) {return;}
|
||||
virtual void MOSQ_USED on_message(const struct mosquitto_message * /*message*/) {return;}
|
||||
virtual void MOSQ_USED on_message_v5(const struct mosquitto_message * /*message*/, const mosquitto_property * /*props*/) {return;}
|
||||
virtual void MOSQ_USED on_subscribe(int /*mid*/, int /*qos_count*/, const int * /*granted_qos*/) {return;}
|
||||
virtual void MOSQ_USED on_subscribe_v5(int /*mid*/, int /*qos_count*/, const int * /*granted_qos*/, const mosquitto_property * /*props*/) {return;}
|
||||
virtual void MOSQ_USED on_unsubscribe(int /*mid*/) {return;}
|
||||
virtual void MOSQ_USED on_unsubscribe_v5(int /*mid*/, const mosquitto_property * /*props*/) {return;}
|
||||
virtual void MOSQ_USED on_log(int /*level*/, const char * /*str*/) {return;}
|
||||
virtual void MOSQ_USED on_error() {return;}
|
||||
virtual int MOSQ_USED on_ext_auth(const char * /*auth_method*/, uint16_t /*auth_data_len*/, const void * /*auth_data*/, const mosquitto_property * /*props*/) {return MOSQ_ERR_AUTH;}
|
||||
|
||||
// names in the functions commented to prevent unused parameter warning
|
||||
virtual void MOSQ_USED on_pre_connect()
|
||||
{return;}
|
||||
|
||||
|
||||
virtual void MOSQ_USED on_connect(int /*rc*/)
|
||||
{return;}
|
||||
|
||||
|
||||
virtual void MOSQ_USED on_connect_with_flags(int /*rc*/, int /*flags*/)
|
||||
{return;}
|
||||
|
||||
|
||||
virtual void MOSQ_USED on_connect_v5(int /*rc*/, int /*flags*/, const mosquitto_property * /*props*/)
|
||||
{return;}
|
||||
|
||||
|
||||
virtual void MOSQ_USED on_disconnect(int /*rc*/)
|
||||
{return;}
|
||||
|
||||
|
||||
virtual void MOSQ_USED on_disconnect_v5(int /*rc*/, const mosquitto_property * /*props*/)
|
||||
{return;}
|
||||
|
||||
|
||||
virtual void MOSQ_USED on_publish(int /*mid*/)
|
||||
{return;}
|
||||
|
||||
|
||||
virtual void MOSQ_USED on_publish_v5(int /*mid*/, int /*reason_code*/, const mosquitto_property * /*props*/)
|
||||
{return;}
|
||||
|
||||
|
||||
virtual void MOSQ_USED on_message(const struct mosquitto_message * /*message*/)
|
||||
{return;}
|
||||
|
||||
|
||||
virtual void MOSQ_USED on_message_v5(const struct mosquitto_message * /*message*/, const mosquitto_property * /*props*/)
|
||||
{return;}
|
||||
|
||||
|
||||
virtual void MOSQ_USED on_subscribe(int /*mid*/, int /*qos_count*/, const int * /*granted_qos*/)
|
||||
{return;}
|
||||
|
||||
|
||||
virtual void MOSQ_USED on_subscribe_v5(int /*mid*/, int /*qos_count*/, const int * /*granted_qos*/, const mosquitto_property * /*props*/)
|
||||
{return;}
|
||||
|
||||
|
||||
virtual void MOSQ_USED on_unsubscribe(int /*mid*/)
|
||||
{return;}
|
||||
|
||||
|
||||
virtual void MOSQ_USED on_unsubscribe_v5(int /*mid*/, const mosquitto_property * /*props*/)
|
||||
{return;}
|
||||
|
||||
|
||||
virtual void MOSQ_USED on_log(int /*level*/, const char * /*str*/)
|
||||
{return;}
|
||||
|
||||
|
||||
virtual void MOSQ_USED on_error()
|
||||
{return;}
|
||||
|
||||
|
||||
virtual int MOSQ_USED on_ext_auth(const char * /*auth_method*/, uint16_t /*auth_data_len*/, const void * /*auth_data*/, const mosquitto_property * /*props*/)
|
||||
{return MOSQ_ERR_AUTH;}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,159 +21,170 @@ Copyright (c) 2022 Cedalo GmbH
|
||||
|
||||
namespace t = testing;
|
||||
|
||||
struct pending_payload{
|
||||
struct pending_payload {
|
||||
struct pending_payload *next, *prev;
|
||||
char payload[1024];
|
||||
};
|
||||
|
||||
class CtrlShellBrokerTest : public ::t::Test
|
||||
{
|
||||
public:
|
||||
::t::StrictMock<CtrlShellMock> ctrl_shell_mock_{};
|
||||
::t::StrictMock<EditLineMock> editline_mock_{};
|
||||
::t::StrictMock<LibMosquittoMock> libmosquitto_mock_{};
|
||||
::t::StrictMock<PThreadMock> pthread_mock_{};
|
||||
LIBMOSQ_CB_connect on_connect{};
|
||||
LIBMOSQ_CB_message on_message{};
|
||||
LIBMOSQ_CB_subscribe on_subscribe{};
|
||||
LIBMOSQ_CB_publish_v5 on_publish{};
|
||||
struct pending_payload *pending_payloads = nullptr;
|
||||
public:
|
||||
::t::StrictMock<CtrlShellMock> ctrl_shell_mock_{};
|
||||
::t::StrictMock<EditLineMock> editline_mock_{};
|
||||
::t::StrictMock<LibMosquittoMock> libmosquitto_mock_{};
|
||||
::t::StrictMock<PThreadMock> pthread_mock_{};
|
||||
LIBMOSQ_CB_connect on_connect{};
|
||||
LIBMOSQ_CB_message on_message{};
|
||||
LIBMOSQ_CB_subscribe on_subscribe{};
|
||||
LIBMOSQ_CB_publish_v5 on_publish{};
|
||||
struct pending_payload *pending_payloads = nullptr;
|
||||
|
||||
void expect_setup(struct mosq_config *config)
|
||||
{
|
||||
editline_mock_.reset();
|
||||
EXPECT_CALL(editline_mock_, rl_bind_key(t::Eq('\t'), t::_));
|
||||
EXPECT_CALL(editline_mock_, add_history(t::_)).WillRepeatedly(t::Return(0));
|
||||
EXPECT_CALL(editline_mock_, clear_history()).Times(t::AnyNumber());
|
||||
config->no_colour = true;
|
||||
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StartsWith("mosquitto_ctrl shell v")));
|
||||
void expect_setup(struct mosq_config *config)
|
||||
{
|
||||
editline_mock_.reset();
|
||||
EXPECT_CALL(editline_mock_, rl_bind_key(t::Eq('\t'), t::_));
|
||||
EXPECT_CALL(editline_mock_, add_history(t::_)).WillRepeatedly(t::Return(0));
|
||||
EXPECT_CALL(editline_mock_, clear_history()).Times(t::AnyNumber());
|
||||
config->no_colour = true;
|
||||
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StartsWith("mosquitto_ctrl shell v")));
|
||||
}
|
||||
|
||||
|
||||
void expect_connect(struct mosquitto *mosq, const char *host, int port)
|
||||
{
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_new(t::Eq(nullptr), t::Eq(true), t::Eq(nullptr)))
|
||||
.WillOnce(t::Return(mosq));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_int_option(t::Eq(mosq), MOSQ_OPT_PROTOCOL_VERSION, 5));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_subscribe_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_subscribe>()))
|
||||
.WillRepeatedly(t::SaveArg<1>(&this->on_subscribe));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish_v5_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_publish_v5>()))
|
||||
.WillRepeatedly(t::SaveArg<1>(&this->on_publish));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_connect(t::Eq(mosq), t::StrEq(host), port, 60));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_loop_start(t::Eq(mosq)));
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_connect_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_connect>()))
|
||||
.WillRepeatedly(t::SaveArg<1>(&this->on_connect));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_message_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_message>()))
|
||||
.WillOnce(t::SaveArg<1>(&this->on_message));
|
||||
}
|
||||
|
||||
|
||||
void expect_disconnect(struct mosquitto *mosq)
|
||||
{
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_disconnect(t::Eq(mosq)));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_loop_stop(t::Eq(mosq), false));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_destroy(t::Eq(mosq)));
|
||||
}
|
||||
|
||||
|
||||
void expect_outputs(const char **outputs, size_t count)
|
||||
{
|
||||
for(size_t i=0; i<count; i++){
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StrEq(outputs[i]))).Times(t::AtLeast(1));
|
||||
}
|
||||
}
|
||||
|
||||
void expect_connect(struct mosquitto *mosq, const char *host, int port)
|
||||
{
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_new(t::Eq(nullptr), t::Eq(true), t::Eq(nullptr)))
|
||||
.WillOnce(t::Return(mosq));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_int_option(t::Eq(mosq), MOSQ_OPT_PROTOCOL_VERSION, 5));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_subscribe_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_subscribe>()))
|
||||
.WillRepeatedly(t::SaveArg<1>(&this->on_subscribe));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish_v5_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_publish_v5>()))
|
||||
.WillRepeatedly(t::SaveArg<1>(&this->on_publish));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_connect(t::Eq(mosq), t::StrEq(host), port, 60));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_loop_start(t::Eq(mosq)));
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_connect_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_connect>()))
|
||||
.WillRepeatedly(t::SaveArg<1>(&this->on_connect));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_message_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_message>()))
|
||||
.WillOnce(t::SaveArg<1>(&this->on_message));
|
||||
}
|
||||
void expect_request_response(struct mosquitto *mosq, const char *request, const char *respons)
|
||||
{
|
||||
struct pending_payload *pp = (struct pending_payload *)calloc(1, sizeof(struct pending_payload));
|
||||
snprintf(pp->payload, sizeof(pp->payload), "%s", respons);
|
||||
|
||||
void expect_disconnect(struct mosquitto *mosq)
|
||||
{
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_disconnect(t::Eq(mosq)));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_loop_stop(t::Eq(mosq), false));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_destroy(t::Eq(mosq)));
|
||||
}
|
||||
|
||||
void expect_outputs(const char **outputs, size_t count)
|
||||
{
|
||||
for(size_t i=0; i<count; i++){
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StrEq(outputs[i]))).Times(t::AtLeast(1));
|
||||
}
|
||||
}
|
||||
|
||||
void expect_request_response(struct mosquitto *mosq, const char *request, const char *respons)
|
||||
{
|
||||
struct pending_payload *pp = (struct pending_payload *)calloc(1, sizeof(struct pending_payload));
|
||||
snprintf(pp->payload, sizeof(pp->payload), "%s", respons);
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish(t::Eq(mosq), nullptr, t::StrEq("$CONTROL/broker/v1"), t::_,
|
||||
t::StrEq(request), 1, false))
|
||||
.WillOnce(t::Invoke([this, pp](){
|
||||
DL_APPEND(this->pending_payloads, pp);
|
||||
return 0;
|
||||
}));
|
||||
}
|
||||
|
||||
void expect_request_response_success(struct mosquitto *mosq, const char *request, const char *command)
|
||||
{
|
||||
char response[100];
|
||||
snprintf(response, sizeof(response), "{\"responses\":[{\"command\":\"%s\"}]}", command);
|
||||
expect_request_response(mosq, request, response);
|
||||
}
|
||||
|
||||
void expect_request_response_empty(struct mosquitto *mosq, const char *command)
|
||||
{
|
||||
char request[100];
|
||||
char response[100];
|
||||
|
||||
snprintf(request, sizeof(request), "{\"commands\":[{\"command\":\"%s\"}]}", command);
|
||||
snprintf(response, sizeof(response), "{\"responses\":[{\"command\":\"%s\",\"data\":{}}]}", command);
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish(t::Eq(mosq), nullptr, t::StrEq("$CONTROL/broker/v1"), t::_,
|
||||
t::StrEq(request), 1, false))
|
||||
.WillOnce(t::Invoke([this, &command](){
|
||||
append_empty_response(command);
|
||||
return 0;
|
||||
}));
|
||||
}
|
||||
|
||||
void append_response(const char *response)
|
||||
{
|
||||
struct pending_payload *pp = (struct pending_payload *)calloc(1, sizeof(struct pending_payload));
|
||||
snprintf(pp->payload, sizeof(pp->payload), "%s", response);
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish(t::Eq(mosq), nullptr, t::StrEq("$CONTROL/broker/v1"), t::_,
|
||||
t::StrEq(request), 1, false))
|
||||
.WillOnce(t::Invoke([this, pp](){
|
||||
DL_APPEND(this->pending_payloads, pp);
|
||||
}
|
||||
return 0;
|
||||
}));
|
||||
}
|
||||
|
||||
void append_empty_response(const char *command)
|
||||
{
|
||||
struct pending_payload *pp = (struct pending_payload *)calloc(1, sizeof(struct pending_payload));
|
||||
snprintf(pp->payload, sizeof(pp->payload),
|
||||
|
||||
void expect_request_response_success(struct mosquitto *mosq, const char *request, const char *command)
|
||||
{
|
||||
char response[100];
|
||||
snprintf(response, sizeof(response), "{\"responses\":[{\"command\":\"%s\"}]}", command);
|
||||
expect_request_response(mosq, request, response);
|
||||
}
|
||||
|
||||
|
||||
void expect_request_response_empty(struct mosquitto *mosq, const char *command)
|
||||
{
|
||||
char request[100];
|
||||
char response[100];
|
||||
|
||||
snprintf(request, sizeof(request), "{\"commands\":[{\"command\":\"%s\"}]}", command);
|
||||
snprintf(response, sizeof(response), "{\"responses\":[{\"command\":\"%s\",\"data\":{}}]}", command);
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish(t::Eq(mosq), nullptr, t::StrEq("$CONTROL/broker/v1"), t::_,
|
||||
t::StrEq(request), 1, false))
|
||||
.WillOnce(t::Invoke([this, &command](){
|
||||
append_empty_response(command);
|
||||
return 0;
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
void append_response(const char *response)
|
||||
{
|
||||
struct pending_payload *pp = (struct pending_payload *)calloc(1, sizeof(struct pending_payload));
|
||||
snprintf(pp->payload, sizeof(pp->payload), "%s", response);
|
||||
DL_APPEND(this->pending_payloads, pp);
|
||||
}
|
||||
|
||||
|
||||
void append_empty_response(const char *command)
|
||||
{
|
||||
struct pending_payload *pp = (struct pending_payload *)calloc(1, sizeof(struct pending_payload));
|
||||
snprintf(pp->payload, sizeof(pp->payload),
|
||||
"{\"responses\":[{\"command\":\"%s\",\"data\":{}}]}", command);
|
||||
DL_APPEND(this->pending_payloads, pp);
|
||||
}
|
||||
DL_APPEND(this->pending_payloads, pp);
|
||||
}
|
||||
|
||||
void expect_broker(const char *host, int port)
|
||||
{
|
||||
char buf[200];
|
||||
snprintf(buf, sizeof(buf), "connect mqtt://%s:%d", host, port);
|
||||
char *s_conn = strdup(buf);
|
||||
|
||||
EXPECT_CALL(editline_mock_, readline(t::StrEq("> ")))
|
||||
.WillOnce(t::Return(s_conn));
|
||||
void expect_broker(const char *host, int port)
|
||||
{
|
||||
char buf[200];
|
||||
snprintf(buf, sizeof(buf), "connect mqtt://%s:%d", host, port);
|
||||
char *s_conn = strdup(buf);
|
||||
|
||||
EXPECT_CALL(editline_mock_, readline(t::StrEq("mqtt://localhost:1883> ")))
|
||||
.WillOnce(t::Return(strdup("broker")));
|
||||
EXPECT_CALL(editline_mock_, readline(t::StrEq("> ")))
|
||||
.WillOnce(t::Return(s_conn));
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_subscribe(t::_, nullptr, t::StrEq("$CONTROL/broker/v1/response"), 1))
|
||||
.WillOnce(t::Return(0));
|
||||
}
|
||||
EXPECT_CALL(editline_mock_, readline(t::StrEq("mqtt://localhost:1883> ")))
|
||||
.WillOnce(t::Return(strdup("broker")));
|
||||
|
||||
void expect_connect_and_messages(struct mosquitto *mosq)
|
||||
{
|
||||
/* This is a hacky way of working around the async mqtt send/receive which we don't directly control.
|
||||
* Each send starts a wait which times out after two seconds. We use that call to produce the effect we want.
|
||||
*/
|
||||
EXPECT_CALL(pthread_mock_, pthread_cond_timedwait(t::_, t::_, t::_))
|
||||
.WillOnce(t::Invoke([this, mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
this->on_connect(mosq, nullptr, 0);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}))
|
||||
.WillRepeatedly(t::Invoke([this, mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
mosquitto_message msg{};
|
||||
struct pending_payload *pp = pending_payloads;
|
||||
if(pp){
|
||||
DL_DELETE(pending_payloads, pp);
|
||||
msg.payload = pp->payload;
|
||||
msg.payloadlen = (int)strlen((char *)msg.payload);
|
||||
this->on_message(mosq, nullptr, &msg);
|
||||
free(pp);
|
||||
}
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}));
|
||||
}
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_subscribe(t::_, nullptr, t::StrEq("$CONTROL/broker/v1/response"), 1))
|
||||
.WillOnce(t::Return(0));
|
||||
}
|
||||
|
||||
|
||||
void expect_connect_and_messages(struct mosquitto *mosq)
|
||||
{
|
||||
/* This is a hacky way of working around the async mqtt send/receive which we don't directly control.
|
||||
* Each send starts a wait which times out after two seconds. We use that call to produce the effect we want.
|
||||
*/
|
||||
EXPECT_CALL(pthread_mock_, pthread_cond_timedwait(t::_, t::_, t::_))
|
||||
.WillOnce(t::Invoke([this, mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
this->on_connect(mosq, nullptr, 0);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}))
|
||||
.WillRepeatedly(t::Invoke([this, mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
mosquitto_message msg{};
|
||||
struct pending_payload *pp = pending_payloads;
|
||||
if(pp){
|
||||
DL_DELETE(pending_payloads, pp);
|
||||
msg.payload = pp->payload;
|
||||
msg.payloadlen = (int)strlen((char *)msg.payload);
|
||||
this->on_message(mosq, nullptr, &msg);
|
||||
free(pp);
|
||||
}
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -229,29 +240,29 @@ TEST_F(CtrlShellBrokerTest, SubscribeDenied)
|
||||
|
||||
EXPECT_CALL(pthread_mock_, pthread_cond_timedwait(t::_, t::_, t::_))
|
||||
.WillOnce(t::Invoke([this, &mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
this->on_connect(&mosq, nullptr, 0);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}))
|
||||
this->on_connect(&mosq, nullptr, 0);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}))
|
||||
.WillOnce(t::Invoke([this, &mosq](){
|
||||
int granted_qos[1] = {128};
|
||||
this->on_subscribe(&mosq, nullptr, 1, 1, granted_qos);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}))
|
||||
int granted_qos[1] = {128};
|
||||
this->on_subscribe(&mosq, nullptr, 1, 1, granted_qos);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}))
|
||||
.WillRepeatedly(t::Invoke([this, &mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
mosquitto_message msg{};
|
||||
struct pending_payload *pp = pending_payloads;
|
||||
if(pp){
|
||||
DL_DELETE(pending_payloads, pp);
|
||||
msg.payload = pp->payload;
|
||||
msg.payloadlen = (int)strlen((char *)msg.payload);
|
||||
this->on_message(&mosq, nullptr, &msg);
|
||||
free(pp);
|
||||
}
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}));
|
||||
mosquitto_message msg{};
|
||||
struct pending_payload *pp = pending_payloads;
|
||||
if(pp){
|
||||
DL_DELETE(pending_payloads, pp);
|
||||
msg.payload = pp->payload;
|
||||
msg.payloadlen = (int)strlen((char *)msg.payload);
|
||||
this->on_message(&mosq, nullptr, &msg);
|
||||
free(pp);
|
||||
}
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}));
|
||||
|
||||
const char *outputs[] = {
|
||||
"Subscribe failed, check you have permission to access this module.\n",
|
||||
@@ -291,24 +302,24 @@ TEST_F(CtrlShellBrokerTest, PublishDenied)
|
||||
|
||||
EXPECT_CALL(pthread_mock_, pthread_cond_timedwait(t::_, t::_, t::_))
|
||||
.WillOnce(t::Invoke([this, &mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
this->on_connect(&mosq, nullptr, 0);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}))
|
||||
this->on_connect(&mosq, nullptr, 0);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}))
|
||||
.WillOnce(t::Invoke([this, &mosq](){
|
||||
int granted_qos[1] = {1};
|
||||
this->on_subscribe(&mosq, nullptr, 1, 1, granted_qos);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}))
|
||||
int granted_qos[1] = {1};
|
||||
this->on_subscribe(&mosq, nullptr, 1, 1, granted_qos);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}))
|
||||
.WillOnce(t::Invoke([this, &mosq](){
|
||||
this->on_publish(&mosq, nullptr, 1, 128, nullptr);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}));
|
||||
this->on_publish(&mosq, nullptr, 1, 128, nullptr);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}));
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish(t::Eq(&mosq), nullptr, t::StrEq("$CONTROL/broker/v1"), t::_,
|
||||
t::StrEq("{\"commands\":[{\"command\":\"listListeners\"}]}"), 1, false));
|
||||
t::StrEq("{\"commands\":[{\"command\":\"listListeners\"}]}"), 1, false));
|
||||
|
||||
const char *outputs[] = {
|
||||
"Publish failed, check you have permission to access this module.\n",
|
||||
@@ -339,9 +350,9 @@ TEST_F(CtrlShellBrokerTest, ListListeners)
|
||||
|
||||
const char request[] = "{\"commands\":[{\"command\":\"listListeners\"}]}";
|
||||
const char response[] = "{\"responses\":[{\"command\":\"listListeners\",\"data\":{"
|
||||
"\"listeners\":["
|
||||
"{\"port\":1883,\"protocol\":\"mqtt\",\"tls\":false}"
|
||||
"]}}]}";
|
||||
"\"listeners\":["
|
||||
"{\"port\":1883,\"protocol\":\"mqtt\",\"tls\":false}"
|
||||
"]}}]}";
|
||||
expect_request_response(&mosq, request, response);
|
||||
|
||||
const char *outputs[] = {
|
||||
@@ -379,9 +390,9 @@ TEST_F(CtrlShellBrokerTest, ListListenersInvalidResponse)
|
||||
|
||||
const char request[] = "{\"commands\":[{\"command\":\"listListeners\"}]}";
|
||||
const char response[] = "{\"responses\":[{\"command\":\"listListeners\",\"data\":{"
|
||||
"\"listeners\":["
|
||||
"{\"protocol\":\"mqtt\",\"tls\":false}"
|
||||
"]}}]}";
|
||||
"\"listeners\":["
|
||||
"{\"protocol\":\"mqtt\",\"tls\":false}"
|
||||
"]}}]}";
|
||||
expect_request_response(&mosq, request, response);
|
||||
|
||||
const char *outputs[] = {
|
||||
@@ -413,9 +424,9 @@ TEST_F(CtrlShellBrokerTest, ListPlugins)
|
||||
|
||||
const char request[] = "{\"commands\":[{\"command\":\"listPlugins\"}]}";
|
||||
const char response[] = "{\"responses\":[{\"command\":\"listPlugins\",\"data\":{"
|
||||
"\"plugins\":["
|
||||
"{\"name\":\"plugin1\",\"control-endpoints\":[\"$CONTROL/plugin1\"]}"
|
||||
"]}}]}";
|
||||
"\"plugins\":["
|
||||
"{\"name\":\"plugin1\",\"control-endpoints\":[\"$CONTROL/plugin1\"]}"
|
||||
"]}}]}";
|
||||
expect_request_response(&mosq, request, response);
|
||||
|
||||
const char *outputs[] = {
|
||||
@@ -450,9 +461,9 @@ TEST_F(CtrlShellBrokerTest, ListPluginsInvalidResponse)
|
||||
|
||||
const char request[] = "{\"commands\":[{\"command\":\"listPlugins\"}]}";
|
||||
const char response[] = "{\"responses\":[{\"command\":\"listPlugins\",\"data\":{"
|
||||
"\"plugins\":["
|
||||
"{\"control-endpoints\":[\"$CONTROL/plugin1\"]}"
|
||||
"]}}]}";
|
||||
"\"plugins\":["
|
||||
"{\"control-endpoints\":[\"$CONTROL/plugin1\"]}"
|
||||
"]}}]}";
|
||||
expect_request_response(&mosq, request, response);
|
||||
|
||||
const char *outputs[] = {
|
||||
|
||||
@@ -19,47 +19,49 @@ Copyright (c) 2022 Cedalo GmbH
|
||||
#include "pthread_mock.hpp"
|
||||
|
||||
extern "C" {
|
||||
char **completion_matcher(const char *text, int start, int end);
|
||||
char *completion_generator(const char *text, int state);
|
||||
void ctrl_shell__cleanup(void);
|
||||
char **completion_matcher(const char *text, int start, int end);
|
||||
char *completion_generator(const char *text, int state);
|
||||
void ctrl_shell__cleanup(void);
|
||||
}
|
||||
|
||||
namespace t = testing;
|
||||
|
||||
class CtrlShellCompletionTest : public ::t::Test
|
||||
{
|
||||
public:
|
||||
::t::StrictMock<CtrlShellMock> ctrl_shell_mock_{};
|
||||
::t::StrictMock<LibMosquittoMock> libmosquitto_mock_{};
|
||||
::t::StrictMock<PThreadMock> pthread_mock_{};
|
||||
public:
|
||||
::t::StrictMock<CtrlShellMock> ctrl_shell_mock_{};
|
||||
::t::StrictMock<LibMosquittoMock> libmosquitto_mock_{};
|
||||
::t::StrictMock<PThreadMock> pthread_mock_{};
|
||||
|
||||
void expect_setup()
|
||||
{
|
||||
EXPECT_CALL(pthread_mock_, pthread_cond_timedwait(t::_, t::_, t::_))
|
||||
.WillRepeatedly(t::Invoke([](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}));
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_subscribe(t::_, t::_, t::_, 1))
|
||||
.WillRepeatedly(t::Return(0));
|
||||
void expect_setup()
|
||||
{
|
||||
EXPECT_CALL(pthread_mock_, pthread_cond_timedwait(t::_, t::_, t::_))
|
||||
.WillRepeatedly(t::Invoke([](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}));
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish(t::_, nullptr, t::_, t::_, t::_, 1, false))
|
||||
.WillRepeatedly(t::Return(0));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_subscribe(t::_, t::_, t::_, 1))
|
||||
.WillRepeatedly(t::Return(0));
|
||||
|
||||
rl_readline_name = "mosquitto_ctrl";
|
||||
rl_completion_entry_function = completion_generator;
|
||||
rl_attempted_completion_function = completion_matcher;
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish(t::_, nullptr, t::_, t::_, t::_, 1, false))
|
||||
.WillRepeatedly(t::Return(0));
|
||||
|
||||
ctrl_shell__load_module(ctrl_shell__dynsec_init);
|
||||
}
|
||||
|
||||
void expect_outputs(const char **outputs, size_t count)
|
||||
{
|
||||
for(size_t i=0; i<count; i++){
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StrEq(outputs[i]))).Times(t::AtLeast(1));
|
||||
}
|
||||
rl_readline_name = "mosquitto_ctrl";
|
||||
rl_completion_entry_function = completion_generator;
|
||||
rl_attempted_completion_function = completion_matcher;
|
||||
|
||||
ctrl_shell__load_module(ctrl_shell__dynsec_init);
|
||||
}
|
||||
|
||||
|
||||
void expect_outputs(const char **outputs, size_t count)
|
||||
{
|
||||
for(size_t i=0; i<count; i++){
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StrEq(outputs[i]))).Times(t::AtLeast(1));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(CtrlShellCompletionTest, NoMatch)
|
||||
@@ -84,17 +86,19 @@ TEST_F(CtrlShellCompletionTest, MatchArg1)
|
||||
ASSERT_NE(matches, nullptr);
|
||||
|
||||
EXPECT_STREQ(matches[0], "add");
|
||||
for(match_count = 1; matches[match_count]; match_count++);
|
||||
for(match_count = 1; matches[match_count]; match_count++){
|
||||
;
|
||||
}
|
||||
ASSERT_EQ(match_count, 5);
|
||||
|
||||
char *match_array[4] = {matches[1], matches[2], matches[3], matches[4]};
|
||||
|
||||
EXPECT_THAT(match_array, t::UnorderedElementsAreArray({
|
||||
t::StrEq("addGroupRole"),
|
||||
t::StrEq("addRoleACL"),
|
||||
t::StrEq("addGroupClient"),
|
||||
t::StrEq("addClientRole")
|
||||
}));
|
||||
t::StrEq("addGroupRole"),
|
||||
t::StrEq("addRoleACL"),
|
||||
t::StrEq("addGroupClient"),
|
||||
t::StrEq("addClientRole")
|
||||
}));
|
||||
for(int i=0; i<match_count; i++){
|
||||
free(matches[i]);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,54 +22,58 @@ namespace t = testing;
|
||||
|
||||
class CtrlShellHelpTest : public ::t::Test
|
||||
{
|
||||
public:
|
||||
::t::StrictMock<CtrlShellMock> ctrl_shell_mock_{};
|
||||
::t::StrictMock<EditLineMock> editline_mock_{};
|
||||
::t::StrictMock<LibMosquittoMock> libmosquitto_mock_{};
|
||||
::t::StrictMock<PThreadMock> pthread_mock_{};
|
||||
LIBMOSQ_CB_connect on_connect{};
|
||||
LIBMOSQ_CB_message on_message{};
|
||||
public:
|
||||
::t::StrictMock<CtrlShellMock> ctrl_shell_mock_{};
|
||||
::t::StrictMock<EditLineMock> editline_mock_{};
|
||||
::t::StrictMock<LibMosquittoMock> libmosquitto_mock_{};
|
||||
::t::StrictMock<PThreadMock> pthread_mock_{};
|
||||
LIBMOSQ_CB_connect on_connect{};
|
||||
LIBMOSQ_CB_message on_message{};
|
||||
|
||||
void expect_setup(struct mosq_config *config)
|
||||
{
|
||||
editline_mock_.reset();
|
||||
EXPECT_CALL(editline_mock_, rl_bind_key(t::Eq('\t'), t::_));
|
||||
EXPECT_CALL(editline_mock_, add_history(t::_)).WillRepeatedly(t::Return(0));
|
||||
EXPECT_CALL(editline_mock_, clear_history()).Times(t::AnyNumber());
|
||||
config->no_colour = true;
|
||||
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StartsWith("mosquitto_ctrl shell v")));
|
||||
}
|
||||
|
||||
void expect_connect(struct mosquitto *mosq, const char *host, int port)
|
||||
{
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_new(t::Eq(nullptr), t::Eq(true), t::Eq(nullptr)))
|
||||
.WillOnce(t::Return(mosq));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_int_option(t::Eq(mosq), MOSQ_OPT_PROTOCOL_VERSION, 5));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_subscribe_callback_set(t::Eq(mosq), t::_));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish_v5_callback_set(t::Eq(mosq), t::_));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_connect(t::Eq(mosq), t::StrEq(host), port, 60));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_loop_start(t::Eq(mosq)));
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_connect_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_connect>()))
|
||||
.WillRepeatedly(t::SaveArg<1>(&this->on_connect));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_message_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_message>()))
|
||||
.WillOnce(t::SaveArg<1>(&this->on_message));
|
||||
}
|
||||
|
||||
void expect_disconnect(struct mosquitto *mosq)
|
||||
{
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_disconnect(t::Eq(mosq)));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_loop_stop(t::Eq(mosq), false));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_destroy(t::Eq(mosq)));
|
||||
}
|
||||
|
||||
void expect_outputs(const char **outputs, size_t count)
|
||||
{
|
||||
for(size_t i=0; i<count; i++){
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StrEq(outputs[i]))).Times(t::AtLeast(1));
|
||||
}
|
||||
void expect_setup(struct mosq_config *config)
|
||||
{
|
||||
editline_mock_.reset();
|
||||
EXPECT_CALL(editline_mock_, rl_bind_key(t::Eq('\t'), t::_));
|
||||
EXPECT_CALL(editline_mock_, add_history(t::_)).WillRepeatedly(t::Return(0));
|
||||
EXPECT_CALL(editline_mock_, clear_history()).Times(t::AnyNumber());
|
||||
config->no_colour = true;
|
||||
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StartsWith("mosquitto_ctrl shell v")));
|
||||
}
|
||||
|
||||
|
||||
void expect_connect(struct mosquitto *mosq, const char *host, int port)
|
||||
{
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_new(t::Eq(nullptr), t::Eq(true), t::Eq(nullptr)))
|
||||
.WillOnce(t::Return(mosq));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_int_option(t::Eq(mosq), MOSQ_OPT_PROTOCOL_VERSION, 5));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_subscribe_callback_set(t::Eq(mosq), t::_));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish_v5_callback_set(t::Eq(mosq), t::_));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_connect(t::Eq(mosq), t::StrEq(host), port, 60));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_loop_start(t::Eq(mosq)));
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_connect_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_connect>()))
|
||||
.WillRepeatedly(t::SaveArg<1>(&this->on_connect));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_message_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_message>()))
|
||||
.WillOnce(t::SaveArg<1>(&this->on_message));
|
||||
}
|
||||
|
||||
|
||||
void expect_disconnect(struct mosquitto *mosq)
|
||||
{
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_disconnect(t::Eq(mosq)));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_loop_stop(t::Eq(mosq), false));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_destroy(t::Eq(mosq)));
|
||||
}
|
||||
|
||||
|
||||
void expect_outputs(const char **outputs, size_t count)
|
||||
{
|
||||
for(size_t i=0; i<count; i++){
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StrEq(outputs[i]))).Times(t::AtLeast(1));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(CtrlShellHelpTest, PreConnectHelp)
|
||||
@@ -103,19 +107,19 @@ TEST_F(CtrlShellHelpTest, PreConnectHelp)
|
||||
"OK\n\n",
|
||||
|
||||
"auth [username]\n",
|
||||
"\nSet a username and password prior to connecting to a broker.\n", /* help auth */
|
||||
"\nSet a username and password prior to connecting to a broker.\n", /* help auth */
|
||||
"connect\n",
|
||||
"connect mqtt://hostname[:port]\n",
|
||||
"connect mqtts://hostname[:port]\n",
|
||||
"connect ws://hostname[:port]\n",
|
||||
"connect wss://hostname[:port]\n",
|
||||
"\nConnect to a broker using the provided transport and port.\n",
|
||||
"If no URL is provided, connects to mqtt://localhost:1883\n", /* help connect */
|
||||
"connect mqtt://hostname[:port]\n",
|
||||
"connect mqtts://hostname[:port]\n",
|
||||
"connect ws://hostname[:port]\n",
|
||||
"connect wss://hostname[:port]\n",
|
||||
"\nConnect to a broker using the provided transport and port.\n",
|
||||
"If no URL is provided, connects to mqtt://localhost:1883\n", /* help connect */
|
||||
"exit\n",
|
||||
"\nQuit the program\n", /* help exit */
|
||||
"\nQuit the program\n", /* help exit */
|
||||
"help <command>\n",
|
||||
"\nFind help on a command using 'help <command>'\n",
|
||||
"Press tab multiple times to find currently available commands.\n", /* help help */
|
||||
"\nFind help on a command using 'help <command>'\n",
|
||||
"Press tab multiple times to find currently available commands.\n", /* help help */
|
||||
"Unknown command 'unknown'\n", /* help unknown */
|
||||
};
|
||||
expect_outputs(outputs, sizeof(outputs)/sizeof(char *));
|
||||
@@ -161,10 +165,10 @@ TEST_F(CtrlShellHelpTest, Connect)
|
||||
/* This is a hacky way of working around the async mqtt CONNECT/CONNACK which we don't directly control. */
|
||||
EXPECT_CALL(pthread_mock_, pthread_cond_timedwait(t::_, t::_, t::_))
|
||||
.WillOnce(t::Invoke([this, &mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
this->on_connect(&mosq, nullptr, 0);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}));
|
||||
this->on_connect(&mosq, nullptr, 0);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}));
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StrEq("\n")));
|
||||
|
||||
ctrl_shell__main(&config);
|
||||
@@ -205,10 +209,10 @@ TEST_F(CtrlShellHelpTest, PostConnectHelp)
|
||||
*/
|
||||
EXPECT_CALL(pthread_mock_, pthread_cond_timedwait(t::_, t::_, t::_))
|
||||
.WillOnce(t::Invoke([this, &mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
this->on_connect(&mosq, nullptr, 0);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}));
|
||||
this->on_connect(&mosq, nullptr, 0);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}));
|
||||
|
||||
const char *outputs[] = {
|
||||
"This is the mosquitto_ctrl interactive shell, for controlling aspects of a mosquitto broker.\n",
|
||||
@@ -225,16 +229,16 @@ TEST_F(CtrlShellHelpTest, PostConnectHelp)
|
||||
"\n",
|
||||
|
||||
"dynsec\n",
|
||||
"\nStart the dynamic-security control mode.\n", /* help dynsec */
|
||||
"\nStart the dynamic-security control mode.\n", /* help dynsec */
|
||||
"broker\n",
|
||||
"\nStart the broker control mode.\n", /* help broker */
|
||||
"\nStart the broker control mode.\n", /* help broker */
|
||||
"disconnect\n",
|
||||
"\nDisconnect from the broker\n", /* help disconnect */
|
||||
"\nDisconnect from the broker\n", /* help disconnect */
|
||||
"exit\n",
|
||||
"\nQuit the program\n", /* help exit */
|
||||
"\nQuit the program\n", /* help exit */
|
||||
"help <command>\n",
|
||||
"\nFind help on a command using 'help <command>'\n",
|
||||
"Press tab multiple times to find currently available commands.\n", /* help help */
|
||||
"\nFind help on a command using 'help <command>'\n",
|
||||
"Press tab multiple times to find currently available commands.\n", /* help help */
|
||||
"Unknown command 'unknown'\n", /* help unknown */
|
||||
};
|
||||
expect_outputs(outputs, sizeof(outputs)/sizeof(char *));
|
||||
@@ -286,16 +290,16 @@ TEST_F(CtrlShellHelpTest, BrokerHelp)
|
||||
*/
|
||||
EXPECT_CALL(pthread_mock_, pthread_cond_timedwait(t::_, t::_, t::_))
|
||||
.WillOnce(t::Invoke([this, &mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
this->on_connect(&mosq, nullptr, 0);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}))
|
||||
this->on_connect(&mosq, nullptr, 0);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}))
|
||||
.WillOnce(t::Invoke([this, &mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
mosquitto_message msg{};
|
||||
this->on_message(&mosq, nullptr, &msg);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}));
|
||||
mosquitto_message msg{};
|
||||
this->on_message(&mosq, nullptr, &msg);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}));
|
||||
|
||||
const char *outputs[] = {
|
||||
"This is the mosquitto_ctrl interactive shell, for controlling aspects of a mosquitto broker.\n",
|
||||
@@ -307,18 +311,18 @@ TEST_F(CtrlShellHelpTest, BrokerHelp)
|
||||
"Unknown command 'unknown'\n",
|
||||
|
||||
"listPlugins\n",
|
||||
"\nLists currently loaded plugins.\n",
|
||||
"\nLists currently loaded plugins.\n",
|
||||
"listListeners\n",
|
||||
"\nLists current listeners.\n",
|
||||
"\nLists current listeners.\n",
|
||||
"disconnect\n",
|
||||
"\nDisconnect from the broker\n", /* help disconnect */
|
||||
"\nDisconnect from the broker\n", /* help disconnect */
|
||||
"return\n",
|
||||
"\nLeave broker mode.\n",
|
||||
"\nLeave broker mode.\n",
|
||||
"exit\n",
|
||||
"\nQuit the program\n", /* help exit */
|
||||
"\nQuit the program\n", /* help exit */
|
||||
"help <command>\n",
|
||||
"\nFind help on a command using 'help <command>'\n",
|
||||
"Press tab multiple times to find currently available commands.\n", /* help help */
|
||||
"\nFind help on a command using 'help <command>'\n",
|
||||
"Press tab multiple times to find currently available commands.\n", /* help help */
|
||||
"Invalid response from broker.\n",
|
||||
};
|
||||
expect_outputs(outputs, sizeof(outputs)/sizeof(char *));
|
||||
@@ -399,39 +403,47 @@ TEST_F(CtrlShellHelpTest, DynsecHelp)
|
||||
*/
|
||||
EXPECT_CALL(pthread_mock_, pthread_cond_timedwait(t::_, t::_, t::_))
|
||||
.WillOnce(t::Invoke([this, &mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
this->on_connect(&mosq, nullptr, 0); data.response_received = true; return 0; }))
|
||||
this->on_connect(&mosq, nullptr, 0); data.response_received = true; return 0;
|
||||
}))
|
||||
.WillOnce(t::Invoke([this, &mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
mosquitto_message msg{};
|
||||
this->on_message(&mosq, nullptr, &msg); data.response_received = true; return 0; }))
|
||||
mosquitto_message msg{};
|
||||
this->on_message(&mosq, nullptr, &msg); data.response_received = true; return 0;
|
||||
}))
|
||||
.WillOnce(t::Invoke([this, &mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
mosquitto_message msg{};
|
||||
this->on_message(&mosq, nullptr, &msg); data.response_received = true; return 0; }))
|
||||
mosquitto_message msg{};
|
||||
this->on_message(&mosq, nullptr, &msg); data.response_received = true; return 0;
|
||||
}))
|
||||
.WillOnce(t::Invoke([this, &mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
mosquitto_message msg{};
|
||||
this->on_message(&mosq, nullptr, &msg); data.response_received = true; return 0; }))
|
||||
mosquitto_message msg{};
|
||||
this->on_message(&mosq, nullptr, &msg); data.response_received = true; return 0;
|
||||
}))
|
||||
.WillOnce(t::Invoke([this, &mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
mosquitto_message msg{};
|
||||
this->on_message(&mosq, nullptr, &msg); data.response_received = true; return 0; }))
|
||||
mosquitto_message msg{};
|
||||
this->on_message(&mosq, nullptr, &msg); data.response_received = true; return 0;
|
||||
}))
|
||||
.WillOnce(t::Invoke([this, &mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
mosquitto_message msg{};
|
||||
this->on_message(&mosq, nullptr, &msg); data.response_received = true; return 0; }))
|
||||
mosquitto_message msg{};
|
||||
this->on_message(&mosq, nullptr, &msg); data.response_received = true; return 0;
|
||||
}))
|
||||
.WillOnce(t::Invoke([this, &mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
mosquitto_message msg{};
|
||||
this->on_message(&mosq, nullptr, &msg); data.response_received = true; return 0; }))
|
||||
mosquitto_message msg{};
|
||||
this->on_message(&mosq, nullptr, &msg); data.response_received = true; return 0;
|
||||
}))
|
||||
.WillOnce(t::Invoke([this, &mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
mosquitto_message msg{};
|
||||
this->on_message(&mosq, nullptr, &msg); data.response_received = true; return 0; }));
|
||||
mosquitto_message msg{};
|
||||
this->on_message(&mosq, nullptr, &msg); data.response_received = true; return 0;
|
||||
}));
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish(t::Eq(&mosq), nullptr, t::StrEq("$CONTROL/dynamic-security/v1"), t::_,
|
||||
t::StrEq("{\"commands\":[{\"command\":\"listClients\"}]}"), 1, false))
|
||||
t::StrEq("{\"commands\":[{\"command\":\"listClients\"}]}"), 1, false))
|
||||
.WillOnce(t::Return(0));
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish(t::Eq(&mosq), nullptr, t::StrEq("$CONTROL/dynamic-security/v1"), t::_,
|
||||
t::StrEq("{\"commands\":[{\"command\":\"listGroups\"}]}"), 1, false))
|
||||
t::StrEq("{\"commands\":[{\"command\":\"listGroups\"}]}"), 1, false))
|
||||
.WillOnce(t::Return(0));
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish(t::Eq(&mosq), nullptr, t::StrEq("$CONTROL/dynamic-security/v1"), t::_,
|
||||
t::StrEq("{\"commands\":[{\"command\":\"listRoles\"}]}"), 1, false))
|
||||
t::StrEq("{\"commands\":[{\"command\":\"listRoles\"}]}"), 1, false))
|
||||
.WillOnce(t::Return(0));
|
||||
|
||||
const char *outputs[] = {
|
||||
@@ -444,100 +456,100 @@ TEST_F(CtrlShellHelpTest, DynsecHelp)
|
||||
"Unknown command 'unknown'\n",
|
||||
|
||||
"addClientRole <username> <rolename>\n",
|
||||
"\nAdds a role directly to a client.\n",
|
||||
"\nAdds a role directly to a client.\n",
|
||||
"addGroupClient <groupname> <username>\n",
|
||||
"\nAdds a client to a group.\n",
|
||||
"\nAdds a client to a group.\n",
|
||||
"addGroupRole <groupname> <rolename>\n",
|
||||
"\nAdds a role to a group.\n",
|
||||
"\nAdds a role to a group.\n",
|
||||
"addRoleACL <rolename> publishClientReceive allow|deny [priority] <topic>\n",
|
||||
"addRoleACL <rolename> publishClientSend allow|deny [priority] <topic>\n",
|
||||
"addRoleACL <rolename> subscribeLiteral allow|deny [priority] <topic>\n",
|
||||
"addRoleACL <rolename> subscribePattern allow|deny [priority] <topic>\n",
|
||||
"addRoleACL <rolename> unsubscribeLiteral allow|deny [priority] <topic>\n",
|
||||
"addRoleACL <rolename> unsubscribePattern allow|deny [priority] <topic>\n",
|
||||
"\nAdds an ACL to a role, with an optional priority.\n",
|
||||
"\nACLs of a specific type within a role are processed in order from highest to lowest priority with the first matching ACL applying.\n",
|
||||
"addRoleACL <rolename> publishClientSend allow|deny [priority] <topic>\n",
|
||||
"addRoleACL <rolename> subscribeLiteral allow|deny [priority] <topic>\n",
|
||||
"addRoleACL <rolename> subscribePattern allow|deny [priority] <topic>\n",
|
||||
"addRoleACL <rolename> unsubscribeLiteral allow|deny [priority] <topic>\n",
|
||||
"addRoleACL <rolename> unsubscribePattern allow|deny [priority] <topic>\n",
|
||||
"\nAdds an ACL to a role, with an optional priority.\n",
|
||||
"\nACLs of a specific type within a role are processed in order from highest to lowest priority with the first matching ACL applying.\n",
|
||||
"createClient <username> [password [clientid]]\n",
|
||||
"\nCreate a client with password and optional client id.\n",
|
||||
"\nCreate a client with password and optional client id.\n",
|
||||
"createGroup <groupname>\n",
|
||||
"\nCreate a new group.\n",
|
||||
"\nCreate a new group.\n",
|
||||
"createRole <rolename>\n",
|
||||
"\nCreate a new role.\n",
|
||||
"\nCreate a new role.\n",
|
||||
"deleteClient <username>\n",
|
||||
"\nDelete a client\n",
|
||||
"\nDelete a client\n",
|
||||
"deleteGroup <groupname>\n",
|
||||
"\nDelete a group\n",
|
||||
"\nDelete a group\n",
|
||||
"deleteRole <rolename>\n",
|
||||
"\nDelete a role\n",
|
||||
"\nDelete a role\n",
|
||||
"disableClient <username>\n",
|
||||
"\nDisable a client. This client will not be able to log in, and will be kicked if it has an existing session.\n",
|
||||
"\nDisable a client. This client will not be able to log in, and will be kicked if it has an existing session.\n",
|
||||
"enableClient <username>\n",
|
||||
"\nEnable a client. Disabled clients are unable to log in.\n",
|
||||
"\nEnable a client. Disabled clients are unable to log in.\n",
|
||||
"getAnonymousGroup\n",
|
||||
"\nPrint the group configured as the anonymous group.\n",
|
||||
"\nPrint the group configured as the anonymous group.\n",
|
||||
"getClient <username>\n",
|
||||
"\nPrint details of a client and its groups and direct roles.\n",
|
||||
"\nPrint details of a client and its groups and direct roles.\n",
|
||||
"getDefaultACLAccess\n",
|
||||
"\nPrint the default allow/deny values for the different classes of ACL.\n",
|
||||
"\nPrint the default allow/deny values for the different classes of ACL.\n",
|
||||
"getDetails\n",
|
||||
"\nPrint details including the client, group, and role count, and the current change index.\n",
|
||||
"\nPrint details including the client, group, and role count, and the current change index.\n",
|
||||
"getGroup <groupname>\n",
|
||||
"\nPrint details of a group and its roles.\n",
|
||||
"\nPrint details of a group and its roles.\n",
|
||||
"getRole <rolename>\n",
|
||||
"\nPrint details of a role and its ACLs.\n",
|
||||
"\nPrint details of a role and its ACLs.\n",
|
||||
"listClients [count [offset]]\n",
|
||||
"\nPrint a list of clients configured in the dynsec plugin, with an optional total count and list offset.\n",
|
||||
"\nPrint a list of clients configured in the dynsec plugin, with an optional total count and list offset.\n",
|
||||
"listGroups [count [offset]]\n",
|
||||
"\nPrint a list of groups configured in the dynsec plugin, with an optional total count and list offset.\n",
|
||||
"\nPrint a list of groups configured in the dynsec plugin, with an optional total count and list offset.\n",
|
||||
"listRoles [count [offset]]\n",
|
||||
"\nPrint a list of roles configured in the dynsec plugin, with an optional total count and list offset.\n",
|
||||
"\nPrint a list of roles configured in the dynsec plugin, with an optional total count and list offset.\n",
|
||||
"removeClientRole <username> <rolename>\n",
|
||||
"\nRemoves a role from a client, where the role was directly attached to the client.\n",
|
||||
"\nRemoves a role from a client, where the role was directly attached to the client.\n",
|
||||
"removeGroupClient <groupname> <username>\n",
|
||||
"\nRemoves a client from a group.\n",
|
||||
"\nRemoves a client from a group.\n",
|
||||
"removeGroupRole <groupname> <rolename>\n",
|
||||
"\nRemoves a role from a group.\n",
|
||||
"\nRemoves a role from a group.\n",
|
||||
"removeRoleACL <rolename> publishClientReceive <topic>\n",
|
||||
"removeRoleACL <rolename> publishClientSend <topic>\n",
|
||||
"removeRoleACL <rolename> subscribeLiteral <topic>\n",
|
||||
"removeRoleACL <rolename> subscribePattern <topic>\n",
|
||||
"removeRoleACL <rolename> unsubscribeLiteral <topic>\n",
|
||||
"removeRoleACL <rolename> unsubscribePattern <topic>\n",
|
||||
"\nRemoves an ACL from a role.\n",
|
||||
"removeRoleACL <rolename> publishClientSend <topic>\n",
|
||||
"removeRoleACL <rolename> subscribeLiteral <topic>\n",
|
||||
"removeRoleACL <rolename> subscribePattern <topic>\n",
|
||||
"removeRoleACL <rolename> unsubscribeLiteral <topic>\n",
|
||||
"removeRoleACL <rolename> unsubscribePattern <topic>\n",
|
||||
"\nRemoves an ACL from a role.\n",
|
||||
"setAnonymousGroup <groupname>\n",
|
||||
"\nSets the anonymous group to a new group.\n",
|
||||
"\nSets the anonymous group to a new group.\n",
|
||||
"setClientId <username>\n",
|
||||
"setClientId <username> <clientid>\n",
|
||||
"\nSets or clears the clientid associated with a client. If a client has a clientid, all three of username, password, and clientid must match for a client to be able to authenticate.\n",
|
||||
"setClientId <username> <clientid>\n",
|
||||
"\nSets or clears the clientid associated with a client. If a client has a clientid, all three of username, password, and clientid must match for a client to be able to authenticate.\n",
|
||||
"setClientPassword <username> [password]\n",
|
||||
"\nSets a new password for a client.\n",
|
||||
"\nSets a new password for a client.\n",
|
||||
"setDefaultACLAccess publishClientReceive allow|deny\n",
|
||||
"setDefaultACLAccess publishClientSend allow|deny\n",
|
||||
"setDefaultACLAccess subscribe allow|deny\n",
|
||||
"setDefaultACLAccess unsubscribe allow|deny\n",
|
||||
"\nSets the default ACL access to use for an ACL type. The default access will be applied if no other ACL rules match.\n",
|
||||
"Setting a rule to 'allow' means that if no ACLs match, it will be accepted.\n",
|
||||
"Setting a rule to 'deny' means that if no ACLs match, it will be denied.\n",
|
||||
"setDefaultACLAccess publishClientSend allow|deny\n",
|
||||
"setDefaultACLAccess subscribe allow|deny\n",
|
||||
"setDefaultACLAccess unsubscribe allow|deny\n",
|
||||
"\nSets the default ACL access to use for an ACL type. The default access will be applied if no other ACL rules match.\n",
|
||||
"Setting a rule to 'allow' means that if no ACLs match, it will be accepted.\n",
|
||||
"Setting a rule to 'deny' means that if no ACLs match, it will be denied.\n",
|
||||
"modifyClient <username> textName <textname>\n",
|
||||
"modifyClient <username> textDescription <textdescription>\n",
|
||||
"\nModify the text name or text description for a client.\n",
|
||||
"These are free-text fields for your own use.\n",
|
||||
"modifyClient <username> textDescription <textdescription>\n",
|
||||
"\nModify the text name or text description for a client.\n",
|
||||
"These are free-text fields for your own use.\n",
|
||||
"modifyGroup <groupname> textName <textname>\n",
|
||||
"modifyGroup <groupname> textDescription <textdescription>\n",
|
||||
"\nModify the text name or text description for a group.\n",
|
||||
"modifyGroup <groupname> textDescription <textdescription>\n",
|
||||
"\nModify the text name or text description for a group.\n",
|
||||
"modifyRole <rolename> textName <textname>\n",
|
||||
"modifyRole <rolename> textDescription <textdescription>\n",
|
||||
"modifyRole <rolename> allowWildcardSubs true|false\n",
|
||||
"\nModify the text name or text description for a role.\n",
|
||||
"modifyRole <rolename> textDescription <textdescription>\n",
|
||||
"modifyRole <rolename> allowWildcardSubs true|false\n",
|
||||
"\nModify the text name or text description for a role.\n",
|
||||
|
||||
"disconnect\n",
|
||||
"\nDisconnect from the broker\n", /* help disconnect */
|
||||
"\nDisconnect from the broker\n", /* help disconnect */
|
||||
"return\n",
|
||||
"\nLeave dynsec mode.\n",
|
||||
"\nLeave dynsec mode.\n",
|
||||
"exit\n",
|
||||
"\nQuit the program\n", /* help exit */
|
||||
"\nQuit the program\n", /* help exit */
|
||||
"help <command>\n",
|
||||
"\nFind help on a command using 'help <command>'\n", "Press tab multiple times to find currently available commands.\n", /* help help */
|
||||
"\nFind help on a command using 'help <command>'\n", "Press tab multiple times to find currently available commands.\n", /* help help */
|
||||
"Invalid response from broker.\n",
|
||||
};
|
||||
expect_outputs(outputs, sizeof(outputs)/sizeof(char *));
|
||||
|
||||
@@ -21,156 +21,167 @@ Copyright (c) 2022 Cedalo GmbH
|
||||
|
||||
namespace t = testing;
|
||||
|
||||
struct pending_payload{
|
||||
struct pending_payload {
|
||||
struct pending_payload *next, *prev;
|
||||
char payload[1024];
|
||||
};
|
||||
|
||||
class CtrlShellOptionsTest : public ::t::Test
|
||||
{
|
||||
public:
|
||||
::t::StrictMock<CtrlShellMock> ctrl_shell_mock_{};
|
||||
::t::StrictMock<EditLineMock> editline_mock_{};
|
||||
::t::StrictMock<LibMosquittoMock> libmosquitto_mock_{};
|
||||
::t::StrictMock<PThreadMock> pthread_mock_{};
|
||||
LIBMOSQ_CB_connect on_connect{};
|
||||
LIBMOSQ_CB_message on_message{};
|
||||
struct pending_payload *pending_payloads = nullptr;
|
||||
public:
|
||||
::t::StrictMock<CtrlShellMock> ctrl_shell_mock_{};
|
||||
::t::StrictMock<EditLineMock> editline_mock_{};
|
||||
::t::StrictMock<LibMosquittoMock> libmosquitto_mock_{};
|
||||
::t::StrictMock<PThreadMock> pthread_mock_{};
|
||||
LIBMOSQ_CB_connect on_connect{};
|
||||
LIBMOSQ_CB_message on_message{};
|
||||
struct pending_payload *pending_payloads = nullptr;
|
||||
|
||||
void expect_setup(struct mosq_config *config)
|
||||
{
|
||||
editline_mock_.reset();
|
||||
EXPECT_CALL(editline_mock_, rl_bind_key(t::Eq('\t'), t::_));
|
||||
EXPECT_CALL(editline_mock_, add_history(t::_)).WillRepeatedly(t::Return(0));
|
||||
EXPECT_CALL(editline_mock_, clear_history()).Times(t::AnyNumber());
|
||||
config->no_colour = true;
|
||||
config->port = PORT_UNDEFINED;
|
||||
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StartsWith("mosquitto_ctrl shell v")));
|
||||
void expect_setup(struct mosq_config *config)
|
||||
{
|
||||
editline_mock_.reset();
|
||||
EXPECT_CALL(editline_mock_, rl_bind_key(t::Eq('\t'), t::_));
|
||||
EXPECT_CALL(editline_mock_, add_history(t::_)).WillRepeatedly(t::Return(0));
|
||||
EXPECT_CALL(editline_mock_, clear_history()).Times(t::AnyNumber());
|
||||
config->no_colour = true;
|
||||
config->port = PORT_UNDEFINED;
|
||||
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StartsWith("mosquitto_ctrl shell v")));
|
||||
}
|
||||
|
||||
|
||||
void expect_connect(struct mosquitto *mosq, const char *host, int port)
|
||||
{
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_new(t::Eq(nullptr), t::Eq(true), t::Eq(nullptr)))
|
||||
.WillOnce(t::Return(mosq));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_int_option(t::Eq(mosq), MOSQ_OPT_PROTOCOL_VERSION, 5));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_subscribe_callback_set(t::Eq(mosq), t::_));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish_v5_callback_set(t::Eq(mosq), t::_));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_connect(t::Eq(mosq), t::StrEq(host), port, 60));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_loop_start(t::Eq(mosq)));
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_connect_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_connect>()))
|
||||
.WillRepeatedly(t::SaveArg<1>(&this->on_connect));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_message_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_message>()))
|
||||
.WillOnce(t::SaveArg<1>(&this->on_message));
|
||||
}
|
||||
|
||||
|
||||
void expect_disconnect(struct mosquitto *mosq)
|
||||
{
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_disconnect(t::Eq(mosq)));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_loop_stop(t::Eq(mosq), false));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_destroy(t::Eq(mosq)));
|
||||
}
|
||||
|
||||
|
||||
void expect_outputs(const char **outputs, size_t count)
|
||||
{
|
||||
for(size_t i=0; i<count; i++){
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StrEq(outputs[i]))).Times(t::AtLeast(1));
|
||||
}
|
||||
}
|
||||
|
||||
void expect_connect(struct mosquitto *mosq, const char *host, int port)
|
||||
{
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_new(t::Eq(nullptr), t::Eq(true), t::Eq(nullptr)))
|
||||
.WillOnce(t::Return(mosq));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_int_option(t::Eq(mosq), MOSQ_OPT_PROTOCOL_VERSION, 5));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_subscribe_callback_set(t::Eq(mosq), t::_));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish_v5_callback_set(t::Eq(mosq), t::_));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_connect(t::Eq(mosq), t::StrEq(host), port, 60));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_loop_start(t::Eq(mosq)));
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_connect_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_connect>()))
|
||||
.WillRepeatedly(t::SaveArg<1>(&this->on_connect));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_message_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_message>()))
|
||||
.WillOnce(t::SaveArg<1>(&this->on_message));
|
||||
}
|
||||
void expect_request_response(struct mosquitto *mosq, const char *request, const char *respons)
|
||||
{
|
||||
struct pending_payload *pp = (struct pending_payload *)calloc(1, sizeof(struct pending_payload));
|
||||
snprintf(pp->payload, sizeof(pp->payload), "%s", respons);
|
||||
|
||||
void expect_disconnect(struct mosquitto *mosq)
|
||||
{
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_disconnect(t::Eq(mosq)));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_loop_stop(t::Eq(mosq), false));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_destroy(t::Eq(mosq)));
|
||||
}
|
||||
|
||||
void expect_outputs(const char **outputs, size_t count)
|
||||
{
|
||||
for(size_t i=0; i<count; i++){
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StrEq(outputs[i]))).Times(t::AtLeast(1));
|
||||
}
|
||||
}
|
||||
|
||||
void expect_request_response(struct mosquitto *mosq, const char *request, const char *respons)
|
||||
{
|
||||
struct pending_payload *pp = (struct pending_payload *)calloc(1, sizeof(struct pending_payload));
|
||||
snprintf(pp->payload, sizeof(pp->payload), "%s", respons);
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish(t::Eq(mosq), nullptr, t::StrEq("$CONTROL/broker/v1"), t::_,
|
||||
t::StrEq(request), 1, false))
|
||||
.WillOnce(t::Invoke([this, pp](){
|
||||
DL_APPEND(this->pending_payloads, pp);
|
||||
return 0;
|
||||
}));
|
||||
}
|
||||
|
||||
void expect_request_response_success(struct mosquitto *mosq, const char *request, const char *command)
|
||||
{
|
||||
char response[100];
|
||||
snprintf(response, sizeof(response), "{\"responses\":[{\"command\":\"%s\"}]}", command);
|
||||
expect_request_response(mosq, request, response);
|
||||
}
|
||||
|
||||
void expect_request_response_empty(struct mosquitto *mosq, const char *command)
|
||||
{
|
||||
char request[100];
|
||||
char response[100];
|
||||
|
||||
snprintf(request, sizeof(request), "{\"commands\":[{\"command\":\"%s\"}]}", command);
|
||||
snprintf(response, sizeof(response), "{\"responses\":[{\"command\":\"%s\",\"data\":{}}]}", command);
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish(t::Eq(mosq), nullptr, t::StrEq("$CONTROL/broker/v1"), t::_,
|
||||
t::StrEq(request), 1, false))
|
||||
.WillOnce(t::Invoke([this, &command](){
|
||||
append_empty_response(command);
|
||||
return 0;
|
||||
}));
|
||||
}
|
||||
|
||||
void append_response(const char *response)
|
||||
{
|
||||
struct pending_payload *pp = (struct pending_payload *)calloc(1, sizeof(struct pending_payload));
|
||||
snprintf(pp->payload, sizeof(pp->payload), "%s", response);
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish(t::Eq(mosq), nullptr, t::StrEq("$CONTROL/broker/v1"), t::_,
|
||||
t::StrEq(request), 1, false))
|
||||
.WillOnce(t::Invoke([this, pp](){
|
||||
DL_APPEND(this->pending_payloads, pp);
|
||||
}
|
||||
return 0;
|
||||
}));
|
||||
}
|
||||
|
||||
void append_empty_response(const char *command)
|
||||
{
|
||||
struct pending_payload *pp = (struct pending_payload *)calloc(1, sizeof(struct pending_payload));
|
||||
snprintf(pp->payload, sizeof(pp->payload),
|
||||
|
||||
void expect_request_response_success(struct mosquitto *mosq, const char *request, const char *command)
|
||||
{
|
||||
char response[100];
|
||||
snprintf(response, sizeof(response), "{\"responses\":[{\"command\":\"%s\"}]}", command);
|
||||
expect_request_response(mosq, request, response);
|
||||
}
|
||||
|
||||
|
||||
void expect_request_response_empty(struct mosquitto *mosq, const char *command)
|
||||
{
|
||||
char request[100];
|
||||
char response[100];
|
||||
|
||||
snprintf(request, sizeof(request), "{\"commands\":[{\"command\":\"%s\"}]}", command);
|
||||
snprintf(response, sizeof(response), "{\"responses\":[{\"command\":\"%s\",\"data\":{}}]}", command);
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish(t::Eq(mosq), nullptr, t::StrEq("$CONTROL/broker/v1"), t::_,
|
||||
t::StrEq(request), 1, false))
|
||||
.WillOnce(t::Invoke([this, &command](){
|
||||
append_empty_response(command);
|
||||
return 0;
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
void append_response(const char *response)
|
||||
{
|
||||
struct pending_payload *pp = (struct pending_payload *)calloc(1, sizeof(struct pending_payload));
|
||||
snprintf(pp->payload, sizeof(pp->payload), "%s", response);
|
||||
DL_APPEND(this->pending_payloads, pp);
|
||||
}
|
||||
|
||||
|
||||
void append_empty_response(const char *command)
|
||||
{
|
||||
struct pending_payload *pp = (struct pending_payload *)calloc(1, sizeof(struct pending_payload));
|
||||
snprintf(pp->payload, sizeof(pp->payload),
|
||||
"{\"responses\":[{\"command\":\"%s\",\"data\":{}}]}", command);
|
||||
DL_APPEND(this->pending_payloads, pp);
|
||||
}
|
||||
DL_APPEND(this->pending_payloads, pp);
|
||||
}
|
||||
|
||||
void expect_broker(const char *host, int port)
|
||||
{
|
||||
char buf[200];
|
||||
snprintf(buf, sizeof(buf), "connect mqtt://%s:%d", host, port);
|
||||
char *s_conn = strdup(buf);
|
||||
|
||||
EXPECT_CALL(editline_mock_, readline(t::StrEq("> ")))
|
||||
.WillOnce(t::Return(s_conn));
|
||||
void expect_broker(const char *host, int port)
|
||||
{
|
||||
char buf[200];
|
||||
snprintf(buf, sizeof(buf), "connect mqtt://%s:%d", host, port);
|
||||
char *s_conn = strdup(buf);
|
||||
|
||||
EXPECT_CALL(editline_mock_, readline(t::StrEq("mqtt://localhost:1883> ")))
|
||||
.WillOnce(t::Return(strdup("broker")));
|
||||
EXPECT_CALL(editline_mock_, readline(t::StrEq("> ")))
|
||||
.WillOnce(t::Return(s_conn));
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_subscribe(t::_, nullptr, t::StrEq("$CONTROL/broker/v1/response"), 1))
|
||||
.WillOnce(t::Return(0));
|
||||
}
|
||||
EXPECT_CALL(editline_mock_, readline(t::StrEq("mqtt://localhost:1883> ")))
|
||||
.WillOnce(t::Return(strdup("broker")));
|
||||
|
||||
void expect_connect_and_messages(struct mosquitto *mosq)
|
||||
{
|
||||
/* This is a hacky way of working around the async mqtt send/receive which we don't directly control.
|
||||
* Each send starts a wait which times out after two seconds. We use that call to produce the effect we want.
|
||||
*/
|
||||
EXPECT_CALL(pthread_mock_, pthread_cond_timedwait(t::_, t::_, t::_))
|
||||
.WillOnce(t::Invoke([this, mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
this->on_connect(mosq, nullptr, 0);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}))
|
||||
.WillRepeatedly(t::Invoke([this, mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
mosquitto_message msg{};
|
||||
struct pending_payload *pp = pending_payloads;
|
||||
if(pp){
|
||||
DL_DELETE(pending_payloads, pp);
|
||||
msg.payload = pp->payload;
|
||||
msg.payloadlen = (int)strlen((char *)msg.payload);
|
||||
this->on_message(mosq, nullptr, &msg);
|
||||
free(pp);
|
||||
}
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}));
|
||||
}
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_subscribe(t::_, nullptr, t::StrEq("$CONTROL/broker/v1/response"), 1))
|
||||
.WillOnce(t::Return(0));
|
||||
}
|
||||
|
||||
|
||||
void expect_connect_and_messages(struct mosquitto *mosq)
|
||||
{
|
||||
/* This is a hacky way of working around the async mqtt send/receive which we don't directly control.
|
||||
* Each send starts a wait which times out after two seconds. We use that call to produce the effect we want.
|
||||
*/
|
||||
EXPECT_CALL(pthread_mock_, pthread_cond_timedwait(t::_, t::_, t::_))
|
||||
.WillOnce(t::Invoke([this, mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
this->on_connect(mosq, nullptr, 0);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}))
|
||||
.WillRepeatedly(t::Invoke([this, mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
mosquitto_message msg{};
|
||||
struct pending_payload *pp = pending_payloads;
|
||||
if(pp){
|
||||
DL_DELETE(pending_payloads, pp);
|
||||
msg.payload = pp->payload;
|
||||
msg.payloadlen = (int)strlen((char *)msg.payload);
|
||||
this->on_message(mosq, nullptr, &msg);
|
||||
free(pp);
|
||||
}
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -406,12 +417,12 @@ TEST_F(CtrlShellOptionsTest, ConnectCertNotFound)
|
||||
.WillOnce(t::Return(strdup("exit")));
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_tls_set(
|
||||
t::_,
|
||||
t::StrEq("missing cafile"),
|
||||
t::StrEq("missing capath"),
|
||||
t::StrEq("missing certfile"),
|
||||
t::StrEq("missing keyfile"),
|
||||
nullptr))
|
||||
t::_,
|
||||
t::StrEq("missing cafile"),
|
||||
t::StrEq("missing capath"),
|
||||
t::StrEq("missing certfile"),
|
||||
t::StrEq("missing keyfile"),
|
||||
nullptr))
|
||||
.WillOnce(t::Return(MOSQ_ERR_INVAL));
|
||||
|
||||
const char *outputs[] = {
|
||||
@@ -455,12 +466,12 @@ TEST_F(CtrlShellOptionsTest, ConnectCertError)
|
||||
.WillOnce(t::Return(strdup("exit")));
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_tls_set(
|
||||
t::_,
|
||||
t::StrEq("cafile"),
|
||||
t::StrEq("capath"),
|
||||
t::StrEq("certfile"),
|
||||
t::StrEq("keyfile"),
|
||||
nullptr))
|
||||
t::_,
|
||||
t::StrEq("cafile"),
|
||||
t::StrEq("capath"),
|
||||
t::StrEq("certfile"),
|
||||
t::StrEq("keyfile"),
|
||||
nullptr))
|
||||
.WillOnce(t::Return(MOSQ_ERR_TLS));
|
||||
|
||||
const char *outputs[] = {
|
||||
|
||||
@@ -22,72 +22,78 @@ namespace t = testing;
|
||||
|
||||
class CtrlShellPreConnectTest : public ::t::Test
|
||||
{
|
||||
public:
|
||||
::t::StrictMock<CtrlShellMock> ctrl_shell_mock_{};
|
||||
::t::StrictMock<EditLineMock> editline_mock_{};
|
||||
::t::StrictMock<LibMosquittoMock> libmosquitto_mock_{};
|
||||
::t::StrictMock<PThreadMock> pthread_mock_{};
|
||||
LIBMOSQ_CB_connect on_connect{};
|
||||
LIBMOSQ_CB_message on_message{};
|
||||
public:
|
||||
::t::StrictMock<CtrlShellMock> ctrl_shell_mock_{};
|
||||
::t::StrictMock<EditLineMock> editline_mock_{};
|
||||
::t::StrictMock<LibMosquittoMock> libmosquitto_mock_{};
|
||||
::t::StrictMock<PThreadMock> pthread_mock_{};
|
||||
LIBMOSQ_CB_connect on_connect{};
|
||||
LIBMOSQ_CB_message on_message{};
|
||||
|
||||
void expect_setup(struct mosq_config *config)
|
||||
{
|
||||
editline_mock_.reset();
|
||||
EXPECT_CALL(editline_mock_, rl_bind_key(t::Eq('\t'), t::_));
|
||||
EXPECT_CALL(editline_mock_, add_history(t::_)).WillRepeatedly(t::Return(0));
|
||||
EXPECT_CALL(editline_mock_, clear_history()).Times(t::AnyNumber());
|
||||
config->no_colour = true;
|
||||
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StartsWith("mosquitto_ctrl shell v")));
|
||||
void expect_setup(struct mosq_config *config)
|
||||
{
|
||||
editline_mock_.reset();
|
||||
EXPECT_CALL(editline_mock_, rl_bind_key(t::Eq('\t'), t::_));
|
||||
EXPECT_CALL(editline_mock_, add_history(t::_)).WillRepeatedly(t::Return(0));
|
||||
EXPECT_CALL(editline_mock_, clear_history()).Times(t::AnyNumber());
|
||||
config->no_colour = true;
|
||||
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StartsWith("mosquitto_ctrl shell v")));
|
||||
}
|
||||
|
||||
|
||||
void expect_connect(struct mosquitto *mosq, const char *host, int port)
|
||||
{
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_new(t::Eq(nullptr), t::Eq(true), t::Eq(nullptr)))
|
||||
.WillOnce(t::Return(mosq));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_int_option(t::Eq(mosq), MOSQ_OPT_PROTOCOL_VERSION, 5));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_subscribe_callback_set(t::Eq(mosq), t::_));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish_v5_callback_set(t::Eq(mosq), t::_));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_connect(t::Eq(mosq), t::StrEq(host), port, 60));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_loop_start(t::Eq(mosq)));
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_connect_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_connect>()))
|
||||
.WillRepeatedly(t::SaveArg<1>(&this->on_connect));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_message_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_message>()))
|
||||
.WillOnce(t::SaveArg<1>(&this->on_message));
|
||||
}
|
||||
|
||||
|
||||
void expect_disconnect(struct mosquitto *mosq)
|
||||
{
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_disconnect(t::Eq(mosq)));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_loop_stop(t::Eq(mosq), false));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_destroy(t::Eq(mosq)));
|
||||
}
|
||||
|
||||
|
||||
void expect_outputs(const char **outputs, size_t count)
|
||||
{
|
||||
for(size_t i=0; i<count; i++){
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StrEq(outputs[i]))).Times(t::AtLeast(1));
|
||||
}
|
||||
}
|
||||
|
||||
void expect_connect(struct mosquitto *mosq, const char *host, int port)
|
||||
{
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_new(t::Eq(nullptr), t::Eq(true), t::Eq(nullptr)))
|
||||
.WillOnce(t::Return(mosq));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_int_option(t::Eq(mosq), MOSQ_OPT_PROTOCOL_VERSION, 5));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_subscribe_callback_set(t::Eq(mosq), t::_));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish_v5_callback_set(t::Eq(mosq), t::_));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_connect(t::Eq(mosq), t::StrEq(host), port, 60));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_loop_start(t::Eq(mosq)));
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_connect_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_connect>()))
|
||||
.WillRepeatedly(t::SaveArg<1>(&this->on_connect));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_message_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_message>()))
|
||||
.WillOnce(t::SaveArg<1>(&this->on_message));
|
||||
}
|
||||
|
||||
void expect_disconnect(struct mosquitto *mosq)
|
||||
{
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_disconnect(t::Eq(mosq)));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_loop_stop(t::Eq(mosq), false));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_destroy(t::Eq(mosq)));
|
||||
}
|
||||
|
||||
void expect_outputs(const char **outputs, size_t count)
|
||||
{
|
||||
for(size_t i=0; i<count; i++){
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StrEq(outputs[i]))).Times(t::AtLeast(1));
|
||||
}
|
||||
}
|
||||
void expect_empty_connect_and_messages(struct mosquitto *mosq)
|
||||
{
|
||||
/* This is a hacky way of working around the async mqtt send/receive which we don't directly control.
|
||||
* Each send starts a wait which times out after two seconds. We use that call to produce the effect we want.
|
||||
*/
|
||||
EXPECT_CALL(pthread_mock_, pthread_cond_timedwait(t::_, t::_, t::_))
|
||||
.WillOnce(t::Invoke([this, mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
this->on_connect(mosq, nullptr, 0);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}))
|
||||
.WillRepeatedly(t::Invoke([this, mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
mosquitto_message msg{};
|
||||
this->on_message(mosq, nullptr, &msg);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}));
|
||||
}
|
||||
void expect_empty_connect_and_messages(struct mosquitto *mosq)
|
||||
{
|
||||
/* This is a hacky way of working around the async mqtt send/receive which we don't directly control.
|
||||
* Each send starts a wait which times out after two seconds. We use that call to produce the effect we want.
|
||||
*/
|
||||
EXPECT_CALL(pthread_mock_, pthread_cond_timedwait(t::_, t::_, t::_))
|
||||
.WillOnce(t::Invoke([this, mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
this->on_connect(mosq, nullptr, 0);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}))
|
||||
.WillRepeatedly(t::Invoke([this, mosq](pthread_cond_t *, pthread_mutex_t *, const struct timespec *){
|
||||
mosquitto_message msg{};
|
||||
this->on_message(mosq, nullptr, &msg);
|
||||
data.response_received = true;
|
||||
return 0;
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -106,9 +112,9 @@ TEST_F(CtrlShellPreConnectTest, AuthNoUsername)
|
||||
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell_fgets(t::_, t::_, t::_))
|
||||
.WillOnce(t::Invoke([](char *s, int size, FILE *){
|
||||
snprintf(s, (size_t)size, "password1");
|
||||
return s;
|
||||
}));
|
||||
snprintf(s, (size_t)size, "password1");
|
||||
return s;
|
||||
}));
|
||||
|
||||
const char *outputs[] = {
|
||||
"password:",
|
||||
@@ -132,9 +138,9 @@ TEST_F(CtrlShellPreConnectTest, AuthWithUsername)
|
||||
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell_fgets(t::_, t::_, t::_))
|
||||
.WillOnce(t::Invoke([](char *s, int size, FILE *){
|
||||
snprintf(s, (size_t)size, "password1");
|
||||
return s;
|
||||
}));
|
||||
snprintf(s, (size_t)size, "password1");
|
||||
return s;
|
||||
}));
|
||||
|
||||
const char *outputs[] = {
|
||||
"password:",
|
||||
|
||||
@@ -21,113 +21,122 @@ Copyright (c) 2022 Cedalo GmbH
|
||||
|
||||
namespace t = testing;
|
||||
|
||||
struct pending_payload{
|
||||
struct pending_payload {
|
||||
struct pending_payload *next, *prev;
|
||||
char payload[1024];
|
||||
};
|
||||
|
||||
class CtrlShellTest : public ::t::Test
|
||||
{
|
||||
public:
|
||||
::t::StrictMock<CtrlShellMock> ctrl_shell_mock_{};
|
||||
::t::StrictMock<EditLineMock> editline_mock_{};
|
||||
::t::StrictMock<LibMosquittoMock> libmosquitto_mock_{};
|
||||
::t::StrictMock<PThreadMock> pthread_mock_{};
|
||||
LIBMOSQ_CB_connect on_connect{};
|
||||
LIBMOSQ_CB_message on_message{};
|
||||
struct pending_payload *pending_payloads = nullptr;
|
||||
public:
|
||||
::t::StrictMock<CtrlShellMock> ctrl_shell_mock_{};
|
||||
::t::StrictMock<EditLineMock> editline_mock_{};
|
||||
::t::StrictMock<LibMosquittoMock> libmosquitto_mock_{};
|
||||
::t::StrictMock<PThreadMock> pthread_mock_{};
|
||||
LIBMOSQ_CB_connect on_connect{};
|
||||
LIBMOSQ_CB_message on_message{};
|
||||
struct pending_payload *pending_payloads = nullptr;
|
||||
|
||||
void expect_setup(struct mosq_config *config)
|
||||
{
|
||||
editline_mock_.reset();
|
||||
EXPECT_CALL(editline_mock_, rl_bind_key(t::Eq('\t'), t::_));
|
||||
EXPECT_CALL(editline_mock_, add_history(t::_)).WillRepeatedly(t::Return(0));
|
||||
EXPECT_CALL(editline_mock_, clear_history()).Times(t::AnyNumber());
|
||||
config->no_colour = true;
|
||||
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StartsWith("mosquitto_ctrl shell v")));
|
||||
void expect_setup(struct mosq_config *config)
|
||||
{
|
||||
editline_mock_.reset();
|
||||
EXPECT_CALL(editline_mock_, rl_bind_key(t::Eq('\t'), t::_));
|
||||
EXPECT_CALL(editline_mock_, add_history(t::_)).WillRepeatedly(t::Return(0));
|
||||
EXPECT_CALL(editline_mock_, clear_history()).Times(t::AnyNumber());
|
||||
config->no_colour = true;
|
||||
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StartsWith("mosquitto_ctrl shell v")));
|
||||
}
|
||||
|
||||
|
||||
void expect_connect(struct mosquitto *mosq, const char *host, int port)
|
||||
{
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_new(t::Eq(nullptr), t::Eq(true), t::Eq(nullptr)))
|
||||
.WillOnce(t::Return(mosq));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_int_option(t::Eq(mosq), MOSQ_OPT_PROTOCOL_VERSION, 5));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_subscribe_callback_set(t::Eq(mosq), t::_));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish_v5_callback_set(t::Eq(mosq), t::_));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_connect(t::Eq(mosq), t::StrEq(host), port, 60));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_loop_start(t::Eq(mosq)));
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_connect_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_connect>()))
|
||||
.WillRepeatedly(t::SaveArg<1>(&this->on_connect));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_message_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_message>()))
|
||||
.WillOnce(t::SaveArg<1>(&this->on_message));
|
||||
}
|
||||
|
||||
|
||||
void expect_disconnect(struct mosquitto *mosq)
|
||||
{
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_disconnect(t::Eq(mosq)));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_loop_stop(t::Eq(mosq), false));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_destroy(t::Eq(mosq)));
|
||||
}
|
||||
|
||||
|
||||
void expect_outputs(const char **outputs, size_t count)
|
||||
{
|
||||
for(size_t i=0; i<count; i++){
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StrEq(outputs[i]))).Times(t::AtLeast(1));
|
||||
}
|
||||
}
|
||||
|
||||
void expect_connect(struct mosquitto *mosq, const char *host, int port)
|
||||
{
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_new(t::Eq(nullptr), t::Eq(true), t::Eq(nullptr)))
|
||||
.WillOnce(t::Return(mosq));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_int_option(t::Eq(mosq), MOSQ_OPT_PROTOCOL_VERSION, 5));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_subscribe_callback_set(t::Eq(mosq), t::_));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish_v5_callback_set(t::Eq(mosq), t::_));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_connect(t::Eq(mosq), t::StrEq(host), port, 60));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_loop_start(t::Eq(mosq)));
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_connect_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_connect>()))
|
||||
.WillRepeatedly(t::SaveArg<1>(&this->on_connect));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_message_callback_set(t::Eq(mosq), t::A<LIBMOSQ_CB_message>()))
|
||||
.WillOnce(t::SaveArg<1>(&this->on_message));
|
||||
}
|
||||
void expect_request_response(struct mosquitto *mosq, const char *request, const char *respons)
|
||||
{
|
||||
struct pending_payload *pp = (struct pending_payload *)calloc(1, sizeof(struct pending_payload));
|
||||
snprintf(pp->payload, sizeof(pp->payload), "%s", respons);
|
||||
|
||||
void expect_disconnect(struct mosquitto *mosq)
|
||||
{
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_disconnect(t::Eq(mosq)));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_loop_stop(t::Eq(mosq), false));
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_destroy(t::Eq(mosq)));
|
||||
}
|
||||
|
||||
void expect_outputs(const char **outputs, size_t count)
|
||||
{
|
||||
for(size_t i=0; i<count; i++){
|
||||
EXPECT_CALL(ctrl_shell_mock_, ctrl_shell__output(t::StrEq(outputs[i]))).Times(t::AtLeast(1));
|
||||
}
|
||||
}
|
||||
|
||||
void expect_request_response(struct mosquitto *mosq, const char *request, const char *respons)
|
||||
{
|
||||
struct pending_payload *pp = (struct pending_payload *)calloc(1, sizeof(struct pending_payload));
|
||||
snprintf(pp->payload, sizeof(pp->payload), "%s", respons);
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish(t::Eq(mosq), nullptr, t::StrEq("$CONTROL/broker/v1"), t::_,
|
||||
t::StrEq(request), 1, false))
|
||||
.WillOnce(t::Invoke([this, pp](){
|
||||
DL_APPEND(this->pending_payloads, pp);
|
||||
return 0;
|
||||
}));
|
||||
}
|
||||
|
||||
void expect_request_response_success(struct mosquitto *mosq, const char *request, const char *command)
|
||||
{
|
||||
char response[100];
|
||||
snprintf(response, sizeof(response), "{\"responses\":[{\"command\":\"%s\"}]}", command);
|
||||
expect_request_response(mosq, request, response);
|
||||
}
|
||||
|
||||
void expect_request_response_empty(struct mosquitto *mosq, const char *command)
|
||||
{
|
||||
char request[100];
|
||||
char response[100];
|
||||
|
||||
snprintf(request, sizeof(request), "{\"commands\":[{\"command\":\"%s\"}]}", command);
|
||||
snprintf(response, sizeof(response), "{\"responses\":[{\"command\":\"%s\",\"data\":{}}]}", command);
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish(t::Eq(mosq), nullptr, t::StrEq("$CONTROL/broker/v1"), t::_,
|
||||
t::StrEq(request), 1, false))
|
||||
.WillOnce(t::Invoke([this, &command](){
|
||||
append_empty_response(command);
|
||||
return 0;
|
||||
}));
|
||||
}
|
||||
|
||||
void append_response(const char *response)
|
||||
{
|
||||
struct pending_payload *pp = (struct pending_payload *)calloc(1, sizeof(struct pending_payload));
|
||||
snprintf(pp->payload, sizeof(pp->payload), "%s", response);
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish(t::Eq(mosq), nullptr, t::StrEq("$CONTROL/broker/v1"), t::_,
|
||||
t::StrEq(request), 1, false))
|
||||
.WillOnce(t::Invoke([this, pp](){
|
||||
DL_APPEND(this->pending_payloads, pp);
|
||||
}
|
||||
return 0;
|
||||
}));
|
||||
}
|
||||
|
||||
void append_empty_response(const char *command)
|
||||
{
|
||||
struct pending_payload *pp = (struct pending_payload *)calloc(1, sizeof(struct pending_payload));
|
||||
snprintf(pp->payload, sizeof(pp->payload),
|
||||
|
||||
void expect_request_response_success(struct mosquitto *mosq, const char *request, const char *command)
|
||||
{
|
||||
char response[100];
|
||||
snprintf(response, sizeof(response), "{\"responses\":[{\"command\":\"%s\"}]}", command);
|
||||
expect_request_response(mosq, request, response);
|
||||
}
|
||||
|
||||
|
||||
void expect_request_response_empty(struct mosquitto *mosq, const char *command)
|
||||
{
|
||||
char request[100];
|
||||
char response[100];
|
||||
|
||||
snprintf(request, sizeof(request), "{\"commands\":[{\"command\":\"%s\"}]}", command);
|
||||
snprintf(response, sizeof(response), "{\"responses\":[{\"command\":\"%s\",\"data\":{}}]}", command);
|
||||
|
||||
EXPECT_CALL(libmosquitto_mock_, mosquitto_publish(t::Eq(mosq), nullptr, t::StrEq("$CONTROL/broker/v1"), t::_,
|
||||
t::StrEq(request), 1, false))
|
||||
.WillOnce(t::Invoke([this, &command](){
|
||||
append_empty_response(command);
|
||||
return 0;
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
void append_response(const char *response)
|
||||
{
|
||||
struct pending_payload *pp = (struct pending_payload *)calloc(1, sizeof(struct pending_payload));
|
||||
snprintf(pp->payload, sizeof(pp->payload), "%s", response);
|
||||
DL_APPEND(this->pending_payloads, pp);
|
||||
}
|
||||
|
||||
|
||||
void append_empty_response(const char *command)
|
||||
{
|
||||
struct pending_payload *pp = (struct pending_payload *)calloc(1, sizeof(struct pending_payload));
|
||||
snprintf(pp->payload, sizeof(pp->payload),
|
||||
"{\"responses\":[{\"command\":\"%s\",\"data\":{}}]}", command);
|
||||
DL_APPEND(this->pending_payloads, pp);
|
||||
}
|
||||
DL_APPEND(this->pending_payloads, pp);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -5,17 +5,18 @@ static int run = -1;
|
||||
|
||||
class mosquittopp_test : public mosqpp::mosquittopp
|
||||
{
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
|
||||
void on_connect_v5(int rc, int flags, const mosquitto_property *props);
|
||||
void on_disconnect_v5(int rc, const mosquitto_property *props);
|
||||
void on_connect_v5(int rc, int flags, const mosquitto_property *props);
|
||||
void on_disconnect_v5(int rc, const mosquitto_property *props);
|
||||
};
|
||||
|
||||
mosquittopp_test::mosquittopp_test(const char *id) : mosqpp::mosquittopp(id)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_connect_v5(int rc, int flags, const mosquitto_property *props)
|
||||
{
|
||||
assert(flags == 0);
|
||||
@@ -29,6 +30,7 @@ void mosquittopp_test::on_connect_v5(int rc, int flags, const mosquitto_property
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_disconnect_v5(int rc, const mosquitto_property *props)
|
||||
{
|
||||
assert(props == NULL);
|
||||
@@ -55,7 +57,9 @@ int main(int argc, char *argv[])
|
||||
mosquitto_property_add_int32(&props, MQTT_PROP_MAXIMUM_PACKET_SIZE, 1000);
|
||||
rc = mosq->connect_v5("localhost", port, 60, NULL, props);
|
||||
mosquitto_property_free_all(&props);
|
||||
if(rc != MOSQ_ERR_SUCCESS) return rc;
|
||||
if(rc != MOSQ_ERR_SUCCESS){
|
||||
return rc;
|
||||
}
|
||||
|
||||
while(run == -1){
|
||||
mosq->loop();
|
||||
|
||||
@@ -5,17 +5,18 @@ static int run = -1;
|
||||
|
||||
class mosquittopp_test : public mosqpp::mosquittopp
|
||||
{
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
|
||||
void on_connect(int rc);
|
||||
void on_disconnect(int rc);
|
||||
void on_connect(int rc);
|
||||
void on_disconnect(int rc);
|
||||
};
|
||||
|
||||
mosquittopp_test::mosquittopp_test(const char *id) : mosqpp::mosquittopp(id)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_connect(int rc)
|
||||
{
|
||||
if(rc){
|
||||
@@ -25,6 +26,7 @@ void mosquittopp_test::on_connect(int rc)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_disconnect(int rc)
|
||||
{
|
||||
run = rc;
|
||||
|
||||
@@ -5,17 +5,18 @@ static int run = -1;
|
||||
|
||||
class mosquittopp_test : public mosqpp::mosquittopp
|
||||
{
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
|
||||
void on_connect(int rc);
|
||||
void on_disconnect(int rc);
|
||||
void on_connect(int rc);
|
||||
void on_disconnect(int rc);
|
||||
};
|
||||
|
||||
mosquittopp_test::mosquittopp_test(const char *id) : mosqpp::mosquittopp(id)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_connect(int rc)
|
||||
{
|
||||
if(rc){
|
||||
@@ -25,6 +26,7 @@ void mosquittopp_test::on_connect(int rc)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_disconnect(int rc)
|
||||
{
|
||||
run = rc;
|
||||
@@ -45,9 +47,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
mosq = new mosquittopp_test("01-con-discon-will");
|
||||
|
||||
/* Set twice, so it has to clear the old settings */
|
||||
mosq->will_set("will/topic", strlen("will-payload"), "will-payload", 1, true);
|
||||
mosq->will_clear();
|
||||
/* Set twice, so it has to clear the old settings */
|
||||
mosq->will_set("will/topic", strlen("will-payload"), "will-payload", 1, true);
|
||||
mosq->will_clear();
|
||||
|
||||
mosq->connect("localhost", port, 60);
|
||||
|
||||
|
||||
@@ -5,17 +5,18 @@ static int run = -1;
|
||||
|
||||
class mosquittopp_test : public mosqpp::mosquittopp
|
||||
{
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
|
||||
void on_connect(int rc);
|
||||
void on_disconnect(int rc);
|
||||
void on_connect(int rc);
|
||||
void on_disconnect(int rc);
|
||||
};
|
||||
|
||||
mosquittopp_test::mosquittopp_test(const char *id) : mosqpp::mosquittopp(id)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_connect(int rc)
|
||||
{
|
||||
if(rc){
|
||||
@@ -25,11 +26,13 @@ void mosquittopp_test::on_connect(int rc)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_disconnect(int rc)
|
||||
{
|
||||
run = rc;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
mosquittopp_test *mosq;
|
||||
|
||||
@@ -5,17 +5,18 @@ static int run = -1;
|
||||
|
||||
class mosquittopp_test : public mosqpp::mosquittopp
|
||||
{
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
|
||||
void on_connect(int rc);
|
||||
void on_disconnect(int rc);
|
||||
void on_connect(int rc);
|
||||
void on_disconnect(int rc);
|
||||
};
|
||||
|
||||
mosquittopp_test::mosquittopp_test(const char *id) : mosqpp::mosquittopp(id)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_connect(int rc)
|
||||
{
|
||||
if(rc){
|
||||
@@ -25,6 +26,7 @@ void mosquittopp_test::on_connect(int rc)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_disconnect(int rc)
|
||||
{
|
||||
run = rc;
|
||||
@@ -44,9 +46,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
mosq = new mosquittopp_test("01-con-discon-will");
|
||||
|
||||
/* Set twice, so it has to clear the old settings */
|
||||
mosq->will_set("will/topic", strlen("will-payload"), "will-payload", 1, true);
|
||||
mosq->will_set("will/topic", strlen("will-payload"), "will-payload", 1, true);
|
||||
/* Set twice, so it has to clear the old settings */
|
||||
mosq->will_set("will/topic", strlen("will-payload"), "will-payload", 1, true);
|
||||
mosq->will_set("will/topic", strlen("will-payload"), "will-payload", 1, true);
|
||||
|
||||
mosq->connect("localhost", port, 60);
|
||||
|
||||
|
||||
@@ -6,18 +6,19 @@ static int run = -1;
|
||||
|
||||
class mosquittopp_test : public mosqpp::mosquittopp
|
||||
{
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
|
||||
void on_connect_v5(int rc, int flags, const mosquitto_property *props);
|
||||
void on_disconnect_v5(int rc, const mosquitto_property *props);
|
||||
int on_ext_auth(const char *auth_method, uint16_t auth_data_len, const void *auth_data, const mosquitto_property *props);
|
||||
void on_connect_v5(int rc, int flags, const mosquitto_property *props);
|
||||
void on_disconnect_v5(int rc, const mosquitto_property *props);
|
||||
int on_ext_auth(const char *auth_method, uint16_t auth_data_len, const void *auth_data, const mosquitto_property *props);
|
||||
};
|
||||
|
||||
mosquittopp_test::mosquittopp_test(const char *id) : mosqpp::mosquittopp(id)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_connect_v5(int rc, int flags, const mosquitto_property *props)
|
||||
{
|
||||
assert(flags == 0);
|
||||
@@ -31,6 +32,7 @@ void mosquittopp_test::on_connect_v5(int rc, int flags, const mosquitto_property
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_disconnect_v5(int rc, const mosquitto_property *props)
|
||||
{
|
||||
assert(props == NULL);
|
||||
@@ -73,7 +75,9 @@ int main(int argc, char *argv[])
|
||||
mosquitto_property_add_int32(&props, MQTT_PROP_MAXIMUM_PACKET_SIZE, 1000);
|
||||
rc = mosq->connect_v5("localhost", port, 60, NULL, props);
|
||||
mosquitto_property_free_all(&props);
|
||||
if(rc != MOSQ_ERR_SUCCESS) return rc;
|
||||
if(rc != MOSQ_ERR_SUCCESS){
|
||||
return rc;
|
||||
}
|
||||
|
||||
while(run == -1){
|
||||
mosq->loop();
|
||||
|
||||
@@ -6,18 +6,19 @@ static int run = -1;
|
||||
|
||||
class mosquittopp_test : public mosqpp::mosquittopp
|
||||
{
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
|
||||
void on_connect_v5(int rc, int flags, const mosquitto_property *props);
|
||||
void on_disconnect_v5(int rc, const mosquitto_property *props);
|
||||
int on_ext_auth(const char *auth_method, uint16_t auth_data_len, const void *auth_data, const mosquitto_property *props);
|
||||
void on_connect_v5(int rc, int flags, const mosquitto_property *props);
|
||||
void on_disconnect_v5(int rc, const mosquitto_property *props);
|
||||
int on_ext_auth(const char *auth_method, uint16_t auth_data_len, const void *auth_data, const mosquitto_property *props);
|
||||
};
|
||||
|
||||
mosquittopp_test::mosquittopp_test(const char *id) : mosqpp::mosquittopp(id)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_connect_v5(int rc, int flags, const mosquitto_property *props)
|
||||
{
|
||||
assert(flags == 0);
|
||||
@@ -31,6 +32,7 @@ void mosquittopp_test::on_connect_v5(int rc, int flags, const mosquitto_property
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_disconnect_v5(int rc, const mosquitto_property *props)
|
||||
{
|
||||
assert(props == NULL);
|
||||
@@ -67,7 +69,9 @@ int main(int argc, char *argv[])
|
||||
mosquitto_property_add_int32(&props, MQTT_PROP_MAXIMUM_PACKET_SIZE, 1000);
|
||||
rc = mosq->connect_v5("localhost", port, 60, NULL, props);
|
||||
mosquitto_property_free_all(&props);
|
||||
if(rc != MOSQ_ERR_SUCCESS) return rc;
|
||||
if(rc != MOSQ_ERR_SUCCESS){
|
||||
return rc;
|
||||
}
|
||||
|
||||
while(run == -1){
|
||||
mosq->loop();
|
||||
|
||||
@@ -4,16 +4,17 @@ static int run = -1;
|
||||
|
||||
class mosquittopp_test : public mosqpp::mosquittopp
|
||||
{
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
|
||||
void on_connect(int rc);
|
||||
void on_connect(int rc);
|
||||
};
|
||||
|
||||
mosquittopp_test::mosquittopp_test(const char *id) : mosqpp::mosquittopp(id)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_connect(int rc)
|
||||
{
|
||||
if(rc){
|
||||
@@ -21,6 +22,7 @@ void mosquittopp_test::on_connect(int rc)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
mosquittopp_test *mosq;
|
||||
@@ -39,7 +41,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
while(run == -1){
|
||||
rc = mosq->loop();
|
||||
if(rc) break;
|
||||
if(rc){
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete mosq;
|
||||
|
||||
|
||||
@@ -5,17 +5,18 @@ static int run = -1;
|
||||
|
||||
class mosquittopp_test : public mosqpp::mosquittopp
|
||||
{
|
||||
public:
|
||||
mosquittopp_test(const char *id, bool clean_session);
|
||||
public:
|
||||
mosquittopp_test(const char *id, bool clean_session);
|
||||
|
||||
void on_connect(int rc);
|
||||
void on_disconnect(int rc);
|
||||
void on_connect(int rc);
|
||||
void on_disconnect(int rc);
|
||||
};
|
||||
|
||||
mosquittopp_test::mosquittopp_test(const char *id, bool clean_session) : mosqpp::mosquittopp(id, clean_session)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_connect(int rc)
|
||||
{
|
||||
if(rc){
|
||||
@@ -25,6 +26,7 @@ void mosquittopp_test::on_connect(int rc)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_disconnect(int rc)
|
||||
{
|
||||
run = rc;
|
||||
|
||||
@@ -4,23 +4,25 @@ static int run = -1;
|
||||
|
||||
class mosquittopp_test : public mosqpp::mosquittopp
|
||||
{
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
|
||||
void on_pre_connect();
|
||||
void on_connect(int rc);
|
||||
void on_disconnect(int rc);
|
||||
void on_pre_connect();
|
||||
void on_connect(int rc);
|
||||
void on_disconnect(int rc);
|
||||
};
|
||||
|
||||
mosquittopp_test::mosquittopp_test(const char *id) : mosqpp::mosquittopp(id)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_pre_connect()
|
||||
{
|
||||
username_pw_set("uname", ";'[08gn=#");
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_connect(int rc)
|
||||
{
|
||||
if(rc){
|
||||
@@ -30,6 +32,7 @@ void mosquittopp_test::on_connect(int rc)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_disconnect(int rc)
|
||||
{
|
||||
run = rc;
|
||||
|
||||
@@ -4,16 +4,17 @@ static int run = -1;
|
||||
|
||||
class mosquittopp_test : public mosqpp::mosquittopp
|
||||
{
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
|
||||
void on_connect(int rc);
|
||||
void on_connect(int rc);
|
||||
};
|
||||
|
||||
mosquittopp_test::mosquittopp_test(const char *id) : mosqpp::mosquittopp(id)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_connect(int rc)
|
||||
{
|
||||
if(rc){
|
||||
@@ -21,6 +22,7 @@ void mosquittopp_test::on_connect(int rc)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
mosquittopp_test *mosq;
|
||||
@@ -40,7 +42,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
while(run == -1){
|
||||
rc = mosq->loop();
|
||||
if(rc) break;
|
||||
if(rc){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delete mosq;
|
||||
|
||||
@@ -5,17 +5,18 @@ static int run = -1;
|
||||
|
||||
class mosquittopp_test : public mosqpp::mosquittopp
|
||||
{
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
|
||||
void on_connect(int rc);
|
||||
void on_disconnect(int rc);
|
||||
void on_connect(int rc);
|
||||
void on_disconnect(int rc);
|
||||
};
|
||||
|
||||
mosquittopp_test::mosquittopp_test(const char *id) : mosqpp::mosquittopp(id)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_connect(int rc)
|
||||
{
|
||||
if(rc){
|
||||
@@ -25,6 +26,7 @@ void mosquittopp_test::on_connect(int rc)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_disconnect(int rc)
|
||||
{
|
||||
run = rc;
|
||||
|
||||
@@ -5,17 +5,18 @@ static int run = -1;
|
||||
|
||||
class mosquittopp_test : public mosqpp::mosquittopp
|
||||
{
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
|
||||
void on_connect(int rc);
|
||||
void on_disconnect(int rc);
|
||||
void on_connect(int rc);
|
||||
void on_disconnect(int rc);
|
||||
};
|
||||
|
||||
mosquittopp_test::mosquittopp_test(const char *id) : mosqpp::mosquittopp(id)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_connect(int rc)
|
||||
{
|
||||
if(rc){
|
||||
@@ -25,11 +26,13 @@ void mosquittopp_test::on_connect(int rc)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_disconnect(int rc)
|
||||
{
|
||||
run = rc;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
mosquittopp_test *mosq;
|
||||
|
||||
@@ -5,17 +5,18 @@ static int run = -1;
|
||||
|
||||
class mosquittopp_test : public mosqpp::mosquittopp
|
||||
{
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
public:
|
||||
mosquittopp_test(const char *id);
|
||||
|
||||
void on_connect(int rc);
|
||||
void on_disconnect(int rc);
|
||||
void on_connect(int rc);
|
||||
void on_disconnect(int rc);
|
||||
};
|
||||
|
||||
mosquittopp_test::mosquittopp_test(const char *id) : mosqpp::mosquittopp(id)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_connect(int rc)
|
||||
{
|
||||
if(rc){
|
||||
@@ -25,11 +26,13 @@ void mosquittopp_test::on_connect(int rc)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mosquittopp_test::on_disconnect(int rc)
|
||||
{
|
||||
run = rc;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
mosquittopp_test *mosq;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#define QOS 2
|
||||
static int mydata = 1;
|
||||
|
||||
|
||||
int cb(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *msg)
|
||||
{
|
||||
assert(mosq);
|
||||
@@ -15,6 +16,7 @@ int cb(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *m
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int port;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#define QOS 2
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int port;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user