9d4e8a5d5c522f08dd62d5a1b7207445a41a3cb4
[m6w6/libmemcached] / testing / lib / random.cpp
1 #include "testing/lib/random.hpp"
2 #include "testing/lib/Connection.hpp"
3
4 #include <chrono>
5 #include <random>
6
7 #include <unistd.h> // getpid()
8
9
10 template<typename T>
11 enable_if_t<is_integral_v<T>, T> random_num(T min, T max) {
12 using namespace chrono;
13 using rnd = mt19937;
14 using dst = uniform_int_distribution<T>;
15
16 auto time = duration_cast<nanoseconds>(system_clock::now().time_since_epoch());
17 auto seed = static_cast<rnd::result_type>(time.count() % numeric_limits<T>::max());
18 auto rgen = rnd{seed};
19 return dst(min, max)(rgen);
20 }
21
22 unsigned random_port() {
23 retry:
24 auto port = random_num(2<<9, 2<<15);
25 Connection conn(port);
26
27 if (!conn.open()) {
28 return port;
29 }
30 if (!conn.isOpen()) {
31 return port;
32 }
33 goto retry;
34 }
35
36 string random_port_string(const string &) {
37 return to_string(random_port());
38 }
39
40 string random_socket(const string &prefix) {
41 return prefix + to_string(random_num(1U, UINT32_MAX)) + "@" + to_string(getpid()) + ".sock";
42 }
43
44 string random_socket_or_port_string(const string &what) {
45 if (what == "-s") {
46 return random_socket();
47 }
48
49 return to_string(random_port());
50 }
51
52 string random_socket_or_port_flag(const string &binary) {
53 (void) binary;
54 return random_num(0, 1) ? "-p" : "-s";
55 }
56
57 char random_ascii(char min, char max) {
58 return static_cast<char>(random_num(min, max));
59 }
60
61 string random_ascii_string(size_t len, char min, char max) {
62 string s;
63 s.reserve(len + 1);
64
65 for (size_t rem = 0; rem < len; ++rem) {
66 s += random_ascii(min, max);
67 }
68
69 s[len] = '\0';
70 assert(strlen(s.c_str()) == s.size());
71
72 return s;
73 }
74
75 pair<string, string> random_ascii_pair(size_t minlen, size_t maxlen) {
76 return {
77 random_ascii_string(random_num(minlen, maxlen)),
78 random_ascii_string(random_num(minlen, maxlen))
79 };
80 }