/* The software in this package is distributed under the GNU General Public License version 2 (with a special exception described below). A copy of GNU General Public License (GPL) is included in this distribution, in the file COPYING.GPL. As a special exception, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other works to produce a work based on this file, this file does not by itself cause the resulting work to be covered by the GNU General Public License. However the source code for this file must still be made available in accordance with section (3) of the GNU General Public License. This exception does not invalidate any other reasons why a work based on this file might be covered by the GNU General Public License. */ /** @file * @brief unit test for time related functions. * * @copyright Copyright © 2001-2008 by Intra2net AG * */ #define BOOST_TEST_DYN_LINK #include #include #include #include #include #include using namespace std; using namespace I2n; using namespace I2n::Time; class TestTimeFuncFixture { protected: typedef std::list< std::string > StringList; std::set used_check_files; std::string tz; /* save and restore TZ from envp */ std::string get_check_file_path(std::string tag) { std::string result; result= "__unittest__" + tag + ".dat"; used_check_files.insert(result); return result; } // eo get_check_file_path void remove_check_files() { for (std::set::iterator it= used_check_files.begin(); it != used_check_files.end(); ++it) { std::string filepath(*it); if (path_exists(filepath)) { unlink(filepath); } //TODO } used_check_files.clear(); } // eo remove_check_files void set_utc (void) { errno = 0; if (setenv ("TZ", "UTC", 1) == -1) { std::cerr << "error setting environment 'TZ': [" << this->tz << "]" << std::endl ; return; } tzset (); } public: TestTimeFuncFixture() : tz (secure_getenv ("TZ") ?: "") { } ~TestTimeFuncFixture() { remove_check_files(); errno = 0; if (setenv ("TZ", this->tz.c_str (), 1) == -1) { std::cerr << "error cleaning up environment 'TZ': [" << this->tz << "]" << std::endl ; } else { tzset(); } } }; BOOST_FIXTURE_TEST_SUITE(TestTimeFunc, TestTimeFuncFixture) BOOST_AUTO_TEST_CASE(AddIntervalsDisjoint) { Intervals intervals; intervals.add( Interval( 10, 100 ) ); intervals.add( Interval( 600, 620 ) ); BOOST_CHECK_EQUAL( false, intervals.empty() ); BOOST_CHECK_EQUAL( 2u, intervals.size() ); BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() ); BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() ); BOOST_CHECK_EQUAL( 600u, intervals.back().lower_bound() ); BOOST_CHECK_EQUAL( 620u, intervals.back().upper_bound() ); } // eo AddIntervalsDisjoint() BOOST_AUTO_TEST_CASE(AddIntervalsInclude) { Intervals intervals; intervals.add( Interval( 10, 100 ) ); intervals.add( Interval( 10, 80 ) ); BOOST_CHECK_EQUAL( false, intervals.empty() ); BOOST_CHECK_EQUAL( 1u, intervals.size() ); BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() ); BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() ); BOOST_CHECK_EQUAL( false, intervals.front().changed() ); } // eo AddIntervalsInclude() BOOST_AUTO_TEST_CASE(AddIntervalsEmbrace) { Intervals intervals; intervals.add( Interval( 10, 100 ) ); intervals.add( Interval( 5, 120 ) ); BOOST_CHECK_EQUAL( false, intervals.empty() ); BOOST_CHECK_EQUAL( 1u, intervals.size() ); BOOST_CHECK_EQUAL( 5u, intervals.front().lower_bound() ); BOOST_CHECK_EQUAL( 120u, intervals.front().upper_bound() ); BOOST_CHECK_EQUAL( true, intervals.front().changed() ); } // eo AddIntervalsEmbrace() BOOST_AUTO_TEST_CASE(AddIntervalsJoin1) { Intervals intervals; intervals.add( Interval( 10, 100 ) ); intervals.add( Interval( 60, 120 ) ); BOOST_CHECK_EQUAL( false, intervals.empty() ); BOOST_CHECK_EQUAL( 1u, intervals.size() ); BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() ); BOOST_CHECK_EQUAL( 120u, intervals.front().upper_bound() ); BOOST_CHECK_EQUAL( true, intervals.front().changed() ); } // eo AddIntervalsJoin1() BOOST_AUTO_TEST_CASE(AddIntervalsJoin1b) { Intervals intervals; intervals.add( Interval( 10, 100 ) ); intervals.add( Interval( 100, 120 ) ); BOOST_CHECK_EQUAL( false, intervals.empty() ); BOOST_CHECK_EQUAL( 1u, intervals.size() ); BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() ); BOOST_CHECK_EQUAL( 120u, intervals.front().upper_bound() ); BOOST_CHECK_EQUAL( true, intervals.front().changed() ); } // eo AddIntervalsJoin1b() BOOST_AUTO_TEST_CASE(AddIntervalsJoin2) { Intervals intervals; intervals.add( Interval( 10, 100 ) ); intervals.add( Interval( 200, 250 ) ); BOOST_CHECK_EQUAL( false, intervals.empty() ); BOOST_CHECK_EQUAL( 2u, intervals.size() ); BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() ); BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() ); BOOST_CHECK_EQUAL( 200u, intervals.back().lower_bound() ); BOOST_CHECK_EQUAL( 250u, intervals.back().upper_bound() ); // now add the gap; the intervals should collapse to one covering all: intervals.add( Interval(100, 200) ); BOOST_CHECK_EQUAL( false, intervals.empty() ); BOOST_CHECK_EQUAL( 1u, intervals.size() ); BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() ); BOOST_CHECK_EQUAL( 250u, intervals.front().upper_bound() ); BOOST_CHECK_EQUAL( true, intervals.front().changed() ); } // eo AddIntervalsJoin2() BOOST_AUTO_TEST_CASE(SubIntervalsDisjoint) { Intervals intervals; intervals.add( Interval(10, 100) ); intervals.sub( Interval(0, 10) ); BOOST_CHECK_EQUAL( false, intervals.empty() ); BOOST_CHECK_EQUAL( 1u, intervals.size() ); BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() ); BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() ); BOOST_CHECK_EQUAL( false, intervals.front().changed() ); } // eo SubIntervalsDisjoint() BOOST_AUTO_TEST_CASE(SubIntervalsExact) { Intervals intervals; intervals.add( Interval(10, 100) ); intervals.sub( Interval(10, 100) ); BOOST_CHECK_EQUAL( true, intervals.empty() ); BOOST_CHECK_EQUAL( 0u, intervals.size() ); } // eo SubIntervalsExact() BOOST_AUTO_TEST_CASE(SubIntervalsSplit1) { Intervals intervals; intervals.add( Interval(10, 100) ); intervals.sub( Interval(20, 40) ); BOOST_CHECK_EQUAL( false, intervals.empty() ); BOOST_CHECK_EQUAL( 2u, intervals.size() ); BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() ); BOOST_CHECK_EQUAL( 20u, intervals.front().upper_bound() ); BOOST_CHECK_EQUAL( 40u, intervals.back().lower_bound() ); BOOST_CHECK_EQUAL( 100u, intervals.back().upper_bound() ); BOOST_CHECK_EQUAL( false, intervals.front().changed() ); BOOST_CHECK_EQUAL( true, intervals.back().changed() ); } // eo SubIntervalsSplit1() BOOST_AUTO_TEST_CASE(SubIntervalsCutFront) { Intervals intervals; intervals.add( Interval(10, 100) ); intervals.sub( Interval(10, 20) ); BOOST_CHECK_EQUAL( false, intervals.empty() ); BOOST_CHECK_EQUAL( 1u, intervals.size() ); BOOST_CHECK_EQUAL( 20u, intervals.front().lower_bound() ); BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() ); BOOST_CHECK_EQUAL( true, intervals.front().changed() ); } // eo SubIntervalsCutFront() BOOST_AUTO_TEST_CASE(SubIntervalsCutBack) { Intervals intervals; intervals.add( Interval(10, 100) ); intervals.sub( Interval(87, 100) ); BOOST_CHECK_EQUAL( false, intervals.empty() ); BOOST_CHECK_EQUAL( 1u, intervals.size() ); BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() ); BOOST_CHECK_EQUAL( 87u, intervals.front().upper_bound() ); BOOST_CHECK_EQUAL( true, intervals.front().changed() ); } // eo SubIntervalsCutBack() BOOST_AUTO_TEST_CASE(SubIntervalsCutMore) { Intervals intervals; intervals.add( Interval( 10, 100) ); intervals.add( Interval(110, 200) ); intervals.add( Interval(210, 300) ); // this should remove the first 2 intervals and cut the third: intervals.sub( Interval(8, 220) ); BOOST_CHECK_EQUAL( false, intervals.empty() ); BOOST_CHECK_EQUAL( 1u, intervals.size() ); BOOST_CHECK_EQUAL( 220u, intervals.front().lower_bound() ); BOOST_CHECK_EQUAL( 300u, intervals.front().upper_bound() ); BOOST_CHECK_EQUAL( true, intervals.front().changed() ); } // eo SubIntervalsCutMore() BOOST_AUTO_TEST_CASE(IntervalComparisons) { Intervals intervals1; Intervals intervals2; intervals1.add( Interval( 10, 120) ); intervals2.add( Interval( 10, 110 ) ); intervals2.add( Interval( 100, 120 ) ); BOOST_CHECK_EQUAL( 1u, intervals2.size() ); BOOST_CHECK( intervals1 == intervals2 ); BOOST_CHECK_EQUAL( true, intervals1.contains( intervals2 )); BOOST_CHECK_EQUAL( true, intervals2.contains( intervals1 )); intervals2.sub( Interval( 40, 50) ); BOOST_CHECK( intervals1 != intervals2 ); BOOST_CHECK_EQUAL( true, intervals1.contains( intervals2 )); BOOST_CHECK_EQUAL( false, intervals2.contains( intervals1 )); } // eo IntervalComparisons() BOOST_AUTO_TEST_CASE(MonotonicClock) { long sec0, nsec0; long sec1, nsec1; bool res = monotonic_clock_gettime(sec0,nsec0); BOOST_CHECK_EQUAL( true, res ); usleep(250000); res= monotonic_clock_gettime(sec1,nsec1); BOOST_CHECK_EQUAL( true, res); long delta_sec = sec1 - sec0; long delta_nsec= nsec1 - nsec0; long delta_millisec= ( delta_nsec / 1000000L) + delta_sec * 1000L; BOOST_CHECK( delta_millisec >= 250 - /*fuzz*/ 1); BOOST_CHECK( delta_millisec < 300 ); } // eo MonotonicClock() BOOST_AUTO_TEST_CASE(WeekInvalid) { Week week("99999999"); BOOST_CHECK_EQUAL(false, week.is_valid()); BOOST_CHECK_EQUAL(string(""), week.get_displaystring()); } BOOST_AUTO_TEST_CASE(WeekDisplayString1) { Week week(""); BOOST_CHECK_EQUAL(true, week.is_valid()); BOOST_CHECK_EQUAL(string(""), week.get_displaystring()); } BOOST_AUTO_TEST_CASE(WeekDisplayString2) { Week week("0123456"); BOOST_CHECK_EQUAL(true, week.is_valid()); BOOST_CHECK_EQUAL(string("Mon-Sun"), week.get_displaystring()); } BOOST_AUTO_TEST_CASE(WeekDisplayString3) { Week week("123456"); BOOST_CHECK_EQUAL(true, week.is_valid()); BOOST_CHECK_EQUAL(string("Mon-Sat"), week.get_displaystring()); } BOOST_AUTO_TEST_CASE(WeekDisplayString4) { Week week("012345"); BOOST_CHECK_EQUAL(true, week.is_valid()); BOOST_CHECK_EQUAL(string("Mon-Fri, Sun"), week.get_displaystring()); } BOOST_AUTO_TEST_CASE(WeekDisplayString5) { Week week("1256"); BOOST_CHECK_EQUAL(true, week.is_valid()); BOOST_CHECK_EQUAL(string("Mon, Tue, Fri, Sat"), week.get_displaystring()); } BOOST_AUTO_TEST_CASE(WeekDisplayString6) { Week week("0246"); BOOST_CHECK_EQUAL(true, week.is_valid()); BOOST_CHECK_EQUAL(string("Tue, Thu, Sat, Sun"), week.get_displaystring()); } BOOST_AUTO_TEST_CASE(WeekDisplayString7) { Week week("135"); BOOST_CHECK_EQUAL(true, week.is_valid()); BOOST_CHECK_EQUAL(string("Mon, Wed, Fri"), week.get_displaystring()); } BOOST_AUTO_TEST_CASE(WeekDisplayString8) { Week week("15"); BOOST_CHECK_EQUAL(true, week.is_valid()); BOOST_CHECK_EQUAL(string("Mon, Fri"), week.get_displaystring()); } BOOST_AUTO_TEST_CASE(WeekDisplayString9) { Week week("06"); BOOST_CHECK_EQUAL(true, week.is_valid()); BOOST_CHECK_EQUAL(string("Sat, Sun"), week.get_displaystring()); } BOOST_AUTO_TEST_CASE(WeekDisplayString10) { Week week("056"); BOOST_CHECK_EQUAL(true, week.is_valid()); BOOST_CHECK_EQUAL(string("Fri-Sun"), week.get_displaystring()); } BOOST_AUTO_TEST_CASE(WeekDisplayString11) { Week week("0"); BOOST_CHECK_EQUAL(true, week.is_valid()); BOOST_CHECK_EQUAL(string("Sun"), week.get_displaystring()); } BOOST_AUTO_TEST_CASE(WeekDisplayString12) { Week week("6"); BOOST_CHECK_EQUAL(true, week.is_valid()); BOOST_CHECK_EQUAL(string("Sat"), week.get_displaystring()); } BOOST_AUTO_TEST_CASE(WeekDisplayString13) { Week week("123"); BOOST_CHECK_EQUAL(true, week.is_valid()); BOOST_CHECK_EQUAL(string("Mon-Wed"), week.get_displaystring()); } BOOST_AUTO_TEST_CASE(FormatFullTime) { time_t seconds = 1318844005; BOOST_CHECK_EQUAL("17.10.2011 11:33", format_full_time(seconds)); } BOOST_AUTO_TEST_CASE(DateToSeconds1) { // no DST BOOST_CHECK_EQUAL(1325372400, date_to_seconds("2012-01-01")); } BOOST_AUTO_TEST_CASE(DateToSeconds2) { // DST BOOST_CHECK_EQUAL(1341093600, date_to_seconds("2012-07-01")); } BOOST_AUTO_TEST_CASE(FormatISO8601_T) { const time_t moment = 1515492684; BOOST_CHECK_EQUAL("10:11:24", format_iso8601 (moment, true, false, true, false)); } BOOST_AUTO_TEST_CASE(FormatISO8601_TZ_local) { const time_t moment = 1515492684; BOOST_CHECK_EQUAL("11:11:24Z+0100", format_iso8601 (moment, false, false, true, true)); } BOOST_AUTO_TEST_CASE(FormatISO8601_TZ) { const time_t moment = 1515492684; BOOST_CHECK_EQUAL("10:11:24Z+0000", format_iso8601 (moment, true, false, true, true)); } BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ_local) { const time_t moment = 1515492684; BOOST_CHECK_EQUAL("2018-01-09T11:11:24Z+0100", format_iso8601 (moment, false, true, true, true)); } BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ) { const time_t moment = 1515492684; BOOST_CHECK_EQUAL("2018-01-09T10:11:24Z+0000", format_iso8601 (moment, true, true, true, true)); } BOOST_AUTO_TEST_CASE(FormatISO8601_DT) { const time_t moment = 1515492684; BOOST_CHECK_EQUAL("2018-01-09T10:11:24", format_iso8601 (moment, true, true, true, false)); } BOOST_AUTO_TEST_CASE(FormatISO8601_D) { const time_t moment = 1515492684; BOOST_CHECK_EQUAL("2018-01-09", format_iso8601 (moment, true, true, false, false)); } BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ_struct_tm) { struct tm helau; helau.tm_sec = 11; helau.tm_min = 11; helau.tm_hour = 11; helau.tm_mday = 11; helau.tm_mon = 10; helau.tm_year = 2018 - 1900; helau.tm_wday = 0; helau.tm_yday = 315; helau.tm_isdst = 0; helau.tm_gmtoff = 0; helau.tm_zone = NULL; BOOST_CHECK_EQUAL("2018-11-11T11:11:11Z+0000", format_iso8601 (helau, true, true, true)); } BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ_struct_timespec) { struct timespec ts = { 1541934671, 11 }; BOOST_CHECK_EQUAL("2018-11-11T11:11:11Z+0000", format_iso8601 (ts, true, true, true, true)); } BOOST_AUTO_TEST_SUITE(Clock) BOOST_AUTO_TEST_CASE(ctor_simple) { I2n::clock::Time t; BOOST_CHECK_EQUAL(t.get_sec (), 0); BOOST_CHECK_EQUAL(t.get_nsec (), 0); } BOOST_AUTO_TEST_CASE(ctor_type) { I2n::clock::Time t1 (I2n::clock::type::real); I2n::clock::Time t2 (I2n::clock::type::mono); I2n::clock::Time t3 (I2n::clock::type::boot); I2n::clock::Time t4 (I2n::clock::type::cpu); BOOST_CHECK_EQUAL(t1.get_sec (), 0); BOOST_CHECK_EQUAL(t1.get_nsec (), 0); BOOST_CHECK_EQUAL(t2.get_sec (), 0); BOOST_CHECK_EQUAL(t2.get_nsec (), 0); BOOST_CHECK_EQUAL(t3.get_sec (), 0); BOOST_CHECK_EQUAL(t3.get_nsec (), 0); BOOST_CHECK_EQUAL(t4.get_sec (), 0); BOOST_CHECK_EQUAL(t4.get_nsec (), 0); } BOOST_AUTO_TEST_CASE(ctor_variant) { I2n::clock::Time tmc (I2n::clock::type::mono); I2n::clock::Time tmr (I2n::clock::type::mono, I2n::clock::type::raw); I2n::clock::Time tme (I2n::clock::type::mono, I2n::clock::type::exact); I2n::clock::Time trc (I2n::clock::type::real); I2n::clock::Time tre (I2n::clock::type::real, I2n::clock::type::exact); I2n::clock::Time tb (I2n::clock::type::boot); I2n::clock::Time tcp (I2n::clock::type::cpu); I2n::clock::Time tct (I2n::clock::type::cpu, I2n::clock::type::thread); BOOST_CHECK_EQUAL(tmc.get_sec (), 0); /* MONO */ BOOST_CHECK_EQUAL(tmc.get_nsec (), 0); BOOST_CHECK_EQUAL(tmr.get_sec (), 0); BOOST_CHECK_EQUAL(tmr.get_nsec (), 0); BOOST_CHECK_EQUAL(tme.get_sec (), 0); BOOST_CHECK_EQUAL(tme.get_nsec (), 0); BOOST_CHECK_EQUAL(trc.get_sec (), 0); /* REAL */ BOOST_CHECK_EQUAL(trc.get_nsec (), 0); BOOST_CHECK_EQUAL(tre.get_sec (), 0); BOOST_CHECK_EQUAL(tre.get_nsec (), 0); BOOST_CHECK_EQUAL(tb.get_sec (), 0); /* BOOT */ BOOST_CHECK_EQUAL(tb.get_nsec (), 0); BOOST_CHECK_EQUAL(tcp.get_sec (), 0); /* CPU */ BOOST_CHECK_EQUAL(tcp.get_nsec (), 0); BOOST_CHECK_EQUAL(tct.get_sec (), 0); BOOST_CHECK_EQUAL(tct.get_nsec (), 0); } BOOST_AUTO_TEST_CASE(initializer_now) { boost::optional t = I2n::clock::now (); BOOST_CHECK(t); BOOST_CHECK_GT(t->get_sec (), 0); BOOST_CHECK_EQUAL(t->err, 0); } BOOST_AUTO_TEST_CASE(initializer_zero) { I2n::clock::Time stundenull = I2n::clock::zero (); BOOST_CHECK_EQUAL(stundenull.get_sec (), 0); BOOST_CHECK_EQUAL(stundenull.get_nsec (), 0); BOOST_CHECK_EQUAL(stundenull.err, 0); } BOOST_AUTO_TEST_CASE(member_set_now) { I2n::clock::Time t; BOOST_CHECK(t.set ()); BOOST_CHECK_NE(t.get_sec (), 0); } BOOST_AUTO_TEST_CASE(member_set_value) { I2n::clock::Time t; t.set (42, 42); BOOST_CHECK_EQUAL(t.get_sec (), 42); BOOST_CHECK_EQUAL(t.get_nsec (), 42); } BOOST_AUTO_TEST_CASE(member_set_value_type) { I2n::clock::Time t; t.set (42, 42, I2n::clock::type::real, I2n::clock::type::exact); BOOST_CHECK_EQUAL(t.get_sec (), 42); BOOST_CHECK_EQUAL(t.get_nsec (), 42); } BOOST_AUTO_TEST_CASE(member_add_parts) { I2n::clock::Time t; t.set (42, 42); t.add (2187, 2187); BOOST_CHECK_EQUAL(t.get_sec (), 2229); BOOST_CHECK_EQUAL(t.get_nsec (), 2229); } BOOST_AUTO_TEST_CASE(member_sub_parts) { I2n::clock::Time t; t.set (2, 0L); t.subtract (1, 1L); BOOST_CHECK_EQUAL(t.get_sec (), 0); BOOST_CHECK_EQUAL(t.get_nsec (), 999999999); } BOOST_AUTO_TEST_CASE(member_sub_Time) { I2n::clock::Time t1; I2n::clock::Time t2; t1.set (42, 42L); t2.set (42, 0L); t1.subtract (t2); BOOST_CHECK_EQUAL(t1.get_sec (), 0); BOOST_CHECK_EQUAL(t1.get_nsec (), 42L); } BOOST_AUTO_TEST_CASE(member_diff) { static const time_t five = 5 * 365 * 24 * 3600; I2n::clock::Time t1 (42, 1337); I2n::clock::Time t2 = t1 + five;; I2n::clock::Time t3 = t1 - five;; BOOST_CHECK_EQUAL(t2, I2n::clock::Time ((time_t)42 + five, 1337)); BOOST_CHECK_EQUAL(t3, I2n::clock::Time ((time_t)42 - five, 1337)); BOOST_CHECK_EQUAL(t1.difference (t3), t3.difference (t1)); BOOST_CHECK_EQUAL(t3.difference (t3), t3.difference (t3)); } BOOST_AUTO_TEST_CASE(op_copyassign) { I2n::clock::Time t1; I2n::clock::Time t2; BOOST_CHECK(t1.set ()); t2 = t1; BOOST_CHECK_EQUAL(t1.get_sec (), t2.get_sec ()); BOOST_CHECK_EQUAL(t1.get_nsec (), t2.get_nsec ()); } BOOST_AUTO_TEST_CASE(op_equal) { I2n::clock::Time t1; I2n::clock::Time t2; BOOST_CHECK(t1.set ()); t2 = t1; BOOST_CHECK_EQUAL(t1, t2); } BOOST_AUTO_TEST_CASE(op_add_Time) { I2n::clock::Time t1; I2n::clock::Time t2; I2n::clock::Time tsum; t1.set (2187, 2187); t2.set (1337, 1337); tsum = t1 + t2; BOOST_CHECK_EQUAL(tsum.get_sec (), 3524); BOOST_CHECK_EQUAL(tsum.get_nsec (), 3524); } BOOST_AUTO_TEST_CASE(op_add_Time_carry) { I2n::clock::Time t1; I2n::clock::Time t2; I2n::clock::Time tsum; t1.set (2187, 2187); # if LONG_BIT == 32 t2.set (1300, 2L * 1000 * 1000 * 1000 + 1337); # else t2.set (1300, 37L * 1000 * 1000 * 1000 + 1337); # endif tsum = t1 + t2; # if LONG_BIT == 32 BOOST_CHECK_EQUAL(tsum.get_sec (), 3489); BOOST_CHECK_EQUAL(tsum.get_nsec (), 3524); # else BOOST_CHECK_EQUAL(tsum.get_sec (), 3524); BOOST_CHECK_EQUAL(tsum.get_nsec (), 3524); # endif } BOOST_AUTO_TEST_CASE(op_add_time_t) { I2n::clock::Time t1 (2187, 2187); time_t t2 = 1337; I2n::clock::Time tsum; tsum = t1 + t2; BOOST_CHECK_EQUAL(tsum.get_sec (), 3524); BOOST_CHECK_EQUAL(tsum.get_nsec (), 2187); } BOOST_AUTO_TEST_CASE(op_add_time_t_external) { time_t t1 = 1337; I2n::clock::Time t2 (2187, 2187); I2n::clock::Time tsum; tsum = t1 + t2; BOOST_CHECK_EQUAL(tsum.get_sec (), 3524); BOOST_CHECK_EQUAL(tsum.get_nsec (), 2187); } BOOST_AUTO_TEST_CASE(op_incr_Time) { I2n::clock::Time t1 (2187, 2187); I2n::clock::Time t2 (1337, 1337); t1 += t2; BOOST_CHECK_EQUAL(t1.get_sec (), 3524); BOOST_CHECK_EQUAL(t1.get_nsec (), 3524); } BOOST_AUTO_TEST_CASE(op_incr_time_t) { I2n::clock::Time t1 (2187, 2187); time_t t2 = 1337; t1 += t2; BOOST_CHECK_EQUAL(t1.get_sec (), 3524); BOOST_CHECK_EQUAL(t1.get_nsec (), 2187); } BOOST_AUTO_TEST_CASE(op_subtract_Time) { I2n::clock::Time t1; I2n::clock::Time t2; I2n::clock::Time tdiff; t1.set (2187, 2187); t2.set (1337, 1337); tdiff = t1 - t2; BOOST_CHECK_EQUAL(tdiff.get_sec (), 850); BOOST_CHECK_EQUAL(tdiff.get_nsec (), 850); } BOOST_AUTO_TEST_CASE(op_subtract_time_t) { I2n::clock::Time t1 (2187, 2187); time_t t2 = 1337; I2n::clock::Time tdiff; tdiff = t1 - t2; BOOST_CHECK_EQUAL(tdiff.get_sec (), 850); BOOST_CHECK_EQUAL(tdiff.get_nsec (), 2187); } BOOST_AUTO_TEST_CASE(op_subtract_time_t_external) { time_t t1 = 1337; I2n::clock::Time t2 (2187, 2187); I2n::clock::Time tdiff; tdiff = t1 - t2; BOOST_CHECK_EQUAL(tdiff.get_sec (), -851); BOOST_CHECK_EQUAL(tdiff.get_nsec (), 999997813); } BOOST_AUTO_TEST_CASE(op_decr_Time) { I2n::clock::Time t1 (2187, 2187); I2n::clock::Time t2 (1337, 1337); t1 -= t2; BOOST_CHECK_EQUAL(t1.get_sec (), 850); BOOST_CHECK_EQUAL(t1.get_nsec (), 850); } BOOST_AUTO_TEST_CASE(op_decr_time_t) { I2n::clock::Time t1 (2187, 2187); time_t t2 = 1337; t1 -= t2; BOOST_CHECK_EQUAL(t1.get_sec (), 850); BOOST_CHECK_EQUAL(t1.get_nsec (), 2187); } BOOST_AUTO_TEST_CASE(op_mult_scale) { I2n::clock::Time t1; I2n::clock::Time t2; t1.set (1, 1); t2 = t1 * 42; BOOST_CHECK_EQUAL(t2.get_sec (), 42); BOOST_CHECK_EQUAL(t2.get_nsec (), 42); } BOOST_AUTO_TEST_CASE(op_mult_mutate) { I2n::clock::Time t1 ( 42, 42); I2n::clock::Time t2 (1337, 0); t1 *= 2; t2 *= -10; BOOST_CHECK_EQUAL(t1.get_sec (), 84); BOOST_CHECK_EQUAL(t1.get_nsec (), 84); BOOST_CHECK_EQUAL(t2.get_sec (), -13370); } BOOST_AUTO_TEST_CASE(op_mult_scale_carry) { I2n::clock::Time t1; I2n::clock::Time t2; t1.set (1, 500 * 1000 * 1000); t2 = t1 * 3; BOOST_CHECK_EQUAL(t2.get_sec (), 4); BOOST_CHECK_EQUAL(t2.get_nsec (), 500 * 1000 * 1000); } BOOST_AUTO_TEST_CASE(op_equals) { I2n::clock::Time t1; I2n::clock::Time t2; t1.set (50, 50); t2.set (50, 50); BOOST_CHECK_EQUAL(t1, t2); } BOOST_AUTO_TEST_CASE(compare_equal) { I2n::clock::Time t1; I2n::clock::Time t2; t1.set (42, 42); t2.set (42, 42); BOOST_CHECK_EQUAL(I2n::clock::compare (t1, t2), 0); } BOOST_AUTO_TEST_CASE(compare_equal_type) { I2n::clock::Time t1 (42, 42, I2n::clock::type::real); I2n::clock::Time t2 (42, 42, I2n::clock::type::cpu); I2n::clock::Time t3 (42, 0, I2n::clock::type::real); I2n::clock::Time t4 (42, 42, I2n::clock::type::real); BOOST_CHECK_NE(t1, t2); BOOST_CHECK_NE(t1, t3); BOOST_CHECK_EQUAL(t1, t4); } BOOST_AUTO_TEST_CASE(compare_ne_sec) { I2n::clock::Time t1; I2n::clock::Time t2; t1.set ( 42, 42); t2.set (1337, 42); BOOST_CHECK_EQUAL(I2n::clock::compare (t1, t2), -1); BOOST_CHECK_EQUAL(I2n::clock::compare (t2, t1), 1); } BOOST_AUTO_TEST_CASE(compare_ne_nsec) { I2n::clock::Time t1; I2n::clock::Time t2; t1.set (42, 42); t2.set (42, 1337); BOOST_CHECK_EQUAL(I2n::clock::compare (t1, t2), -1); BOOST_CHECK_EQUAL(I2n::clock::compare (t2, t1), 1); } BOOST_AUTO_TEST_CASE(compare_ne_both) { I2n::clock::Time t1; I2n::clock::Time t2; t1.set (42, 2187); t2.set (23, 1337); BOOST_CHECK_EQUAL(I2n::clock::compare (t1, t2), 1); BOOST_CHECK_EQUAL(I2n::clock::compare (t2, t1), -1); } BOOST_AUTO_TEST_CASE(op_ineq_sec) { I2n::clock::Time t1 (1337); I2n::clock::Time t2 (2187); BOOST_CHECK_LT(t1, t2); BOOST_CHECK_GT(t2, t1); } BOOST_AUTO_TEST_CASE(op_ineq_nsec) { I2n::clock::Time t1 (1337, 23); I2n::clock::Time t2 (1337, 42); BOOST_CHECK_LT(t1, t2); BOOST_CHECK_GT(t2, t1); } BOOST_AUTO_TEST_CASE(op_ineq_both) { I2n::clock::Time t1 (2187, 23); I2n::clock::Time t2 (1337, 42); BOOST_CHECK_LT(t2, t1); BOOST_CHECK_GT(t1, t2); } BOOST_AUTO_TEST_CASE(op_eq_time_t) { boost::optional t1 = I2n::clock::now (); const time_t t2 = time (NULL); /* race here */ *t1 -= (time_t)42; BOOST_CHECK_NE(*t1, t2); BOOST_CHECK_LT(*t1, t2); BOOST_CHECK_GT( t2, *t1); } BOOST_AUTO_TEST_CASE(Format_sec_msec) { I2n::clock::Time t1 (42, 42); I2n::clock::Time t2 ( 4, 242424242); I2n::clock::Time t3 ( 0, 133713371); I2n::clock::Time t4 ( 0, 0); std::string s1 = t1.format_sec_msec (); std::string s2 = t2.format_sec_msec (); std::string s3 = t3.format_sec_msec (); std::string s4 = t4.format_sec_msec (); BOOST_CHECK_EQUAL("42s 0ms" , s1); BOOST_CHECK_EQUAL( "4s 242ms", s2); BOOST_CHECK_EQUAL( "0s 133ms", s3); BOOST_CHECK_EQUAL( "0s 0ms" , s4); } BOOST_AUTO_TEST_CASE(Format_min_sec_msec) { I2n::clock::Time t1 (42*60 + 42, 42); I2n::clock::Time t2 ( 4*60 + 42, 242424242); I2n::clock::Time t3 ( 0*60 + 42, 133713371); I2n::clock::Time t4 ( 0 + 0, 0); std::string s1 = *t1.format_min_sec_msec (); std::string s2 = *t2.format_min_sec_msec (); std::string s3 = *t3.format_min_sec_msec (); std::string s4 = *t4.format_min_sec_msec (); BOOST_CHECK_EQUAL("42m42.000s", s1); BOOST_CHECK_EQUAL( "4m42.242s", s2); BOOST_CHECK_EQUAL( "0m42.133s", s3); BOOST_CHECK_EQUAL( "0m0.000s", s4); } BOOST_AUTO_TEST_CASE(FormatISO8601_T) { I2n::clock::Time t (42, 42); boost::optional s = t.format_iso8601 (true, false, true, false); BOOST_CHECK_EQUAL("00:00:42", *s); } BOOST_AUTO_TEST_CASE(FormatISO8601_DT) { I2n::clock::Time t (1541934671, 0); boost::optional s = t.format_iso8601 (true, true, true, false); BOOST_CHECK_EQUAL("2018-11-11T11:11:11", *s); } BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ) { I2n::clock::Time t (1541934671, 0); boost::optional s = t.format_iso8601 (true, true, true, true); BOOST_CHECK_EQUAL("2018-11-11T11:11:11Z+0000", *s); } BOOST_AUTO_TEST_CASE(Format_make_nice_time) { I2n::clock::Time t (111111, 0); boost::optional s = t.make_nice_time (); BOOST_CHECK_EQUAL("1 day, 06:51:51", *s); } BOOST_AUTO_TEST_CASE(Format_format_full_time) { I2n::clock::Time t (1541934671, 0); /* * brr, the old formatters use localtime without a way to opt out of * it! */ this->set_utc (); boost::optional s = t.format_full_time (); BOOST_CHECK_EQUAL("11.11.2018 11:11", *s); } BOOST_AUTO_TEST_CASE(Format_format_date) { I2n::clock::Time t (1541934671, 0); boost::optional s = t.format_date (); BOOST_CHECK_EQUAL("11.11.2018", *s); } BOOST_AUTO_TEST_CASE(FromString_iso8601_full) { const std::string in1 ("0001-01-01T00:00:00Z+0000"); const std::string in2 ("2018-11-11T11:11:11Z+0000"); this->set_utc (); boost::optional t1 = I2n::clock::time_of_iso8601 (in1); boost::optional t2 = I2n::clock::time_of_iso8601 (in2); # if LONG_BIT == 32 BOOST_CHECK(!t1); # else BOOST_CHECK(t1); BOOST_CHECK_EQUAL(*t1->format_iso8601 (), in1); # endif BOOST_CHECK(t2); BOOST_CHECK_EQUAL(*t2->format_iso8601 (), in2); } BOOST_AUTO_TEST_CASE(FromString_iso8601_full_negyear) { const std::string in1 ("-0001-01-01T00:00:00Z+0000"); const std::string in2 ("-2018-11-11T11:11:11Z+0000"); this->set_utc (); boost::optional t1 = I2n::clock::time_of_iso8601 (in1); boost::optional t2 = I2n::clock::time_of_iso8601 (in2); # if LONG_BIT == 32 BOOST_CHECK(!t1); BOOST_CHECK(!t2); # else BOOST_CHECK(t1); BOOST_CHECK(t2); BOOST_CHECK_EQUAL(*t1->format_iso8601 (), in1); BOOST_CHECK_EQUAL(*t2->format_iso8601 (), in2); # endif } BOOST_AUTO_TEST_CASE(FromString_iso8601_partial) { const std::string in1 ("2018-11-11T11:11:11"); const std::string in2 ("2018-11-11"); this->set_utc (); boost::optional t1 = I2n::clock::time_of_iso8601 (in1, true, true, false); boost::optional t2 = I2n::clock::time_of_iso8601 (in2, true, false, false); BOOST_CHECK(t1); BOOST_CHECK(t2); /* * We test for the difference here which is zero if the number is * correct but causes the difference from the expected value to be * printed in case the test fails. */ BOOST_CHECK_EQUAL(*t1->format_iso8601 (true, true, true, false), in1); BOOST_CHECK_EQUAL(*t2->format_iso8601 (true, true, false, false), in2); } BOOST_AUTO_TEST_CASE(FromString_iso8601_32bit_time_t_err) { const std::string timeless ("11:11:11"); boost::optional untimely = boost::none; this->set_utc (); untimely = I2n::clock::time_of_iso8601 (timeless, false, true, false); # if LONG_BIT == 32 BOOST_CHECK(!untimely); # else BOOST_CHECK(untimely); BOOST_CHECK_EQUAL(*untimely->format_iso8601 (true, false, true, false), timeless); # endif } BOOST_AUTO_TEST_CASE(Ctor_32bit_time_t_err) { boost::optional threw = boost::none; struct tm tm; memset (&tm, 0, sizeof (tm)); tm.tm_sec = 11; tm.tm_min = 11; tm.tm_hour = 11; tm.tm_mday = 11; tm.tm_mon = 10; tm.tm_year = -789; tm.tm_gmtoff = 0; try { I2n::clock::Time untimely (tm); } catch (I2n::clock::conversion_error &exn) { threw = std::string (exn); } # if LONG_BIT == 32 BOOST_CHECK_EQUAL(*threw, "errno=0 [mktime: from struct tm {Sun Nov 11 11:11:11 1111}]"); # else BOOST_CHECK(!threw); # endif } BOOST_AUTO_TEST_CASE(containers_list) { std::list ts; ts.push_back (I2n::clock::zero ()); ts.push_back (I2n::clock::zero ()); BOOST_CHECK_EQUAL(ts.size (), 2); } BOOST_AUTO_TEST_CASE(containers_vec) { std::vector ts; ts.push_back (I2n::clock::zero ()); ts.push_back (I2n::clock::zero ()); BOOST_CHECK_EQUAL(ts.size (), 2); } BOOST_AUTO_TEST_CASE(containers_set) { std::set ts; ts.insert (I2n::clock::zero ()); ts.insert (I2n::clock::Time (42, 2187)); ts.insert (I2n::clock::zero ()); BOOST_CHECK_EQUAL(ts.size (), 2); } BOOST_AUTO_TEST_CASE(containers_list_mean) { std::list ts; ts.push_back (I2n::clock::Time (42, 42)); ts.push_back (I2n::clock::Time (1337, 1337)); BOOST_CHECK_EQUAL(I2n::clock::mean (ts), I2n::clock::Time (689, 500000689)); } BOOST_AUTO_TEST_CASE(containers_list_mean_zero) { std::list ts; ts.push_back (I2n::clock::Time (0, 0)); ts.push_back (I2n::clock::Time (0, 0)); ts.push_back (I2n::clock::Time (0, 0)); ts.push_back (I2n::clock::Time (0, 0)); BOOST_CHECK_EQUAL(I2n::clock::mean (ts), I2n::clock::zero ()); } BOOST_AUTO_TEST_CASE(containers_list_mean_empty) { std::list ts; BOOST_CHECK_EQUAL(I2n::clock::mean (ts), I2n::clock::Time (0, 0)); } BOOST_AUTO_TEST_CASE(containers_set_mean) { std::set ts; ts.insert (I2n::clock::Time (42)); ts.insert (I2n::clock::Time (1337)); ts.insert (I2n::clock::Time (2187)); BOOST_CHECK_EQUAL(I2n::clock::mean (ts), I2n::clock::Time (1188, 666666666)); } BOOST_AUTO_TEST_CASE(containers_set_median_empty) { std::set ts; BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (0, 0)); } BOOST_AUTO_TEST_CASE(containers_set_median_one) { std::set ts; ts.insert (I2n::clock::Time (42, 0)); BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (42, 0)); } BOOST_AUTO_TEST_CASE(containers_set_median_multi) { std::set ts; ts.insert (I2n::clock::Time (42)); ts.insert (I2n::clock::Time (1337)); ts.insert (I2n::clock::Time (2187)); BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (1337)); } BOOST_AUTO_TEST_CASE(containers_vec_median_multi) { std::vector ts; ts.push_back (I2n::clock::Time (42)); ts.push_back (I2n::clock::Time (1337)); ts.push_back (I2n::clock::Time (2187)); BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (1337)); } BOOST_AUTO_TEST_CASE(containers_list_median_multi) { std::list ts; ts.push_back (I2n::clock::Time (42)); ts.push_back (I2n::clock::Time (1337)); ts.push_back (I2n::clock::Time (2187)); ts.push_back (I2n::clock::Time (0xdead)); ts.push_back (I2n::clock::Time (0xbeef)); BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (2187)); } BOOST_AUTO_TEST_CASE(containers_list_median_multi_evensize) { std::list ts; ts.push_back (I2n::clock::Time (42)); ts.push_back (I2n::clock::Time (1337)); ts.push_back (I2n::clock::Time (2187)); ts.push_back (I2n::clock::Time (0xf00d)); ts.push_back (I2n::clock::Time (0xfeed)); ts.push_back (I2n::clock::Time (0xdeadf0e)); BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (0xf00d)); } BOOST_AUTO_TEST_SUITE_END() /* [Clock] */ BOOST_AUTO_TEST_SUITE_END()