We have implemented a number of applications to test the qsastime library. In general, if you want to build any of these test applications you specify the cmake option -DTEST_QSASTIME=ON (but an additional option has to be set for the qsastime_testlib case discussed below in III). (I) lib/qsastime/qsastime_test is automatically built in the build tree if -DTEST_QSASTIME=ON. This test routine does some minimal tests of the qsastime library using the C library. Because the date range is so small, I believe this test builds and runs on every platform without running into C library limitations. Note some of the results of this test depend on C library routines whose results depend on the local time zone. Run this test as follows from the top of the build tree lib/qsastime/qsastime_test >qsastime_test.out Then compare these output results with those at lib/qsastime/qsastime_test.out_standard in the source tree. Your results will differ in some respects if you have a different time zone than the PST (7 hours west of Greenwich) time zone where the lib/qsastime/qsastime_test.out_standard result was produced. (II) lib/qsastime/bhunt_search_test is automatically built in the build tree if -DTEST_QSASTIME=ON. Depending on input, this test routine is capable of severe testing of the bhunt_search routine in the qsastime library. The point of bhunt_search is to avoid scanning through the whole leap second table every time you are dealing with a broken-down or continuous time. So this algorithm follows the general idea in Numerical Recipes of first having a hunt phase where the increment (or decrement) in index is doubled until the value is bracketed, and then bisection is used to find the index such that x[index] <= value < x[index+1], (1) This has been implemented as a completely generalized routine so "<=" and "<" stand for a generalized comparison of anything that can be stuffed into a struct, with the comparisons provided by a callback routine. bhunt_search_test tests bhunt_search as follows: ntable, offset, and multiplier values are provided via stdin. bhunt_search_test then creates a table of ntable double values (of 0. through (double) ntable-1) and searches that table at a set of ntest = (ntable-1)*multiplier +1 (2) points which are offset from the table range by offset. (Thus, large positive or negative offset values allow you to test repeated searches for data beyond the ends of the table.) An offset of zero and a multiplier of 1 mean you search the table for the exact table values rather than something in between the table values. For each of the ntest values, bhunt_search returns an index which the test routine then tests to make sure it satisfies condition 1 above. Here are some typical results for a table with 64 values (somewhat larger than the current TAI-UTC offset table which has 38 values.) software@raven> echo '64 0 1000'| lib/qsastime/bhunt_search_test ntable, offset, multiplier, ntest = 64, 0, 1000, 63001 Average number of gedouble calls per bhunt_search call = 6.015889 for ifhunt, ifrandom = 0,0 Average number of gedouble calls per bhunt_search call = 6.016444 for ifhunt, ifrandom = 0,1 Average number of gedouble calls per bhunt_search call = 2.002016 for ifhunt, ifrandom = 1,0 Average number of gedouble calls per bhunt_search call = 8.502754 for ifhunt, ifrandom = 1,1 Successful completion of bhunt_search test software@raven> echo '64 -64 1000'| lib/qsastime/bhunt_search_test ntable, offset, multiplier, ntest = 64, -64, 1000, 63001 Average number of gedouble calls per bhunt_search call = 6.000000 for ifhunt, ifrandom = 0,0 Average number of gedouble calls per bhunt_search call = 6.000000 for ifhunt, ifrandom = 0,1 Average number of gedouble calls per bhunt_search call = 1.000079 for ifhunt, ifrandom = 1,0 Average number of gedouble calls per bhunt_search call = 1.000079 for ifhunt, ifrandom = 1,1 Successful completion of bhunt_search test software@raven> echo '64 64 1000'| lib/qsastime/bhunt_search_test ntable, offset, multiplier, ntest = 64, 64, 1000, 63001 Average number of gedouble calls per bhunt_search call = 7.000000 for ifhunt, ifrandom = 0,0 Average number of gedouble calls per bhunt_search call = 7.000000 for ifhunt, ifrandom = 0,1 Average number of gedouble calls per bhunt_search call = 1.000095 for ifhunt, ifrandom = 1,0 Average number of gedouble calls per bhunt_search call = 1.000095 for ifhunt, ifrandom = 1,1 Successful completion of bhunt_search test Here are results for a table with one million values. software@raven> echo '1000000 0 10'| lib/qsastime/bhunt_search_test ntable, offset, multiplier, ntest = 1000000, 0, 10, 9999991 Average number of gedouble calls per bhunt_search call = 19.951426 for ifhunt, ifrandom = 0,0 Average number of gedouble calls per bhunt_search call = 19.951496 for ifhunt, ifrandom = 0,1 Average number of gedouble calls per bhunt_search call = 2.200001 for ifhunt, ifrandom = 1,0 Average number of gedouble calls per bhunt_search call = 35.978823 for ifhunt, ifrandom = 1,1 Successful completion of bhunt_search test As expected for a table with 2^6 = 64 entries, bhunt_search requires only an average of 6 calls to gedouble (my simple callback test code inside bhunt_search_test.c which compares two floating point numbers) to search per bhunt_search call if you turn off the hunt phase part of the routine. That number drops down close to 2 if the hunt phase is turned on and the successive numbers tend to be correlated (as happens quite often with time variables, for example). The number drops close to unity if you are beyond the end of the table (which also happens often for time variables). The hunt phase actually slows down the search for completely uncorrelated (i.e., random) variables, but that is a rare case for time variables so within the qsastime library, the the hunt phase is always turned on when using bhunt_search to determine the offset between TAI and UTC. For fun, I also showed a test above for a large table of one million values (near 2^20). As expected bhunt_search scales well for this case requiring an average of only 20 calls to gedouble if the hunt phase is turned off and only 2 calls to geodouble if the hunt phase is turned on for correlated data. (III) lib/qsastime/qsastime_testlib is automatically built in the build tree if _both_ -DTEST_QSASTIME=ON and -DBUILD_QSASTIME_TESTLIB=ON. This test routine tests the qsastime library over essentially the complete range of possible dates that can be represented internally without integer overflow by the qsastime library continuous time variable which stores the integer part of the MJD as a signed int. This works out to a range of +/-5.9 million years from the (Gregorian and Julian) calendar epoch. The actual tests in lib/qsastime/qsastime_testlib range over +/- 5 million years from the calendar epoch. Internally our build system forces BUILD_QSASTIME_TESTLIB to OFF for the Windows (WIN32) case because we have found in practice that the Windows C library time function limitations are so severe (e.g., dates prior to 1970 give incorrect results) that this test of a large date range is worthless on Windows. Also, once we acknowledged that Windows was never going to give good results for this test because of limitations in the Windows C library, it greatly simplified the programming of qsastime_testlib to ignore the Windows case completely. N.B. This is just an issue with the qsastime_testlib routine. The qsastime library itself works fine on Windows because it specifically avoids using any C library time routines. For 32-bit Linux platforms qsastime_testlib is also worthless because of limitations in the 32-bit C Linux library (e.g., the date range is limited to just 1902 through 2038). However, qsastime_testlib gives excellent results for the 64-bit Linux C library. To avoid wasting time on a 32-bit test, we have installed a check in qsastime_testlib which refuses to run the test if (sizeof(time_t) < 8). N.B. The sizeof(time_t) issue is only relevant for the qsastime_testlib routine. The qsastime library itself works fine on 32-bit platforms because it specifically avoids using any C library time routines. On 64-bit Linux (and possibly Mac OS X) platforms run this test as follows: echo 0xffff |lib/qsastime/qsastime_testlib > qsastime_testlib.out Then compare these output results with those at lib/qsastime/qsastime_testlib.out_standard in the source tree. They should be identical in all cases because the C library time routines that qsastime_testlib calls are made independent of time zone issues by forcing a zero time zone. (The qsastime library itself is, of course, independent of time zone issues.) N.B. this comprehensive test of the qsastime library takes 12 minutes to run on a 2.4GHz PC.