File: runnermanagertest.cpp

package info (click to toggle)
krunner 5.116.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 828 kB
  • sloc: cpp: 4,954; sh: 46; xml: 25; python: 23; makefile: 7
file content (133 lines) | stat: -rw-r--r-- 5,095 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
    SPDX-FileCopyrightText: 2022 Eduardo Cruz <eduardo.cruz@kdemail.net>
    SPDX-License-Identifier: LGPL-2.1-or-later
*/

#include "runnermanager.h"

#include <KSharedConfig>
#include <QAction>
#include <QCoreApplication>
#include <QObject>
#include <QProcess>
#include <QStandardPaths>
#include <QTest>

#include "abstractrunnertest.h"
#include "kpluginmetadata_utils_p.h"

Q_DECLARE_METATYPE(Plasma::QueryMatch)
Q_DECLARE_METATYPE(QList<Plasma::QueryMatch>)

using namespace Plasma;

class RunnerManagerTest : public AbstractRunnerTest
{
    Q_OBJECT
private Q_SLOTS:
    void initTestCase()
    {
        startDBusRunnerProcess({QStringLiteral("net.krunnertests.dave")});
        qputenv("XDG_DATA_DIRS", QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation).toLocal8Bit());
        QCoreApplication::setLibraryPaths(QStringList());
        initProperties();
        auto md = parseMetaDataFromDesktopFile(QFINDTESTDATA("dbusrunnertestmulti.desktop"));
        QVERIFY(md.isValid());
        manager->loadRunner(md);
        qRegisterMetaType<QList<Plasma::QueryMatch>>();
    }

    void cleanupTestCase()
    {
        killRunningDBusProcesses();
    }

    /**
     * This will test the mechanismm that stalls for 250ms before emiting any result in RunnerManager::scheduleMatchesChanged()
     * and the mechanism that anticipates the last results emission in RunnerManager::jobDone().
     */
    void testScheduleMatchesChanged()
    {
        QSignalSpy spyQueryFinished(manager.get(), &Plasma::RunnerManager::queryFinished);
        QSignalSpy spyMatchesChanged(manager.get(), &Plasma::RunnerManager::matchesChanged);

        QVERIFY(spyQueryFinished.isValid());
        QVERIFY(spyMatchesChanged.isValid());

        QCOMPARE(spyQueryFinished.count(), 0);

        // This will track the total execution time
        QElapsedTimer timer;
        timer.start();

        // This special string will simulate a 300ms delay
        manager->launchQuery("fooDelay300");

        // However not yet a matcheschanged, it should be stalled for 250ms
        QCOMPARE(spyMatchesChanged.count(), 0);

        // After 250ms it will emit with empty matches, we wait for that.
        // We can't put a low upper limit on these wait() calls because the CI environment can be slow.
        QVERIFY(spyMatchesChanged.wait()); // This should take just a tad longer than 250ms.

        // This should have taken no less than 250ms. It waits for 250s before "giving up" and emitting an empty matches list.
        QVERIFY(timer.elapsed() >= 250);
        QCOMPARE(spyMatchesChanged.count(), 1);
        QCOMPARE(manager->matches().count(), 0); // This is the empty matches "reset" emission, result is not ready yet
        QCOMPARE(spyQueryFinished.count(), 0); // Still the same, query is not done

        // We programmed it to emit the result after 300ms, so we need to wait 50ms more for the next emission
        QVERIFY(spyQueryFinished.wait());

        // This should have taken at least 300ms total, as we requested via the special query string
        QVERIFY(timer.elapsed() >= 300);

        // At this point RunnerManager::jobDone() should have anticipated the final emission.
        QCOMPARE(spyMatchesChanged.count(), 2); // We had the second matchesChanged emission, now with the query result
        QCOMPARE(manager->matches().count(), 1); // The result is here
        QCOMPARE(spyQueryFinished.count(), 1); // Will have emited queryFinished, job is done

        // Now we will make sure that RunnerManager::scheduleMatchesChanged() emits matchesChanged instantly
        // if we start a query with an empty string. It will never produce results, stalling is meaningless
        manager->launchQuery("");
        QCOMPARE(spyMatchesChanged.count(), 3); // One more, instantly, without stall
        QCOMPARE(manager->matches().count(), 0); // Empty results for empty query string
        QVERIFY(spyQueryFinished.wait());
    }

    /**
     * This will test queryFinished signal from reset() is emitted when the previous runners are
     * still running.
     */
    void testQueryFinishedFromReset()
    {
        QSignalSpy spyQueryFinished(manager.get(), &Plasma::RunnerManager::queryFinished);

        manager->launchQuery("fooDelay1000");
        QCOMPARE(spyQueryFinished.size(), 0);

        manager->launchQuery("fooDelay300");
        QCOMPARE(spyQueryFinished.size(), 1); // From reset()

        QVERIFY(spyQueryFinished.wait());
        QCOMPARE(spyQueryFinished.size(), 2);
    }

    /**
     * When we delete the RunnerManager while a job is still running, we should not crash
     */
    void testNotCrashWhenDeletingRunnerManager()
    {
        RunnerManager manager;
        manager.setAllowedRunners({QStringLiteral("fakerunnerplugin")});
        manager.loadRunner(KPluginMetaData::findPluginById(QStringLiteral("krunnertest"), QStringLiteral("fakerunnerplugin")));

        QCOMPARE(manager.runners().size(), 1);

        manager.launchQuery("somequery");
    }
};

QTEST_MAIN(RunnerManagerTest)

#include "runnermanagertest.moc"