File indexing completed on 2024-04-28 05:50:04
0001 /* 0002 * SPDX-License-Identifier: GPL-3.0-or-later 0003 * SPDX-FileCopyrightText: 2020 Johan Ouwerkerk <jm.ouwerkerk@gmail.com> 0004 */ 0005 #include "oath/oath.h" 0006 0007 #include <QTest> 0008 #include <QtDebug> 0009 0010 class TimeStepCounterTest: public QObject 0011 { 0012 Q_OBJECT 0013 private Q_SLOTS: 0014 void invalidCount(void); 0015 void invalidCount_data(void); 0016 void validCount(void); 0017 void validCount_data(void); 0018 void rfcTestVector(void); 0019 void rfcTestVector_data(void); 0020 }; 0021 0022 static void define_valid_test_case(const QDateTime &epoch, qint64 now, uint timeStep, quint64 expected) 0023 { 0024 static const QString testCase(QLatin1String("%2 - %1 (%3) ... %4")); 0025 QTest::newRow(qPrintable(testCase.arg(epoch.toMSecsSinceEpoch()).arg(now).arg(timeStep).arg(expected))) << epoch << now << timeStep << expected; 0026 } 0027 0028 static void define_invalid_test_case(const QDateTime &epoch, qint64 now, uint timeStep) 0029 { 0030 static const QString testCase(QLatin1String("%2 - %1 (%3)")); 0031 QTest::newRow(qPrintable(testCase.arg(epoch.toMSecsSinceEpoch()).arg(now).arg(timeStep))) << epoch << now << timeStep; 0032 } 0033 0034 void TimeStepCounterTest::validCount(void) 0035 { 0036 QFETCH(QDateTime, epoch); 0037 QFETCH(qint64, now); 0038 QFETCH(uint, timeStep); 0039 QFETCH(quint64, expected); 0040 const std::function<qint64(void)> clock([now](void) -> qint64 0041 { 0042 return now; 0043 }); 0044 QCOMPARE(oath::count(epoch, timeStep, clock), std::optional<quint64>(expected)); 0045 } 0046 0047 void TimeStepCounterTest::validCount_data(void) 0048 { 0049 QTest::addColumn<QDateTime>("epoch"); 0050 QTest::addColumn<qint64>("now"); 0051 QTest::addColumn<uint>("timeStep"); 0052 QTest::addColumn<quint64>("expected"); 0053 0054 define_valid_test_case(QDateTime::fromMSecsSinceEpoch(0LL), 1500LL, 30UL, 0ULL); 0055 define_valid_test_case(QDateTime::fromMSecsSinceEpoch(0LL), 1500LL, 1UL, 1ULL); 0056 define_valid_test_case(QDateTime::fromMSecsSinceEpoch(0LL), 30500LL, 30UL, 1ULL); 0057 } 0058 0059 void TimeStepCounterTest::invalidCount(void) 0060 { 0061 QFETCH(QDateTime, epoch); 0062 QFETCH(qint64, now); 0063 QFETCH(uint, timeStep); 0064 const std::function<qint64(void)> clock([now](void) -> qint64 0065 { 0066 return now; 0067 }); 0068 QVERIFY2(!oath::count(epoch, timeStep, clock), "counting timesteps should fail (invalid inputs)"); 0069 } 0070 0071 void TimeStepCounterTest::invalidCount_data(void) 0072 { 0073 QTest::addColumn<QDateTime>("epoch"); 0074 QTest::addColumn<qint64>("now"); 0075 QTest::addColumn<uint>("timeStep"); 0076 QTest::addColumn<quint64>("expected"); 0077 0078 define_invalid_test_case(QDateTime::fromMSecsSinceEpoch(1500LL), 0LL, 30UL); 0079 define_invalid_test_case(QDateTime::fromMSecsSinceEpoch(0LL), 1500LL, 0UL); 0080 } 0081 0082 static void define_rfc_test_case(const QString &datetime, quint64 expected) 0083 { 0084 static QString testCase(QLatin1String("%1 ... 0x%2")); 0085 const QDateTime dt = QDateTime::fromString(datetime, Qt::ISODate); 0086 QTest::newRow(qPrintable(testCase.arg(datetime).arg(expected, 8, 16, QLatin1Char('0')))) << dt << expected; 0087 } 0088 0089 /* 0090 * (Static) test vector params obtained from RFC-6238 0091 * https://tools.ietf.org/html/rfc6238#page-9 0092 */ 0093 0094 void TimeStepCounterTest::rfcTestVector(void) 0095 { 0096 QFETCH(QDateTime, now); 0097 const QDateTime epoch = QDateTime::fromMSecsSinceEpoch(0); 0098 const uint timeStep = 30U; 0099 0100 std::optional<quint64> counter = oath::count(epoch, timeStep, [now](void) -> qint64 0101 { 0102 return now.toMSecsSinceEpoch(); 0103 }); 0104 0105 QVERIFY2(counter, "should be able to count timesteps using the settings of the RFC test vector"); 0106 QTEST(*counter, "rfc-test-vector"); 0107 } 0108 0109 void TimeStepCounterTest::rfcTestVector_data(void) 0110 { 0111 QTest::addColumn<QDateTime>("now"); 0112 QTest::addColumn<quint64>("rfc-test-vector"); 0113 0114 define_rfc_test_case(QStringLiteral("1970-01-01 00:00:59Z"), 0x1ULL); 0115 define_rfc_test_case(QStringLiteral("2005-03-18 01:58:29Z"), 0x23523ECULL); 0116 define_rfc_test_case(QStringLiteral("2005-03-18 01:58:31Z"), 0x23523EDULL); 0117 define_rfc_test_case(QStringLiteral("2009-02-13 23:31:30Z"), 0x273EF07ULL); 0118 define_rfc_test_case(QStringLiteral("2033-05-18 03:33:20Z"), 0x3F940AAULL); 0119 define_rfc_test_case(QStringLiteral("2603-10-11 11:33:20Z"), 0x27BC86AAULL); 0120 } 0121 0122 QTEST_APPLESS_MAIN(TimeStepCounterTest) 0123 0124 #include "count-timesteps.moc"