MailJDTourDownloadDocsQualityTestsCoverage

Which source lines and branches the tests execute. Lines 91.5 %, branches 75.0 % (minimum 85 % and 72 %). main @ 399ffe3d · 21 October 2026 · pipeline 7238.

GCC Code Coverage Report


Directory: src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 98.6% 73 / 0 / 74
Functions: 100.0% 15 / 0 / 15
Branches: 84.4% 81 / 0 / 96

app/core/DavPushStatistics.cpp
Line Branch Exec Source
1 #include "DavPushStatistics.h"
2
3 #include "data/CalendarModels.h"
4 #include "data/DavPushStore.h"
5
6 857 DavPushStatistics::DavPushStatistics(DavPushStore *store, std::function<qint64()> nowSeconds, QObject *parent)
7
1/1
✓ Branch 8 → 9 taken 857 times.
857 : QObject(parent), m_store(store), m_now(std::move(nowSeconds)) {
8
1/1
✓ Branch 9 → 10 taken 857 times.
857 m_flush.setInterval(kFlushIntervalMs);
9
1/1
✓ Branch 10 → 11 taken 857 times.
857 connect(&m_flush, &QTimer::timeout, this, &DavPushStatistics::flush);
10
1/1
✓ Branch 12 → 13 taken 857 times.
857 m_flush.start();
11 857 }
12
13 1713 DavPushStatistics::~DavPushStatistics() {
14 857 flush();
15 1713 }
16
17 202 QString DavPushStatistics::accountScope(const QString &accountId) {
18
1/1
✓ Branch 5 → 6 taken 202 times.
202 return QStringLiteral("account:") + accountId;
19 }
20
21 318 QString DavPushStatistics::collectionScope(const QString &accountId, const QString &path) {
22
2/2
✓ Branch 2 → 3 taken 318 times.
✓ Branch 6 → 7 taken 318 times.
636 return QStringLiteral("collection:") + calendarSelectionKey(accountId, path);
23 }
24
25 819 void DavPushStatistics::count(const QString &scope, const QString &name, qint64 delta) {
26 819 m_counts.append({scope, name, delta, m_now()});
27 819 emit changed();
28 1638 }
29
30 29 void DavPushStatistics::latency(const QString &scope, const QString &kind, qint64 millis) {
31 29 m_samples.append({scope, kind, millis, m_now()});
32 29 emit changed();
33 58 }
34
35 207 void DavPushStatistics::event(const QString &scope, const QString &kind, const QString &detail) {
36 207 m_events.append({scope, kind, detail, m_now()});
37 207 emit changed();
38 414 }
39
40 // Runs on the GUI thread every 30 s: equal counters of the same hour are
41 // summed first and everything is written in one transaction (one commit;
42 // per-statement commits cost one fsync each and blocked the event loop
43 // for 100-300 ms under sustained push load).
44 2547 void DavPushStatistics::flush() {
45
4/7
✓ Branch 2 → 3 taken 2547 times.
✗ Branch 2 → 5 not taken.
✓ Branch 3 → 4 taken 2547 times.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 2547 times.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 2547 times.
5059 if (!m_store || !m_store->isOpen()) return;
46
7/8
✓ Branch 10 → 11 taken 2514 times.
✓ Branch 10 → 16 taken 33 times.
✓ Branch 12 → 13 taken 2514 times.
✗ Branch 12 → 16 not taken.
✓ Branch 14 → 15 taken 2512 times.
✓ Branch 14 → 16 taken 2 times.
✓ Branch 17 → 18 taken 2512 times.
✓ Branch 17 → 19 taken 35 times.
2547 if (m_counts.isEmpty() && m_samples.isEmpty() && m_events.isEmpty()) return;
47 35 QList<PendingCount> merged;
48 35 QHash<QString, qsizetype> index; // scope|name|hour -> position in merged
49
2/2
✓ Branch 49 → 22 taken 817 times.
✓ Branch 49 → 50 taken 35 times.
852 for (const auto &c : std::as_const(m_counts)) {
50
5/5
✓ Branch 23 → 24 taken 817 times.
✓ Branch 28 → 29 taken 817 times.
✓ Branch 29 → 30 taken 817 times.
✓ Branch 30 → 31 taken 817 times.
✓ Branch 31 → 32 taken 817 times.
817 const QString key = c.scope + QLatin1Char('|') + c.name + QLatin1Char('|') + QString::number(c.at - c.at % 3600);
51 817 const auto found = index.constFind(key);
52
2/2
✓ Branch 39 → 40 taken 549 times.
✓ Branch 39 → 43 taken 268 times.
817 if (found != index.cend()) {
53
1/1
✓ Branch 41 → 42 taken 549 times.
549 merged[*found].delta += c.delta;
54 } else {
55
1/1
✓ Branch 44 → 45 taken 268 times.
268 index.insert(key, merged.size());
56
1/1
✓ Branch 45 → 46 taken 268 times.
268 merged.append(c);
57 }
58 817 }
59
1/1
✓ Branch 50 → 51 taken 35 times.
35 const bool transaction = m_store->beginTransaction();
60
3/3
✓ Branch 55 → 56 taken 268 times.
✓ Branch 58 → 54 taken 268 times.
✓ Branch 58 → 59 taken 35 times.
303 for (const auto &c : std::as_const(merged)) m_store->addCounter(c.scope, c.name, c.delta, c.at);
61
3/3
✓ Branch 63 → 64 taken 21 times.
✓ Branch 66 → 62 taken 21 times.
✓ Branch 66 → 67 taken 35 times.
56 for (const auto &s : std::as_const(m_samples)) m_store->addLatency(s.scope, s.kind, s.millis, s.at);
62
3/3
✓ Branch 71 → 72 taken 204 times.
✓ Branch 74 → 70 taken 204 times.
✓ Branch 74 → 75 taken 35 times.
239 for (const auto &e : std::as_const(m_events)) m_store->addEvent(e.scope, e.kind, e.detail, e.at);
63
2/2
✓ Branch 75 → 76 taken 35 times.
✓ Branch 76 → 77 taken 35 times.
35 m_store->pruneHourly(m_now());
64
4/8
✓ Branch 77 → 78 taken 35 times.
✗ Branch 77 → 81 not taken.
✓ Branch 78 → 79 taken 35 times.
✗ Branch 79 → 80 not taken.
✓ Branch 79 → 81 taken 35 times.
✗ Branch 82 → 83 not taken.
✓ Branch 82 → 84 taken 35 times.
✗ Branch 83 → 84 not taken.
35 if (transaction && !m_store->commitTransaction()) m_store->rollbackTransaction();
65
1/1
✓ Branch 84 → 85 taken 35 times.
35 m_counts.clear();
66
1/1
✓ Branch 85 → 86 taken 35 times.
35 m_samples.clear();
67
1/1
✓ Branch 86 → 87 taken 35 times.
35 m_events.clear();
68 35 }
69
70 152 qint64 DavPushStatistics::counter(const QString &scope, const QString &name) const {
71
1/2
✓ Branch 2 → 3 taken 152 times.
✗ Branch 2 → 5 not taken.
152 qint64 value = m_store ? m_store->counter(scope, name) : 0;
72
2/2
✓ Branch 19 → 8 taken 730 times.
✓ Branch 19 → 20 taken 152 times.
882 for (const auto &c : m_counts)
73
6/6
✓ Branch 10 → 11 taken 249 times.
✓ Branch 10 → 14 taken 481 times.
✓ Branch 12 → 13 taken 30 times.
✓ Branch 12 → 14 taken 219 times.
✓ Branch 15 → 16 taken 30 times.
✓ Branch 15 → 17 taken 700 times.
730 if (c.scope == scope && c.name == name) value += c.delta;
74 152 return value;
75 }
76
77 32 qint64 DavPushStatistics::periodSum(const QString &scope, const QString &name, qint64 sinceSeconds) const {
78
1/2
✓ Branch 2 → 3 taken 32 times.
✗ Branch 2 → 5 not taken.
32 qint64 value = m_store ? m_store->periodSum(scope, name, sinceSeconds) : 0;
79
2/2
✓ Branch 20 → 8 taken 64 times.
✓ Branch 20 → 21 taken 32 times.
96 for (const auto &c : m_counts)
80
7/8
✓ Branch 10 → 11 taken 22 times.
✓ Branch 10 → 15 taken 42 times.
✓ Branch 12 → 13 taken 2 times.
✓ Branch 12 → 15 taken 20 times.
✓ Branch 13 → 14 taken 2 times.
✗ Branch 13 → 15 not taken.
✓ Branch 16 → 17 taken 2 times.
✓ Branch 16 → 18 taken 62 times.
64 if (c.scope == scope && c.name == name && c.at >= sinceSeconds - sinceSeconds % 3600) value += c.delta;
81 32 return value;
82 }
83
84 8 QList<qint64> DavPushStatistics::latencies(const QString &scope, const QString &kind) const {
85
1/2
✓ Branch 2 → 3 taken 8 times.
✗ Branch 2 → 4 not taken.
8 QList<qint64> values = m_store ? m_store->latencies(scope, kind) : QList<qint64>();
86
2/2
✓ Branch 18 → 7 taken 36 times.
✓ Branch 18 → 19 taken 8 times.
44 for (const auto &s : m_samples)
87
7/7
✓ Branch 9 → 10 taken 20 times.
✓ Branch 9 → 13 taken 16 times.
✓ Branch 11 → 12 taken 12 times.
✓ Branch 11 → 13 taken 8 times.
✓ Branch 14 → 15 taken 12 times.
✓ Branch 14 → 16 taken 24 times.
✓ Branch 15 → 16 taken 12 times.
36 if (s.scope == scope && s.kind == kind) values.append(s.millis);
88
1/2
✗ Branch 22 → 20 not taken.
✓ Branch 22 → 23 taken 8 times.
8 while (values.size() > DavPushStore::kMaxLatencySamples) values.removeFirst();
89 8 return values;
90 ✗ }
91
92 1 bool DavPushStatistics::reset(const QString &scope) {
93 3 m_counts.removeIf([&](const PendingCount &c) { return c.scope == scope; });
94 9 m_samples.removeIf([&](const PendingSample &s) { return s.scope == scope; });
95 4 m_events.removeIf([&](const PendingEvent &e) { return e.scope == scope; });
96
2/4
✓ Branch 5 → 6 taken 1 time.
✗ Branch 5 → 10 not taken.
✓ Branch 8 → 9 taken 1 time.
✗ Branch 8 → 10 not taken.
1 const bool ok = m_store && m_store->resetStatistics(scope, m_now());
97 1 emit changed();
98 1 return ok;
99 }
100