45 #include <sys/types.h>
53 #ifdef XAPIAN_HAS_REMOTE_BACKEND
61 if (mkdir(path.c_str(), 0700) == -1 && errno != EEXIST) {
62 FAIL_TEST(
"Can't make temporary directory");
66 static size_t do_read(
int fd,
char *
p,
size_t desired)
70 ssize_t c = read(fd,
p, desired);
71 if (c == 0)
return total;
73 if (errno == EINTR)
continue;
83 static void do_write(
int fd,
const char *
p,
size_t n)
86 ssize_t c = write(fd,
p, n);
88 if (errno == EINTR)
continue;
99 const string& destpath,
104 FAIL_TEST(
"Open failed (when opening '" << srcpath <<
"')");
107 FD fdout(
open(destpath.c_str(), O_WRONLY | O_CREAT | O_TRUNC |
O_BINARY, 0666));
109 FAIL_TEST(
"Open failed (when creating '" << destpath <<
"')");
112 const int BUFSIZE = 1024;
114 size_t total_bytes = 0;
116 size_t thiscopy = tocopy > BUFSIZE ? BUFSIZE : tocopy;
117 size_t bytes =
do_read(fdin, buf, thiscopy);
118 if (thiscopy != bytes) {
119 FAIL_TEST(
"Couldn't read desired number of bytes from changeset");
122 total_bytes += bytes;
126 if (
close(fdout) == -1)
136 int expected_changesets,
137 int expected_fullcopies,
138 bool expected_changed,
139 bool full_copy =
false)
141 FD fd(
open(changesetpath.c_str(), O_WRONLY | O_CREAT | O_TRUNC |
O_BINARY, 0666));
143 FAIL_TEST(
"Open failed (when creating a new changeset file at '"
144 << changesetpath <<
"')");
159 int expected_changesets,
160 int expected_fullcopies,
161 bool expected_changed)
165 FAIL_TEST(
"Open failed (when reading changeset file at '"
166 << changesetpath <<
"')");
173 bool client_changed =
false;
179 client_changed =
true;
184 client_changed =
true;
197 const string & tempdir,
198 int expected_changesets,
199 int expected_fullcopies,
200 bool expected_changed,
201 bool full_copy =
false)
203 string changesetpath = tempdir +
"/changeset";
232 #define set_max_changesets(N) setenv("XAPIAN_MAX_CHANGESETS", #N, 1)
241 #define UNSET_MAX_CHANGESETS_AFTERWARDS unset_max_changesets_helper_ ezlxq
250 #ifdef XAPIAN_HAS_REMOTE_BACKEND
252 string tempdir =
".replicatmp";
265 string replicapath = tempdir +
"/replica";
275 int count =
replicate(master, replica, tempdir, 0, 1,
true);
284 count =
replicate(master, replica, tempdir, 0, 0,
false);
296 int count =
replicate(master, replica, tempdir, 0, 0,
false);
308 count =
replicate(master, replica, tempdir, 2, 0,
true);
329 #ifdef XAPIAN_HAS_REMOTE_BACKEND
333 string tempdir =
".replicatmp";
342 string replicapath = tempdir +
"/replica";
346 string replica2path = tempdir +
"/replica2";
430 #ifdef XAPIAN_HAS_REMOTE_BACKEND
434 const string & tempdir,
435 int expected_changesets,
436 int expected_fullcopies,
437 bool expected_changed)
439 string changesetpath = tempdir +
"/changeset";
444 string brokenchangesetpath = tempdir +
"/changeset_broken";
445 auto filesize =
file_size(changesetpath);
447 FAIL_TEST(
"Can't stat '" << changesetpath <<
"'");
451 while (len < filesize) {
452 copylen =
truncated_copy(changesetpath, brokenchangesetpath, len);
454 tout <<
"Trying replication with a changeset truncated to " << len <<
455 " bytes, from " << filesize <<
" bytes\n";
458 expected_changesets, expected_fullcopies,
460 if (len < 30 || len >= filesize - 10) {
467 if (len >= filesize - 10) {
477 #ifdef XAPIAN_HAS_REMOTE_BACKEND
479 string tempdir =
".replicatmp";
488 string replicapath = tempdir +
"/replica";
528 #ifdef XAPIAN_HAS_REMOTE_BACKEND
530 string tempdir =
".replicatmp";
539 string replicapath = tempdir +
"/replica";
551 int count =
replicate(master, replica, tempdir, 0, 1,
true);
564 count =
replicate(master, replica, tempdir, 1, 0,
true);
584 count =
replicate(master, replica, tempdir, 1, 0,
true);
606 count =
replicate(master, replica, tempdir, 0, 1,
true);
626 #ifdef XAPIAN_HAS_REMOTE_BACKEND
628 string tempdir =
".replicatmp";
637 string replicapath = tempdir +
"/replica";
649 int count =
replicate(master, replica, tempdir, 0, 1,
true);
662 count =
replicate(master, replica, tempdir, 1, 0,
true);
678 count =
replicate(master, replica, tempdir, 1, 0,
true);
694 count =
replicate(master, replica, tempdir, 1, 0,
true);
718 count =
replicate(master, replica, tempdir, 1, 0,
true);
734 count =
replicate(master, replica, tempdir, 1, 0,
true);
757 #ifdef XAPIAN_HAS_REMOTE_BACKEND
759 string tempdir =
".replicatmp";
768 string replicapath = tempdir +
"/replica";
779 rm_rf(masterpath +
"1");
780 cp_R(masterpath, masterpath +
"1");
787 int count =
replicate(master, replica, tempdir, 0, 1,
true);
797 count =
replicate(master1, replica, tempdir, 0, 0,
false);
801 count =
replicate(master1, replica, tempdir, 0, 1,
true,
true);
808 count =
replicate(master, replica, tempdir, 2, 0,
true);
823 #ifdef XAPIAN_HAS_REMOTE_BACKEND
825 string tempdir =
".replicatmp";
833 string replicapath = tempdir +
"/replica";
850 int count =
replicate(master, replica, tempdir, 0, 1,
true);
860 string d = replicapath;
874 if (entry->
d_name[0] ==
'.')
continue;
879 int fd =
open(file.c_str(), O_WRONLY|O_TRUNC);
890 int count =
replicate(master, replica, tempdir, 0, 1,
true);
static int apply_changeset(const string &changesetpath, Xapian::DatabaseReplica &replica, int expected_changesets, int expected_fullcopies, bool expected_changed)
#define UNSET_MAX_CHANGESETS_AFTERWARDS
static void mktmpdir(const string &path)
static void do_write(int fd, const char *p, size_t n)
static void get_changeset(const string &changesetpath, Xapian::DatabaseMaster &master, Xapian::DatabaseReplica &replica, int expected_changesets, int expected_fullcopies, bool expected_changed, bool full_copy=false)
static size_t do_read(int fd, char *p, size_t desired)
static file_size_type truncated_copy(const string &srcpath, const string &destpath, file_size_type tocopy)
#define set_max_changesets(N)
static int replicate(Xapian::DatabaseMaster &master, Xapian::DatabaseReplica &replica, const string &tempdir, int expected_changesets, int expected_fullcopies, bool expected_changed, bool full_copy=false)
static void replicate_with_brokenness(Xapian::DatabaseMaster &master, Xapian::DatabaseReplica &replica, const string &tempdir, int expected_changesets, int expected_fullcopies, bool expected_changed)
static void check_equal_dbs(const string &masterpath, const string &replicapath)
static void rmtmpdir(const string &path)
DEFINE_TESTCASE(replicate1, replicas)
std::string get_named_writable_database_path(const std::string &name)
Xapian::WritableDatabase get_writable_database_again()
Xapian::WritableDatabase get_named_writable_database(const std::string &name, const std::string &source)
test functionality of the Xapian API
#define SKIP_TEST_FOR_BACKEND(B)
Access to a master database for replication.
void write_changesets_to_fd(int fd, const std::string &start_revision, ReplicationInfo *info) const
Write a set of changesets for upgrading the database to a file.
Access to a database replica, for applying replication to it.
bool apply_next_changeset(ReplicationInfo *info, double reader_close_time)
Read and apply the next changeset.
void set_read_fd(int fd)
Set the file descriptor to read changesets from.
std::string get_revision_info() const
Get a string describing the current revision of the replica.
An indexed database of documents.
static size_t check(std::string_view path, int opts=0, std::ostream *out=NULL)
Check the integrity of a database or database table.
void close()
Close the database.
TermIterator allterms_end(std::string_view={}) const noexcept
End iterator corresponding to allterms_begin(prefix).
Xapian::doccount get_doccount() const
Get the number of documents in the database.
Xapian::docid get_lastdocid() const
Get the highest document id which has been used in the database.
TermIterator allterms_begin(std::string_view prefix={}) const
Start iterating all terms in the database with a given prefix.
std::string get_uuid() const
Get the UUID for the database.
Class representing a document.
void set_data(std::string_view data)
Set the document data.
void add_term(std::string_view term, Xapian::termcount wdf_inc=1)
Add a term to this document.
void add_posting(std::string_view term, Xapian::termpos term_pos, Xapian::termcount wdf_inc=1)
Add a posting for a term.
Indicates a problem communicating with a remote database.
Class for iterating over a list of terms.
This class provides read/write access to a database.
void commit()
Commit pending modifications.
Xapian::docid add_document(const Xapian::Document &doc)
Add a document to the database.
test database contents and consistency.
void errno_to_string(int e, string &s)
Convert errno value to std::string, thread-safe if possible.
Wrapper class around a file descriptor to avoid leaks.
Utility functions for testing files.
std::make_unsigned_t< off_t > file_size_type
Unsigned return type of file_size() function.
bool file_exists(const char *path)
Test if a file exists.
file_size_type file_size(const char *path)
Returns the size of a file.
struct dirent * readdir(DIR *)
DIR * opendir(const char *)
Database open(std::string_view host, unsigned int port, unsigned timeout=10000, unsigned connect_timeout=10000)
Construct a Database object for read-only access to a remote database accessed via a TCP connection.
Replication support for Xapian databases.
include <dirent.h>, with alternative implementation for windows.
include <fcntl.h>, but working around broken platforms.
include <sys/stat.h> with portability enhancements
<unistd.h>, but with compat.
Provide setenv() with compatibility versions.
Information about the steps involved in performing a replication.
bool changed
True if and only if the replication corresponds to a change in the live version of the database.
int fullcopy_count
Number of times a full database copy was performed.
int changeset_count
Number of changesets applied.
~unset_max_changesets_helper_()
unset_max_changesets_helper_()
void dbcheck(const Xapian::Database &db, Xapian::doccount expected_doccount, Xapian::docid expected_lastdocid)
Check consistency of database and statistics.
string postlist_to_string(const Xapian::Database &db, const string &tname)
Convert the list of postings in a postlist to a string.
std::ostringstream tout
The debug printing stream.
a generic test suite engine
#define FAIL_TEST(MSG)
Fail the current testcase with message MSG.
#define TEST_EQUAL(a, b)
Test for equality of two things.
#define TEST(a)
Test a condition, without an additional explanation for failure.
Xapian-specific test helper functions and macros.
#define TEST_EXCEPTION(TYPE, CODE)
Check that CODE throws exactly Xapian exception TYPE.
void cp_R(const std::string &src, const std::string &dest)
Recursively copy a directory.
void rm_rf(const string &filename)
Remove a directory and contents, just like the Unix "rm -rf" command.
C++ function versions of useful Unix commands.
Public interfaces for the Xapian library.