swift
testsharedstate.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2020 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
11 #include "testsharedstate.h"
12 
13 #include <QDBusConnection>
14 #include <QProcess>
15 #include <QTest>
16 
17 #include "test.h"
18 
19 #include "misc/dbusserver.h"
20 #include "misc/registermetadata.h"
23 
24 using namespace QTest;
25 using namespace swift::misc;
26 using namespace swift::misc::shared_state;
27 
28 namespace MiscTest
29 {
31  class CTestSharedState : public QObject
32  {
33  Q_OBJECT
34 
35  private slots:
37  void initTestCase();
38 
40  void testPromise();
41 
43  void localScalar();
44 
46  void localList();
47 
49  void dbusScalar();
50 
52  void dbusList();
53  };
54 
55  void CTestSharedState::initTestCase()
56  {
58  CTestFilter::registerMetadata();
59  }
60 
61  void CTestSharedState::testPromise()
62  {
63  int result = 0;
64  CPromise<int> promise;
65  doAfter(promise.future(), nullptr, [&](QFuture<int> future) { result = future.result(); });
66  promise.setResult(42);
67  bool ok = qWaitFor([&] { return result == 42; });
68  QVERIFY2(ok, "future contains expected result");
69  }
70 
71  void CTestSharedState::localScalar()
72  {
73  CDataLinkLocal dataLink;
74  CTestScalarMutator mutator(this);
75  CTestScalarJournal journal(this);
76  CTestScalarObserver observer(this);
77  mutator.initialize(&dataLink);
78  journal.initialize(&dataLink);
79  observer.initialize(&dataLink);
80 
81  mutator.setValue(42);
82  bool ok = qWaitFor([&] { return observer.value() == 42; });
83  QVERIFY2(ok, "expected value received");
84  qWait(0);
85  QVERIFY2(observer.value() == 42, "still has expected value");
86 
87  CTestScalarObserver observer2(this);
88  observer2.initialize(&dataLink);
89 
90  ok = qWaitFor([&] { return observer2.value() == 42; });
91  QVERIFY2(ok, "new observer got existing value");
92  qWait(0);
93  QVERIFY2(observer2.value() == 42, "still has correct value");
94  }
95 
96  void CTestSharedState::localList()
97  {
98  CDataLinkLocal dataLink;
99  CTestListMutator mutator(this);
100  CTestListJournal journal(this);
101  CTestListObserver observer(this);
102  mutator.initialize(&dataLink);
103  journal.initialize(&dataLink);
104  observer.initialize(&dataLink);
105 
106  observer.setFilter({});
107  mutator.addElement(1);
108  bool ok = qWaitFor([&] { return observer.allValues() == QList<int> { 1 }; });
109  QVERIFY2(ok, "expected value received");
110  qWait(0);
111  QVERIFY2(observer.allValues() == QList<int> { 1 }, "still has expected value");
112 
113  for (int e = 2; e <= 6; ++e) { mutator.addElement(e); }
114  ok = qWaitFor([&] { return observer.allValues() == QList<int> { 1, 2, 3, 4, 5, 6 }; });
115  QVERIFY2(ok, "expected value received");
116 
117  observer.allValues() = {};
118  observer.setFilter({ 1 });
119  ok = qWaitFor([&] { return observer.allValues() == QList<int> { 1, 3, 5 }; });
120  QVERIFY2(ok, "expected value received");
121  }
122 
124  class Server
125  {
126  public:
129  {
130  QObject::connect(&m_process, qOverload<int, QProcess::ExitStatus>(&QProcess::finished),
131  [](int code, QProcess::ExitStatus status) {
132  qDebug() << "Server process exited" << (status ? "abnormally" : "normally")
133  << "with exit code" << code;
134  });
135  m_process.start(QCoreApplication::applicationDirPath() + "/tests_sharedstatetestserver", QStringList());
136  if (!m_process.waitForStarted()) { qDebug() << "Server failed to start"; }
137  }
140  {
141  m_process.disconnect();
142  m_process.kill();
143  m_process.waitForFinished();
144  }
145 
146  private:
147  QProcess m_process;
148  };
149 
150  void CTestSharedState::dbusScalar()
151  {
152  QDBusConnection connection = QDBusConnection::sessionBus();
153  if (!connection.isConnected()) { QSKIP("No session bus"); }
154  Server s;
155 
156  CDataLinkDBus dataLink;
157  dataLink.initializeRemote(connection, SWIFT_SERVICENAME);
158  bool ok = qWaitFor([&] { return dataLink.watcher()->isConnected(); });
159  QVERIFY2(ok, "Connection failed");
160 
161  CTestScalarObserver observer(this);
162  CTestScalarMutator mutator(this);
163  observer.initialize(&dataLink);
164  mutator.initialize(&dataLink);
165 
166  ok = qWaitFor([&] { return observer.value() == 42; });
167  QVERIFY2(ok, "expected value received");
168  qWait(1000);
169  QVERIFY2(observer.value() == 42, "still has expected value");
170 
171  mutator.setValue(69);
172  ok = qWaitFor([&] { return observer.value() == 69; });
173  QVERIFY2(ok, "expected value received");
174  qWait(1000);
175  QVERIFY2(observer.value() == 69, "still has expected value");
176  }
177 
178  void CTestSharedState::dbusList()
179  {
180  QDBusConnection connection = QDBusConnection::sessionBus();
181  if (!connection.isConnected()) { QSKIP("No session bus"); }
182  Server s;
183 
184  CDataLinkDBus dataLink;
185  dataLink.initializeRemote(connection, SWIFT_SERVICENAME);
186  bool ok = qWaitFor([&] { return dataLink.watcher()->isConnected(); });
187  QVERIFY2(ok, "Connection failed");
188 
189  CTestListObserver observer(this);
190  CTestListMutator mutator(this);
191  observer.initialize(&dataLink);
192  mutator.initialize(&dataLink);
193 
194  observer.setFilter({});
195  ok = qWaitFor([&] { return observer.allValues() == QList<int> { 1, 2, 3, 4, 5, 6 }; });
196  QVERIFY2(ok, "expected value received");
197  qWait(1000);
198  QVERIFY2(observer.allValues() == QList<int>({ 1, 2, 3, 4, 5, 6 }), "still has expected value");
199 
200  observer.allValues() = {};
201  observer.setFilter({ 1 });
202  ok = qWaitFor([&] { return observer.allValues() == QList<int> { 1, 3, 5 }; });
203  QVERIFY2(ok, "expected value received");
204 
205  mutator.addElement(7);
206  ok = qWaitFor([&] { return observer.allValues() == QList<int> { 1, 3, 5, 7 }; });
207  QVERIFY2(ok, "expected value received");
208  qWait(1000);
209  QVERIFY2(observer.allValues() == QList<int>({ 1, 3, 5, 7 }), "still has expected value");
210  }
211 } // namespace MiscTest
212 
215 
216 #include "testsharedstate.moc"
217 
DBus implementation classes tests.
A promise-based interface to QFuture, similar to std::promise for std::future.
Definition: promise.h:78
QFuture< T > future()
Return a future that can be used to access the result.
Definition: promise.h:81
void setResult(const T &value)
Set the result value that will be made available through the future.
Definition: promise.h:91
@ Server
What server are you on?
#define SWIFT_SERVICENAME
Service name of DBus service.
Definition: dbusserver.h:23
Utilities for sharing state between multiple objects.
Definition: application.h:48
Free functions in swift::misc.
void registerMetadata()
Register all relevant metadata in Misc.
SWIFTTEST_MAIN(MiscTest::CTestSharedState)
main