From: Jeremy Kerr Date: Fri, 4 Oct 2013 03:09:10 +0000 (+0800) Subject: test/parser: Add check_file_contents X-Git-Tag: v1.0.0~401 X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=commitdiff_plain;h=1b646fb733ef99b1dc1862276ae3595bdeaf355b test/parser: Add check_file_contents We want to test grub2's save_env command, which requires a new function to check the contents of a file. Signed-off-by: Jeremy Kerr --- diff --git a/test/parser/parser-test.h b/test/parser/parser-test.h index eb43c25..ab3424c 100644 --- a/test/parser/parser-test.h +++ b/test/parser/parser-test.h @@ -37,10 +37,10 @@ int test_run_parser(struct parser_test *test, const char *parser_name); void test_hotplug_device(struct parser_test *test, struct discover_device *dev); void test_add_file_data(struct parser_test *test, struct discover_device *dev, - const char *filename, void *data, int size); + const char *filename, const void *data, int size); #define test_add_file_string(test, dev, filename, str) \ - test_add_file_data(test, dev, filename, str, sizeof(str)) + test_add_file_data(test, dev, filename, str, sizeof(str) - 1) struct discover_boot_option *get_boot_option(struct discover_context *ctx, int idx); @@ -125,4 +125,15 @@ void __check_not_present_resource(struct resource *res, #define check_not_present_resource(res) \ __check_not_present_resource(res, __FILE__, __LINE__) +/** + * Check the contents of a file - file @filename must be present on @dev, + * and match the @len bytes of @buf. + */ +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); +#define check_file_contents(test, dev, filename, buf, len) \ + __check_file_contents(test, dev, filename, buf, len, __FILE__, __LINE__) + #endif /* PARSER_TEST_H */ diff --git a/test/parser/utils.c b/test/parser/utils.c index 33efda8..083d916 100644 --- a/test/parser/utils.c +++ b/test/parser/utils.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -152,14 +153,14 @@ void test_set_conf_source(struct parser_test *test, const char *url) } void test_add_file_data(struct parser_test *test, struct discover_device *dev, - const char *filename, void *data, int size) + 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 = data; + file->data = talloc_memdup(test, data, size); file->size = size; list_add(&test->files, &file->list); } @@ -171,6 +172,7 @@ int parser_request_file(struct discover_context *ctx, { 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) @@ -178,7 +180,12 @@ int parser_request_file(struct discover_context *ctx, if (strcmp(file->name, filename)) continue; - *buf = talloc_memdup(test, file->data, file->size); + /* 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; } @@ -208,8 +215,6 @@ int parser_replace_file(struct discover_context *ctx, file->dev = dev; file->name = filename; list_add(&test->files, &file->list); - } else { - talloc_free(file->data); } file->data = talloc_memdup(test, buf, len); @@ -419,3 +424,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); + } +}