Files
arduino-libs/arduino-cli/libraries/painlessMesh-master/test/include/catch_utils.hpp
2024-07-20 22:09:06 +08:00

210 lines
4.9 KiB
C++

#ifndef CATCH_UTILS_H_
#define CATCH_UTILS_H_
/*
* Some helper functions to be used in catch based tests
*/
#include <limits>
#include <random>
#include "painlessmesh/protocol.hpp"
static std::random_device
rd; // Will be used to obtain a seed for the random number engine
static std::mt19937 gen(rd());
uint32_t runif(uint32_t from, uint32_t to) {
std::uniform_int_distribution<uint32_t> distribution(from, to);
return distribution(gen);
}
uint32_t rbinom(size_t n, double p) {
std::binomial_distribution<uint32_t> distribution(n, p);
return distribution(gen);
}
std::string randomString(uint32_t length) {
std::string str;
for (uint32_t i = 0; i < length; ++i) {
char rnd = (char)runif(65, 90);
str += rnd;
}
return str;
}
void randomCString(char* str, uint32_t length) {
for (uint32_t i = 0; i < length; ++i) {
char rnd = (char)runif(65, 90);
str[i] = rnd;
}
str[length] = '\0';
}
painlessmesh::protocol::Single createSingle(int length = -1) {
auto pkg = painlessmesh::protocol::Single();
pkg.dest = runif(0, std::numeric_limits<uint32_t>::max());
pkg.from = runif(0, std::numeric_limits<uint32_t>::max());
if (length < 0) length = runif(0, 4096);
pkg.msg = randomString(length);
return pkg;
}
painlessmesh::protocol::Broadcast createBroadcast(int length = -1) {
auto pkg = painlessmesh::protocol::Broadcast();
pkg.dest = runif(0, std::numeric_limits<uint32_t>::max());
pkg.from = runif(0, std::numeric_limits<uint32_t>::max());
if (length < 0) length = runif(0, 4096);
pkg.msg = randomString(length);
return pkg;
}
/*
```
{
"dest": ...,
"from": ...,
"type": ...,
"subs": [
{
"nodeId": ...,
"root" : true,
"subs": [
{
"nodeId": ...,
"subs": []
}
]
}
]
}
```
*/
painlessmesh::protocol::NodeTree createNodeTree(int nodes, int contains_root) {
auto pkg = painlessmesh::protocol::NodeTree();
pkg.nodeId = runif(0, std::numeric_limits<uint32_t>::max());
if (contains_root == 0) {
pkg.root = true;
}
--nodes; // The current node
--contains_root;
auto noSubs = runif(1, 5);
for (uint32_t i = 0; i < noSubs; ++i) {
if (nodes > 0) {
if (i == noSubs - 1) {
pkg.subs.push_back(createNodeTree(nodes, contains_root));
} else {
auto newNodes = 1 + rbinom(nodes - 1, 1.0 / noSubs);
nodes -= newNodes;
if (newNodes > 0)
pkg.subs.push_back(createNodeTree(newNodes, contains_root));
contains_root -= newNodes;
}
}
}
return pkg;
}
painlessmesh::protocol::NodeSyncReply createNodeSyncReply(
int nodes = -1, bool contains_root = true) {
auto pkg = painlessmesh::protocol::NodeSyncReply();
pkg.dest = runif(0, std::numeric_limits<uint32_t>::max());
pkg.from = runif(0, std::numeric_limits<uint32_t>::max());
if (nodes < 0) nodes = runif(1, 254);
auto rt = -1;
if (contains_root) rt = runif(0, nodes - 1);
auto ns = createNodeTree(nodes, rt);
pkg.subs = ns.subs;
pkg.nodeId = ns.nodeId;
pkg.root = ns.root;
return pkg;
}
painlessmesh::protocol::NodeSyncRequest createNodeSyncRequest(
int nodes = -1, bool contains_root = true) {
auto pkg = painlessmesh::protocol::NodeSyncRequest();
pkg.dest = runif(0, std::numeric_limits<uint32_t>::max());
pkg.from = runif(0, std::numeric_limits<uint32_t>::max());
if (nodes < 0) nodes = runif(1, 254);
auto rt = -1;
if (contains_root) rt = runif(0, nodes - 1);
auto ns = createNodeTree(nodes, rt);
pkg.subs = ns.subs;
pkg.nodeId = ns.nodeId;
pkg.root = ns.root;
return pkg;
}
/*
```
{
"dest": 887034362,
"from": 37418,
"type":4,
"msg":{
"type":0
}
}
{
"dest": 887034362,
"from": 37418,
"type":4,
"msg":{
"type":1,
"t0":32990
}
}
{
"dest": 37418,
"from": 887034362,
"type":4,
"msg":{
"type":2,
"t0":32990,
"t1":448585896,
"t2":448596056,
}
}
```
*/
painlessmesh::protocol::TimeSync createTimeSync(int type = -1) {
auto pkg = painlessmesh::protocol::TimeSync();
pkg.dest = runif(0, std::numeric_limits<uint32_t>::max());
pkg.from = runif(0, std::numeric_limits<uint32_t>::max());
if (type < 0) type = runif(0, 2);
pkg.msg.type = type;
auto t = runif(0, std::numeric_limits<uint32_t>::max());
if (type >= 1) pkg.msg.t0 = t;
if (type >= 2) {
t += runif(0, 10000);
pkg.msg.t1 = t;
t += runif(0, 10000);
pkg.msg.t2 = t;
}
return pkg;
}
painlessmesh::protocol::TimeDelay createTimeDelay(int type = -1) {
auto pkg = painlessmesh::protocol::TimeDelay();
pkg.dest = runif(0, std::numeric_limits<uint32_t>::max());
pkg.from = runif(0, std::numeric_limits<uint32_t>::max());
if (type < 0) type = runif(0, 2);
pkg.msg.type = type;
auto t = runif(0, std::numeric_limits<uint32_t>::max());
if (type == 1) pkg.msg.t0 = t;
if (type == 2) {
t += runif(0, 10000);
pkg.msg.t1 = t;
t += runif(0, 10000);
pkg.msg.t2 = t;
}
return pkg;
}
#endif