2
Sample test application.
1
/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
5
* Copyright (C) 2011 Data Differential, http://datadifferential.com/
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 3 of the License, or (at your option) any later version.
12
* This library 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 GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
#include <libtest/common.h>
7
28
#include <sys/time.h>
8
29
#include <sys/types.h>
9
30
#include <sys/stat.h>
10
32
#include <unistd.h>
12
34
#include <fnmatch.h>
17
long int timedif(struct timeval a, struct timeval b)
21
us = a.tv_usec - b.tv_usec;
39
#ifndef __INTEL_COMPILER
40
#pragma GCC diagnostic ignored "-Wold-style-cast"
43
using namespace libtest;
45
static void stats_print(Stats *stats)
47
if (stats->collection_failed == 0 and stats->collection_success == 0)
52
Out << "\tTotal Collections\t\t\t\t" << stats->collection_total;
53
Out << "\tFailed Collections\t\t\t\t" << stats->collection_failed;
54
Out << "\tSkipped Collections\t\t\t\t" << stats->collection_skipped;
55
Out << "\tSucceeded Collections\t\t\t\t" << stats->collection_success;
57
Out << "Total\t\t\t\t" << stats->total;
58
Out << "\tFailed\t\t\t" << stats->failed;
59
Out << "\tSkipped\t\t\t" << stats->skipped;
60
Out << "\tSucceeded\t\t" << stats->success;
63
static long int timedif(struct timeval a, struct timeval b)
67
us = (long)(a.tv_usec - b.tv_usec);
23
s = a.tv_sec - b.tv_sec;
69
s = (long)(a.tv_sec - b.tv_sec);
28
77
int main(int argc, char *argv[])
31
char *collection_to_run= NULL;
33
server_startup_st *startup_ptr;
34
memcached_server_st *servers;
36
collection_st *collection;
41
memset(&world, 0, sizeof(world_st));
43
collection= world.collections;
46
world_ptr= world.create();
50
startup_ptr= (server_startup_st *)world_ptr;
51
servers= (memcached_server_st *)startup_ptr->servers;
54
collection_to_run= argv[1];
59
for (next= collection; next->name; next++)
79
bool opt_repeat= false;
80
std::string collection_to_run;
64
if (collection_to_run && fnmatch(collection_to_run, next->name, 0))
67
fprintf(stderr, "\n%s\n\n", next->name);
69
for (x= 0; run->name; run++)
74
struct timeval start_time, end_time;
77
if (wildcard && fnmatch(wildcard, run->name, 0))
80
fprintf(stderr, "Testing %s", run->name);
82
memc= memcached_create(NULL);
85
rc= memcached_server_push(memc, servers);
86
assert(rc == MEMCACHED_SUCCESS);
88
if (run->requires_flush)
90
memcached_flush(memc, 0);
94
for (loop= 0; loop < memcached_server_list_count(servers); loop++)
96
assert(memc->hosts[loop].fd == -1);
97
assert(memc->hosts[loop].cursor_active == 0);
105
if (rc != MEMCACHED_SUCCESS)
107
fprintf(stderr, "\t\t\t\t\t [ skipping ]\n");
112
gettimeofday(&start_time, NULL);
113
failed= run->function(memc);
114
gettimeofday(&end_time, NULL);
115
load_time= timedif(end_time, start_time);
117
fprintf(stderr, "\t\t\t\t\t %ld.%03ld [ failed ]\n", load_time / 1000,
120
fprintf(stderr, "\t\t\t\t\t %ld.%03ld [ ok ]\n", load_time / 1000,
124
(void)next->post(memc);
128
memcached_free(memc);
86
OPT_LIBYATL_MATCH_COLLECTION,
90
static struct option long_options[]=
92
{"repeat", no_argument, NULL, OPT_LIBYATL_REPEAT},
93
{"collection", required_argument, NULL, OPT_LIBYATL_MATCH_COLLECTION},
100
int option_rv= getopt_long(argc, argv, "", long_options, &option_index);
108
case OPT_LIBYATL_VERSION:
111
case OPT_LIBYATL_REPEAT:
115
case OPT_LIBYATL_MATCH_COLLECTION:
116
collection_to_run= optarg;
120
/* getopt_long already printed an error message. */
121
Error << "unknown option to getopt_long()";
132
fprintf(stderr, "All tests completed successfully\n\n");
135
world.destroy(world_ptr);
130
srandom((unsigned int)time(NULL));
132
if (getenv("LIBTEST_QUIET") and strcmp(getenv("LIBTEST_QUIET"), "0") == 0)
134
close(STDOUT_FILENO);
136
else if (getenv("JENKINS_URL"))
138
close(STDOUT_FILENO);
142
if (getenv("LIBTEST_TMP"))
144
snprintf(buffer, sizeof(buffer), "%s", getenv("LIBTEST_TMP"));
148
snprintf(buffer, sizeof(buffer), "%s", LIBTEST_TEMP);
151
if (chdir(buffer) == -1)
153
char getcwd_buffer[1024];
154
char *dir= getcwd(getcwd_buffer, sizeof(getcwd_buffer));
156
Error << "Unable to chdir() from " << dir << " to " << buffer << " errno:" << strerror(errno);
160
if (libtest::libtool() == NULL)
162
Error << "Failed to locate libtool";
170
exit_code= EXIT_SUCCESS;
173
fatal_assert(sigignore(SIGPIPE) == 0);
175
libtest::SignalThread signal;
176
if (not signal.setup())
178
Error << "Failed to setup signals";
187
void *creators_ptr= world.create(error);
195
Out << "SKIP " << argv[0];
202
if (getenv("TEST_COLLECTION"))
204
if (strlen(getenv("TEST_COLLECTION")))
206
collection_to_run= getenv("TEST_COLLECTION");
210
if (collection_to_run.empty() == false)
212
Out << "Only testing " << collection_to_run;
215
char *wildcard= NULL;
221
for (collection_st *next= world.collections; next and next->name and (not signal.is_shutdown()); next++)
226
if (collection_to_run.empty() == false and fnmatch(collection_to_run.c_str(), next->name, 0))
231
stats.collection_total++;
233
test_return_t collection_rc= world.startup(creators_ptr);
235
if (collection_rc == TEST_SUCCESS and next->pre)
237
collection_rc= world.runner()->pre(next->pre, creators_ptr);
240
switch (collection_rc)
246
Out << next->name << " [ failed ]";
248
signal.set_shutdown(SHUTDOWN_GRACEFUL);
252
Out << next->name << " [ skipping ]";
257
throw fatal_message("invalid return code");
260
Out << "Collection: " << next->name;
262
for (test_st *run= next->tests; run->name; run++)
264
struct timeval start_time, end_time;
265
long int load_time= 0;
267
if (wildcard && fnmatch(wildcard, run->name, 0))
272
test_return_t return_code;
274
if (test_success(return_code= world.item.startup(creators_ptr)))
276
if (test_success(return_code= world.item.flush(creators_ptr, run)))
278
// @note pre will fail is SKIPPED is returned
279
if (test_success(return_code= world.item.pre(creators_ptr)))
282
gettimeofday(&start_time, NULL);
283
assert(world.runner());
284
assert(run->test_fn);
287
return_code= world.runner()->run(run->test_fn, creators_ptr);
289
// Special case where check for the testing of the exception
291
catch (libtest::fatal &e)
293
if (fatal::is_disabled())
295
fatal::increment_disabled_counter();
296
return_code= TEST_SUCCESS;
304
gettimeofday(&end_time, NULL);
305
load_time= timedif(end_time, start_time);
309
// @todo do something if post fails
310
(void)world.item.post(creators_ptr);
312
else if (return_code == TEST_SKIPPED)
314
else if (return_code == TEST_FAILURE)
316
Error << " item.flush(failure)";
317
signal.set_shutdown(SHUTDOWN_GRACEFUL);
320
else if (return_code == TEST_SKIPPED)
322
else if (return_code == TEST_FAILURE)
324
Error << " item.startup(failure)";
325
signal.set_shutdown(SHUTDOWN_GRACEFUL);
329
catch (std::exception &e)
331
Error << "Exception was thrown: " << e.what();
332
return_code= TEST_FAILURE;
336
Error << "Unknown exception occurred";
337
return_code= TEST_FAILURE;
345
Out << "\tTesting " << run->name << "\t\t\t\t\t" << load_time / 1000 << "." << load_time % 1000 << "[ " << test_strerror(return_code) << " ]";
352
Out << "\tTesting " << run->name << "\t\t\t\t\t" << "[ " << test_strerror(return_code) << " ]";
358
Out << "\tTesting " << run->name << "\t\t\t\t\t" << "[ " << test_strerror(return_code) << " ]";
362
throw fatal_message("invalid return code");
365
if (test_failed(world.on_error(return_code, creators_ptr)))
367
Error << "Failed while running on_error()";
368
signal.set_shutdown(SHUTDOWN_GRACEFUL);
373
(void) world.runner()->post(next->post, creators_ptr);
376
if (failed == false and skipped == false)
378
stats.collection_success++;
383
stats.collection_failed++;
388
stats.collection_skipped++;
391
world.shutdown(creators_ptr);
395
if (not signal.is_shutdown())
397
signal.set_shutdown(SHUTDOWN_GRACEFUL);
400
shutdown_t status= signal.get_shutdown();
401
if (status == SHUTDOWN_FORCED)
403
Out << "Tests were aborted.";
404
exit_code= EXIT_FAILURE;
406
else if (stats.collection_failed)
408
Out << "Some test failed.";
409
exit_code= EXIT_FAILURE;
411
else if (stats.collection_skipped and stats.collection_failed and stats.collection_success)
413
Out << "Some tests were skipped.";
415
else if (stats.collection_success and stats.collection_failed == 0)
417
Out << "All tests completed successfully.";
422
Outn(); // Generate a blank to break up the messages if make check/test has been run
423
} while (exit_code == EXIT_SUCCESS and opt_repeat);
425
catch (libtest::fatal& e)
427
std::cerr << e.what() << std::endl;
429
catch (std::exception& e)
431
std::cerr << e.what() << std::endl;
435
std::cerr << "Unknown exception halted execution." << std::endl;