+#include <vector>
+
+namespace libtest {
+
+struct Server {
+private:
+ typedef std::vector< std::pair<std::string, std::string> > Options;
+
+private:
+ uint64_t _magic;
+ bool _is_socket;
+ std::string _socket;
+ std::string _sasl;
+ std::string _pid_file;
+ std::string _log_file;
+ std::string _base_command; // executable command which include libtool, valgrind, gdb, etc
+ std::string _running; // Current string being used for system()
+
+protected:
+ in_port_t _port;
+ std::string _hostname;
+ std::string _extra_args;
+
+public:
+ Server(const std::string& hostname, const in_port_t port_arg,
+ const std::string& executable, const bool _is_libtool,
+ const bool is_socket_arg= false);
+
+ virtual ~Server();
+
+ virtual const char *name()= 0;
+ virtual bool is_libtool()= 0;
+
+ virtual bool has_socket_file_option() const
+ {
+ return false;
+ }
+
+ virtual void socket_file_option(Application& app, const std::string& socket_arg)
+ {
+ if (socket_arg.empty() == false)
+ {
+ std::string buffer("--socket=");
+ buffer+= socket_arg;
+ app.add_option(buffer);
+ }
+ }
+
+ virtual bool has_log_file_option() const
+ {
+ return false;
+ }
+
+ virtual void log_file_option(Application& app, const std::string& arg)
+ {
+ if (arg.empty() == false)
+ {
+ std::string buffer("--log-file=");
+ buffer+= arg;
+ app.add_option(buffer);
+ }
+ }
+
+ virtual void pid_file_option(Application& app, const std::string& arg)
+ {
+ if (arg.empty() == false)
+ {
+ std::string buffer("--pid-file=");
+ buffer+= arg;
+ app.add_option(buffer);
+ }
+ }
+
+ virtual bool has_port_option() const
+ {
+ return false;
+ }
+
+ virtual void port_option(Application& app, in_port_t arg)
+ {
+ if (arg > 0)
+ {
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "--port=%d", int(arg));
+ app.add_option(buffer);
+ }
+ }
+
+ virtual bool broken_socket_cleanup()
+ {
+ return false;
+ }
+
+ virtual bool broken_pid_file()
+ {
+ return false;
+ }
+
+ const std::string& pid_file() const
+ {
+ return _pid_file;
+ }
+
+ const std::string& base_command() const
+ {
+ return _base_command;
+ }
+
+ const std::string& log_file() const
+ {
+ return _log_file;
+ }
+
+ const std::string& hostname() const
+ {
+ return _hostname;
+ }
+
+ const std::string& socket() const
+ {
+ return _socket;
+ }
+
+ bool has_socket() const
+ {
+ return _is_socket;
+ }
+
+ bool cycle();
+
+ virtual bool ping()= 0;
+
+ virtual bool build(size_t argc, const char *argv[])= 0;
+
+ void add_option(const std::string&);
+ void add_option(const std::string&, const std::string&);
+
+ in_port_t port() const
+ {
+ return _port;
+ }
+
+ bool has_port() const
+ {
+ return (_port != 0);
+ }
+
+ virtual bool has_syslog() const
+ {
+ return false;
+ }
+
+ // Reset a server if another process has killed the server
+ void reset()
+ {
+ _pid_file.clear();
+ _log_file.clear();
+ }
+
+ pid_t pid() const;
+
+ bool has_pid() const;
+
+ virtual bool has_pid_file() const
+ {
+ return true;
+ }
+
+ const std::string& error()
+ {
+ return _error;
+ }
+
+ void error(std::string arg)
+ {
+ _error= arg;
+ }
+
+ virtual bool wait_for_pidfile() const;
+
+ bool check_pid(pid_t pid_arg) const
+ {
+ return (pid_arg > 1);
+ }
+
+ bool is_socket() const
+ {
+ return _is_socket;
+ }
+
+ const std::string running() const
+ {
+ return _running;
+ }
+
+ bool check();
+
+ std::string log_and_pid();
+
+ bool kill();
+ bool start();
+ bool command(libtest::Application& app);
+
+ bool validate();
+
+ void out_of_ban_killed(bool arg)
+ {
+ out_of_ban_killed_= arg;
+ }
+
+ bool out_of_ban_killed()
+ {
+ return out_of_ban_killed_;
+ }
+
+protected:
+ bool set_pid_file();
+ Options _options;
+ Application _app;
+
+private:
+ bool is_helgrind() const;
+ bool is_valgrind() const;
+ bool is_debug() const;
+ bool set_log_file();
+ bool set_socket_file();
+ void reset_pid();
+ bool out_of_ban_killed_;
+ bool args(Application&);