performance/FixtureGenerator.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "performance/FixtureGenerator.h" | ||
| 2 | #include "performance/ThreadFixture.h" | ||
| 3 | |||
| 4 | #include "data/CalendarStore.h" | ||
| 5 | #include "data/ContactStore.h" | ||
| 6 | #include "performance/ContactShowcase.h" | ||
| 7 | #include "data/ContactQueries.h" | ||
| 8 | #include "data/VCardCodec.h" | ||
| 9 | #include "data/MailCache.h" | ||
| 10 | #include "ui/ThemeManager.h" | ||
| 11 | |||
| 12 | #include <QCryptographicHash> | ||
| 13 | #include <QDate> | ||
| 14 | #include <QDir> | ||
| 15 | #include <QDirIterator> | ||
| 16 | #include <QElapsedTimer> | ||
| 17 | #include <QFile> | ||
| 18 | #include <QFileInfo> | ||
| 19 | #include <QJsonArray> | ||
| 20 | #include <QJsonDocument> | ||
| 21 | #include <QSaveFile> | ||
| 22 | #include <QSqlDatabase> | ||
| 23 | #include <QSqlError> | ||
| 24 | #include <QSqlQuery> | ||
| 25 | #include <QTime> | ||
| 26 | #include <QTimeZone> | ||
| 27 | #include <QUuid> | ||
| 28 | |||
| 29 | #include <algorithm> | ||
| 30 | |||
| 31 | namespace MailJD::Performance { | ||
| 32 | |||
| 33 | namespace { | ||
| 34 | |||
| 35 | constexpr auto OwnerMarker = ".mailjd-performance-fixture-v1"; | ||
| 36 | constexpr auto AccountId = "performance-account"; | ||
| 37 | |||
| 38 | class DeterministicBytes { | ||
| 39 | public: | ||
| 40 |
2/2✓ Branch 2 → 3 taken 30 times.
✓ Branch 2 → 4 taken 1 time.
|
31 | explicit DeterministicBytes(quint64 seed) : m_state(seed ? seed : 1) {} |
| 41 | |||
| 42 | 31792268 | quint64 next() { | |
| 43 | 31792268 | m_state ^= m_state << 13; | |
| 44 | 31792268 | m_state ^= m_state >> 7; | |
| 45 | 31792268 | m_state ^= m_state << 17; | |
| 46 | 31792268 | return m_state; | |
| 47 | } | ||
| 48 | |||
| 49 | 75 | QByteArray bytes(qsizetype size) { | |
| 50 | 75 | QByteArray result(size, Qt::Uninitialized); | |
| 51 |
2/2✓ Branch 7 → 4 taken 31580160 times.
✓ Branch 7 → 8 taken 75 times.
|
31580235 | for (qsizetype i = 0; i < size; ++i) |
| 52 |
1/1✓ Branch 5 → 6 taken 31580160 times.
|
31580160 | result[i] = static_cast<char>(next() & 0xff); |
| 53 | 75 | return result; | |
| 54 | ✗ | } | |
| 55 | |||
| 56 | private: | ||
| 57 | quint64 m_state; | ||
| 58 | }; | ||
| 59 | |||
| 60 | 217 | QByteArray sha256(const QByteArray &data) { | |
| 61 |
2/2✓ Branch 3 → 4 taken 217 times.
✓ Branch 4 → 5 taken 217 times.
|
217 | return QCryptographicHash::hash(data, QCryptographicHash::Sha256).toHex(); |
| 62 | } | ||
| 63 | |||
| 64 | 903 | QByteArray fileSha256(const QString &path) { | |
| 65 |
1/1✓ Branch 2 → 3 taken 903 times.
|
903 | QFile file(path); |
| 66 |
2/3✓ Branch 4 → 5 taken 903 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 903 times.
|
903 | if (!file.open(QIODevice::ReadOnly)) |
| 67 | ✗ | return {}; | |
| 68 |
1/1✓ Branch 7 → 8 taken 903 times.
|
903 | QCryptographicHash hash(QCryptographicHash::Sha256); |
| 69 |
2/3✓ Branch 8 → 9 taken 903 times.
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 903 times.
|
903 | if (!hash.addData(&file)) |
| 70 | ✗ | return {}; | |
| 71 |
2/2✓ Branch 11 → 12 taken 903 times.
✓ Branch 12 → 13 taken 903 times.
|
903 | return hash.result().toHex(); |
| 72 | 903 | } | |
| 73 | |||
| 74 | 178 | bool writeBytes(const QString &path, const QByteArray &data, QString *error) { | |
| 75 |
1/1✓ Branch 2 → 3 taken 178 times.
|
178 | QSaveFile file(path); |
| 76 |
7/8✓ Branch 4 → 5 taken 178 times.
✓ Branch 5 → 6 taken 176 times.
✓ Branch 5 → 11 taken 2 times.
✓ Branch 6 → 7 taken 176 times.
✓ Branch 8 → 9 taken 176 times.
✗ Branch 8 → 11 not taken.
✓ Branch 13 → 14 taken 2 times.
✓ Branch 13 → 26 taken 176 times.
|
354 | if (!file.open(QIODevice::WriteOnly) || file.write(data) != data.size() || |
| 77 |
2/3✓ Branch 9 → 10 taken 176 times.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 176 times.
|
176 | !file.commit()) { |
| 78 |
2/2✓ Branch 14 → 15 taken 1 time.
✓ Branch 14 → 25 taken 1 time.
|
2 | if (error) |
| 79 |
1/1✓ Branch 19 → 20 taken 1 time.
|
2 | *error = QStringLiteral("Cannot write fixture file: %1").arg(path); |
| 80 | 2 | return false; | |
| 81 | } | ||
| 82 | 176 | return true; | |
| 83 | 178 | } | |
| 84 | |||
| 85 | 58 | bool writeJson(const QString &path, const QJsonObject &object, QString *error) { | |
| 86 |
3/3✓ Branch 2 → 3 taken 58 times.
✓ Branch 3 → 4 taken 58 times.
✓ Branch 4 → 5 taken 58 times.
|
116 | return writeBytes(path, QJsonDocument(object).toJson(QJsonDocument::Indented), |
| 87 | 116 | error); | |
| 88 | } | ||
| 89 | |||
| 90 | 29 | QByteArray minimalPdf() { | |
| 91 | const QList<QByteArray> objects = { | ||
| 92 | "<< /Type /Catalog /Pages 2 0 R >>", | ||
| 93 | "<< /Type /Pages /Kids [3 0 R] /Count 1 >>", | ||
| 94 | "<< /Type /Page /Parent 2 0 R /MediaBox [0 0 300 144] /Resources << " | ||
| 95 | "/Font << /F1 5 0 R >> >> /Contents 4 0 R >>", | ||
| 96 | "<< /Length 55 >>\nstream\nBT /F1 18 Tf 36 72 Td (Synthetic PDF fixture) " | ||
| 97 | "Tj ET\nendstream", | ||
| 98 | "<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>", | ||
| 99 |
2/4✓ Branch 9 → 10 taken 145 times.
✓ Branch 9 → 11 taken 29 times.
✗ Branch 70 → 71 not taken.
✗ Branch 70 → 72 not taken.
|
174 | }; |
| 100 |
1/1✓ Branch 11 → 12 taken 29 times.
|
29 | QByteArray pdf("%PDF-1.4\n"); |
| 101 | 29 | QList<qint64> offsets; | |
| 102 |
2/2✓ Branch 27 → 13 taken 145 times.
✓ Branch 27 → 28 taken 29 times.
|
174 | for (qsizetype i = 0; i < objects.size(); ++i) { |
| 103 |
1/1✓ Branch 14 → 15 taken 145 times.
|
145 | offsets.append(pdf.size()); |
| 104 | pdf += | ||
| 105 |
5/5✓ Branch 16 → 17 taken 145 times.
✓ Branch 17 → 18 taken 145 times.
✓ Branch 18 → 19 taken 145 times.
✓ Branch 19 → 20 taken 145 times.
✓ Branch 20 → 21 taken 145 times.
|
145 | QByteArray::number(i + 1) + " 0 obj\n" + objects.at(i) + "\nendobj\n"; |
| 106 | } | ||
| 107 | 29 | const qint64 xref = pdf.size(); | |
| 108 |
2/2✓ Branch 30 → 31 taken 29 times.
✓ Branch 31 → 32 taken 29 times.
|
58 | pdf += "xref\n0 " + QByteArray::number(objects.size() + 1) + |
| 109 |
2/2✓ Branch 32 → 33 taken 29 times.
✓ Branch 33 → 34 taken 29 times.
|
29 | "\n0000000000 65535 f \n"; |
| 110 |
4/4✓ Branch 37 → 38 taken 29 times.
✓ Branch 38 → 39 taken 29 times.
✓ Branch 50 → 40 taken 145 times.
✓ Branch 50 → 51 taken 29 times.
|
174 | for (qint64 offset : offsets) |
| 111 |
4/4✓ Branch 41 → 42 taken 145 times.
✓ Branch 42 → 43 taken 145 times.
✓ Branch 43 → 44 taken 145 times.
✓ Branch 44 → 45 taken 145 times.
|
145 | pdf += QByteArray::number(offset).rightJustified(10, '0') + " 00000 n \n"; |
| 112 |
2/2✓ Branch 53 → 54 taken 29 times.
✓ Branch 54 → 55 taken 29 times.
|
58 | pdf += "trailer\n<< /Size " + QByteArray::number(objects.size() + 1) + |
| 113 |
3/3✓ Branch 51 → 52 taken 29 times.
✓ Branch 55 → 56 taken 29 times.
✓ Branch 56 → 57 taken 29 times.
|
116 | " /Root 1 0 R >>\nstartxref\n" + QByteArray::number(xref) + |
| 114 |
2/2✓ Branch 57 → 58 taken 29 times.
✓ Branch 58 → 59 taken 29 times.
|
29 | "\n%%EOF\n"; |
| 115 | 29 | return pdf; | |
| 116 | 58 | } | |
| 117 | |||
| 118 | 76 | QString folderName(int index) { | |
| 119 |
1/1✓ Branch 7 → 8 taken 76 times.
|
76 | return QStringLiteral("Synthetic-%1").arg(index + 1, 3, 10, QLatin1Char('0')); |
| 120 | } | ||
| 121 | |||
| 122 | 36 | bool removeOwnedOutput(const QString &directory, QString *error) { | |
| 123 |
1/1✓ Branch 2 → 3 taken 36 times.
|
36 | const QDir dir(directory); |
| 124 |
3/3✓ Branch 3 → 4 taken 36 times.
✓ Branch 4 → 5 taken 21 times.
✓ Branch 4 → 6 taken 15 times.
|
36 | if (!dir.exists()) |
| 125 | 21 | return true; | |
| 126 |
5/5✓ Branch 7 → 8 taken 15 times.
✓ Branch 8 → 9 taken 15 times.
✓ Branch 9 → 10 taken 15 times.
✓ Branch 12 → 13 taken 1 time.
✓ Branch 12 → 25 taken 14 times.
|
15 | if (!QFileInfo::exists(dir.filePath(QString::fromLatin1(OwnerMarker)))) { |
| 127 |
1/2✓ Branch 13 → 14 taken 1 time.
✗ Branch 13 → 24 not taken.
|
1 | if (error) |
| 128 | *error = | ||
| 129 | 2 | QStringLiteral("Refusing to replace an unowned fixture directory: %1") | |
| 130 |
1/1✓ Branch 18 → 19 taken 1 time.
|
2 | .arg(directory); |
| 131 | 1 | return false; | |
| 132 | } | ||
| 133 | const QStringList files = { | ||
| 134 | ✗ | QStringLiteral("mail.sqlite"), | |
| 135 | 14 | QStringLiteral("mail.sqlite-wal"), | |
| 136 | 14 | QStringLiteral("mail.sqlite-shm"), | |
| 137 | 14 | QStringLiteral("calendar.sqlite"), | |
| 138 | 14 | QStringLiteral("calendar.sqlite-wal"), | |
| 139 | 14 | QStringLiteral("calendar.sqlite-shm"), | |
| 140 | 14 | QStringLiteral("contacts.sqlite"), | |
| 141 | 14 | QStringLiteral("contacts.sqlite-wal"), | |
| 142 | 14 | QStringLiteral("contacts.sqlite-shm"), | |
| 143 | 14 | QStringLiteral("workloads.json"), | |
| 144 | 14 | QStringLiteral("manifest.json"), | |
| 145 |
2/4✓ Branch 60 → 61 taken 154 times.
✓ Branch 60 → 62 taken 14 times.
✗ Branch 152 → 153 not taken.
✗ Branch 152 → 154 not taken.
|
168 | }; |
| 146 |
2/2✓ Branch 81 → 75 taken 154 times.
✓ Branch 81 → 82 taken 14 times.
|
168 | for (const QString &file : files) |
| 147 |
2/2✓ Branch 76 → 77 taken 154 times.
✓ Branch 77 → 78 taken 154 times.
|
154 | QFile::remove(dir.filePath(file)); |
| 148 | 28 | for (const QString &child : | |
| 149 |
2/2✓ Branch 123 → 92 taken 28 times.
✓ Branch 123 → 124 taken 14 times.
|
126 | {QStringLiteral("payloads"), QStringLiteral("migrations")}) { |
| 150 |
2/2✓ Branch 92 → 93 taken 28 times.
✓ Branch 93 → 94 taken 28 times.
|
28 | QDir childDir(dir.filePath(child)); |
| 151 |
6/8✓ Branch 95 → 96 taken 28 times.
✓ Branch 96 → 97 taken 20 times.
✓ Branch 96 → 100 taken 8 times.
✓ Branch 97 → 98 taken 20 times.
✗ Branch 98 → 99 not taken.
✓ Branch 98 → 100 taken 20 times.
✗ Branch 101 → 102 not taken.
✓ Branch 101 → 116 taken 28 times.
|
28 | if (childDir.exists() && !childDir.removeRecursively()) { |
| 152 | ✗ | if (error) | |
| 153 | ✗ | *error = QStringLiteral("Cannot clear generated fixture child: %1") | |
| 154 | ✗ | .arg(childDir.path()); | |
| 155 | ✗ | return false; | |
| 156 | } | ||
| 157 | 70 | } | |
| 158 | 14 | return true; | |
| 159 | 204 | } | |
| 160 | |||
| 161 | 87 | bool mutateSqlite(const QString &path, const QStringList &statements, | |
| 162 | QString *error) { | ||
| 163 | 174 | const QString connection = QStringLiteral("fixture_snapshot_") + | |
| 164 |
3/3✓ Branch 2 → 3 taken 87 times.
✓ Branch 3 → 4 taken 87 times.
✓ Branch 7 → 8 taken 87 times.
|
261 | QUuid::createUuid().toString(QUuid::WithoutBraces); |
| 165 | 87 | bool ok = true; | |
| 166 | { | ||
| 167 | QSqlDatabase db = | ||
| 168 |
1/1✓ Branch 14 → 15 taken 87 times.
|
87 | QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), connection); |
| 169 |
1/1✓ Branch 17 → 18 taken 87 times.
|
87 | db.setDatabaseName(path); |
| 170 |
2/3✓ Branch 18 → 19 taken 87 times.
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 28 taken 87 times.
|
87 | if (!db.open()) { |
| 171 | ✗ | if (error) | |
| 172 | ✗ | *error = db.lastError().text(); | |
| 173 | ✗ | ok = false; | |
| 174 | } else { | ||
| 175 |
1/1✓ Branch 28 → 29 taken 87 times.
|
87 | QSqlQuery query(db); |
| 176 |
2/2✓ Branch 51 → 31 taken 667 times.
✓ Branch 51 → 52 taken 87 times.
|
754 | for (const QString &statement : statements) { |
| 177 |
2/3✓ Branch 32 → 33 taken 667 times.
✗ Branch 33 → 34 not taken.
✓ Branch 33 → 49 taken 667 times.
|
667 | if (!query.exec(statement)) { |
| 178 | ✗ | if (error) | |
| 179 | ✗ | *error = QStringLiteral("Snapshot SQL failed: %1: %2") | |
| 180 | ✗ | .arg(statement, query.lastError().text()); | |
| 181 | ✗ | ok = false; | |
| 182 | ✗ | break; | |
| 183 | } | ||
| 184 | } | ||
| 185 |
1/1✓ Branch 52 → 53 taken 87 times.
|
87 | db.close(); |
| 186 | 87 | } | |
| 187 | 87 | } | |
| 188 |
1/1✓ Branch 56 → 57 taken 87 times.
|
87 | QSqlDatabase::removeDatabase(connection); |
| 189 | 87 | return ok; | |
| 190 | 87 | } | |
| 191 | |||
| 192 | 29 | QJsonObject artifactManifest(const QString &directory) { | |
| 193 |
1/1✓ Branch 2 → 3 taken 29 times.
|
29 | QJsonObject artifacts; |
| 194 |
3/3✓ Branch 3 → 4 taken 29 times.
✓ Branch 4 → 5 taken 29 times.
✓ Branch 5 → 6 taken 29 times.
|
29 | QDir root(QFileInfo(directory).absoluteFilePath()); |
| 195 |
1/1✓ Branch 10 → 11 taken 29 times.
|
58 | QDirIterator it(root.absolutePath(), QDir::Files, |
| 196 |
1/1✓ Branch 11 → 12 taken 29 times.
|
58 | QDirIterator::Subdirectories); |
| 197 |
3/3✓ Branch 72 → 73 taken 320 times.
✓ Branch 73 → 14 taken 291 times.
✓ Branch 73 → 74 taken 29 times.
|
320 | while (it.hasNext()) { |
| 198 |
1/1✓ Branch 14 → 15 taken 291 times.
|
291 | const QString absolute = it.next(); |
| 199 |
1/1✓ Branch 15 → 16 taken 291 times.
|
291 | const QString relative = root.relativeFilePath(absolute); |
| 200 |
4/12✓ Branch 20 → 21 taken 291 times.
✗ Branch 20 → 25 not taken.
✗ Branch 24 → 25 not taken.
✓ Branch 24 → 26 taken 291 times.
✓ Branch 31 → 32 taken 291 times.
✗ Branch 31 → 33 not taken.
✗ Branch 33 → 34 not taken.
✓ Branch 33 → 35 taken 291 times.
✗ Branch 94 → 95 not taken.
✗ Branch 94 → 96 not taken.
✗ Branch 98 → 99 not taken.
✗ Branch 98 → 100 not taken.
|
1164 | if (relative == QStringLiteral("manifest.json") || |
| 201 |
3/7✓ Branch 22 → 23 taken 291 times.
✓ Branch 27 → 28 taken 291 times.
✗ Branch 27 → 29 not taken.
✓ Branch 29 → 30 taken 291 times.
✗ Branch 29 → 31 not taken.
✗ Branch 89 → 90 not taken.
✗ Branch 89 → 91 not taken.
|
582 | relative == QString::fromLatin1(OwnerMarker)) |
| 202 | ✗ | continue; | |
| 203 |
1/1✓ Branch 35 → 36 taken 291 times.
|
291 | const QFileInfo info(absolute); |
| 204 |
1/1✓ Branch 49 → 50 taken 291 times.
|
291 | artifacts.insert(relative, |
| 205 |
1/1✓ Branch 39 → 40 taken 291 times.
|
873 | QJsonObject{{QStringLiteral("bytes"), info.size()}, |
| 206 | 582 | {QStringLiteral("sha256"), | |
| 207 |
4/6✓ Branch 44 → 45 taken 291 times.
✓ Branch 45 → 46 taken 291 times.
✓ Branch 53 → 54 taken 582 times.
✓ Branch 53 → 55 taken 291 times.
✗ Branch 107 → 108 not taken.
✗ Branch 107 → 109 not taken.
|
1164 | QString::fromLatin1(fileSha256(absolute))}}); |
| 208 | 291 | } | |
| 209 | 29 | return artifacts; | |
| 210 | 902 | } | |
| 211 | |||
| 212 | 2 | QJsonObject readJsonObject(const QString &path) { | |
| 213 |
1/1✓ Branch 2 → 3 taken 2 times.
|
2 | QFile file(path); |
| 214 |
2/3✓ Branch 4 → 5 taken 2 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 8 taken 2 times.
|
2 | if (!file.open(QIODevice::ReadOnly)) |
| 215 | ✗ | return {}; | |
| 216 | 2 | QJsonParseError error; | |
| 217 | const QJsonDocument document = | ||
| 218 |
2/2✓ Branch 8 → 9 taken 2 times.
✓ Branch 9 → 10 taken 2 times.
|
2 | QJsonDocument::fromJson(file.readAll(), &error); |
| 219 |
2/3✓ Branch 12 → 13 taken 2 times.
✓ Branch 13 → 14 taken 2 times.
✗ Branch 13 → 16 not taken.
|
2 | return error.error == QJsonParseError::NoError && document.isObject() |
| 220 |
1/2✓ Branch 11 → 12 taken 2 times.
✗ Branch 11 → 16 not taken.
|
2 | ? document.object() |
| 221 |
1/2✓ Branch 14 → 15 taken 2 times.
✗ Branch 16 → 17 not taken.
|
2 | : QJsonObject{}; |
| 222 | 2 | } | |
| 223 | |||
| 224 | 131 | bool validateSqlite(const QString &path, int expectedSchema, | |
| 225 | int expectedFtsRows, QString *error) { | ||
| 226 | 262 | const QString connection = QStringLiteral("fixture_verify_") + | |
| 227 |
3/3✓ Branch 2 → 3 taken 131 times.
✓ Branch 3 → 4 taken 131 times.
✓ Branch 7 → 8 taken 131 times.
|
393 | QUuid::createUuid().toString(QUuid::WithoutBraces); |
| 228 | 131 | bool valid = true; | |
| 229 | { | ||
| 230 | QSqlDatabase db = | ||
| 231 |
1/1✓ Branch 14 → 15 taken 131 times.
|
131 | QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), connection); |
| 232 |
1/1✓ Branch 17 → 18 taken 131 times.
|
131 | db.setDatabaseName(path); |
| 233 |
2/3✓ Branch 18 → 19 taken 131 times.
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 36 taken 131 times.
|
131 | if (!db.open()) { |
| 234 | ✗ | if (error) | |
| 235 | ✗ | *error = QStringLiteral("Cannot validate fixture database: %1") | |
| 236 | ✗ | .arg(db.lastError().text()); | |
| 237 | ✗ | valid = false; | |
| 238 | } else { | ||
| 239 |
1/1✓ Branch 36 → 37 taken 131 times.
|
131 | QSqlQuery query(db); |
| 240 |
6/13✓ Branch 40 → 41 taken 131 times.
✓ Branch 41 → 42 taken 131 times.
✗ Branch 41 → 44 not taken.
✓ Branch 46 → 47 taken 131 times.
✗ Branch 46 → 48 not taken.
✓ Branch 48 → 49 taken 131 times.
✗ Branch 48 → 50 not taken.
✓ Branch 50 → 51 taken 2 times.
✓ Branch 50 → 63 taken 129 times.
✗ Branch 167 → 168 not taken.
✗ Branch 167 → 169 not taken.
✗ Branch 171 → 172 not taken.
✗ Branch 171 → 173 not taken.
|
393 | if (!query.exec(QStringLiteral("PRAGMA foreign_key_check")) || |
| 241 |
3/3✓ Branch 42 → 43 taken 131 times.
✓ Branch 43 → 44 taken 2 times.
✓ Branch 43 → 45 taken 129 times.
|
131 | query.next()) { |
| 242 |
2/2✓ Branch 51 → 52 taken 1 time.
✓ Branch 51 → 62 taken 1 time.
|
2 | if (error) |
| 243 | *error = | ||
| 244 | 2 | QStringLiteral("Fixture database has a foreign-key violation: %1") | |
| 245 |
1/1✓ Branch 56 → 57 taken 1 time.
|
2 | .arg(path); |
| 246 | 2 | valid = false; | |
| 247 | } | ||
| 248 |
4/4✓ Branch 63 → 64 taken 129 times.
✓ Branch 63 → 76 taken 2 times.
✓ Branch 64 → 65 taken 90 times.
✓ Branch 64 → 76 taken 39 times.
|
221 | if (valid && expectedSchema >= 0 && |
| 249 |
6/11✓ Branch 68 → 69 taken 90 times.
✓ Branch 69 → 70 taken 90 times.
✗ Branch 69 → 75 not taken.
✓ Branch 81 → 82 taken 90 times.
✓ Branch 81 → 83 taken 41 times.
✓ Branch 83 → 84 taken 2 times.
✓ Branch 83 → 96 taken 129 times.
✗ Branch 187 → 188 not taken.
✗ Branch 187 → 189 not taken.
✗ Branch 191 → 192 not taken.
✗ Branch 191 → 193 not taken.
|
221 | (!query.exec(QStringLiteral("PRAGMA user_version")) || |
| 250 |
10/13✓ Branch 70 → 71 taken 90 times.
✓ Branch 71 → 72 taken 90 times.
✗ Branch 71 → 75 not taken.
✓ Branch 72 → 73 taken 90 times.
✓ Branch 73 → 74 taken 90 times.
✓ Branch 74 → 75 taken 2 times.
✓ Branch 74 → 76 taken 88 times.
✓ Branch 77 → 78 taken 90 times.
✓ Branch 77 → 79 taken 41 times.
✓ Branch 79 → 80 taken 90 times.
✓ Branch 79 → 81 taken 41 times.
✗ Branch 183 → 184 not taken.
✗ Branch 183 → 185 not taken.
|
221 | !query.next() || query.value(0).toInt() != expectedSchema)) { |
| 251 |
2/2✓ Branch 84 → 85 taken 1 time.
✓ Branch 84 → 95 taken 1 time.
|
2 | if (error) |
| 252 | 2 | *error = QStringLiteral( | |
| 253 | "Fixture database schema version is unexpected: %1") | ||
| 254 |
1/1✓ Branch 89 → 90 taken 1 time.
|
2 | .arg(path); |
| 255 | 2 | valid = false; | |
| 256 | } | ||
| 257 |
4/4✓ Branch 96 → 97 taken 127 times.
✓ Branch 96 → 109 taken 4 times.
✓ Branch 97 → 98 taken 47 times.
✓ Branch 97 → 109 taken 80 times.
|
178 | if (valid && expectedFtsRows >= 0 && |
| 258 |
6/11✓ Branch 101 → 102 taken 47 times.
✓ Branch 102 → 103 taken 47 times.
✗ Branch 102 → 108 not taken.
✓ Branch 114 → 115 taken 47 times.
✓ Branch 114 → 116 taken 84 times.
✓ Branch 116 → 117 taken 2 times.
✓ Branch 116 → 129 taken 129 times.
✗ Branch 207 → 208 not taken.
✗ Branch 207 → 209 not taken.
✗ Branch 211 → 212 not taken.
✗ Branch 211 → 213 not taken.
|
178 | (!query.exec(QStringLiteral("SELECT COUNT(*) FROM mail_fts")) || |
| 259 |
10/13✓ Branch 103 → 104 taken 47 times.
✓ Branch 104 → 105 taken 47 times.
✗ Branch 104 → 108 not taken.
✓ Branch 105 → 106 taken 47 times.
✓ Branch 106 → 107 taken 47 times.
✓ Branch 107 → 108 taken 2 times.
✓ Branch 107 → 109 taken 45 times.
✓ Branch 110 → 111 taken 47 times.
✓ Branch 110 → 112 taken 84 times.
✓ Branch 112 → 113 taken 47 times.
✓ Branch 112 → 114 taken 84 times.
✗ Branch 203 → 204 not taken.
✗ Branch 203 → 205 not taken.
|
178 | !query.next() || query.value(0).toInt() != expectedFtsRows)) { |
| 260 |
2/2✓ Branch 117 → 118 taken 1 time.
✓ Branch 117 → 128 taken 1 time.
|
2 | if (error) |
| 261 | 2 | *error = QStringLiteral("Fixture FTS row count is unexpected: %1") | |
| 262 |
1/1✓ Branch 122 → 123 taken 1 time.
|
2 | .arg(path); |
| 263 | 2 | valid = false; | |
| 264 | } | ||
| 265 |
1/1✓ Branch 129 → 130 taken 131 times.
|
131 | db.close(); |
| 266 | 131 | } | |
| 267 | 131 | } | |
| 268 |
1/1✓ Branch 133 → 134 taken 131 times.
|
131 | QSqlDatabase::removeDatabase(connection); |
| 269 | 131 | return valid; | |
| 270 | 131 | } | |
| 271 | |||
| 272 | 29 | qint64 artifactBytes(const QJsonObject &artifacts) { | |
| 273 | 29 | qint64 total = 0; | |
| 274 |
3/3✓ Branch 15 → 16 taken 320 times.
✓ Branch 17 → 3 taken 291 times.
✓ Branch 17 → 18 taken 29 times.
|
320 | for (auto it = artifacts.constBegin(); it != artifacts.constEnd(); ++it) |
| 275 |
3/3✓ Branch 4 → 5 taken 291 times.
✓ Branch 8 → 9 taken 291 times.
✓ Branch 9 → 10 taken 291 times.
|
582 | total += it.value().toObject().value(QStringLiteral("bytes")).toInteger(); |
| 276 | 29 | return total; | |
| 277 | } | ||
| 278 | |||
| 279 | 29 | QJsonObject workloadManifest(const FixtureProfile &profile) { | |
| 280 | QJsonObject manifest = { | ||
| 281 | 58 | {QStringLiteral("schema_version"), 1}, | |
| 282 |
2/4✓ Branch 154 → 155 taken 116 times.
✓ Branch 154 → 156 taken 29 times.
✗ Branch 553 → 554 not taken.
✗ Branch 553 → 555 not taken.
|
174 | {QStringLiteral("mutation_sets"), QJsonArray{1, 10, 100, 1000}}, |
| 283 |
2/4✓ Branch 148 → 149 taken 87 times.
✓ Branch 148 → 150 taken 29 times.
✗ Branch 534 → 535 not taken.
✗ Branch 534 → 536 not taken.
|
145 | {QStringLiteral("delivery_bursts"), QJsonArray{1, 10, 100}}, |
| 284 |
2/4✓ Branch 142 → 143 taken 87 times.
✓ Branch 142 → 144 taken 29 times.
✗ Branch 515 → 516 not taken.
✗ Branch 515 → 517 not taken.
|
145 | {QStringLiteral("attachment_counts"), QJsonArray{1, 10, 50}}, |
| 285 |
2/4✓ Branch 136 → 137 taken 87 times.
✓ Branch 136 → 138 taken 29 times.
✗ Branch 496 → 497 not taken.
✗ Branch 496 → 498 not taken.
|
145 | {QStringLiteral("contact_scales"), QJsonArray{100, 2000, 20000}}, |
| 286 |
2/4✓ Branch 130 → 131 taken 116 times.
✓ Branch 130 → 132 taken 29 times.
✗ Branch 477 → 478 not taken.
✗ Branch 477 → 479 not taken.
|
174 | {QStringLiteral("folder_row_scales"), QJsonArray{0, 100, 10000, 100000}}, |
| 287 | 58 | {QStringLiteral("draft_revisions"), 5}, | |
| 288 | 58 | {QStringLiteral("contention_schedule"), | |
| 289 | 58 | QJsonArray{QStringLiteral("mail_open_during_header_sync"), | |
| 290 | 58 | QStringLiteral("search_during_fts"), | |
| 291 | 58 | QStringLiteral("calendar_during_caldav"), | |
| 292 |
2/4✓ Branch 114 → 115 taken 116 times.
✓ Branch 114 → 116 taken 29 times.
✗ Branch 427 → 428 not taken.
✗ Branch 427 → 429 not taken.
|
203 | QStringLiteral("autosave_during_attachment")}}, |
| 293 | 58 | {QStringLiteral("profile_counts"), | |
| 294 | 87 | QJsonObject{{QStringLiteral("headers"), profile.headers}, | |
| 295 | 58 | {QStringLiteral("events"), profile.events}, | |
| 296 | 58 | {QStringLiteral("tasks"), profile.tasks}, | |
| 297 |
2/4✓ Branch 100 → 101 taken 116 times.
✓ Branch 100 → 102 taken 29 times.
✗ Branch 384 → 385 not taken.
✗ Branch 384 → 386 not taken.
|
203 | {QStringLiteral("contacts"), profile.contacts}}}, |
| 298 |
2/4✓ Branch 96 → 97 taken 261 times.
✓ Branch 96 → 98 taken 29 times.
✗ Branch 378 → 379 not taken.
✗ Branch 378 → 380 not taken.
|
319 | }; |
| 299 |
2/2✓ Branch 166 → 167 taken 1 time.
✓ Branch 166 → 250 taken 28 times.
|
29 | if (profile.name == QStringLiteral("thread-dense")) { |
| 300 |
2/2✓ Branch 170 → 171 taken 1 time.
✓ Branch 174 → 175 taken 1 time.
|
2 | manifest.insert(QStringLiteral("thread_oracle"), QStringLiteral("thread-oracle.jsonl")); |
| 301 |
2/2✓ Branch 180 → 181 taken 1 time.
✓ Branch 184 → 185 taken 1 time.
|
2 | manifest.insert(QStringLiteral("thread_block_size"), 100); |
| 302 |
1/1✓ Branch 225 → 226 taken 1 time.
|
2 | manifest.insert(QStringLiteral("thread_shapes"), QJsonArray{ |
| 303 | 4 | QStringLiteral("singleton"), QStringLiteral("deep"), QStringLiteral("wide"), | |
| 304 | 3 | QStringLiteral("missing-parent"), QStringLiteral("cycle"), | |
| 305 | 3 | QStringLiteral("late-parent"), QStringLiteral("duplicate-message-id"), | |
| 306 |
2/4✓ Branch 231 → 232 taken 8 times.
✓ Branch 231 → 233 taken 1 time.
✗ Branch 617 → 618 not taken.
✗ Branch 617 → 619 not taken.
|
11 | QStringLiteral("filtered-descendant")}); |
| 307 |
2/2✓ Branch 256 → 257 taken 1 time.
✓ Branch 256 → 295 taken 27 times.
|
28 | } else if (profile.name == QStringLiteral("large-body")) { |
| 308 |
1/1✓ Branch 278 → 279 taken 1 time.
|
2 | manifest.insert(QStringLiteral("large_body_shapes"), |
| 309 | 3 | QJsonArray{QStringLiteral("plain-1m-raw"), | |
| 310 | 2 | QStringLiteral("plain-10m-raw"), | |
| 311 | 2 | QStringLiteral("html-1m-raw"), | |
| 312 |
2/4✓ Branch 284 → 285 taken 4 times.
✓ Branch 284 → 286 taken 1 time.
✗ Branch 687 → 688 not taken.
✗ Branch 687 → 689 not taken.
|
7 | QStringLiteral("html-10m-raw-attachment")}); |
| 313 |
2/2✓ Branch 301 → 302 taken 1 time.
✓ Branch 301 → 336 taken 26 times.
|
27 | } else if (profile.name == QStringLiteral("tab-churn")) { |
| 314 |
1/1✓ Branch 315 → 316 taken 1 time.
|
2 | manifest.insert( |
| 315 | 2 | QStringLiteral("tab_sequence"), | |
| 316 |
2/4✓ Branch 321 → 322 taken 2 times.
✓ Branch 321 → 323 taken 1 time.
✗ Branch 733 → 734 not taken.
✗ Branch 733 → 735 not taken.
|
5 | QJsonArray{QStringLiteral("plain"), QStringLiteral("html")}); |
| 317 |
2/2✓ Branch 327 → 328 taken 1 time.
✓ Branch 331 → 332 taken 1 time.
|
2 | manifest.insert(QStringLiteral("tab_cycles"), 50); |
| 318 |
2/2✓ Branch 342 → 343 taken 1 time.
✓ Branch 342 → 375 taken 25 times.
|
26 | } else if (profile.name == QStringLiteral("contact-dense")) { |
| 319 |
1/1✓ Branch 360 → 361 taken 1 time.
|
2 | manifest.insert(QStringLiteral("contact_collision_families"), |
| 320 | 3 | QJsonArray{QStringLiteral("case"), | |
| 321 | 2 | QStringLiteral("diacritic"), | |
| 322 |
2/4✓ Branch 366 → 367 taken 3 times.
✓ Branch 366 → 368 taken 1 time.
✗ Branch 776 → 777 not taken.
✗ Branch 776 → 778 not taken.
|
6 | QStringLiteral("stable-sort")}); |
| 323 | } | ||
| 324 | 29 | return manifest; | |
| 325 | 543 | } | |
| 326 | |||
| 327 | 29 | bool createMigrationSnapshots(const QString &directory, QString *error) { | |
| 328 |
1/1✓ Branch 2 → 3 taken 29 times.
|
29 | QDir dir(directory); |
| 329 |
2/3✓ Branch 6 → 7 taken 29 times.
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 19 taken 29 times.
|
29 | if (!dir.mkpath(QStringLiteral("migrations"))) { |
| 330 | ✗ | if (error) | |
| 331 | ✗ | *error = QStringLiteral("Cannot create migration snapshot directory"); | |
| 332 | ✗ | return false; | |
| 333 | } | ||
| 334 |
1/1✓ Branch 22 → 23 taken 29 times.
|
29 | const QString migrations = dir.filePath(QStringLiteral("migrations")); |
| 335 | |||
| 336 | const QString mail = | ||
| 337 |
2/2✓ Branch 25 → 26 taken 29 times.
✓ Branch 29 → 30 taken 29 times.
|
58 | QDir(migrations).filePath(QStringLiteral("mail-v16.sqlite")); |
| 338 |
6/16✓ Branch 36 → 37 taken 29 times.
✓ Branch 37 → 38 taken 29 times.
✓ Branch 38 → 39 taken 29 times.
✗ Branch 38 → 51 not taken.
✓ Branch 67 → 68 taken 29 times.
✗ Branch 67 → 69 not taken.
✓ Branch 69 → 70 taken 29 times.
✗ Branch 69 → 71 not taken.
✗ Branch 71 → 72 not taken.
✓ Branch 71 → 73 taken 29 times.
✗ Branch 275 → 276 not taken.
✗ Branch 275 → 277 not taken.
✗ Branch 279 → 280 not taken.
✗ Branch 279 → 281 not taken.
✗ Branch 283 → 284 not taken.
✗ Branch 283 → 285 not taken.
|
116 | if (!QFile::copy(dir.filePath(QStringLiteral("mail.sqlite")), mail) || |
| 339 |
6/15✓ Branch 49 → 50 taken 29 times.
✗ Branch 50 → 51 not taken.
✓ Branch 50 → 52 taken 29 times.
✓ Branch 53 → 54 taken 29 times.
✗ Branch 53 → 55 not taken.
✓ Branch 55 → 56 taken 29 times.
✗ Branch 55 → 59 not taken.
✓ Branch 57 → 58 taken 87 times.
✓ Branch 57 → 59 taken 29 times.
✗ Branch 247 → 248 not taken.
✗ Branch 247 → 249 not taken.
✗ Branch 251 → 252 not taken.
✗ Branch 251 → 255 not taken.
✗ Branch 253 → 254 not taken.
✗ Branch 253 → 255 not taken.
|
145 | !mutateSqlite( |
| 340 | mail, | ||
| 341 |
1/4✓ Branch 65 → 66 taken 29 times.
✗ Branch 65 → 67 not taken.
✗ Branch 265 → 266 not taken.
✗ Branch 265 → 267 not taken.
|
29 | {QStringLiteral("ALTER TABLE attachments DROP COLUMN presentation"), |
| 342 |
1/4✓ Branch 63 → 64 taken 29 times.
✗ Branch 63 → 65 not taken.
✗ Branch 261 → 262 not taken.
✗ Branch 261 → 263 not taken.
|
29 | QStringLiteral("DROP TABLE mutation_journal"), |
| 343 |
2/6✓ Branch 59 → 60 taken 29 times.
✗ Branch 59 → 61 not taken.
✓ Branch 61 → 62 taken 29 times.
✗ Branch 61 → 63 not taken.
✗ Branch 257 → 258 not taken.
✗ Branch 257 → 259 not taken.
|
29 | QStringLiteral("PRAGMA user_version=16")}, |
| 344 | error)) | ||
| 345 | ✗ | return false; | |
| 346 | |||
| 347 | const QString calendar = | ||
| 348 |
2/2✓ Branch 73 → 74 taken 29 times.
✓ Branch 77 → 78 taken 29 times.
|
58 | QDir(migrations).filePath(QStringLiteral("calendar-v4.sqlite")); |
| 349 |
6/16✓ Branch 84 → 85 taken 29 times.
✓ Branch 85 → 86 taken 29 times.
✓ Branch 86 → 87 taken 29 times.
✗ Branch 86 → 144 not taken.
✓ Branch 190 → 191 taken 29 times.
✗ Branch 190 → 192 not taken.
✓ Branch 192 → 193 taken 29 times.
✗ Branch 192 → 194 not taken.
✗ Branch 194 → 195 not taken.
✓ Branch 194 → 196 taken 29 times.
✗ Branch 384 → 385 not taken.
✗ Branch 384 → 386 not taken.
✗ Branch 388 → 389 not taken.
✗ Branch 388 → 390 not taken.
✗ Branch 392 → 393 not taken.
✗ Branch 392 → 394 not taken.
|
116 | if (!QFile::copy(dir.filePath(QStringLiteral("calendar.sqlite")), calendar) || |
| 350 |
6/15✓ Branch 142 → 143 taken 29 times.
✗ Branch 143 → 144 not taken.
✓ Branch 143 → 145 taken 29 times.
✓ Branch 146 → 147 taken 29 times.
✗ Branch 146 → 148 not taken.
✓ Branch 148 → 149 taken 29 times.
✗ Branch 148 → 152 not taken.
✓ Branch 150 → 151 taken 522 times.
✓ Branch 150 → 152 taken 29 times.
✗ Branch 296 → 297 not taken.
✗ Branch 296 → 298 not taken.
✗ Branch 300 → 301 not taken.
✗ Branch 300 → 304 not taken.
✗ Branch 302 → 303 not taken.
✗ Branch 302 → 304 not taken.
|
580 | !mutateSqlite( |
| 351 | calendar, | ||
| 352 |
1/4✓ Branch 188 → 189 taken 29 times.
✗ Branch 188 → 190 not taken.
✗ Branch 374 → 375 not taken.
✗ Branch 374 → 376 not taken.
|
29 | {QStringLiteral("DROP INDEX IF EXISTS idx_tasks_parent"), |
| 353 |
1/4✓ Branch 186 → 187 taken 29 times.
✗ Branch 186 → 188 not taken.
✗ Branch 370 → 371 not taken.
✗ Branch 370 → 372 not taken.
|
29 | QStringLiteral("ALTER TABLE tasks DROP COLUMN ical_raw"), |
| 354 |
1/4✓ Branch 184 → 185 taken 29 times.
✗ Branch 184 → 186 not taken.
✗ Branch 366 → 367 not taken.
✗ Branch 366 → 368 not taken.
|
29 | QStringLiteral("ALTER TABLE tasks DROP COLUMN tz_due"), |
| 355 |
1/4✓ Branch 182 → 183 taken 29 times.
✗ Branch 182 → 184 not taken.
✗ Branch 362 → 363 not taken.
✗ Branch 362 → 364 not taken.
|
29 | QStringLiteral("ALTER TABLE tasks DROP COLUMN tz_start"), |
| 356 |
1/4✓ Branch 180 → 181 taken 29 times.
✗ Branch 180 → 182 not taken.
✗ Branch 358 → 359 not taken.
✗ Branch 358 → 360 not taken.
|
29 | QStringLiteral("ALTER TABLE tasks DROP COLUMN start_all_day"), |
| 357 |
1/4✓ Branch 178 → 179 taken 29 times.
✗ Branch 178 → 180 not taken.
✗ Branch 354 → 355 not taken.
✗ Branch 354 → 356 not taken.
|
29 | QStringLiteral("ALTER TABLE tasks DROP COLUMN parent_uid"), |
| 358 |
1/4✓ Branch 176 → 177 taken 29 times.
✗ Branch 176 → 178 not taken.
✗ Branch 350 → 351 not taken.
✗ Branch 350 → 352 not taken.
|
29 | QStringLiteral("ALTER TABLE tasks DROP COLUMN rrule"), |
| 359 |
1/4✓ Branch 174 → 175 taken 29 times.
✗ Branch 174 → 176 not taken.
✗ Branch 346 → 347 not taken.
✗ Branch 346 → 348 not taken.
|
29 | QStringLiteral("ALTER TABLE tasks DROP COLUMN tags"), |
| 360 |
1/4✓ Branch 172 → 173 taken 29 times.
✗ Branch 172 → 174 not taken.
✗ Branch 342 → 343 not taken.
✗ Branch 342 → 344 not taken.
|
29 | QStringLiteral("ALTER TABLE tasks DROP COLUMN alarms"), |
| 361 |
1/4✓ Branch 170 → 171 taken 29 times.
✗ Branch 170 → 172 not taken.
✗ Branch 338 → 339 not taken.
✗ Branch 338 → 340 not taken.
|
29 | QStringLiteral("ALTER TABLE tasks DROP COLUMN sort_order"), |
| 362 |
1/4✓ Branch 168 → 169 taken 29 times.
✗ Branch 168 → 170 not taken.
✗ Branch 334 → 335 not taken.
✗ Branch 334 → 336 not taken.
|
29 | QStringLiteral("ALTER TABLE tasks DROP COLUMN previous_status"), |
| 363 |
1/4✓ Branch 166 → 167 taken 29 times.
✗ Branch 166 → 168 not taken.
✗ Branch 330 → 331 not taken.
✗ Branch 330 → 332 not taken.
|
29 | QStringLiteral("ALTER TABLE tasks DROP COLUMN previous_percent"), |
| 364 |
1/4✓ Branch 164 → 165 taken 29 times.
✗ Branch 164 → 166 not taken.
✗ Branch 326 → 327 not taken.
✗ Branch 326 → 328 not taken.
|
29 | QStringLiteral("ALTER TABLE calendars DROP COLUMN supported_components"), |
| 365 |
1/4✓ Branch 162 → 163 taken 29 times.
✗ Branch 162 → 164 not taken.
✗ Branch 322 → 323 not taken.
✗ Branch 322 → 324 not taken.
|
29 | QStringLiteral("ALTER TABLE calendar_outbox DROP COLUMN component_type"), |
| 366 |
1/4✓ Branch 160 → 161 taken 29 times.
✗ Branch 160 → 162 not taken.
✗ Branch 318 → 319 not taken.
✗ Branch 318 → 320 not taken.
|
29 | QStringLiteral("ALTER TABLE calendar_outbox DROP COLUMN dependency_key"), |
| 367 |
1/4✓ Branch 158 → 159 taken 29 times.
✗ Branch 158 → 160 not taken.
✗ Branch 314 → 315 not taken.
✗ Branch 314 → 316 not taken.
|
29 | QStringLiteral("ALTER TABLE tasks DROP COLUMN due_all_day"), |
| 368 |
1/4✓ Branch 156 → 157 taken 29 times.
✗ Branch 156 → 158 not taken.
✗ Branch 310 → 311 not taken.
✗ Branch 310 → 312 not taken.
|
29 | QStringLiteral("ALTER TABLE events DROP COLUMN series_end"), |
| 369 |
2/6✓ Branch 152 → 153 taken 29 times.
✗ Branch 152 → 154 not taken.
✓ Branch 154 → 155 taken 29 times.
✗ Branch 154 → 156 not taken.
✗ Branch 306 → 307 not taken.
✗ Branch 306 → 308 not taken.
|
29 | QStringLiteral("PRAGMA user_version=4")}, |
| 370 | error)) | ||
| 371 | ✗ | return false; | |
| 372 | |||
| 373 | const QString contacts = | ||
| 374 |
2/2✓ Branch 196 → 197 taken 29 times.
✓ Branch 200 → 201 taken 29 times.
|
58 | QDir(migrations).filePath(QStringLiteral("contacts-legacy.sqlite")); |
| 375 |
3/5✓ Branch 211 → 212 taken 29 times.
✓ Branch 215 → 216 taken 58 times.
✓ Branch 215 → 217 taken 29 times.
✗ Branch 408 → 409 not taken.
✗ Branch 408 → 410 not taken.
|
116 | return mutateSqlite( |
| 376 | contacts, | ||
| 377 | ✗ | {QStringLiteral( | |
| 378 | "CREATE TABLE contacts (id INTEGER PRIMARY KEY AUTOINCREMENT, " | ||
| 379 | "display_name TEXT NOT NULL DEFAULT '', email TEXT NOT NULL, " | ||
| 380 | "source TEXT NOT NULL DEFAULT 'local', carddav_uid TEXT DEFAULT '', " | ||
| 381 | "carddav_etag TEXT DEFAULT '', last_used TEXT, " | ||
| 382 | "use_count INTEGER NOT NULL DEFAULT 0, " | ||
| 383 | "created_at TEXT NOT NULL DEFAULT (datetime('now')), " | ||
| 384 | "updated_at TEXT NOT NULL DEFAULT (datetime('now')), " | ||
| 385 | "UNIQUE(email, source))"), | ||
| 386 | 29 | QStringLiteral( | |
| 387 | "INSERT INTO contacts(display_name,email,source,use_count) VALUES " | ||
| 388 | "('Synthetic Legacy','legacy@example.invalid','local',1)")}, | ||
| 389 | 29 | error); | |
| 390 | 783 | } | |
| 391 | |||
| 392 | } // namespace | ||
| 393 | |||
| 394 | 109 | QStringList FixtureGenerator::profileNames() { | |
| 395 | 109 | return {QStringLiteral("empty"), QStringLiteral("small"), | |
| 396 | 109 | QStringLiteral("typical"), QStringLiteral("large"), | |
| 397 | 109 | QStringLiteral("stress"), QStringLiteral("dense-folder"), | |
| 398 | 109 | QStringLiteral("large-body"), QStringLiteral("tab-churn"), | |
| 399 | 109 | QStringLiteral("contact-dense"), QStringLiteral("contacts-showcase"), | |
| 400 | 109 | QStringLiteral("million-folder"), QStringLiteral("million-account"), | |
| 401 |
2/4✓ Branch 43 → 44 taken 1417 times.
✓ Branch 43 → 45 taken 109 times.
✗ Branch 61 → 62 not taken.
✗ Branch 61 → 63 not taken.
|
1635 | QStringLiteral("thread-dense")}; |
| 402 | 1526 | } | |
| 403 | |||
| 404 | 114 | FixtureProfile FixtureGenerator::profile(const QString &name) { | |
| 405 |
2/2✓ Branch 8 → 9 taken 75 times.
✓ Branch 8 → 11 taken 39 times.
|
114 | if (name == QStringLiteral("empty")) |
| 406 | 75 | return {name, 0, 0, 0, 0, 0, 0}; | |
| 407 |
2/2✓ Branch 17 → 18 taken 20 times.
✓ Branch 17 → 20 taken 19 times.
|
39 | if (name == QStringLiteral("small")) |
| 408 | 20 | return {name, 12, 1000, 100, 100, 50, 100}; | |
| 409 |
1/2✗ Branch 26 → 27 not taken.
✓ Branch 26 → 29 taken 19 times.
|
19 | if (name == QStringLiteral("typical")) |
| 410 | ✗ | return {name, 30, 10000, 1000, 1000, 500, 2000}; | |
| 411 |
2/2✓ Branch 35 → 36 taken 1 time.
✓ Branch 35 → 38 taken 18 times.
|
19 | if (name == QStringLiteral("large")) |
| 412 | 1 | return {name, 100, 100000, 10000, 10000, 5000, 20000}; | |
| 413 |
1/2✗ Branch 44 → 45 not taken.
✓ Branch 44 → 47 taken 18 times.
|
18 | if (name == QStringLiteral("stress")) |
| 414 | ✗ | return {name, 250, 500000, 25000, 50000, 25000, 100000}; | |
| 415 |
2/2✓ Branch 53 → 54 taken 1 time.
✓ Branch 53 → 56 taken 17 times.
|
18 | if (name == QStringLiteral("dense-folder")) |
| 416 | 1 | return {name, 1, 100000, 1000, 0, 0, 0}; | |
| 417 |
2/2✓ Branch 62 → 63 taken 3 times.
✓ Branch 62 → 65 taken 14 times.
|
17 | if (name == QStringLiteral("large-body")) |
| 418 | 3 | return {name, 1, 4, 4, 0, 0, 0}; | |
| 419 |
2/2✓ Branch 71 → 72 taken 3 times.
✓ Branch 71 → 74 taken 11 times.
|
14 | if (name == QStringLiteral("tab-churn")) |
| 420 | 3 | return {name, 1, 50, 50, 0, 0, 0}; | |
| 421 |
2/2✓ Branch 80 → 81 taken 3 times.
✓ Branch 80 → 83 taken 8 times.
|
11 | if (name == QStringLiteral("contact-dense")) |
| 422 | 3 | return {name, 0, 0, 0, 0, 0, 20000}; | |
| 423 | // Sprint 97 S97.0.5: realistic contacts for captures (ContactShowcase). | ||
| 424 |
1/2✗ Branch 89 → 90 not taken.
✓ Branch 89 → 92 taken 8 times.
|
8 | if (name == QStringLiteral("contacts-showcase")) |
| 425 | ✗ | return {name, 0, 0, 0, 0, 0, 116}; | |
| 426 |
1/2✗ Branch 98 → 99 not taken.
✓ Branch 98 → 101 taken 8 times.
|
8 | if (name == QStringLiteral("million-folder")) |
| 427 | ✗ | return {name, 1, 1000000, 10000, 0, 0, 0}; | |
| 428 |
1/2✗ Branch 107 → 108 not taken.
✓ Branch 107 → 110 taken 8 times.
|
8 | if (name == QStringLiteral("million-account")) |
| 429 | ✗ | return {name, 250, 1000000, 10000, 0, 0, 0}; | |
| 430 |
2/2✓ Branch 116 → 117 taken 3 times.
✓ Branch 116 → 119 taken 5 times.
|
8 | if (name == QStringLiteral("thread-dense")) |
| 431 | 3 | return {name, 1, 100000, 1000, 0, 0, 0}; | |
| 432 | 5 | return {}; | |
| 433 | 109 | } | |
| 434 | |||
| 435 | QByteArray | ||
| 436 | 101 | FixtureGenerator::logicalChecksum(const QJsonObject &logicalManifest) { | |
| 437 |
3/3✓ Branch 2 → 3 taken 101 times.
✓ Branch 3 → 4 taken 101 times.
✓ Branch 4 → 5 taken 101 times.
|
101 | return sha256(QJsonDocument(logicalManifest).toJson(QJsonDocument::Compact)); |
| 438 | } | ||
| 439 | |||
| 440 | 39 | bool FixtureGenerator::generate(const QString &outputRoot, | |
| 441 | const QString &profileName, quint64 seed, | ||
| 442 | bool force, QString *error) const { | ||
| 443 |
1/1✓ Branch 2 → 3 taken 39 times.
|
39 | const FixtureProfile spec = profile(profileName); |
| 444 |
3/3✓ Branch 3 → 4 taken 39 times.
✓ Branch 6 → 7 taken 2 times.
✓ Branch 6 → 19 taken 37 times.
|
39 | if (!profileNames().contains(profileName)) { |
| 445 |
2/2✓ Branch 7 → 8 taken 1 time.
✓ Branch 7 → 18 taken 1 time.
|
2 | if (error) |
| 446 |
1/1✓ Branch 12 → 13 taken 1 time.
|
2 | *error = QStringLiteral("Unknown fixture profile: %1").arg(profileName); |
| 447 | 2 | return false; | |
| 448 | } | ||
| 449 |
2/2✓ Branch 19 → 20 taken 37 times.
✓ Branch 20 → 21 taken 37 times.
|
37 | const QString directory = QDir(outputRoot).filePath(profileName); |
| 450 | const QString manifestPath = | ||
| 451 |
2/2✓ Branch 22 → 23 taken 37 times.
✓ Branch 26 → 27 taken 37 times.
|
74 | QDir(directory).filePath(QStringLiteral("manifest.json")); |
| 452 |
10/10✓ Branch 30 → 31 taken 20 times.
✓ Branch 30 → 36 taken 17 times.
✓ Branch 31 → 32 taken 20 times.
✓ Branch 32 → 33 taken 3 times.
✓ Branch 32 → 36 taken 17 times.
✓ Branch 33 → 34 taken 3 times.
✓ Branch 34 → 35 taken 2 times.
✓ Branch 34 → 36 taken 1 time.
✓ Branch 37 → 38 taken 2 times.
✓ Branch 37 → 85 taken 35 times.
|
37 | if (!force && QFileInfo::exists(manifestPath) && verify(directory, nullptr)) { |
| 453 |
1/1✓ Branch 38 → 39 taken 2 times.
|
2 | const QJsonObject logical = readJsonObject(manifestPath) |
| 454 |
1/1✓ Branch 42 → 43 taken 2 times.
|
4 | .value(QStringLiteral("logical")) |
| 455 |
1/1✓ Branch 43 → 44 taken 2 times.
|
2 | .toObject(); |
| 456 |
8/20✓ Branch 51 → 52 taken 2 times.
✓ Branch 52 → 53 taken 2 times.
✓ Branch 54 → 55 taken 2 times.
✗ Branch 54 → 62 not taken.
✓ Branch 71 → 72 taken 2 times.
✗ Branch 71 → 73 not taken.
✓ Branch 73 → 74 taken 2 times.
✗ Branch 73 → 75 not taken.
✓ Branch 75 → 76 taken 2 times.
✗ Branch 75 → 77 not taken.
✓ Branch 77 → 78 taken 1 time.
✓ Branch 77 → 79 taken 1 time.
✗ Branch 1741 → 1742 not taken.
✗ Branch 1741 → 1743 not taken.
✗ Branch 1745 → 1746 not taken.
✗ Branch 1745 → 1747 not taken.
✗ Branch 1749 → 1750 not taken.
✗ Branch 1749 → 1751 not taken.
✗ Branch 1753 → 1754 not taken.
✗ Branch 1753 → 1755 not taken.
|
8 | if (logical.value(QStringLiteral("profile")).toString() == profileName && |
| 457 |
6/16✓ Branch 58 → 59 taken 2 times.
✓ Branch 59 → 60 taken 2 times.
✓ Branch 63 → 64 taken 2 times.
✗ Branch 63 → 65 not taken.
✓ Branch 65 → 66 taken 2 times.
✗ Branch 65 → 67 not taken.
✓ Branch 67 → 68 taken 2 times.
✗ Branch 67 → 69 not taken.
✓ Branch 69 → 70 taken 2 times.
✗ Branch 69 → 71 not taken.
✗ Branch 1729 → 1730 not taken.
✗ Branch 1729 → 1731 not taken.
✗ Branch 1733 → 1734 not taken.
✗ Branch 1733 → 1735 not taken.
✗ Branch 1737 → 1738 not taken.
✗ Branch 1737 → 1739 not taken.
|
4 | logical.value(QStringLiteral("seed")).toInteger() == |
| 458 |
2/2✓ Branch 60 → 61 taken 1 time.
✓ Branch 60 → 62 taken 1 time.
|
2 | static_cast<qint64>(seed)) |
| 459 | 1 | return true; | |
| 460 | 2 | } | |
| 461 |
3/3✓ Branch 85 → 86 taken 36 times.
✓ Branch 86 → 87 taken 1 time.
✓ Branch 86 → 88 taken 35 times.
|
36 | if (!removeOwnedOutput(directory, error)) |
| 462 | 1 | return false; | |
| 463 |
4/4✓ Branch 89 → 90 taken 35 times.
✓ Branch 90 → 91 taken 35 times.
✓ Branch 93 → 94 taken 2 times.
✓ Branch 93 → 106 taken 33 times.
|
35 | if (!QDir().mkpath(directory)) { |
| 464 |
2/2✓ Branch 94 → 95 taken 1 time.
✓ Branch 94 → 105 taken 1 time.
|
2 | if (error) |
| 465 | *error = | ||
| 466 |
1/1✓ Branch 99 → 100 taken 1 time.
|
2 | QStringLiteral("Cannot create fixture directory: %1").arg(directory); |
| 467 | 2 | return false; | |
| 468 | } | ||
| 469 |
4/4✓ Branch 108 → 109 taken 33 times.
✓ Branch 110 → 111 taken 33 times.
✓ Branch 111 → 112 taken 33 times.
✓ Branch 112 → 113 taken 33 times.
|
33 | if (!writeBytes(QDir(directory).filePath(QString::fromLatin1(OwnerMarker)), |
| 470 |
2/2✓ Branch 118 → 119 taken 2 times.
✓ Branch 118 → 120 taken 31 times.
|
66 | QByteArrayLiteral("MailJD performance fixture v1\n"), error)) |
| 471 | 2 | return false; | |
| 472 | |||
| 473 | 31 | QElapsedTimer generationTimer; | |
| 474 | 31 | generationTimer.start(); | |
| 475 | 31 | DeterministicBytes random(seed); | |
| 476 |
4/4✓ Branch 122 → 123 taken 31 times.
✓ Branch 123 → 124 taken 31 times.
✓ Branch 124 → 125 taken 31 times.
✓ Branch 125 → 126 taken 31 times.
|
31 | const QDateTime epoch(QDate(2026, 1, 1), QTime(0, 0), QTimeZone::utc()); |
| 477 | |||
| 478 |
1/1✓ Branch 127 → 128 taken 31 times.
|
31 | MailCache mail; |
| 479 |
5/5✓ Branch 128 → 129 taken 31 times.
✓ Branch 132 → 133 taken 31 times.
✓ Branch 133 → 134 taken 31 times.
✓ Branch 138 → 139 taken 2 times.
✓ Branch 138 → 145 taken 29 times.
|
62 | if (!mail.open(QDir(directory).filePath(QStringLiteral("mail.sqlite")))) { |
| 480 |
2/2✓ Branch 139 → 140 taken 1 time.
✓ Branch 139 → 144 taken 1 time.
|
2 | if (error) |
| 481 |
1/1✓ Branch 140 → 141 taken 1 time.
|
1 | *error = mail.lastError(); |
| 482 | 2 | return false; | |
| 483 | } | ||
| 484 |
5/11✓ Branch 148 → 149 taken 29 times.
✓ Branch 149 → 150 taken 29 times.
✗ Branch 149 → 153 not taken.
✓ Branch 152 → 153 taken 1 time.
✓ Branch 152 → 154 taken 28 times.
✓ Branch 157 → 158 taken 29 times.
✗ Branch 157 → 159 not taken.
✗ Branch 1809 → 1810 not taken.
✗ Branch 1809 → 1811 not taken.
✗ Branch 1813 → 1814 not taken.
✗ Branch 1813 → 1815 not taken.
|
116 | const bool streamHeaders = profileName.startsWith(QStringLiteral("million-")) || |
| 485 |
1/2✓ Branch 155 → 156 taken 29 times.
✗ Branch 155 → 157 not taken.
|
58 | profileName == QLatin1String("thread-dense"); |
| 486 | 29 | int globalHeader = 0; | |
| 487 | 29 | int storedBodies = 0; | |
| 488 |
1/1✓ Branch 159 → 160 taken 29 times.
|
29 | QJsonArray bodyHitIdentities; |
| 489 |
1/1✓ Branch 160 → 161 taken 29 times.
|
29 | QJsonArray bodyMissIdentities; |
| 490 |
2/2✓ Branch 591 → 162 taken 75 times.
✓ Branch 591 → 592 taken 29 times.
|
104 | for (int folderIndex = 0; folderIndex < spec.folders; ++folderIndex) { |
| 491 |
1/1✓ Branch 162 → 163 taken 75 times.
|
75 | const QString path = folderName(folderIndex); |
| 492 | const qint64 folderId = | ||
| 493 |
2/2✓ Branch 164 → 165 taken 75 times.
✓ Branch 165 → 166 taken 75 times.
|
75 | mail.ensureFolder(QString::fromLatin1(AccountId), path); |
| 494 |
1/2✗ Branch 167 → 168 not taken.
✓ Branch 167 → 177 taken 75 times.
|
75 | if (folderId <= 0) { |
| 495 | ✗ | if (error) | |
| 496 | ✗ | *error = QStringLiteral("Cannot create synthetic folder"); | |
| 497 | ✗ | return false; | |
| 498 | } | ||
| 499 | 150 | const int count = spec.headers / spec.folders + | |
| 500 |
2/2✓ Branch 177 → 178 taken 24 times.
✓ Branch 177 → 179 taken 51 times.
|
75 | (folderIndex < spec.headers % spec.folders ? 1 : 0); |
| 501 | // Preserve the frozen generation order; new million profiles stream setup. | ||
| 502 | 75 | const int folderGlobalStart = globalHeader; | |
| 503 |
2/2✓ Branch 180 → 181 taken 1 time.
✓ Branch 180 → 182 taken 74 times.
|
75 | const int batchLimit = streamHeaders ? 1000 : std::max(1, count); |
| 504 |
2/2✓ Branch 584 → 185 taken 174 times.
✓ Branch 584 → 585 taken 75 times.
|
249 | for (int batchStart = 0; batchStart < count; batchStart += batchLimit) { |
| 505 | 174 | const int batchEnd = std::min(count, batchStart + batchLimit); | |
| 506 | 174 | QList<MailHeader> headers; | |
| 507 |
1/1✓ Branch 186 → 187 taken 174 times.
|
174 | headers.reserve(batchEnd - batchStart); |
| 508 |
2/2✓ Branch 308 → 188 taken 106054 times.
✓ Branch 308 → 309 taken 174 times.
|
106228 | for (int local = batchStart; local < batchEnd; ++local) { |
| 509 | 106054 | ++globalHeader; | |
| 510 | 106054 | MailHeader header; | |
| 511 | 106054 | header.uid = local + 1; | |
| 512 | 106054 | header.folderId = folderId; | |
| 513 | 212108 | header.subject = QStringLiteral("Synthetic mail %1") | |
| 514 |
1/1✓ Branch 194 → 195 taken 106054 times.
|
212108 | .arg(globalHeader, 7, 10, QLatin1Char('0')); |
| 515 | header.from = | ||
| 516 |
1/1✓ Branch 203 → 204 taken 106054 times.
|
212108 | QStringLiteral("sender-%1@example.invalid").arg(globalHeader % 257); |
| 517 | 106054 | header.to = QStringLiteral("recipient@example.invalid"); | |
| 518 |
1/1✓ Branch 215 → 216 taken 106054 times.
|
106054 | header.date = epoch.addSecs(globalHeader * 61 + random.next() % 17); |
| 519 |
2/2✓ Branch 218 → 219 taken 35348 times.
✓ Branch 218 → 220 taken 70706 times.
|
106054 | header.flags = globalHeader % 3 == 0 ? MailFlag::Seen : MailFlag::None; |
| 520 |
2/2✓ Branch 221 → 222 taken 9634 times.
✓ Branch 221 → 223 taken 96420 times.
|
106054 | if (globalHeader % 11 == 0) |
| 521 | 9634 | header.flags |= MailFlag::Flagged; | |
| 522 |
2/2✓ Branch 223 → 224 taken 3653 times.
✓ Branch 223 → 225 taken 102401 times.
|
106054 | if (globalHeader % 29 == 0) |
| 523 | 3653 | header.flags |= MailFlag::Answered; | |
| 524 |
2/2✓ Branch 225 → 226 taken 1044 times.
✓ Branch 225 → 227 taken 105010 times.
|
106054 | if (globalHeader % 101 == 0) |
| 525 | 1044 | header.flags |= MailFlag::Draft; | |
| 526 | 106054 | header.size = 512 + static_cast<qint64>(random.next() % 65536); | |
| 527 | 212108 | header.hasAttachments = profileName == QStringLiteral("large-body") | |
| 528 |
2/2✓ Branch 232 → 233 taken 4 times.
✓ Branch 232 → 234 taken 106050 times.
|
106054 | ? globalHeader == spec.headers |
| 529 | 106050 | : globalHeader % 100 == 0; | |
| 530 |
2/2✓ Branch 237 → 238 taken 8151 times.
✓ Branch 237 → 251 taken 97903 times.
|
106054 | if (globalHeader % 13 == 0) |
| 531 |
2/4✓ Branch 246 → 247 taken 16302 times.
✓ Branch 246 → 248 taken 8151 times.
✗ Branch 1840 → 1841 not taken.
✗ Branch 1840 → 1842 not taken.
|
24453 | header.labels = {QStringLiteral("perf-a"), QStringLiteral("perf-b")}; |
| 532 |
2/2✓ Branch 251 → 252 taken 105122 times.
✓ Branch 251 → 270 taken 932 times.
|
106054 | if (globalHeader % 113 != 0) { |
| 533 | header.messageId = | ||
| 534 | 105122 | globalHeader % 97 == 0 | |
| 535 |
3/5✓ Branch 252 → 253 taken 1081 times.
✓ Branch 252 → 256 taken 104041 times.
✓ Branch 260 → 261 taken 104041 times.
✗ Branch 1864 → 1865 not taken.
✗ Branch 1864 → 1866 not taken.
|
420488 | ? QStringLiteral("duplicate@example.invalid") |
| 536 |
6/10✓ Branch 263 → 264 taken 104041 times.
✓ Branch 263 → 265 taken 1081 times.
✓ Branch 265 → 266 taken 104041 times.
✓ Branch 265 → 267 taken 1081 times.
✓ Branch 267 → 268 taken 1081 times.
✓ Branch 267 → 269 taken 104041 times.
✗ Branch 1856 → 1857 not taken.
✗ Branch 1856 → 1858 not taken.
✗ Branch 1860 → 1861 not taken.
✗ Branch 1860 → 1862 not taken.
|
314285 | : QStringLiteral("mail-%1@example.invalid").arg(globalHeader); |
| 537 | } | ||
| 538 |
4/4✓ Branch 270 → 271 taken 79541 times.
✓ Branch 270 → 301 taken 26513 times.
✓ Branch 271 → 272 taken 79532 times.
✓ Branch 271 → 301 taken 9 times.
|
106054 | if (globalHeader % 4 != 0 && globalHeader > 1) { |
| 539 | header.inReplyTo = | ||
| 540 |
1/1✓ Branch 276 → 277 taken 79532 times.
|
159064 | QStringLiteral("mail-%1@example.invalid").arg(globalHeader - 1); |
| 541 |
2/4✓ Branch 284 → 285 taken 79532 times.
✓ Branch 284 → 286 taken 79532 times.
✗ Branch 1878 → 1879 not taken.
✗ Branch 1878 → 1880 not taken.
|
159064 | header.inReplyToIds = {header.inReplyTo}; |
| 542 |
2/4✓ Branch 295 → 296 taken 159064 times.
✓ Branch 295 → 298 taken 79532 times.
✗ Branch 1888 → 1889 not taken.
✗ Branch 1888 → 1891 not taken.
|
397660 | header.references = {QStringLiteral("mail-%1@example.invalid") |
| 543 | 79532 | .arg(std::max(1, globalHeader - 3)), | |
| 544 | 238596 | header.inReplyTo}; | |
| 545 | } | ||
| 546 |
2/2✓ Branch 303 → 304 taken 100000 times.
✓ Branch 303 → 305 taken 6054 times.
|
106054 | if (profileName == QLatin1String("thread-dense")) |
| 547 |
1/1✓ Branch 304 → 305 taken 100000 times.
|
100000 | applyThreadFixture(header); |
| 548 |
1/1✓ Branch 305 → 306 taken 106054 times.
|
106054 | headers.append(header); |
| 549 | 106054 | } | |
| 550 |
2/3✓ Branch 309 → 310 taken 174 times.
✗ Branch 310 → 311 not taken.
✓ Branch 310 → 317 taken 174 times.
|
174 | if (!mail.storeHeaders(folderId, headers)) { |
| 551 | ✗ | if (error) *error = mail.lastError(); | |
| 552 | ✗ | return false; | |
| 553 | } | ||
| 554 |
2/2✓ Branch 317 → 318 taken 75 times.
✓ Branch 317 → 319 taken 99 times.
|
174 | if (batchStart == 0) |
| 555 |
1/1✓ Branch 318 → 319 taken 75 times.
|
75 | mail.storeBadge(folderId, (count * 2) / 3); |
| 556 | |||
| 557 |
4/4✓ Branch 319 → 320 taken 174 times.
✓ Branch 320 → 321 taken 174 times.
✓ Branch 577 → 322 taken 106054 times.
✓ Branch 577 → 578 taken 174 times.
|
106228 | for (const MailHeader &header : headers) { |
| 558 | const QJsonObject identity = { | ||
| 559 | 212108 | {QStringLiteral("folder"), path}, | |
| 560 | 212108 | {QStringLiteral("uid"), static_cast<qint64>(header.uid)}, | |
| 561 |
2/4✓ Branch 333 → 334 taken 212108 times.
✓ Branch 333 → 335 taken 106054 times.
✗ Branch 1912 → 1913 not taken.
✗ Branch 1912 → 1914 not taken.
|
318162 | }; |
| 562 |
2/2✓ Branch 339 → 340 taken 104400 times.
✓ Branch 339 → 347 taken 1654 times.
|
106054 | if (storedBodies >= spec.bodies) { |
| 563 |
3/3✓ Branch 340 → 341 taken 104400 times.
✓ Branch 341 → 342 taken 28 times.
✓ Branch 341 → 346 taken 104372 times.
|
104400 | if (bodyMissIdentities.size() < 4) |
| 564 |
2/2✓ Branch 342 → 343 taken 28 times.
✓ Branch 343 → 344 taken 28 times.
|
28 | bodyMissIdentities.append(identity); |
| 565 | 104400 | continue; | |
| 566 | } | ||
| 567 | 1654 | ++storedBodies; | |
| 568 |
3/3✓ Branch 347 → 348 taken 1654 times.
✓ Branch 348 → 349 taken 36 times.
✓ Branch 348 → 353 taken 1618 times.
|
1654 | if (bodyHitIdentities.size() < 4) |
| 569 |
2/2✓ Branch 349 → 350 taken 36 times.
✓ Branch 350 → 351 taken 36 times.
|
36 | bodyHitIdentities.append(identity); |
| 570 | 1654 | MailBody body; | |
| 571 | 1654 | body.uid = header.uid; | |
| 572 |
2/2✓ Branch 359 → 360 taken 4 times.
✓ Branch 359 → 415 taken 1650 times.
|
1654 | if (profileName == QStringLiteral("large-body")) { |
| 573 | 4 | const int payloadBytes = | |
| 574 |
2/2✓ Branch 360 → 361 taken 2 times.
✓ Branch 360 → 362 taken 2 times.
|
4 | storedBodies % 2 == 0 ? 10 * 1024 * 1024 : 1024 * 1024; |
| 575 |
1/1✓ Branch 365 → 366 taken 4 times.
|
4 | const QString payload(payloadBytes, QLatin1Char('x')); |
| 576 |
2/2✓ Branch 366 → 367 taken 2 times.
✓ Branch 366 → 379 taken 2 times.
|
4 | if (storedBodies <= 2) { |
| 577 | body.textPlain = | ||
| 578 |
1/1✓ Branch 371 → 372 taken 2 times.
|
6 | QStringLiteral("PERF-LARGE-PLAIN-%1 ").arg(storedBodies) + |
| 579 |
1/1✓ Branch 372 → 373 taken 2 times.
|
2 | payload; |
| 580 | } else { | ||
| 581 | 4 | body.textHtml = QStringLiteral("<html><body><p>PERF-LARGE-HTML-%1 ") | |
| 582 |
1/1✓ Branch 386 → 387 taken 2 times.
|
4 | .arg(storedBodies) + |
| 583 |
2/2✓ Branch 387 → 388 taken 2 times.
✓ Branch 388 → 389 taken 2 times.
|
6 | payload + QStringLiteral("</p></body></html>"); |
| 584 | } | ||
| 585 |
1/1✓ Branch 401 → 402 taken 4 times.
|
8 | body.rawSource = QByteArray("PERF-LARGE-RAW-") + |
| 586 |
4/4✓ Branch 399 → 400 taken 4 times.
✓ Branch 400 → 401 taken 4 times.
✓ Branch 402 → 403 taken 4 times.
✓ Branch 403 → 404 taken 4 times.
|
16 | QByteArray::number(storedBodies) + QByteArray("\r\n") + |
| 587 |
2/2✓ Branch 398 → 399 taken 4 times.
✓ Branch 404 → 405 taken 4 times.
|
12 | QByteArray(payloadBytes, 'r'); |
| 588 |
2/2✓ Branch 421 → 422 taken 50 times.
✓ Branch 421 → 455 taken 1600 times.
|
1654 | } else if (profileName == QStringLiteral("tab-churn")) { |
| 589 |
2/2✓ Branch 422 → 423 taken 25 times.
✓ Branch 422 → 433 taken 25 times.
|
50 | if (storedBodies % 2 == 1) |
| 590 | body.textPlain = | ||
| 591 |
1/1✓ Branch 427 → 428 taken 25 times.
|
50 | QStringLiteral("PERF-TAB-PLAIN-%1").arg(storedBodies); |
| 592 | else | ||
| 593 | body.textHtml = | ||
| 594 |
1/1✓ Branch 437 → 438 taken 25 times.
|
50 | QStringLiteral("<p>PERF-TAB-HTML-%1</p>").arg(storedBodies); |
| 595 |
1/1✓ Branch 445 → 446 taken 50 times.
|
100 | body.rawSource = QByteArray("PERF-TAB-RAW-") + |
| 596 |
4/4✓ Branch 443 → 444 taken 50 times.
✓ Branch 444 → 445 taken 50 times.
✓ Branch 446 → 447 taken 50 times.
✓ Branch 447 → 448 taken 50 times.
|
150 | QByteArray::number(storedBodies) + QByteArray("\r\n"); |
| 597 | } else { | ||
| 598 | const qint64 marker = streamHeaders | ||
| 599 |
2/2✓ Branch 455 → 456 taken 1000 times.
✓ Branch 455 → 457 taken 600 times.
|
1600 | ? folderGlobalStart + static_cast<qint64>(header.uid) |
| 600 | 1600 | : globalHeader - headers.size() + storedBodies; | |
| 601 | 3200 | body.textPlain = QStringLiteral("PERF-BODY-%1 synthetic-search-token\n") | |
| 602 |
1/1✓ Branch 463 → 464 taken 1600 times.
|
1600 | .arg(marker); |
| 603 |
2/2✓ Branch 468 → 469 taken 400 times.
✓ Branch 468 → 479 taken 1200 times.
|
1600 | if (storedBodies % 4 == 0) { |
| 604 | body.textHtml = | ||
| 605 | 800 | QStringLiteral("<html><body><p>PERF-HTML-%1 " | |
| 606 | "synthetic-search-token</p></body></html>") | ||
| 607 |
1/1✓ Branch 473 → 474 taken 400 times.
|
800 | .arg(storedBodies); |
| 608 | } | ||
| 609 | 1600 | body.rawSource = QByteArrayLiteral("Synthetic fixture MIME source\r\n"); | |
| 610 | } | ||
| 611 | // S106-215: a failed write fails the generation instead of leaving a | ||
| 612 | // fixture with silently missing bodies or attachments. | ||
| 613 |
2/3✓ Branch 485 → 486 taken 1654 times.
✗ Branch 486 → 487 not taken.
✓ Branch 486 → 501 taken 1654 times.
|
1654 | if (!mail.storeBody(folderId, header.uid, body)) { |
| 614 | ✗ | if (error) | |
| 615 | ✗ | *error = QStringLiteral("Cannot store a fixture body: %1").arg(mail.lastError()); | |
| 616 | ✗ | return false; | |
| 617 | } | ||
| 618 |
2/2✓ Branch 501 → 502 taken 17 times.
✓ Branch 501 → 564 taken 1637 times.
|
1654 | if (header.hasAttachments) { |
| 619 | 17 | Attachment attachment; | |
| 620 | attachment.filename = | ||
| 621 |
1/1✓ Branch 506 → 507 taken 17 times.
|
34 | QStringLiteral("synthetic-%1.bin").arg(storedBodies); |
| 622 | 17 | attachment.contentType = QStringLiteral("application/octet-stream"); | |
| 623 | 17 | attachment.size = | |
| 624 |
2/2✓ Branch 521 → 522 taken 1 time.
✓ Branch 521 → 523 taken 16 times.
|
17 | profileName == QStringLiteral("large-body") ? 1024 * 1024 : 256; |
| 625 |
5/9✓ Branch 531 → 532 taken 17 times.
✓ Branch 534 → 535 taken 17 times.
✓ Branch 534 → 536 taken 17 times.
✓ Branch 538 → 539 taken 17 times.
✓ Branch 538 → 540 taken 17 times.
✗ Branch 2062 → 2063 not taken.
✗ Branch 2062 → 2064 not taken.
✗ Branch 2075 → 2076 not taken.
✗ Branch 2075 → 2077 not taken.
|
68 | mail.attachments().storeAttachments(folderId, header.uid, {attachment}, |
| 626 | {random.bytes(attachment.size)}); | ||
| 627 |
2/3✓ Branch 540 → 541 taken 17 times.
✗ Branch 543 → 544 not taken.
✓ Branch 543 → 558 taken 17 times.
|
17 | if (!mail.lastError().isEmpty()) { |
| 628 | ✗ | if (error) | |
| 629 | ✗ | *error = QStringLiteral("Cannot store a fixture attachment: %1").arg(mail.lastError()); | |
| 630 | ✗ | return false; | |
| 631 | } | ||
| 632 | 17 | } | |
| 633 | 106054 | } | |
| 634 | 174 | } | |
| 635 | 75 | } | |
| 636 |
5/7✓ Branch 592 → 593 taken 9 times.
✓ Branch 592 → 597 taken 20 times.
✓ Branch 594 → 595 taken 9 times.
✗ Branch 595 → 596 not taken.
✓ Branch 595 → 597 taken 9 times.
✗ Branch 598 → 599 not taken.
✓ Branch 598 → 608 taken 29 times.
|
29 | if (spec.headers > 0 && !mail.search().rebuildSearchIndex()) { |
| 637 | ✗ | if (error) | |
| 638 | ✗ | *error = QStringLiteral("Cannot build deterministic FTS index"); | |
| 639 | ✗ | return false; | |
| 640 | } | ||
| 641 |
1/1✓ Branch 608 → 609 taken 29 times.
|
29 | mail.close(); |
| 642 | |||
| 643 |
1/1✓ Branch 609 → 610 taken 29 times.
|
29 | CalendarStore calendar; |
| 644 |
1/1✓ Branch 615 → 616 taken 29 times.
|
29 | if (!calendar.open( |
| 645 |
3/4✓ Branch 610 → 611 taken 29 times.
✓ Branch 614 → 615 taken 29 times.
✗ Branch 620 → 621 not taken.
✓ Branch 620 → 630 taken 29 times.
|
87 | QDir(directory).filePath(QStringLiteral("calendar.sqlite")))) { |
| 646 | ✗ | if (error) | |
| 647 | ✗ | *error = QStringLiteral("Cannot open generated calendar database"); | |
| 648 | ✗ | return false; | |
| 649 | } | ||
| 650 |
1/2✗ Branch 631 → 632 not taken.
✓ Branch 631 → 634 taken 23 times.
|
23 | const int calendarCount = spec.events == 0 && spec.tasks == 0 |
| 651 |
2/2✓ Branch 630 → 631 taken 23 times.
✓ Branch 630 → 632 taken 6 times.
|
52 | ? 0 |
| 652 |
1/1✓ Branch 632 → 633 taken 6 times.
|
6 | : std::clamp(spec.folders / 6, 1, 10); |
| 653 |
1/1✓ Branch 635 → 636 taken 29 times.
|
29 | const QStringList calendarPalette = ThemeManager::calendarPalette(); |
| 654 |
2/2✓ Branch 674 → 637 taken 12 times.
✓ Branch 674 → 675 taken 29 times.
|
41 | for (int i = 0; i < calendarCount; ++i) { |
| 655 | 12 | CalendarInfo info; | |
| 656 |
1/1✓ Branch 641 → 642 taken 12 times.
|
24 | info.path = QStringLiteral("/performance/calendar-%1/").arg(i + 1); |
| 657 |
1/1✓ Branch 647 → 648 taken 12 times.
|
12 | info.accountId = QString::fromLatin1(AccountId); |
| 658 |
1/1✓ Branch 654 → 655 taken 12 times.
|
24 | info.displayName = QStringLiteral("Synthetic calendar %1").arg(i + 1); |
| 659 | 12 | info.color = calendarPalette.at(i % calendarPalette.size()); | |
| 660 |
1/1✓ Branch 666 → 667 taken 12 times.
|
24 | info.ctag = QStringLiteral("ctag-%1").arg(i + 1); |
| 661 |
1/1✓ Branch 671 → 672 taken 12 times.
|
12 | calendar.upsertCalendar(info, info.accountId); |
| 662 | 12 | } | |
| 663 |
2/2✓ Branch 675 → 676 taken 6 times.
✓ Branch 675 → 677 taken 23 times.
|
29 | if (calendarCount > 0) |
| 664 |
1/1✓ Branch 676 → 677 taken 6 times.
|
6 | calendar.beginTransaction(); |
| 665 |
2/2✓ Branch 766 → 678 taken 600 times.
✓ Branch 766 → 767 taken 29 times.
|
629 | for (int i = 0; i < spec.events; ++i) { |
| 666 | 600 | CalendarEvent event; | |
| 667 |
1/1✓ Branch 683 → 684 taken 600 times.
|
1200 | event.uid = QStringLiteral("event-%1@example.invalid").arg(i + 1); |
| 668 |
1/1✓ Branch 689 → 690 taken 600 times.
|
600 | event.accountId = QString::fromLatin1(AccountId); |
| 669 | event.calendarPath = | ||
| 670 |
1/1✓ Branch 696 → 697 taken 600 times.
|
1200 | QStringLiteral("/performance/calendar-%1/").arg(i % calendarCount + 1); |
| 671 | event.resourceHref = | ||
| 672 |
2/2✓ Branch 704 → 705 taken 600 times.
✓ Branch 705 → 706 taken 600 times.
|
600 | event.calendarPath + event.uid + QStringLiteral(".ics"); |
| 673 |
1/1✓ Branch 715 → 716 taken 600 times.
|
1200 | event.summary = QStringLiteral("Synthetic event %1").arg(i + 1); |
| 674 | 600 | event.description = QStringLiteral("Synthetic performance fixture"); | |
| 675 | 600 | event.location = QStringLiteral("Synthetic location"); | |
| 676 |
1/1✓ Branch 732 → 733 taken 600 times.
|
600 | event.dtStart = epoch.addSecs((i % 365) * 86400 + (i % 12) * 1800); |
| 677 |
1/1✓ Branch 735 → 736 taken 600 times.
|
600 | event.dtEnd = event.dtStart.addSecs(1800 + (i % 4) * 1800); |
| 678 | 600 | event.allDay = i % 17 == 0; | |
| 679 |
2/2✓ Branch 738 → 739 taken 90 times.
✓ Branch 738 → 746 taken 510 times.
|
600 | if (i % 7 == 0) |
| 680 | 90 | event.rrule = QStringLiteral("FREQ=WEEKLY;COUNT=12"); | |
| 681 |
2/2✓ Branch 746 → 747 taken 18 times.
✓ Branch 746 → 753 taken 582 times.
|
600 | if (i % 35 == 0) |
| 682 |
2/4✓ Branch 750 → 751 taken 18 times.
✓ Branch 750 → 752 taken 18 times.
✗ Branch 2195 → 2196 not taken.
✗ Branch 2195 → 2197 not taken.
|
36 | event.exdates = {event.dtStart.addDays(7)}; |
| 683 |
1/1✓ Branch 757 → 758 taken 600 times.
|
1200 | event.etag = QStringLiteral("event-etag-%1").arg(i + 1); |
| 684 | 600 | event.lastModified = epoch; | |
| 685 |
1/1✓ Branch 763 → 764 taken 600 times.
|
600 | calendar.upsertEvent(event); |
| 686 | 600 | } | |
| 687 |
2/2✓ Branch 858 → 768 taken 300 times.
✓ Branch 858 → 859 taken 29 times.
|
329 | for (int i = 0; i < spec.tasks; ++i) { |
| 688 | 300 | CalendarTask task; | |
| 689 |
1/1✓ Branch 773 → 774 taken 300 times.
|
600 | task.uid = QStringLiteral("task-%1@example.invalid").arg(i + 1); |
| 690 |
1/1✓ Branch 779 → 780 taken 300 times.
|
300 | task.accountId = QString::fromLatin1(AccountId); |
| 691 | task.calendarPath = | ||
| 692 |
1/1✓ Branch 786 → 787 taken 300 times.
|
600 | QStringLiteral("/performance/calendar-%1/").arg(i % calendarCount + 1); |
| 693 |
2/2✓ Branch 794 → 795 taken 300 times.
✓ Branch 795 → 796 taken 300 times.
|
300 | task.resourceHref = task.calendarPath + task.uid + QStringLiteral(".ics"); |
| 694 |
1/1✓ Branch 805 → 806 taken 300 times.
|
600 | task.summary = QStringLiteral("Synthetic task %1").arg(i + 1); |
| 695 | 300 | task.description = QStringLiteral("Synthetic performance fixture"); | |
| 696 |
1/1✓ Branch 816 → 817 taken 300 times.
|
300 | task.dtStart = epoch.addDays(i % 30); |
| 697 |
1/1✓ Branch 819 → 820 taken 300 times.
|
300 | task.due = epoch.addDays((i % 120) - 30); |
| 698 | 300 | task.dueAllDay = i % 5 == 0; | |
| 699 | 300 | task.priority = i % 10; | |
| 700 |
2/2✓ Branch 822 → 823 taken 78 times.
✓ Branch 822 → 826 taken 222 times.
|
1200 | task.status = i % 4 == 0 ? QStringLiteral("COMPLETED") |
| 701 |
4/4✓ Branch 831 → 832 taken 222 times.
✓ Branch 831 → 833 taken 78 times.
✓ Branch 833 → 834 taken 78 times.
✓ Branch 833 → 835 taken 222 times.
|
600 | : QStringLiteral("NEEDS-ACTION"); |
| 702 |
2/2✓ Branch 839 → 840 taken 78 times.
✓ Branch 839 → 841 taken 222 times.
|
300 | task.percentComplete = task.status == QStringLiteral("COMPLETED") ? 100 : 0; |
| 703 | 300 | task.created = epoch; | |
| 704 | 300 | task.lastModified = epoch; | |
| 705 |
1/1✓ Branch 850 → 851 taken 300 times.
|
600 | task.etag = QStringLiteral("task-etag-%1").arg(i + 1); |
| 706 |
1/1✓ Branch 855 → 856 taken 300 times.
|
300 | calendar.upsertTask(task); |
| 707 | 300 | } | |
| 708 |
2/2✓ Branch 859 → 860 taken 6 times.
✓ Branch 859 → 861 taken 23 times.
|
29 | if (calendarCount > 0) |
| 709 |
1/1✓ Branch 860 → 861 taken 6 times.
|
6 | calendar.commitTransaction(); |
| 710 |
1/1✓ Branch 861 → 862 taken 29 times.
|
29 | calendar.close(); |
| 711 | |||
| 712 |
1/1✓ Branch 862 → 863 taken 29 times.
|
29 | ContactStore contacts; |
| 713 |
1/1✓ Branch 868 → 869 taken 29 times.
|
29 | if (!contacts.open( |
| 714 |
3/4✓ Branch 863 → 864 taken 29 times.
✓ Branch 867 → 868 taken 29 times.
✗ Branch 873 → 874 not taken.
✓ Branch 873 → 883 taken 29 times.
|
87 | QDir(directory).filePath(QStringLiteral("contacts.sqlite")))) { |
| 715 | ✗ | if (error) | |
| 716 | ✗ | *error = QStringLiteral("Cannot open generated contacts database"); | |
| 717 | ✗ | return false; | |
| 718 | } | ||
| 719 |
4/15✗ Branch 887 → 888 not taken.
✓ Branch 887 → 891 taken 29 times.
✗ Branch 888 → 889 not taken.
✗ Branch 889 → 890 not taken.
✗ Branch 889 → 891 not taken.
✓ Branch 892 → 893 taken 29 times.
✗ Branch 892 → 894 not taken.
✓ Branch 894 → 895 taken 29 times.
✗ Branch 894 → 896 not taken.
✗ Branch 896 → 897 not taken.
✓ Branch 896 → 898 taken 29 times.
✗ Branch 2276 → 2277 not taken.
✗ Branch 2276 → 2278 not taken.
✗ Branch 2280 → 2281 not taken.
✗ Branch 2280 → 2282 not taken.
|
58 | if (profileName == QStringLiteral("contacts-showcase") && !ContactShowcase::seed(contacts, error)) |
| 720 | ✗ | return false; | |
| 721 | // Sprint 97: one card per person; every third contact lives in a | ||
| 722 | // CardDAV-like book, the rest on this computer; usage feeds the ranking. | ||
| 723 |
1/1✓ Branch 904 → 905 taken 29 times.
|
58 | const qint64 remoteBook = contacts.ensureBook(QStringLiteral("fixture"), QStringLiteral("/dav/addressbooks/fixture/")); |
| 724 |
1/1✓ Branch 909 → 910 taken 29 times.
|
29 | contacts.beginTransaction(); |
| 725 |
7/10✓ Branch 1117 → 1118 taken 20629 times.
✗ Branch 1117 → 1120 not taken.
✓ Branch 1118 → 1119 taken 20600 times.
✓ Branch 1118 → 1120 taken 29 times.
✓ Branch 1121 → 1122 taken 20629 times.
✗ Branch 1121 → 1123 not taken.
✓ Branch 1123 → 1124 taken 20629 times.
✗ Branch 1123 → 1125 not taken.
✓ Branch 1125 → 911 taken 20600 times.
✓ Branch 1125 → 1126 taken 29 times.
|
41258 | for (int i = 0; profileName != QStringLiteral("contacts-showcase") && i < spec.contacts; ++i) { |
| 726 |
1/1✓ Branch 911 → 912 taken 20600 times.
|
20600 | ContactCard card; |
| 727 |
2/2✓ Branch 918 → 919 taken 20000 times.
✓ Branch 918 → 986 taken 600 times.
|
20600 | if (profileName == QStringLiteral("contact-dense")) { |
| 728 | static const QStringList collisionNames = { | ||
| 729 |
1/1✓ Branch 926 → 927 taken 1 time.
|
2 | QString(QChar(0x00c4)) + QStringLiteral("nne Alpha"), |
| 730 |
1/1✓ Branch 932 → 933 taken 1 time.
|
2 | QString(QChar(0x00e4)) + QStringLiteral("nne alpha"), |
| 731 | 1 | QStringLiteral("ANNE ALPHA"), | |
| 732 |
1/1✓ Branch 944 → 945 taken 1 time.
|
3 | QStringLiteral("M") + QChar(0x00fc) + QStringLiteral("ller, Zoe"), |
| 733 |
5/10✓ Branch 919 → 920 taken 1 time.
✓ Branch 919 → 969 taken 19999 times.
✓ Branch 921 → 922 taken 1 time.
✗ Branch 921 → 969 not taken.
✓ Branch 953 → 954 taken 5 times.
✓ Branch 953 → 955 taken 1 time.
✗ Branch 2297 → 2298 not taken.
✗ Branch 2297 → 2299 not taken.
✗ Branch 2348 → 2349 not taken.
✗ Branch 2348 → 2350 not taken.
|
20007 | QStringLiteral("Muller, Zoe")}; |
| 734 | card.formattedName = | ||
| 735 | 40000 | QStringLiteral("%1 %2") | |
| 736 |
1/1✓ Branch 975 → 976 taken 20000 times.
|
40000 | .arg(collisionNames.at(i % collisionNames.size())) |
| 737 |
1/1✓ Branch 979 → 980 taken 20000 times.
|
40000 | .arg(i / collisionNames.size(), 5, 10, QLatin1Char('0')); |
| 738 | } else { | ||
| 739 |
1/1✓ Branch 991 → 992 taken 600 times.
|
600 | card.formattedName = QStringLiteral("Synthetic Contact %1").arg(i + 1, 7, 10, QLatin1Char('0')); |
| 740 | } | ||
| 741 |
1/1✓ Branch 1001 → 1002 taken 20600 times.
|
41200 | card.uid = QStringLiteral("contact-uid-%1").arg(i + 1); |
| 742 | 20600 | ContactValue address; | |
| 743 |
1/1✓ Branch 1010 → 1011 taken 20600 times.
|
41200 | address.value = QStringLiteral("contact-%1@example.invalid").arg(i + 1); |
| 744 |
2/4✓ Branch 1018 → 1019 taken 20600 times.
✓ Branch 1018 → 1020 taken 20600 times.
✗ Branch 2390 → 2391 not taken.
✗ Branch 2390 → 2392 not taken.
|
41200 | card.emails = {address}; |
| 745 | 20600 | bool stored = false; | |
| 746 |
2/2✓ Branch 1020 → 1021 taken 6871 times.
✓ Branch 1020 → 1054 taken 13729 times.
|
20600 | if (i % 3 == 0) { |
| 747 | 6871 | StoredCard remote; | |
| 748 | 6871 | remote.bookId = remoteBook; | |
| 749 | 6871 | remote.uid = card.uid; | |
| 750 |
1/1✓ Branch 1026 → 1027 taken 6871 times.
|
13742 | remote.href = QStringLiteral("/dav/addressbooks/fixture/%1.vcf").arg(card.uid); |
| 751 |
1/1✓ Branch 1035 → 1036 taken 6871 times.
|
13742 | remote.etag = QStringLiteral("\"contact-etag-%1\"").arg(i + 1); |
| 752 |
1/1✓ Branch 1044 → 1045 taken 6871 times.
|
13742 | remote.raw = VCardCodec::create(card); |
| 753 | 6871 | remote.baseRaw = remote.raw; | |
| 754 |
1/1✓ Branch 1051 → 1052 taken 6871 times.
|
6871 | stored = contacts.putCard(remote) > 0; |
| 755 | 6871 | } else { | |
| 756 |
1/1✓ Branch 1054 → 1055 taken 13729 times.
|
13729 | stored = contacts.addLocalCard(card) > 0; |
| 757 | } | ||
| 758 |
2/2✓ Branch 1056 → 1057 taken 20600 times.
✓ Branch 1057 → 1058 taken 20600 times.
|
20600 | QSqlQuery usage(contacts.database()); |
| 759 |
1/1✓ Branch 1062 → 1063 taken 20600 times.
|
20600 | usage.prepare(QStringLiteral("INSERT OR REPLACE INTO address_usage (address_key, use_count, last_used) VALUES (?, ?, ?)")); |
| 760 |
1/1✓ Branch 1067 → 1068 taken 20600 times.
|
20600 | usage.addBindValue(address.value); |
| 761 |
1/1✓ Branch 1071 → 1072 taken 20600 times.
|
20600 | usage.addBindValue(i % 101); |
| 762 |
3/3✓ Branch 1074 → 1075 taken 20600 times.
✓ Branch 1075 → 1076 taken 20600 times.
✓ Branch 1077 → 1078 taken 20600 times.
|
20600 | usage.addBindValue(epoch.addDays(-(i % 365)).toString(Qt::ISODate)); |
| 763 |
4/7✓ Branch 1081 → 1082 taken 20600 times.
✗ Branch 1081 → 1084 not taken.
✓ Branch 1082 → 1083 taken 20600 times.
✗ Branch 1083 → 1084 not taken.
✓ Branch 1083 → 1085 taken 20600 times.
✗ Branch 1086 → 1087 not taken.
✓ Branch 1086 → 1099 taken 20600 times.
|
20600 | if (!stored || !usage.exec()) { |
| 764 | ✗ | if (error) | |
| 765 | ✗ | *error = QStringLiteral("Cannot store synthetic contact %1").arg(i + 1); | |
| 766 | ✗ | return false; | |
| 767 | } | ||
| 768 | 20600 | } | |
| 769 |
1/1✓ Branch 1126 → 1127 taken 29 times.
|
29 | contacts.commitTransaction(); |
| 770 |
1/1✓ Branch 1127 → 1128 taken 29 times.
|
29 | contacts.close(); |
| 771 | |||
| 772 |
1/1✓ Branch 1128 → 1129 taken 29 times.
|
29 | QDir dir(directory); |
| 773 |
2/3✓ Branch 1132 → 1133 taken 29 times.
✗ Branch 1135 → 1136 not taken.
✓ Branch 1135 → 1145 taken 29 times.
|
29 | if (!dir.mkpath(QStringLiteral("payloads"))) { |
| 774 | ✗ | if (error) | |
| 775 | ✗ | *error = QStringLiteral("Cannot create payload directory"); | |
| 776 | ✗ | return false; | |
| 777 | } | ||
| 778 |
1/1✓ Branch 1145 → 1146 taken 29 times.
|
29 | const QByteArray smallPayload = random.bytes(4096); |
| 779 |
1/1✓ Branch 1146 → 1147 taken 29 times.
|
29 | const QByteArray largePayload = random.bytes(1024 * 1024); |
| 780 |
1/1✓ Branch 1147 → 1148 taken 29 times.
|
29 | const QByteArray pdfPayload = minimalPdf(); |
| 781 |
4/13✓ Branch 1151 → 1152 taken 29 times.
✓ Branch 1182 → 1183 taken 29 times.
✗ Branch 1182 → 1184 not taken.
✓ Branch 1184 → 1185 taken 29 times.
✗ Branch 1184 → 1186 not taken.
✗ Branch 1186 → 1187 not taken.
✓ Branch 1186 → 1188 taken 29 times.
✗ Branch 2500 → 2501 not taken.
✗ Branch 2500 → 2502 not taken.
✗ Branch 2504 → 2505 not taken.
✗ Branch 2504 → 2506 not taken.
✗ Branch 2508 → 2509 not taken.
✗ Branch 2508 → 2510 not taken.
|
58 | if (!writeBytes(dir.filePath(QStringLiteral("payloads/small.bin")), |
| 782 | 58 | smallPayload, error) || | |
| 783 |
6/16✓ Branch 1157 → 1158 taken 29 times.
✓ Branch 1158 → 1159 taken 29 times.
✓ Branch 1159 → 1160 taken 29 times.
✗ Branch 1159 → 1166 not taken.
✓ Branch 1176 → 1177 taken 29 times.
✗ Branch 1176 → 1178 not taken.
✓ Branch 1178 → 1179 taken 29 times.
✗ Branch 1178 → 1180 not taken.
✓ Branch 1180 → 1181 taken 29 times.
✗ Branch 1180 → 1182 not taken.
✗ Branch 2488 → 2489 not taken.
✗ Branch 2488 → 2490 not taken.
✗ Branch 2492 → 2493 not taken.
✗ Branch 2492 → 2494 not taken.
✗ Branch 2496 → 2497 not taken.
✗ Branch 2496 → 2498 not taken.
|
58 | !writeBytes(dir.filePath(QStringLiteral("payloads/large.bin")), |
| 784 |
2/3✓ Branch 1152 → 1153 taken 29 times.
✓ Branch 1153 → 1154 taken 29 times.
✗ Branch 1153 → 1166 not taken.
|
87 | largePayload, error) || |
| 785 |
7/18✓ Branch 1163 → 1164 taken 29 times.
✓ Branch 1164 → 1165 taken 29 times.
✗ Branch 1165 → 1166 not taken.
✓ Branch 1165 → 1167 taken 29 times.
✓ Branch 1168 → 1169 taken 29 times.
✗ Branch 1168 → 1170 not taken.
✓ Branch 1170 → 1171 taken 29 times.
✗ Branch 1170 → 1172 not taken.
✓ Branch 1172 → 1173 taken 29 times.
✗ Branch 1172 → 1174 not taken.
✓ Branch 1174 → 1175 taken 29 times.
✗ Branch 1174 → 1176 not taken.
✗ Branch 2476 → 2477 not taken.
✗ Branch 2476 → 2478 not taken.
✗ Branch 2480 → 2481 not taken.
✗ Branch 2480 → 2482 not taken.
✗ Branch 2484 → 2485 not taken.
✗ Branch 2484 → 2486 not taken.
|
58 | !writeBytes(dir.filePath(QStringLiteral("payloads/sample.pdf")), |
| 786 | pdfPayload, error)) | ||
| 787 | ✗ | return false; | |
| 788 | |||
| 789 |
1/1✓ Branch 1188 → 1189 taken 29 times.
|
29 | const QJsonObject workloads = workloadManifest(spec); |
| 790 |
4/13✓ Branch 1192 → 1193 taken 29 times.
✓ Branch 1201 → 1202 taken 29 times.
✗ Branch 1201 → 1203 not taken.
✓ Branch 1203 → 1204 taken 29 times.
✗ Branch 1203 → 1205 not taken.
✗ Branch 1205 → 1206 not taken.
✓ Branch 1205 → 1207 taken 29 times.
✗ Branch 2512 → 2513 not taken.
✗ Branch 2512 → 2514 not taken.
✗ Branch 2516 → 2517 not taken.
✗ Branch 2516 → 2518 not taken.
✗ Branch 2520 → 2521 not taken.
✗ Branch 2520 → 2522 not taken.
|
58 | if (!writeJson(dir.filePath(QStringLiteral("workloads.json")), workloads, |
| 791 |
3/5✓ Branch 1193 → 1194 taken 29 times.
✓ Branch 1194 → 1195 taken 29 times.
✗ Branch 1194 → 1197 not taken.
✓ Branch 1199 → 1200 taken 29 times.
✗ Branch 1199 → 1201 not taken.
|
87 | error) || |
| 792 |
2/3✓ Branch 1195 → 1196 taken 29 times.
✗ Branch 1196 → 1197 not taken.
✓ Branch 1196 → 1198 taken 29 times.
|
29 | !createMigrationSnapshots(directory, error)) |
| 793 | ✗ | return false; | |
| 794 | |||
| 795 | QJsonObject logical = { | ||
| 796 | 58 | {QStringLiteral("generator_schema_version"), GeneratorSchemaVersion}, | |
| 797 | 58 | {QStringLiteral("profile"), spec.name}, | |
| 798 | 58 | {QStringLiteral("seed"), static_cast<qint64>(seed)}, | |
| 799 | 58 | {QStringLiteral("database_schemas"), | |
| 800 | 58 | QJsonObject{{QStringLiteral("mail"), MailCache::SchemaVersion}, | |
| 801 | 58 | {QStringLiteral("calendar"), CalendarStore::SchemaVersion}, | |
| 802 |
2/4✓ Branch 1455 → 1456 taken 87 times.
✓ Branch 1455 → 1457 taken 29 times.
✗ Branch 2795 → 2796 not taken.
✗ Branch 2795 → 2797 not taken.
|
203 | {QStringLiteral("contacts"), QStringLiteral("current")}}}, |
| 803 | 58 | {QStringLiteral("counts"), | |
| 804 | 58 | QJsonObject{{QStringLiteral("folders"), spec.folders}, | |
| 805 | 58 | {QStringLiteral("headers"), spec.headers}, | |
| 806 | 58 | {QStringLiteral("cached_bodies"), spec.bodies}, | |
| 807 | 58 | {QStringLiteral("events"), spec.events}, | |
| 808 | 58 | {QStringLiteral("tasks"), spec.tasks}, | |
| 809 |
2/4✓ Branch 1437 → 1438 taken 174 times.
✓ Branch 1437 → 1439 taken 29 times.
✗ Branch 2740 → 2741 not taken.
✗ Branch 2740 → 2742 not taken.
|
261 | {QStringLiteral("contacts"), spec.contacts}}}, |
| 810 | 58 | {QStringLiteral("known_markers"), | |
| 811 | 87 | QJsonObject{{QStringLiteral("mail_body"), QStringLiteral("PERF-BODY-1")}, | |
| 812 | 87 | {QStringLiteral("html_body"), QStringLiteral("PERF-HTML-4")}, | |
| 813 | 58 | {QStringLiteral("search"), | |
| 814 |
2/4✓ Branch 1419 → 1420 taken 87 times.
✓ Branch 1419 → 1421 taken 29 times.
✗ Branch 2685 → 2686 not taken.
✗ Branch 2685 → 2687 not taken.
|
174 | QStringLiteral("synthetic-search-token")}}}, |
| 815 | 58 | {QStringLiteral("cache_contract"), | |
| 816 | ✗ | QJsonObject{ | |
| 817 | 58 | {QStringLiteral("body_hit_count"), spec.bodies}, | |
| 818 | 58 | {QStringLiteral("body_miss_count"), spec.headers - spec.bodies}, | |
| 819 | 58 | {QStringLiteral("known_body_hits"), bodyHitIdentities}, | |
| 820 |
2/4✓ Branch 1405 → 1406 taken 116 times.
✓ Branch 1405 → 1407 taken 29 times.
✗ Branch 2641 → 2642 not taken.
✗ Branch 2641 → 2643 not taken.
|
203 | {QStringLiteral("known_body_misses"), bodyMissIdentities}}}, |
| 821 | 58 | {QStringLiteral("payloads"), | |
| 822 | 58 | QJsonObject{{QStringLiteral("small_sha256"), | |
| 823 |
2/2✓ Branch 1321 → 1322 taken 29 times.
✓ Branch 1322 → 1323 taken 29 times.
|
58 | QString::fromLatin1(sha256(smallPayload))}, |
| 824 | 58 | {QStringLiteral("large_sha256"), | |
| 825 |
2/2✓ Branch 1327 → 1328 taken 29 times.
✓ Branch 1328 → 1329 taken 29 times.
|
58 | QString::fromLatin1(sha256(largePayload))}, |
| 826 | 58 | {QStringLiteral("pdf_sha256"), | |
| 827 |
4/6✓ Branch 1333 → 1334 taken 29 times.
✓ Branch 1334 → 1335 taken 29 times.
✓ Branch 1387 → 1388 taken 87 times.
✓ Branch 1387 → 1389 taken 29 times.
✗ Branch 2586 → 2587 not taken.
✗ Branch 2586 → 2588 not taken.
|
174 | QString::fromLatin1(sha256(pdfPayload))}}}, |
| 828 | 58 | {QStringLiteral("workload_sha256"), | |
| 829 |
1/1✓ Branch 1344 → 1345 taken 29 times.
|
29 | QString::fromLatin1( |
| 830 |
3/3✓ Branch 1341 → 1342 taken 29 times.
✓ Branch 1342 → 1343 taken 29 times.
✓ Branch 1343 → 1344 taken 29 times.
|
58 | sha256(QJsonDocument(workloads).toJson(QJsonDocument::Compact)))}, |
| 831 | 58 | {QStringLiteral("migration_snapshots"), | |
| 832 | 116 | QJsonArray{QStringLiteral("mail-v16"), QStringLiteral("calendar-v4"), | |
| 833 |
2/4✓ Branch 1369 → 1370 taken 87 times.
✓ Branch 1369 → 1371 taken 29 times.
✗ Branch 2531 → 2532 not taken.
✗ Branch 2531 → 2533 not taken.
|
174 | QStringLiteral("contacts-legacy")}}, |
| 834 |
2/4✓ Branch 1365 → 1366 taken 290 times.
✓ Branch 1365 → 1367 taken 29 times.
✗ Branch 2525 → 2526 not taken.
✗ Branch 2525 → 2527 not taken.
|
319 | }; |
| 835 |
2/2✓ Branch 1473 → 1474 taken 1 time.
✓ Branch 1473 → 1534 taken 28 times.
|
29 | if (streamHeaders) { |
| 836 |
2/2✓ Branch 1474 → 1475 taken 1 time.
✓ Branch 1478 → 1479 taken 1 time.
|
2 | logical.insert(QStringLiteral("setup_header_batch_limit"), 1000); |
| 837 |
1/1✓ Branch 1512 → 1513 taken 1 time.
|
2 | logical.insert(QStringLiteral("last_header_identity"), |
| 838 |
1/1✓ Branch 1486 → 1487 taken 1 time.
|
3 | QJsonObject{{QStringLiteral("account"), QString::fromLatin1(AccountId)}, |
| 839 |
1/1✓ Branch 1491 → 1492 taken 1 time.
|
2 | {QStringLiteral("folder"), folderName(spec.folders - 1)}, |
| 840 | 2 | {QStringLiteral("uid"), spec.headers / spec.folders}, | |
| 841 |
3/5✓ Branch 1505 → 1506 taken 1 time.
✓ Branch 1518 → 1519 taken 4 times.
✓ Branch 1518 → 1520 taken 1 time.
✗ Branch 2880 → 2881 not taken.
✗ Branch 2880 → 2882 not taken.
|
8 | {QStringLiteral("subject"), QStringLiteral("Synthetic mail %1").arg(spec.headers, 7, 10, QLatin1Char('0'))}}); |
| 842 | } | ||
| 843 |
2/2✓ Branch 1536 → 1537 taken 1 time.
✓ Branch 1536 → 1617 taken 28 times.
|
29 | if (profileName == QLatin1String("thread-dense")) { |
| 844 |
2/2✓ Branch 1540 → 1541 taken 1 time.
✓ Branch 1541 → 1542 taken 1 time.
|
1 | QSaveFile oracle(dir.filePath(QStringLiteral("thread-oracle.jsonl"))); |
| 845 |
2/3✓ Branch 1546 → 1547 taken 1 time.
✗ Branch 1547 → 1548 not taken.
✓ Branch 1547 → 1557 taken 1 time.
|
1 | if (!oracle.open(QIODevice::WriteOnly)) { |
| 846 | ✗ | if (error) | |
| 847 | ✗ | *error = QStringLiteral("Cannot open thread oracle"); | |
| 848 | ✗ | return false; | |
| 849 | } | ||
| 850 |
2/2✓ Branch 1599 → 1558 taken 100000 times.
✓ Branch 1599 → 1600 taken 1 time.
|
100001 | for (qint64 uid = 1; uid <= spec.headers; ++uid) { |
| 851 | 100000 | const auto row = QJsonDocument(QJsonObject{ | |
| 852 | 200000 | {QStringLiteral("uid"), uid}, | |
| 853 |
5/7✓ Branch 1568 → 1569 taken 100000 times.
✓ Branch 1569 → 1570 taken 100000 times.
✓ Branch 1570 → 1571 taken 100000 times.
✓ Branch 1575 → 1576 taken 200000 times.
✓ Branch 1575 → 1577 taken 100000 times.
✗ Branch 2951 → 2952 not taken.
✗ Branch 2951 → 2953 not taken.
|
500000 | {QStringLiteral("parent_uid"), threadFixtureParent(uid)}}).toJson(QJsonDocument::Compact) + '\n'; |
| 854 |
2/3✓ Branch 1581 → 1582 taken 100000 times.
✗ Branch 1583 → 1584 not taken.
✓ Branch 1583 → 1593 taken 100000 times.
|
100000 | if (oracle.write(row) != row.size()) { |
| 855 | ✗ | if (error) | |
| 856 | ✗ | *error = QStringLiteral("Cannot write thread oracle"); | |
| 857 | ✗ | return false; | |
| 858 | } | ||
| 859 | 100000 | } | |
| 860 |
2/3✓ Branch 1600 → 1601 taken 1 time.
✗ Branch 1601 → 1602 not taken.
✓ Branch 1601 → 1611 taken 1 time.
|
1 | if (!oracle.commit()) { |
| 861 | ✗ | if (error) | |
| 862 | ✗ | *error = QStringLiteral("Cannot publish thread oracle"); | |
| 863 | ✗ | return false; | |
| 864 | } | ||
| 865 | 1 | } | |
| 866 |
1/1✓ Branch 1617 → 1618 taken 29 times.
|
29 | const QJsonObject artifacts = artifactManifest(directory); |
| 867 | const QJsonObject manifest = { | ||
| 868 | 58 | {QStringLiteral("schema_version"), GeneratorSchemaVersion}, | |
| 869 | 58 | {QStringLiteral("logical"), logical}, | |
| 870 | 58 | {QStringLiteral("logical_sha256"), | |
| 871 |
2/2✓ Branch 1629 → 1630 taken 29 times.
✓ Branch 1630 → 1631 taken 29 times.
|
58 | QString::fromLatin1(logicalChecksum(logical))}, |
| 872 | 58 | {QStringLiteral("artifacts"), artifacts}, | |
| 873 | 58 | {QStringLiteral("generation_duration_ns"), | |
| 874 | 29 | generationTimer.nsecsElapsed()}, | |
| 875 |
1/1✓ Branch 1644 → 1645 taken 29 times.
|
58 | {QStringLiteral("disk_bytes"), artifactBytes(artifacts)}, |
| 876 |
2/4✓ Branch 1648 → 1649 taken 174 times.
✓ Branch 1648 → 1650 taken 29 times.
✗ Branch 2984 → 2985 not taken.
✗ Branch 2984 → 2986 not taken.
|
232 | }; |
| 877 |
3/4✓ Branch 1667 → 1668 taken 29 times.
✓ Branch 1668 → 1669 taken 29 times.
✗ Branch 1672 → 1673 not taken.
✓ Branch 1672 → 1674 taken 29 times.
|
29 | if (!writeJson(dir.filePath(QStringLiteral("manifest.json")), manifest, |
| 878 | error)) | ||
| 879 | ✗ | return false; | |
| 880 |
1/1✓ Branch 1674 → 1675 taken 29 times.
|
29 | return verify(directory, error); |
| 881 | 982588 | } | |
| 882 | |||
| 883 | 77 | bool FixtureGenerator::verify(const QString &profileDirectory, | |
| 884 | QString *error) const { | ||
| 885 |
1/1✓ Branch 2 → 3 taken 77 times.
|
77 | QDir dir(profileDirectory); |
| 886 |
2/2✓ Branch 6 → 7 taken 77 times.
✓ Branch 7 → 8 taken 77 times.
|
77 | QFile manifestFile(dir.filePath(QStringLiteral("manifest.json"))); |
| 887 |
3/3✓ Branch 12 → 13 taken 77 times.
✓ Branch 13 → 14 taken 2 times.
✓ Branch 13 → 23 taken 75 times.
|
77 | if (!manifestFile.open(QIODevice::ReadOnly)) { |
| 888 |
2/2✓ Branch 14 → 15 taken 1 time.
✓ Branch 14 → 22 taken 1 time.
|
2 | if (error) |
| 889 | 1 | *error = QStringLiteral("Fixture manifest is missing"); | |
| 890 | 2 | return false; | |
| 891 | } | ||
| 892 | 75 | QJsonParseError parseError; | |
| 893 | const QJsonDocument document = | ||
| 894 |
2/2✓ Branch 23 → 24 taken 75 times.
✓ Branch 24 → 25 taken 75 times.
|
75 | QJsonDocument::fromJson(manifestFile.readAll(), &parseError); |
| 895 |
6/7✓ Branch 26 → 27 taken 73 times.
✓ Branch 26 → 29 taken 2 times.
✓ Branch 27 → 28 taken 73 times.
✗ Branch 28 → 29 not taken.
✓ Branch 28 → 30 taken 73 times.
✓ Branch 31 → 32 taken 2 times.
✓ Branch 31 → 41 taken 73 times.
|
75 | if (parseError.error != QJsonParseError::NoError || !document.isObject()) { |
| 896 |
2/2✓ Branch 32 → 33 taken 1 time.
✓ Branch 32 → 40 taken 1 time.
|
2 | if (error) |
| 897 | 1 | *error = QStringLiteral("Fixture manifest is malformed"); | |
| 898 | 2 | return false; | |
| 899 | } | ||
| 900 |
1/1✓ Branch 41 → 42 taken 73 times.
|
73 | const QJsonObject manifest = document.object(); |
| 901 |
4/4✓ Branch 45 → 46 taken 73 times.
✓ Branch 46 → 47 taken 73 times.
✓ Branch 50 → 51 taken 2 times.
✓ Branch 50 → 60 taken 71 times.
|
73 | if (manifest.value(QStringLiteral("schema_version")).toInt() != |
| 902 | GeneratorSchemaVersion) { | ||
| 903 |
2/2✓ Branch 51 → 52 taken 1 time.
✓ Branch 51 → 59 taken 1 time.
|
2 | if (error) |
| 904 | 1 | *error = QStringLiteral("Fixture schema version is stale or unknown"); | |
| 905 | 2 | return false; | |
| 906 | } | ||
| 907 | const QJsonObject logical = | ||
| 908 |
2/2✓ Branch 63 → 64 taken 71 times.
✓ Branch 64 → 65 taken 71 times.
|
71 | manifest.value(QStringLiteral("logical")).toObject(); |
| 909 |
2/2✓ Branch 73 → 74 taken 71 times.
✓ Branch 74 → 75 taken 71 times.
|
142 | if (QString::fromLatin1(logicalChecksum(logical)) != |
| 910 |
4/4✓ Branch 71 → 72 taken 71 times.
✓ Branch 72 → 73 taken 71 times.
✓ Branch 82 → 83 taken 2 times.
✓ Branch 82 → 92 taken 69 times.
|
213 | manifest.value(QStringLiteral("logical_sha256")).toString()) { |
| 911 |
2/2✓ Branch 83 → 84 taken 1 time.
✓ Branch 83 → 91 taken 1 time.
|
2 | if (error) |
| 912 | 1 | *error = QStringLiteral("Fixture logical checksum does not match"); | |
| 913 | 2 | return false; | |
| 914 | } | ||
| 915 | const FixtureProfile spec = | ||
| 916 |
3/3✓ Branch 95 → 96 taken 69 times.
✓ Branch 96 → 97 taken 69 times.
✓ Branch 97 → 98 taken 69 times.
|
69 | profile(logical.value(QStringLiteral("profile")).toString()); |
| 917 |
3/3✓ Branch 102 → 103 taken 69 times.
✓ Branch 105 → 106 taken 2 times.
✓ Branch 105 → 115 taken 67 times.
|
69 | if (!profileNames().contains(spec.name)) { |
| 918 |
2/2✓ Branch 106 → 107 taken 1 time.
✓ Branch 106 → 114 taken 1 time.
|
2 | if (error) |
| 919 | 1 | *error = QStringLiteral("Fixture profile is unknown"); | |
| 920 | 2 | return false; | |
| 921 | } | ||
| 922 | const QJsonObject artifacts = | ||
| 923 |
2/2✓ Branch 118 → 119 taken 67 times.
✓ Branch 119 → 120 taken 67 times.
|
67 | manifest.value(QStringLiteral("artifacts")).toObject(); |
| 924 | const QStringList requiredArtifacts = { | ||
| 925 | ✗ | QStringLiteral("mail.sqlite"), | |
| 926 | 67 | QStringLiteral("calendar.sqlite"), | |
| 927 | 67 | QStringLiteral("contacts.sqlite"), | |
| 928 | 67 | QStringLiteral("workloads.json"), | |
| 929 | 67 | QStringLiteral("payloads/small.bin"), | |
| 930 | 67 | QStringLiteral("payloads/large.bin"), | |
| 931 | 67 | QStringLiteral("payloads/sample.pdf"), | |
| 932 | 67 | QStringLiteral("migrations/mail-v16.sqlite"), | |
| 933 | 67 | QStringLiteral("migrations/calendar-v4.sqlite"), | |
| 934 | 67 | QStringLiteral("migrations/contacts-legacy.sqlite"), | |
| 935 |
2/4✓ Branch 155 → 156 taken 670 times.
✓ Branch 155 → 157 taken 67 times.
✗ Branch 534 → 535 not taken.
✗ Branch 534 → 536 not taken.
|
737 | }; |
| 936 |
2/2✓ Branch 186 → 169 taken 667 times.
✓ Branch 186 → 187 taken 66 times.
|
733 | for (const QString &required : requiredArtifacts) { |
| 937 |
3/3✓ Branch 170 → 171 taken 667 times.
✓ Branch 171 → 172 taken 1 time.
✓ Branch 171 → 184 taken 666 times.
|
667 | if (!artifacts.contains(required)) { |
| 938 |
1/2✓ Branch 172 → 173 taken 1 time.
✗ Branch 172 → 183 not taken.
|
1 | if (error) |
| 939 | *error = | ||
| 940 | 2 | QStringLiteral("Fixture artifact is absent from the manifest: %1") | |
| 941 |
1/1✓ Branch 177 → 178 taken 1 time.
|
2 | .arg(required); |
| 942 | 1 | return false; | |
| 943 | } | ||
| 944 | } | ||
| 945 |
3/3✓ Branch 261 → 262 taken 676 times.
✓ Branch 263 → 188 taken 618 times.
✓ Branch 263 → 264 taken 58 times.
|
676 | for (auto it = artifacts.constBegin(); it != artifacts.constEnd(); ++it) { |
| 946 |
2/2✓ Branch 188 → 189 taken 618 times.
✓ Branch 189 → 190 taken 618 times.
|
618 | const QString path = dir.filePath(it.key()); |
| 947 |
1/1✓ Branch 192 → 193 taken 618 times.
|
618 | const QJsonObject expected = it.value().toObject(); |
| 948 |
1/1✓ Branch 193 → 194 taken 618 times.
|
618 | QFileInfo info(path); |
| 949 | 3086 | if (!info.isFile() || | |
| 950 |
14/20✓ Branch 194 → 195 taken 618 times.
✓ Branch 195 → 196 taken 616 times.
✓ Branch 195 → 212 taken 2 times.
✓ Branch 196 → 197 taken 616 times.
✓ Branch 200 → 201 taken 616 times.
✓ Branch 201 → 202 taken 616 times.
✓ Branch 202 → 203 taken 612 times.
✓ Branch 202 → 212 taken 4 times.
✓ Branch 228 → 229 taken 616 times.
✓ Branch 228 → 230 taken 2 times.
✓ Branch 230 → 231 taken 616 times.
✓ Branch 230 → 232 taken 2 times.
✓ Branch 232 → 233 taken 8 times.
✓ Branch 232 → 247 taken 610 times.
✗ Branch 610 → 611 not taken.
✗ Branch 610 → 612 not taken.
✗ Branch 614 → 615 not taken.
✗ Branch 614 → 616 not taken.
✗ Branch 618 → 619 not taken.
✗ Branch 618 → 620 not taken.
|
2464 | info.size() != expected.value(QStringLiteral("bytes")).toInteger() || |
| 951 |
8/12✓ Branch 208 → 209 taken 612 times.
✓ Branch 209 → 210 taken 612 times.
✓ Branch 211 → 212 taken 2 times.
✓ Branch 211 → 213 taken 610 times.
✓ Branch 214 → 215 taken 612 times.
✓ Branch 214 → 216 taken 6 times.
✓ Branch 216 → 217 taken 612 times.
✓ Branch 216 → 218 taken 6 times.
✗ Branch 586 → 587 not taken.
✗ Branch 586 → 588 not taken.
✗ Branch 590 → 591 not taken.
✗ Branch 590 → 592 not taken.
|
1842 | QString::fromLatin1(fileSha256(path)) != |
| 952 |
12/20✓ Branch 206 → 207 taken 612 times.
✓ Branch 207 → 208 taken 612 times.
✓ Branch 218 → 219 taken 612 times.
✓ Branch 218 → 220 taken 6 times.
✓ Branch 220 → 221 taken 612 times.
✓ Branch 220 → 222 taken 6 times.
✓ Branch 222 → 223 taken 612 times.
✓ Branch 222 → 224 taken 6 times.
✓ Branch 224 → 225 taken 612 times.
✓ Branch 224 → 226 taken 6 times.
✓ Branch 226 → 227 taken 616 times.
✓ Branch 226 → 228 taken 2 times.
✗ Branch 594 → 595 not taken.
✗ Branch 594 → 596 not taken.
✗ Branch 598 → 599 not taken.
✗ Branch 598 → 600 not taken.
✗ Branch 602 → 603 not taken.
✗ Branch 602 → 604 not taken.
✗ Branch 606 → 607 not taken.
✗ Branch 606 → 608 not taken.
|
1842 | expected.value(QStringLiteral("sha256")).toString()) { |
| 953 |
2/2✓ Branch 233 → 234 taken 4 times.
✓ Branch 233 → 246 taken 4 times.
|
8 | if (error) |
| 954 | 8 | *error = QStringLiteral("Fixture artifact is missing or corrupt: %1") | |
| 955 |
2/2✓ Branch 238 → 239 taken 4 times.
✓ Branch 239 → 240 taken 4 times.
|
8 | .arg(it.key()); |
| 956 | 8 | return false; | |
| 957 | } | ||
| 958 | 634 | } | |
| 959 | |||
| 960 |
1/1✓ Branch 264 → 265 taken 58 times.
|
58 | MailCache mail; |
| 961 |
4/4✓ Branch 268 → 269 taken 58 times.
✓ Branch 269 → 270 taken 58 times.
✓ Branch 273 → 274 taken 4 times.
✓ Branch 273 → 280 taken 54 times.
|
58 | if (!mail.open(dir.filePath(QStringLiteral("mail.sqlite")))) { |
| 962 |
2/2✓ Branch 274 → 275 taken 2 times.
✓ Branch 274 → 279 taken 2 times.
|
4 | if (error) |
| 963 |
1/1✓ Branch 275 → 276 taken 2 times.
|
2 | *error = mail.lastError(); |
| 964 | 4 | return false; | |
| 965 | } | ||
| 966 | const QStringList folders = | ||
| 967 |
2/2✓ Branch 281 → 282 taken 54 times.
✓ Branch 282 → 283 taken 54 times.
|
54 | mail.allFolderPaths(QString::fromLatin1(AccountId)); |
| 968 | 54 | int headers = 0; | |
| 969 | 54 | int bodies = 0; | |
| 970 |
2/2✓ Branch 299 → 286 taken 162 times.
✓ Branch 299 → 300 taken 54 times.
|
216 | for (const QString &path : folders) { |
| 971 |
2/2✓ Branch 289 → 290 taken 162 times.
✓ Branch 290 → 291 taken 162 times.
|
162 | headers += mail.payloadLimits().cachedHeaderCount(QString::fromLatin1(AccountId), path); |
| 972 |
2/2✓ Branch 294 → 295 taken 162 times.
✓ Branch 295 → 296 taken 162 times.
|
162 | bodies += mail.payloadLimits().cachedBodyCount(QString::fromLatin1(AccountId), path); |
| 973 | } | ||
| 974 |
2/2✓ Branch 300 → 301 taken 17 times.
✓ Branch 300 → 308 taken 37 times.
|
71 | const bool ftsOk = spec.headers == 0 || |
| 975 |
9/15✓ Branch 305 → 306 taken 17 times.
✓ Branch 307 → 308 taken 16 times.
✓ Branch 307 → 309 taken 1 time.
✓ Branch 310 → 311 taken 17 times.
✓ Branch 310 → 312 taken 37 times.
✓ Branch 312 → 313 taken 17 times.
✓ Branch 312 → 314 taken 37 times.
✓ Branch 314 → 315 taken 17 times.
✓ Branch 314 → 316 taken 37 times.
✗ Branch 665 → 666 not taken.
✗ Branch 665 → 667 not taken.
✗ Branch 669 → 670 not taken.
✗ Branch 669 → 671 not taken.
✗ Branch 673 → 674 not taken.
✗ Branch 673 → 675 not taken.
|
88 | !mail.search().searchFts(QStringLiteral("synthetic"), 1).isEmpty(); |
| 976 |
1/1✓ Branch 316 → 317 taken 54 times.
|
54 | mail.close(); |
| 977 |
2/2✓ Branch 319 → 320 taken 51 times.
✓ Branch 319 → 322 taken 1 time.
|
106 | if (folders.size() != spec.folders || headers != spec.headers || |
| 978 |
8/8✓ Branch 318 → 319 taken 52 times.
✓ Branch 318 → 322 taken 2 times.
✓ Branch 320 → 321 taken 50 times.
✓ Branch 320 → 322 taken 1 time.
✓ Branch 321 → 322 taken 1 time.
✓ Branch 321 → 323 taken 49 times.
✓ Branch 324 → 325 taken 5 times.
✓ Branch 324 → 334 taken 49 times.
|
106 | bodies != spec.bodies || !ftsOk) { |
| 979 |
2/2✓ Branch 325 → 326 taken 3 times.
✓ Branch 325 → 333 taken 2 times.
|
5 | if (error) |
| 980 | 3 | *error = QStringLiteral( | |
| 981 | "Generated mail database failed API count verification"); | ||
| 982 | 5 | return false; | |
| 983 | } | ||
| 984 |
4/4✓ Branch 337 → 338 taken 49 times.
✓ Branch 338 → 339 taken 49 times.
✓ Branch 342 → 343 taken 4 times.
✓ Branch 342 → 344 taken 45 times.
|
49 | if (!validateSqlite(dir.filePath(QStringLiteral("mail.sqlite")), |
| 985 | 49 | MailCache::SchemaVersion, spec.headers, error)) | |
| 986 | 4 | return false; | |
| 987 | |||
| 988 |
1/1✓ Branch 344 → 345 taken 45 times.
|
45 | CalendarStore calendar; |
| 989 |
3/4✓ Branch 348 → 349 taken 45 times.
✓ Branch 349 → 350 taken 45 times.
✗ Branch 353 → 354 not taken.
✓ Branch 353 → 363 taken 45 times.
|
45 | if (!calendar.open(dir.filePath(QStringLiteral("calendar.sqlite")))) { |
| 990 | ✗ | if (error) | |
| 991 | ✗ | *error = QStringLiteral("Generated calendar database cannot be reopened"); | |
| 992 | ✗ | return false; | |
| 993 | } | ||
| 994 | const auto events = calendar.eventsForDateRange( | ||
| 995 |
4/4✓ Branch 367 → 368 taken 45 times.
✓ Branch 368 → 369 taken 45 times.
✓ Branch 369 → 370 taken 45 times.
✓ Branch 370 → 371 taken 45 times.
|
90 | QDateTime(QDate(2000, 1, 1), QTime(0, 0), QTimeZone::utc()), |
| 996 |
5/5✓ Branch 363 → 364 taken 45 times.
✓ Branch 364 → 365 taken 45 times.
✓ Branch 365 → 366 taken 45 times.
✓ Branch 366 → 367 taken 45 times.
✓ Branch 371 → 372 taken 45 times.
|
135 | QDateTime(QDate(2100, 1, 1), QTime(0, 0), QTimeZone::utc())); |
| 997 |
1/1✓ Branch 376 → 377 taken 45 times.
|
45 | const int taskCount = calendar.allTasks().size(); |
| 998 |
1/1✓ Branch 379 → 380 taken 45 times.
|
45 | calendar.close(); |
| 999 |
6/6✓ Branch 381 → 382 taken 44 times.
✓ Branch 381 → 383 taken 1 time.
✓ Branch 382 → 383 taken 1 time.
✓ Branch 382 → 384 taken 43 times.
✓ Branch 385 → 386 taken 2 times.
✓ Branch 385 → 395 taken 43 times.
|
45 | if (events.size() != spec.events || taskCount != spec.tasks) { |
| 1000 |
2/2✓ Branch 386 → 387 taken 1 time.
✓ Branch 386 → 394 taken 1 time.
|
2 | if (error) |
| 1001 | 1 | *error = QStringLiteral( | |
| 1002 | "Generated calendar database failed API count verification"); | ||
| 1003 | 2 | return false; | |
| 1004 | } | ||
| 1005 |
4/4✓ Branch 398 → 399 taken 43 times.
✓ Branch 399 → 400 taken 43 times.
✓ Branch 403 → 404 taken 2 times.
✓ Branch 403 → 405 taken 41 times.
|
43 | if (!validateSqlite(dir.filePath(QStringLiteral("calendar.sqlite")), |
| 1006 | CalendarStore::SchemaVersion, -1, error)) | ||
| 1007 | 2 | return false; | |
| 1008 | |||
| 1009 |
1/1✓ Branch 405 → 406 taken 41 times.
|
41 | ContactStore contacts; |
| 1010 |
3/4✓ Branch 409 → 410 taken 41 times.
✓ Branch 410 → 411 taken 41 times.
✗ Branch 414 → 415 not taken.
✓ Branch 414 → 424 taken 41 times.
|
41 | if (!contacts.open(dir.filePath(QStringLiteral("contacts.sqlite")))) { |
| 1011 | ✗ | if (error) | |
| 1012 | ✗ | *error = QStringLiteral("Generated contact database cannot be reopened"); | |
| 1013 | ✗ | return false; | |
| 1014 | } | ||
| 1015 |
2/2✓ Branch 424 → 425 taken 41 times.
✓ Branch 425 → 426 taken 41 times.
|
41 | const int contactCount = ContactQueries::allCount(contacts.database()); |
| 1016 |
1/1✓ Branch 427 → 428 taken 41 times.
|
41 | contacts.close(); |
| 1017 |
2/2✓ Branch 428 → 429 taken 2 times.
✓ Branch 428 → 438 taken 39 times.
|
41 | if (contactCount != spec.contacts) { |
| 1018 |
2/2✓ Branch 429 → 430 taken 1 time.
✓ Branch 429 → 437 taken 1 time.
|
2 | if (error) |
| 1019 | 1 | *error = QStringLiteral( | |
| 1020 | "Generated contact database failed API count verification"); | ||
| 1021 | 2 | return false; | |
| 1022 | } | ||
| 1023 |
3/4✓ Branch 441 → 442 taken 39 times.
✓ Branch 442 → 443 taken 39 times.
✗ Branch 446 → 447 not taken.
✓ Branch 446 → 448 taken 39 times.
|
39 | if (!validateSqlite(dir.filePath(QStringLiteral("contacts.sqlite")), -1, -1, |
| 1024 | error)) | ||
| 1025 | ✗ | return false; | |
| 1026 | 39 | return true; | |
| 1027 | 814 | } | |
| 1028 | |||
| 1029 | } // namespace MailJD::Performance | ||
| 1030 |