Add a test for relocations that are valid paths but would be invalid URIs if mis-interpreted
2 * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
3 * Copyright (C) 2008 Red Hat, Inc
4 * Copyright (C) 2009 J. Ali Harlow <ali@juiblex.co.uk>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 #define XML_BUFFER_SIZE 4096
35 parse_xml_file(const char *filename,
36 XML_StartElementHandler start,
37 XML_EndElementHandler end,
44 parser = XML_ParserCreate(NULL);
45 XML_SetElementHandler(parser, start, end);
46 XML_SetUserData(parser, data);
48 fd = open(filename, O_RDONLY);
50 fprintf(stderr, "failed to open %s: %s\n", filename,
56 buffer = XML_GetBuffer(parser, XML_BUFFER_SIZE);
57 len = read(fd, buffer, XML_BUFFER_SIZE);
60 err = XML_ParseBuffer(parser, len, len == 0);
61 if (err == XML_STATUS_ERROR) {
62 fprintf(stderr, "parse error at line %lu:\n%s\n",
63 XML_GetCurrentLineNumber(parser),
64 XML_ErrorString(XML_GetErrorCode(parser)));
78 struct razor_set *system_set, *repo_set, *result_set;
80 struct razor_importer *importer;
81 struct razor_set **importer_set;
83 struct razor_transaction *trans;
85 char *install_pkgs[3], *remove_pkgs[3];
86 int n_install_pkgs, n_remove_pkgs;
95 get_atts(const char **atts, ...)
98 const char *name, **ptr;
102 while (name = va_arg(ap, const char *), name != NULL) {
103 ptr = va_arg(ap, const char **);
105 for (i = 0; atts[i]; i += 2) {
106 if (strcmp(atts[i], name) == 0)
113 static enum razor_property_flags
114 parse_relation (const char *rel_str)
118 if (rel_str[0] == 'L')
119 return rel_str[1] == 'E' ? RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL : RAZOR_PROPERTY_LESS;
120 else if (rel_str[0] == 'G')
121 return rel_str[1] == 'E' ? RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL : RAZOR_PROPERTY_GREATER;
122 else if (rel_str[0] == 'E' || rel_str[1] == 'Q')
123 return RAZOR_PROPERTY_EQUAL;
129 start_test(struct test_context *ctx, const char **atts)
131 const char *name = NULL;
133 get_atts(atts, "name", &name, NULL);
135 fprintf(stderr, "Test with no name\n");
138 printf("%s\n", name);
142 end_test(struct test_context *ctx)
144 if (ctx->system_set) {
145 razor_set_unref(ctx->system_set);
146 ctx->system_set = NULL;
149 razor_set_unref(ctx->repo_set);
150 ctx->repo_set = NULL;
152 if (ctx->result_set) {
153 razor_set_unref(ctx->result_set);
154 ctx->result_set = NULL;
157 razor_transaction_destroy(ctx->trans);
163 start_set(struct test_context *ctx, const char **atts)
165 const char *name = NULL;
167 ctx->importer = razor_importer_create();
168 get_atts(atts, "name", &name, NULL);
170 ctx->importer_set = &ctx->result_set;
171 else if (!strcmp(name, "system"))
172 ctx->importer_set = &ctx->system_set;
173 else if (!strcmp(name, "repo"))
174 ctx->importer_set = &ctx->repo_set;
176 fprintf(stderr, " bad set name '%s'\n", name);
182 end_set(struct test_context *ctx)
184 *ctx->importer_set = razor_importer_finish(ctx->importer);
185 ctx->importer = NULL;
189 start_package(struct test_context *ctx, const char **atts)
191 const char *name = NULL, *version = NULL, *arch = NULL;
193 get_atts(atts, "name", &name,
199 fprintf(stderr, " package with no name\n");
203 razor_importer_begin_package(ctx->importer, name, version, arch);
204 razor_importer_add_property(ctx->importer, name,
205 RAZOR_PROPERTY_EQUAL | RAZOR_PROPERTY_PROVIDES,
210 end_package(struct test_context *ctx)
212 razor_importer_finish_package(ctx->importer);
216 add_property(struct test_context *ctx, enum razor_property_flags type, const char *name, enum razor_property_flags rel, const char *version)
218 razor_importer_add_property(ctx->importer, name,
219 rel | type, version);
223 razor_property_flags_relation_to_string(enum razor_property_flags rel)
225 if (rel == RAZOR_PROPERTY_LESS)
227 if (rel == (RAZOR_PROPERTY_EQUAL | RAZOR_PROPERTY_LESS))
229 if (rel == RAZOR_PROPERTY_EQUAL)
231 if (rel == (RAZOR_PROPERTY_EQUAL | RAZOR_PROPERTY_GREATER))
233 if (rel == RAZOR_PROPERTY_GREATER)
240 check_unsatisfiable_property(struct test_context *ctx,
241 enum razor_property_flags type,
243 enum razor_property_flags rel,
249 if (razor_transaction_unsatisfied_property(ctx->trans,
250 name, rel | type, version))
253 fprintf(stderr, " didn't get unsatisfiable '%s %s %s'\n",
254 name, razor_property_flags_relation_to_string(rel), version);
259 start_property(struct test_context *ctx, enum razor_property_flags type, const char **atts)
261 const char *name = NULL, *rel_str = NULL, *version = NULL;
262 enum razor_property_flags rel;
264 get_atts(atts, "name", &name, "relation", &rel_str, "version", &version, NULL);
266 fprintf(stderr, " no name specified for property\n");
270 rel = parse_relation(rel_str);
272 fprintf(stderr, " bad or missing version relation for property %s\n", name);
276 rel = RAZOR_PROPERTY_EQUAL;
279 check_unsatisfiable_property(ctx, type, name, rel, version);
281 add_property(ctx, type, name, rel, version);
285 start_transaction(struct test_context *ctx, const char **atts)
287 ctx->n_install_pkgs = 0;
288 ctx->n_remove_pkgs = 0;
291 static struct razor_package *
292 get_package(struct razor_set *set, const char *package)
294 struct razor_package_iterator *pi;
295 struct razor_package *p;
296 const char *name, *version, *arch;
298 pi = razor_package_iterator_create(set);
299 while (razor_package_iterator_next(pi, &p, RAZOR_DETAIL_NAME, &name,
300 RAZOR_DETAIL_VERSION, &version,
301 RAZOR_DETAIL_ARCH, &arch,
302 RAZOR_DETAIL_LAST)) {
303 if (strcmp(package, name) == 0)
306 razor_package_iterator_destroy(pi);
312 end_transaction(struct test_context *ctx)
314 struct razor_package *pkg;
317 ctx->trans = razor_transaction_create(ctx->system_set, ctx->repo_set);
318 for (i = 0; i < ctx->n_install_pkgs; i++) {
319 pkg = get_package(ctx->repo_set, ctx->install_pkgs[i]);
320 razor_transaction_install_package(ctx->trans, pkg);
322 for (i = 0; i < ctx->n_remove_pkgs; i++) {
323 pkg = get_package(ctx->system_set, ctx->remove_pkgs[i]);
325 pkg = get_package(ctx->repo_set, ctx->remove_pkgs[i]);
327 razor_transaction_remove_package(ctx->trans, pkg);
330 razor_transaction_resolve(ctx->trans);
331 errors = razor_transaction_describe(ctx->trans);
334 while (ctx->n_install_pkgs--)
335 free(ctx->install_pkgs[ctx->n_install_pkgs]);
336 while (ctx->n_remove_pkgs--)
337 free(ctx->remove_pkgs[ctx->n_remove_pkgs]);
340 struct razor_set *new;
341 new = razor_transaction_commit(ctx->trans);
342 razor_transaction_destroy(ctx->trans);
344 ctx->system_set = new;
349 start_install_or_update(struct test_context *ctx, const char **atts)
351 const char *name = NULL;
353 get_atts(atts, "name", &name, NULL);
355 fprintf(stderr, " install/update with no name\n");
359 ctx->install_pkgs[ctx->n_install_pkgs++] = strdup(name);
363 start_remove(struct test_context *ctx, const char **atts)
365 const char *name = NULL;
367 get_atts(atts, "name", &name, NULL);
369 fprintf(stderr, " remove with no name\n");
373 ctx->remove_pkgs[ctx->n_remove_pkgs++] = strdup(name);
377 start_result(struct test_context *ctx, const char **atts)
383 diff_callback(enum razor_diff_action action,
384 struct razor_package *package,
390 struct test_context *ctx = data;
393 if (action == RAZOR_DIFF_ACTION_REMOVE) {
394 fprintf(stderr, " result set should not contain %s %s\n",
397 fprintf(stderr, " result set should contain %s %s\n",
403 end_result(struct test_context *ctx)
407 if (ctx->result_set) {
408 if (!ctx->system_set)
409 ctx->system_set = razor_set_create();
410 razor_set_diff(ctx->system_set, ctx->result_set,
416 start_unsatisfiable(struct test_context *ctx, const char **atts)
418 if (ctx->result_set) {
419 fprintf(stderr, "Expected to fail, but didn't\n");
427 end_unsatisfiable(struct test_context *ctx)
433 start_test_element(void *data, const char *element, const char **atts)
435 struct test_context *ctx = data;
437 if (strcmp(element, "tests") == 0) {
439 } else if (strcmp(element, "test") == 0) {
440 start_test(ctx, atts);
441 } else if (strcmp(element, "set") == 0) {
442 start_set(ctx, atts);
443 } else if (strcmp(element, "transaction") == 0) {
444 start_transaction(ctx, atts);
445 } else if (strcmp(element, "install") == 0) {
446 start_install_or_update(ctx, atts);
447 } else if (strcmp(element, "install") == 0) {
448 start_install_or_update(ctx, atts);
449 } else if (strcmp(element, "remove") == 0) {
450 start_remove(ctx, atts);
451 } else if (strcmp(element, "result") == 0) {
452 start_result(ctx, atts);
453 } else if (strcmp(element, "unsatisfiable") == 0) {
454 start_unsatisfiable(ctx, atts);
455 } else if (strcmp(element, "package") == 0) {
456 start_package(ctx, atts);
457 } else if (strcmp(element, "requires") == 0) {
458 start_property(ctx, RAZOR_PROPERTY_REQUIRES, atts);
459 } else if (strcmp(element, "provides") == 0) {
460 start_property(ctx, RAZOR_PROPERTY_PROVIDES, atts);
461 } else if (strcmp(element, "conflicts") == 0) {
462 start_property(ctx, RAZOR_PROPERTY_CONFLICTS, atts);
463 } else if (strcmp(element, "obsoletes") == 0) {
464 start_property(ctx, RAZOR_PROPERTY_OBSOLETES, atts);
466 fprintf(stderr, "Unrecognized element '%s'\n", element);
472 end_test_element (void *data, const char *element)
474 struct test_context *ctx = data;
476 if (strcmp(element, "test") == 0) {
478 } else if (strcmp(element, "set") == 0) {
480 } else if (strcmp(element, "package") == 0) {
482 } else if (strcmp(element, "transaction") == 0) {
483 end_transaction(ctx);
484 } else if (strcmp(element, "result") == 0) {
486 } else if (strcmp(element, "unsatisfiable") == 0) {
487 end_unsatisfiable(ctx);
491 int main(int argc, char *argv[])
493 struct test_context ctx;
494 const char *test_file;
496 memset(&ctx, 0, sizeof ctx);
499 fprintf(stderr, "usage: %s [-d] [TESTS-FILE]\n", argv[0]);
503 if (argc >= 2 && !strcmp (argv[1], "-d")) {
511 test_file = "test.xml";
513 parse_xml_file(test_file, start_test_element, end_test_element, &ctx);
516 fprintf(stderr, "\n%d errors\n", ctx.errors);