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 buffer = XML_GetBuffer(parser, XML_BUFFER_SIZE);
29 fd = open(filename, O_RDONLY);
31 fprintf(stderr, "failed to open %s: %m\n", filename);
35 while (len = read(fd, buffer, XML_BUFFER_SIZE), len > 0) {
36 err = XML_ParseBuffer(parser, len, len == 0);
37 if (err == XML_STATUS_ERROR) {
38 fprintf(stderr, "parse error at line %lu:\n%s\n",
39 XML_GetCurrentLineNumber(parser),
40 XML_ErrorString(XML_GetErrorCode(parser)));
46 fprintf(stderr, "read: %m\n");
54 struct razor_set *system_set, *repo_set, *result_set;
56 struct razor_importer *importer;
57 struct razor_set **importer_set;
59 char *install_pkgs[3], *remove_pkgs[3];
60 int n_install_pkgs, n_remove_pkgs;
62 int in_result, result_errors;
67 get_atts(const char **atts, ...)
70 const char *name, **ptr;
74 while (name = va_arg(ap, const char *), name != NULL) {
75 ptr = va_arg(ap, const char **);
77 for (i = 0; atts[i]; i += 2) {
78 if (strcmp(atts[i], name) == 0)
85 static enum razor_version_relation
86 parse_relation (const char *rel_str)
90 if (rel_str[0] == 'l')
91 return rel_str[1] == 'e' ? RAZOR_VERSION_LESS_OR_EQUAL : RAZOR_VERSION_LESS;
92 else if (rel_str[0] == 'g')
93 return rel_str[1] == 'e' ? RAZOR_VERSION_GREATER_OR_EQUAL : RAZOR_VERSION_GREATER;
94 else if (rel_str[0] == 'e' || rel_str[1] == 'q')
95 return RAZOR_VERSION_EQUAL;
101 start_test(struct test_context *ctx, const char **atts)
103 const char *name = NULL;
105 get_atts(atts, "name", &name, NULL);
107 fprintf(stderr, "Test with no name\n");
110 printf("%s\n", name);
114 end_test(struct test_context *ctx)
116 if (ctx->system_set) {
117 razor_set_destroy(ctx->system_set);
118 ctx->system_set = NULL;
121 razor_set_destroy(ctx->repo_set);
122 ctx->repo_set = NULL;
124 if (ctx->result_set) {
125 razor_set_destroy(ctx->result_set);
126 ctx->result_set = NULL;
131 start_set(struct test_context *ctx, const char **atts)
133 const char *name = NULL;
135 ctx->importer = razor_importer_new();
136 get_atts(atts, "name", &name, NULL);
138 ctx->importer_set = &ctx->result_set;
139 else if (!strcmp(name, "system"))
140 ctx->importer_set = &ctx->system_set;
141 else if (!strcmp(name, "repo"))
142 ctx->importer_set = &ctx->repo_set;
144 fprintf(stderr, " bad set name '%s'\n", name);
150 end_set(struct test_context *ctx)
152 *ctx->importer_set = razor_importer_finish(ctx->importer);
153 ctx->importer = NULL;
157 start_package(struct test_context *ctx, const char **atts)
159 const char *name = NULL, *version = NULL, *arch = NULL;
161 get_atts(atts, "name", &name, "version", &version, "arch", &arch, NULL);
163 fprintf(stderr, " package with no name\n");
167 razor_importer_begin_package(ctx->importer, name, version);
168 razor_importer_add_property(ctx->importer, name,
169 RAZOR_VERSION_EQUAL, version,
170 RAZOR_PROPERTY_PROVIDES);
174 end_package(struct test_context *ctx)
176 razor_importer_finish_package(ctx->importer);
180 start_property(struct test_context *ctx, enum razor_property_type type, const char **atts)
182 const char *name = NULL, *rel_str = NULL, *version = NULL;
183 enum razor_version_relation rel;
185 if (ctx->in_unsatisfiable)
188 get_atts(atts, "name", &name, "rel", &rel_str, "version", &version, NULL);
190 fprintf(stderr, " no name specified for property\n");
194 rel = parse_relation(rel_str);
196 fprintf(stderr, " bad or missing version relation for property %s\n", name);
200 rel = RAZOR_VERSION_EQUAL;
202 razor_importer_add_property(ctx->importer, name,
207 start_transaction(struct test_context *ctx, const char **atts)
209 ctx->n_install_pkgs = 0;
210 ctx->n_remove_pkgs = 0;
214 end_transaction(struct test_context *ctx)
216 if (ctx->n_install_pkgs) {
217 ctx->system_set = razor_set_update(ctx->system_set,
220 (const char **)ctx->install_pkgs);
222 if (ctx->n_remove_pkgs && ctx->system_set) {
223 ctx->system_set = razor_set_remove(ctx->system_set,
225 (const char **)ctx->remove_pkgs);
228 while (ctx->n_install_pkgs--)
229 free(ctx->install_pkgs[ctx->n_install_pkgs]);
230 while (ctx->n_remove_pkgs--)
231 free(ctx->remove_pkgs[ctx->n_remove_pkgs]);
235 start_install_or_update(struct test_context *ctx, const char **atts)
237 const char *name = NULL;
239 get_atts(atts, "name", &name, NULL);
241 fprintf(stderr, " install/update with no name\n");
245 ctx->install_pkgs[ctx->n_install_pkgs++] = strdup(name);
249 start_remove(struct test_context *ctx, const char **atts)
251 const char *name = NULL;
253 get_atts(atts, "name", &name, NULL);
255 fprintf(stderr, " remove with no name\n");
259 ctx->remove_pkgs[ctx->n_remove_pkgs++] = strdup(name);
263 start_result(struct test_context *ctx, const char **atts)
269 diff_callback(const char *name,
270 const char *old_version, const char *new_version,
273 struct test_context *ctx = data;
275 ctx->result_errors++;
277 fprintf(stderr, " result set should not contain %s %s\n",
280 fprintf(stderr, " result set should contain %s %s\n",
286 end_result(struct test_context *ctx)
290 if (ctx->result_set) {
291 if (!ctx->system_set)
292 ctx->system_set = razor_set_create();
293 ctx->result_errors = 0;
294 razor_set_diff(ctx->system_set, ctx->result_set,
296 if (ctx->result_errors)
302 start_unsatisfiable(struct test_context *ctx, const char **atts)
304 if (ctx->system_set) {
305 fprintf(stderr, "Expected to fail, but didn't\n");
310 fprintf(stderr, " Not actually checking <unsatisfiable>\n");
311 ctx->in_unsatisfiable = 1;
315 end_unsatisfiable(struct test_context *ctx)
317 ctx->in_unsatisfiable = 0;
321 start_test_element(void *data, const char *element, const char **atts)
323 struct test_context *ctx = data;
325 if (strcmp(element, "tests") == 0) {
327 } else if (strcmp(element, "test") == 0) {
328 start_test(ctx, atts);
329 } else if (strcmp(element, "set") == 0) {
330 start_set(ctx, atts);
331 } else if (strcmp(element, "transaction") == 0) {
332 start_transaction(ctx, atts);
333 } else if (strcmp(element, "install") == 0) {
334 start_install_or_update(ctx, atts);
335 } else if (strcmp(element, "install") == 0) {
336 start_install_or_update(ctx, atts);
337 } else if (strcmp(element, "remove") == 0) {
338 start_remove(ctx, atts);
339 } else if (strcmp(element, "result") == 0) {
340 start_result(ctx, atts);
341 } else if (strcmp(element, "unsatisfiable") == 0) {
342 start_unsatisfiable(ctx, atts);
343 } else if (strcmp(element, "package") == 0) {
344 start_package(ctx, atts);
345 } else if (strcmp(element, "requires") == 0) {
346 start_property(ctx, RAZOR_PROPERTY_REQUIRES, atts);
347 } else if (strcmp(element, "provides") == 0) {
348 start_property(ctx, RAZOR_PROPERTY_PROVIDES, atts);
349 } else if (strcmp(element, "conflicts") == 0) {
350 start_property(ctx, RAZOR_PROPERTY_CONFLICTS, atts);
351 } else if (strcmp(element, "obsoletes") == 0) {
352 start_property(ctx, RAZOR_PROPERTY_OBSOLETES, atts);
354 fprintf(stderr, "Unrecognized element '%s'\n", element);
360 end_test_element (void *data, const char *element)
362 struct test_context *ctx = data;
364 if (strcmp(element, "test") == 0) {
366 } else if (strcmp(element, "set") == 0) {
368 } else if (strcmp(element, "package") == 0) {
370 } else if (strcmp(element, "transaction") == 0) {
371 end_transaction(ctx);
372 } else if (strcmp(element, "result") == 0) {
374 } else if (strcmp(element, "unsatisfiable") == 0) {
375 end_unsatisfiable(ctx);
379 int main(int argc, char *argv[])
381 struct test_context ctx;
384 fprintf(stderr, "usage: %s TESTS-FILE\n", argv[0]);
388 memset(&ctx, 0, sizeof ctx);
389 parse_xml_file(argv[1], start_test_element, end_test_element, &ctx);