X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=blobdiff_plain;f=test%2Fparser%2Futils.c;h=33efda80536f8354ebc4e10e6b64fe1299755831;hp=fb558cf2c3ec457be3d0ef63a8f399bb06b3f343;hb=9fbd73a208c9465b4bf9e2c80c7290b72e62ead1;hpb=31998343c5eb5533ef85b97f5bb2ffe200eb2ad0 diff --git a/test/parser/utils.c b/test/parser/utils.c index fb558cf..33efda8 100644 --- a/test/parser/utils.c +++ b/test/parser/utils.c @@ -17,40 +17,59 @@ #include "parser-test.h" -static int n_parsers; -static struct parser **parsers; +struct p_item { + struct list_item list; + struct parser *parser; +}; + +struct test_file { + struct discover_device *dev; + const char *name; + void *data; + int size; + struct list_item list; +}; + +STATIC_LIST(parsers); void __register_parser(struct parser *parser) { - parsers = talloc_realloc(NULL, parsers, struct parser *, n_parsers + 1); - parsers[n_parsers] = parser; - n_parsers++; + struct p_item* i = talloc(NULL, struct p_item); + + i->parser = parser; + list_add(&parsers, &i->list); +} + +static void __attribute__((destructor)) __cleanup_parsers(void) +{ + struct p_item *item, *tmp; + + list_for_each_entry_safe(&parsers, item, tmp, list) + talloc_free(item); } static struct discover_device *test_create_device_simple( - struct discover_context *ctx) + struct parser_test *test) { static int dev_idx; char name[10]; sprintf(name, "__test%d", dev_idx++); - return test_create_device(ctx, name); + return test_create_device(test, name); } -struct discover_device *test_create_device(struct discover_context *ctx, +struct discover_device *test_create_device(struct parser_test *test, const char *name) { struct discover_device *dev; - dev = talloc_zero(ctx, struct discover_device); - dev->device = talloc_zero(dev, struct device); - - list_init(&dev->boot_options); + dev = discover_device_create(test->handler, name); dev->device->id = talloc_strdup(dev, name); dev->device_path = talloc_asprintf(dev, "/dev/%s", name); dev->mount_path = talloc_asprintf(dev, "/test/mount/%s", name); + dev->mounted = true; return dev; } @@ -63,18 +82,24 @@ static struct discover_context *test_create_context(struct parser_test *test) assert(ctx); list_init(&ctx->boot_options); - ctx->device = test_create_device_simple(ctx); + ctx->device = test_create_device_simple(test); + ctx->test_data = test; + device_handler_add_device(test->handler, ctx->device); return ctx; } +extern struct config *test_config_init(struct parser_test *test); + struct parser_test *test_init(void) { struct parser_test *test; test = talloc_zero(NULL, struct parser_test); - test->handler = device_handler_init(NULL, 0); + test->config = test_config_init(test); + test->handler = device_handler_init(NULL, NULL, 0); test->ctx = test_create_context(test); + list_init(&test->files); return test; } @@ -120,25 +145,121 @@ void test_read_conf_file(struct parser_test *test, const char *filename) talloc_free(path); } -int test_run_parser(struct parser_test *test, const char *parser_name) +void test_set_conf_source(struct parser_test *test, const char *url) { - struct parser *parser; - int i, rc = 0; + test->ctx->conf_url = pb_url_parse(test, url); + assert(test->ctx->conf_url); +} + +void test_add_file_data(struct parser_test *test, struct discover_device *dev, + const char *filename, void *data, int size) +{ + struct test_file *file; + + file = talloc_zero(test, struct test_file); + file->dev = dev; + file->name = filename; + file->data = data; + file->size = size; + list_add(&test->files, &file->list); +} + - for (i = 0; i < n_parsers; i++) { - parser = parsers[i]; - if (strcmp(parser->name, parser_name)) +int parser_request_file(struct discover_context *ctx, + struct discover_device *dev, const char *filename, + char **buf, int *len) +{ + struct parser_test *test = ctx->test_data; + struct test_file *file; + + list_for_each_entry(&test->files, file, list) { + if (file->dev != dev) + continue; + if (strcmp(file->name, filename)) continue; - test->ctx->parser = parser; - rc = parser->parse(test->ctx, test->conf.buf, test->conf.size); + + *buf = talloc_memdup(test, file->data, file->size); + *len = file->size; + return 0; + } + + return -1; +} + +int parser_replace_file(struct discover_context *ctx, + struct discover_device *dev, const char *filename, + char *buf, int len) +{ + struct parser_test *test = ctx->test_data; + struct test_file *f, *file; + + list_for_each_entry(&test->files, f, list) { + if (f->dev != dev) + continue; + if (strcmp(f->name, filename)) + continue; + + file = f; break; } - if (i == n_parsers) - errx(EXIT_FAILURE, "%s: parser '%s' not found", - __func__, parser_name); + if (!file) { + file = talloc_zero(test, struct test_file); + file->dev = dev; + file->name = filename; + list_add(&test->files, &file->list); + } else { + talloc_free(file->data); + } + + file->data = talloc_memdup(test, buf, len); + file->size = len; + return 0; +} +int test_run_parser(struct parser_test *test, const char *parser_name) +{ + struct p_item* i; + + list_for_each_entry(&parsers, i, list) { + if (strcmp(i->parser->name, parser_name)) + continue; + test->ctx->parser = i->parser; + return i->parser->parse(test->ctx, test->conf.buf, test->conf.size); + } + + errx(EXIT_FAILURE, "%s: parser '%s' not found", __func__, parser_name); +} + +bool resource_resolve(struct device_handler *handler, struct parser *parser, + struct resource *resource) +{ + if (!resource) + return true; + if (resource->resolved) + return true; + + assert(parser); + assert(parser->resolve_resource); - return rc; + return parser->resolve_resource(handler, resource); +} + +void boot_option_resolve(struct device_handler *handler, + struct discover_boot_option *opt) +{ + resource_resolve(handler, opt->source, opt->boot_image); + resource_resolve(handler, opt->source, opt->initrd); + resource_resolve(handler, opt->source, opt->icon); +} + +void test_hotplug_device(struct parser_test *test, struct discover_device *dev) +{ + struct discover_boot_option *opt; + + device_handler_add_device(test->handler, dev); + + list_for_each_entry(&test->ctx->boot_options, opt, list) + boot_option_resolve(test->handler, opt); } struct discover_boot_option *get_boot_option(struct discover_context *ctx, @@ -161,10 +282,19 @@ void __check_boot_option_count(struct discover_context *ctx, int count, const char *file, int line) { struct discover_boot_option *opt; - int i = 0; + int defaults = 0, i = 0; - list_for_each_entry(&ctx->boot_options, opt, list) + list_for_each_entry(&ctx->boot_options, opt, list) { i++; + if (opt->option->is_default) + defaults++; + } + + if (defaults > 1) { + fprintf(stderr, "%s:%d: parser returned multiple default " + "options\n", file, line); + exit(EXIT_FAILURE); + } if (i == count) return; @@ -185,8 +315,11 @@ void __check_args(struct discover_boot_option *opt, const char *args, { int rc; + if (!opt->option->boot_args && !args) + return; + if (!opt->option->boot_args) { - fprintf(stderr, "%s%d: arg check failed\n", file, line); + fprintf(stderr, "%s:%d: arg check failed\n", file, line); fprintf(stderr, " no arguments parsed\n"); fprintf(stderr, " expected '%s'\n", args); exit(EXIT_FAILURE); @@ -194,7 +327,7 @@ void __check_args(struct discover_boot_option *opt, const char *args, rc = strcmp(opt->option->boot_args, args); if (rc) { - fprintf(stderr, "%s%d: arg check failed\n", file, line); + fprintf(stderr, "%s:%d: arg check failed\n", file, line); fprintf(stderr, " got '%s'\n", opt->option->boot_args); fprintf(stderr, " expected '%s'\n", args); exit(EXIT_FAILURE); @@ -208,13 +341,23 @@ void __check_name(struct discover_boot_option *opt, const char *name, rc = strcmp(opt->option->name, name); if (rc) { - fprintf(stderr, "%s%d: name check failed\n", file, line); + fprintf(stderr, "%s:%d: name check failed\n", file, line); fprintf(stderr, " got '%s'\n", opt->option->name); fprintf(stderr, " expected '%s'\n", name); exit(EXIT_FAILURE); } } +void __check_is_default(struct discover_boot_option *opt, + const char *file, int line) +{ + if (opt->option->is_default) + return; + + fprintf(stderr, "%s:%d: default check failed\n", file, line); + exit(EXIT_FAILURE); +} + void __check_resolved_local_resource(struct resource *res, struct discover_device *dev, const char *local_path, const char *file, int line) @@ -233,12 +376,33 @@ void __check_resolved_local_resource(struct resource *res, got_url = pb_url_to_string(res->url); if (strcmp(got_url, exp_url)) { - errx(EXIT_FAILURE, - "%s:%d Resource mismatch: got %s, expected %s", - file, line, got_url, exp_url); + fprintf(stderr, "%s:%d: Resource mismatch\n", file, line); + fprintf(stderr, " got '%s'\n", got_url); + fprintf(stderr, " expected '%s'\n", exp_url); + exit(EXIT_FAILURE); } } +void __check_resolved_url_resource(struct resource *res, + const char *url, const char *file, int line) +{ + char *res_url; + + if (!res) + errx(EXIT_FAILURE, "%s:%d: No resource", file, line); + + if (!res->resolved) + errx(EXIT_FAILURE, "%s:%d: Resource is not resolved", + file, line); + + res_url = pb_url_to_string(res->url); + if (strcmp(url, res_url)) { + fprintf(stderr, "%s:%d: Resource mismatch\n", file, line); + fprintf(stderr, " got '%s'\n", res_url); + fprintf(stderr, " expected '%s'\n", url); + exit(EXIT_FAILURE); + } +} void __check_unresolved_resource(struct resource *res, const char *file, int line) { @@ -248,3 +412,10 @@ void __check_unresolved_resource(struct resource *res, if (res->resolved) errx(EXIT_FAILURE, "%s:%d: Resource is resolved", file, line); } + +void __check_not_present_resource(struct resource *res, + const char *file, int line) +{ + if (res) + errx(EXIT_FAILURE, "%s:%d: Resource present", file, line); +}