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: 87.8% 43 / 0 / 49
Functions: 100.0% 10 / 0 / 10
Branches: 77.5% 55 / 0 / 71

app/core/ProcessTimeZone.cpp
Line Branch Exec Source
1 #include "ProcessTimeZone.h"
2
3 #include <QFileInfo>
4 #include <QLoggingCategory>
5 #include <QTimeZone>
6 #include <ctime>
7
8
3/7
✓ Branch 2 → 3 taken 3 times.
✗ Branch 2 → 8 not taken.
✓ Branch 4 → 5 taken 3 times.
✗ Branch 4 → 8 not taken.
✓ Branch 5 → 6 taken 3 times.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 12 not taken.
3 Q_LOGGING_CATEGORY(lcProcessZone, "mailjd.timezone")
9
10 namespace {
11 bool g_pinned = false;
12 // F100-26: pin() runs before the log rules exist; its outcome is kept and
13 // written by logPinResult() once they apply (info, hidden by default).
14 QString g_pinResult;
15
16
2/2
✓ Branch 5 → 6 taken 2 times.
✓ Branch 6 → 7 taken 2 times.
4 QString readLocaltimeLink() { return QFileInfo(QStringLiteral("/etc/localtime")).symLinkTarget(); }
17
18 3 void applyTz(const QByteArray &zoneId) {
19
1/1
✓ Branch 3 → 4 taken 3 times.
3 qputenv("TZ", zoneId);
20 3 tzset(); // glibc and Qt's local time follow the new TZ from here on
21 3 }
22 } // namespace
23
24 namespace ProcessTimeZone {
25
26 11 QByteArray zoneIdFromLink(const QString &linkTarget) {
27 11 const QString marker = QStringLiteral("/zoneinfo/");
28
1/1
✓ Branch 6 → 7 taken 11 times.
11 const int at = linkTarget.lastIndexOf(marker);
29
2/2
✓ Branch 7 → 8 taken 2 times.
✓ Branch 7 → 9 taken 9 times.
11 if (at < 0) return {};
30
1/1
✓ Branch 10 → 11 taken 9 times.
9 QString id = linkTarget.mid(at + marker.size());
31 // posix/ and right/ are variants of the same zone database.
32
4/4
✓ Branch 12 → 13 taken 9 times.
✓ Branch 13 → 14 taken 1 time.
✓ Branch 13 → 18 taken 8 times.
✓ Branch 14 → 15 taken 1 time.
9 if (id.startsWith(QLatin1String("posix/"))) id = id.mid(6);
33
2/4
✓ Branch 19 → 20 taken 9 times.
✗ Branch 20 → 21 not taken.
✓ Branch 20 → 25 taken 9 times.
✗ Branch 21 → 22 not taken.
9 if (id.startsWith(QLatin1String("right/"))) id = id.mid(6);
34
1/1
✓ Branch 25 → 26 taken 9 times.
9 const QByteArray bytes = id.toUtf8();
35
3/3
✓ Branch 26 → 27 taken 9 times.
✓ Branch 27 → 28 taken 8 times.
✓ Branch 27 → 29 taken 1 time.
9 return QTimeZone::isTimeZoneIdAvailable(bytes) ? bytes : QByteArray();
36 11 }
37
38
2/2
✓ Branch 2 → 3 taken 2 times.
✓ Branch 3 → 4 taken 2 times.
2 QByteArray systemZoneIdFromLink() { return zoneIdFromLink(readLocaltimeLink()); }
39
40 2 void logPinResult() {
41
3/7
✓ Branch 3 → 4 taken 2 times.
✗ Branch 3 → 16 not taken.
✓ Branch 4 → 5 taken 2 times.
✗ Branch 8 → 9 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 14 → 6 not taken.
✓ Branch 14 → 15 taken 2 times.
2 if (!g_pinResult.isEmpty()) qCInfo(lcProcessZone).noquote() << g_pinResult;
42 2 }
43
44 3 bool pin() {
45
2/2
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 17 taken 2 times.
3 if (!qEnvironmentVariableIsEmpty("TZ")) {
46
3/3
✓ Branch 4 → 5 taken 1 time.
✓ Branch 5 → 6 taken 1 time.
✓ Branch 9 → 10 taken 1 time.
2 g_pinResult = QStringLiteral("TZ set by the environment: ") + QString::fromLocal8Bit(qgetenv("TZ"));
47 1 return false;
48 }
49
1/1
✓ Branch 17 → 18 taken 2 times.
2 const QByteArray zone = systemZoneIdFromLink();
50
1/2
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 27 taken 2 times.
2 if (zone.isEmpty()) {
51 ✗ g_pinResult = QStringLiteral("/etc/localtime names no zone; TZ stays unset");
52 ✗ return false;
53 }
54
1/1
✓ Branch 27 → 28 taken 2 times.
2 applyTz(zone);
55 2 g_pinned = true;
56
2/2
✓ Branch 28 → 29 taken 2 times.
✓ Branch 32 → 33 taken 2 times.
4 g_pinResult = QStringLiteral("TZ pinned to the system zone ") + QString::fromUtf8(zone);
57 2 return true;
58 2 }
59
60 767 bool pinned() { return g_pinned; }
61
62 } // namespace ProcessTimeZone
63
64 766 ProcessTimeZoneWatcher::ProcessTimeZoneWatcher(QObject *parent)
65
2/2
✓ Branch 3 → 4 taken 766 times.
✓ Branch 4 → 5 taken 766 times.
766 : QObject(parent), m_zone(qgetenv("TZ")), m_reader(readLocaltimeLink) {
66
1/2
✓ Branch 7 → 8 taken 766 times.
✗ Branch 7 → 9 not taken.
766 if (!ProcessTimeZone::pinned()) return; // TZ unset or set by the user: nothing to follow
67 ✗ m_timer.setInterval(60 * 1000);
68 ✗ connect(&m_timer, &QTimer::timeout, this, &ProcessTimeZoneWatcher::check);
69 ✗ m_timer.start();
70 ✗ }
71
72 3 void ProcessTimeZoneWatcher::check() {
73
2/2
✓ Branch 2 → 3 taken 3 times.
✓ Branch 3 → 4 taken 3 times.
3 const QByteArray zone = ProcessTimeZone::zoneIdFromLink(m_reader());
74
5/6
✓ Branch 6 → 7 taken 3 times.
✗ Branch 6 → 9 not taken.
✓ Branch 8 → 9 taken 2 times.
✓ Branch 8 → 10 taken 1 time.
✓ Branch 11 → 12 taken 2 times.
✓ Branch 11 → 13 taken 1 time.
3 if (zone.isEmpty() || zone == m_zone) return;
75
8/8
✓ Branch 13 → 14 taken 1 time.
✓ Branch 17 → 18 taken 1 time.
✓ Branch 18 → 19 taken 1 time.
✓ Branch 19 → 20 taken 1 time.
✓ Branch 20 → 21 taken 1 time.
✓ Branch 21 → 22 taken 1 time.
✓ Branch 25 → 15 taken 1 time.
✓ Branch 25 → 26 taken 1 time.
2 qCInfo(lcProcessZone) << "System time zone changed" << m_zone << "->" << zone;
76 1 m_zone = zone;
77
1/1
✓ Branch 27 → 28 taken 1 time.
1 applyTz(zone);
78
1/1
✓ Branch 28 → 29 taken 1 time.
1 emit changed(zone);
79 3 }
80