martinzink commented on code in PR #1335: URL: https://github.com/apache/nifi-minifi-cpp/pull/1335#discussion_r882753117
########## libminifi/test/unit/CronTests.cpp: ########## @@ -0,0 +1,641 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <string> + +#include "../Catch.h" +#include "utils/Cron.h" +#include "date/date.h" +#include "date/tz.h" + +using std::chrono::system_clock; +using std::chrono::seconds; +using org::apache::nifi::minifi::utils::Cron; + + +void checkNext(const std::string& expr, const date::zoned_time<seconds>& from, const date::zoned_time<seconds>& next) { + auto cron_expression = Cron(expr); + auto next_trigger = cron_expression.calculateNextTrigger(from.get_local_time()); + CHECK(next_trigger == next.get_local_time()); +} + + +TEST_CASE("Cron expression ctor tests", "[cron]") { + REQUIRE_THROWS(Cron("1600 ms")); + REQUIRE_THROWS(Cron("foo")); + REQUIRE_THROWS(Cron("61 0 0 * * *")); + REQUIRE_THROWS(Cron("0 61 0 * * *")); + REQUIRE_THROWS(Cron("0 0 24 * * *")); + REQUIRE_THROWS(Cron("0 0 0 32 * *")); + REQUIRE_THROWS(Cron("0 0 0 32 * *")); + + // Number of fields must be 6 or 7 + REQUIRE_THROWS(Cron("* * * * *")); + REQUIRE_NOTHROW(Cron("* * * * * *")); + REQUIRE_NOTHROW(Cron("* * * * * * *")); + REQUIRE_THROWS(Cron("* * * * * * * *")); + + // LW can only be used in 4th field + REQUIRE_THROWS(Cron("LW * * * * * *")); + REQUIRE_THROWS(Cron("* LW * * * * *")); + REQUIRE_THROWS(Cron("* * LW * * * *")); + REQUIRE_NOTHROW(Cron("* * * LW * * *")); + REQUIRE_THROWS(Cron("* * * * LW * *")); + REQUIRE_THROWS(Cron("* * * * * LW *")); + REQUIRE_THROWS(Cron("* * * * * * LW")); + + // n#m can only be used in 6th field + REQUIRE_THROWS(Cron("2#1 * * * * * *")); + REQUIRE_THROWS(Cron("* 2#1 * * * * *")); + REQUIRE_THROWS(Cron("* * 2#1 * * * *")); + REQUIRE_THROWS(Cron("* * * 2#1 * * *")); + REQUIRE_THROWS(Cron("* * * * 2#1 * *")); + REQUIRE_NOTHROW(Cron("* * * * * 2#1 *")); + REQUIRE_THROWS(Cron("* * * * * * 2#1")); + + // L can only be used in 4th, 5th, 6th fields + REQUIRE_THROWS(Cron("L * * * * * *")); + REQUIRE_THROWS(Cron("* L * * * * *")); + REQUIRE_THROWS(Cron("* * L * * * *")); + REQUIRE_NOTHROW(Cron("* * * L * * *")); + REQUIRE_THROWS(Cron("* * * * L * *")); + REQUIRE_NOTHROW(Cron("* * * * * L *")); + REQUIRE_THROWS(Cron("* * * * * * L")); + + REQUIRE_NOTHROW(Cron("0 0 12 * * ?")); + REQUIRE_NOTHROW(Cron("0 15 10 ? * *")); + REQUIRE_NOTHROW(Cron("0 15 10 * * ?")); + REQUIRE_NOTHROW(Cron("0 15 10 * * ? *")); + REQUIRE_NOTHROW(Cron("0 15 10 * * ? 2005")); + REQUIRE_NOTHROW(Cron("0 * 14 * * ?")); + REQUIRE_NOTHROW(Cron("0 0/5 14 * * ?")); + REQUIRE_NOTHROW(Cron("0 0/5 14,18 * * ?")); + REQUIRE_NOTHROW(Cron("0 0-5 14 * * ?")); + REQUIRE_NOTHROW(Cron("0 10,44 14 ? 3 WED")); + REQUIRE_NOTHROW(Cron("0 15 10 ? * MON-FRI")); + REQUIRE_NOTHROW(Cron("0 15 10 15 * ?")); + REQUIRE_NOTHROW(Cron("0 15 10 L * ?")); + REQUIRE_NOTHROW(Cron("0 15 10 L-2 * ?")); + REQUIRE_NOTHROW(Cron("0 15 10 ? * 6L")); + REQUIRE_NOTHROW(Cron("0 15 10 ? * 6L")); + REQUIRE_NOTHROW(Cron("0 15 10 ? * 6L 2002-2005")); + REQUIRE_NOTHROW(Cron("0 15 10 ? * 6#3")); + REQUIRE_NOTHROW(Cron("0 0 12 1/5 * ?")); + REQUIRE_NOTHROW(Cron("0 11 11 11 11 ?")); +} + +TEST_CASE("Cron allowed nonnumerical inputs", "[cron]") { + REQUIRE_NOTHROW(Cron("* * * * Jan,fEb,MAR,Apr,May,jun,Jul,Aug,Sep,Oct,Nov,Dec * *")); + REQUIRE_NOTHROW(Cron("* * * * * Mon,tUe,WeD,Thu,Fri,SAT,Sun *")); +} + +TEST_CASE("Cron::calculateNextTrigger", "[cron]") { + using date::sys_days; + using namespace date::literals; + using namespace std::literals::chrono_literals; +#ifdef WIN32 + date::set_install(TZ_DATA_DIR); +#endif + + checkNext("0/15 * 1-4 * * ?", + sys_days(2012_y / 07 / 01) + 9h + 53min + 50s, + sys_days(2012_y / 07 / 02) + 01h + 00min + 00s); + checkNext("0/15 * 1-4 * * ? *", + sys_days(2012_y / 07 / 01) + 9h + 53min + 50s, + sys_days(2012_y / 07 / 02) + 01h + 00min + 00s); + checkNext("0/15 * 1-4 * * ?", + sys_days(2012_y / 07 / 01) + 9h + 53min + 00s, + sys_days(2012_y / 07 / 02) + 01h + 00min + 00s); + checkNext("*/15 * 1-4 * * ?", + sys_days(2012_y / 07 / 01) + 9h + 53min + 50s, + sys_days(2012_y / 07 / 02) + 01h + 00min + 00s); + checkNext("*/15 * 1-4 * * ? *", + sys_days(2012_y / 07 / 01) + 9h + 53min + 50s, + sys_days(2012_y / 07 / 02) + 01h + 00min + 00s); + checkNext("*/15 * 1-4 * * ?", + sys_days(2012_y / 07 / 01) + 9h + 53min + 00s, + sys_days(2012_y / 07 / 02) + 01h + 00min + 00s); + checkNext("0 0/2 1-4 * * ?", + sys_days(2012_y / 07 / 01) + 9h + 00min + 00s, + sys_days(2012_y / 07 / 02) + 01h + 00min + 00s); + checkNext("* * * * * ?", + sys_days(2012_y / 07 / 01) + 9h + 00min + 00s, + sys_days(2012_y / 07 / 01) + 9h + 00min + 01s); + checkNext("* * * * * ?", + sys_days(2012_y / 12 / 01) + 9h + 00min + 58s, + sys_days(2012_y / 12 / 01) + 9h + 00min + 59s); + checkNext("10 * * * * ?", + sys_days(2012_y / 12 / 01) + 9h + 42min + 9s, + sys_days(2012_y / 12 / 01) + 9h + 42min + 10s); + checkNext("11 * * * * ?", + sys_days(2012_y / 12 / 01) + 9h + 42min + 10s, + sys_days(2012_y / 12 / 01) + 9h + 42min + 11s); + checkNext("10 * * * * ?", + sys_days(2012_y / 12 / 01) + 9h + 42min + 10s, + sys_days(2012_y / 12 / 01) + 9h + 43min + 10s); + checkNext("10-15 * * * * ?", + sys_days(2012_y / 12 / 01) + 9h + 42min + 9s, + sys_days(2012_y / 12 / 01) + 9h + 42min + 10s); + checkNext("10-15 * * * * ?", + sys_days(2012_y / 12 / 01) + 21h + 42min + 14s, + sys_days(2012_y / 12 / 01) + 21h + 42min + 15s); + checkNext("0 * * * * ?", + sys_days(2012_y / 12 / 01) + 21h + 10min + 42s, + sys_days(2012_y / 12 / 01) + 21h + 11min + 00s); + checkNext("0 * * * * ?", + sys_days(2012_y / 12 / 01) + 21h + 11min + 00s, + sys_days(2012_y / 12 / 01) + 21h + 12min + 00s); + checkNext("0 11 * * * ?", + sys_days(2012_y / 12 / 01) + 21h + 10min + 42s, + sys_days(2012_y / 12 / 01) + 21h + 11min + 00s); + checkNext("0 10 * * * ?", + sys_days(2012_y / 12 / 01) + 21h + 11min + 00s, + sys_days(2012_y / 12 / 01) + 22h + 10min + 00s); + checkNext("0 0 * * * ?", + sys_days(2012_y / 9 / 30) + 11h + 01min + 00s, + sys_days(2012_y / 9 / 30) + 12h + 00min + 00s); + checkNext("0 0 * * * ?", + sys_days(2012_y / 9 / 30) + 12h + 00min + 00s, + sys_days(2012_y / 9 / 30) + 13h + 00min + 00s); + checkNext("0 0 * * * ?", + sys_days(2012_y / 9 / 10) + 23h + 01min + 00s, + sys_days(2012_y / 9 / 11) + 00h + 00min + 00s); + checkNext("0 0 * * * ?", + sys_days(2012_y / 9 / 11) + 00h + 00min + 00s, + sys_days(2012_y / 9 / 11) + 01h + 00min + 00s); + checkNext("0 0 0 * * ?", + sys_days(2012_y / 9 / 01) + 14h + 42min + 43s, + sys_days(2012_y / 9 / 02) + 00h + 00min + 00s); + checkNext("0 0 0 * * ?", + sys_days(2012_y / 9 / 02) + 00h + 00min + 00s, + sys_days(2012_y / 9 / 03) + 00h + 00min + 00s); + checkNext("* * * 10 * ?", + sys_days(2012_y / 10 / 9) + 15h + 12min + 42s, + sys_days(2012_y / 10 / 10) + 00h + 00min + 00s); + checkNext("* * * 10 * ?", + sys_days(2012_y / 10 / 11) + 15h + 12min + 42s, + sys_days(2012_y / 11 / 10) + 00h + 00min + 00s); + checkNext("0 0 0 * * ? 2020", + sys_days(2012_y / 9 / 30) + 15h + 12min + 42s, + sys_days(2020_y / 01 / 01) + 00h + 00min + 00s); + checkNext("0 0 0 * * ?", + sys_days(2012_y / 9 / 30) + 15h + 12min + 42s, + sys_days(2012_y / 10 / 01) + 00h + 00min + 00s); + checkNext("0 0 0 * * ?", + sys_days(2012_y / 10 / 01) + 00h + 00min + 00s, + sys_days(2012_y / 10 / 02) + 00h + 00min + 00s); + checkNext("0 0 0 * * ?", + sys_days(2012_y / 8 / 30) + 15h + 12min + 42s, + sys_days(2012_y / 8 / 31) + 00h + 00min + 00s); + checkNext("0 0 0 * * ?", + sys_days(2012_y / 8 / 31) + 00h + 00min + 00s, + sys_days(2012_y / 9 / 01) + 00h + 00min + 00s); + checkNext("0 0 0 * * ?", + sys_days(2012_y / 10 / 30) + 15h + 12min + 42s, + sys_days(2012_y / 10 / 31) + 00h + 00min + 00s); + checkNext("0 0 0 * * ?", + sys_days(2012_y / 10 / 31) + 00h + 00min + 00s, + sys_days(2012_y / 11 / 01) + 00h + 00min + 00s); + checkNext("0 0 0 1 * ?", + sys_days(2012_y / 10 / 30) + 15h + 12min + 42s, + sys_days(2012_y / 11 / 01) + 00h + 00min + 00s); + checkNext("0 0 0 1 * ?", + sys_days(2012_y / 11 / 01) + 00h + 00min + 00s, + sys_days(2012_y / 12 / 01) + 00h + 00min + 00s); + checkNext("0 0 0 1 * ?", + sys_days(2010_y / 12 / 31) + 15h + 12min + 42s, + sys_days(2011_y / 01 / 01) + 00h + 00min + 00s); + checkNext("0 0 0 1 * ?", + sys_days(2011_y / 01 / 01) + 00h + 00min + 00s, + sys_days(2011_y / 02 / 01) + 00h + 00min + 00s); + checkNext("0 0 0 31 * ?", + sys_days(2011_y / 10 / 30) + 15h + 12min + 42s, + sys_days(2011_y / 10 / 31) + 00h + 00min + 00s); + checkNext("0 0 0 1 * ?", + sys_days(2011_y / 10 / 30) + 15h + 12min + 42s, + sys_days(2011_y / 11 / 01) + 00h + 00min + 00s); + checkNext("* * * ? * 2", + sys_days(2010_y / 10 / 25) + 15h + 12min + 42s, + sys_days(2010_y / 10 / 25) + 15h + 12min + 43s); + checkNext("* * * ? * 2", + sys_days(2010_y / 10 / 20) + 15h + 12min + 42s, + sys_days(2010_y / 10 / 25) + 00h + 00min + 00s); + checkNext("* * * ? * 2", + sys_days(2010_y / 10 / 27) + 15h + 12min + 42s, + sys_days(2010_y / 11 / 01) + 00h + 00min + 00s); + checkNext("55 5 * * * ?", + sys_days(2010_y / 10 / 27) + 15h + 04min + 54s, + sys_days(2010_y / 10 / 27) + 15h + 05min + 55s); + checkNext("55 5 * * * ?", + sys_days(2010_y / 10 / 27) + 15h + 05min + 55s, + sys_days(2010_y / 10 / 27) + 16h + 05min + 55s); + checkNext("55 * 10 * * ?", + sys_days(2010_y / 10 / 27) + 9h + 04min + 54s, + sys_days(2010_y / 10 / 27) + 10h + 00min + 55s); + checkNext("55 * 10 * * ?", + sys_days(2010_y / 10 / 27) + 10h + 00min + 55s, + sys_days(2010_y / 10 / 27) + 10h + 01min + 55s); + checkNext("* 5 10 * * ?", + sys_days(2010_y / 10 / 27) + 9h + 04min + 55s, + sys_days(2010_y / 10 / 27) + 10h + 05min + 00s); + checkNext("* 5 10 * * ?", + sys_days(2010_y / 10 / 27) + 10h + 05min + 00s, + sys_days(2010_y / 10 / 27) + 10h + 05min + 01s); + checkNext("55 * * 3 * ?", + sys_days(2010_y / 10 / 02) + 10h + 05min + 54s, + sys_days(2010_y / 10 / 03) + 00h + 00min + 55s); + checkNext("55 * * 3 * ?", + sys_days(2010_y / 10 / 03) + 00h + 00min + 55s, + sys_days(2010_y / 10 / 03) + 00h + 01min + 55s); + checkNext("* * * 3 11 ?", + sys_days(2010_y / 10 / 02) + 14h + 42min + 55s, + sys_days(2010_y / 11 / 03) + 00h + 00min + 00s); + checkNext("* * * 3 11 ?", + sys_days(2010_y / 11 / 03) + 00h + 00min + 00s, + sys_days(2010_y / 11 / 03) + 00h + 00min + 01s); + checkNext("0 0 0 29 2 ?", + sys_days(2007_y / 02 / 10) + 14h + 42min + 55s, + sys_days(2008_y / 02 / 29) + 00h + 00min + 00s); + checkNext("0 0 0 29 2 ?", + sys_days(2008_y / 02 / 29) + 00h + 00min + 00s, + sys_days(2012_y / 02 / 29) + 00h + 00min + 00s); + checkNext("0 0 7 ? * Mon-Fri", + sys_days(2009_y / 9 / 26) + 00h + 42min + 55s, + sys_days(2009_y / 9 / 28) + 07h + 00min + 00s); + checkNext("0 0 7 ? * Mon-Fri", + sys_days(2009_y / 9 / 26) + 00h + 42min + 55s, + sys_days(2009_y / 9 / 28) + 07h + 00min + 00s); + checkNext("0 0 7 ? * Mon,Tue,Wed,Thu,Fri", + sys_days(2009_y / 9 / 28) + 07h + 00min + 00s, + sys_days(2009_y / 9 / 29) + 07h + 00min + 00s); + checkNext("0 30 23 30 1/3 ?", + sys_days(2010_y / 12 / 30) + 00h + 00min + 00s, + sys_days(2011_y / 01 / 30) + 23h + 30min + 00s); + checkNext("0 30 23 30 1/3 ?", + sys_days(2011_y / 01 / 30) + 23h + 30min + 00s, + sys_days(2011_y / 04 / 30) + 23h + 30min + 00s); + checkNext("0 30 23 30 1/3 ?", + sys_days(2011_y / 04 / 30) + 23h + 30min + 00s, + sys_days(2011_y / 07 / 30) + 23h + 30min + 00s); + + checkNext("0 0 0 LW * ? *", + sys_days(2022_y / 02 / 27) + 02h + 00min + 00s, + sys_days(2022_y / 02 / 28) + 00h + 00min + 00s); + checkNext("0 0 0 LW * ? *", + sys_days(2024_y / 02 / 27) + 02h + 00min + 00s, + sys_days(2024_y / 02 / 29) + 00h + 00min + 00s); + checkNext("0 0 0 LW * ? *", + sys_days(2027_y / 02 / 27) + 02h + 00min + 00s, + sys_days(2027_y / 03 / 31) + 00h + 00min + 00s); + checkNext("0 0 0 ? * 3#1 *", + sys_days(2022_y / 05 / 04) + 00h + 00min + 00s, + sys_days(2022_y / 06 / 07) + 00h + 00min + 00s); + checkNext("0 0 0 ? * 3#2 *", + sys_days(2022_y / 05 / 04) + 00h + 00min + 00s, + sys_days(2022_y / 05 / 10) + 00h + 00min + 00s); + checkNext("0 0 0 ? * 3#3 *", + sys_days(2022_y / 05 / 04) + 00h + 00min + 00s, + sys_days(2022_y / 05 / 17) + 00h + 00min + 00s); + checkNext("0 0 0 ? * 3#4 *", + sys_days(2022_y / 05 / 04) + 00h + 00min + 00s, + sys_days(2022_y / 05 / 24) + 00h + 00min + 00s); + checkNext("0 0 0 ? * 3#5 *", + sys_days(2022_y / 05 / 04) + 00h + 00min + 00s, + sys_days(2022_y / 05 / 31) + 00h + 00min + 00s); + checkNext("0 0 0 L * ? *", + sys_days(2022_y / 01 / 04) + 00h + 00min + 00s, + sys_days(2022_y / 01 / 31) + 00h + 00min + 00s); + checkNext("0 0 0 L * ? *", + sys_days(2022_y / 02 / 04) + 00h + 00min + 00s, + sys_days(2022_y / 02 / 28) + 00h + 00min + 00s); + checkNext("0 0 0 L * ? *", + sys_days(2024_y / 02 / 04) + 00h + 00min + 00s, + sys_days(2024_y / 02 / 29) + 00h + 00min + 00s); + checkNext("0 0 0 L * ? *", + sys_days(2022_y / 03 / 04) + 00h + 00min + 00s, + sys_days(2022_y / 03 / 31) + 00h + 00min + 00s); + checkNext("0 0 0 L * ? *", + sys_days(2022_y / 04 / 04) + 00h + 00min + 00s, + sys_days(2022_y / 04 / 30) + 00h + 00min + 00s); + checkNext("0 0 0 L * ? *", + sys_days(2022_y / 05 / 31) + 00h + 00min + 00s, + sys_days(2022_y / 06 / 30) + 00h + 00min + 00s); + checkNext("0 0 0 ? * L *", + sys_days(2022_y / 01 / 07) + 00h + 00min + 00s, + sys_days(2022_y / 01 / 8) + 00h + 00min + 00s); + checkNext("0 0 0 ? * L *", + sys_days(2022_y / 02 / 04) + 00h + 00min + 00s, + sys_days(2022_y / 02 / 05) + 00h + 00min + 00s); + checkNext("0 0 0 ? * L *", + sys_days(2024_y / 02 / 04) + 00h + 00min + 00s, + sys_days(2024_y / 02 / 10) + 00h + 00min + 00s); + checkNext("0 0 0 ? * L *", + sys_days(2022_y / 03 / 04) + 00h + 00min + 00s, + sys_days(2022_y / 03 / 05) + 00h + 00min + 00s); + checkNext("0 0 0 ? * L *", + sys_days(2022_y / 04 / 04) + 00h + 00min + 00s, + sys_days(2022_y / 04 / 9) + 00h + 00min + 00s); + checkNext("0 0 0 ? * L *", + sys_days(2022_y / 05 / 28) + 00h + 00min + 00s, + sys_days(2022_y / 06 / 04) + 00h + 00min + 00s); + checkNext("0 0 0 1W * ? *", + sys_days(2022_y / 05 / 01) + 00h + 00min + 00s, + sys_days(2022_y / 05 / 02) + 00h + 00min + 00s); + checkNext("0 0 0 4W * ? *", + sys_days(2022_y / 05 / 01) + 00h + 00min + 00s, + sys_days(2022_y / 05 / 04) + 00h + 00min + 00s); + checkNext("0 0 0 14W * ? *", + sys_days(2022_y / 05 / 01) + 00h + 00min + 00s, + sys_days(2022_y / 05 / 13) + 00h + 00min + 00s); + checkNext("0 0 0 15W * ? *", + sys_days(2022_y / 05 / 01) + 00h + 00min + 00s, + sys_days(2022_y / 05 / 16) + 00h + 00min + 00s); + checkNext("0 0 0 31W * ? *", + sys_days(2022_y / 02 / 01) + 00h + 00min + 00s, + sys_days(2022_y / 03 / 31) + 00h + 00min + 00s); +} Review Comment: good idea, I've added them https://github.com/apache/nifi-minifi-cpp/pull/1335/commits/1745a0dff6c4420d34b8bdbaf3f76a8d18e7fde0#diff-99182a0f9eeb09751e25ef7c3291f861bbcafcdfb35bfd7adfb666d075aff57eR368-R373, and they did fail before I added your other suggestion https://github.com/apache/nifi-minifi-cpp/pull/1335/commits/1745a0dff6c4420d34b8bdbaf3f76a8d18e7fde0#diff-977a7d8d2ef0da59036a2e53f02f087ea0b5c962d8d3bad8a5c566d3842c322dR322-R326 -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
