36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering/***
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering This file is part of systemd.
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering Copyright 2012 Lennart Poettering
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering systemd is free software; you can redistribute it and/or modify it
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering under the terms of the GNU Lesser General Public License as published by
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering (at your option) any later version.
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering systemd is distributed in the hope that it will be useful, but
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering Lesser General Public License for more details.
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering You should have received a copy of the GNU Lesser General Public License
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering***/
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering#include <string.h>
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "alloc-util.h"
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering#include "calendarspec.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "string-util.h"
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering#include "util.h"
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poetteringstatic void test_one(const char *input, const char *output) {
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering CalendarSpec *c;
aaa870928ffe140783aff0724d4927cea8da56aeLennart Poettering _cleanup_free_ char *p = NULL, *q = NULL;
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering usec_t u;
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering char buf[FORMAT_TIMESTAMP_MAX];
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering int r;
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering assert_se(calendar_spec_from_string(input, &c) >= 0);
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering assert_se(calendar_spec_to_string(c, &p) >= 0);
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering printf("\"%s\" → \"%s\"\n", input, p);
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering assert_se(streq(p, output));
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering u = now(CLOCK_REALTIME);
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering r = calendar_spec_next_usec(c, u, &u);
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering printf("Next: %s\n", r < 0 ? strerror(-r) : format_timestamp(buf, sizeof(buf), u));
aaa870928ffe140783aff0724d4927cea8da56aeLennart Poettering calendar_spec_free(c);
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering
aaa870928ffe140783aff0724d4927cea8da56aeLennart Poettering assert_se(calendar_spec_from_string(p, &c) >= 0);
aaa870928ffe140783aff0724d4927cea8da56aeLennart Poettering assert_se(calendar_spec_to_string(c, &q) >= 0);
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering calendar_spec_free(c);
aaa870928ffe140783aff0724d4927cea8da56aeLennart Poettering
aaa870928ffe140783aff0724d4927cea8da56aeLennart Poettering assert_se(streq(q, p));
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering}
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venevstatic void test_next(const char *input, const char *new_tz, usec_t after, usec_t expect) {
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev CalendarSpec *c;
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev usec_t u;
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev char *old_tz;
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev char buf[FORMAT_TIMESTAMP_MAX];
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev int r;
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev old_tz = getenv("TZ");
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev if (old_tz)
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev old_tz = strdupa(old_tz);
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev if (new_tz)
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev assert_se(setenv("TZ", new_tz, 1) >= 0);
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev else
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev assert_se(unsetenv("TZ") >= 0);
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev tzset();
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev assert_se(calendar_spec_from_string(input, &c) >= 0);
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev printf("\"%s\"\n", input);
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev u = after;
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev r = calendar_spec_next_usec(c, after, &u);
f22554a06d81359b7c24f72f2b30f87f8526fb3bHristo Venev printf("At: %s\n", r < 0 ? strerror(-r) : format_timestamp_us(buf, sizeof(buf), u));
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev if (expect != (usec_t)-1)
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev assert_se(r >= 0 && u == expect);
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev else
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev assert(r == -ENOENT);
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev calendar_spec_free(c);
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev if (old_tz)
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev assert_se(setenv("TZ", old_tz, 1) >= 0);
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev else
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev assert_se(unsetenv("TZ") >= 0);
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev tzset();
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev}
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poetteringint main(int argc, char* argv[]) {
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering CalendarSpec *c;
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("Sat,Thu,Mon-Wed,Sat-Sun", "Mon-Thu,Sat,Sun *-*-* 00:00:00");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("Mon,Sun 12-*-* 2,1:23", "Mon,Sun 2012-*-* 01,02:23:00");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("Wed *-1", "Wed *-*-01 00:00:00");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("Wed-Wed,Wed *-1", "Wed *-*-01 00:00:00");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("Wed, 17:48", "Wed *-*-* 17:48:00");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("Wed-Sat,Tue 12-10-15 1:2:3", "Tue-Sat 2012-10-15 01:02:03");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("*-*-7 0:0:0", "*-*-07 00:00:00");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("10-15", "*-10-15 00:00:00");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("monday *-12-* 17:00", "Mon *-12-* 17:00:00");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("Mon,Fri *-*-3,1,2 *:30:45", "Mon,Fri *-*-01,02,03 *:30:45");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("12,14,13,12:20,10,30", "*-*-* 12,13,14:10,20,30:00");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("mon,fri *-1/2-1,3 *:30:45", "Mon,Fri *-01/2-01,03 *:30:45");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("03-05 08:05:40", "*-03-05 08:05:40");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("08:05:40", "*-*-* 08:05:40");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("05:40", "*-*-* 05:40:00");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("Sat,Sun 12-05 08:05:40", "Sat,Sun *-12-05 08:05:40");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("Sat,Sun 08:05:40", "Sat,Sun *-*-* 08:05:40");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("2003-03-05 05:40", "2003-03-05 05:40:00");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("2003-03-05", "2003-03-05 00:00:00");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("03-05", "*-03-05 00:00:00");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("hourly", "*-*-* *:00:00");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("daily", "*-*-* 00:00:00");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("monthly", "*-*-01 00:00:00");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("weekly", "Mon *-*-* 00:00:00");
dbfd41e2df44113d1d2d07fb751db11b443f186bLennart Poettering test_one("minutely", "*-*-* *:*:00");
dbfd41e2df44113d1d2d07fb751db11b443f186bLennart Poettering test_one("quarterly", "*-01,04,07,10-01 00:00:00");
dbfd41e2df44113d1d2d07fb751db11b443f186bLennart Poettering test_one("semi-annually", "*-01,07-01 00:00:00");
dbfd41e2df44113d1d2d07fb751db11b443f186bLennart Poettering test_one("annually", "*-01-01 00:00:00");
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering test_one("*:2/3", "*-*-* *:02/3:00");
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev test_one("2015-10-25 01:00:00 uTc", "2015-10-25 01:00:00 UTC");
f22554a06d81359b7c24f72f2b30f87f8526fb3bHristo Venev test_one("2016-03-27 03:17:00.4200005", "2016-03-27 03:17:00.420001");
f22554a06d81359b7c24f72f2b30f87f8526fb3bHristo Venev test_one("2016-03-27 03:17:00/0.42", "2016-03-27 03:17:00/0.420000");
f22554a06d81359b7c24f72f2b30f87f8526fb3bHristo Venev test_one("2016-03-27 03:17:00/0.42", "2016-03-27 03:17:00/0.420000");
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev test_next("2016-03-27 03:17:00", "", 12345, 1459048620000000);
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev test_next("2016-03-27 03:17:00", "CET", 12345, 1459041420000000);
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev test_next("2016-03-27 03:17:00", "EET", 12345, -1);
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev test_next("2016-03-27 03:17:00 UTC", NULL, 12345, 1459048620000000);
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev test_next("2016-03-27 03:17:00 UTC", "", 12345, 1459048620000000);
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev test_next("2016-03-27 03:17:00 UTC", "CET", 12345, 1459048620000000);
9d5bd70d9e839a5f01ade0c5767503f6fad6f320Hristo Venev test_next("2016-03-27 03:17:00 UTC", "EET", 12345, 1459048620000000);
f22554a06d81359b7c24f72f2b30f87f8526fb3bHristo Venev test_next("2016-03-27 03:17:00.420000001 UTC", "EET", 12345, 1459048620420000);
f22554a06d81359b7c24f72f2b30f87f8526fb3bHristo Venev test_next("2016-03-27 03:17:00.4200005 UTC", "EET", 12345, 1459048620420001);
f22554a06d81359b7c24f72f2b30f87f8526fb3bHristo Venev test_next("2015-11-13 09:11:23.42", "EET", 12345, 1447398683420000);
f22554a06d81359b7c24f72f2b30f87f8526fb3bHristo Venev test_next("2015-11-13 09:11:23.42/1.77", "EET", 1447398683420000, 1447398685190000);
f22554a06d81359b7c24f72f2b30f87f8526fb3bHristo Venev test_next("2015-11-13 09:11:23.42/1.77", "EET", 1447398683419999, 1447398683420000);
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering assert_se(calendar_spec_from_string("test", &c) < 0);
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering assert_se(calendar_spec_from_string("", &c) < 0);
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering assert_se(calendar_spec_from_string("7", &c) < 0);
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering assert_se(calendar_spec_from_string("121212:1:2", &c) < 0);
f22554a06d81359b7c24f72f2b30f87f8526fb3bHristo Venev assert_se(calendar_spec_from_string("2000-03-05.23 00:00:00", &c) < 0);
f22554a06d81359b7c24f72f2b30f87f8526fb3bHristo Venev assert_se(calendar_spec_from_string("2000-03-05 00:00.1:00", &c) < 0);
f22554a06d81359b7c24f72f2b30f87f8526fb3bHristo Venev assert_se(calendar_spec_from_string("00:00:00/0.00000001", &c) < 0);
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering return 0;
36697dc0199e25f09b78090fcf5f1cf8a3648ffdLennart Poettering}