server.cc 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
  2. *
  3. * libtest
  4. *
  5. * Copyright (C) 2011 Data Differential, http://datadifferential.com/
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 3 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include <config.h>
  22. #include <libtest/common.h>
  23. #include <cassert>
  24. #include <cerrno>
  25. #include <cstdlib>
  26. #include <iostream>
  27. #include <algorithm>
  28. #include <functional>
  29. #include <locale>
  30. // trim from end
  31. static inline std::string &rtrim(std::string &s)
  32. {
  33. s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
  34. return s;
  35. }
  36. #include <libtest/server.h>
  37. #include <libtest/stream.h>
  38. #include <libtest/killpid.h>
  39. namespace libtest {
  40. std::ostream& operator<<(std::ostream& output, const Server &arg)
  41. {
  42. if (arg.is_socket())
  43. {
  44. output << arg.hostname();
  45. }
  46. else
  47. {
  48. output << arg.hostname() << ":" << arg.port();
  49. }
  50. if (arg.has_pid())
  51. {
  52. output << " Pid:" << arg.pid();
  53. }
  54. if (arg.has_socket())
  55. {
  56. output << " Socket:" << arg.socket();
  57. }
  58. if (arg.running().empty() == false)
  59. {
  60. output << " Exec:" << arg.running();
  61. }
  62. return output; // for multiple << operators
  63. }
  64. #define MAGIC_MEMORY 123570
  65. Server::Server(const std::string& host_arg, const in_port_t port_arg, bool is_socket_arg) :
  66. _magic(MAGIC_MEMORY),
  67. _is_socket(is_socket_arg),
  68. _pid(-1),
  69. _port(port_arg),
  70. _hostname(host_arg)
  71. {
  72. }
  73. Server::~Server()
  74. {
  75. if (has_pid() and not kill(_pid))
  76. {
  77. Error << "Unable to kill:" << *this;
  78. }
  79. }
  80. bool Server::validate()
  81. {
  82. return _magic == MAGIC_MEMORY;
  83. }
  84. // If the server exists, kill it
  85. bool Server::cycle()
  86. {
  87. uint32_t limit= 3;
  88. // Try to ping, and kill the server #limit number of times
  89. pid_t current_pid;
  90. while (--limit and
  91. is_pid_valid(current_pid= get_pid()))
  92. {
  93. if (kill(current_pid))
  94. {
  95. Log << "Killed existing server," << *this << " with pid:" << current_pid;
  96. dream(0, 50000);
  97. continue;
  98. }
  99. }
  100. // For whatever reason we could not kill it, and we reached limit
  101. if (limit == 0)
  102. {
  103. Error << "Reached limit, could not kill server pid:" << current_pid;
  104. return false;
  105. }
  106. return true;
  107. }
  108. bool Server::wait_for_pidfile() const
  109. {
  110. Wait wait(pid_file(), 4);
  111. return wait.successful();
  112. }
  113. bool Server::start()
  114. {
  115. // If we find that we already have a pid then kill it.
  116. if (has_pid() and kill(_pid) == false)
  117. {
  118. Error << "Could not kill() existing server during start() pid:" << _pid;
  119. return false;
  120. }
  121. if (has_pid() == false)
  122. {
  123. fatal_message("has_pid() failed, programer error");
  124. }
  125. Application app(executable(), is_libtool());
  126. if (is_debug())
  127. {
  128. app.use_gdb();
  129. }
  130. else if (getenv("TESTS_ENVIRONMENT"))
  131. {
  132. if (strstr(getenv("TESTS_ENVIRONMENT"), "gdb"))
  133. {
  134. app.use_gdb();
  135. }
  136. }
  137. if (args(app) == false)
  138. {
  139. Error << "Could not build command()";
  140. return false;
  141. }
  142. Application::error_t ret;
  143. if (Application::SUCCESS != (ret= app.run()))
  144. {
  145. Error << "Application::run() " << ret;
  146. return false;
  147. }
  148. _running= app.print();
  149. if (Application::SUCCESS != (ret= app.wait()))
  150. {
  151. Error << "Application::wait() " << _running << " " << ret;
  152. return false;
  153. }
  154. if (is_helgrind() or is_valgrind())
  155. {
  156. dream(5, 50000);
  157. }
  158. if (pid_file().empty() == false)
  159. {
  160. Wait wait(pid_file(), 8);
  161. if (wait.successful() == false)
  162. {
  163. libtest::fatal(LIBYATL_DEFAULT_PARAM,
  164. "Unable to open pidfile for: %s",
  165. _running.c_str());
  166. }
  167. }
  168. int counter= 0;
  169. bool pinged= false;
  170. while ((pinged= ping()) == false and
  171. counter < (is_helgrind() or is_valgrind() ? 20 : 5))
  172. {
  173. dream(counter++, 50000);
  174. }
  175. if (pinged == false)
  176. {
  177. // If we happen to have a pid file, lets try to kill it
  178. if (pid_file().empty() == false)
  179. {
  180. if (kill_file(pid_file()) == false)
  181. {
  182. fatal_message("Failed to kill off server after startup occurred, when pinging failed");
  183. }
  184. Error << "Failed to ping() server started, having pid_file. exec:" << _running;
  185. }
  186. else
  187. {
  188. Error << "Failed to ping() server started. exec:" << _running;
  189. }
  190. _running.clear();
  191. return false;
  192. }
  193. // A failing get_pid() at this point is considered an error
  194. _pid= get_pid(true);
  195. return has_pid();
  196. }
  197. void Server::reset_pid()
  198. {
  199. _running.clear();
  200. _pid_file.clear();
  201. _pid= -1;
  202. }
  203. pid_t Server::pid()
  204. {
  205. return _pid;
  206. }
  207. void Server::add_option(const std::string& arg)
  208. {
  209. _options.push_back(std::make_pair(arg, std::string()));
  210. }
  211. void Server::add_option(const std::string& name, const std::string& value)
  212. {
  213. _options.push_back(std::make_pair(name, value));
  214. }
  215. bool Server::set_socket_file()
  216. {
  217. char file_buffer[FILENAME_MAX];
  218. file_buffer[0]= 0;
  219. if (broken_pid_file())
  220. {
  221. snprintf(file_buffer, sizeof(file_buffer), "/tmp/%s.socketXXXXXX", name());
  222. }
  223. else
  224. {
  225. snprintf(file_buffer, sizeof(file_buffer), "var/run/%s.socketXXXXXX", name());
  226. }
  227. int fd;
  228. if ((fd= mkstemp(file_buffer)) == -1)
  229. {
  230. perror(file_buffer);
  231. return false;
  232. }
  233. close(fd);
  234. unlink(file_buffer);
  235. _socket= file_buffer;
  236. return true;
  237. }
  238. bool Server::set_pid_file()
  239. {
  240. char file_buffer[FILENAME_MAX];
  241. file_buffer[0]= 0;
  242. if (broken_pid_file())
  243. {
  244. snprintf(file_buffer, sizeof(file_buffer), "/tmp/%s.pidXXXXXX", name());
  245. }
  246. else
  247. {
  248. snprintf(file_buffer, sizeof(file_buffer), "var/run/%s.pidXXXXXX", name());
  249. }
  250. int fd;
  251. if ((fd= mkstemp(file_buffer)) == -1)
  252. {
  253. perror(file_buffer);
  254. return false;
  255. }
  256. close(fd);
  257. unlink(file_buffer);
  258. _pid_file= file_buffer;
  259. return true;
  260. }
  261. bool Server::set_log_file()
  262. {
  263. char file_buffer[FILENAME_MAX];
  264. file_buffer[0]= 0;
  265. snprintf(file_buffer, sizeof(file_buffer), "var/log/%s.logXXXXXX", name());
  266. int fd;
  267. if ((fd= mkstemp(file_buffer)) == -1)
  268. {
  269. libtest::fatal(LIBYATL_DEFAULT_PARAM, "mkstemp() failed on %s with %s", file_buffer, strerror(errno));
  270. }
  271. close(fd);
  272. _log_file= file_buffer;
  273. return true;
  274. }
  275. bool Server::args(Application& app)
  276. {
  277. // Set a log file if it was requested (and we can)
  278. if (has_log_file_option())
  279. {
  280. set_log_file();
  281. log_file_option(app, _log_file);
  282. }
  283. if (getenv("LIBTEST_SYSLOG") and has_syslog())
  284. {
  285. app.add_option("--syslog");
  286. }
  287. // Update pid_file
  288. {
  289. if (_pid_file.empty() and set_pid_file() == false)
  290. {
  291. return false;
  292. }
  293. pid_file_option(app, pid_file());
  294. }
  295. assert(daemon_file_option());
  296. if (daemon_file_option() and not is_valgrind() and not is_helgrind())
  297. {
  298. app.add_option(daemon_file_option());
  299. }
  300. if (has_socket_file_option())
  301. {
  302. if (set_socket_file() == false)
  303. {
  304. return false;
  305. }
  306. socket_file_option(app, _socket);
  307. }
  308. if (has_port_option())
  309. {
  310. port_option(app, _port);
  311. }
  312. for (Options::const_iterator iter= _options.begin(); iter != _options.end(); iter++)
  313. {
  314. if ((*iter).second.empty() == false)
  315. {
  316. app.add_option((*iter).first, (*iter).second);
  317. }
  318. else
  319. {
  320. app.add_option((*iter).first);
  321. }
  322. }
  323. return true;
  324. }
  325. bool Server::is_debug() const
  326. {
  327. return bool(getenv("LIBTEST_MANUAL_GDB"));
  328. }
  329. bool Server::is_valgrind() const
  330. {
  331. return bool(getenv("LIBTEST_MANUAL_VALGRIND"));
  332. }
  333. bool Server::is_helgrind() const
  334. {
  335. return bool(getenv("LIBTEST_MANUAL_HELGRIND"));
  336. }
  337. bool Server::kill(pid_t pid_arg)
  338. {
  339. if (check_pid(pid_arg) and kill_pid(pid_arg)) // If we kill it, reset
  340. {
  341. if (broken_pid_file() and pid_file().empty() == false)
  342. {
  343. unlink(pid_file().c_str());
  344. }
  345. if (broken_socket_cleanup() and has_socket() and not socket().empty())
  346. {
  347. unlink(socket().c_str());
  348. }
  349. reset_pid();
  350. return true;
  351. }
  352. return false;
  353. }
  354. } // namespace libtest