testsuite: allow to check generated files

This gives the test cases the ability to supply files that must be
checked after the test is run, rather than just checking stdout/stderr.

This is intended to be used with tools that generate files, like depmod.
It includes a poor's man implementation of a "check for differences in
files". Not really optimized, but it's simple enough and does what it
proposes to.
This commit is contained in:
Lucas De Marchi 2012-10-04 00:21:52 -03:00
parent 88c247f7f1
commit 3e451bfefb
2 changed files with 106 additions and 0 deletions

View File

@ -434,6 +434,100 @@ out:
return err == 0;
}
static inline int safe_read(int fd, void *buf, size_t count)
{
int r;
while (1) {
r = read(fd, buf, count);
if (r == -1 && errno == -EINTR)
continue;
break;
}
return r;
}
static bool check_generated_files(const struct test *t)
{
const struct keyval *k;
/* This is not meant to be a diff replacement, just stupidly check if
* the files match. Bear in mind they can be binary files */
for (k = t->output.files; k && k->key; k++) {
struct stat sta, stb;
int fda = -1, fdb = -1;
char bufa[4096];
char bufb[4096];
fda = open(k->key, O_RDONLY);
if (fda < 0) {
ERR("could not open %s\n - %m\n", k->key);
goto fail;
}
fdb = open(k->val, O_RDONLY);
if (fdb < 0) {
ERR("could not open %s\n - %m\n", k->val);
goto fail;
}
if (fstat(fda, &sta) != 0) {
ERR("could not fstat %d %s\n - %m\n", fda, k->key);
goto fail;
}
if (fstat(fdb, &stb) != 0) {
ERR("could not fstat %d %s\n - %m\n", fdb, k->key);
goto fail;
}
if (sta.st_size != stb.st_size) {
ERR("sizes do not match %s %s\n", k->key, k->val);
goto fail;
}
for (;;) {
int r, done;
r = safe_read(fda, bufa, sizeof(bufa));
if (r < 0)
goto fail;
if (r == 0)
/* size is already checked, go to next file */
goto next;
for (done = 0; done < r;) {
int r2 = safe_read(fdb, bufb + done, r - done);
if (r2 <= 0)
goto fail;
done += r2;
}
if (memcmp(bufa, bufb, r) != 0)
goto fail;
}
next:
close(fda);
close(fdb);
continue;
fail:
if (fda >= 0)
close(fda);
if (fdb >= 0)
close(fdb);
return false;
}
return true;
}
static inline int test_run_parent(const struct test *t, int fdout[2],
int fderr[2], int fdmonitor[2], pid_t child)
{
@ -482,6 +576,9 @@ static inline int test_run_parent(const struct test *t, int fdout[2],
return EXIT_FAILURE;
}
if (matchout)
matchout = check_generated_files(t);
if (t->expected_fail == false) {
if (err == 0) {
if (matchout)

View File

@ -81,8 +81,17 @@ struct test {
const char *name;
const char *description;
struct {
/* File with correct stdout */
const char *stdout;
/* File with correct stderr */
const char *stderr;
/*
* Vector with pair of files
* key = correct file
* val = file to check
*/
const struct keyval *files;
} output;
testfunc func;
const char *config[_TC_LAST];