bbebe95714c2b000a9d2ee353175a8c9606cb57e
[awesomized/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 bool init(const char *argv[]);
181 virtual bool build()= 0;
182
183 void add_option(const std::string&);
184 void add_option(const std::string&, const std::string&);
185
186 in_port_t port() const
187 {
188 return _port;
189 }
190
191 bool has_port() const
192 {
193 return (_port != 0);
194 }
195
196 virtual bool has_syslog() const
197 {
198 return false;
199 }
200
201 // Reset a server if another process has killed the server
202 void reset()
203 {
204 _pid_file.clear();
205 _log_file.clear();
206 }
207
208 pid_t pid() const;
209
210 bool has_pid() const;
211
212 virtual bool has_pid_file() const
213 {
214 return true;
215 }
216
217 const std::string& error()
218 {
219 return _error;
220 }
221
222 void error(std::string arg)
223 {
224 _error= arg;
225 }
226
227 void reset_error()
228 {
229 _error.clear();
230 }
231
232 virtual bool wait_for_pidfile() const;
233
234 bool check_pid(pid_t pid_arg) const
235 {
236 return (pid_arg > 1);
237 }
238
239 bool is_socket() const
240 {
241 return _is_socket;
242 }
243
244 const std::string running() const
245 {
246 return _running;
247 }
248
249 bool check();
250
251 std::string log_and_pid();
252
253 bool kill();
254 bool start();
255 bool command(libtest::Application& app);
256
257 bool validate();
258
259 void out_of_ban_killed(bool arg)
260 {
261 out_of_ban_killed_= arg;
262 }
263
264 bool out_of_ban_killed()
265 {
266 return out_of_ban_killed_;
267 }
268
269 void timeout(uint32_t timeout_)
270 {
271 _timeout= timeout_;
272 }
273
274 protected:
275 bool set_pid_file();
276 Options _options;
277 Application _app;
278
279 private:
280 bool is_helgrind() const;
281 bool is_valgrind() const;
282 bool is_debug() const;
283 bool set_log_file();
284 bool set_socket_file();
285 void reset_pid();
286 bool out_of_ban_killed_;
287 bool args(Application&);
288
289 std::string _error;
290 uint32_t _timeout; // This number should be high enough for valgrind startup (which is slow)
291 };
292
293 std::ostream& operator<<(std::ostream& output, const libtest::Server &arg);
294
295 } // namespace libtest
296
297