X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=blobdiff_plain;f=test%2Fparser%2Futils.c;h=67401abc9e0d8fa5d95cfb2ed9f1b27ba2fce35e;hp=7af4df7397970e6b97c0794b64cb6f647434cab6;hb=d14bf38b9881c385478a460e3058d7cadee107fb;hpb=b201464a18c990ea6df0f2878e532618d4936c53 diff --git a/test/parser/utils.c b/test/parser/utils.c index 7af4df7..67401ab 100644 --- a/test/parser/utils.c +++ b/test/parser/utils.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -14,6 +15,7 @@ #include "device-handler.h" #include "parser.h" #include "resource.h" +#include "event.h" #include "parser-test.h" @@ -22,6 +24,14 @@ struct p_item { 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) @@ -75,6 +85,7 @@ static struct discover_context *test_create_context(struct parser_test *test) list_init(&ctx->boot_options); ctx->device = test_create_device_simple(test); + ctx->test_data = test; device_handler_add_device(test->handler, ctx->device); return ctx; @@ -90,6 +101,7 @@ struct parser_test *test_init(void) 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; } @@ -101,17 +113,20 @@ void test_fini(struct parser_test *test) } void __test_read_conf_data(struct parser_test *test, + struct discover_device *dev, const char *conf_file, const char *buf, size_t len) { - test->conf.size = len; - test->conf.buf = talloc_memdup(test, buf, len); + test_add_file_data(test, dev, conf_file, buf, len); } -void test_read_conf_file(struct parser_test *test, const char *filename) +void test_read_conf_file(struct parser_test *test, const char *filename, + const char *conf_file) { struct stat stat; + size_t size; char *path; int fd, rc; + char *buf; path = talloc_asprintf(test, "%s/%s", TEST_CONF_BASE, filename); @@ -123,22 +138,125 @@ void test_read_conf_file(struct parser_test *test, const char *filename) assert(!rc); (void)rc; - test->conf.size = stat.st_size; - test->conf.buf = talloc_array(test, char, test->conf.size + 1); + size = stat.st_size; + buf = talloc_array(test, char, size + 1); - rc = read(fd, test->conf.buf, test->conf.size); - assert(rc == (ssize_t)test->conf.size); + rc = read(fd, buf, size); + assert(rc == (ssize_t)size); - *(char *)(test->conf.buf + test->conf.size) = '\0'; + *(buf + size) = '\0'; close(fd); talloc_free(path); + + test_add_file_data(test, test->ctx->device, conf_file, buf, size); +} + +void test_add_file_data(struct parser_test *test, struct discover_device *dev, + const char *filename, const void *data, int size) +{ + struct test_file *file; + + file = talloc_zero(test, struct test_file); + file->dev = dev; + file->name = filename; + file->data = talloc_memdup(test, data, size); + file->size = size; + list_add(&test->files, &file->list); +} + +void test_set_event_source(struct parser_test *test) +{ + test->ctx->event = talloc_zero(test->ctx, struct event); } -void test_set_conf_source(struct parser_test *test, const char *url) +void test_set_event_param(struct event *event, const char *name, + const char *value) { - test->ctx->conf_url = pb_url_parse(test, url); - assert(test->ctx->conf_url); + event_set_param(event, name, value); +} + +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; + char *tmp; + + list_for_each_entry(&test->files, file, list) { + if (file->dev != dev) + continue; + if (strcmp(file->name, filename)) + continue; + + /* the read_file() interface always adds a trailing null + * for string-safety; do the same here */ + tmp = talloc_array(test, char, file->size + 1); + memcpy(tmp, file->data, file->size); + tmp[file->size] = '\0'; + *buf = tmp; + *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 (!file) { + file = talloc_zero(test, struct test_file); + file->dev = dev; + file->name = filename; + list_add(&test->files, &file->list); + } + + file->data = talloc_memdup(test, buf, len); + file->size = len; + return 0; +} + +int parser_request_url(struct discover_context *ctx, struct pb_url *url, + char **buf, int *len) +{ + struct parser_test *test = ctx->test_data; + struct test_file *file; + char *tmp; + + list_for_each_entry(&test->files, file, list) { + if (file->dev) + continue; + + if (strcmp(file->name, url->full)) + continue; + + /* the read_file() interface always adds a trailing null + * for string-safety; do the same here */ + tmp = talloc_array(test, char, file->size + 1); + memcpy(tmp, file->data, file->size); + tmp[file->size] = '\0'; + *buf = tmp; + *len = file->size; + return 0; + } + + return -1; } int test_run_parser(struct parser_test *test, const char *parser_name) @@ -149,7 +267,7 @@ int test_run_parser(struct parser_test *test, const char *parser_name) 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); + return i->parser->parse(test->ctx); } errx(EXIT_FAILURE, "%s: parser '%s' not found", __func__, parser_name); @@ -187,6 +305,21 @@ void test_hotplug_device(struct parser_test *test, struct discover_device *dev) boot_option_resolve(test->handler, opt); } +void test_remove_device(struct parser_test *test, struct discover_device *dev) +{ + struct discover_boot_option *opt, *tmp; + + if (dev == test->ctx->device) { + list_for_each_entry_safe(&test->ctx->boot_options, + opt, tmp, list) { + list_remove(&opt->list); + talloc_free(opt); + } + } + + device_handler_remove(test->handler, dev); +} + struct discover_boot_option *get_boot_option(struct discover_context *ctx, int idx) { @@ -344,3 +477,62 @@ void __check_not_present_resource(struct resource *res, if (res) errx(EXIT_FAILURE, "%s:%d: Resource present", file, line); } + +static void dump_file_data(const void *buf, int len) +{ + int i, j, hex_len = strlen("00 "); + const int row_len = 16; + + for (i = 0; i < len; i += row_len) { + char hbuf[row_len * hex_len + 1]; + char cbuf[row_len + strlen("|") + 1]; + + for (j = 0; (j < row_len) && ((i+j) < len); j++) { + char c = ((const char *)buf)[i + j]; + + snprintf(hbuf + j * hex_len, hex_len + 1, "%02x ", c); + + if (!isprint(c)) + c = '.'; + + snprintf(cbuf + j, hex_len + 1, "%c", c); + } + + strcat(cbuf, "|"); + + fprintf(stderr, "%08x %*s |%s\n", i, + 0 - (int)sizeof(hbuf) + 1, hbuf, cbuf); + } +} + +void __check_file_contents(struct parser_test *test, + struct discover_device *dev, const char *filename, + const char *buf, int len, + const char *srcfile, int srcline) +{ + struct test_file *f, *file = NULL; + + list_for_each_entry(&test->files, f, list) { + if (f->dev != dev) + continue; + if (strcmp(f->name, filename)) + continue; + + file = f; + break; + } + + if (!file) + errx(EXIT_FAILURE, "%s:%d: File '%s' not found", + srcfile, srcline, filename); + + if (file->size != len || memcmp(file->data, buf, len)) { + fprintf(stderr, "%s:%d: File '%s' data/size mismatch\n", + srcfile, srcline, filename); + fprintf(stderr, "Expected:\n"); + dump_file_data(buf, len); + fprintf(stderr, "Got:\n"); + dump_file_data(file->data, file->size); + exit(EXIT_FAILURE); + } +}