Update all licenses to BSD.
[m6w6/libmemcached] / libtest / server.h
1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2 *
3 * Data Differential YATL (i.e. libtest) library
4 *
5 * Copyright (C) 2012 Data Differential, http://datadifferential.com/
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following disclaimer
16 * in the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * * The names of its contributors may not be used to endorse or
20 * promote products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *
35 */
36
37 #pragma once
38
39 #include <libtest/cmdline.h>
40
41 #include <cassert>
42 #include <cstdio>
43 #include <cstring>
44 #include <netdb.h>
45 #include <netinet/in.h>
46 #include <string>
47 #include <unistd.h>
48 #include <vector>
49
50 namespace libtest {
51
52 struct Server {
53 private:
54 typedef std::vector< std::pair<std::string, std::string> > Options;
55
56 private:
57 uint64_t _magic;
58 bool _is_socket;
59 std::string _socket;
60 std::string _sasl;
61 std::string _pid_file;
62 std::string _log_file;
63 std::string _base_command; // executable command which include libtool, valgrind, gdb, etc
64 std::string _running; // Current string being used for system()
65
66 protected:
67 in_port_t _port;
68 std::string _hostname;
69 std::string _extra_args;
70
71 public:
72 Server(const std::string& hostname, const in_port_t port_arg,
73 const std::string& executable, const bool _is_libtool,
74 const bool is_socket_arg= false);
75
76 virtual ~Server();
77
78 virtual const char *name()= 0;
79 virtual bool is_libtool()= 0;
80
81 virtual bool has_socket_file_option() const
82 {
83 return false;
84 }
85
86 virtual void socket_file_option(Application& app, const std::string& socket_arg)
87 {
88 if (socket_arg.empty() == false)
89 {
90 std::string buffer("--socket=");
91 buffer+= socket_arg;
92 app.add_option(buffer);
93 }
94 }
95
96 virtual bool has_log_file_option() const
97 {
98 return false;
99 }
100
101 virtual void log_file_option(Application& app, const std::string& arg)
102 {
103 if (arg.empty() == false)
104 {
105 std::string buffer("--log-file=");
106 buffer+= arg;
107 app.add_option(buffer);
108 }
109 }
110
111 virtual void pid_file_option(Application& app, const std::string& arg)
112 {
113 if (arg.empty() == false)
114 {
115 std::string buffer("--pid-file=");
116 buffer+= arg;
117 app.add_option(buffer);
118 }
119 }
120
121 virtual bool has_port_option() const
122 {
123 return false;
124 }
125
126 virtual void port_option(Application& app, in_port_t arg)
127 {
128 if (arg > 0)
129 {
130 char buffer[1024];
131 snprintf(buffer, sizeof(buffer), "--port=%d", int(arg));
132 app.add_option(buffer);
133 }
134 }
135
136 virtual bool broken_socket_cleanup()
137 {
138 return false;
139 }
140
141 virtual bool broken_pid_file()
142 {
143 return false;
144 }
145
146 const std::string& pid_file() const
147 {
148 return _pid_file;
149 }
150
151 const std::string& base_command() const
152 {
153 return _base_command;
154 }
155
156 const std::string& log_file() const
157 {
158 return _log_file;
159 }
160
161 const std::string& hostname() const
162 {
163 return _hostname;
164 }
165
166 const std::string& socket() const
167 {
168 return _socket;
169 }
170
171 bool has_socket() const
172 {
173 return _is_socket;
174 }
175
176 bool cycle();
177
178 virtual bool ping()= 0;
179
180 virtual bool build(size_t argc, const char *argv[])= 0;
181
182 void add_option(const std::string&);
183 void add_option(const std::string&, const std::string&);
184
185 in_port_t port() const
186 {
187 return _port;
188 }
189
190 bool has_port() const
191 {
192 return (_port != 0);
193 }
194
195 virtual bool has_syslog() const
196 {
197 return false;
198 }
199
200 // Reset a server if another process has killed the server
201 void reset()
202 {
203 _pid_file.clear();
204 _log_file.clear();
205 }
206
207 bool args(Application&);
208
209 pid_t pid() const;
210
211 bool has_pid() const;
212
213 virtual bool wait_for_pidfile() const;
214
215 bool check_pid(pid_t pid_arg) const
216 {
217 return (pid_arg > 1);
218 }
219
220 bool is_socket() const
221 {
222 return _hostname[0] == '/';
223 }
224
225 const std::string running() const
226 {
227 return _running;
228 }
229
230 bool check();
231
232 std::string log_and_pid();
233
234 bool kill();
235 bool start();
236 bool command(libtest::Application& app);
237
238 bool validate();
239
240 protected:
241 bool set_pid_file();
242 Options _options;
243 Application _app;
244
245 private:
246 bool is_helgrind() const;
247 bool is_valgrind() const;
248 bool is_debug() const;
249 bool set_log_file();
250 bool set_socket_file();
251 void reset_pid();
252 };
253
254 std::ostream& operator<<(std::ostream& output, const libtest::Server &arg);
255
256 } // namespace libtest
257
258