server.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  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. #pragma once
  37. #include <libtest/cmdline.h>
  38. #include <cassert>
  39. #include <cstdio>
  40. #include <cstring>
  41. #include <netdb.h>
  42. #include <netinet/in.h>
  43. #include <string>
  44. #include <unistd.h>
  45. #include <vector>
  46. namespace libtest {
  47. struct Server {
  48. private:
  49. typedef std::vector< std::pair<std::string, std::string> > Options;
  50. private:
  51. uint64_t _magic;
  52. bool _is_socket;
  53. std::string _socket;
  54. std::string _sasl;
  55. std::string _pid_file;
  56. std::string _log_file;
  57. std::string _base_command; // executable command which include libtool, valgrind, gdb, etc
  58. std::string _running; // Current string being used for system()
  59. protected:
  60. in_port_t _port;
  61. std::string _hostname;
  62. std::string _extra_args;
  63. public:
  64. Server(const std::string& hostname, const in_port_t port_arg,
  65. const std::string& executable, const bool _is_libtool,
  66. const bool is_socket_arg= false);
  67. virtual ~Server();
  68. virtual const char *name()= 0;
  69. virtual bool is_libtool()= 0;
  70. virtual bool has_socket_file_option() const
  71. {
  72. return false;
  73. }
  74. virtual void socket_file_option(Application& app, const std::string& socket_arg)
  75. {
  76. if (socket_arg.empty() == false)
  77. {
  78. std::string buffer("--socket=");
  79. buffer+= socket_arg;
  80. app.add_option(buffer);
  81. }
  82. }
  83. virtual bool has_log_file_option() const
  84. {
  85. return false;
  86. }
  87. virtual void log_file_option(Application& app, const std::string& arg)
  88. {
  89. if (arg.empty() == false)
  90. {
  91. std::string buffer("--log-file=");
  92. buffer+= arg;
  93. app.add_option(buffer);
  94. }
  95. }
  96. virtual void pid_file_option(Application& app, const std::string& arg)
  97. {
  98. if (arg.empty() == false)
  99. {
  100. std::string buffer("--pid-file=");
  101. buffer+= arg;
  102. app.add_option(buffer);
  103. }
  104. }
  105. virtual bool has_port_option() const
  106. {
  107. return false;
  108. }
  109. virtual void port_option(Application& app, in_port_t arg)
  110. {
  111. if (arg > 0)
  112. {
  113. char buffer[1024];
  114. snprintf(buffer, sizeof(buffer), "--port=%d", int(arg));
  115. app.add_option(buffer);
  116. }
  117. }
  118. virtual bool broken_socket_cleanup()
  119. {
  120. return false;
  121. }
  122. virtual bool broken_pid_file()
  123. {
  124. return false;
  125. }
  126. const std::string& pid_file() const
  127. {
  128. return _pid_file;
  129. }
  130. const std::string& base_command() const
  131. {
  132. return _base_command;
  133. }
  134. const std::string& log_file() const
  135. {
  136. return _log_file;
  137. }
  138. const std::string& hostname() const
  139. {
  140. return _hostname;
  141. }
  142. const std::string& socket() const
  143. {
  144. return _socket;
  145. }
  146. bool has_socket() const
  147. {
  148. return _is_socket;
  149. }
  150. bool cycle();
  151. virtual bool ping()= 0;
  152. bool init(const char *argv[]);
  153. virtual bool build()= 0;
  154. void add_option(const std::string&);
  155. void add_option(const std::string&, const std::string&);
  156. in_port_t port() const
  157. {
  158. return _port;
  159. }
  160. bool has_port() const
  161. {
  162. return (_port != 0);
  163. }
  164. virtual bool has_syslog() const
  165. {
  166. return false;
  167. }
  168. // Reset a server if another process has killed the server
  169. void reset()
  170. {
  171. _pid_file.clear();
  172. _log_file.clear();
  173. }
  174. pid_t pid() const;
  175. bool has_pid() const;
  176. virtual bool has_pid_file() const
  177. {
  178. return true;
  179. }
  180. const std::string& error()
  181. {
  182. return _error;
  183. }
  184. void error(const char* file_, int line_, const std::string& error_)
  185. {
  186. _error_file= file_;
  187. _error_line= line_;
  188. _error= error_;
  189. }
  190. const char* error_file() const
  191. {
  192. return _error_file;
  193. }
  194. int error_line() const
  195. {
  196. return _error_line;
  197. }
  198. void error(std::string arg)
  199. {
  200. _error= arg;
  201. }
  202. void reset_error()
  203. {
  204. _error.clear();
  205. }
  206. virtual bool wait_for_pidfile() const;
  207. bool check_pid(pid_t pid_arg) const
  208. {
  209. return (pid_arg > 1);
  210. }
  211. bool is_socket() const
  212. {
  213. return _is_socket;
  214. }
  215. const std::string running() const
  216. {
  217. return _running;
  218. }
  219. bool check();
  220. std::string log_and_pid();
  221. bool kill();
  222. bool start();
  223. bool command(libtest::Application& app);
  224. bool validate();
  225. void out_of_ban_killed(bool arg)
  226. {
  227. out_of_ban_killed_= arg;
  228. }
  229. bool out_of_ban_killed()
  230. {
  231. return out_of_ban_killed_;
  232. }
  233. void timeout(uint32_t timeout_)
  234. {
  235. _timeout= timeout_;
  236. }
  237. protected:
  238. bool set_pid_file();
  239. Options _options;
  240. Application _app;
  241. private:
  242. bool is_helgrind() const;
  243. virtual bool is_valgrind() const;
  244. bool is_debug() const;
  245. bool set_log_file();
  246. bool set_socket_file();
  247. void reset_pid();
  248. bool out_of_ban_killed_;
  249. bool args(Application&);
  250. std::string _error;
  251. const char* _error_file;
  252. int _error_line;
  253. uint32_t _timeout; // This number should be high enough for valgrind startup (which is slow)
  254. };
  255. std::ostream& operator<<(std::ostream& output, const libtest::Server &arg);
  256. } // namespace libtest