Commit 9d292108 authored by Rich Prohaska's avatar Rich Prohaska Committed by Yoni Fogel

closes[t:2637] common brtloader error injector source

git-svn-id: file:///svn/toku/tokudb@20687 c7de825b-a66e-492c-adef-691d508d4ae1
parent 85bfc804
/* -*- mode: C; c-basic-offset: 4 -*- */
#ident "$Id: $"
#ident "Copyright (c) 2010 Tokutek Inc. All rights reserved."
#ident "The technology is licensed by the Massachusetts Institute of Technology, Rutgers State University of New Jersey, and the Research Foundation of State University of New York at Stony Brook under United States of America Serial No. 11/760379 and to the patents and/or patent applications resulting from it."
#ifndef TOKU_BRTLOADER_ERROR_INJECTOR_H
#define TOKU_BRTLOADER_ERROR_INJECTOR_H
#if defined(__cplusplus)
extern "C" {
#if 0
}
#endif
#endif
static int event_count, event_count_trigger;
__attribute__((__unused__))
static void reset_event_counts(void) {
event_count = event_count_trigger = 0;
}
__attribute__((__unused__))
static void event_hit(void) {
}
__attribute__((__unused__))
static int event_add_and_fetch(void) {
return __sync_add_and_fetch(&event_count, 1);
}
static int do_user_errors = 0;
__attribute__((__unused__))
static int loader_poll_callback(void *UU(extra), float UU(progress)) {
int r;
if (do_user_errors && event_count_trigger == event_add_and_fetch()) {
event_hit();
r = 1;
} else {
r = 0;
}
return r;
}
static int do_write_errors = 0;
__attribute__((__unused__))
static size_t bad_fwrite (const void *ptr, size_t size, size_t nmemb, FILE *stream) {
size_t r;
if (do_write_errors && event_count_trigger == event_add_and_fetch()) {
event_hit();
errno = ENOSPC;
r = -1;
} else {
r = fwrite(ptr, size, nmemb, stream);
if (r!=nmemb) {
errno = ferror(stream);
}
}
return r;
}
__attribute__((__unused__))
static ssize_t bad_write(int fd, const void * bp, size_t len) {
ssize_t r;
if (do_write_errors && event_count_trigger == event_add_and_fetch()) {
event_hit();
errno = ENOSPC;
r = -1;
} else {
r = write(fd, bp, len);
}
return r;
}
__attribute__((__unused__))
static ssize_t bad_pwrite(int fd, const void * bp, size_t len, toku_off_t off) {
ssize_t r;
if (do_write_errors && event_count_trigger == event_add_and_fetch()) {
event_hit();
errno = ENOSPC;
r = -1;
} else {
r = pwrite(fd, bp, len, off);
}
return r;
}
static int do_malloc_errors = 0;
static int my_malloc_count = 0, my_big_malloc_count = 0;
static int my_realloc_count = 0, my_big_realloc_count = 0;
static size_t my_big_malloc_limit = 64*1024;
__attribute__((__unused__))
static void reset_my_malloc_counts(void) {
my_malloc_count = my_big_malloc_count = 0;
my_realloc_count = my_big_realloc_count = 0;
}
__attribute__((__unused__))
static void *my_malloc(size_t n) {
void *caller = __builtin_return_address(0);
if (!((void*)toku_malloc <= caller && caller <= (void*)toku_free))
goto skip;
(void) __sync_fetch_and_add(&my_malloc_count, 1); // my_malloc_count++;
if (n >= my_big_malloc_limit) {
(void) __sync_fetch_and_add(&my_big_malloc_count, 1); // my_big_malloc_count++;
if (do_malloc_errors) {
caller = __builtin_return_address(1);
if ((void*)toku_xmalloc <= caller && caller <= (void*)toku_malloc_report)
goto skip;
if (event_add_and_fetch()== event_count_trigger) {
event_hit();
errno = ENOMEM;
return NULL;
}
}
}
skip:
return malloc(n);
}
static int do_realloc_errors = 0;
__attribute__((__unused__))
static void *my_realloc(void *p, size_t n) {
void *caller = __builtin_return_address(0);
if (!((void*)toku_realloc <= caller && caller <= (void*)toku_free))
goto skip;
(void) __sync_add_and_fetch(&my_realloc_count, 1); // my_realloc_count++;
if (n >= my_big_malloc_limit) {
(void) __sync_add_and_fetch(&my_big_realloc_count, 1); // my_big_realloc_count++;
if (do_realloc_errors) {
caller = __builtin_return_address(1);
if ((void*)toku_xrealloc <= caller && caller <= (void*)toku_malloc_report)
goto skip;
if (event_add_and_fetch() == event_count_trigger) {
event_hit();
errno = ENOMEM;
return NULL;
}
}
}
skip:
return realloc(p, n);
}
#if defined(__cplusplus)
}
#endif
#endif
...@@ -3,95 +3,44 @@ ...@@ -3,95 +3,44 @@
#ident "Copyright (c) 2010 Tokutek Inc. All rights reserved." #ident "Copyright (c) 2010 Tokutek Inc. All rights reserved."
#ident "The technology is licensed by the Massachusetts Institute of Technology, Rutgers State University of New Jersey, and the Research Foundation of State University of New York at Stony Brook under United States of America Serial No. 11/760379 and to the patents and/or patent applications resulting from it." #ident "The technology is licensed by the Massachusetts Institute of Technology, Rutgers State University of New Jersey, and the Research Foundation of State University of New York at Stony Brook under United States of America Serial No. 11/760379 and to the patents and/or patent applications resulting from it."
// The purpose of this test is to test the error return from the generate callback // The purpose of this test is force errors returned from the generate function
#define DONT_DEPRECATE_MALLOC #define DONT_DEPRECATE_MALLOC
#define DONT_DEPRECATE_WRITES #define DONT_DEPRECATE_WRITES
#include "test.h" #include "test.h"
#include "brtloader.h" #include "brtloader.h"
#include "brtloader-internal.h" #include "brtloader-internal.h"
#include "brtloader-error-injector.h"
#include "memory.h" #include "memory.h"
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {
#endif #endif
#if 0 static void copy_dbt(DBT *dest, const DBT *src) {
assert(dest->flags & DB_DBT_REALLOC);
static int my_malloc_count = 0; dest->data = toku_realloc(dest->data, src->size);
static int my_malloc_trigger = 0; dest->size = src->size;
memcpy(dest->data, src->data, src->size);
static void set_my_malloc_trigger(int n) {
my_malloc_count = 0;
my_malloc_trigger = n;
}
static void *my_malloc(size_t n) {
my_malloc_count++;
if (my_malloc_count == my_malloc_trigger) {
errno = ENOSPC;
return NULL;
} else
return malloc(n);
} }
#endif static int generate(DB *dest_db, DB *src_db, DBT *dest_key, DBT *dest_val, const DBT *src_key, const DBT *src_val, void *extra) {
if (verbose) printf("%s %p %p %p %p %p %p %p\n", __FUNCTION__, dest_db, src_db, dest_key, dest_val, src_key, src_val, extra);
static int write_count, write_count_trigger, write_enospc;
static void reset_write_counts(void) {
write_count = write_count_trigger = write_enospc = 0;
}
static void count_enospc(void) {
write_enospc++;
}
static size_t bad_fwrite (const void *ptr, size_t size, size_t nmemb, FILE *stream) {
write_count++;
size_t r;
if (write_count_trigger == write_count) {
count_enospc();
errno = ENOSPC;
r = -1;
} else {
r = fwrite(ptr, size, nmemb, stream);
if (r!=nmemb) {
errno = ferror(stream);
}
}
return r;
}
static ssize_t bad_write(int fd, const void * bp, size_t len) { assert(dest_db == NULL); assert(src_db == NULL); assert(extra == NULL);
ssize_t r;
write_count++;
if (write_count_trigger == write_count) {
count_enospc();
errno = ENOSPC;
r = -1;
} else {
r = write(fd, bp, len);
}
return r;
}
static ssize_t bad_pwrite(int fd, const void * bp, size_t len, toku_off_t off) { int result;
ssize_t r; if (event_count_trigger == event_add_and_fetch()) {
write_count++; event_hit();
if (write_count_trigger == write_count) { result = EINVAL;
count_enospc();
errno = ENOSPC;
r = -1;
} else { } else {
r = pwrite(fd, bp, len, off); copy_dbt(dest_key, src_key);
copy_dbt(dest_val, src_val);
result = 0;
} }
return r;
}
static int generate(DB *dest_db, DB *src_db, DBT *dest_key, DBT *dest_val, const DBT *src_key, const DBT *src_val, void *extra) { if (verbose) printf("%s %d\n", __FUNCTION__, result);
dest_db = dest_db; src_db = src_db; dest_key = dest_key; dest_val = dest_val; src_key = src_key; src_val = src_val; extra = extra; return result;
return EINVAL;
} }
static int qsort_compare_ints (const void *a, const void *b) { static int qsort_compare_ints (const void *a, const void *b) {
...@@ -111,8 +60,8 @@ static int compare_int(DB *dest_db, const DBT *akey, const DBT *bkey) { ...@@ -111,8 +60,8 @@ static int compare_int(DB *dest_db, const DBT *akey, const DBT *bkey) {
static void populate_rowset(struct rowset *rowset, int seq, int nrows) { static void populate_rowset(struct rowset *rowset, int seq, int nrows) {
for (int i = 0; i < nrows; i++) { for (int i = 0; i < nrows; i++) {
int k = seq + i; int k = seq * nrows + i;
int v = seq + i; int v = seq * nrows + i;
DBT key = { .size = sizeof k, .data = &k }; DBT key = { .size = sizeof k, .data = &k };
DBT val = { .size = sizeof v, .data = &v }; DBT val = { .size = sizeof v, .data = &v };
add_row(rowset, &key, &val); add_row(rowset, &key, &val);
...@@ -149,28 +98,24 @@ static void test_extractor(int nrows, int nrowsets, BOOL expect_fail) { ...@@ -149,28 +98,24 @@ static void test_extractor(int nrows, int nrowsets, BOOL expect_fail) {
populate_rowset(rowset[i], i, nrows); populate_rowset(rowset[i], i, nrows);
} }
// setup error injection
brtloader_set_os_fwrite(bad_fwrite);
toku_set_func_write(bad_write);
toku_set_func_pwrite(bad_pwrite);
// feed rowsets to the extractor // feed rowsets to the extractor
for (int i = 0; i < nrowsets; i++) { for (int i = 0; i < nrowsets; i++) {
r = queue_enq(loader->primary_rowset_queue, rowset[i], 1, NULL); r = queue_enq(loader->primary_rowset_queue, rowset[i], 1, NULL);
assert(r == 0); assert(r == 0);
} }
brtloader_set_os_fwrite(bad_fwrite); r = toku_brt_loader_finish_extractor(loader);
toku_set_func_write(bad_write); assert(r == 0);
toku_set_func_pwrite(bad_pwrite);
int loader_error;
r = toku_brt_loader_get_error(loader, &loader_error);
assert(r == 0);
// verify the temp files assert(expect_fail ? loader_error != 0 : loader_error == 0);
// abort the brtloader. this ends the test // abort the brtloader. this ends the test
r = toku_brt_loader_abort(loader, TRUE); r = toku_brt_loader_abort(loader, TRUE);
assert(r == 0); assert(r == 0);
expect_fail = expect_fail;
} }
static int nrows = 1; static int nrows = 1;
...@@ -213,12 +158,12 @@ int test_main (int argc, const char *argv[]) { ...@@ -213,12 +158,12 @@ int test_main (int argc, const char *argv[]) {
test_extractor(nrows, nrowsets, FALSE); test_extractor(nrows, nrowsets, FALSE);
// run tests // run tests
int write_error_limit = write_count; int event_limit = event_count;
if (verbose) printf("write_error_limit=%d\n", write_error_limit); if (verbose) printf("event_limit=%d\n", event_limit);
for (int i = 1; i <= write_error_limit; i++) { for (int i = 1; i <= event_limit; i++) {
reset_write_counts(); reset_event_counts();
write_count_trigger = i; event_count_trigger = i;
test_extractor(nrows, nrowsets, TRUE); test_extractor(nrows, nrowsets, TRUE);
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "test.h" #include "test.h"
#include "brtloader.h" #include "brtloader.h"
#include "brtloader-internal.h" #include "brtloader-internal.h"
#include "brtloader-error-injector.h"
#include "memory.h" #include "memory.h"
#if defined(__cplusplus) #if defined(__cplusplus)
...@@ -20,129 +21,6 @@ extern "C" { ...@@ -20,129 +21,6 @@ extern "C" {
#endif #endif
#endif #endif
static int event_count, event_count_trigger;
static void reset_event_counts(void) {
event_count = event_count_trigger = 0;
}
static void event_hit(void) {
}
static int event_add_and_fetch(void) {
return __sync_add_and_fetch(&event_count, 1);
}
static int do_user_errors = 0;
static int loader_poll_callback(void *UU(extra), float UU(progress)) {
int r;
if (do_user_errors && event_count_trigger == event_add_and_fetch()) {
event_hit();
r = 1;
} else {
r = 0;
}
return r;
}
static int do_write_errors = 0;
static size_t bad_fwrite (const void *ptr, size_t size, size_t nmemb, FILE *stream) {
size_t r;
if (do_write_errors && event_count_trigger == event_add_and_fetch()) {
event_hit();
errno = ENOSPC;
r = -1;
} else {
r = fwrite(ptr, size, nmemb, stream);
if (r!=nmemb) {
errno = ferror(stream);
}
}
return r;
}
static ssize_t bad_write(int fd, const void * bp, size_t len) {
ssize_t r;
if (do_write_errors && event_count_trigger == event_add_and_fetch()) {
event_hit();
errno = ENOSPC;
r = -1;
} else {
r = write(fd, bp, len);
}
return r;
}
static ssize_t bad_pwrite(int fd, const void * bp, size_t len, toku_off_t off) {
ssize_t r;
if (do_write_errors && event_count_trigger == event_add_and_fetch()) {
event_hit();
errno = ENOSPC;
r = -1;
} else {
r = pwrite(fd, bp, len, off);
}
return r;
}
static int do_malloc_errors = 0;
static int my_malloc_count = 0, my_big_malloc_count = 0;
static int my_realloc_count = 0, my_big_realloc_count = 0;
static size_t my_big_malloc_limit = 64*1024;
static void reset_my_malloc_counts(void) {
my_malloc_count = my_big_malloc_count = 0;
my_realloc_count = my_big_realloc_count = 0;
}
static void *my_malloc(size_t n) {
void *caller = __builtin_return_address(0);
if (!((void*)toku_malloc <= caller && caller <= (void*)toku_free))
goto skip;
(void) __sync_add_and_fetch(&my_malloc_count, 1); // my_malloc_count++;
if (n >= my_big_malloc_limit) {
(void) __sync_add_and_fetch(&my_big_malloc_count, 1); // my_big_malloc_count++;
if (do_malloc_errors) {
caller = __builtin_return_address(1);
if ((void*)toku_xmalloc <= caller && caller <= (void*)toku_malloc_report)
goto skip;
if (event_add_and_fetch()== event_count_trigger) {
event_hit();
errno = ENOMEM;
return NULL;
}
}
}
skip:
return malloc(n);
}
static int do_realloc_errors = 0;
static void *my_realloc(void *p, size_t n) {
void *caller = __builtin_return_address(0);
if (!((void*)toku_realloc <= caller && caller <= (void*)toku_free))
goto skip;
(void) __sync_add_and_fetch(&my_realloc_count, 1); // my_realloc_count++;
if (n >= my_big_malloc_limit) {
(void) __sync_add_and_fetch(&my_big_realloc_count, 1); // my_big_realloc_count++;
if (do_realloc_errors) {
caller = __builtin_return_address(1);
if ((void*)toku_xrealloc <= caller && caller <= (void*)toku_malloc_report)
goto skip;
if (event_add_and_fetch() == event_count_trigger) {
event_hit();
errno = ENOMEM;
return NULL;
}
}
}
skip:
return realloc(p, n);
}
static void copy_dbt(DBT *dest, const DBT *src) { static void copy_dbt(DBT *dest, const DBT *src) {
assert(dest->flags & DB_DBT_REALLOC); assert(dest->flags & DB_DBT_REALLOC);
dest->data = toku_realloc(dest->data, src->size); dest->data = toku_realloc(dest->data, src->size);
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "includes.h" #include "includes.h"
#include "test.h" #include "test.h"
#include "brtloader-internal.h" #include "brtloader-internal.h"
#include "brtloader-error-injector.h"
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {
...@@ -18,129 +19,6 @@ extern "C" { ...@@ -18,129 +19,6 @@ extern "C" {
#endif #endif
#endif #endif
static int event_count, event_count_trigger;
static void reset_event_counts(void) {
event_count = event_count_trigger = 0;
}
static void event_hit(void) {
}
static int event_add_and_fetch(void) {
return __sync_add_and_fetch(&event_count, 1);
}
static int do_user_errors = 0;
static int loader_poll_callback(void *UU(extra), float UU(progress)) {
int r;
if (do_user_errors && event_count_trigger == event_add_and_fetch()) {
event_hit();
r = 1;
} else {
r = 0;
}
return r;
}
static int do_write_errors = 0;
static size_t bad_fwrite (const void *ptr, size_t size, size_t nmemb, FILE *stream) {
size_t r;
if (do_write_errors && event_count_trigger == event_add_and_fetch()) {
event_hit();
errno = ENOSPC;
r = -1;
} else {
r = fwrite(ptr, size, nmemb, stream);
if (r!=nmemb) {
errno = ferror(stream);
}
}
return r;
}
static ssize_t bad_write(int fd, const void * bp, size_t len) {
ssize_t r;
if (do_write_errors && event_count_trigger == event_add_and_fetch()) {
event_hit();
errno = ENOSPC;
r = -1;
} else {
r = write(fd, bp, len);
}
return r;
}
static ssize_t bad_pwrite(int fd, const void * bp, size_t len, toku_off_t off) {
ssize_t r;
if (do_write_errors && event_count_trigger == event_add_and_fetch()) {
event_hit();
errno = ENOSPC;
r = -1;
} else {
r = pwrite(fd, bp, len, off);
}
return r;
}
static int do_malloc_errors = 0;
static int my_malloc_count = 0, my_big_malloc_count = 0;
static int my_realloc_count = 0, my_big_realloc_count = 0;
static size_t my_big_malloc_limit = 64*1024;
static void reset_my_malloc_counts(void) {
my_malloc_count = my_big_malloc_count = 0;
my_realloc_count = my_big_realloc_count = 0;
}
static void *my_malloc(size_t n) {
void *caller = __builtin_return_address(0);
if (!((void*)toku_malloc <= caller && caller <= (void*)toku_free))
goto skip;
(void) __sync_fetch_and_add(&my_malloc_count, 1); // my_malloc_count++;
if (n >= my_big_malloc_limit) {
(void) __sync_fetch_and_add(&my_big_malloc_count, 1); // my_big_malloc_count++;
if (do_malloc_errors) {
caller = __builtin_return_address(1);
if ((void*)toku_xmalloc <= caller && caller <= (void*)toku_malloc_report)
goto skip;
if (event_add_and_fetch()== event_count_trigger) {
event_hit();
errno = ENOMEM;
return NULL;
}
}
}
skip:
return malloc(n);
}
static int do_realloc_errors = 0;
static void *my_realloc(void *p, size_t n) {
void *caller = __builtin_return_address(0);
if (!((void*)toku_realloc <= caller && caller <= (void*)toku_free))
goto skip;
(void) __sync_add_and_fetch(&my_realloc_count, 1); // my_realloc_count++;
if (n >= my_big_malloc_limit) {
(void) __sync_add_and_fetch(&my_big_realloc_count, 1); // my_big_realloc_count++;
if (do_realloc_errors) {
caller = __builtin_return_address(1);
if ((void*)toku_xrealloc <= caller && caller <= (void*)toku_malloc_report)
goto skip;
if (event_add_and_fetch() == event_count_trigger) {
event_hit();
errno = ENOMEM;
return NULL;
}
}
}
skip:
return realloc(p, n);
}
static int qsort_compare_ints (const void *a, const void *b) { static int qsort_compare_ints (const void *a, const void *b) {
int avalue = *(int*)a; int avalue = *(int*)a;
int bvalue = *(int*)b; int bvalue = *(int*)b;
......
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