File indexing completed on 2025-01-05 04:58:37
0001 /* 0002 * Copyright (C) 2016 Christian Mollekopf <chrigi_1@fastmail.fm> 0003 * 0004 * This program is free software; you can redistribute it and/or modify 0005 * it under the terms of the GNU General Public License as published by 0006 * the Free Software Foundation; either version 2 of the License, or 0007 * (at your option) any later version. 0008 * 0009 * This program is distributed in the hope that it will be useful, 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0012 * GNU General Public License for more details. 0013 * 0014 * You should have received a copy of the GNU General Public License 0015 * along with this program; if not, write to the 0016 * Free Software Foundation, Inc., 0017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 0018 */ 0019 #include <QTest> 0020 #include <QTcpSocket> 0021 0022 #include "../imapresource.h" 0023 #include "../imapserverproxy.h" 0024 0025 #include "common/test.h" 0026 #include "common/domain/applicationdomaintype.h" 0027 #include "common/store.h" 0028 #include "common/resourcecontrol.h" 0029 #include "common/secretstore.h" 0030 #include "common/commands.h" 0031 #include "common/notification.h" 0032 0033 #include <tests/hawd/dataset.h> 0034 #include <tests/hawd/formatter.h> 0035 0036 using namespace Sink; 0037 using namespace Sink::ApplicationDomain; 0038 0039 /** 0040 * Test if the system remains somewhat responsive under load. 0041 */ 0042 class ImapMailSyncResponsivenessTest : public QObject 0043 { 0044 Q_OBJECT 0045 0046 bool isBackendAvailable() 0047 { 0048 QTcpSocket socket; 0049 socket.connectToHost("localhost", 143); 0050 return socket.waitForConnected(200); 0051 } 0052 0053 void resetTestEnvironment() 0054 { 0055 system("populatemailbox.sh"); 0056 } 0057 0058 Sink::ApplicationDomain::SinkResource createResource() 0059 { 0060 auto resource = ApplicationDomain::ImapResource::create("account1"); 0061 resource.setProperty("server", "localhost"); 0062 resource.setProperty("port", 143); 0063 resource.setProperty("username", "doe"); 0064 Sink::SecretStore::instance().insert(resource.identifier(), "doe"); 0065 return resource; 0066 } 0067 0068 void removeResourceFromDisk(const QByteArray &identifier) 0069 { 0070 ::ImapResource::removeFromDisk(identifier); 0071 } 0072 0073 QByteArray mResourceInstanceIdentifier; 0074 0075 private slots: 0076 0077 void initTestCase() 0078 { 0079 Test::initTest(); 0080 QVERIFY(isBackendAvailable()); 0081 resetTestEnvironment(); 0082 auto resource = createResource(); 0083 QVERIFY(!resource.identifier().isEmpty()); 0084 0085 VERIFYEXEC(Store::create(resource)); 0086 0087 mResourceInstanceIdentifier = resource.identifier(); 0088 } 0089 0090 void cleanup() 0091 { 0092 VERIFYEXEC(ResourceControl::shutdown(mResourceInstanceIdentifier)); 0093 removeResourceFromDisk(mResourceInstanceIdentifier); 0094 } 0095 0096 void init() 0097 { 0098 VERIFYEXEC(ResourceControl::start(mResourceInstanceIdentifier)); 0099 } 0100 0101 void testResponsivenessDuringSync() 0102 { 0103 Sink::Query query; 0104 query.resourceFilter(mResourceInstanceIdentifier); 0105 0106 QTime time; 0107 time.start(); 0108 0109 // Trigger the sync 0110 Store::synchronize(query).exec(); 0111 0112 //Repeatedly ping the resource and check if a response arrives within an acceptable timeframe 0113 //We could improve this check by actually modifying something (it should get priority over the sync) 0114 Sink::ResourceAccess resourceAccess(mResourceInstanceIdentifier, ""); 0115 resourceAccess.open(); 0116 0117 auto flush = ResourceControl::flushMessageQueue(mResourceInstanceIdentifier).exec(); 0118 0119 const int roundtripSoftLimit = 500; 0120 const int roundtripHardLimit = 2000; 0121 0122 QTime pingTime; 0123 for (int i = 0; i < 500; i++) { 0124 pingTime.start(); 0125 VERIFYEXEC(resourceAccess.sendCommand(Sink::Commands::PingCommand)); 0126 SinkWarning() << "Ping took: " << Sink::Log::TraceTime(pingTime.elapsed()); 0127 if (pingTime.elapsed() > roundtripSoftLimit) { 0128 if (pingTime.elapsed() > roundtripHardLimit) { 0129 SinkError() << "Ping took: " << Sink::Log::TraceTime(pingTime.elapsed()); 0130 QVERIFY(false); 0131 } else { 0132 SinkWarning() << "Ping took: " << Sink::Log::TraceTime(pingTime.elapsed()); 0133 } 0134 } 0135 //Until the sync is complete 0136 if (flush.isFinished()) { 0137 break; 0138 } 0139 QTest::qWait(500); 0140 } 0141 0142 auto total = time.elapsed(); 0143 SinkLog() << "Total took: " << Sink::Log::TraceTime(total); 0144 } 0145 }; 0146 0147 QTEST_MAIN(ImapMailSyncResponsivenessTest) 0148 0149 #include "imapmailsyncresponsivenesstest.moc"