File indexing completed on 2024-12-22 05:06:07
0001 /* 0002 * Copyright (C) 2018 Christian Mollekopf <mollekopf@kolabsys.com> 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 0020 #include <QCoreApplication> 0021 #include <QDebug> 0022 #include <QObject> // tr() 0023 #include <QModelIndex> 0024 #include <QTime> 0025 0026 #include "common/resource.h" 0027 #include "common/storage.h" 0028 #include "common/resourceconfig.h" 0029 #include "common/log.h" 0030 #include "common/storage.h" 0031 #include "common/definitions.h" 0032 #include "common/store.h" 0033 #include "common/propertyparser.h" 0034 #include "common/resourceaccess.h" 0035 #include "common/commands.h" 0036 0037 #include "sinksh_utils.h" 0038 #include "state.h" 0039 #include "syntaxtree.h" 0040 0041 namespace SinkSelfTest 0042 { 0043 0044 bool selfTest(const QStringList &args_, State &state) 0045 { 0046 using namespace Sink::ApplicationDomain; 0047 auto options = SyntaxTree::parseOptions(args_); 0048 if (options.positionalArguments.contains("stresstest")) { 0049 auto resource = SinkshUtils::parseUid(options.options.value("resource").first().toUtf8()); 0050 qWarning() << "Stresstest on resource: " << resource; 0051 auto models = QSharedPointer<QList<QSharedPointer<QAbstractItemModel>>>::create(); 0052 0053 //Simulate the maillist, where we scroll down and trigger lots of fetchMore calls 0054 { 0055 Sink::Query query; 0056 query.resourceFilter(resource); 0057 query.limit(100); 0058 query.request<Mail::Subject>(); 0059 query.request<Mail::Sender>(); 0060 query.request<Mail::To>(); 0061 query.request<Mail::Cc>(); 0062 query.request<Mail::Bcc>(); 0063 query.request<Mail::Date>(); 0064 query.request<Mail::Unread>(); 0065 query.request<Mail::Important>(); 0066 query.request<Mail::Draft>(); 0067 query.request<Mail::Sent>(); 0068 query.request<Mail::Trash>(); 0069 query.request<Mail::Folder>(); 0070 query.sort<Mail::Date>(); 0071 query.reduce<Mail::ThreadId>(Sink::Query::Reduce::Selector::max<Mail::Date>()) 0072 .count("count") 0073 .collect<Mail::Unread>("unreadCollected") 0074 .collect<Mail::Important>("importantCollected"); 0075 0076 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Mail>(query); 0077 models->append(model); 0078 QObject::connect(model.data(), &QAbstractItemModel::dataChanged, [models, model, &state](const QModelIndex &start, const QModelIndex &end, const QVector<int> &roles) { 0079 if (roles.contains(Sink::Store::ChildrenFetchedRole)) { 0080 if (!model->canFetchMore({})) { 0081 qWarning() << "Model complete: " << models->count(); 0082 models->removeAll(model); 0083 } else { 0084 qWarning() << "Fetching more"; 0085 //Simulate superfluous fetchMore calls 0086 for (int i = 0; i < 10; i++) { 0087 model->fetchMore({}); 0088 } 0089 return; 0090 } 0091 if (models->isEmpty()) { 0092 state.commandFinished(); 0093 } 0094 } 0095 }); 0096 0097 } 0098 0099 //Simluate lot's of mailviewers doing a bunch of queries 0100 { 0101 Sink::Query query; 0102 query.resourceFilter(resource); 0103 query.limit(10); 0104 query.request<Mail::Subject>(); 0105 query.request<Mail::Sender>(); 0106 query.request<Mail::To>(); 0107 query.request<Mail::Cc>(); 0108 query.request<Mail::Bcc>(); 0109 query.request<Mail::Date>(); 0110 query.request<Mail::Unread>(); 0111 query.request<Mail::Important>(); 0112 query.request<Mail::Draft>(); 0113 query.request<Mail::Sent>(); 0114 query.request<Mail::Trash>(); 0115 query.request<Mail::Folder>(); 0116 query.sort<Sink::ApplicationDomain::Mail::Date>(); 0117 query.bloom<Sink::ApplicationDomain::Mail::ThreadId>(); 0118 0119 for (int i = 0; i < 50; i++) { 0120 auto model = Sink::Store::loadModel<Sink::ApplicationDomain::Mail>(query); 0121 *models << model; 0122 QObject::connect(model.data(), &QAbstractItemModel::dataChanged, [models, model, &state](const QModelIndex &start, const QModelIndex &end, const QVector<int> &roles) { 0123 if (roles.contains(Sink::Store::ChildrenFetchedRole)) { 0124 models->removeAll(model); 0125 qWarning() << "Model complete: " << models->count(); 0126 if (models->isEmpty()) { 0127 state.commandFinished(); 0128 } 0129 } 0130 }); 0131 } 0132 } 0133 0134 return true; 0135 } 0136 0137 state.printLine("Looking for resource plugins:"); 0138 if (!Sink::ResourceFactory::load("sink.imap")) { 0139 state.printLine("Failure: Failed to load the imap resource", 1); 0140 } else { 0141 state.printLine("Success: Managed to load the imap resource", 1); 0142 state.printLine("Trying to start and connect to a resource.", 1); 0143 auto resourceAccess = Sink::ResourceAccessFactory::instance().getAccess("imap.selftest.resource", "sink.imap"); 0144 resourceAccess->open(); 0145 resourceAccess->sendCommand(Sink::Commands::PingCommand).addToContext(resourceAccess).then([&](const KAsync::Error &error) { 0146 if (error) { 0147 state.printLine("Failure: Failed to start/connect to the resource.", 1); 0148 } else { 0149 state.printLine("Success: Managed to start and connect to the resource.", 1); 0150 } 0151 }).exec().waitForFinished(); 0152 } 0153 0154 return false; 0155 } 0156 0157 Syntax::List syntax() 0158 { 0159 Syntax syntax("selftest", QObject::tr("A selftest module."), &SinkSelfTest::selfTest, Syntax::EventDriven); 0160 return Syntax::List() << syntax; 0161 } 0162 0163 REGISTER_SYNTAX(SinkSelfTest) 0164 0165 }