5e263267b1cdd252d61180d9d8808fe0c3061701
[m6w6/libmemcached] / test / lib / Server.hpp
1 /*
2 +--------------------------------------------------------------------+
3 | libmemcached - C/C++ Client Library for memcached |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted under the terms of the BSD license. |
7 | You should have received a copy of the license in a bundled file |
8 | named LICENSE; in case you did not receive a copy you can review |
9 | the terms online at: https://opensource.org/licenses/BSD-3-Clause |
10 +--------------------------------------------------------------------+
11 | Copyright (c) 2006-2014 Brian Aker https://datadifferential.com/ |
12 | Copyright (c) 2020 Michael Wallner <mike@php.net> |
13 +--------------------------------------------------------------------+
14 */
15
16 #pragma once
17
18 #include "common.hpp"
19
20 #include <csignal>
21 #include <unordered_map>
22
23 class Server {
24 public:
25 friend class Cluster;
26
27 using arg_func_t = function<string(string)>;
28 using arg_t = variant<string, arg_func_t>;
29 using arg_pair_t = pair<arg_t, arg_t>;
30 using argv_t = vector<variant<arg_t, arg_pair_t>>;
31
32 explicit Server(string binary_ = "false", argv_t args_ = {});
33
34 ~Server();
35
36 Server(const Server &s);
37 Server &operator=(const Server &s);
38
39 Server(Server &&s) { *this = move(s); };
40 Server &operator=(Server &&s) {
41 binary = exchange(s.binary, "false");
42 args = exchange(s.args, {});
43 pid = exchange(s.pid, 0);
44 pipe = exchange(s.pipe, -1);
45 status = exchange(s.status, 0);
46 signalled = exchange(s.signalled, {});
47 socket_or_port = exchange(s.socket_or_port, {});
48 output = exchange(s.output, {});
49 return *this;
50 };
51
52 pid_t getPid() const;
53 int getPipe() const;
54 const string &getBinary() const;
55 const argv_t &getArgs() const;
56 const socket_or_port_t &getSocketOrPort() const;
57
58 struct ChildProc {
59 pid_t pid;
60 int pipe;
61 ChildProc(pid_t pid_, int pipe_)
62 : pid{pid_}
63 , pipe{pipe_} {}
64 };
65 optional<ChildProc> start();
66 bool stop();
67
68 bool signal(int signo = SIGTERM);
69 bool check();
70 bool isListening();
71 bool ensureListening();
72
73 bool wait(int flags = 0);
74 bool tryWait();
75 string &drain();
76
77 private:
78 string binary;
79 argv_t args;
80 bool sasl = false;
81 pid_t pid = 0;
82 int pipe = -1;
83 int status = 0;
84 unordered_map<int, unsigned> signalled;
85 socket_or_port_t socket_or_port = 11211;
86 string output;
87
88 [[nodiscard]] vector<char *> createArgv();
89 optional<string> handleArg(vector<char *> &arr, const string &arg, const arg_func_t &next_arg);
90 };
91
92 inline ostream &operator<<(ostream &out, const socket_or_port_t sop) {
93 if (holds_alternative<string>(sop)) {
94 out << get<string>(sop);
95 } else {
96 out << ":" << get<int>(sop);
97 }
98 return out;
99 }
100
101 inline ostream &operator<<(ostream &out, const Server &server) {
102 out << "Server{binary=" << server.getBinary() << ",pid=" << server.getPid()
103 << ",conn=" << server.getSocketOrPort() << "}";
104 return out;
105 }