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");
55 struct razor_set *set;
56 struct test_set *next;
60 struct razor_importer *importer;
61 struct test_set *sets;
62 struct razor_package_iterator *package_iterator;
63 struct razor_property_iterator *property_iterator;
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)
86 parse_property(struct test_context *ctx, const char **atts,
87 enum razor_property_type type)
89 const char *name = NULL, *version = NULL;
91 get_atts(atts, "name", &name, "eq", &version, NULL);
94 fprintf(stderr, "no name specified for property\n");
98 razor_importer_add_property(ctx->importer, name,
99 RAZOR_VERSION_EQUAL, version, type);
103 start_set_element(void *data, const char *element, const char **atts)
105 struct test_context *ctx = data;
106 struct test_set *set;
107 const char *name, *version;
109 if (strcmp(element, "set") == 0) {
110 get_atts(atts, "name", &name, NULL);
111 ctx->importer = razor_importer_new();
112 set = malloc(sizeof *set);
113 set->name = strdup(name);
114 set->next = ctx->sets;
116 } else if (strcmp(element, "package") == 0) {
117 get_atts(atts, "name", &name, "version", &version, NULL);
118 razor_importer_begin_package(ctx->importer, name, version);
119 } else if (strcmp(element, "requires") == 0) {
120 parse_property(ctx, atts, RAZOR_PROPERTY_REQUIRES);
121 } else if (strcmp(element, "provides") == 0) {
122 parse_property(ctx, atts, RAZOR_PROPERTY_PROVIDES);
123 } else if (strcmp(element, "obsoletes") == 0) {
124 parse_property(ctx, atts, RAZOR_PROPERTY_OBSOLETES);
125 } else if (strcmp(element, "conflicts") == 0) {
126 parse_property(ctx, atts, RAZOR_PROPERTY_CONFLICTS);
127 } else if (strcmp(element, "file") == 0) {
128 get_atts(atts, "name", &name, NULL);
129 razor_importer_add_file(ctx->importer, name);
130 } else if (strcmp(element, "dir") == 0) {
131 get_atts(atts, "name", &name, NULL);
132 razor_importer_add_file(ctx->importer, name);
137 end_set_element (void *data, const char *name)
139 struct test_context *ctx = data;
141 if (strcmp(name, "set") == 0) {
142 ctx->sets->set = razor_importer_finish(ctx->importer);
143 } else if (strcmp(name, "package") == 0) {
144 razor_importer_finish_package(ctx->importer);
148 static struct razor_set *
149 lookup_set(struct test_context *ctx, const char *name)
151 struct test_set *set;
153 for (set = ctx->sets; set != NULL; set = set->next) {
154 if (strcmp(set->name, name) == 0)
162 verify_begin(struct test_context *ctx, const char **atts)
164 struct razor_set *set;
165 const char *type, *name;
167 get_atts(atts, "type", &type, "set", &name, NULL);
168 set = lookup_set(ctx, name);
170 fprintf(stderr, "set %s not found\n", name);
174 if (strcmp(type, "packages") == 0) {
175 ctx->package_iterator =
176 razor_package_iterator_create(set);
177 } else if (strcmp(type, "properties") == 0) {
178 ctx->property_iterator =
179 razor_property_iterator_create(set, NULL);
182 "unknown compare type \"%s\"\n", type);
188 verify_end(struct test_context *ctx)
190 struct razor_package *package;
191 struct razor_property *property;
192 const char *name, *version;
193 enum razor_property_type type;
194 enum razor_version_relation relation;
196 if (ctx->package_iterator != NULL) {
197 if (razor_package_iterator_next(ctx->package_iterator,
200 fprintf(stderr, "too few packages in set\n");
204 razor_package_iterator_destroy(ctx->package_iterator);
205 ctx->package_iterator = NULL;
208 if (ctx->property_iterator != NULL) {
209 if (razor_property_iterator_next(ctx->property_iterator,
211 &name, &relation, &version,
213 fprintf(stderr, "too few properties in set\n");
217 razor_property_iterator_destroy(ctx->property_iterator);
218 ctx->property_iterator = NULL;
223 verify_package(struct test_context *ctx, const char **atts)
225 struct razor_package *package;
226 const char *name, *version, *ref_name, *ref_version;
228 if (ctx->package_iterator == NULL) {
230 "\"package\" element seen, "
231 "but not in package verify mode\n");
235 get_atts(atts, "name", &ref_name, "version", &ref_version, NULL);
236 if (!razor_package_iterator_next(ctx->package_iterator,
237 &package, &name, &version)) {
238 fprintf(stderr, "too many packages in set\n");
242 if (strcmp(name, ref_name) != 0 || strcmp(version, ref_version) != 0) {
244 "package mismatch; expected %s-%s, got %s-%s\n",
245 ref_name, ref_version, name, version);
251 verify_property(struct test_context *ctx,
252 enum razor_property_type ref_type, const char **atts)
254 struct razor_property *property;
255 const char *name, *version, *ref_name, *ref_version;
256 enum razor_property_type type;
257 enum razor_version_relation relation;
260 if (ctx->property_iterator == NULL) {
262 "\"requires/provides\" element seen, "
263 "but not in property verify mode\n");
267 get_atts(atts, "name", &ref_name, "eq", &ref_version, NULL);
268 if (!razor_property_iterator_next(ctx->property_iterator, &property,
269 &name, &relation, &version, &type)) {
270 fprintf(stderr, "too many properties in set\n");
274 if (version != NULL && ref_version != NULL)
275 same_version = strcmp(version, ref_version) == 0;
276 else if (version == NULL && ref_version == NULL)
281 if (strcmp(name, ref_name) != 0 || !same_version || type != ref_type) {
283 "property mismatch; expected %s-%s/%d, got %s-%s/%d\n",
284 ref_name, ref_version, ref_type,
285 name, version, type);
291 start_test_element(void *data, const char *element, const char **atts)
293 struct test_context *ctx = data;
296 if (strcmp(element, "import") == 0) {
297 get_atts(atts, "file", &name, NULL);
298 parse_xml_file(name, start_set_element, end_set_element, ctx);
299 } else if (strcmp(element, "update") == 0) {
300 /* run update to create new set */
301 } else if (strcmp(element, "verify") == 0) {
302 verify_begin(ctx, atts);
303 } else if (strcmp(element, "package") == 0) {
304 verify_package(ctx, atts);
305 } else if (strcmp(element, "requires") == 0) {
306 verify_property(ctx, RAZOR_PROPERTY_REQUIRES, atts);
307 } else if (strcmp(element, "provides") == 0) {
308 verify_property(ctx, RAZOR_PROPERTY_PROVIDES, atts);
309 } else if (strcmp(element, "conflicts") == 0) {
310 verify_property(ctx, RAZOR_PROPERTY_CONFLICTS, atts);
311 } else if (strcmp(element, "obsoletes") == 0) {
312 verify_property(ctx, RAZOR_PROPERTY_OBSOLETES, atts);
317 end_test_element (void *data, const char *element)
319 struct test_context *ctx = data;
321 if (strcmp(element, "verify") == 0)
325 int main(int argc, char *argv[])
327 struct test_context ctx;
330 fprintf(stderr, "usage: %s TESTS-FILE\n", argv[0]);
334 memset(&ctx, 0, sizeof ctx);
335 parse_xml_file(argv[1], start_test_element, end_test_element, &ctx);