11 #define XML_BUFFER_SIZE 4096
14 parse_xml_file(const char *filename,
15 XML_StartElementHandler start,
16 XML_EndElementHandler end,
23 parser = XML_ParserCreate(NULL);
24 XML_SetElementHandler(parser, start, end);
25 XML_SetUserData(parser, data);
27 fd = open(filename, O_RDONLY);
29 fprintf(stderr, "failed to open %s: %m\n", filename);
34 buffer = XML_GetBuffer(parser, XML_BUFFER_SIZE);
35 len = read(fd, buffer, XML_BUFFER_SIZE);
38 err = XML_ParseBuffer(parser, len, len == 0);
39 if (err == XML_STATUS_ERROR) {
40 fprintf(stderr, "parse error at line %lu:\n%s\n",
41 XML_GetCurrentLineNumber(parser),
42 XML_ErrorString(XML_GetErrorCode(parser)));
48 fprintf(stderr, "read: %m\n");
56 struct razor_set *system_set, *repo_set, *result_set;
58 struct razor_importer *importer;
59 struct razor_set **importer_set;
61 struct razor_transaction *trans;
63 char *install_pkgs[3], *remove_pkgs[3];
64 int n_install_pkgs, n_remove_pkgs;
73 get_atts(const char **atts, ...)
76 const char *name, **ptr;
80 while (name = va_arg(ap, const char *), name != NULL) {
81 ptr = va_arg(ap, const char **);
83 for (i = 0; atts[i]; i += 2) {
84 if (strcmp(atts[i], name) == 0)
91 static enum razor_property_flags
92 parse_relation (const char *rel_str)
96 if (rel_str[0] == 'L')
97 return rel_str[1] == 'E' ? RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL : RAZOR_PROPERTY_LESS;
98 else if (rel_str[0] == 'G')
99 return rel_str[1] == 'E' ? RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL : RAZOR_PROPERTY_GREATER;
100 else if (rel_str[0] == 'E' || rel_str[1] == 'Q')
101 return RAZOR_PROPERTY_EQUAL;
107 start_test(struct test_context *ctx, const char **atts)
109 const char *name = NULL;
111 get_atts(atts, "name", &name, NULL);
113 fprintf(stderr, "Test with no name\n");
116 printf("%s\n", name);
120 end_test(struct test_context *ctx)
122 if (ctx->system_set) {
123 razor_set_destroy(ctx->system_set);
124 ctx->system_set = NULL;
127 razor_set_destroy(ctx->repo_set);
128 ctx->repo_set = NULL;
130 if (ctx->result_set) {
131 razor_set_destroy(ctx->result_set);
132 ctx->result_set = NULL;
135 razor_transaction_destroy(ctx->trans);
141 start_set(struct test_context *ctx, const char **atts)
143 const char *name = NULL;
145 ctx->importer = razor_importer_create();
146 get_atts(atts, "name", &name, NULL);
148 ctx->importer_set = &ctx->result_set;
149 else if (!strcmp(name, "system"))
150 ctx->importer_set = &ctx->system_set;
151 else if (!strcmp(name, "repo"))
152 ctx->importer_set = &ctx->repo_set;
154 fprintf(stderr, " bad set name '%s'\n", name);
160 end_set(struct test_context *ctx)
162 *ctx->importer_set = razor_importer_finish(ctx->importer);
163 ctx->importer = NULL;
167 start_package(struct test_context *ctx, const char **atts)
169 const char *name = NULL, *version = NULL, *arch = NULL;
171 get_atts(atts, "name", &name,
177 fprintf(stderr, " package with no name\n");
181 razor_importer_begin_package(ctx->importer, name, version, arch);
182 razor_importer_add_property(ctx->importer, name,
183 RAZOR_PROPERTY_EQUAL | RAZOR_PROPERTY_PROVIDES,
188 end_package(struct test_context *ctx)
190 razor_importer_finish_package(ctx->importer);
194 add_property(struct test_context *ctx, enum razor_property_flags type, const char *name, enum razor_property_flags rel, const char *version)
196 razor_importer_add_property(ctx->importer, name,
197 rel | type, version);
201 razor_property_flags_relation_to_string(enum razor_property_flags rel)
203 if (rel == RAZOR_PROPERTY_LESS)
205 if (rel == (RAZOR_PROPERTY_EQUAL | RAZOR_PROPERTY_LESS))
207 if (rel == RAZOR_PROPERTY_EQUAL)
209 if (rel == (RAZOR_PROPERTY_EQUAL | RAZOR_PROPERTY_GREATER))
211 if (rel == RAZOR_PROPERTY_GREATER)
218 check_unsatisfiable_property(struct test_context *ctx,
219 enum razor_property_flags type,
221 enum razor_property_flags rel,
227 if (razor_transaction_unsatisfied_property(ctx->trans,
228 name, rel | type, version))
231 fprintf(stderr, " didn't get unsatisfiable '%s %s %s'\n",
232 name, razor_property_flags_relation_to_string(rel), version);
237 start_property(struct test_context *ctx, enum razor_property_flags type, const char **atts)
239 const char *name = NULL, *rel_str = NULL, *version = NULL;
240 enum razor_property_flags rel;
242 get_atts(atts, "name", &name, "relation", &rel_str, "version", &version, NULL);
244 fprintf(stderr, " no name specified for property\n");
248 rel = parse_relation(rel_str);
250 fprintf(stderr, " bad or missing version relation for property %s\n", name);
254 rel = RAZOR_PROPERTY_EQUAL;
257 check_unsatisfiable_property(ctx, type, name, rel, version);
259 add_property(ctx, type, name, rel, version);
263 start_transaction(struct test_context *ctx, const char **atts)
265 ctx->n_install_pkgs = 0;
266 ctx->n_remove_pkgs = 0;
270 end_transaction(struct test_context *ctx)
272 struct razor_package *pkg;
275 ctx->trans = razor_transaction_create(ctx->system_set, ctx->repo_set);
276 for (i = 0; i < ctx->n_install_pkgs; i++) {
277 pkg = razor_set_get_package(ctx->repo_set,
278 ctx->install_pkgs[i]);
279 razor_transaction_install_package(ctx->trans, pkg);
281 for (i = 0; i < ctx->n_remove_pkgs; i++) {
282 pkg = razor_set_get_package(ctx->system_set,
283 ctx->remove_pkgs[i]);
285 pkg = razor_set_get_package(ctx->repo_set,
286 ctx->remove_pkgs[i]);
288 razor_transaction_remove_package(ctx->trans, pkg);
291 razor_transaction_resolve(ctx->trans);
292 errors = razor_transaction_describe(ctx->trans);
295 while (ctx->n_install_pkgs--)
296 free(ctx->install_pkgs[ctx->n_install_pkgs]);
297 while (ctx->n_remove_pkgs--)
298 free(ctx->remove_pkgs[ctx->n_remove_pkgs]);
301 struct razor_set *new;
302 new = razor_transaction_finish(ctx->trans);
304 ctx->system_set = new;
309 start_install_or_update(struct test_context *ctx, const char **atts)
311 const char *name = NULL;
313 get_atts(atts, "name", &name, NULL);
315 fprintf(stderr, " install/update with no name\n");
319 ctx->install_pkgs[ctx->n_install_pkgs++] = strdup(name);
323 start_remove(struct test_context *ctx, const char **atts)
325 const char *name = NULL;
327 get_atts(atts, "name", &name, NULL);
329 fprintf(stderr, " remove with no name\n");
333 ctx->remove_pkgs[ctx->n_remove_pkgs++] = strdup(name);
337 start_result(struct test_context *ctx, const char **atts)
343 diff_callback(enum razor_diff_action action,
344 struct razor_package *package,
350 struct test_context *ctx = data;
353 if (action == RAZOR_DIFF_ACTION_REMOVE) {
354 fprintf(stderr, " result set should not contain %s %s\n",
357 fprintf(stderr, " result set should contain %s %s\n",
363 end_result(struct test_context *ctx)
367 if (ctx->result_set) {
368 if (!ctx->system_set)
369 ctx->system_set = razor_set_create();
370 razor_set_diff(ctx->system_set, ctx->result_set,
376 start_unsatisfiable(struct test_context *ctx, const char **atts)
378 if (ctx->result_set) {
379 fprintf(stderr, "Expected to fail, but didn't\n");
387 end_unsatisfiable(struct test_context *ctx)
393 start_test_element(void *data, const char *element, const char **atts)
395 struct test_context *ctx = data;
397 if (strcmp(element, "tests") == 0) {
399 } else if (strcmp(element, "test") == 0) {
400 start_test(ctx, atts);
401 } else if (strcmp(element, "set") == 0) {
402 start_set(ctx, atts);
403 } else if (strcmp(element, "transaction") == 0) {
404 start_transaction(ctx, atts);
405 } else if (strcmp(element, "install") == 0) {
406 start_install_or_update(ctx, atts);
407 } else if (strcmp(element, "install") == 0) {
408 start_install_or_update(ctx, atts);
409 } else if (strcmp(element, "remove") == 0) {
410 start_remove(ctx, atts);
411 } else if (strcmp(element, "result") == 0) {
412 start_result(ctx, atts);
413 } else if (strcmp(element, "unsatisfiable") == 0) {
414 start_unsatisfiable(ctx, atts);
415 } else if (strcmp(element, "package") == 0) {
416 start_package(ctx, atts);
417 } else if (strcmp(element, "requires") == 0) {
418 start_property(ctx, RAZOR_PROPERTY_REQUIRES, atts);
419 } else if (strcmp(element, "provides") == 0) {
420 start_property(ctx, RAZOR_PROPERTY_PROVIDES, atts);
421 } else if (strcmp(element, "conflicts") == 0) {
422 start_property(ctx, RAZOR_PROPERTY_CONFLICTS, atts);
423 } else if (strcmp(element, "obsoletes") == 0) {
424 start_property(ctx, RAZOR_PROPERTY_OBSOLETES, atts);
426 fprintf(stderr, "Unrecognized element '%s'\n", element);
432 end_test_element (void *data, const char *element)
434 struct test_context *ctx = data;
436 if (strcmp(element, "test") == 0) {
438 } else if (strcmp(element, "set") == 0) {
440 } else if (strcmp(element, "package") == 0) {
442 } else if (strcmp(element, "transaction") == 0) {
443 end_transaction(ctx);
444 } else if (strcmp(element, "result") == 0) {
446 } else if (strcmp(element, "unsatisfiable") == 0) {
447 end_unsatisfiable(ctx);
451 int main(int argc, char *argv[])
453 struct test_context ctx;
454 const char *test_file;
456 memset(&ctx, 0, sizeof ctx);
459 fprintf(stderr, "usage: %s [-d] [TESTS-FILE]\n", argv[0]);
463 if (argc >= 2 && !strcmp (argv[1], "-d")) {
471 test_file = "test.xml";
473 parse_xml_file(test_file, start_test_element, end_test_element, &ctx);
476 fprintf(stderr, "\n%d errors\n", ctx.errors);