recover-descriptor6.cc 5.31 KB
Newer Older
1 2 3 4 5
/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
#ident "$Id$"
#ident "Copyright (c) 2007-2012 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."
6 7 8 9 10
#include "test.h"

// verify recovery of an update log entry which changes values at keys

static const int envflags = DB_INIT_MPOOL|DB_CREATE|DB_THREAD|DB_INIT_LOCK|DB_INIT_LOG|DB_INIT_TXN|DB_PRIVATE;
Yoni Fogel's avatar
Yoni Fogel committed
11 12
uint32_t four_byte_desc = 101;
uint64_t eight_byte_desc = 10101;
13 14 15

static void assert_desc_four (DB* db) {
    assert(db->descriptor->dbt.size == sizeof(four_byte_desc));
Yoni Fogel's avatar
Yoni Fogel committed
16
    assert(*(uint32_t *)(db->descriptor->dbt.data) == four_byte_desc);
17 18 19
}
static void assert_desc_eight (DB* db) {
    assert(db->descriptor->dbt.size == sizeof(eight_byte_desc));
Yoni Fogel's avatar
Yoni Fogel committed
20
    assert(*(uint32_t *)(db->descriptor->dbt.data) == eight_byte_desc);
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
}

static void run_test(void)
{
    DB_ENV *env;
    DB *db;
    DB *db2;
    DB *db3;
    DB_TXN* txn;
    DB_TXN* txn2;
    DB_TXN* txn3;
    DBT desc;
    memset(&desc, 0, sizeof(desc));
    desc.size = sizeof(four_byte_desc);
    desc.data = &four_byte_desc;

    DBT other_desc;
    memset(&other_desc, 0, sizeof(other_desc));
    other_desc.size = sizeof(eight_byte_desc);
    other_desc.data = &eight_byte_desc;

42 43 44
    { int chk_r = system("rm -rf " ENVDIR); CKERR(chk_r); }
    { int chk_r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(chk_r); }
    { int chk_r = db_env_create(&env, 0); CKERR(chk_r); }
45
    env->set_errfile(env, stderr);
46
    { int chk_r = env->open(env, ENVDIR, envflags, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(chk_r); }
47 48

    IN_TXN_COMMIT(env, NULL, txn_1, 0, {
49 50
            { int chk_r = db_create(&db, env, 0); CKERR(chk_r); }
            { int chk_r = db->open(db, txn_1, "foo.db", NULL, DB_BTREE, DB_CREATE, 0666); CKERR(chk_r); }
51 52
        });
    IN_TXN_COMMIT(env, NULL, txn_2, 0, {
53 54 55
            { int chk_r = db_create(&db2, env, 0); CKERR(chk_r); }
            { int chk_r = db2->open(db2, txn_2, "foo2.db", NULL, DB_BTREE, DB_CREATE, 0666); CKERR(chk_r); }
            { int chk_r = db2->change_descriptor(db2, txn_2, &other_desc, 0); CKERR(chk_r); }
56 57 58
            assert_desc_eight(db2);
        });
    IN_TXN_COMMIT(env, NULL, txn_3, 0, {
59 60 61
            { int chk_r = db_create(&db3, env, 0); CKERR(chk_r); }
            { int chk_r = db3->open(db3, txn_3, "foo3.db", NULL, DB_BTREE, DB_CREATE, 0666); CKERR(chk_r); }
            { int chk_r = db3->change_descriptor(db3, txn_3, &other_desc, 0); CKERR(chk_r); }
62 63 64
            assert_desc_eight(db3);
        });
    
65 66
    { int chk_r = env->txn_checkpoint(env,0,0,0); CKERR(chk_r); }

67 68 69
    { int chk_r = env->txn_begin(env, NULL, &txn, 0); CKERR(chk_r); }
    { int chk_r = db->change_descriptor(db, txn, &desc, 0); CKERR(chk_r); }
    { int chk_r = txn->commit(txn,0); CKERR(chk_r); }
70

71 72 73
    { int chk_r = env->txn_begin(env, NULL, &txn2, 0); CKERR(chk_r); }
    { int chk_r = db2->change_descriptor(db2, txn2, &desc, 0); CKERR(chk_r); }
    { int chk_r = txn2->abort(txn2); CKERR(chk_r); }
74

75 76
    { int chk_r = env->txn_begin(env, NULL, &txn3, 0); CKERR(chk_r); }
    { int chk_r = db3->change_descriptor(db3, txn3, &desc, 0); CKERR(chk_r); }
77 78 79 80 81 82 83 84 85 86 87 88

    toku_hard_crash_on_purpose();
}


static void run_recover(void)
{
    DB_ENV *env;
    DB *db;
    DB *db2;
    DB *db3;

89
    { int chk_r = db_env_create(&env, 0); CKERR(chk_r); }
90
    env->set_errfile(env, stderr);
91
    { int chk_r = env->open(env, ENVDIR, envflags|DB_RECOVER, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(chk_r); }
92

93 94
    { int chk_r = db_create(&db, env, 0); CKERR(chk_r); }
    { int chk_r = db->open(db, NULL, "foo.db", NULL, DB_BTREE, DB_AUTO_COMMIT, 0666); CKERR(chk_r); }
95
    assert_desc_four(db);
96
    { int chk_r = db->close(db, 0); CKERR(chk_r); }
97

98 99
    { int chk_r = db_create(&db2, env, 0); CKERR(chk_r); }
    { int chk_r = db2->open(db2, NULL, "foo2.db", NULL, DB_BTREE, DB_AUTO_COMMIT, 0666); CKERR(chk_r); }
100
    assert_desc_eight(db2);
101
    { int chk_r = db2->close(db2, 0); CKERR(chk_r); }
102

103 104
    { int chk_r = db_create(&db3, env, 0); CKERR(chk_r); }
    { int chk_r = db3->open(db3, NULL, "foo3.db", NULL, DB_BTREE, DB_AUTO_COMMIT, 0666); CKERR(chk_r); }
105
    assert_desc_eight(db3);
106
    { int chk_r = db3->close(db3, 0); CKERR(chk_r); }
107

108
    { int chk_r = env->close(env, 0); CKERR(chk_r); }
109 110 111 112 113 114 115 116 117
}

static int usage(void)
{
    return 1;
}

int test_main(int argc, char * const argv[])
{
Yoni Fogel's avatar
Yoni Fogel committed
118 119
    bool do_test = false;
    bool do_recover = false;
120 121 122 123 124 125 126 127 128 129 130 131 132 133

    for (int i = 1; i < argc; i++) {
        char * const arg = argv[i];
        if (strcmp(arg, "-v") == 0) {
            verbose++;
            continue;
        }
        if (strcmp(arg, "-q") == 0) {
            verbose--;
            if (verbose < 0)
                verbose = 0;
            continue;
        }
        if (strcmp(arg, "--test") == 0) {
Yoni Fogel's avatar
Yoni Fogel committed
134
            do_test = true;
135 136 137
            continue;
        }
        if (strcmp(arg, "--recover") == 0) {
Yoni Fogel's avatar
Yoni Fogel committed
138
            do_recover = true;
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
            continue;
        }
        if (strcmp(arg, "--help") == 0) {
            return usage();
        }
    }

    if (do_test) {
        run_test();
    }
    if (do_recover) {
        run_recover();
    }

    return 0;
}