File indexing completed on 2024-11-10 04:40:16

0001 /*
0002     SPDX-FileCopyrightText: 2020 Daniel Vrátil <dvratil@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "compressionstream_p.h"
0008 
0009 #include <QBuffer>
0010 #include <QObject>
0011 #include <QRandomGenerator>
0012 #include <QTest>
0013 
0014 #include <array>
0015 
0016 using namespace Akonadi;
0017 
0018 class CompressionStreamTest : public QObject
0019 {
0020     Q_OBJECT
0021 
0022 private Q_SLOTS:
0023     void testCompression_data()
0024     {
0025         QTest::addColumn<QByteArray>("testData");
0026 
0027         QTest::newRow("Null") << QByteArray{};
0028         QTest::newRow("Empty") << QByteArray("");
0029         QTest::newRow("Hello world") << QByteArray("Hello world");
0030     }
0031 
0032     void testCompression()
0033     {
0034         QFETCH(QByteArray, testData);
0035 
0036         QByteArray compressedData;
0037         QBuffer compressedBuffer(&compressedData);
0038         compressedBuffer.open(QIODevice::WriteOnly);
0039 
0040         {
0041             CompressionStream stream(&compressedBuffer);
0042             QVERIFY(stream.open(QIODevice::WriteOnly));
0043             QCOMPARE(stream.write(testData), testData.size());
0044             stream.close();
0045             QVERIFY(!stream.error());
0046         }
0047 
0048         compressedBuffer.close();
0049         compressedBuffer.open(QIODevice::ReadOnly);
0050         QByteArray decompressedData;
0051 
0052         {
0053             CompressionStream stream(&compressedBuffer);
0054             QVERIFY(stream.open(QIODevice::ReadOnly));
0055             decompressedData = stream.readAll();
0056             stream.close();
0057             QVERIFY(!stream.error());
0058         }
0059 
0060         QCOMPARE(decompressedData.size(), testData.size());
0061         QCOMPARE(decompressedData, testData);
0062     }
0063 
0064     void testUnbufferedCompressionOfLargeText()
0065     {
0066         std::array<std::string, 101> loremIpsum = {
0067             "Lorem",        "ipsum",      "dolor",     "sit",      "amet,",       "consectetur", "adipiscing", "elit.",       "Integer",   "dictum",
0068             "massa",        "orci,",      "eget",      "tempor",   "neque",       "euismod",     "a.",         "Suspendisse", "mi",        "arcu,",
0069             "facilisis",    "eu",         "risus",     "at,",      "varius",      "vehicula",    "mi.",        "Proin",       "tristique", "eros",
0070             "nisl,",        "vel",        "porttitor", "erat",     "elementum",   "at.",         "Quisque",    "et",          "ex",        "id",
0071             "risus",        "hendrerit",  "rhoncus",   "eu",       "vel",         "enim.",       "Vivamus",    "at",          "lorem",     "laoreet",
0072             "ex",           "mattis",     "feugiat",   "vitae",    "sit",         "amet",        "sem.",       "Vestibulum",  "in",        "ante",
0073             "sagittis,",    "venenatis",  "nibh",      "et,",      "consectetur", "est.",        "Donec",      "cursus",      "enim",      "ac",
0074             "pellentesque", "euismod.",   "Nullam",    "interdum", "metus",       "sed",         "blandit",    "dapibus.",    "Ut",        "nec",
0075             "euismod",      "magna.",     "Aenean",    "gravida",  "elit",        "metus,",      "eget",       "vehicula",    "nibh",      "euismod",
0076             "ut.",          "Vestibulum", "risus",     "lectus,",  "molestie",    "elementum",   "lobortis",   "at,",         "finibus",   "a",
0077             "quam."};
0078 
0079         QByteArray testData;
0080         QRandomGenerator *generator = QRandomGenerator::system();
0081         while (testData.size() < 10 * 1024) {
0082             testData += QByteArray(" ") + loremIpsum[generator->bounded(100)].c_str();
0083         }
0084 
0085         QByteArray compressedData;
0086         QBuffer compressedBuffer(&compressedData);
0087         compressedBuffer.open(QIODevice::WriteOnly);
0088 
0089         {
0090             CompressionStream stream(&compressedBuffer);
0091             QVERIFY(stream.open(QIODevice::WriteOnly | QIODevice::Unbuffered));
0092             qint64 written = 0;
0093             for (int i = 0; i < testData.size(); ++i) {
0094                 written += stream.write(testData.constData() + i, 1);
0095             }
0096             QCOMPARE(written, testData.size());
0097             stream.close();
0098             QVERIFY(!stream.error());
0099         }
0100 
0101         compressedBuffer.close();
0102         compressedBuffer.open(QIODevice::ReadOnly);
0103 
0104         QByteArray decompressedData;
0105         {
0106             CompressionStream stream(&compressedBuffer);
0107             QVERIFY(stream.open(QIODevice::ReadOnly | QIODevice::Unbuffered));
0108             while (!stream.atEnd()) {
0109                 char buf[3] = {};
0110                 const auto read = stream.read(buf, sizeof(buf));
0111                 decompressedData.append(buf, read);
0112             }
0113             stream.close();
0114             QVERIFY(!stream.error());
0115         }
0116 
0117         QCOMPARE(decompressedData.size(), testData.size());
0118         QCOMPARE(decompressedData, testData);
0119     }
0120 
0121     void testDetection_data()
0122     {
0123         QTest::addColumn<QList<uint8_t>>("data");
0124         QTest::addColumn<bool>("isValid");
0125 
0126         QTest::newRow("Too short - random") << QList<uint8_t>{0x65, 0x66} << false;
0127         QTest::newRow("Too short - valid start") << QList<uint8_t>{0xfd, 0x37, 0x7a, 0x58, 0x5a} << false;
0128         QTest::newRow("Valid magic only") << QList<uint8_t>{0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00} << true;
0129         QTest::newRow("Valid input") << QList<uint8_t>{0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00, 0x00, 0x04, 0xe6, 0xd6, 0xb4, 0x46, 0x02, 0x00, 0x21,
0130                                                        0x01, 0x16, 0x00, 0x00, 0x00, 0x74, 0x2f, 0xe5, 0xa3, 0x01, 0x00, 0x01, 0x41, 0x0a, 0x00,
0131                                                        0x00, 0x00, 0x8f, 0xe8, 0x69, 0xe6, 0x2b, 0x6a, 0xcd, 0x94, 0x00, 0x01, 0x1a, 0x02, 0xdc,
0132                                                        0x2e, 0xa5, 0x7e, 0x1f, 0xb6, 0xf3, 0x7d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x59, 0x5a}
0133                                      << true;
0134     }
0135 
0136     void testDetection()
0137     {
0138         QFETCH(QList<uint8_t>, data);
0139         QFETCH(bool, isValid);
0140 
0141         QByteArray ba(reinterpret_cast<const char *>(data.constData()), data.size());
0142         QBuffer buffer(&ba);
0143         QVERIFY(buffer.open(QIODevice::ReadOnly));
0144 
0145         QCOMPARE(CompressionStream::isCompressed(&buffer), isValid);
0146         QCOMPARE(buffer.pos(), 0);
0147     }
0148 };
0149 
0150 QTEST_GUILESS_MAIN(CompressionStreamTest)
0151 
0152 #include "compressionstreamtest.moc"