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"