summaryrefslogtreecommitdiffstats
path: root/tests/pipelinetest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/pipelinetest.cpp')
-rw-r--r--tests/pipelinetest.cpp241
1 files changed, 241 insertions, 0 deletions
diff --git a/tests/pipelinetest.cpp b/tests/pipelinetest.cpp
new file mode 100644
index 0000000..96448e2
--- /dev/null
+++ b/tests/pipelinetest.cpp
@@ -0,0 +1,241 @@
1#include <QtTest>
2
3#include <QString>
4
5#include "event_generated.h"
6#include "entity_generated.h"
7#include "metadata_generated.h"
8#include "createentity_generated.h"
9#include "modifyentity_generated.h"
10#include "deleteentity_generated.h"
11#include "dummyresource/resourcefactory.h"
12#include "clientapi.h"
13#include "synclistresult.h"
14#include "commands.h"
15#include "entitybuffer.h"
16#include "resourceconfig.h"
17#include "pipeline.h"
18#include "log.h"
19#include "domainadaptor.h"
20
21class TestEventAdaptorFactory : public DomainTypeAdaptorFactory<Akonadi2::ApplicationDomain::Event, Akonadi2::ApplicationDomain::Buffer::Event, Akonadi2::ApplicationDomain::Buffer::EventBuilder>
22{
23public:
24 TestEventAdaptorFactory()
25 : DomainTypeAdaptorFactory()
26 {
27 }
28
29 virtual ~TestEventAdaptorFactory() {};
30};
31
32static void removeFromDisk(const QString &name)
33{
34 Akonadi2::Storage store(Akonadi2::Store::storageLocation(), name, Akonadi2::Storage::ReadWrite);
35 store.removeFromDisk();
36}
37
38static QList<QByteArray> getKeys(const QByteArray &dbEnv, const QByteArray &name)
39{
40 Akonadi2::Storage store(Akonadi2::storageLocation(), dbEnv, Akonadi2::Storage::ReadOnly);
41 auto transaction = store.createTransaction(Akonadi2::Storage::ReadOnly);
42 auto db = transaction.openDatabase(name, nullptr, false);
43 QList<QByteArray> result;
44 db.scan("", [&](const QByteArray &key, const QByteArray &value) {
45 result << key;
46 return true;
47 });
48 return result;
49}
50
51static QByteArray getEntity(const QByteArray &dbEnv, const QByteArray &name, const QByteArray &uid)
52{
53 Akonadi2::Storage store(Akonadi2::storageLocation(), dbEnv, Akonadi2::Storage::ReadOnly);
54 auto transaction = store.createTransaction(Akonadi2::Storage::ReadOnly);
55 auto db = transaction.openDatabase(name, nullptr, false);
56 QByteArray result;
57 db.scan(uid, [&](const QByteArray &key, const QByteArray &value) {
58 result = value;
59 return true;
60 });
61 return result;
62}
63
64flatbuffers::FlatBufferBuilder &createEvent(flatbuffers::FlatBufferBuilder &entityFbb, const QString &s = QString("summary"))
65{
66 flatbuffers::FlatBufferBuilder eventFbb;
67 eventFbb.Clear();
68 {
69 Akonadi2::ApplicationDomain::Buffer::EventBuilder eventBuilder(eventFbb);
70 auto eventLocation = eventBuilder.Finish();
71 Akonadi2::ApplicationDomain::Buffer::FinishEventBuffer(eventFbb, eventLocation);
72 }
73
74 flatbuffers::FlatBufferBuilder localFbb;
75 {
76 auto uid = localFbb.CreateString("testuid");
77 auto summary = localFbb.CreateString(s.toStdString());
78 auto localBuilder = Akonadi2::ApplicationDomain::Buffer::EventBuilder(localFbb);
79 localBuilder.add_uid(uid);
80 localBuilder.add_summary(summary);
81 auto location = localBuilder.Finish();
82 Akonadi2::ApplicationDomain::Buffer::FinishEventBuffer(localFbb, location);
83 }
84
85 Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, eventFbb.GetBufferPointer(), eventFbb.GetSize(), localFbb.GetBufferPointer(), localFbb.GetSize());
86 return entityFbb;
87}
88
89QByteArray createEntityCommand(const flatbuffers::FlatBufferBuilder &entityFbb)
90{
91 flatbuffers::FlatBufferBuilder fbb;
92 auto type = fbb.CreateString(Akonadi2::ApplicationDomain::getTypeName<Akonadi2::ApplicationDomain::Event>().toStdString().data());
93 auto delta = fbb.CreateVector<uint8_t>(entityFbb.GetBufferPointer(), entityFbb.GetSize());
94 Akonadi2::Commands::CreateEntityBuilder builder(fbb);
95 builder.add_domainType(type);
96 builder.add_delta(delta);
97 auto location = builder.Finish();
98 Akonadi2::Commands::FinishCreateEntityBuffer(fbb, location);
99
100 const QByteArray command(reinterpret_cast<const char *>(fbb.GetBufferPointer()), fbb.GetSize());
101 {
102 flatbuffers::Verifier verifyer(reinterpret_cast<const uint8_t *>(command.data()), command.size());
103 Q_ASSERT(Akonadi2::Commands::VerifyCreateEntityBuffer(verifyer));
104 }
105 return command;
106}
107
108QByteArray modifyEntityCommand(const flatbuffers::FlatBufferBuilder &entityFbb, const QByteArray &uid, qint64 revision)
109{
110 flatbuffers::FlatBufferBuilder fbb;
111 auto type = fbb.CreateString(Akonadi2::ApplicationDomain::getTypeName<Akonadi2::ApplicationDomain::Event>().toStdString().data());
112 auto id = fbb.CreateString(std::string(uid.constData(), uid.size()));
113 auto delta = fbb.CreateVector<uint8_t>(entityFbb.GetBufferPointer(), entityFbb.GetSize());
114 // auto delta = Akonadi2::EntityBuffer::appendAsVector(fbb, buffer.constData(), buffer.size());
115 Akonadi2::Commands::ModifyEntityBuilder builder(fbb);
116 builder.add_domainType(type);
117 builder.add_delta(delta);
118 builder.add_revision(revision);
119 builder.add_entityId(id);
120 auto location = builder.Finish();
121 Akonadi2::Commands::FinishModifyEntityBuffer(fbb, location);
122
123 const QByteArray command(reinterpret_cast<const char *>(fbb.GetBufferPointer()), fbb.GetSize());
124 {
125 flatbuffers::Verifier verifyer(reinterpret_cast<const uint8_t *>(command.data()), command.size());
126 Q_ASSERT(Akonadi2::Commands::VerifyCreateEntityBuffer(verifyer));
127 }
128 return command;
129}
130
131QByteArray deleteEntityCommand(const QByteArray &uid, qint64 revision)
132{
133 flatbuffers::FlatBufferBuilder fbb;
134 auto type = fbb.CreateString(Akonadi2::ApplicationDomain::getTypeName<Akonadi2::ApplicationDomain::Event>().toStdString().data());
135 auto id = fbb.CreateString(std::string(uid.constData(), uid.size()));
136 Akonadi2::Commands::DeleteEntityBuilder builder(fbb);
137 builder.add_domainType(type);
138 builder.add_revision(revision);
139 builder.add_entityId(id);
140 auto location = builder.Finish();
141 Akonadi2::Commands::FinishDeleteEntityBuffer(fbb, location);
142
143 const QByteArray command(reinterpret_cast<const char *>(fbb.GetBufferPointer()), fbb.GetSize());
144 {
145 flatbuffers::Verifier verifyer(reinterpret_cast<const uint8_t *>(command.data()), command.size());
146 Q_ASSERT(Akonadi2::Commands::VerifyDeleteEntityBuffer(verifyer));
147 }
148 return command;
149}
150
151class PipelineTest : public QObject
152{
153 Q_OBJECT
154private Q_SLOTS:
155 void initTestCase()
156 {
157 Akonadi2::Log::setDebugOutputLevel(Akonadi2::Log::Trace);
158 }
159
160 void init()
161 {
162 removeFromDisk("org.kde.pipelinetest.instance1");
163 }
164
165 void testCreate()
166 {
167 flatbuffers::FlatBufferBuilder entityFbb;
168 auto command = createEntityCommand(createEvent(entityFbb));
169
170 Akonadi2::Pipeline pipeline("org.kde.pipelinetest.instance1");
171 pipeline.startTransaction();
172 pipeline.newEntity(command.constData(), command.size());
173 pipeline.commit();
174
175 auto result = getKeys("org.kde.pipelinetest.instance1", "event.main");
176 QCOMPARE(result.size(), 1);
177 }
178
179 void testModify()
180 {
181 flatbuffers::FlatBufferBuilder entityFbb;
182 auto command = createEntityCommand(createEvent(entityFbb));
183
184 Akonadi2::Pipeline pipeline("org.kde.pipelinetest.instance1");
185
186 auto adaptorFactory = QSharedPointer<TestEventAdaptorFactory>::create();
187 pipeline.setAdaptorFactory("event", adaptorFactory);
188
189 //Create the initial revision
190 pipeline.startTransaction();
191 pipeline.newEntity(command.constData(), command.size());
192 pipeline.commit();
193
194 //Get uid of written entity
195 auto keys = getKeys("org.kde.pipelinetest.instance1", "event.main");
196 QCOMPARE(keys.size(), 1);
197 const auto key = keys.first();
198 const auto uid = Akonadi2::Storage::uidFromKey(key);
199
200 //Execute the modification
201 entityFbb.Clear();
202 auto modifyCommand = modifyEntityCommand(createEvent(entityFbb, "summary2"), uid, 1);
203 pipeline.startTransaction();
204 pipeline.modifiedEntity(modifyCommand.constData(), modifyCommand.size());
205 pipeline.commit();
206
207 //Ensure we've got the new revision with the modification
208 auto buffer = getEntity("org.kde.pipelinetest.instance1", "event.main", Akonadi2::Storage::assembleKey(uid, 2));
209 QVERIFY(!buffer.isEmpty());
210 Akonadi2::EntityBuffer entityBuffer(buffer.data(), buffer.size());
211 auto adaptor = adaptorFactory->createAdaptor(entityBuffer.entity());
212 QCOMPARE(adaptor->getProperty("summary").toString(), QString("summary2"));
213 }
214
215 void testDelete()
216 {
217 flatbuffers::FlatBufferBuilder entityFbb;
218 auto command = createEntityCommand(createEvent(entityFbb));
219
220 //Create the initial revision
221 Akonadi2::Pipeline pipeline("org.kde.pipelinetest.instance1");
222 pipeline.startTransaction();
223 pipeline.newEntity(command.constData(), command.size());
224 pipeline.commit();
225
226 // const auto uid = Akonadi2::Storage::uidFromKey(key);
227 auto result = getKeys("org.kde.pipelinetest.instance1", "event.main");
228 QCOMPARE(result.size(), 1);
229
230 const auto uid = Akonadi2::Storage::uidFromKey(result.first());
231
232 //Delete entity
233 auto deleteCommand = deleteEntityCommand(uid,1);
234 pipeline.startTransaction();
235 pipeline.deletedEntity(deleteCommand.constData(), deleteCommand.size());
236 pipeline.commit();
237 }
238};
239
240QTEST_MAIN(PipelineTest)
241#include "pipelinetest.moc"