27 #define XAPIAN_DEPRECATED(X) X 44 #ifdef HAVE_SOCKETPAIR 58 #if !defined __WIN32__ && !defined __CYGWIN__ && !defined __OS2__ 59 mode_t old_umask = umask(022);
67 TEST(stat(path.c_str(), &statbuf) == 0);
92 for (
int i = 0; i != 20; ++i) {
145 bool multi = (db1.
size() > 1);
147 doc = i.get_document();
174 get_dbtype().find(
"remote") == string::npos) {
210 get_dbtype().find(
"remote") == string::npos) {
273 #if !defined __WIN32__ && !defined __CYGWIN__ && !defined __OS2__ 274 int old_stdin = dup(0);
275 int old_stdout = dup(1);
317 int fd =
::open((path +
"/flintlock").c_str(), O_RDONLY);
339 TEST(db_as_database.locked());
343 TEST(db_as_database.locked());
347 SKIP_TEST(
"Database::locked() not supported on this platform");
349 db_as_database = rdb;
351 TEST(db_as_database.locked());
353 db_as_database.close();
359 TEST(db_as_database.locked());
365 TEST(!db_as_database.locked());
413 SKIP_TEST(
"Database::locked() not supported on this platform");
441 mset = enquire.
get_mset(0, 10, NULL, &mdecider));
471 for (
int i = 0; i < 10000; ++i) {
547 for (
int i = 0; i < N; ++i) {
562 FAIL_TEST(
"Expected DatabaseModifiedError wasn't thrown");
570 FAIL_TEST(
"Expected DatabaseModifiedError wasn't thrown");
582 for (
int i = 100; i < 120; ++i) {
586 for (
int j = 0; j < 50; ++j) {
595 for (
int k = 0; k < 1000; ++k) {
600 SKIP_TEST(
"didn't manage to trigger DatabaseModifiedError");
607 const char * value0 =
608 "ABBCDEFGHIJKLMMNOPQQRSTTUUVVWXYZZaabcdefghhijjkllmnopqrsttuvwxyz";
609 const char * value1 =
610 "EMLEMMMMMMMNMMLMELEDNLEDMLMLDMLMLMLMEDGFHPOPBAHJIQJNGRKCGF";
657 const char * value0 =
"AAABCDEEFGHIIJJKLLMNNOOPPQQRSTTUVWXYZ";
658 const char * value1 =
"MLEMNMLMLMEDEDEMLEMLMLMLPOAHGF";
705 for (
int n = 1; n != 50; ++n) {
707 for (
int i = 1; i != 50; ++i) {
733 const char * p =
"VJ=QC]LUNTaARLI;715RR^];A4O=P4ZG<2CS4EM^^VS[A6QENR";
734 for (
int d = 0; p[d]; ++d) {
735 int l = int(p[d] -
'0');
737 for (
int n = 1; n < l; ++n) {
739 if (n % (d + 1) == 0) {
756 for (
unsigned int i = 1; i < msetall.
size(); ++i) {
768 std::vector<Xapian::Query> q;
779 for (
unsigned int i = 1; i < msetall.
size(); ++i) {
788 static const unsigned t1[] = {2, 4, 6, 8, 10};
789 static const unsigned t2[] = {6, 7, 8, 11, 12, 13, 14, 15, 16, 17};
790 static const unsigned t3[] = {3, 7, 8, 11, 12, 13, 14, 15, 16, 17};
792 for (
unsigned i = 1; i <= 17; ++i) {
796 for (
unsigned i : t1) {
801 for (
unsigned i : t2) {
805 doc.add_term(
"T2_lowfreq");
807 doc.add_value(2,
"1");
810 for (
unsigned i : t3) {
814 doc.add_term(
"T3_lowfreq");
816 doc.add_value(3,
"1");
835 tout <<
"Checking q2 OR q3\n";
840 tout <<
"Checking q2l OR q3\n";
845 tout <<
"Checking q2 OR q3l\n";
850 tout <<
"Checking v2 OR q3\n";
855 tout <<
"Checking q2 OR v3\n";
907 static const char *
const phrase_words[] = {
"phrase",
"near" };
925 mset = enquire.
get_mset(0xfffffff0, 1);
928 mset = enquire.
get_mset(1, 0xfffffff0);
986 static const char* terms[] = {
"two",
"all",
"paragraph",
"banana"};
988 for (
auto& test :
tests) {
991 tout << op <<
" should give " << hits <<
" hits\n";
1025 static const struct {
Xapian::docid did;
double wt; } expected[] = {
1026 { 2, 1.2058248004573934864 },
1027 { 4, 0.81127876655507624726 },
1028 { 1, 0.17309550762546158098 },
1029 { 3, 0.14609528172558261527 }
1043 static const struct {
Xapian::docid did;
double wt; } expected2[] = {
1044 { 6, 0.73354729848273669823 },
1045 { 2, 0.45626501034348893038 }
1048 TEST_EQUAL(mset.
size(),
sizeof(expected2) /
sizeof(expected2[0]));
1090 mkdir(db_dir.c_str(), 0755);
1091 db_dir +=
"/db__blocksize1";
1098 static const unsigned bad_sizes[] = {
1099 65537, 8000, 2000, 1024, 16, 7, 3, 1, 0
1101 for (
size_t i = 0; i <
sizeof(bad_sizes) /
sizeof(bad_sizes[0]); ++i) {
1102 size_t block_size = bad_sizes[i];
1116 mkdir(db_dir.c_str(), 0755);
1117 db_dir +=
"/db__notermlist1";
1139 for (
int i = 100; i < 120; ++i) {
1144 for (
int j = 0; j < 50; ++j) {
1149 for (
int k = 0; k < 1000; ++k) {
1161 #if !defined __WIN32__ && !defined __CYGWIN__ && !defined __OS2__ 1164 (void)chmod(path.c_str(), 0700);
1165 mkdir(path.c_str(), 0777);
1166 mkdir((path +
"/sub").c_str(), 0777);
1168 TEST(chmod(path.c_str(), 0500) == 0);
1178 (void)chmod(path.c_str(), 0700);
1181 TEST(chmod(path.c_str(), 0700) == 0);
1200 static const char *
const qterms[] = {
"katrina",
"hurricane" };
1206 static const char *
const qterms2[] = {
"hurricane",
"katrina" };
1217 #if defined HAVE_FORK && defined HAVE_SOCKETPAIR 1219 if (socketpair(AF_UNIX, SOCK_STREAM|
SOCK_CLOEXEC, PF_UNSPEC, fds) < 0) {
1222 if (fds[1] >= FD_SETSIZE)
1223 SKIP_TEST(
"socketpair() gave fd >= FD_SETSIZE");
1224 if (fcntl(fds[1], F_SETFL, O_NONBLOCK) < 0)
1225 FAIL_TEST(
"fcntl() failed to set O_NONBLOCK");
1226 pid_t child = fork();
1232 while (read(fds[0], &ch, 1) < 0) { }
1237 if (write(fds[0],
"y", 1)) { }
1239 if (write(fds[0],
"l", 1)) { }
1242 if (write(fds[0], m.data(), m.size())) { }
1244 if (write(fds[0],
"o", 1)) { }
1252 if (write(fds[1],
"", 1) != 1)
1253 FAIL_TEST(
"Failed to signal to child process");
1256 int r = read(fds[1], result,
sizeof(result));
1258 if (errno == EAGAIN) {
1267 }
else if (r >= 1) {
1268 if (result[0] ==
'y') {
1281 kill(child, SIGKILL);
1283 while (waitpid(child, &status, 0) < 0) {
1284 if (errno != EINTR)
break;
1289 if (result[0] ==
'y') {
1296 FD_SET(fds[1], &fdset);
1297 int sr = select(fds[1] + 1, &fdset, NULL, NULL, &tv);
1302 }
else if (sr == -1) {
1303 if (errno == EINTR || errno == EAGAIN)
1305 tout <<
"select() failed with errno=" << errno <<
": " 1310 r = read(fds[1], result,
sizeof(result));
1313 tout <<
"read() failed with errno=" << errno <<
": " 1317 }
else if (r == 0) {
1327 kill(child, SIGKILL);
1329 while (waitpid(child, &status, 0) < 0) {
1330 if (errno != EINTR)
break;
1333 tout << string(result, r) <<
'\n';
1340 #if !defined __WIN32__ && !defined __CYGWIN__ && !defined __OS2__ 1342 for (
int i = 0; i < 3; ++i) {
1346 for (
int j = 0; j < 3; ++j) {
1348 TEST_REL(lseek(j, 0, SEEK_CUR), <, 0);
1357 for (
int fd = 0; fd < 3; ++fd) {
1361 int flags = fcntl(fd, F_GETFL);
1364 }
else if ((flags & O_ACCMODE) != O_RDWR) {
1370 TEST(S_ISSOCK(sb.st_mode));
1379 for (
int j = 0; j < 3; ++j) {
1386 for (
int j = 0; j < 3; ++j) {
1401 for (
int repeat = 0; repeat < 10; ++repeat) {
1403 tout <<
"iteration #" << repeat <<
'\n';
1405 const int ITEMS = 10;
1407 int offset = max(free_id, ITEMS * 2) - (ITEMS * 2);
1408 int limit = offset + (ITEMS * 2);
1410 mset = enq.
get_mset(offset, limit);
1412 (void)m1.get_document().get_value(0);
1415 for (
int i = free_id; i <= free_id + ITEMS; ++i) {
1417 const string &
id =
str(i);
1418 string qterm =
"Q" + id;
1426 mset = enq.
get_mset(offset, limit);
1428 (void)m2.get_document().get_value(0);
1447 TEST(old_key <= key);
1462 off_t offset = 1234;
1466 const string & tmp_path = db_path +
"-embedded";
1467 ofstream out(tmp_path, fstream::trunc|fstream::binary);
1469 out << ifstream(db_path, fstream::binary).rdbuf();
1474 lseek(fd, offset, SEEK_SET);
1481 lseek(fd, offset, SEEK_SET);
1482 size_t check_errors =
1493 static const char *
const words[4] = {
1494 "blank",
"test",
"paragraph",
"banana" 1505 static const char *
const words2[4] = {
1506 "queri",
"test",
"paragraph",
"word" 1615 static const char*
const terms1[] = {
"foo",
"baz" };
1616 static const char*
const terms2[] = {
"baz",
"foo" };
1620 begin(terms1), end(terms1), 10));
1624 begin(terms2), end(terms2), 10));
1628 begin(terms1), end(terms1), 10));
1632 begin(terms2), end(terms2), 10));
1637 begin(terms1), end(terms1), 2));
1641 begin(terms2), end(terms2), 2));
1670 size_t check_errors =
1697 if (expect % 20 == 15) expect += 5;
1707 TEST(db2.size() != 0);
1739 const unsigned MAX_LEN = 300;
1741 term.reserve(MAX_LEN);
1742 while (term.size() < MAX_LEN) {
1745 TEST_EQUAL(enquire.get_mset(0, 10).size(), 0);
1751 mkdir(
".stub", 0755);
1752 const char* stubpath =
".stub/unsupportedcheck1";
1753 ofstream out(stubpath);
1754 TEST(out.is_open());
1761 FAIL_TEST(
"Managed to check remote stub");
1762 #ifdef XAPIAN_HAS_REMOTE_BACKEND 1766 "Remote database checking not implemented");
1775 mkdir(
".stub", 0755);
1776 const char* stubpath =
".stub/unsupportedcheck2";
1777 ofstream out(stubpath);
1778 TEST(out.is_open());
1779 out <<
"inmemory\n";
1804 for (
int n =
'1'; n <=
'3'; ++n) {
static const char * get_xapian_progsrv_command()
Get the command line required to run xapian-progsrv.
Xapian::doccount size() const
Return number of items in this MSet object.
Xapian::Document get_document(Xapian::docid did) const
Get a document from the database, given its document id.
Xapian::docid add_document(const Xapian::Document &document)
Add a new document to the database.
PositionIterator positionlist_end(Xapian::docid, const std::string &) const
Corresponding end iterator to positionlist_begin().
Run multiple tests for different backends.
void add_value(Xapian::valueno slot, const std::string &value)
Add a new value.
static size_t check(const std::string &path, int opts=0, std::ostream *out=NULL)
Check the integrity of a database or database table.
TermIterator termlist_begin(Xapian::docid did) const
An iterator pointing to the start of the termlist for a given document.
Indicates an attempt to access a closed database.
#define TEST(a)
Test a condition, without an additional explanation for failure.
void skip_to(Xapian::termpos termpos)
Advance the iterator to term position termpos.
This class is used to access a database, or a group of databases.
void set_sort_by_value(Xapian::valueno sort_key, bool reverse)
Set the sorting to be by value only.
Xapian::termcount termlist_count() const
The length of the termlist - i.e.
static const Xapian::Query MatchAll
A query matching all documents.
Match documents which an odd number of subqueries match.
const int DB_CREATE
Create a new database.
DatabaseOpeningError indicates failure to open a database.
PositionIterator positionlist_begin(Xapian::docid did, const std::string &tname) const
An iterator pointing to the start of the position list for a given term in a given document...
bool mset_range_is_same(const Xapian::MSet &mset1, unsigned int first1, const Xapian::MSet &mset2, unsigned int first2, unsigned int count)
Xapian::termcount get_doclength_lower_bound() const
Get a lower bound on the length of a document in this DB.
Xapian::doccount get_matches_lower_bound() const
Lower bound on the total number of matching documents.
TermIterator allterms_end(const std::string &=std::string()) const
Corresponding end iterator to allterms_begin(prefix).
Xapian::WritableDatabase get_writable_database(const string &dbname)
include <sys/socket.h> with portability workarounds.
Xapian::docid get_lastdocid() const
Get the highest document id which has been used in the database.
const std::string & get_msg() const
Message giving details of the error, intended for human consumption.
Convert errno value to std::string, thread-safe if possible.
Build a Xapian::Query object from a user query string.
a generic test suite engine
bool reopen()
Re-open the database.
C++ function versions of useful Unix commands.
WritableDatabase open()
Construct a WritableDatabase object for a new, empty InMemory database.
Class for iterating over document values.
Class representing a list of search results.
void skip_to(const std::string &term)
Advance the iterator to term term.
Xapian::WritableDatabase get_writable_database_again()
Pick the maximum weight of any subquery.
MSet get_mset(Xapian::doccount first, Xapian::doccount maxitems, Xapian::doccount checkatleast=0, const RSet *omrset=0, const MatchDecider *mdecider=0) const
Get (a portion of) the match set for the current query.
Convert types to std::string.
static double est(double l, double r, double n)
const int DB_CREATE_OR_OPEN
Create database if it doesn't already exist.
Utility functions for testing files.
Xapian::rev get_revision() const
Get the revision of the database.
void replace_document(Xapian::docid did, const Xapian::Document &document)
Replace a given document in the database.
void set_metadata(const std::string &key, const std::string &metadata)
Set the user-specified metadata associated with a given key.
void clear_terms()
Remove all terms (and postings) from the document.
Xapian::doccount get_doccount() const
Get the number of documents in the database.
const int DOC_ASSUME_VALID
Assume document id is valid.
DEFINE_TESTCASE(lockfileumask1, chert||glass)
Regression test - lockfile should honour umask, was only user-readable.
Xapian::totallength get_total_length() const
Get the total length of all the documents in the database.
static std::string get_srcdir()
Read srcdir from environment and if not present, make a valiant attempt to guess a value...
include <sys/stat.h> with portability enhancements
static void make_msize2_db(Xapian::WritableDatabase &db, const string &)
const int DB_BACKEND_GLASS
Use the glass backend.
docid get_docid() const
Get the document id which is associated with this document (if any).
Xapian::WritableDatabase get_named_writable_database(const std::string &name, const std::string &source)
test functionality of the Xapian API
void rm_rf(const string &filename)
Remove a directory and contents, just like the Unix "rm -rf" command.
Xapian::doccount get_matches_upper_bound() const
Upper bound on the total number of matching documents.
Xapian::doclength get_avlength() const
Get the average length of the documents in the database.
static void make_xordecay1_db(Xapian::WritableDatabase &db, const string &)
Class for iterating over a list of terms.
unsigned XAPIAN_TERMCOUNT_BASE_TYPE termcount
A counts of terms.
#define TEST_REL(A, REL, B)
Test a relation holds,e.g. TEST_REL(a,>,b);.
Class for iterating over a list of terms.
#define TEST_NOT_EQUAL(a, b)
Test for non-equality of two things.
InvalidArgumentError indicates an invalid parameter value was passed to the API.
Xapian::termcount get_doclength_upper_bound() const
Get an upper bound on the length of a document in this DB.
Base class for backend handling in test harness.
string get_database_path(const string &dbname)
Class implementing a "boolean" weighting scheme.
Xapian::doccount get_firstitem() const
Rank of first item in this MSet.
ValueIterator valuestream_end(Xapian::valueno) const
Return end iterator corresponding to valuestream_begin().
std::string get_named_writable_database_path(const std::string &name)
DatabaseModifiedError indicates a database was modified.
DatabaseLockError indicates failure to lock a database.
Pick the best N subqueries and combine with OP_OR.
const int DB_OPEN
Open an existing database.
This class provides read/write access to a database.
static void make_phrasebug1_db(Xapian::WritableDatabase &db, const string &)
std::ostringstream tout
The debug printing stream.
void errno_to_string(int e, string &s)
Iterator over a Xapian::MSet.
Match only documents where all subqueries match near and in order.
Indicates an attempt to use a feature which is unavailable.
Match the first subquery taking extra weight from other subqueries.
Public interfaces for the Xapian library.
Match like OP_AND but only taking weight from the first subquery.
bool locked() const
Test if this database is currently locked for writing.
void delete_document(Xapian::docid did)
Delete a document from the database.
#define TEST_EXCEPTION(TYPE, CODE)
Check that CODE throws exactly Xapian exception TYPE.
Match only documents where a value slot is within a given range.
string str(int value)
Convert int to std::string.
MSetIterator begin() const
Return iterator pointing to the first item in this MSet.
MSetIterator end() const
Return iterator pointing to just after the last item in this MSet.
Xapian::termcount get_doclength(Xapian::docid did) const
Get the length of a document.
void commit()
Commit any pending modifications made to the database.
Xapian::Database get_writable_database_as_database()
Class for iterating over term positions.
static const test_desc tests[]
The lists of tests to perform.
Indicates an attempt to access a database not present.
Query parse_query(const std::string &query_string, unsigned flags=FLAG_DEFAULT, const std::string &default_prefix=std::string())
Parse a query.
TermIterator allterms_begin(const std::string &prefix=std::string()) const
An iterator which runs across all terms with a given prefix.
TermIterator termlist_end(Xapian::docid) const
Corresponding end iterator to termlist_begin().
#define TEST_EQUAL_DOUBLE(a, b)
Test two doubles for near equality.
#define SKIP_TEST_FOR_BACKEND(B)
ValueIterator valuestream_begin(Xapian::valueno slot) const
Return an iterator over the value in slot slot for each document.
void add_database(const Database &database)
Add an existing database (or group of databases) to those accessed by this object.
void set_query(const Xapian::Query &query, Xapian::termcount qlen=0)
Set the query to run.
Indicates an attempt to access a document not present in the database.
size_t size() const
Return number of shards in this Database object.
Match like OP_OR but weighting as if a single term.
DatabaseCorruptError indicates database corruption was detected.
std::string get_description() const
Return a string describing this object.
Base class for matcher decision functor.
bool check(Xapian::docid docid)
Check if the specified docid occurs.
void add_posting(const std::string &tname, Xapian::termpos tpos, Xapian::termcount wdfinc=1)
Add an occurrence of a term at a particular position.
#define FAIL_TEST(MSG)
Fail the current testcase with message MSG.
static void gen_uniqterms_gt_doclen_db(Xapian::WritableDatabase &db, const string &)
Match only documents which all subqueries match.
static Xapian::Query query(Xapian::Query::op op, const string &t1=string(), const string &t2=string(), const string &t3=string(), const string &t4=string(), const string &t5=string(), const string &t6=string(), const string &t7=string(), const string &t8=string(), const string &t9=string(), const string &t10=string())
Xapian::Database get_database(const string &dbname)
Xapian::doccount get_matches_estimated() const
Estimate of the total number of matching documents.
const Xapian::Query & get_query() const
Get the current query.
const int DB_BACKEND_STUB
Open a stub database file.
void set_database(const Database &db)
Specify the database being searched.
#define SKIP_TEST(MSG)
Skip the current testcase with message MSG.
std::string get_description() const
Return a string describing this object.
This class provides an interface to the information retrieval system for the purpose of searching...
unsigned XAPIAN_DOCID_BASE_TYPE doccount
A count of documents.
Match only documents where all subqueries match near each other.
void flush()
Pre-1.1.0 name for commit().
const char * get_error_string() const
Returns any system error string associated with this exception.
All exceptions thrown by Xapian are subclasses of Xapian::Error.
Match documents which the first subquery matches but no others do.
Match documents which at least one subquery matches.
void skip_to(Xapian::docid did)
Advance the iterator to document did.
Xapian-specific test helper functions and macros.
unsigned XAPIAN_TERMPOS_BASE_TYPE termpos
A term position within a document or query.
static const Xapian::Query MatchNothing
A query matching no documents.
#define TEST_STRINGS_EQUAL(a, b)
Test for equality of two strings.
const int DB_NO_TERMLIST
When creating a database, don't create a termlist table.
<unistd.h>, but with compat.
include <sys/wait.h>, with portability stuff.
void add_boolean_term(const std::string &term)
Add a boolean filter term to the document.
void mset_expect_order(const Xapian::MSet &A, Xapian::docid d1, Xapian::docid d2, Xapian::docid d3, Xapian::docid d4, Xapian::docid d5, Xapian::docid d6, Xapian::docid d7, Xapian::docid d8, Xapian::docid d9, Xapian::docid d10, Xapian::docid d11, Xapian::docid d12)
static void make_msize1_db(Xapian::WritableDatabase &db, const string &)
const int DB_RETRY_LOCK
If the database is already locked, retry the lock.
void set_weighting_scheme(const Weight &weight_)
Set the weighting scheme to use for queries.
unsigned XAPIAN_DOCID_BASE_TYPE docid
A unique identifier for a document.
Class representing a query.
std::string get_data() const
Get data stored in the document.
#define TEST_EQUAL(a, b)
Test for equality of two things.
Xapian::termcount get_unique_terms(Xapian::docid did) const
Get the number of unique terms in document.
PostingIterator postlist_end(const std::string &) const
Corresponding end iterator to postlist_begin().
static void make_ordecay_db(Xapian::WritableDatabase &db, const string &)
void set_data(const std::string &data)
Set data stored in the document.
bool file_exists(const char *path)
Test if a file exists.
void set_collapse_key(Xapian::valueno collapse_key, Xapian::doccount collapse_max=1)
Set the collapse key to use for queries.
std::string get_value(Xapian::valueno slot) const
Get value by number.
virtual void close()
Close the database.
include <fcntl.h>, but working around broken platforms.
Xapian::doccount get_termfreq(const std::string &tname) const
Get the number of documents in the database indexed by a given term.
A handle representing a document in a Xapian database.
const int DB_BACKEND_CHERT
Use the chert backend.
UnimplementedError indicates an attempt to use an unimplemented feature.
PostingIterator postlist_begin(const std::string &tname) const
An iterator pointing to the start of the postlist for a given term.
void skip_to(Xapian::docid docid_or_slot)
Advance the iterator to document id or value slot docid_or_slot.
void add_term(const std::string &tname, Xapian::termcount wdfinc=1)
Add a term to the document, without positional information.
Xapian::termcount get_collection_freq(const std::string &tname) const
Return the total number of occurrences of the given term.
Xapian::termcount get_wdf_upper_bound(const std::string &term) const
Get an upper bound on the wdf of term term.
bool operator()(const Xapian::Document &) const override
Decide whether we want this document to be in the MSet.
static void make_orcheck_db(Xapian::WritableDatabase &db, const string &)
const int DBCHECK_SHOW_STATS
Show statistics for the B-tree.