37 #define XAPIAN_UNITTEST 39 #define UNITTEST_CHECK_EXCEPTION \ 40 if (unittest_assertion_failed) { \ 41 const char * unittest_assertion_failed_ = unittest_assertion_failed;\ 42 unittest_assertion_failed = NULL;\ 43 throw unittest_assertion_failed_;\ 50 #define UNITTEST_ASSERT_LOCATION__(LINE,MSG) __FILE__":"#LINE": "#MSG 51 #define UNITTEST_ASSERT_LOCATION_(LINE,MSG) UNITTEST_ASSERT_LOCATION__(LINE,MSG) 52 #define UNITTEST_ASSERT_LOCATION(MSG) UNITTEST_ASSERT_LOCATION_(__LINE__,MSG) 53 #define UNITTEST_ASSERT_NOTHROW(COND, RET) \ 56 unittest_assertion_failed = UNITTEST_ASSERT_LOCATION(COND);\ 62 #include "../common/stringutils.h" 63 #include "../common/log2.h" 66 #define TEST_EXCEPTION(TYPE, CODE) \ 70 UNITTEST_CHECK_EXCEPTION \ 71 FAIL_TEST("Expected exception "#TYPE" not thrown"); \ 72 } catch (const TYPE &) { \ 77 #include "../common/closefrom.cc" 78 #include "../common/errno_to_string.cc" 79 #include "../common/io_utils.cc" 80 #include "../common/fileutils.cc" 81 #include "../common/overflow.h" 82 #include "../common/parseint.h" 83 #include "../common/posixy_wrapper.cc" 84 #include "../common/serialise-double.cc" 85 #include "../common/str.cc" 86 #include "../backends/uuids.cc" 87 #include "../net/length.cc" 88 #include "../net/serialise-error.cc" 89 #include "../api/error.cc" 90 #include "../api/sortable-serialise.cc" 93 #include "../common/msvc_dirent.cc" 96 #include "../api/constinfo.cc" 172 TEST_EQUAL(
r_r_p(
"C:rel/a/tive",
"c:\\foo\\bar"),
"C:\\foo\\rel/a/tive");
179 TEST_EQUAL(
r_r_p(
"rel/a/tive",
"\\\\SRV\\VOL\\DIR\\FILE"),
"\\\\SRV\\VOL\\DIR\\rel/a/tive");
180 TEST_EQUAL(
r_r_p(
"/abs/o/lute",
"\\\\SRV\\VOL\\FILE"),
"\\\\SRV\\VOL/abs/o/lute");
181 TEST_EQUAL(
r_r_p(
"/abs/o/lute",
"\\\\S\\V\\FILE"),
"\\\\S\\V/abs/o/lute");
185 TEST_EQUAL(
r_r_p(
"rel/a/tive",
"//SRV/VOL/DIR/FILE"),
"//SRV/VOL/DIR/rel/a/tive");
186 TEST_EQUAL(
r_r_p(
"/abs/o/lute",
"//SRV/VOL/FILE"),
"//SRV/VOL/abs/o/lute");
190 TEST_EQUAL(
r_r_p(
"/abs/o/lute",
"\\\\?\\C:\\wibble"),
"\\\\?\\C:\\abs\\o\\lute");
191 TEST_EQUAL(
r_r_p(
"/abs/o/lute",
"\\\\?\\UNC\\S\\V"),
"\\\\?\\UNC\\S\\V\\abs\\o\\lute");
192 TEST_EQUAL(
r_r_p(
"/abs/o/lute",
"\\\\?\\UNC\\S\\V\\"),
"\\\\?\\UNC\\S\\V\\abs\\o\\lute");
193 TEST_EQUAL(
r_r_p(
"/abs/o/lute",
"\\\\?\\UNC\\S\\V\\TMP\\README.TXT"),
"\\\\?\\UNC\\S\\V\\abs\\o\\lute");
194 TEST_EQUAL(
r_r_p(
"r/elativ/e",
"\\\\?\\C:\\wibble"),
"\\\\?\\C:\\r\\elativ\\e");
195 TEST_EQUAL(
r_r_p(
"r/elativ/e",
"\\\\?\\C:\\wibble\\wobble"),
"\\\\?\\C:\\wibble\\r\\elativ\\e");
196 #if 0 // Is this a valid testcase? It fails, but isn't relevant to Xapian. 197 TEST_EQUAL(
r_r_p(
"r/elativ/e",
"\\\\?\\UNC\\S\\V"),
"\\\\?\\UNC\\S\\V\\r\\elativ\\e");
199 TEST_EQUAL(
r_r_p(
"r/elativ/e",
"\\\\?\\UNC\\S\\V\\"),
"\\\\?\\UNC\\S\\V\\r\\elativ\\e");
200 TEST_EQUAL(
r_r_p(
"r/elativ/e",
"\\\\?\\UNC\\S\\V\\TMP\\README.TXT"),
"\\\\?\\UNC\\S\\V\\TMP\\r\\elativ\\e");
214 TEST(encoded.size() <
sizeof(buf));
215 memcpy(buf, encoded.data(), encoded.size());
219 const char * ptr[3] = { NULL, buf, NULL };
220 const char * end = ptr[1] + encoded.size();
222 if (ptr[1] != end || u != v) {
223 cout << u <<
" -> " << v <<
", difference = " << v - u <<
'\n';
224 cout <<
"FLT_RADIX = " << FLT_RADIX <<
'\n';
225 cout <<
"DBL_MAX_EXP = " << DBL_MAX_EXP <<
'\n';
227 TEST_EQUAL(static_cast<const void*>(ptr[1]), static_cast<const void*>(end));
232 static const double test_values[] = {
252 for (p = test_values; p < test_values +
sizeof(test_values) /
sizeof(
double); ++p) {
261 #ifdef XAPIAN_HAS_REMOTE_BACKEND 266 while (n < 0xff000000) {
268 const char *p = s.data();
269 const char *p_end = p + s.size();
272 if (n != decoded_n || p != p_end)
tout <<
"[" << s <<
"]\n";
290 const char *p = s.data();
291 const char *p_end = p + s.size();
299 const char *p = s.data();
300 const char *p_end = p + s.size();
311 const char *p = s.data();
312 const char *p_end = p + s.size();
319 const char *p = s.data();
320 const char *p_end = p + s.size();
328 const char *p = s.data();
329 const char *p_end = p + s.size();
337 for (
size_t n = 2; n < 1000; n = (n + 1) * 2 + (n >> 1)) {
340 const char *p = s.data();
341 const char *p_end = p + s.size();
346 s.append(n - 1,
'x');
348 const char *p = s.data();
349 const char *p_end = p + s.size();
356 const char *p = s.data();
357 const char *p_end = p + s.size();
365 const char *p = s.data();
366 const char *p_end = p + s.size();
425 -3.14159265358979323846,
457 3.14159265358979323846,
473 bool started =
false;
476 tout <<
"Number: " << num <<
'\n';
478 tout <<
"String: " << str <<
'\n';
485 }
else if (prevnum > num) {
491 }
else if (prevstr > str) {
496 "Numbers " << prevnum <<
" and " << num <<
497 " don't sort the same way as their string " 509 const S max_val = numeric_limits<S>::max();
510 const S min_val = numeric_limits<S>::min();
511 tout <<
"Testing with tostring_helper\n";
512 std::ostringstream oss;
513 oss << (
long long)max_val;
518 oss << (
long long)min_val;
545 tostring_helper<char>();
546 tostring_helper<short>();
547 tostring_helper<int>();
548 tostring_helper<long>();
549 tostring_helper<long long>();
606 for (
int i = 0; i != 8; ++i) {
607 unsigned char ch = str[i];
612 for (
int i = 9; i != 13; ++i) {
613 unsigned char ch = str[i];
618 for (
int i = 14; i != 18; ++i) {
619 unsigned char ch = str[i];
624 for (
int i = 19; i != 23; ++i) {
625 unsigned char ch = str[i];
630 for (
int i = 24; i != 36; ++i) {
631 unsigned char ch = str[i];
660 TEST_EQUAL(str,
"00000000-0000-0000-0000-000000000000");
671 explicit A(
int x_) : x(x_) {}
682 B(
int x_,
bool & alive_) : x(x_), alive(alive_) {
695 opt_intrusive_base::release();
721 B * b1 =
new B{5, alive};
744 const auto ulong_max = numeric_limits<unsigned long>::max();
745 const auto uint_max = numeric_limits<unsigned int>::max();
746 const auto ushort_max = numeric_limits<unsigned short>::max();
747 const auto uchar_max = numeric_limits<unsigned char>::max();
749 unsigned long res_ulong;
751 unsigned short res_ushort;
752 unsigned char res_uchar;
841 const U max_val = numeric_limits<U>::max();
842 tout <<
"Testing with parseunsigned_helper\n";
854 if (max_val + 1ull != 0)
860 parseunsigned_helper<unsigned char>();
861 parseunsigned_helper<unsigned short>();
862 parseunsigned_helper<unsigned>();
863 parseunsigned_helper<unsigned long>();
864 parseunsigned_helper<unsigned long long>();
870 const S max_val = numeric_limits<S>::max();
871 const S min_val = numeric_limits<S>::min();
872 tout <<
"Testing with parsesigned_helper\n";
890 unsigned long long one_too_large = max_val + 1ull;
893 unsigned long long one_too_small_negated = 1ull - min_val;
899 parsesigned_helper<signed char>();
900 parsesigned_helper<short>();
901 parsesigned_helper<int>();
902 parsesigned_helper<long>();
903 parsesigned_helper<long long>();
909 const char* tmp_file =
".unittest_ioutils1";
917 string buf(BLOCK_SIZE,
'x');
925 out.resize(BLOCK_SIZE);
934 out.resize(BLOCK_SIZE);
942 if (
sizeof(off_t) <= 4) {
943 SKIP_TEST(
"Skipping rest of testcase - no Large File Support");
948 TEST(fstat(fd, &statbuf) == 0);
950 off_t hole = lseek(fd, 0, SEEK_HOLE);
952 SKIP_TEST(
"Skipping rest of testcase - SEEK_HOLE failed");
954 if (hole >= statbuf.st_size) {
955 SKIP_TEST(
"Skipping rest of testcase - sparse file support not " 962 constexpr off_t high_offset = (off_t{1} << 32) + BLOCK_SIZE;
963 constexpr off_t high_block = high_offset /
BLOCK_SIZE;
968 SKIP_TEST(
"Skipping rest of testcase - FS doesn't allow a > 4GB " 972 TEST(fstat(fd, &statbuf) == 0);
973 TEST_EQUAL(statbuf.st_size, high_offset + BLOCK_SIZE);
991 SKIP_TEST(
"Skipping rest of testcase - SEEK_HOLE not supported");
1009 #ifdef XAPIAN_HAS_REMOTE_BACKEND 1034 }
catch (
const char * e) {
int io_open_block_rd(const char *fname)
Open a block-based file for reading.
static void test_serialiseerror1()
static void test_serialiselength2()
std::enable_if< std::is_unsigned< T1 >::value &&std::is_unsigned< T2 >::value &&std::is_unsigned< R >::value, bool >::type add_overflows(T1 a, T2 b, R &res)
Addition with overflow checking.
static void test_parsesigned1()
static void check_double_serialisation(double u)
#define TEST(a)
Test a condition, without an additional explanation for failure.
bool io_unlink(const std::string &filename)
Delete a file.
static void parse_command_line(int argc, char **argv)
Parse the command line arguments.
DatabaseOpeningError indicates failure to open a database.
void io_read_block(int fd, char *p, size_t n, off_t b, off_t o)
Read block b size n bytes into buffer p from file descriptor fd, offset o.
static void parseunsigned_helper()
#define TEST_AND_EXPLAIN(a, b)
Test a condition, and display the test with an extra explanation if the condition fails...
static void test_suboverflows1()
bool io_sync(int fd)
Ensure all data previously written to file descriptor fd has been written to disk.
int io_open_block_wr(const char *fname, bool anew)
Open a block-based file for writing.
a generic test suite engine
bool io_readahead_block(int, size_t, off_t, off_t=0)
Readahead block b size n bytes from file descriptor fd.
string serialise_error(const Xapian::Error &e)
Serialise a Xapian::Error object to a string.
std::string sortable_serialise(double value)
Convert a floating point number to a string, preserving sort order.
std::string encode_length(T len)
Encode a length as a variable-length string.
static string r_r_p(string a, const string &b)
static void parsesigned_helper()
static void test_serialiselength1()
void unserialise_error(const string &serialised_error, const string &prefix, const string &new_context)
Unserialise a Xapian::Error object and throw it.
#define TEST_REL(A, REL, B)
Test a relation holds,e.g. TEST_REL(a,>,b);.
static const char * unittest_assertion_failed
#define TEST_NOT_EQUAL(a, b)
Test for non-equality of two things.
bool io_full_sync(int fd)
double unserialise_double(const char **p, const char *end)
Unserialise a double serialised by serialise_double.
void description_append(std::string &desc, const std::string &s)
std::ostringstream tout
The debug printing stream.
void errno_to_string(int e, string &s)
#define TEST_EXCEPTION(TYPE, CODE)
static void test_parseunsigned1()
void io_write_block(int fd, const char *p, size_t n, off_t b, off_t o)
Write block b size n bytes from buffer p to file descriptor fd, offset o.
static void test_tostring1()
string str(int value)
Convert int to std::string.
std::string to_string() const
static void test_ioblock1()
Test working with a block-based file using functions from io_utils.h.
static void test_sortableserialise1()
void parse(const char *in)
Base class for objects managed by intrusive_ptr.
Base class for objects managed by opt_intrusive_ptr.
static void test_muloverflows1()
double sortable_unserialise(const std::string &serialised)
Convert a string encoded using sortable_serialise back to a floating point number.
std::string get_description() const
Return a string describing this object.
static void test_closefrom1()
void resolve_relative_path(string &path, const string &base)
Resolve path relative to base.
std::string serialise_double(double v)
Serialise a double to a string.
void decode_length_and_check(const char **p, const char *end, unsigned &out)
Decode a length encoded by encode_length.
#define SKIP_TEST(MSG)
Skip the current testcase with message MSG.
static void test_movesupport1()
static void tostring_helper()
const char * get_error_string() const
Returns any system error string associated with this exception.
static constexpr unsigned BINARY_SIZE
The size of a UUID in bytes.
bool parse_signed(const char *p, T &res)
All exceptions thrown by Xapian are subclasses of Xapian::Error.
static const double test_sortableserialise_numbers[]
std::enable_if< std::is_unsigned< T1 >::value &&std::is_unsigned< T2 >::value &&std::is_unsigned< R >::value, bool >::type sub_overflows(T1 a, T2 b, R &res)
Subtraction with overflow checking.
#define TEST_STRINGS_EQUAL(a, b)
Test for equality of two strings.
static void test_strbool1()
Regression test for bug fixed in 1.1.1.
static int run(const test_desc *tests)
std::enable_if< std::is_unsigned< T1 >::value &&std::is_unsigned< T2 >::value &&std::is_unsigned< R >::value, bool >::type mul_overflows(T1 a, T2 b, R &res)
Multiplication with overflow checking.
<unistd.h>, but with compat.
static const test_desc tests[]
int main(int argc, char **argv)
static void test_addoverflows1()
const char * data() const
Structure holding a description of a test.
DatabaseError indicates some sort of database related error.
bool parse_unsigned(const char *p, T &res)
#define TEST_EQUAL(a, b)
Test for equality of two things.
A smart pointer that optionally uses intrusive reference counting.
A smart pointer that uses intrusive reference counting.
void decode_length(const char **p, const char *end, unsigned &out)
Decode a length encoded by encode_length.
DEFINE_TESTCASE_(simple_exceptions_work1)