Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
grn-test-server.c
Go to the documentation of this file.
1 /* -*- c-basic-offset: 2; coding: utf-8 -*- */
2 /*
3  Copyright (C) 2009 Kouhei Sutou <kou@clear-code.com>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License version 2.1 as published by the Free Software Foundation.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #include <errno.h>
20 
21 #include "grn-test-server.h"
22 #include "grn-test-utils.h"
23 
24 #include <gcutter.h>
25 
26 #define GRN_TEST_SERVER_DEFAULT_PORT 5454
27 
28 #define GRN_TEST_SERVER_GET_PRIVATE(obj) \
29  (G_TYPE_INSTANCE_GET_PRIVATE((obj), GRN_TYPE_TEST_SERVER, \
30  GrnTestServerPrivate))
31 
34 {
35  GCutEgg *egg;
37  gchar *database_path;
39  gchar *address;
40  guint port;
41  gchar *encoding;
42  gchar *http_uri_base;
44 };
45 
46 
47 G_DEFINE_TYPE(GrnTestServer, grn_test_server, G_TYPE_OBJECT)
48 
49 static void dispose (GObject *object);
50 
51 static void
52 grn_test_server_class_init(GrnTestServerClass *klass)
53 {
54  GObjectClass *gobject_class;
55 
56  gobject_class = G_OBJECT_CLASS(klass);
57 
58  gobject_class->dispose = dispose;
59 
60  g_type_class_add_private(gobject_class, sizeof(GrnTestServerPrivate));
61 }
62 
63 static void
64 grn_test_server_init(GrnTestServer *factory)
65 {
67 
68  priv = GRN_TEST_SERVER_GET_PRIVATE(factory);
69 
70  priv->egg = NULL;
71  priv->base_directory = NULL;
72  priv->database_path = NULL;
74  priv->address = g_strdup("127.0.0.1");
76  priv->encoding = g_strdup("utf8");
77  priv->http_uri_base = NULL;
78  priv->memcached_address = NULL;
79 }
80 
81 static void
82 dispose(GObject *object)
83 {
85 
86  priv = GRN_TEST_SERVER_GET_PRIVATE(object);
87 
88  if (priv->egg) {
89  g_object_unref(priv->egg);
90  priv->egg = NULL;
91  }
92 
93  if (!priv->custom_database_path) {
94  if (priv->base_directory)
95  cut_utils_remove_path_recursive_force(priv->base_directory);
96  }
97 
98  if (priv->base_directory) {
99  g_free(priv->base_directory);
100  priv->base_directory = NULL;
101  }
102 
103  if (priv->database_path) {
104  g_free(priv->database_path);
105  priv->database_path = NULL;
106  }
107 
108  if (priv->address) {
109  g_free(priv->address);
110  priv->address = NULL;
111  }
112 
113  if (priv->encoding) {
114  g_free(priv->encoding);
115  priv->encoding = NULL;
116  }
117 
118  if (priv->http_uri_base) {
119  g_free(priv->http_uri_base);
120  priv->http_uri_base = NULL;
121  }
122 
123  if (priv->memcached_address) {
124  g_free(priv->memcached_address);
125  priv->memcached_address = NULL;
126  }
127 
128  G_OBJECT_CLASS(grn_test_server_parent_class)->dispose(object);
129 }
130 
131 GQuark
133 {
134  return g_quark_from_static_string("grn-test-server-error-quark");
135 }
136 
139 {
140  return g_object_new(GRN_TYPE_TEST_SERVER, NULL);
141 }
142 
143 static gboolean
144 grn_test_server_ensure_base_directory(GrnTestServer *server, GError **error)
145 {
146  GrnTestServerPrivate *priv;
147 
148  priv = GRN_TEST_SERVER_GET_PRIVATE(server);
149  if (priv->base_directory)
150  return TRUE;
151 
152  priv->base_directory = g_build_filename(grn_test_get_tmp_dir(),
153  "tmp-server", NULL);
154  cut_utils_remove_path_recursive_force(priv->base_directory);
155  if (g_mkdir_with_parents(priv->base_directory, 0700) == -1) {
156  g_set_error(error,
159  "failed to create base directory: %s", g_strerror(errno));
160  return FALSE;
161  }
162 
163  return TRUE;
164 }
165 
166 gboolean
167 grn_test_server_start(GrnTestServer *server, GError **error)
168 {
169  GrnTestServerPrivate *priv;
170  const gchar *database_path;
171  gchar *port_string;
172 
173  priv = GRN_TEST_SERVER_GET_PRIVATE(server);
174  if (priv->egg) {
175  g_set_error(error,
178  "server is already started");
179  return FALSE;
180  }
181 
182  database_path = grn_test_server_get_database_path(server, error);
183  if (!database_path)
184  return FALSE;
185 
186  port_string = g_strdup_printf("%u", priv->port);
187  priv->egg = gcut_egg_new(GROONGA,
188  "-s",
189  "-i", priv->address,
190  "-p", port_string,
191  "-n", database_path,
192  "-e", priv->encoding,
193  NULL);
194  g_free(port_string);
195  if (!gcut_egg_hatch(priv->egg, error))
196  return FALSE;
197 
198  g_usleep(G_USEC_PER_SEC); /* FIXME: use select */
199 
200  return TRUE;
201 }
202 
203 gboolean
204 grn_test_server_stop(GrnTestServer *server, GError **error)
205 {
206  GrnTestServerPrivate *priv;
207 
208  priv = GRN_TEST_SERVER_GET_PRIVATE(server);
209  if (!priv->egg) {
210  g_set_error(error,
213  "server is not started");
214  return FALSE;
215  }
216 
217  /* FIXME: send shutdown command */
218 
219  g_object_unref(priv->egg);
220  priv->egg = NULL;
221 
222  return TRUE;
223 }
224 
225 const gchar *
227 {
228  GrnTestServerPrivate *priv;
229 
230  priv = GRN_TEST_SERVER_GET_PRIVATE(server);
231  if (!priv->custom_database_path) {
232  if (!grn_test_server_ensure_base_directory(server, error))
233  return NULL;
234  if (priv->database_path)
235  g_free(priv->database_path);
236  priv->database_path = g_build_filename(priv->base_directory,
237  "server.db", NULL);
238  }
239 
240  return priv->database_path;
241 }
242 
243 void
245 {
246  GrnTestServerPrivate *priv;
247 
248  priv = GRN_TEST_SERVER_GET_PRIVATE(server);
249 
250  g_free(priv->database_path);
251  if (path) {
252  priv->custom_database_path = TRUE;
253  priv->database_path = g_strdup(path);
254  } else {
255  priv->custom_database_path = FALSE;
256  priv->database_path = NULL;
257  }
258 }
259 
260 const gchar *
262 {
263  return GRN_TEST_SERVER_GET_PRIVATE(server)->address;
264 }
265 
266 void
267 grn_test_server_set_address(GrnTestServer *server, const gchar *address)
268 {
269  GrnTestServerPrivate *priv;
270 
271  priv = GRN_TEST_SERVER_GET_PRIVATE(server);
272 
273  g_free(priv->address);
274  priv->address = g_strdup(address);
275 }
276 
277 guint
279 {
280  return GRN_TEST_SERVER_GET_PRIVATE(server)->port;
281 }
282 
283 void
285 {
286  GRN_TEST_SERVER_GET_PRIVATE(server)->port = port;
287 }
288 
289 const gchar *
291 {
292  return GRN_TEST_SERVER_GET_PRIVATE(server)->encoding;
293 }
294 
295 void
296 grn_test_server_set_encoding(GrnTestServer *server, const gchar *encoding)
297 {
298  GrnTestServerPrivate *priv;
299 
300  priv = GRN_TEST_SERVER_GET_PRIVATE(server);
301 
302  g_free(priv->encoding);
303  priv->encoding = g_strdup(encoding);
304 }
305 
306 const gchar *
308 {
309  GrnTestServerPrivate *priv;
310 
311  priv = GRN_TEST_SERVER_GET_PRIVATE(server);
312  g_free(priv->http_uri_base);
313  priv->http_uri_base =
314  g_strdup_printf("http://%s:%u/", priv->address, priv->port);
315  return priv->http_uri_base;
316 }
317 
318 const gchar *
320 {
321  GrnTestServerPrivate *priv;
322 
323  priv = GRN_TEST_SERVER_GET_PRIVATE(server);
324  g_free(priv->memcached_address);
325  priv->memcached_address = g_strdup_printf("%s:%u", priv->address, priv->port);
326  return priv->memcached_address;
327 }