aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLucas De Marchi <lucas.de.marchi@gmail.com>2012-10-04 00:21:52 -0300
committerLucas De Marchi <lucas.de.marchi@gmail.com>2012-10-04 01:04:52 -0300
commit3e451bfefbe1cb481fe9263a64e00926ebfaa229 (patch)
treedf7e23f1601ae8a3333455899dc44875f1a40018
parent88c247f7f18ac25181ddcaff97fbbecbd3a29f57 (diff)
downloadkmod-3e451bfefbe1cb481fe9263a64e00926ebfaa229.tar.gz
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.
-rw-r--r--testsuite/testsuite.c97
-rw-r--r--testsuite/testsuite.h9
2 files changed, 106 insertions, 0 deletions
diff --git a/testsuite/testsuite.c b/testsuite/testsuite.c
index e874191..db51dae 100644
--- a/testsuite/testsuite.c
+++ b/testsuite/testsuite.c
@@ -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)
diff --git a/testsuite/testsuite.h b/testsuite/testsuite.h
index 1f8eb6e..80bf8a1 100644
--- a/testsuite/testsuite.h
+++ b/testsuite/testsuite.h
@@ -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];