|
| 1 | +/* |
| 2 | + SPDX-FileCopyrightText: Lieven Hey <[email protected]> |
| 3 | + SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company, [email protected] |
| 4 | +
|
| 5 | + SPDX-License-Identifier: GPL-2.0-or-later |
| 6 | +*/ |
| 7 | + |
| 8 | +#include <QTest> |
| 9 | + |
| 10 | +#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) |
| 11 | +#include <QHashSeed> |
| 12 | +#endif // QT_VERSION < QT_VERSION_CHECK(6, 2, 0) |
| 13 | + |
| 14 | +#include <tracepointformat.h> |
| 15 | + |
| 16 | +class TestTracepointFormat : public QObject |
| 17 | +{ |
| 18 | + Q_OBJECT |
| 19 | +private slots: |
| 20 | + void initTestCase() |
| 21 | + { |
| 22 | +#if QT_VERSION < QT_VERSION_CHECK(6, 2, 0) |
| 23 | + qSetGlobalQHashSeed(0); |
| 24 | +#else |
| 25 | + QHashSeed::setDeterministicGlobalSeed(); |
| 26 | +#endif // QT_VERSION < QT_VERSION_CHECK(6, 2, 0) |
| 27 | + } |
| 28 | + |
| 29 | + void testFormatString() |
| 30 | + { |
| 31 | + // taken from /sys/kernel/tracing/events/syscalls/sys_enter_openat/format |
| 32 | + auto format = QStringLiteral( |
| 33 | + "\"dfd: 0x%08lx, filename: 0x%08lx, flags: 0x%08lx, mode: 0x%08lx\", ((unsigned long)(REC->dfd)), " |
| 34 | + "((unsigned long)(REC->filename)), ((unsigned long)(REC->flags)), ((unsigned long)(REC->mode))"); |
| 35 | + |
| 36 | + TracePointFormatter formatter(format); |
| 37 | + |
| 38 | + QCOMPARE(formatter.formatString(), |
| 39 | + QStringLiteral("dfd: 0x%08lx, filename: 0x%08lx, flags: 0x%08lx, mode: 0x%08lx")); |
| 40 | + QCOMPARE(formatter.args(), |
| 41 | + (QStringList {{QStringLiteral("dfd")}, |
| 42 | + {QStringLiteral("filename")}, |
| 43 | + {QStringLiteral("flags")}, |
| 44 | + {QStringLiteral("mode")}})); |
| 45 | + } |
| 46 | + |
| 47 | + void testSyscallEnterOpenat() |
| 48 | + { |
| 49 | + Data::TracePointData tracepointData = {{QStringLiteral("filename"), QVariant(140732347873408ull)}, |
| 50 | + {QStringLiteral("dfd"), QVariant(4294967196ull)}, |
| 51 | + {QStringLiteral("__syscall_nr"), QVariant(257)}, |
| 52 | + {QStringLiteral("flags"), QVariant(0ull)}, |
| 53 | + {QStringLiteral("mode"), QVariant(0)}}; |
| 54 | + |
| 55 | + const Data::TracePointFormat format = { |
| 56 | + QStringLiteral("syscalls"), QStringLiteral("syscall_enter_openat"), 0, |
| 57 | + QStringLiteral( |
| 58 | + "\"dfd: 0x%08lx, filename: 0x%08lx, flags: 0x%08lx, mode: 0x%08lx\", ((unsigned long)(REC->dfd)), " |
| 59 | + "((unsigned long)(REC->filename)), ((unsigned long)(REC->flags)), ((unsigned long)(REC->mode))")}; |
| 60 | + |
| 61 | + TracePointFormatter formatter(format.format); |
| 62 | + } |
| 63 | + |
| 64 | + void testInvalidFormatString_data() |
| 65 | + { |
| 66 | + QTest::addColumn<QString>("format"); |
| 67 | + QTest::addRow("Too complex format") << QStringLiteral( |
| 68 | + "\"%d,%d %s (%s) %llu + %u %s,%u,%u [%d]\", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) " |
| 69 | + "((REC->dev) & ((1U << 20) - 1))), REC->rwbs, __get_str(cmd), (unsigned long long)REC->sector, " |
| 70 | + "REC->nr_sector, __print_symbolic((((REC->ioprio) >> 13) & (8 - 1)), { IOPRIO_CLASS_NONE, \"none\" }, " |
| 71 | + "{IOPRIO_CLASS_RT, \"rt\"}, {IOPRIO_CLASS_BE, \"be\"}, {IOPRIO_CLASS_IDLE, \"idle\"}, " |
| 72 | + "{IOPRIO_CLASS_INVALID, \"invalid\"}), (((REC->ioprio) >> 3) & ((1 << 10) - 1)), ((REC->ioprio) & ((1 << " |
| 73 | + "3) - 1)), REC->error "); |
| 74 | + |
| 75 | + QTest::addRow("Invalid format string") << QStringLiteral("abc123%s"); |
| 76 | + QTest::addRow("Emptry format string") << QString {}; |
| 77 | + } |
| 78 | + void testInvalidFormatString() |
| 79 | + { |
| 80 | + QFETCH(QString, format); |
| 81 | + |
| 82 | + Data::TracePointData data = {{QStringLiteral("ioprio"), QVariant(0)}, |
| 83 | + {QStringLiteral("sector"), QVariant(18446744073709551615ull)}, |
| 84 | + {QStringLiteral("nr_sector"), QVariant(0u)}, |
| 85 | + {QStringLiteral("rwbs"), QVariant(QByteArray("N\x00\x00\x00\x00\x00\x00\x00"))}, |
| 86 | + {QStringLiteral("dev"), QVariant(8388624u)}, |
| 87 | + {QStringLiteral("cmd"), QVariant(65584u)}, |
| 88 | + {QStringLiteral("error"), QVariant(-5)}}; |
| 89 | + |
| 90 | + TracePointFormatter formatter(format); |
| 91 | + QVERIFY(formatter.formatString().isEmpty()); |
| 92 | + |
| 93 | + // if the format string cannot be decoded then for formatter will just concat the tracepoint data |
| 94 | + // Qt5 and Qt6 use different hashing functions so we need two different outputs |
| 95 | +#if QT_VERSION < QT_VERSION_CHECK(6, 2, 0) |
| 96 | + auto output = QLatin1String("dev: 8388624\ncmd: 65584\nnr_sector: 0\nrwbs: 0\nioprio: 0\nerror: " |
| 97 | + "18446744073709551611\nsector: 18446744073709551615"); |
| 98 | +#else |
| 99 | + auto output = QLatin1String("cmd: 65584\nioprio: 0\nnr_sector: 0\nrwbs: 0\nsector: 18446744073709551615\ndev: " |
| 100 | + "8388624\nerror: 18446744073709551611"); |
| 101 | +#endif // QT_VERSION < QT_VERSION_CHECK(6, 2, 0) |
| 102 | + |
| 103 | + QCOMPARE(formatter.format(data), output); |
| 104 | + } |
| 105 | +}; |
| 106 | + |
| 107 | +QTEST_GUILESS_MAIN(TestTracepointFormat) |
| 108 | + |
| 109 | +#include "tst_tracepointformat.moc" |
0 commit comments