When uniquifying properties, also sort them on the owning package.
This ensures that whenever two packages provide or (or require, obsolete
or conflict) the same property, they appear in the same order in the
propertys list of packages.
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_version_relation
92 parse_relation (const char *rel_str)
96 if (rel_str[0] == 'L')
97 return rel_str[1] == 'E' ? RAZOR_VERSION_LESS_OR_EQUAL : RAZOR_VERSION_LESS;
98 else if (rel_str[0] == 'G')
99 return rel_str[1] == 'E' ? RAZOR_VERSION_GREATER_OR_EQUAL : RAZOR_VERSION_GREATER;
100 else if (rel_str[0] == 'E' || rel_str[1] == 'Q')
101 return RAZOR_VERSION_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_new();
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_VERSION_EQUAL, version,
184 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_type type, const char *name, enum razor_version_relation rel, const char *version)
196 razor_importer_add_property(ctx->importer, name,
201 check_unsatisfiable_property(struct test_context *ctx,
202 enum razor_property_type type,
204 enum razor_version_relation rel,
207 static const char *relation_string[] = { "<", "<=", "=", ">=", ">" };
212 if (razor_transaction_unsatisfied_property(ctx->trans,
213 name, rel, version, type))
216 fprintf(stderr, " didn't get unsatisfiable '%s %s %s'\n",
217 name, relation_string[rel], version);
222 start_property(struct test_context *ctx, enum razor_property_type type, const char **atts)
224 const char *name = NULL, *rel_str = NULL, *version = NULL;
225 enum razor_version_relation rel;
227 get_atts(atts, "name", &name, "relation", &rel_str, "version", &version, NULL);
229 fprintf(stderr, " no name specified for property\n");
233 rel = parse_relation(rel_str);
235 fprintf(stderr, " bad or missing version relation for property %s\n", name);
239 rel = RAZOR_VERSION_EQUAL;
242 check_unsatisfiable_property(ctx, type, name, rel, version);
244 add_property(ctx, type, name, rel, version);
248 start_transaction(struct test_context *ctx, const char **atts)
250 ctx->n_install_pkgs = 0;
251 ctx->n_remove_pkgs = 0;
255 end_transaction(struct test_context *ctx)
257 struct razor_package *pkg;
260 ctx->trans = razor_transaction_create(ctx->system_set, ctx->repo_set);
261 for (i = 0; i < ctx->n_install_pkgs; i++) {
262 pkg = razor_set_get_package(ctx->repo_set,
263 ctx->install_pkgs[i]);
264 razor_transaction_install_package(ctx->trans, pkg);
266 for (i = 0; i < ctx->n_remove_pkgs; i++) {
267 pkg = razor_set_get_package(ctx->repo_set,
268 ctx->remove_pkgs[i]);
269 razor_transaction_remove_package(ctx->trans, pkg);
272 errors = razor_transaction_resolve(ctx->trans);
275 while (ctx->n_install_pkgs--)
276 free(ctx->install_pkgs[ctx->n_install_pkgs]);
277 while (ctx->n_remove_pkgs--)
278 free(ctx->remove_pkgs[ctx->n_remove_pkgs]);
281 struct razor_set *new;
282 new = razor_transaction_finish(ctx->trans);
283 ctx->system_set = new;
288 start_install_or_update(struct test_context *ctx, const char **atts)
290 const char *name = NULL;
292 get_atts(atts, "name", &name, NULL);
294 fprintf(stderr, " install/update with no name\n");
298 ctx->install_pkgs[ctx->n_install_pkgs++] = strdup(name);
302 start_remove(struct test_context *ctx, const char **atts)
304 const char *name = NULL;
306 get_atts(atts, "name", &name, NULL);
308 fprintf(stderr, " remove with no name\n");
312 ctx->remove_pkgs[ctx->n_remove_pkgs++] = strdup(name);
316 start_result(struct test_context *ctx, const char **atts)
322 diff_callback(const char *name,
323 const char *old_version,
324 const char *new_version,
328 struct test_context *ctx = data;
332 fprintf(stderr, " result set should not contain %s %s\n",
335 fprintf(stderr, " result set should contain %s %s\n",
341 end_result(struct test_context *ctx)
345 if (ctx->result_set) {
346 if (!ctx->system_set)
347 ctx->system_set = razor_set_create();
348 razor_set_diff(ctx->system_set, ctx->result_set,
354 start_unsatisfiable(struct test_context *ctx, const char **atts)
356 if (ctx->result_set) {
357 fprintf(stderr, "Expected to fail, but didn't\n");
365 end_unsatisfiable(struct test_context *ctx)
371 start_test_element(void *data, const char *element, const char **atts)
373 struct test_context *ctx = data;
375 if (strcmp(element, "tests") == 0) {
377 } else if (strcmp(element, "test") == 0) {
378 start_test(ctx, atts);
379 } else if (strcmp(element, "set") == 0) {
380 start_set(ctx, atts);
381 } else if (strcmp(element, "transaction") == 0) {
382 start_transaction(ctx, atts);
383 } else if (strcmp(element, "install") == 0) {
384 start_install_or_update(ctx, atts);
385 } else if (strcmp(element, "install") == 0) {
386 start_install_or_update(ctx, atts);
387 } else if (strcmp(element, "remove") == 0) {
388 start_remove(ctx, atts);
389 } else if (strcmp(element, "result") == 0) {
390 start_result(ctx, atts);
391 } else if (strcmp(element, "unsatisfiable") == 0) {
392 start_unsatisfiable(ctx, atts);
393 } else if (strcmp(element, "package") == 0) {
394 start_package(ctx, atts);
395 } else if (strcmp(element, "requires") == 0) {
396 start_property(ctx, RAZOR_PROPERTY_REQUIRES, atts);
397 } else if (strcmp(element, "provides") == 0) {
398 start_property(ctx, RAZOR_PROPERTY_PROVIDES, atts);
399 } else if (strcmp(element, "conflicts") == 0) {
400 start_property(ctx, RAZOR_PROPERTY_CONFLICTS, atts);
401 } else if (strcmp(element, "obsoletes") == 0) {
402 start_property(ctx, RAZOR_PROPERTY_OBSOLETES, atts);
404 fprintf(stderr, "Unrecognized element '%s'\n", element);
410 end_test_element (void *data, const char *element)
412 struct test_context *ctx = data;
414 if (strcmp(element, "test") == 0) {
416 } else if (strcmp(element, "set") == 0) {
418 } else if (strcmp(element, "package") == 0) {
420 } else if (strcmp(element, "transaction") == 0) {
421 end_transaction(ctx);
422 } else if (strcmp(element, "result") == 0) {
424 } else if (strcmp(element, "unsatisfiable") == 0) {
425 end_unsatisfiable(ctx);
429 int main(int argc, char *argv[])
431 struct test_context ctx;
432 const char *test_file;
434 memset(&ctx, 0, sizeof ctx);
437 fprintf(stderr, "usage: %s [-d] [TESTS-FILE]\n", argv[0]);
441 if (argc >= 2 && !strcmp (argv[1], "-d")) {
449 test_file = "test.xml";
451 parse_xml_file(test_file, start_test_element, end_test_element, &ctx);
454 fprintf(stderr, "\n%d errors\n", ctx.errors);