File indexing completed on 2024-05-12 05:17:26

0001 /*
0002 
0003    This program is free software; you can redistribute it and/or
0004    modify it under the terms of the GNU General Public
0005    License as published by the Free Software Foundation; either
0006    version 2 of the License, or (at your option) any later version.
0007 
0008    This program is distributed in the hope that it will be useful,
0009    but WITHOUT ANY WARRANTY; without even the implied warranty of
0010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0011    General Public License for more details.
0012 
0013    You should have received a copy of the GNU General Public License
0014    along with this program; if not, write to the Free Software
0015    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
0016 */
0017 
0018 #include <qtest.h>
0019 
0020 #include "kimap2test/fakeserver.h"
0021 #include "kimap2/session.h"
0022 #include "kimap2/fetchjob.h"
0023 #include "imapstreamparser.h"
0024 
0025 #include <QtTest>
0026 
0027 Q_DECLARE_METATYPE(KIMAP2::FetchJob::FetchScope)
0028 
0029 using namespace KIMAP2;
0030 
0031 class Benchmark: public QObject
0032 {
0033     Q_OBJECT
0034 
0035 private:
0036     QStringList m_signals;
0037 
0038     QMap<qint64, qint64> m_uids;
0039     QMap<qint64, qint64> m_sizes;
0040     QMap<qint64, KIMAP2::MessageFlags> m_flags;
0041     QMap<qint64, KIMAP2::MessagePtr> m_messages;
0042     QMap<qint64, KIMAP2::MessageAttributes> m_attrs;
0043 
0044 public Q_SLOTS:
0045     void onResultReceived(const FetchJob::Result &result)
0046     {
0047         m_signals << QStringLiteral("headersReceived");
0048         m_uids.insert(result.sequenceNumber, result.uid);
0049         m_sizes.insert(result.sequenceNumber, result.size);
0050         m_flags.insert(result.sequenceNumber, result.flags);
0051         m_messages.insert(result.sequenceNumber, result.message);
0052         if (!result.attributes.isEmpty()) {
0053             m_attrs.insert(result.sequenceNumber, result.attributes);
0054         }
0055     }
0056 
0057     void onMessagesReceived(const QString &/*mailbox*/,
0058                             const QMap<qint64, qint64> uids,
0059                             const QMap<qint64, KIMAP2::MessageAttribute> &/*attrs*/,
0060                             const QMap<qint64, KIMAP2::MessagePtr> &messages)
0061     {
0062         m_signals << QStringLiteral("messagesReceived");
0063         m_uids.unite(uids);
0064         m_messages.unite(messages);
0065     }
0066 
0067 private Q_SLOTS:
0068 
0069     void testFetchParseOnly()
0070     {
0071         int count = 5000;
0072         int parsedBytes = 0;
0073         QByteArray data;
0074         for (int i = 1; i <= count; i++) {
0075             data += QString("* %1 FETCH (UID %2 FLAGS (\\Seen) BODY[HEADER.FIELDS (TO FROM MESSAGE-ID REFERENCES IN-REPLY-TO SUBJECT DATE)] {154}\r\nFrom: Joe Smith <smith@example.com>\r\nDate: Wed, 2 Mar 2011 11:33:24 +0700\r\nMessage-ID: <1234@example.com>\r\nSubject: hello\r\nTo: Jane <jane@example.com>\r\n\r\n BODY[1.1.1] {28}\r\nHi Jane, nice to meet you!\r\n BODY[1.1.1.MIME] {48}\r\nContent-Type: text/plain; charset=ISO-8859-1\r\n\r\n)\r\n").arg(i).arg(i).toLatin1();
0076         };
0077         data += "A000001 OK fetch done\r\n";
0078         parsedBytes = data.size();
0079 
0080         QBuffer buffer(&data);
0081         buffer.open(QIODevice::ReadOnly);
0082         KIMAP2::ImapStreamParser parser(&buffer);
0083         int resultCount = 0;
0084         parser.onResponseReceived([&resultCount](const KIMAP2::Message &) {
0085             resultCount++;
0086         });
0087 
0088 
0089         QTime time;
0090         time.start();
0091 
0092         while (parser.availableDataSize()) {
0093             parser.parseStream();
0094         }
0095 
0096         qWarning() << "Reading " << count << " messages took: " << time.elapsed() << " ms.";
0097         qWarning() << parsedBytes << " bytes expected to be parsed";
0098         qWarning() << "Received " << resultCount << " results";
0099     }
0100 
0101     void testFetchParts()
0102     {
0103         int count = 5000;
0104         int parsedBytes = 0;
0105         QList<QByteArray> scenario;
0106         scenario << FakeServer::preauth();
0107         parsedBytes += scenario.last().size();
0108         scenario << "C: A000001 FETCH 1:* (BODY.PEEK[HEADER.FIELDS (TO FROM MESSAGE-ID REFERENCES IN-REPLY-TO SUBJECT DATE)] BODY.PEEK[1.1.1.MIME] BODY.PEEK[1.1.1] FLAGS UID)";
0109         for (int i = 1; i <= count; i++) {
0110             scenario << QString("S: * %1 FETCH (UID %2 FLAGS (\\Seen) BODY[HEADER.FIELDS (TO FROM MESSAGE-ID REFERENCES IN-REPLY-TO SUBJECT DATE)] {154}\r\nFrom: Joe Smith <smith@example.com>\r\nDate: Wed, 2 Mar 2011 11:33:24 +0700\r\nMessage-ID: <1234@example.com>\r\nSubject: hello\r\nTo: Jane <jane@example.com>\r\n\r\n BODY[1.1.1] {28}\r\nHi Jane, nice to meet you!\r\n BODY[1.1.1.MIME] {48}\r\nContent-Type: text/plain; charset=ISO-8859-1\r\n\r\n)\r\n").arg(i).arg(i).toLatin1();
0111             parsedBytes += scenario.last().size();
0112         };
0113         scenario << "S: A000001 OK fetch done";
0114         parsedBytes += scenario.last().size();
0115 
0116         KIMAP2::FetchJob::FetchScope scope;
0117         scope.mode = KIMAP2::FetchJob::FetchScope::HeaderAndContent;
0118         scope.parts.clear();
0119         scope.parts.append("1.1.1");
0120 
0121         FakeServer fakeServer;
0122         fakeServer.setScenario(scenario);
0123         fakeServer.startAndWait();
0124 
0125         KIMAP2::Session session(QStringLiteral("127.0.0.1"), 5989);
0126 
0127         KIMAP2::FetchJob *job = new KIMAP2::FetchJob(&session);
0128         job->setUidBased(false);
0129         job->setSequenceSet(KIMAP2::ImapSet(1, 0));
0130         job->setScope(scope);
0131 
0132         connect(job, &FetchJob::resultReceived, this, &Benchmark::onResultReceived);
0133 
0134         QTime time;
0135         time.start();
0136 
0137         bool result = job->exec();
0138 
0139         qWarning() << "Reading " << count << " messages took: " << time.elapsed() << " ms.";
0140         qWarning() << parsedBytes << " bytes expected to be parsed";
0141 
0142         QVERIFY(result);
0143         QVERIFY(m_signals.count() > 0);
0144         QCOMPARE(m_uids.count(), count);
0145         QCOMPARE(m_messages.count(), count);
0146         QCOMPARE(m_attrs.count(), 0);
0147 
0148         // Check that we received the message header
0149         QVERIFY(m_messages[1]);
0150         m_messages[1]->parse();
0151         QCOMPARE(m_messages[1]->messageID()->identifier(), QByteArray("1234@example.com"));
0152 
0153         fakeServer.quit();
0154 
0155         m_signals.clear();
0156         m_uids.clear();
0157         m_sizes.clear();
0158         m_flags.clear();
0159         m_messages.clear();
0160         m_attrs.clear();
0161     }
0162 
0163     void testFetchFlags()
0164     {
0165         int count = 5000;
0166         int parsedBytes = 0;
0167         QList<QByteArray> scenario;
0168         scenario << FakeServer::preauth();
0169         parsedBytes += scenario.last().size();
0170         scenario << "C: A000001 FETCH 1:* (FLAGS UID)";
0171         for (int i = 1; i <= count; i++) {
0172             scenario << QString("S: * %1 FETCH ( FLAGS (\\Seen) UID %2 )\r\n").arg(i).arg(i).toLatin1();
0173             parsedBytes += scenario.last().size();
0174         };
0175         scenario << "S: A000001 OK fetch done";
0176         parsedBytes += scenario.last().size();
0177 
0178         KIMAP2::FetchJob::FetchScope scope;
0179         scope.mode = KIMAP2::FetchJob::FetchScope::Flags;
0180 
0181         FakeServer fakeServer;
0182         fakeServer.setScenario(scenario);
0183         fakeServer.startAndWait();
0184 
0185         KIMAP2::Session session(QStringLiteral("127.0.0.1"), 5989);
0186 
0187         KIMAP2::FetchJob *job = new KIMAP2::FetchJob(&session);
0188         job->setUidBased(false);
0189         job->setSequenceSet(KIMAP2::ImapSet(1, 0));
0190         job->setScope(scope);
0191 
0192         connect(job, &FetchJob::resultReceived, this, &Benchmark::onResultReceived);
0193 
0194         QTime time;
0195         time.start();
0196 
0197         bool result = job->exec();
0198 
0199         qWarning() << "Reading " << count << " messages took: " << time.elapsed() << " ms.";
0200         qWarning() << parsedBytes << " bytes expected to be parsed";
0201 
0202         QVERIFY(result);
0203         QVERIFY(m_signals.count() > 0);
0204         QCOMPARE(m_uids.count(), count);
0205         QCOMPARE(m_messages.count(), count);
0206         QCOMPARE(m_attrs.count(), 0);
0207 
0208         // Check that we received the message header
0209 
0210         fakeServer.quit();
0211 
0212         m_signals.clear();
0213         m_uids.clear();
0214         m_sizes.clear();
0215         m_flags.clear();
0216         m_messages.clear();
0217         m_attrs.clear();
0218     }
0219 
0220 };
0221 
0222 QTEST_GUILESS_MAIN(Benchmark)
0223 
0224 #include "benchmark.moc"