diff options
Diffstat (limited to 'tests/pipelinetest.cpp')
-rw-r--r-- | tests/pipelinetest.cpp | 241 |
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 | |||
21 | class TestEventAdaptorFactory : public DomainTypeAdaptorFactory<Akonadi2::ApplicationDomain::Event, Akonadi2::ApplicationDomain::Buffer::Event, Akonadi2::ApplicationDomain::Buffer::EventBuilder> | ||
22 | { | ||
23 | public: | ||
24 | TestEventAdaptorFactory() | ||
25 | : DomainTypeAdaptorFactory() | ||
26 | { | ||
27 | } | ||
28 | |||
29 | virtual ~TestEventAdaptorFactory() {}; | ||
30 | }; | ||
31 | |||
32 | static void removeFromDisk(const QString &name) | ||
33 | { | ||
34 | Akonadi2::Storage store(Akonadi2::Store::storageLocation(), name, Akonadi2::Storage::ReadWrite); | ||
35 | store.removeFromDisk(); | ||
36 | } | ||
37 | |||
38 | static 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 | |||
51 | static 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 | |||
64 | flatbuffers::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 | |||
89 | QByteArray 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 | |||
108 | QByteArray 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 | |||
131 | QByteArray 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 | |||
151 | class PipelineTest : public QObject | ||
152 | { | ||
153 | Q_OBJECT | ||
154 | private 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 | |||
240 | QTEST_MAIN(PipelineTest) | ||
241 | #include "pipelinetest.moc" | ||