bfbab812259a44ec14118fa221d577009368874f
[awesomized/libmemcached] / test / lib / Server.hpp
1 #pragma once
2
3 #include "common.hpp"
4
5 #include <csignal>
6 #include <unordered_map>
7
8 class Server {
9 public:
10
11 friend class Cluster;
12
13 using arg_func_t = function<string(string)>;
14 using arg_t = variant<string, arg_func_t>;
15 using arg_pair_t = pair<arg_t, arg_t>;
16 using argv_t = vector<variant<arg_t, arg_pair_t>>;
17
18 explicit
19 Server(string binary_ = "false", argv_t args_ = {});
20
21 ~Server();
22
23 Server(const Server &s);
24 Server &operator = (const Server &s);
25
26 Server(Server &&s) {
27 *this = move(s);
28 };
29 Server &operator = (Server &&s) {
30 binary = exchange(s.binary, "false");
31 args = exchange(s.args, {});
32 pid = exchange(s.pid, 0);
33 pipe = exchange(s.pipe, -1);
34 status = exchange(s.status, 0);
35 signalled = exchange(s.signalled, {});
36 #if __clang__ && __clang_major__ <= 7
37 socket_or_port = s.socket_or_port;
38 s.socket_or_port = 11211;
39 #else
40 socket_or_port = exchange(s.socket_or_port, 11211);
41 #endif
42 output = exchange(s.output, {});
43 return *this;
44 };
45
46 pid_t getPid() const;
47 int getPipe() const;
48 const string &getBinary() const;
49 const argv_t &getArgs() const;
50 const socket_or_port_t &getSocketOrPort() const;
51
52 struct ChildProc {
53 pid_t pid;
54 int pipe;
55 ChildProc(pid_t pid_, int pipe_)
56 : pid{pid_}
57 , pipe{pipe_}
58 {
59 }
60 };
61 optional<ChildProc> start();
62 bool stop();
63
64 bool signal(int signo = SIGTERM);
65 bool check();
66 bool isListening();
67 bool ensureListening();
68
69 bool wait(int flags = 0);
70 bool tryWait();
71 string &drain();
72
73
74 private:
75 string binary;
76 argv_t args;
77 bool sasl = false;
78 pid_t pid = 0;
79 int pipe = -1;
80 int status = 0;
81 unordered_map<int, unsigned> signalled;
82 socket_or_port_t socket_or_port = 11211;
83 string output;
84
85 [[nodiscard]]
86 vector<char *> createArgv();
87 optional<string> handleArg(vector<char *> &arr, const string &arg, const arg_func_t &next_arg);
88 };
89
90 inline ostream &operator << (ostream &out, const socket_or_port_t sop) {
91 if (holds_alternative<string>(sop)) {
92 out << get<string>(sop);
93 } else {
94 out << ":" << get<int>(sop);
95 }
96 return out;
97 }
98
99 inline ostream &operator << (ostream &out, const Server &server) {
100 out << "Server{binary=" << server.getBinary() << ",pid=" << server.getPid() << ",conn=" << server.getSocketOrPort() << "}";
101 return out;
102 }