1 /*
2     SPDX-FileCopyrightText: 2010 Joris Guisson <joris.guisson@gmail.com>
3 
4     SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include <QObject>
8 #include <QRandomGenerator>
9 #include <QtTest>
10 
11 #include <util/functions.h>
12 #include <util/log.h>
13 #include <util/resourcemanager.h>
14 
15 using namespace bt;
16 
17 static bt::Resource *last_acquired = nullptr;
18 
19 class TestResource : public bt::Resource
20 {
21 public:
TestResource(ResourceManager * rman,const QString & group)22     TestResource(ResourceManager *rman, const QString &group)
23         : Resource(rman, group)
24         , acq(false)
25     {
26     }
27 
acquired()28     void acquired() override
29     {
30         Out(SYS_GEN | LOG_DEBUG) << "Resource of " << groupName() << " acquired" << endl;
31         acq = true;
32         last_acquired = this;
33     }
34 
35     bool acq;
36 };
37 
38 class ResourceManagerTest : public QObject
39 {
40     Q_OBJECT
41 public:
42 private Q_SLOTS:
initTestCase()43     void initTestCase()
44     {
45         bt::InitLog("resourcemanagertest.log");
46     }
47 
cleanupTestCase()48     void cleanupTestCase()
49     {
50     }
51 
testSingleClass()52     void testSingleClass()
53     {
54         Out(SYS_GEN | LOG_DEBUG) << "testSingleClass" << endl;
55         ResourceManager rm(4);
56 
57         QList<TestResource *> tr;
58         for (int i = 0; i < 8; i++) {
59             TestResource *r = new TestResource(&rm, "test");
60             tr.append(r);
61             rm.add(r);
62             // The first 4 should get acquired
63             QVERIFY(r->acq == (i < 4));
64         }
65 
66         for (int i = 0; i < 4; i++) {
67             delete tr.takeFirst();
68             QVERIFY(tr.at(3)->acq); // The next availabe one should now be acquired
69         }
70         qDeleteAll(tr);
71     }
72 
testMultiClass()73     void testMultiClass()
74     {
75         Out(SYS_GEN | LOG_DEBUG) << "testMultiClass" << endl;
76         ResourceManager rm(4);
77         const char *classes[4] = {"aaa", "bbb", "ccc", "ddd"};
78 
79         // 4 resources for each class
80         QList<TestResource *> tr;
81         for (int i = 0; i < 16; i++) {
82             TestResource *r = new TestResource(&rm, classes[i % 4]);
83             tr.append(r);
84             rm.add(r);
85             // The first 4 should get acquired
86             QVERIFY(r->acq == (i < 4));
87         }
88 
89         QString last_group;
90         for (int i = 0; i < 12; i++) {
91             Resource *r = tr.takeFirst();
92             QString g = r->groupName();
93             delete r;
94             QVERIFY(tr.at(3)->acq); // The next availabe one should now be acquired
95             QVERIFY(g != last_group);
96             last_group = g;
97         }
98         qDeleteAll(tr);
99     }
100 
testFullyRandom()101     void testFullyRandom()
102     {
103         Out(SYS_GEN | LOG_DEBUG) << "testFullyRandom" << endl;
104         ResourceManager rm(4);
105         const char *classes[4] = {"aaa", "bbb", "ccc", "ddd"};
106 
107         // A random amount of resources for each class
108         QList<TestResource *> tr;
109 
110         Uint32 num_acquired = 0;
111         for (int i = 0; i < 500; i++) {
112             TestResource *r = new TestResource(&rm, classes[QRandomGenerator::global()->bounded(4)]);
113             tr.append(r);
114             rm.add(r);
115             if (r->acq)
116                 num_acquired++;
117         }
118 
119         QVERIFY(num_acquired == 4);
120 
121         QString last_acquired_group;
122         for (int i = 0; i < 496; i++) {
123             tr.removeAll((TestResource *)last_acquired);
124             delete last_acquired;
125             QVERIFY(last_acquired);
126             if (last_acquired->groupName() == last_acquired_group) {
127                 // This is only possible if there are no other groups which are still pending
128                 for (TestResource *r : qAsConst(tr))
129                     if (!r->acq)
130                         QVERIFY(r->groupName() == last_acquired_group);
131             }
132             last_acquired_group = last_acquired->groupName();
133         }
134         qDeleteAll(tr);
135     }
136 };
137 
138 QTEST_MAIN(ResourceManagerTest)
139 
140 #include "resourcemanagertest.moc"
141