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