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"