Branch data Line data Source code
1 : : /** \file testrunner.cc
2 : : * \brief Run multiple tests for different backends.
3 : : */
4 : : /* Copyright 2008,2009 Lemur Consulting Ltd
5 : : * Copyright 2008,2009,2010 Olly Betts
6 : : *
7 : : * This program is free software; you can redistribute it and/or
8 : : * modify it under the terms of the GNU General Public License as
9 : : * published by the Free Software Foundation; either version 2 of the
10 : : * License, or (at your option) any later version.
11 : : *
12 : : * This program 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
15 : : * GNU General Public License for more details.
16 : : *
17 : : * You should have received a copy of the GNU General Public License
18 : : * along with this program; if not, write to the Free Software
19 : : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
20 : : * USA
21 : : */
22 : :
23 : : #include <config.h>
24 : :
25 : : #include "testrunner.h"
26 : :
27 : : #include "testsuite.h"
28 : : #include "backendmanager.h"
29 : : #include "backendmanager_brass.h"
30 : : #include "backendmanager_chert.h"
31 : : #include "backendmanager_flint.h"
32 : : #include "backendmanager_inmemory.h"
33 : : #include "backendmanager_multi.h"
34 : : #include "backendmanager_remoteprog.h"
35 : : #include "backendmanager_remotetcp.h"
36 : :
37 : : #include "stringutils.h"
38 : : #include <iostream>
39 : :
40 : : using namespace std;
41 : :
42 : : BackendManager * backendmanager;
43 : :
44 : : /** A description of the properties which a particular backend supports.
45 : : */
46 : : struct BackendProperties {
47 : : const char * name;
48 : : const char * properties;
49 : : };
50 : :
51 : : /** A list of the properties of each backend.
52 : : */
53 : : static BackendProperties backend_properties[] = {
54 : : { "none", "" },
55 : : { "inmemory", "backend,positional,writable,metadata,valuestats,inmemory" },
56 : : { "brass", "backend,transactions,positional,writable,spelling,metadata,"
57 : : "synonyms,replicas,valuestats,generated,brass" },
58 : : { "chert", "backend,transactions,positional,writable,spelling,metadata,"
59 : : "synonyms,replicas,valuestats,generated,chert" },
60 : : { "flint", "backend,transactions,positional,writable,spelling,metadata,"
61 : : "synonyms,replicas,generated,flint" },
62 : : { "multi_brass", "backend,positional,valuestats,multi" },
63 : : { "multi_chert", "backend,positional,valuestats,multi" },
64 : : { "multi_flint", "backend,positional,multi" },
65 : : { "remoteprog_brass", "backend,remote,transactions,positional,valuestats,writable,metadata" },
66 : : { "remotetcp_brass", "backend,remote,transactions,positional,valuestats,writable,metadata" },
67 : : { "remoteprog_chert", "backend,remote,transactions,positional,valuestats,writable,metadata" },
68 : : { "remotetcp_chert", "backend,remote,transactions,positional,valuestats,writable,metadata" },
69 : : { "remoteprog_flint", "backend,remote,transactions,positional,writable,metadata" },
70 : : { "remotetcp_flint", "backend,remote,transactions,positional,writable,metadata" },
71 : : { NULL, NULL }
72 : : };
73 : :
74 [ # # ][ # # ]: 1 : TestRunner::~TestRunner() { }
[ - + ]
75 : :
76 : : void
77 : 14 : TestRunner::set_properties(const string & properties)
78 : : {
79 : : // Clear the flags
80 : 14 : backend = false;
81 : 14 : remote = false;
82 : 14 : transactions = false;
83 : 14 : positional = false;
84 : 14 : writable = false;
85 : 14 : multi = false;
86 : 14 : spelling = false;
87 : 14 : synonyms = false;
88 : 14 : metadata = false;
89 : 14 : replicas = false;
90 : 14 : valuestats = false;
91 : 14 : generated = false;
92 : 14 : inmemory = false;
93 : 14 : brass = false;
94 : 14 : chert = false;
95 : 14 : flint = false;
96 : :
97 : : // Read the properties specified in the string
98 : 14 : string::size_type pos = 0;
99 : 14 : string::size_type comma = 0;
100 [ + + ][ + - ]: 104 : while (pos != string::npos) {
101 : 90 : comma = properties.find(',', pos + 1);
102 : 90 : string propname = properties.substr(pos, comma - pos);
103 : :
104 : : // Set the flags according to the property.
105 [ + + ]: 90 : if (propname.empty()) {}
106 [ + + ]: 89 : else if (propname == "backend")
107 : 13 : backend = true;
108 [ + + ]: 76 : else if (propname == "remote")
109 : 6 : remote = true;
110 [ + + ]: 70 : else if (propname == "transactions")
111 : 9 : transactions = true;
112 [ + + ]: 61 : else if (propname == "positional")
113 : 13 : positional = true;
114 [ + + ]: 48 : else if (propname == "writable")
115 : 10 : writable = true;
116 [ + + ]: 38 : else if (propname == "multi")
117 : 3 : multi = true;
118 [ + + ]: 35 : else if (propname == "spelling")
119 : 3 : spelling = true;
120 [ + + ]: 32 : else if (propname == "synonyms")
121 : 3 : synonyms = true;
122 [ + + ]: 29 : else if (propname == "metadata")
123 : 10 : metadata = true;
124 [ + + ]: 19 : else if (propname == "replicas")
125 : 3 : replicas = true;
126 [ + + ]: 16 : else if (propname == "valuestats")
127 : 9 : valuestats = true;
128 [ + + ]: 7 : else if (propname == "generated")
129 : 3 : generated = true;
130 [ + + ]: 4 : else if (propname == "inmemory")
131 : 1 : inmemory = true;
132 [ + + ]: 3 : else if (propname == "brass")
133 : 1 : brass = true;
134 [ + + ]: 2 : else if (propname == "chert")
135 : 1 : chert = true;
136 [ + - ]: 1 : else if (propname == "flint")
137 : 1 : flint = true;
138 : : else
139 : 0 : throw Xapian::InvalidArgumentError("Unknown property '" + propname + "' found in proplist");
140 : :
141 [ + + ]: 90 : if (comma == string::npos)
142 : : break;
143 : 76 : pos = comma + 1;
144 : : }
145 : 14 : }
146 : :
147 : : bool
148 : 14 : TestRunner::use_backend(const string & backend_name)
149 : : {
150 [ + - ]: 14 : if (user_backend.empty())
151 : 14 : return true;
152 [ # # ]: 0 : if (backend_name == user_backend)
153 : 0 : return true;
154 [ # # ]: 0 : if (startswith(backend_name, user_backend + "_"))
155 : 0 : return true;
156 : 14 : return false;
157 : : }
158 : :
159 : : void
160 : 14 : TestRunner::set_properties_for_backend(const string & backend_name)
161 : : {
162 : 14 : const char * propstring = NULL;
163 [ + - ]: 105 : for (const BackendProperties * i = backend_properties; i->name; ++i) {
164 [ + + ]: 105 : if (backend_name == i->name) {
165 : 14 : propstring = i->properties;
166 : 14 : break;
167 : : }
168 : : }
169 [ - + ]: 14 : if (!propstring)
170 : 0 : throw Xapian::InvalidArgumentError("Unknown backend " + backend_name);
171 : 14 : set_properties(propstring);
172 : 14 : }
173 : :
174 : : void
175 : 14 : TestRunner::do_tests_for_backend(BackendManager * manager)
176 : : {
177 : 14 : string backend_name = manager->get_dbtype();
178 [ + - ]: 14 : if (use_backend(backend_name)) {
179 : 14 : backendmanager = manager;
180 : 14 : backendmanager->set_datadir(srcdir + "/testdata/");
181 : 14 : set_properties_for_backend(backend_name);
182 : 14 : cout << "Running tests with backend \"" << backendmanager->get_dbtype() << "\"..." << endl;
183 : 14 : result_so_far = max(result_so_far, run());
184 : 14 : }
185 : 14 : }
186 : :
187 : : int
188 : 1 : TestRunner::run_tests(int argc, char ** argv)
189 : : {
190 : 1 : result_so_far = 0;
191 : : try {
192 : 1 : test_driver::add_command_line_option("backend", 'b', &user_backend);
193 : 1 : test_driver::parse_command_line(argc, argv);
194 : 1 : srcdir = test_driver::get_srcdir();
195 : :
196 : : {
197 : 1 : BackendManager m;
198 : 1 : do_tests_for_backend(&m);
199 : : }
200 : :
201 : : #ifdef XAPIAN_HAS_INMEMORY_BACKEND
202 : : {
203 : 1 : BackendManagerInMemory m;
204 : 1 : do_tests_for_backend(&m);
205 : : }
206 : : #endif
207 : :
208 : : #ifdef XAPIAN_HAS_BRASS_BACKEND
209 : : {
210 : 1 : BackendManagerBrass m;
211 : 1 : do_tests_for_backend(&m);
212 : : }
213 : : #endif
214 : :
215 : : #ifdef XAPIAN_HAS_CHERT_BACKEND
216 : : {
217 : 1 : BackendManagerChert m;
218 : 1 : do_tests_for_backend(&m);
219 : : }
220 : : #endif
221 : :
222 : : #ifdef XAPIAN_HAS_FLINT_BACKEND
223 : : {
224 : 1 : BackendManagerFlint m;
225 : 1 : do_tests_for_backend(&m);
226 : : }
227 : : #endif
228 : :
229 : : #ifdef XAPIAN_HAS_BRASS_BACKEND
230 : : {
231 : 1 : BackendManagerMulti m("brass");
232 : 1 : do_tests_for_backend(&m);
233 : : }
234 : : #endif
235 : : #ifdef XAPIAN_HAS_CHERT_BACKEND
236 : : {
237 : 1 : BackendManagerMulti m("chert");
238 : 1 : do_tests_for_backend(&m);
239 : : }
240 : : #endif
241 : : #ifdef XAPIAN_HAS_FLINT_BACKEND
242 : : {
243 : 1 : BackendManagerMulti m("flint");
244 : 1 : do_tests_for_backend(&m);
245 : : }
246 : : #endif
247 : :
248 : : #ifdef XAPIAN_HAS_REMOTE_BACKEND
249 : : #ifdef XAPIAN_HAS_BRASS_BACKEND
250 : : {
251 : 1 : BackendManagerRemoteProg m("brass");
252 : 1 : do_tests_for_backend(&m);
253 : : }
254 : : {
255 : 1 : BackendManagerRemoteTcp m("brass");
256 : 1 : do_tests_for_backend(&m);
257 : : }
258 : : #endif
259 : : #ifdef XAPIAN_HAS_CHERT_BACKEND
260 : : {
261 : 1 : BackendManagerRemoteProg m("chert");
262 : 1 : do_tests_for_backend(&m);
263 : : }
264 : : {
265 : 1 : BackendManagerRemoteTcp m("chert");
266 : 1 : do_tests_for_backend(&m);
267 : : }
268 : : #endif
269 : : #ifdef XAPIAN_HAS_FLINT_BACKEND
270 : : {
271 : 1 : BackendManagerRemoteProg m("flint");
272 : 1 : do_tests_for_backend(&m);
273 : : }
274 : : {
275 : 1 : BackendManagerRemoteTcp m("flint");
276 : 1 : do_tests_for_backend(&m);
277 : : }
278 : : #endif
279 : : #endif
280 : 0 : } catch (const Xapian::Error &e) {
281 : 0 : cerr << "\nTest harness failed with " << e.get_description() << endl;
282 : 0 : return 1;
283 : 0 : } catch (const std::string &e) {
284 : 0 : cerr << "\nTest harness failed with \"" << e << "\"" << endl;
285 : 0 : return 1;
286 : 0 : } catch (const char * e) {
287 : 0 : cout << e << endl;
288 : 0 : return 1;
289 : : }
290 : 1 : return result_so_far;
291 [ + - ][ + - ]: 15 : }
|