Ticket #434: replicate_reopen_tests.patch

File replicate_reopen_tests.patch, 5.3 KB (added by Richard Boulton, 15 years ago)

Some partially written tests for this issue, which may (or may not) be helpful when implementing a fix for this.

  • api_replicate.cc

     
    22 *
    33 * Copyright 2008 Lemur Consulting Ltd
    44 * Copyright 2009 Olly Betts
     5 * Copyright 2010 Richard Boulton
    56 *
    67 * This program is free software; you can redistribute it and/or
    78 * modify it under the terms of the GNU General Public License as
     
    2627#include <xapian.h>
    2728
    2829#include "apitest.h"
     30#include "dbcheck.h"
    2931#include "safeerrno.h"
    3032#include "safefcntl.h"
    3133#include "safesysstat.h"
     
    112114    Xapian::Database db2(path2);
    113115
    114116    TEST_EQUAL(db1.get_doccount(), db2.get_doccount());
     117
     118    // FIXME - do a proper check here.
    115119}
    116120
    117121// #######################################################################
     
    191195    rmtmpdir(tempdir);
    192196    return true;
    193197}
     198
     199static void write_stub(const string & stubpath, const string & contents) {
     200    int fd = open(stubpath.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
     201    TEST_EQUAL(write(fd, contents.c_str(), contents.size()), (ssize_t)contents.size());
     202    close(fd);
     203}
     204
     205// Test of reopen of a database which has been replaced underneath the reader.
     206DEFINE_TESTCASE(reopen1, flint || chert || brass) {
     207    // Create a directory with a XAPIANDB file pointing to a sub database.
     208    string topdbdir = get_named_writable_database_path("reopen1");
     209    mkdir(topdbdir.c_str(), 0755);
     210    string stubpath = topdbdir + "/XAPIANDB";
     211    string subdb1path = topdbdir + "/db1";
     212    string subdb2path = topdbdir + "/db2";
     213
     214    write_stub(stubpath, "auto db1");
     215
     216    // Make the sub database, and add document to it.
     217    {
     218        Xapian::WritableDatabase db(get_named_writable_database("reopen1/db1"));
     219        for (int i = 0; i != 1000; ++i) {
     220            Xapian::Document doc1;
     221            doc1.add_term("hello");
     222            db.add_document(doc1);
     223        }
     224        db.commit();
     225        db.close();
     226    }
     227
     228    // Open the database through the stub directory, through the stub, and
     229    // directly.
     230    Xapian::Database db1(topdbdir);
     231    Xapian::Database db2(stubpath);
     232    Xapian::Database db3(subdb1path);
     233    dbcheck(db1, 1000, 1000);
     234    dbcheck(db2, 1000, 1000);
     235    dbcheck(db3, 1000, 1000);
     236    check_equal_dbs(topdbdir, stubpath);
     237    check_equal_dbs(topdbdir, subdb1path);
     238
     239    // Delete the old database.
     240    rm_rf(subdb1path);
     241
     242    // Make a new database in the original location.
     243    {
     244        Xapian::WritableDatabase db(get_named_writable_database("reopen1/db1"));
     245        Xapian::Document doc1;
     246        doc1.add_term("hola");
     247        doc1.add_term("hello");
     248        db.add_document(doc1);
     249        db.commit();
     250        db.add_document(doc1);
     251        db.commit();
     252        db.delete_document(1);
     253        db.commit();
     254        db.close();
     255    }
     256
     257    // Reopen the database and check.
     258    db1.reopen();
     259    db2.reopen();
     260    db3.reopen();
     261    dbcheck(db1, 1, 2);
     262    dbcheck(db2, 1, 2);
     263    dbcheck(db3, 1, 2);
     264    check_equal_dbs(topdbdir, stubpath);
     265    check_equal_dbs(topdbdir, subdb1path);
     266 
     267    return true;
     268}
     269
     270// Test of reopen of a database opened through a stub path.
     271DEFINE_TESTCASE(reopen2, flint || chert || brass) {
     272    // Create a directory with a XAPIANDB file pointing to a sub database.
     273    string topdbdir = get_named_writable_database_path("reopen2");
     274    mkdir(topdbdir.c_str(), 0755);
     275    string stubpath = topdbdir + "/XAPIANDB";
     276    string subdb1path = topdbdir + "/db1";
     277    string subdb2path = topdbdir + "/db2";
     278
     279    write_stub(stubpath, "auto db1");
     280
     281    // Make the sub database, and add document to it.
     282    {
     283        Xapian::WritableDatabase db(get_named_writable_database("reopen2/db1"));
     284        Xapian::Document doc1;
     285        doc1.add_term("hello");
     286        db.add_document(doc1);
     287        db.commit();
     288        db.close();
     289    }
     290
     291    // Open the database through the stub directory, through the stub, and
     292    // directly.
     293    Xapian::Database db1(topdbdir);
     294    Xapian::Database db2(stubpath);
     295    Xapian::Database db3(subdb1path);
     296    dbcheck(db1, 1, 1);
     297    dbcheck(db2, 1, 1);
     298    dbcheck(db3, 1, 1);
     299    check_equal_dbs(topdbdir, stubpath);
     300    check_equal_dbs(topdbdir, subdb1path);
     301
     302    // Make a new database, and change the stub to point to it.
     303    {
     304        Xapian::WritableDatabase db(get_named_writable_database("reopen2/db2"));
     305        Xapian::Document doc1;
     306        doc1.add_term("world");
     307        db.add_document(doc1);
     308        db.commit();
     309        db.close();
     310    }
     311    write_stub(stubpath, "auto db2");
     312
     313    // Delete the old database.
     314    rm_rf(subdb1path);
     315
     316    // Reopen the database and check.
     317    db1.reopen();
     318    db2.reopen();
     319    db3.reopen();
     320    dbcheck(db1, 1, 1);
     321    dbcheck(db2, 1, 1);
     322    dbcheck(db3, 1, 1);
     323    check_equal_dbs(topdbdir, stubpath);
     324    check_equal_dbs(topdbdir, subdb2path);
     325
     326    // Make a new database in the original location.
     327    rm_rf(subdb1path);
     328    {
     329        Xapian::WritableDatabase db(get_named_writable_database("reopen2/db1"));
     330        Xapian::Document doc1;
     331        doc1.add_term("hola");
     332        doc1.add_term("hello");
     333        db.add_document(doc1);
     334        db.commit();
     335        db.add_document(doc1);
     336        db.commit();
     337        db.delete_document(1);
     338        db.commit();
     339        db.close();
     340    }
     341
     342    // Reopen the database and check.
     343    db1.reopen();
     344    db2.reopen();
     345    db3.reopen();
     346    dbcheck(db1, 1, 2);
     347    dbcheck(db2, 1, 2);
     348    dbcheck(db3, 1, 2);
     349    check_equal_dbs(topdbdir, stubpath);
     350    check_equal_dbs(topdbdir, subdb2path);
     351 
     352    return true;
     353}