Commit bfe190f7 authored by Bradley C. Kuszmaul's avatar Bradley C. Kuszmaul Committed by Yoni Fogel

#2642 runs with -r 1000 and no valgrind problems. The problem is we must...

#2642 runs with -r 1000 and no valgrind problems.  The problem is we must actually call fclose even when injecting errors in bad_fclose.  [t:2642] Refs #2642

git-svn-id: file:///svn/toku/tokudb@20487 c7de825b-a66e-492c-adef-691d508d4ae1
parent b3800e01
...@@ -44,7 +44,8 @@ ...@@ -44,7 +44,8 @@
#include "ydb-internal.h" #include "ydb-internal.h"
enum test_type {commit, // close loader, commit txn enum test_type {event, // any event
commit, // close loader, commit txn
abort_txn, // close loader, abort txn abort_txn, // close loader, abort txn
abort_loader, // abort loader, abort txn abort_loader, // abort loader, abort txn
abort_via_poll, // close loader, but poll function returns non-zero, abort txn abort_via_poll, // close loader, but poll function returns non-zero, abort txn
...@@ -66,6 +67,8 @@ int NUM_ROWS=100000; ...@@ -66,6 +67,8 @@ int NUM_ROWS=100000;
//static int NUM_ROWS=50000000; //static int NUM_ROWS=50000000;
int CHECK_RESULTS=0; int CHECK_RESULTS=0;
int USE_PUTS=0; int USE_PUTS=0;
int event_trigger_lo=0; // what event triggers to use?
int event_trigger_hi =0; // 0 and 0 mean none.
int assert_temp_files = 0; int assert_temp_files = 0;
enum {MAGIC=311}; enum {MAGIC=311};
...@@ -85,6 +88,10 @@ static void free_inames(DBT* inames); ...@@ -85,6 +88,10 @@ static void free_inames(DBT* inames);
// how many different system calls are intercepted with error injection // how many different system calls are intercepted with error injection
#define NUM_ERR_TYPES 7 #define NUM_ERR_TYPES 7
int64_t event_count = 0; // number of calls of all types so far (in this run)
int64_t event_count_nominal = 0; // number of calls of all types in the nominally error-free run.
int64_t event_count_trigger = 0; // which call will we complain about
int fwrite_count = 0; int fwrite_count = 0;
int fwrite_count_nominal = 0; // number of fwrite calls for normal operation, initially zero int fwrite_count_nominal = 0; // number of fwrite calls for normal operation, initially zero
int fwrite_count_trigger = 0; // sequence number of fwrite call that will fail (zero disables induced failure) int fwrite_count_trigger = 0; // sequence number of fwrite call that will fail (zero disables induced failure)
...@@ -114,45 +121,31 @@ int fclose_count_nominal = 0; // number of fclose calls for normal operation, i ...@@ -114,45 +121,31 @@ int fclose_count_nominal = 0; // number of fclose calls for normal operation, i
int fclose_count_trigger = 0; // sequence number of fclose call that will fail (zero disables induced failure) int fclose_count_trigger = 0; // sequence number of fclose call that will fail (zero disables induced failure)
const char * fwrite_str = "fwrite";
const char * write_str = "write";
const char * pwrite_str = "pwrite";
const char * fdopen_str = "fdopen";
const char * fopen_str = "fopen";
const char * open_str = "open";
const char * fclose_str = "fclose";
static const char * static const char *
err_type_str (enum test_type t) { err_type_str (enum test_type t) {
const char * rval;
switch(t) { switch(t) {
case enospc_f: case event: return "anyevent";
rval = fwrite_str; break; case enospc_f: return "fwrite";
case enospc_w: case enospc_w: return "write";
rval = write_str; break; case enospc_p: return "pwrite";
case enospc_p: case einval_fdo: return "fdopen";
rval = pwrite_str; break; case einval_fo: return "fopen";
case einval_fdo: case einval_o: return "open";
rval = fdopen_str; break; case enospc_fc: return "fclose";
case einval_fo: case commit: assert(0);
rval = fopen_str; break; case abort_txn: assert(0);
case einval_o: case abort_loader: assert(0);
rval = open_str; break; case abort_via_poll: assert(0);
case enospc_fc: }
rval = fclose_str; break; // I know that Barry prefers the single-return case, but writing the code this way means that the compiler will complain if I forget something in the enum. -Bradley
default: assert(0);
assert(0);
}
return rval;
} }
static size_t bad_fwrite (const void *ptr, size_t size, size_t nmemb, FILE *stream) { static size_t bad_fwrite (const void *ptr, size_t size, size_t nmemb, FILE *stream) {
fwrite_count++; fwrite_count++;
event_count++;
size_t r; size_t r;
if (fwrite_count_trigger == fwrite_count) { if (fwrite_count_trigger == fwrite_count || event_count == event_count_trigger) {
errno = ENOSPC; errno = ENOSPC;
r = -1; r = -1;
} else { } else {
...@@ -169,7 +162,8 @@ static ssize_t ...@@ -169,7 +162,8 @@ static ssize_t
bad_write(int fd, const void * bp, size_t len) { bad_write(int fd, const void * bp, size_t len) {
ssize_t r; ssize_t r;
write_count++; write_count++;
if (write_count_trigger == write_count) { event_count++;
if (write_count_trigger == write_count || event_count == event_count_trigger) {
errno = ENOSPC; errno = ENOSPC;
r = -1; r = -1;
} else { } else {
...@@ -182,7 +176,8 @@ static ssize_t ...@@ -182,7 +176,8 @@ static ssize_t
bad_pwrite (int fd, const void *buf, size_t len, toku_off_t off) { bad_pwrite (int fd, const void *buf, size_t len, toku_off_t off) {
int r; int r;
pwrite_count++; pwrite_count++;
if (pwrite_count_trigger == pwrite_count) { event_count++;
if (pwrite_count_trigger == pwrite_count || event_count == event_count_trigger) {
errno = ENOSPC; errno = ENOSPC;
r = -1; r = -1;
} else { } else {
...@@ -197,7 +192,8 @@ static FILE * ...@@ -197,7 +192,8 @@ static FILE *
bad_fdopen(int fd, const char * mode) { bad_fdopen(int fd, const char * mode) {
FILE * rval; FILE * rval;
fdopen_count++; fdopen_count++;
if (fdopen_count_trigger == fdopen_count) { event_count++;
if (fdopen_count_trigger == fdopen_count || event_count == event_count_trigger) {
errno = EINVAL; errno = EINVAL;
rval = NULL; rval = NULL;
} else { } else {
...@@ -210,7 +206,8 @@ static FILE * ...@@ -210,7 +206,8 @@ static FILE *
bad_fopen(const char *filename, const char *mode) { bad_fopen(const char *filename, const char *mode) {
FILE * rval; FILE * rval;
fopen_count++; fopen_count++;
if (fopen_count_trigger == fopen_count) { event_count++;
if (fopen_count_trigger == fopen_count || event_count == event_count_trigger) {
errno = EINVAL; errno = EINVAL;
rval = NULL; rval = NULL;
} else { } else {
...@@ -224,7 +221,8 @@ static int ...@@ -224,7 +221,8 @@ static int
bad_open(const char *path, int oflag, int mode) { bad_open(const char *path, int oflag, int mode) {
int rval; int rval;
open_count++; open_count++;
if (open_count_trigger == open_count) { event_count++;
if (open_count_trigger == open_count || event_count == event_count_trigger) {
errno = EINVAL; errno = EINVAL;
rval = -1; rval = -1;
} else { } else {
...@@ -239,11 +237,14 @@ static int ...@@ -239,11 +237,14 @@ static int
bad_fclose(FILE * stream) { bad_fclose(FILE * stream) {
int rval; int rval;
fclose_count++; fclose_count++;
if (fclose_count_trigger == fclose_count) { event_count++;
errno = ENOSPC; // Must close the stream even in the "error case" because otherwise there is no way to get the memory back.
rval = -1; rval = fclose(stream);
} else { if (rval==0) {
rval = fclose(stream); if (fclose_count_trigger == fclose_count || event_count == event_count_trigger) {
errno = ENOSPC;
rval = -1;
}
} }
return rval; return rval;
} }
...@@ -748,6 +749,7 @@ static void run_test(enum test_type t, int trigger) ...@@ -748,6 +749,7 @@ static void run_test(enum test_type t, int trigger)
generate_permute_tables(); generate_permute_tables();
event_count_trigger = event_count = 0;
fwrite_count_trigger = fwrite_count = 0; fwrite_count_trigger = fwrite_count = 0;
write_count_trigger = write_count = 0; write_count_trigger = write_count = 0;
pwrite_count_trigger = pwrite_count = 0; pwrite_count_trigger = pwrite_count = 0;
...@@ -762,6 +764,8 @@ static void run_test(enum test_type t, int trigger) ...@@ -762,6 +764,8 @@ static void run_test(enum test_type t, int trigger)
case abort_loader: case abort_loader:
case abort_via_poll: case abort_via_poll:
break; break;
case event:
event_count_trigger = trigger; break;
case enospc_f: case enospc_f:
fwrite_count_trigger = trigger; break; fwrite_count_trigger = trigger; break;
case enospc_w: case enospc_w:
...@@ -821,6 +825,13 @@ static void run_all_tests(void) { ...@@ -821,6 +825,13 @@ static void run_all_tests(void) {
if (verbose) printf("\n\nTesting loader with loader close and txn abort\n"); if (verbose) printf("\n\nTesting loader with loader close and txn abort\n");
run_test(abort_txn, 0); run_test(abort_txn, 0);
if (event_trigger_lo || event_trigger_hi) {
if (verbose) printf("\n\nDoing events %d-%d\n", event_trigger_lo, event_trigger_hi);
for (int i=event_trigger_lo; i<=event_trigger_hi; i++)
run_test(event, i);
return;
}
enum test_type et[NUM_ERR_TYPES] = {enospc_f, enospc_w, enospc_p, einval_fdo, einval_fo, einval_o, enospc_fc}; enum test_type et[NUM_ERR_TYPES] = {enospc_f, enospc_w, enospc_p, einval_fdo, einval_fo, einval_o, enospc_fc};
int * nomp[NUM_ERR_TYPES] = {&fwrite_count_nominal, &write_count_nominal, &pwrite_count_nominal, int * nomp[NUM_ERR_TYPES] = {&fwrite_count_nominal, &write_count_nominal, &pwrite_count_nominal,
&fdopen_count_nominal, &fopen_count_nominal, &open_count_nominal, &fclose_count_nominal}; &fdopen_count_nominal, &fopen_count_nominal, &open_count_nominal, &fclose_count_nominal};
...@@ -868,6 +879,7 @@ int test_main(int argc, char * const *argv) { ...@@ -868,6 +879,7 @@ int test_main(int argc, char * const *argv) {
db_env_set_loader_size_factor(1); db_env_set_loader_size_factor(1);
assert_temp_files = 1; assert_temp_files = 1;
run_all_tests(); run_all_tests();
printf("\nTotal event_trigger count is %" PRId64 ". (Use with -t N M, where 1<=N<=M<=%" PRId64 "\n", event_count, event_count);
return 0; return 0;
} }
...@@ -903,6 +915,12 @@ static void do_args(int argc, char * const argv[]) { ...@@ -903,6 +915,12 @@ static void do_args(int argc, char * const argv[]) {
} else if (strcmp(argv[0], "-p")==0) { } else if (strcmp(argv[0], "-p")==0) {
USE_PUTS = LOADER_USE_PUTS; USE_PUTS = LOADER_USE_PUTS;
printf("Using puts\n"); printf("Using puts\n");
} else if (strcmp(argv[0], "-t")==0) {
assert(argc>2);
argc--; argv++;
event_trigger_lo = atoi(argv[0]);
argc--; argv++;
event_trigger_hi = atoi(argv[0]);
} else { } else {
fprintf(stderr, "Unknown arg: %s\n", argv[0]); fprintf(stderr, "Unknown arg: %s\n", argv[0]);
resultcode=1; resultcode=1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment