From dfbe7ca9de60b95551dcb0c2441a59a479a8cdfe Mon Sep 17 00:00:00 2001 From: Thomas Jarosch Date: Fri, 30 Jan 2009 10:34:10 +0100 Subject: [PATCH] Added some safety checks to WeekCron. Updated StartHourStaysTheSameTill2038 unit test --- src/cron.cpp | 20 +++++++++++++------- src/cron.hpp | 6 +++--- test/test_cron.cpp | 39 ++++++++++++++++----------------------- 3 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/cron.cpp b/src/cron.cpp index 08d1e74..3983632 100644 --- a/src/cron.cpp +++ b/src/cron.cpp @@ -74,7 +74,7 @@ bool WeekCron::is_sane() const * @return Next point in time the item is scheduled for * returns constant #StNimmerleinsDay if it is scheduled never */ -time_t WeekCron::get_next_run(time_t calc_from) +time_t WeekCron::get_next_run(time_t calc_from) const { if (!calc_from) calc_from=time(NULL); @@ -131,13 +131,14 @@ time_t WeekCron::get_next_run(time_t calc_from) If yes, we will advance to the next day. * @return Next point in time */ -time_t WeekCron::get_next_point(const time_t calc_from, const int daysec, const bool todaycheck) +time_t WeekCron::get_next_point(const time_t calc_from, const int daysec, const bool todaycheck) const { struct tm ft; - localtime_r(&calc_from,&ft); + if (localtime_r(&calc_from,&ft) == NULL) + return calc_from; // take care of the weekday - ft.tm_mday+=Week.days_till_set(static_cast(ft.tm_wday)); + ft.tm_mday+=Week.days_till_set(static_cast(ft.tm_wday)); //lint !e737 !e713 ft.tm_hour=0; ft.tm_min=0; @@ -147,6 +148,8 @@ time_t WeekCron::get_next_point(const time_t calc_from, const int daysec, const // get unixtime of start of the day and add daysec time_t target=mktime(&ft)+daysec; + if (target == (time_t)-1) + return calc_from; // todays schedule could already been through or now if (todaycheck && target <= calc_from) @@ -171,13 +174,14 @@ time_t WeekCron::get_next_point(const time_t calc_from, const int daysec, const If yes, we will go back to the previos day * @return Previous point in time */ -time_t WeekCron::get_previousnow_point(const time_t calc_from, const int daysec, const bool todaycheck) +time_t WeekCron::get_previousnow_point(const time_t calc_from, const int daysec, const bool todaycheck) const { struct tm ft; - localtime_r(&calc_from,&ft); + if (localtime_r(&calc_from,&ft) == NULL) + return calc_from; // take care of the weekday - ft.tm_mday-=Week.days_since_set(static_cast(ft.tm_wday)); + ft.tm_mday-=Week.days_since_set(static_cast(ft.tm_wday)); //lint !e737 !e713 ft.tm_hour=0; ft.tm_min=0; @@ -187,6 +191,8 @@ time_t WeekCron::get_previousnow_point(const time_t calc_from, const int daysec, // get unixtime of start of the day and add daysec time_t target=mktime(&ft)+daysec; + if (target == (time_t)-1) + return calc_from; // target later than we are looking for // target==calc_from is ok (that's why it is called lastnow...) diff --git a/src/cron.hpp b/src/cron.hpp index ff0bd3e..4563ae4 100644 --- a/src/cron.hpp +++ b/src/cron.hpp @@ -36,8 +36,8 @@ class WeekCron /// Stores the active days this WeekCron is valid for I2n::Time::Week Week; - time_t get_next_point(const time_t calc_from, const int daysec, const bool todaycheck); - time_t get_previousnow_point(const time_t calc_from, const int daysec, const bool todaycheck); + time_t get_next_point(const time_t calc_from, const int daysec, const bool todaycheck) const; + time_t get_previousnow_point(const time_t calc_from, const int daysec, const bool todaycheck) const; public: WeekCron(const std::string& daystring, const int begin); @@ -45,7 +45,7 @@ class WeekCron bool is_sane() const; - time_t get_next_run(time_t calc_from=0); + time_t get_next_run(time_t calc_from=0) const; }; } diff --git a/test/test_cron.cpp b/test/test_cron.cpp index a961ddf..d55ea93 100644 --- a/test/test_cron.cpp +++ b/test/test_cron.cpp @@ -82,7 +82,7 @@ class TestCronFunc : public TestFixture CPPUNIT_TEST(IntervalOnceShort); CPPUNIT_TEST(IntervalTooShort); -// CPPUNIT_TEST(StartHourStaysTheSameTill2038); + CPPUNIT_TEST(StartHourStaysTheSameTill2038); CPPUNIT_TEST_SUITE_END(); @@ -465,35 +465,28 @@ public: void StartHourStaysTheSameTill2038() { - time_t result = 0; - struct tm result_localtime; + int daysec = 79200; - // Schedule daily at 22h from 1970 till 01.01.2038. Check every 30 minutes. - WeekCron cron("0123456",79200); - for (time_t now = 86400*15; now < 2145916800; now += 30*60) + // Schedule daily at 22h from 1970 till 01.01.2038. Check every 90 minutes. + WeekCron cron("0123456", daysec); + for (time_t now = 86400*15; now < 2145916800; now += 90*60) { - result = cron.get_next_run(now); + time_t result = cron.get_next_run(now); - bool conversion_ok = (localtime_r(&result, &result_localtime) != NULL); + // Calculate unix time for the begin of the day + struct tm calc_daybegin; + bool conversion_ok = (localtime_r(&result, &calc_daybegin) != NULL); CPPUNIT_ASSERT_EQUAL(true, conversion_ok); - if (result_localtime.tm_hour != 22) - { - struct tm debug_now; + calc_daybegin.tm_hour=0; + calc_daybegin.tm_min=0; + calc_daybegin.tm_sec=0; + // tm_isdst means to use the dst in use at the given time + calc_daybegin.tm_isdst=-1; - conversion_ok = (localtime_r(&now, &debug_now) != NULL); - CPPUNIT_ASSERT_EQUAL(true, conversion_ok); + time_t daybegin = mktime(&calc_daybegin); - char buf[50]; - strftime(buf, 50, "%Y-%m-%d %H:%M:%S", &debug_now); - - cout << "ERROR: Failed for " << now << " (" << buf << "): Resulting hour is " << result_localtime.tm_hour << ". Ignoring." << endl; - - // TODO: Remove this line once the test is working - result_localtime.tm_hour = 22; - } - - CPPUNIT_ASSERT_EQUAL(22, result_localtime.tm_hour); + CPPUNIT_ASSERT_EQUAL(daybegin + daysec, result); } } }; -- 1.7.1