8a457dabcb4af03e9e08d2d18097f3519ae9d343
[platform/core/system/libdbuspolicy.git] / src / test-serializer.cpp
1 /*  MIT License
2  *
3  * Copyright (c) 2019-2020 Samsung Electronics Co., Ltd
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to deal
7  * in the Software without restriction, including without limitation the rights
8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9  * copies of the Software, and to permit persons to whom the Software is furnished
10  * to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21  * THE SOFTWARE. */
22 #include "internal/include/fb_generated.h"
23 #include "internal/include/flatbuffers/flatbuffers.h"
24 #include "internal/policy_containers.hpp"
25 #include "internal/serializer.hpp"
26 #include <cstdarg>
27 #include <iostream>
28 #include <ostream>
29
30 namespace ldp_xml_parser {
31
32 static void print_error(const char *fmt...) {
33         va_list args;
34         va_start(args, fmt);
35         printf("[ERROR]: ");
36         vprintf(fmt, args);
37         printf("\n");
38         va_end(args);
39 }
40
41 std::map<FB::MessageType, const char *> messageTypeMap = {
42         { FB::MessageType_ANY,           "ANY"           },
43         { FB::MessageType_MIN,           "MIN"           },
44         { FB::MessageType_MAX,           "MAX"           },
45         { FB::MessageType_METHOD_RETURN, "METHOD_RETURN" },
46         { FB::MessageType_ERROR,         "ERROR"         },
47         { FB::MessageType_SIGNAL,        "SIGNAL"        },
48         { FB::MessageType_METHOD_CALL,   "METHOD_CALL"   }
49 };
50
51 std::map<FB::Decision, const char *> decisionTypeMap = {
52         { FB::Decision_ANY,   "ANY"   },
53         { FB::Decision_MIN,   "MIN"   },
54         { FB::Decision_MAX,   "MAX"   },
55         { FB::Decision_CHECK, "CHECK" },
56         { FB::Decision_DENY,  "DENY"  },
57         { FB::Decision_ALLOW, "ALLOW" }
58 };
59
60 std::map<FB::BusAccessType, const char *> busTypeMap = {
61         { FB::BusAccessType_MIN,        "MIN"        },
62         { FB::BusAccessType_MAX,        "MAX"        },
63         { FB::BusAccessType_USER,       "USER"       },
64         { FB::BusAccessType_GROUP,      "GROUP"      },
65         { FB::BusAccessType_ALL_USERS,  "ALL_USERS"  },
66         { FB::BusAccessType_ALL_GROUPS, "ALL_GROUPS" },
67 };
68
69 struct TestsHelper {
70         static const char *to_str(const bool value) {
71                 return value ? "true" : "false";
72         }
73
74         static const char *to_str(const char *value) {
75                 return value;
76         }
77
78         static const char *to_str(const std::string & value) {
79                 return value.c_str();
80         }
81
82         static const char *to_str(const FB::MessageType value) {
83                 return messageTypeMap[value];
84         }
85
86         static const char *to_str(const FB::Decision value) {
87                 return decisionTypeMap[value];
88         }
89
90         static const char *to_str(const FB::BusAccessType value) {
91                 return busTypeMap[value];
92         }
93
94         template <typename T>
95         static bool compare(const T current, const T expected) {
96                 if (current != expected) {
97                         // print_error("Current: \"%s\" expected: \"%s\"", to_str(current), to_str(expected));
98                         return false;
99                 }
100                 return true;
101         }
102
103         template <typename T>
104         static void print_property(const char *name, const T value) {
105                 std::cout << name << ": " << to_str(value) << std::endl;
106         }
107 };
108
109 using TH = TestsHelper;
110
111 struct NodeTest {
112         const std::string name;
113         const std::string privilege;
114         const FB::Decision decision;
115         const std::string prefix_privilege;
116         const FB::Decision prefix_decision;
117
118         void printContent() const {
119                 TH::print_property("name", name);
120                 TH::print_property("privilege", privilege);
121                 TH::print_property("decision", decision);
122                 TH::print_property("prefix_privilege", prefix_privilege);
123                 TH::print_property("prefix_decision", prefix_decision);
124         }
125
126         bool isMatch(const FB::PolicyOwnNode *node, const std::string &token) const {
127                 return (TH::compare(node->token()->str(), token) &&
128                         TH::compare(node->decision_item()->privilege()->str(), privilege) &&
129                         TH::compare(node->decision_item()->decision(), decision) &&
130                         TH::compare(node->prefix_decision_item()->privilege()->str(), prefix_privilege) &&
131                         TH::compare(node->prefix_decision_item()->decision(), prefix_decision));
132         }
133 };
134
135 struct ItemSRTest {
136         const std::string name;
137         const std::string interface;
138         const std::string member;
139         const std::string path;
140         const FB::MessageType type;
141         const bool is_name_prefix;
142         const FB::Decision decision;
143
144         void printContent() const {
145                 TH::print_property("name", name);
146                 TH::print_property("interface", interface);
147                 TH::print_property("member", member);
148                 TH::print_property("path", path);
149                 TH::print_property("type", type);
150                 TH::print_property("is_name_prefix", is_name_prefix);
151                 TH::print_property("decision", decision);
152         }
153
154         template <typename T>
155         bool isMatch(const T *item) const {
156                 return TH::compare(item->name()->str(), name) &&
157                         TH::compare(item->interface()->str(), interface) &&
158                         TH::compare(item->member()->str(), member) &&
159                         TH::compare(item->path()->str(), path) &&
160                         TH::compare(item->type(), type) &&
161                         TH::compare(item->is_name_prefix(), is_name_prefix) &&
162                         TH::compare(item->decision()->decision(), decision);
163         }
164 };
165
166 struct ItemAccessTest {
167         const uid_t uid;
168         const gid_t gid;
169         const FB::Decision decision;
170         const std::string privilege;
171         const FB::BusAccessType type;
172
173         void printContent() const {
174                 TH::print_property("uid", uid);
175                 TH::print_property("gid", gid);
176                 TH::print_property("decision", decision);
177                 TH::print_property("privilege", privilege);
178                 TH::print_property("type", type);
179         }
180
181         bool isMatch(const FB::ItemAccess *item) const {
182                 return TH::compare(item->uid(), uid) &&
183                         TH::compare(item->gid(), gid) &&
184                         TH::compare(item->decision()->decision(), decision) &&
185                         TH::compare(item->decision()->privilege()->str(), privilege) &&
186                         TH::compare(item->type(), type);
187         }
188 };
189
190
191 std::vector<NodeTest> context_default_tests = {
192         { "org",                 "",                                                FB::Decision_ANY,   "",                                                FB::Decision_ANY   },
193         { "org.tizen",           "",                                                FB::Decision_ANY,   "",                                                FB::Decision_ANY   },
194         { "org.tizen.pok2",      "",                                                FB::Decision_ANY,   "privilege1",                                      FB::Decision_CHECK },
195         { "org.tizen.pok2.a",    "",                                                FB::Decision_ANY,   "",                                                FB::Decision_DENY  },
196         { "org.tizen.pok2.a.b",  "",                                                FB::Decision_ANY,   "privilege2",                                      FB::Decision_CHECK },
197         { "org.tizen.pnope",     "http://tizen.org/privilege/packagemanager.nope",  FB::Decision_CHECK, "",                                                FB::Decision_ANY   },
198         { "org.tizen.pok1.a1",   "http://tizen.org/privilege/packagemanager.nope",  FB::Decision_CHECK, "http://tizen.org/privilege/packagemanager.admin", FB::Decision_CHECK },
199         { "org.tizen.pok1.a",    "",                                                FB::Decision_ANY,   "",                                                FB::Decision_DENY  },
200         { "org.tizen.pok1.a.b4", "http://tizen.org/privilege/packagemanager.nope",  FB::Decision_CHECK, "",                                                FB::Decision_ANY   },
201         { "org.tizen.pok1.a.b3", "",                                                FB::Decision_ANY,   "http://tizen.org/privilege/packagemanager.nope",  FB::Decision_CHECK },
202         { "org.tizen.pok1.a.b2", "http://tizen.org/privilege/packagemanager.admin", FB::Decision_CHECK, "",                                                FB::Decision_ANY   },
203         { "org.tizen.pok1.a.b1", "",                                                FB::Decision_ANY,   "http://tizen.org/privilege/packagemanager.admin", FB::Decision_CHECK },
204         { "org.tizen.pok",       "http://tizen.org/privilege/packagemanager.admin", FB::Decision_CHECK, "",                                                FB::Decision_ANY   },
205 };
206
207 std::vector<NodeTest> context_mandatory_tests = {};
208
209 std::vector<NodeTest> user_root_tests = {
210         { "org",                        "", FB::Decision_ANY,   "", FB::Decision_ANY   },
211         { "org.tizen",                  "", FB::Decision_ANY,   "", FB::Decision_ANY   },
212         { "org.tizen.a1",               "", FB::Decision_ANY,   "", FB::Decision_ALLOW },
213         { "org.tizen.a1.b",             "", FB::Decision_DENY,  "", FB::Decision_ANY   },
214         { "org.tizen.b",                "", FB::Decision_ANY,   "", FB::Decision_ANY   },
215         { "org.tizen.b.z",              "", FB::Decision_ALLOW, "", FB::Decision_ANY   },
216         { "org.tizen.b.c",              "", FB::Decision_ANY,   "", FB::Decision_ALLOW },
217         { "org.tizen.a",                "", FB::Decision_ANY,   "", FB::Decision_ALLOW },
218         { "org.tizen.a.d",              "", FB::Decision_ANY,   "", FB::Decision_ALLOW },
219         { "org.tizen.a.c",              "", FB::Decision_DENY,  "", FB::Decision_ALLOW },
220         { "org.tizen.a.b",              "", FB::Decision_ANY,   "", FB::Decision_DENY  },
221         { "org.tizen.a.b.c2",           "", FB::Decision_ANY,   "", FB::Decision_ALLOW },
222         { "org.tizen.a.b.c1",           "", FB::Decision_ANY,   "", FB::Decision_DENY  },
223         { "org.tizen.a.b.c1.d",         "", FB::Decision_ANY,   "", FB::Decision_ANY   },
224         { "org.tizen.a.b.c1.d.e",       "", FB::Decision_ANY,   "", FB::Decision_ANY   },
225         { "org.tizen.a.b.c1.d.e.f",     "", FB::Decision_ANY,   "", FB::Decision_ANY   },
226         { "org.tizen.a.b.c1.d.e.f.g",   "", FB::Decision_ALLOW, "", FB::Decision_ANY   },
227         { "org.tizen.a.b.c3",           "", FB::Decision_DENY,  "", FB::Decision_ALLOW },
228         { "org.tizen.a.b.c3.d",         "", FB::Decision_ANY,   "", FB::Decision_DENY  },
229         { "org.tizen.a.b.c3.d.esth",    "", FB::Decision_ALLOW, "", FB::Decision_ANY   },
230         { "org.tizen.a.b.c3.d.e",       "", FB::Decision_ANY,   "", FB::Decision_ALLOW },
231         { "org.tizen.a.b.c3.d.e.f",     "", FB::Decision_DENY,  "", FB::Decision_ANY   },
232         { "org.tizen.a.b.c3.d.e.f.g",   "", FB::Decision_ALLOW, "", FB::Decision_ANY   },
233         { "org.tizen.a.b.c",            "", FB::Decision_ANY,   "", FB::Decision_ALLOW },
234         { "org.tizen.a.b.c.d",          "", FB::Decision_ANY,   "", FB::Decision_DENY  },
235         { "org.tizen.a.b.c.d.esth",     "", FB::Decision_ALLOW, "", FB::Decision_ANY   },
236         { "org.tizen.a.b.c.d.e",        "", FB::Decision_ANY,   "", FB::Decision_ALLOW },
237         { "org.tizen.a.b.c.d.e.f",      "", FB::Decision_DENY,  "", FB::Decision_ANY   },
238         { "org.tizen.a.bsth",           "", FB::Decision_DENY,  "", FB::Decision_ANY   },
239         { "org.tizen.ldposd",           "", FB::Decision_ALLOW, "", FB::Decision_ANY   },
240         { "org.tizen.ldposa",           "", FB::Decision_ALLOW, "", FB::Decision_ANY   },
241         { "org.tizen.test",             "", FB::Decision_ANY,   "", FB::Decision_ANY   },
242         { "org.tizen.test.dest_prefix", "", FB::Decision_ANY,   "", FB::Decision_ALLOW },
243         { "org.tizen.ldpoga",           "", FB::Decision_ALLOW, "", FB::Decision_ANY   },
244         { "org.tizen.ldpo",             "", FB::Decision_ANY,   "", FB::Decision_ALLOW },
245         { "org.tizen.ldpogd",           "", FB::Decision_ALLOW, "", FB::Decision_ANY   },
246 };
247
248 std::vector<ItemSRTest> item_send_context_default_tests {
249         { "",                     "",                                    "",                            "", FB::MessageType_METHOD_CALL, false, FB::Decision_DENY  },
250         { "org.freedesktop.DBus", "org.freedesktop.DBus",                "",                            "", FB::MessageType_ANY,         false, FB::Decision_ALLOW },
251         { "org.freedesktop.DBus", "org.freedesktop.DBus.Introspectable", "",                            "", FB::MessageType_ANY,         false, FB::Decision_ALLOW },
252         { "org.freedesktop.DBus", "org.freedesktop.DBus",                "UpdateActivationEnvironment", "", FB::MessageType_ANY,         false, FB::Decision_DENY  },
253         { "org.freedesktop.DBus", "org.freedesktop.DBus.Debug.Stats",    "",                            "", FB::MessageType_ANY,         false, FB::Decision_DENY  },
254         { "org.freedesktop.DBus", "org.freedesktop.systemd1.Activator",  "",                            "", FB::MessageType_ANY,         false, FB::Decision_DENY  },
255 };
256
257 std::vector<ItemSRTest> item_receive_context_default_test {
258         { "", "", "", "", FB::MessageType_METHOD_CALL,   false, FB::Decision_ALLOW },
259         { "", "", "", "", FB::MessageType_METHOD_RETURN, false, FB::Decision_ALLOW },
260         { "", "", "", "", FB::MessageType_ERROR,         false, FB::Decision_ALLOW },
261         { "", "", "", "", FB::MessageType_SIGNAL,        false, FB::Decision_ALLOW },
262 };
263
264 std::vector<ItemSRTest> item_send_root_tests {
265         { "org.tizen.test.dest_prefix.ap",                   "", "", "", FB::MessageType_ANY, true,  FB::Decision_ALLOW },
266         { "org.tizen.test.dest_prefix.ao",                   "", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW },
267         { "org.tizen.test.dest_prefix.ap.1.d",               "", "", "", FB::MessageType_ANY, false, FB::Decision_DENY  },
268         { "org.tizen.test.dest_prefix.ap.1.dp",              "", "", "", FB::MessageType_ANY, true,  FB::Decision_DENY  },
269         { "org.tizen.test.dest_prefix.ap.1.d.ap",            "", "", "", FB::MessageType_ANY, true,  FB::Decision_ALLOW },
270         { "org.tizen.test.dest_prefix.ap.1.dp.ap",           "", "", "", FB::MessageType_ANY, true,  FB::Decision_ALLOW },
271         { "org.tizen.test.dest_prefix.ap.1.dp.a",            "", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW },
272
273         { "org.tizen.test.dest_prefix.ap.2.apxdp",           "", "", "", FB::MessageType_ANY, true,  FB::Decision_ALLOW },
274         { "org.tizen.test.dest_prefix.ap.2.apxdp.dp",        "", "", "", FB::MessageType_ANY, true,  FB::Decision_DENY  },
275         { "org.tizen.test.dest_prefix.ap.2.apxdp.dp.ap",     "", "", "", FB::MessageType_ANY, true,  FB::Decision_ALLOW },
276         { "org.tizen.test.dest_prefix.ap.2.apxdp.dp.ap.d",   "", "", "", FB::MessageType_ANY, false, FB::Decision_DENY  },
277
278         { "org.tizen.test.dest_prefix.ap.3.dpxap",           "", "", "", FB::MessageType_ANY, true,  FB::Decision_DENY  },
279         { "org.tizen.test.dest_prefix.ap.3.dpxap.ap",        "", "", "", FB::MessageType_ANY, true,  FB::Decision_ALLOW },
280         { "org.tizen.test.dest_prefix.ap.3.dpxap.ap.dp",     "", "", "", FB::MessageType_ANY, true,  FB::Decision_DENY  },
281         { "org.tizen.test.dest_prefix.ap.3.dpxap.ap.dp.ap",  "", "", "", FB::MessageType_ANY, true,  FB::Decision_ALLOW },
282         { "org.tizen.test.dest_prefix.ap.3.dpxap.ap.dp.a",   "", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW },
283         { "org.tizen.test.dest_prefix.ap.3.dpxap",           "", "", "", FB::MessageType_ANY, true,  FB::Decision_ALLOW },
284
285         { "org.tizen.test.dest_prefix.dp",                   "", "", "", FB::MessageType_ANY, true,  FB::Decision_DENY  },
286
287         { "org.tizen.test.dest_prefix.do",                   "", "", "", FB::MessageType_ANY, false, FB::Decision_DENY  },
288         { "org.tizen.test.dest_prefix.ao.ao",                "", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW },
289
290         { "org.tizen.test.dest_prefix.dp.1.a",               "", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW },
291         { "org.tizen.test.dest_prefix.dp.1.ap",              "", "", "", FB::MessageType_ANY, true,  FB::Decision_ALLOW },
292
293         { "org.tizen.test.dest_prefix.dp.1.a.dp",            "", "", "", FB::MessageType_ANY, true,  FB::Decision_DENY  },
294         { "org.tizen.test.dest_prefix.dp.1.ap.dp",           "", "", "", FB::MessageType_ANY, true,  FB::Decision_DENY  },
295         { "org.tizen.test.dest_prefix.dp.1.ap.d",            "", "", "", FB::MessageType_ANY, false, FB::Decision_DENY  },
296
297         { "org.tizen.test.dest_prefix.dp.2.dpxap",           "", "", "", FB::MessageType_ANY, true,  FB::Decision_DENY  },
298         { "org.tizen.test.dest_prefix.dp.2.dpxap.ap",        "", "", "", FB::MessageType_ANY, true,  FB::Decision_ALLOW },
299         { "org.tizen.test.dest_prefix.dp.2.dpxap.ap.dp",     "", "", "", FB::MessageType_ANY, true,  FB::Decision_DENY  },
300         { "org.tizen.test.dest_prefix.dp.2.dpxap.ap.dp.a",   "", "", "", FB::MessageType_ANY, false, FB::Decision_ALLOW },
301
302         { "org.tizen.test.dest_prefix.dp.2.dpxap",           "", "", "", FB::MessageType_ANY, true,  FB::Decision_ALLOW },
303         { "org.tizen.test.dest_prefix.dp.2.dpxap.ap.d",      "", "", "", FB::MessageType_ANY, false, FB::Decision_DENY  },
304         { "org.tizen.test.dest_prefix.dp.2.dpxap.ap.dp.f.d", "", "", "", FB::MessageType_ANY, false, FB::Decision_DENY  },
305         { "org.tizen.test.dest_prefix.dp.2.dpxap.f.f.f.dp",  "", "", "", FB::MessageType_ANY, true,  FB::Decision_DENY  },
306
307         { "org.tizen.test.dest_prefix.dp.3.apxdp",           "", "", "", FB::MessageType_ANY, true,  FB::Decision_ALLOW },
308         { "org.tizen.test.dest_prefix.dp.3.apxdp.dp",        "", "", "", FB::MessageType_ANY, true,  FB::Decision_DENY  },
309         { "org.tizen.test.dest_prefix.dp.3.apxdp.dp.ap",     "", "", "", FB::MessageType_ANY, true,  FB::Decision_ALLOW },
310         { "org.tizen.test.dest_prefix.dp.3.apxdp.dp.ap.dp",  "", "", "", FB::MessageType_ANY, true,  FB::Decision_DENY  },
311         { "org.tizen.test.dest_prefix.dp.3.apxdp.dp.ap.d",   "", "", "", FB::MessageType_ANY, false, FB::Decision_DENY  },
312         { "org.tizen.test.dest_prefix.dp.3.apxdp",           "", "", "", FB::MessageType_ANY, true,  FB::Decision_DENY  },
313
314 };
315
316 std::vector<ItemAccessTest> item_access_context_default_test {
317         { 0,    0,  FB::Decision_ALLOW, "",           FB::BusAccessType_ALL_USERS },
318         { 1,    0,  FB::Decision_DENY,  "",           FB::BusAccessType_USER      },
319         { 2,    0,  FB::Decision_DENY,  "",           FB::BusAccessType_USER      },
320         { 0,    20, FB::Decision_ALLOW, "",           FB::BusAccessType_GROUP     },
321         { 0,    30, FB::Decision_DENY,  "",           FB::BusAccessType_GROUP     },
322         { 3,    0,  FB::Decision_ALLOW, "",           FB::BusAccessType_USER      },
323         { 7,    0,  FB::Decision_ALLOW, "",           FB::BusAccessType_USER      },
324         { 8,    0,  FB::Decision_DENY,  "",           FB::BusAccessType_USER      },
325         { 9991, 0,  FB::Decision_CHECK, "privilege1", FB::BusAccessType_USER      },
326         { 9992, 0,  FB::Decision_CHECK, "privilege2", FB::BusAccessType_USER      },
327         { 9993, 0,  FB::Decision_CHECK, "privilege1", FB::BusAccessType_USER      },
328         { 888,  0,  FB::Decision_CHECK, "privilege1", FB::BusAccessType_USER      },
329 };
330
331
332 std::vector<ItemAccessTest> item_access_context_mandatory_test {
333         { 6,    0,    FB::Decision_DENY,  "",           FB::BusAccessType_USER  },
334         { 7,    0,    FB::Decision_DENY,  "",           FB::BusAccessType_USER  },
335         { 8,    0,    FB::Decision_ALLOW, "",           FB::BusAccessType_USER  },
336         { 0,    9992, FB::Decision_CHECK, "privilege1", FB::BusAccessType_GROUP },
337         { 9993, 0,    FB::Decision_CHECK, "privilege2", FB::BusAccessType_USER  },
338 };
339
340 class SerializerTests {
341         ldp_serializer::Serializer serializer;
342         const FB::File *file;
343
344         void serialize_xml(const std::string &file_name) {
345                 size_t size;
346                 auto buff = serializer.serialize(file_name, size);
347
348                 file = FB::GetFile(buff);
349         }
350
351         bool check_tree(const std::string &token, const FB::PolicyOwnNode *nnode, const NodeTest &test) {
352                 size_t dot = token.find('.');
353                 if (dot == std::string::npos) {
354                         auto node = nnode->children()->LookupByKey(token.c_str());
355                         if (node == nullptr) {
356                                 print_error("node %s not found for:", TH::to_str(token));
357                                 test.printContent();
358                                 return false;
359                         }
360
361                         if (!test.isMatch(node, token)) {
362                                 print_error("No matching child found for test:");
363                                 test.printContent();
364                                 return false;
365                         }
366
367                         return true;
368                 } else {
369                         std::string part = token.substr(0, dot);
370                         std::string rest = token.substr(dot + 1);
371
372                         auto new_node = nnode->children()->LookupByKey(part.c_str());
373                         if (new_node == nullptr) {
374                                 print_error("node %s not found", TH::to_str(part));
375                                 return false;
376                         }
377                         return check_tree(rest, new_node, test);
378                 }
379         }
380
381         bool check_tree(const FB::PolicyOwnNode *tree, const std::vector<NodeTest> &tree_tests) {
382                 for (const auto &test : tree_tests) {
383                         if (!check_tree(test.name, tree, test))
384                                 return false;
385                 }
386                 return true;
387         }
388
389         bool check_own_set() {
390                 return check_tree(file->m_own_set()->context_default()->tree(), context_default_tests) &&
391                         check_tree(file->m_own_set()->context_mandatory()->tree(), context_mandatory_tests) &&
392                         check_tree(file->m_own_set()->user()->LookupByKey(0)->policy()->tree(), user_root_tests);
393         }
394
395         template <typename T, typename U>
396         bool checkPolicy(const T *policy, const std::vector<U> &tests) {
397                 for (const auto &test : tests) {
398                         bool found = false;
399                         for (const auto &item : *policy->items()) {
400                                 if (test.isMatch(item)) {
401                                         found = true;
402                                         break;
403                                 }
404                         }
405                         if (!found) {
406                                 print_error("No matching item found for test:");
407                                 test.printContent();
408                                 return false;
409                         }
410                 }
411                 return true;
412         }
413
414         bool check_send_set() {
415                 return checkPolicy(file->m_send_set()->context_default(), item_send_context_default_tests) &&
416                         checkPolicy(file->m_send_set()->user()->LookupByKey(0)->policy(), item_send_root_tests);
417         }
418
419         bool check_receive_set() {
420                 return checkPolicy(file->m_receive_set()->context_default(), item_receive_context_default_test);
421         }
422
423         bool check_access_set() {
424                 return checkPolicy(file->m_access_set()->context_default(), item_access_context_default_test) &&
425                         checkPolicy(file->m_access_set()->context_mandatory(), item_access_context_mandatory_test);
426         }
427
428 public:
429         SerializerTests() : file(nullptr) {}
430         bool run_all_tests(const std::string &config) {
431                 serialize_xml(config);
432
433                 return check_own_set() &&
434                         check_send_set() &&
435                         check_receive_set() &&
436                         check_access_set();
437         }
438 };
439 }
440
441 int main() {
442         auto st = ldp_xml_parser::SerializerTests();
443         if (st.run_all_tests("tests/default_deny/system.conf"))
444                 return 0;
445         return -1;
446 }