/* * SPDX-License-Identifier: GPL-3.0-or-later * SPDX-FileCopyrightText: 2020 Johan Ouwerkerk */ #include "oath/oath.h" #include #include class TimeStepCounterTest: public QObject { Q_OBJECT private Q_SLOTS: void invalidCount(void); void invalidCount_data(void); void validCount(void); void validCount_data(void); void rfcTestVector(void); void rfcTestVector_data(void); }; static void define_valid_test_case(const QDateTime &epoch, qint64 now, uint timeStep, quint64 expected) { static const QString testCase(QLatin1String("%2 - %1 (%3) ... %4")); QTest::newRow(qPrintable(testCase.arg(epoch.toMSecsSinceEpoch()).arg(now).arg(timeStep).arg(expected))) << epoch << now << timeStep << expected; } static void define_invalid_test_case(const QDateTime &epoch, qint64 now, uint timeStep) { static const QString testCase(QLatin1String("%2 - %1 (%3)")); QTest::newRow(qPrintable(testCase.arg(epoch.toMSecsSinceEpoch()).arg(now).arg(timeStep))) << epoch << now << timeStep; } void TimeStepCounterTest::validCount(void) { QFETCH(QDateTime, epoch); QFETCH(qint64, now); QFETCH(uint, timeStep); QFETCH(quint64, expected); const std::function clock([now](void) -> qint64 { return now; }); QCOMPARE(oath::count(epoch, timeStep, clock), std::optional(expected)); } void TimeStepCounterTest::validCount_data(void) { QTest::addColumn("epoch"); QTest::addColumn("now"); QTest::addColumn("timeStep"); QTest::addColumn("expected"); define_valid_test_case(QDateTime::fromMSecsSinceEpoch(0LL), 1500LL, 30UL, 0ULL); define_valid_test_case(QDateTime::fromMSecsSinceEpoch(0LL), 1500LL, 1UL, 1ULL); define_valid_test_case(QDateTime::fromMSecsSinceEpoch(0LL), 30500LL, 30UL, 1ULL); } void TimeStepCounterTest::invalidCount(void) { QFETCH(QDateTime, epoch); QFETCH(qint64, now); QFETCH(uint, timeStep); const std::function clock([now](void) -> qint64 { return now; }); QVERIFY2(!oath::count(epoch, timeStep, clock), "counting timesteps should fail (invalid inputs)"); } void TimeStepCounterTest::invalidCount_data(void) { QTest::addColumn("epoch"); QTest::addColumn("now"); QTest::addColumn("timeStep"); QTest::addColumn("expected"); define_invalid_test_case(QDateTime::fromMSecsSinceEpoch(1500LL), 0LL, 30UL); define_invalid_test_case(QDateTime::fromMSecsSinceEpoch(0LL), 1500LL, 0UL); } static void define_rfc_test_case(const char *datetime, quint64 expected) { static QString testCase(QLatin1String("%1 ... 0x%2")); const QDateTime dt = QDateTime::fromString(datetime, Qt::ISODate); QTest::newRow(qPrintable(testCase.arg(datetime).arg(expected, 8, 16, QLatin1Char('0')))) << dt << expected; } /* * (Static) test vector params obtained from RFC-6238 * https://tools.ietf.org/html/rfc6238#page-9 */ void TimeStepCounterTest::rfcTestVector(void) { QFETCH(QDateTime, now); const QDateTime epoch = QDateTime::fromMSecsSinceEpoch(0); const uint timeStep = 30U; std::optional counter = oath::count(epoch, timeStep, [now](void) -> qint64 { return now.toMSecsSinceEpoch(); }); QVERIFY2(counter, "should be able to count timesteps using the settings of the RFC test vector"); QTEST(*counter, "rfc-test-vector"); } void TimeStepCounterTest::rfcTestVector_data(void) { QTest::addColumn("now"); QTest::addColumn("rfc-test-vector"); define_rfc_test_case("1970-01-01 00:00:59Z", 0x1ULL); define_rfc_test_case("2005-03-18 01:58:29Z", 0x23523ECULL); define_rfc_test_case("2005-03-18 01:58:31Z", 0x23523EDULL); define_rfc_test_case("2009-02-13 23:31:30Z", 0x273EF07ULL); define_rfc_test_case("2033-05-18 03:33:20Z", 0x3F940AAULL); define_rfc_test_case("2603-10-11 11:33:20Z", 0x27BC86AAULL); } QTEST_APPLESS_MAIN(TimeStepCounterTest) #include "count-timesteps.moc"