Merge in all of libtest updates.
[m6w6/libmemcached] / libtest / memcached.cc
1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2 *
3 * libtest
4 *
5 * Copyright (C) 2011 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 #include <libtest/common.h>
38
39 #include <libmemcached/memcached.h>
40 #include <libmemcached/util.h>
41
42 using namespace libtest;
43
44 #include <cassert>
45 #include <cerrno>
46 #include <cstdio>
47 #include <cstdlib>
48 #include <cstring>
49 #include <iostream>
50 #include <signal.h>
51 #include <sys/types.h>
52 #include <sys/wait.h>
53 #include <unistd.h>
54
55 #include <libtest/server.h>
56 #include <libtest/wait.h>
57
58 #include <libtest/memcached.h>
59
60 #ifndef __INTEL_COMPILER
61 #pragma GCC diagnostic ignored "-Wold-style-cast"
62 #endif
63
64 using namespace libtest;
65
66 class Memcached : public Server
67 {
68 public:
69 Memcached(const std::string& host_arg, const in_port_t port_arg, const bool is_socket_arg) :
70 Server(host_arg, port_arg, is_socket_arg)
71 { }
72
73 pid_t get_pid(bool error_is_ok)
74 {
75 // Memcached is slow to start, so we need to do this
76 if (not pid_file().empty())
77 {
78 Wait wait(pid_file(), 0);
79
80 if (not wait.successful())
81 {
82 Error << "Pidfile was not found:" << pid_file();
83 return -1;
84 }
85 }
86
87 memcached_return_t rc;
88 if (has_socket())
89 {
90 _pid= libmemcached_util_getpid(socket().c_str(), port(), &rc);
91 }
92 else
93 {
94 _pid= libmemcached_util_getpid(hostname().c_str(), port(), &rc);
95 }
96
97 if ((memcached_failed(rc) or _pid < 1) and not error_is_ok)
98 {
99 Error << "libmemcached_util_getpid(" << memcached_strerror(NULL, rc) << ") pid: " << _pid << " for:" << *this;
100 }
101
102 return _pid;
103 }
104
105 bool ping()
106 {
107 // Memcached is slow to start, so we need to do this
108 if (not pid_file().empty())
109 {
110 Wait wait(pid_file(), 0);
111
112 if (not wait.successful())
113 {
114 Error << "Pidfile was not found:" << pid_file();
115 return -1;
116 }
117 }
118
119 memcached_return_t rc;
120 bool ret;
121 if (has_socket())
122 {
123 ret= libmemcached_util_ping(socket().c_str(), 0, &rc);
124 }
125 else
126 {
127 ret= libmemcached_util_ping(hostname().c_str(), port(), &rc);
128 }
129
130 if (memcached_failed(rc) or not ret)
131 {
132 Error << "libmemcached_util_ping(" << memcached_strerror(NULL, rc) << ")";
133 }
134 return ret;
135 }
136
137 const char *name()
138 {
139 return "memcached";
140 };
141
142 const char *executable()
143 {
144 return MEMCACHED_BINARY;
145 }
146
147 const char *pid_file_option()
148 {
149 return "-P ";
150 }
151
152 const char *socket_file_option() const
153 {
154 return "-s ";
155 }
156
157 const char *daemon_file_option()
158 {
159 return "-d";
160 }
161
162 const char *log_file_option()
163 {
164 return NULL;
165 }
166
167 const char *port_option()
168 {
169 return "-p ";
170 }
171
172 bool is_libtool()
173 {
174 return false;
175 }
176
177 // Memcached's pidfile is broken
178 bool broken_pid_file()
179 {
180 return true;
181 }
182
183 bool build(int argc, const char *argv[]);
184 };
185
186
187 #include <sstream>
188
189 bool Memcached::build(int argc, const char *argv[])
190 {
191 std::stringstream arg_buffer;
192
193 if (getuid() == 0 or geteuid() == 0)
194 {
195 arg_buffer << " -u root ";
196 }
197
198 for (int x= 1 ; x < argc ; x++)
199 {
200 arg_buffer << " " << argv[x] << " ";
201 }
202
203 set_extra_args(arg_buffer.str());
204
205 return true;
206 }
207
208 namespace libtest {
209
210 Server *build_memcached(const std::string& hostname, const in_port_t try_port)
211 {
212 return new Memcached(hostname, try_port, false);
213 }
214
215 Server *build_memcached_socket(const std::string& hostname, const in_port_t try_port)
216 {
217 return new Memcached(hostname, try_port, true);
218 }
219
220 }
221