Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
test-stress.c
Go to the documentation of this file.
1 /* -*- c-basic-offset: 2; coding: utf-8 -*- */
2 /*
3  Copyright (C) 2008-2009 Kouhei Sutou <kou@cozmixng.org>
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 <hash.h>
20 #include <pat.h>
21 
22 #include <gcutter.h>
23 
24 #include "../lib/grn-assertions.h"
25 
26 void data_hash(void);
27 void test_hash(gconstpointer test_data);
28 void data_patricia_trie(void);
29 void test_patricia_trie(gconstpointer test_data);
30 
31 #define VALUE_SIZE 1024
32 
33 static grn_ctx *context;
34 static grn_hash *hash;
35 static grn_pat *trie;
36 static gchar *base_dir;
37 static gchar *env_hash_path;
38 static gchar *env_patricia_trie_path;
39 static gchar *env_multi_thread;
40 static gchar *env_n_processes;
41 static gchar *env_process_number;
42 
43 void
44 cut_setup(void)
45 {
46  const gchar *tmp_dir;
47 
48  context = g_new0(grn_ctx, 1);
49  hash = NULL;
50  trie = NULL;
51 
52 #define SAVE_ENV_VALUE(var_name, macro_name) \
53  env_ ## var_name = g_strdup(g_getenv(GRN_TEST_ENV_ ## macro_name))
54 
55  SAVE_ENV_VALUE(hash_path, HASH_PATH);
56  SAVE_ENV_VALUE(patricia_trie_path, PATRICIA_TRIE_PATH);
57  SAVE_ENV_VALUE(multi_thread, MULTI_THREAD);
58  SAVE_ENV_VALUE(n_processes, N_PROCESSES);
59  SAVE_ENV_VALUE(process_number, PROCESS_NUMBER);
60 
61 #undef SAVE_ENV_VALUE
62 
63  tmp_dir = grn_test_get_tmp_dir();
64  cut_remove_path(tmp_dir, NULL);
65 
66  base_dir = g_build_filename(tmp_dir, "stress", NULL);
67 
68  g_mkdir_with_parents(base_dir, 0755);
69  cut_assert_path_exist(base_dir);
70 }
71 
72 void
74 {
75  if (context) {
76  if (hash)
77  grn_hash_close(context, hash);
78  if (trie)
79  grn_pat_close(context, trie);
80  grn_ctx_fin(context);
81  g_free(context);
82  }
83 
84 #define RESTORE_ENV_VALUE(var_name, macro_name) do \
85  { \
86  if (env_ ## var_name) { \
87  g_setenv(GRN_TEST_ENV_ ## macro_name, env_ ## var_name, TRUE); \
88  g_free(env_ ## var_name); \
89  } else { \
90  g_unsetenv(GRN_TEST_ENV_ ## macro_name); \
91  } \
92  } while(0)
93 
94  RESTORE_ENV_VALUE(hash_path, HASH_PATH);
95  RESTORE_ENV_VALUE(patricia_trie_path, PATRICIA_TRIE_PATH);
96  RESTORE_ENV_VALUE(multi_thread, MULTI_THREAD);
97  RESTORE_ENV_VALUE(n_processes, N_PROCESSES);
98  RESTORE_ENV_VALUE(process_number, PROCESS_NUMBER);
99 
100 #undef RESTORE_ENV_VALUE
101 
102  if (base_dir) {
103  cut_remove_path(base_dir, NULL);
104  g_free(base_dir);
105  }
106 }
107 
108 typedef struct _grn_test_data
109 {
110  gint n_processes;
111  gboolean multi_thread;
112 } grn_test_data;
113 
114 static grn_test_data *
115 test_data_new(gint n_processes, gboolean multi_thread)
116 {
117  grn_test_data *data;
118 
119  data = g_new0(grn_test_data, 1);
120  data->n_processes = n_processes;
121  data->multi_thread = multi_thread;
122 
123  return data;
124 }
125 
126 static void
127 test_data_free(grn_test_data *data)
128 {
129  g_free(data);
130 }
131 
132 static gboolean
133 run(const gchar **test_case_names, const grn_test_data *data)
134 {
135  gint i;
136  const gchar *test_dir;
137  CutSubProcessGroup *group;
138 
139  test_dir = cut_take_string(g_build_filename(grn_test_get_base_dir(),
140  "fixtures",
141  NULL));
142 
143  group = cut_take_new_sub_process_group();
144  for (i = 0; i < data->n_processes; i++) {
145  CutSubProcess *sub_process;
146 
147  sub_process = cut_take_new_sub_process(test_dir);
148  cut_sub_process_set_multi_thread(sub_process, data->multi_thread);
149  cut_sub_process_set_fatal_failures(sub_process, TRUE);
150  cut_sub_process_set_target_test_case_names(sub_process, test_case_names);
151 
152  cut_sub_process_group_add(group, sub_process);
153  if (data->multi_thread)
154  g_setenv(GRN_TEST_ENV_MULTI_THREAD, "TRUE", TRUE);
155  else
156  g_unsetenv(GRN_TEST_ENV_MULTI_THREAD);
157  g_setenv(GRN_TEST_ENV_N_PROCESSES,
158  cut_take_printf("%d", data->n_processes), TRUE);
159  g_setenv(GRN_TEST_ENV_PROCESS_NUMBER, cut_take_printf("%d", i), TRUE);
160  cut_sub_process_run_async(sub_process);
161  }
162  return cut_sub_process_group_wait(group);
163 }
164 
165 void
167 {
168  cut_add_data("single process - single thread",
169  test_data_new(1, FALSE), test_data_free,
170  "single process - multi thread",
171  test_data_new(1, TRUE), test_data_free,
172  "multi process - single thread",
173  test_data_new(10, FALSE), test_data_free,
174  "multi process - multi thread",
175  test_data_new(10, TRUE), test_data_free);
176 }
177 
178 void
179 test_hash(gconstpointer test_data)
180 {
181  const grn_test_data *data = test_data;
182  gchar *path;
183  const gchar *test_case_names[] = {"test_stress_hash", NULL};
184 
186 
187  path = g_build_filename(base_dir, "hash", NULL);
188  g_setenv(GRN_TEST_ENV_HASH_PATH, path, TRUE);
190  hash = grn_hash_create(context, path, sizeof(gint), VALUE_SIZE, 0);
191  g_free(path);
192  cut_assert_not_null(hash);
193 
194  cut_assert_true(run(test_case_names, data));
195 }
196 
197 void
199 {
200  cut_add_data("single process - single thread",
201  test_data_new(1, FALSE), test_data_free,
202  "single process - multi thread",
203  test_data_new(1, TRUE), test_data_free,
204  "multi process - single thread",
205  test_data_new(10, FALSE), test_data_free,
206  "multi process - multi thread",
207  test_data_new(10, TRUE), test_data_free);
208 }
209 
210 void
211 test_patricia_trie(gconstpointer test_data)
212 {
213  const grn_test_data *data = test_data;
214  gchar *path;
215  const gchar *test_case_names[] = {"test_stress_patricia_trie", NULL};
216 
218 
219  path = g_build_filename(base_dir, "patricia-trie", NULL);
220  g_setenv(GRN_TEST_ENV_PATRICIA_TRIE_PATH, path, TRUE);
222  trie = grn_pat_create(context, path, GRN_PAT_MAX_KEY_SIZE / 2, VALUE_SIZE, 0);
223  g_free(path);
224  cut_assert_not_null(trie);
225 
226  cut_assert_true(run(test_case_names, data));
227 }