From 1720aceeab541ac22686bdfc047e477e2d513fa5 Mon Sep 17 00:00:00 2001 From: Gerd v. Egidy Date: Wed, 28 Jan 2009 01:06:36 +0100 Subject: [PATCH] add class for weekly scheduling, intervals still missing --- src/Makefile.am | 10 +++--- src/cron.cpp | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/cron.hpp | 52 ++++++++++++++++++++++++++++++++ src/timefunc.cpp | 25 +++++++++++++++ src/timefunc.hxx | 2 + test/Makefile.am | 4 +- test/test_cron.cpp | 70 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 239 insertions(+), 7 deletions(-) create mode 100644 src/cron.cpp create mode 100644 src/cron.hpp create mode 100644 test/test_cron.cpp diff --git a/src/Makefile.am b/src/Makefile.am index a5a6b2f..b0aaecf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,15 +4,15 @@ INCLUDES = -I$(top_srcdir)/src @LIBGETTEXT_CFLAGS@ @LIBICONV_CFLAGS@ $(all_inclu # the library search path. lib_LTLIBRARIES = libi2ncommon.la -include_HEADERS = containerfunc.hpp daemonfunc.hpp filefunc.hxx \ +include_HEADERS = containerfunc.hpp cron.hpp daemonfunc.hpp filefunc.hxx \ i2n_configdata.hpp i2n_configfile.hpp insocketstream.hxx ip_type.hxx ipfunc.hxx \ log_macros.hpp logfunc.hpp logread.hxx oftmpstream.hxx pidfile.hpp pipestream.hxx \ pointer_func.hpp signalfunc.hpp source_track_basics.hpp stringfunc.hxx timefunc.hxx \ tracefunc.hpp userfunc.hpp -libi2ncommon_la_SOURCES = containerfunc.cpp daemonfunc.cpp filefunc.cpp \ - i2n_configfile.cpp ipfunc.cpp logfunc.cpp logread.cpp oftmpstream.cpp pidfile.cpp \ - pointer_func.cpp signalfunc.cpp source_track_basics.cpp stringfunc.cpp timefunc.cpp \ - tracefunc.cpp userfunc.cpp +libi2ncommon_la_SOURCES = containerfunc.cpp cron.cpp daemonfunc.cpp \ + filefunc.cpp i2n_configfile.cpp ipfunc.cpp logfunc.cpp logread.cpp oftmpstream.cpp \ + pidfile.cpp pointer_func.cpp signalfunc.cpp source_track_basics.cpp stringfunc.cpp \ + timefunc.cpp tracefunc.cpp userfunc.cpp # Note: If you specify a:b:c as the version in the next line, # the library that is made has version (a-c).c.b. In this diff --git a/src/cron.cpp b/src/cron.cpp new file mode 100644 index 0000000..f3103bf --- /dev/null +++ b/src/cron.cpp @@ -0,0 +1,83 @@ + +/** @file + * @brief repeating time-points and intervals + * + * @copyright Copyright © 2009 by Intra2net AG + * @license commercial + * @contact info@intra2net.com + * + */ +#include + +#include + +#include + +bool WeekCron::is_sane() +{ + if (begin < 0 || begin > 86399) + return false; + + if (every != -1) + { + if (end < 0 || end > 86399 || + every < 0 || every > 86399 || + begin > end) + return false; + } + + return true; +} + +time_t WeekCron::get_next_run(time_t calc_from) +{ + if (!calc_from) + calc_from=time(NULL); + + if (!is_sane()) + throw std::runtime_error("illegal cron value"); + + if (calc_from <= 86400) + throw std::runtime_error("WeekCron doesn't work for times near 0"); + + if (week.none_set()) + return 0; + + if (every == -1) + { + // point in time + return get_next_point(calc_from); + } + else + { + // interval + + // TODO + } +} + +time_t WeekCron::get_next_point(time_t calc_from) +{ + struct tm ft; + localtime_r(&calc_from,&ft); + + // take care of the weekday + ft.tm_mday+=week.days_till_set(static_cast(ft.tm_wday)); + + ft.tm_hour=0; + ft.tm_min=0; + ft.tm_sec=begin; + + time_t target=mktime(&ft); + + // todays schedule could already been through + if (target < calc_from) + { + ft.tm_mday++; + target=mktime(&ft); + } + + return target; +} + + diff --git a/src/cron.hpp b/src/cron.hpp new file mode 100644 index 0000000..26e67f4 --- /dev/null +++ b/src/cron.hpp @@ -0,0 +1,52 @@ +/** @file + * @brief repeating time-points and intervals + * + * @copyright Copyright © 2009 by Intra2net AG + * @license commercial + * @contact info@intra2net.com + * + */ + +#ifndef __CRON_HPP +#define __CRON_HPP + +#include + +#include + +/** + @brief time-points and intervals repeating each week + @note begin and end are given in seconds since start of the day +*/ +class WeekCron +{ + private: + + int begin; + int end; + int every; + WEEK week; + + time_t get_next_point(time_t calc_from=0); + + public: + + WeekCron(void) + : begin(0), end(0), every(-1), week() + { } + + WeekCron(const std::string& daystring, int _begin) + : begin(_begin), end(0), every(-1), week(daystring) + { } + + WeekCron(const std::string& daystring, int _begin, int _end, int _every) + : begin(_begin), end(_end), every(_every), week(daystring) + { } + + bool is_sane(); + + time_t get_next_run(time_t calc_from=0); + +}; + +#endif diff --git a/src/timefunc.cpp b/src/timefunc.cpp index a9bc8df..f66e61b 100644 --- a/src/timefunc.cpp +++ b/src/timefunc.cpp @@ -183,6 +183,31 @@ void WEEK::set(const std::string& daystring) } } +/** + @brief returns the number of days till the next weekday which is set + @param start weekday to start checking + @note returns 0 if the start-day is set +*/ +int WEEK::days_till_set(WEEKDAY start) +{ + if (none_set()) + return -1; + + for (unsigned int days=0; days < 8; days++) + { + unsigned int check=start+days; + if (check > 6) + check-=7; + if (is_set(static_cast(check))) + return days; + } + + throw logic_error("can't find next weekday"); + + // fake + return -1; +} + std::string WEEK::get_daystring() const { ostringstream out; diff --git a/src/timefunc.hxx b/src/timefunc.hxx index 9ceb753..8467af6 100644 --- a/src/timefunc.hxx +++ b/src/timefunc.hxx @@ -75,6 +75,8 @@ class WEEK bool none_set() const { return days.none(); } + int days_till_set(WEEKDAY day); + std::string get_daystring() const; std::string get_displaystring() const; std::string get_netfilterstring() const; diff --git a/test/Makefile.am b/test/Makefile.am index 0cc3379..31d151d 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -2,8 +2,8 @@ INCLUDES = -I$(top_srcdir)/configlib -I$(top_srcdir)/src @CPPUNIT_CFLAGS@ METASOURCES = AUTO check_PROGRAMS = test test_SOURCES = ip_range.cpp stringfunc.cpp test.cpp test_containerfunc.cpp \ - test_filefunc.cpp test_global_config.cpp test_logging.cpp test_pidfile.cpp \ - test_timefunc.cpp + test_cron.cpp test_filefunc.cpp test_global_config.cpp test_logging.cpp \ + test_pidfile.cpp test_timefunc.cpp test_LDADD = $(top_builddir)/src/libi2ncommon.la \ $(top_builddir)/configlib/libi2ncommon_config.la @CPPUNIT_LIBS@ diff --git a/test/test_cron.cpp b/test/test_cron.cpp new file mode 100644 index 0000000..ca83ba0 --- /dev/null +++ b/test/test_cron.cpp @@ -0,0 +1,70 @@ +/** @file + * @brief unit test for cron functions. + * + * @copyright Copyright © 2009 by Intra2net AG + * @license commercial + * @contact info@intra2net.com + * + */ + +#include +#include +#include + +#include +#include + +#include + +using namespace std; +using namespace CppUnit; + +class TestCronFunc : public TestFixture +{ + CPPUNIT_TEST_SUITE(TestCronFunc); + + CPPUNIT_TEST(NotYetToday); + CPPUNIT_TEST(LaterToday); + CPPUNIT_TEST(Tomorrow); + CPPUNIT_TEST(NextWeek); + + CPPUNIT_TEST_SUITE_END(); + +public: + + void setUp() + { + // our check-values are set for Germany + setenv("TZ",":Europe/Berlin",1); + } + + void tearDown() + { } + + void NotYetToday() + { + WeekCron cron("2345",3600); + CPPUNIT_ASSERT_EQUAL( 1233100800, static_cast(cron.get_next_run(1233099657))); + } + + void LaterToday() + { + WeekCron cron("2345",3600); + CPPUNIT_ASSERT_EQUAL( 1233187200, static_cast(cron.get_next_run(1233100801))); + } + + void Tomorrow() + { + WeekCron cron("45",3600); + CPPUNIT_ASSERT_EQUAL( 1233187200, static_cast(cron.get_next_run(1233099657))); + } + + void NextWeek() + { + WeekCron cron("1",3600); + CPPUNIT_ASSERT_EQUAL( 1233532800, static_cast(cron.get_next_run(1233099657))); + } + +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(TestCronFunc); -- 1.7.1