/* * SPDX-License-Identifier: GPL-3.0-or-later * SPDX-FileCopyrightText: 2020-2021 Johan Ouwerkerk */ #include "oath/oath.h" #include #include #include class TimeStepCountConversionTest : public QObject // clazy:exclude=ctor-missing-parent-argument { Q_OBJECT private Q_SLOTS: void invalidCount(void); void invalidCount_data(void); void validCount(void); void validCount_data(void); }; static void define_valid_test_case(const QDateTime &epoch, uint timeStep, quint64 count, const QDateTime &expected) { static const QString testCase(QStringLiteral("%1 + %2 * 1000 * %3 ... %4")); QTest::newRow(qPrintable(testCase.arg(epoch.toMSecsSinceEpoch()).arg(timeStep).arg(count).arg(expected.toMSecsSinceEpoch()))) << epoch << timeStep << count << expected; } static void define_invalid_test_case(const QDateTime &epoch, uint timeStep, quint64 count) { static const QString testCase(QStringLiteral("%1 + %2 * 1000 * %3")); QTest::newRow(qPrintable(testCase.arg(epoch.toMSecsSinceEpoch()).arg(timeStep).arg(count))) << epoch << timeStep << count; } void TimeStepCountConversionTest::validCount(void) { QFETCH(QDateTime, epoch); QFETCH(uint, timeStep); QFETCH(quint64, count); auto result = oath::fromCounter(count, epoch, timeStep); QVERIFY2(result, "should be able to determine the datetime associated with the counter"); QTEST(*result, "expected"); } void TimeStepCountConversionTest::validCount_data(void) { QTest::addColumn("epoch"); QTest::addColumn("timeStep"); QTest::addColumn("count"); QTest::addColumn("expected"); const qint64 min = std::numeric_limits::min(); const qint64 s2038 = std::numeric_limits::max(); // few basic cases define_valid_test_case(QDateTime::fromMSecsSinceEpoch(0LL), 30UL, 0ULL, QDateTime::fromMSecsSinceEpoch(0LL)); define_valid_test_case(QDateTime::fromMSecsSinceEpoch(0LL), 30UL, 1ULL, QDateTime::fromMSecsSinceEpoch(30'000LL)); define_valid_test_case(QDateTime::fromMSecsSinceEpoch(-30'000LL), 30UL, 1ULL, QDateTime::fromMSecsSinceEpoch(0LL)); // checking max 'classic' 32bit unix time for counting utc seconds define_valid_test_case(QDateTime::fromMSecsSinceEpoch(0LL), 30UL, s2038 / 30LL, QDateTime::fromMSecsSinceEpoch(30'000LL * (s2038 / 30LL))); define_valid_test_case(QDateTime::fromMSecsSinceEpoch(0LL), 1UL, s2038, QDateTime::fromMSecsSinceEpoch(1'000LL * s2038)); // finding the actual upper limit(s) which QDateTime can cope with define_valid_test_case(QDateTime::fromMSecsSinceEpoch(0LL), 1ULL, 0x7fffffffff921fd8ULL / 1000ULL, QDateTime::fromMSecsSinceEpoch(0x7fffffffff921fd8LL)); define_valid_test_case(QDateTime::fromMSecsSinceEpoch(808LL), 1ULL, 0x7fffffffff921fd8ULL / 1000ULL - 1ULL, QDateTime::fromMSecsSinceEpoch(0x7fffffffff921fd8LL - 192LL)); define_valid_test_case(QDateTime::fromMSecsSinceEpoch(807LL), 1ULL, 0x7fffffffff921fd8ULL / 1000ULL, QDateTime::fromMSecsSinceEpoch(0x7fffffffff921fd8LL + 807LL)); // finding the lower limit(s) which QDateTime can cope with define_valid_test_case(QDateTime::fromMSecsSinceEpoch(min), 1UL, 0ULL, QDateTime::fromMSecsSinceEpoch(min)); } void TimeStepCountConversionTest::invalidCount(void) { QFETCH(QDateTime, epoch); QFETCH(uint, timeStep); QFETCH(quint64, count); QVERIFY2(!oath::fromCounter(count, epoch, timeStep), "should not be able to associate a datetime with the counter"); } void TimeStepCountConversionTest::invalidCount_data(void) { QTest::addColumn("epoch"); QTest::addColumn("timeStep"); QTest::addColumn("count"); const quint64 max = std::numeric_limits::max(); define_invalid_test_case(QDateTime::fromMSecsSinceEpoch(0LL), 1UL, max / 2); define_invalid_test_case(QDateTime::fromMSecsSinceEpoch(0LL), 1UL, max); define_invalid_test_case(QDateTime::fromMSecsSinceEpoch(std::numeric_limits::min()), 1UL, max); define_invalid_test_case(QDateTime::fromMSecsSinceEpoch(std::numeric_limits::min()), 1UL, max / 1000ULL + 1ULL); // fits within qint64 ultimately but QDateTime gets confused about it define_invalid_test_case(QDateTime::fromMSecsSinceEpoch(0LL), 1ULL, (quint64)(max / 1000LL)); define_invalid_test_case(QDateTime::fromMSecsSinceEpoch(0LL), 1ULL, (quint64)(max >> 9)); define_invalid_test_case(QDateTime::fromMSecsSinceEpoch(0LL), 1ULL, (quint64)(max >> 10) + (max >> 11L)); define_invalid_test_case(QDateTime::fromMSecsSinceEpoch(808LL), 1ULL, 0x7fffffffffffffffULL / 1000ULL); } QTEST_APPLESS_MAIN(TimeStepCountConversionTest) #include "convert-timestep-counter.moc"