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"