aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-04-02 14:52:17 +0100
committerPeter Maydell <peter.maydell@linaro.org>2019-04-02 14:52:17 +0100
commit436960c95946007aca713330e7a488a6f2e0696f (patch)
tree2ee2842fa097887052aa09c4f409af7a6367e193 /tests
parent9a363f0bcc65f5805396241d16973d0c62615162 (diff)
parentb4682a63f86ed81abcaa543ea6135e17f9e99d01 (diff)
Merge remote-tracking branch 'remotes/berrange/tags/filemon-next-pull-request' into staging
filemon: various fixes / improvements to file monitor for USB MTP Ensure watch IDs unique within a monitor and avoid integer wraparound issues when many watches are set & unset over time. # gpg: Signature made Tue 02 Apr 2019 13:53:40 BST # gpg: using RSA key BE86EBB415104FDF # gpg: Good signature from "Daniel P. Berrange <dan@berrange.com>" [full] # gpg: aka "Daniel P. Berrange <berrange@redhat.com>" [full] # Primary key fingerprint: DAF3 A6FD B26B 6291 2D0E 8E3F BE86 EBB4 1510 4FDF * remotes/berrange/tags/filemon-next-pull-request: filemon: fix watch IDs to avoid potential wraparound issues filemon: ensure watch IDs are unique to QFileMonitor scope tests: refactor file monitor test to make it more understandable Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/test-util-filemonitor.c650
1 files changed, 323 insertions, 327 deletions
diff --git a/tests/test-util-filemonitor.c b/tests/test-util-filemonitor.c
index 5d95cea5ee..46e781c022 100644
--- a/tests/test-util-filemonitor.c
+++ b/tests/test-util-filemonitor.c
@@ -26,34 +26,29 @@
#include <utime.h>
enum {
+ QFILE_MONITOR_TEST_OP_ADD_WATCH,
+ QFILE_MONITOR_TEST_OP_DEL_WATCH,
+ QFILE_MONITOR_TEST_OP_EVENT,
QFILE_MONITOR_TEST_OP_CREATE,
QFILE_MONITOR_TEST_OP_APPEND,
QFILE_MONITOR_TEST_OP_TRUNC,
QFILE_MONITOR_TEST_OP_RENAME,
QFILE_MONITOR_TEST_OP_TOUCH,
QFILE_MONITOR_TEST_OP_UNLINK,
+ QFILE_MONITOR_TEST_OP_MKDIR,
+ QFILE_MONITOR_TEST_OP_RMDIR,
};
typedef struct {
int type;
const char *filesrc;
const char *filedst;
+ int64_t *watchid;
+ int eventid;
} QFileMonitorTestOp;
typedef struct {
- const char *file;
-} QFileMonitorTestWatch;
-
-typedef struct {
- gsize nwatches;
- const QFileMonitorTestWatch *watches;
-
- gsize nops;
- const QFileMonitorTestOp *ops;
-} QFileMonitorTestPlan;
-
-typedef struct {
- int id;
+ int64_t id;
QFileMonitorEvent event;
char *filename;
} QFileMonitorTestRecord;
@@ -67,6 +62,7 @@ typedef struct {
static QemuMutex evlock;
static bool evstopping;
static bool evrunning;
+static bool debug;
/*
* Main function for a background thread that is
@@ -94,7 +90,7 @@ qemu_file_monitor_test_event_loop(void *opaque G_GNUC_UNUSED)
* an ordered list of all events that it receives
*/
static void
-qemu_file_monitor_test_handler(int id,
+qemu_file_monitor_test_handler(int64_t id,
QFileMonitorEvent event,
const char *filename,
void *opaque)
@@ -160,7 +156,7 @@ qemu_file_monitor_test_next_record(QFileMonitorTestData *data)
*/
static bool
qemu_file_monitor_test_expect(QFileMonitorTestData *data,
- int id,
+ int64_t id,
QFileMonitorEvent event,
const char *filename)
{
@@ -170,13 +166,14 @@ qemu_file_monitor_test_expect(QFileMonitorTestData *data,
rec = qemu_file_monitor_test_next_record(data);
if (!rec) {
- g_printerr("Missing event watch id %d event %d file %s\n",
+ g_printerr("Missing event watch id %" PRIx64 " event %d file %s\n",
id, event, filename);
return false;
}
if (id != rec->id) {
- g_printerr("Expected watch id %d but got %d\n", id, rec->id);
+ g_printerr("Expected watch id %" PRIx64 " but got %" PRIx64 "\n",
+ id, rec->id);
goto cleanup;
}
@@ -200,9 +197,179 @@ qemu_file_monitor_test_expect(QFileMonitorTestData *data,
static void
-test_file_monitor_events(const void *opaque)
+test_file_monitor_events(void)
{
- const QFileMonitorTestPlan *plan = opaque;
+ int64_t watch0 = 0;
+ int64_t watch1 = 0;
+ int64_t watch2 = 0;
+ int64_t watch3 = 0;
+ int64_t watch4 = 0;
+ int64_t watch5 = 0;
+ QFileMonitorTestOp ops[] = {
+ { .type = QFILE_MONITOR_TEST_OP_ADD_WATCH,
+ .filesrc = NULL, .watchid = &watch0 },
+ { .type = QFILE_MONITOR_TEST_OP_ADD_WATCH,
+ .filesrc = "one.txt", .watchid = &watch1 },
+ { .type = QFILE_MONITOR_TEST_OP_ADD_WATCH,
+ .filesrc = "two.txt", .watchid = &watch2 },
+
+
+ { .type = QFILE_MONITOR_TEST_OP_CREATE,
+ .filesrc = "one.txt", },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "one.txt", .watchid = &watch0,
+ .eventid = QFILE_MONITOR_EVENT_CREATED },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "one.txt", .watchid = &watch1,
+ .eventid = QFILE_MONITOR_EVENT_CREATED },
+
+
+ { .type = QFILE_MONITOR_TEST_OP_CREATE,
+ .filesrc = "two.txt", },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "two.txt", .watchid = &watch0,
+ .eventid = QFILE_MONITOR_EVENT_CREATED },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "two.txt", .watchid = &watch2,
+ .eventid = QFILE_MONITOR_EVENT_CREATED },
+
+
+ { .type = QFILE_MONITOR_TEST_OP_CREATE,
+ .filesrc = "three.txt", },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "three.txt", .watchid = &watch0,
+ .eventid = QFILE_MONITOR_EVENT_CREATED },
+
+
+ { .type = QFILE_MONITOR_TEST_OP_UNLINK,
+ .filesrc = "three.txt", },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "three.txt", .watchid = &watch0,
+ .eventid = QFILE_MONITOR_EVENT_DELETED },
+
+
+ { .type = QFILE_MONITOR_TEST_OP_RENAME,
+ .filesrc = "one.txt", .filedst = "two.txt" },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "one.txt", .watchid = &watch0,
+ .eventid = QFILE_MONITOR_EVENT_DELETED },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "one.txt", .watchid = &watch1,
+ .eventid = QFILE_MONITOR_EVENT_DELETED },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "two.txt", .watchid = &watch0,
+ .eventid = QFILE_MONITOR_EVENT_CREATED },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "two.txt", .watchid = &watch2,
+ .eventid = QFILE_MONITOR_EVENT_CREATED },
+
+
+ { .type = QFILE_MONITOR_TEST_OP_APPEND,
+ .filesrc = "two.txt", },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "two.txt", .watchid = &watch0,
+ .eventid = QFILE_MONITOR_EVENT_MODIFIED },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "two.txt", .watchid = &watch2,
+ .eventid = QFILE_MONITOR_EVENT_MODIFIED },
+
+
+ { .type = QFILE_MONITOR_TEST_OP_TOUCH,
+ .filesrc = "two.txt", },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "two.txt", .watchid = &watch0,
+ .eventid = QFILE_MONITOR_EVENT_ATTRIBUTES },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "two.txt", .watchid = &watch2,
+ .eventid = QFILE_MONITOR_EVENT_ATTRIBUTES },
+
+
+ { .type = QFILE_MONITOR_TEST_OP_DEL_WATCH,
+ .filesrc = "one.txt", .watchid = &watch1 },
+ { .type = QFILE_MONITOR_TEST_OP_ADD_WATCH,
+ .filesrc = "one.txt", .watchid = &watch3 },
+ { .type = QFILE_MONITOR_TEST_OP_CREATE,
+ .filesrc = "one.txt", },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "one.txt", .watchid = &watch0,
+ .eventid = QFILE_MONITOR_EVENT_CREATED },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "one.txt", .watchid = &watch3,
+ .eventid = QFILE_MONITOR_EVENT_CREATED },
+
+
+ { .type = QFILE_MONITOR_TEST_OP_DEL_WATCH,
+ .filesrc = "one.txt", .watchid = &watch3 },
+ { .type = QFILE_MONITOR_TEST_OP_UNLINK,
+ .filesrc = "one.txt", },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "one.txt", .watchid = &watch0,
+ .eventid = QFILE_MONITOR_EVENT_DELETED },
+
+
+ { .type = QFILE_MONITOR_TEST_OP_MKDIR,
+ .filesrc = "fish", },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "fish", .watchid = &watch0,
+ .eventid = QFILE_MONITOR_EVENT_CREATED },
+
+
+ { .type = QFILE_MONITOR_TEST_OP_ADD_WATCH,
+ .filesrc = "fish/", .watchid = &watch4 },
+ { .type = QFILE_MONITOR_TEST_OP_ADD_WATCH,
+ .filesrc = "fish/one.txt", .watchid = &watch5 },
+ { .type = QFILE_MONITOR_TEST_OP_CREATE,
+ .filesrc = "fish/one.txt", },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "one.txt", .watchid = &watch4,
+ .eventid = QFILE_MONITOR_EVENT_CREATED },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "one.txt", .watchid = &watch5,
+ .eventid = QFILE_MONITOR_EVENT_CREATED },
+
+
+ { .type = QFILE_MONITOR_TEST_OP_DEL_WATCH,
+ .filesrc = "fish/one.txt", .watchid = &watch5 },
+ { .type = QFILE_MONITOR_TEST_OP_RENAME,
+ .filesrc = "fish/one.txt", .filedst = "two.txt", },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "one.txt", .watchid = &watch4,
+ .eventid = QFILE_MONITOR_EVENT_DELETED },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "two.txt", .watchid = &watch0,
+ .eventid = QFILE_MONITOR_EVENT_CREATED },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "two.txt", .watchid = &watch2,
+ .eventid = QFILE_MONITOR_EVENT_CREATED },
+
+
+ { .type = QFILE_MONITOR_TEST_OP_RMDIR,
+ .filesrc = "fish", },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "", .watchid = &watch4,
+ .eventid = QFILE_MONITOR_EVENT_IGNORED },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "fish", .watchid = &watch0,
+ .eventid = QFILE_MONITOR_EVENT_DELETED },
+ { .type = QFILE_MONITOR_TEST_OP_DEL_WATCH,
+ .filesrc = "fish", .watchid = &watch4 },
+
+
+ { .type = QFILE_MONITOR_TEST_OP_UNLINK,
+ .filesrc = "two.txt", },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "two.txt", .watchid = &watch0,
+ .eventid = QFILE_MONITOR_EVENT_DELETED },
+ { .type = QFILE_MONITOR_TEST_OP_EVENT,
+ .filesrc = "two.txt", .watchid = &watch2,
+ .eventid = QFILE_MONITOR_EVENT_DELETED },
+
+
+ { .type = QFILE_MONITOR_TEST_OP_DEL_WATCH,
+ .filesrc = "two.txt", .watchid = &watch2 },
+ { .type = QFILE_MONITOR_TEST_OP_DEL_WATCH,
+ .filesrc = NULL, .watchid = &watch0 },
+ };
Error *local_err = NULL;
GError *gerr = NULL;
QFileMonitor *mon = qemu_file_monitor_new(&local_err);
@@ -210,10 +377,11 @@ test_file_monitor_events(const void *opaque)
GTimer *timer;
gchar *dir = NULL;
int err = -1;
- gsize i, j;
+ gsize i;
char *pathsrc = NULL;
char *pathdst = NULL;
QFileMonitorTestData data;
+ GHashTable *ids = g_hash_table_new(g_int64_hash, g_int64_equal);
qemu_mutex_init(&data.lock);
data.records = NULL;
@@ -248,34 +416,15 @@ test_file_monitor_events(const void *opaque)
}
/*
- * First register all the directory / file watches
- * we're interested in seeing events against
- */
- for (i = 0; i < plan->nwatches; i++) {
- int watchid;
- watchid = qemu_file_monitor_add_watch(mon,
- dir,
- plan->watches[i].file,
- qemu_file_monitor_test_handler,
- &data,
- &local_err);
- if (watchid < 0) {
- g_printerr("Unable to add watch %s",
- error_get_pretty(local_err));
- goto cleanup;
- }
- }
-
-
- /*
- * Now invoke all the file operations (create,
- * delete, rename, chmod, etc). These operations
- * will trigger the various file monitor events
+ * Run through the operation sequence validating events
+ * as we go
*/
- for (i = 0; i < plan->nops; i++) {
- const QFileMonitorTestOp *op = &(plan->ops[i]);
+ for (i = 0; i < G_N_ELEMENTS(ops); i++) {
+ const QFileMonitorTestOp *op = &(ops[i]);
int fd;
struct utimbuf ubuf;
+ char *watchdir;
+ const char *watchfile;
pathsrc = g_strdup_printf("%s/%s", dir, op->filesrc);
if (op->filedst) {
@@ -283,7 +432,75 @@ test_file_monitor_events(const void *opaque)
}
switch (op->type) {
+ case QFILE_MONITOR_TEST_OP_ADD_WATCH:
+ if (debug) {
+ g_printerr("Add watch %s %s\n",
+ dir, op->filesrc);
+ }
+ if (op->filesrc && strchr(op->filesrc, '/')) {
+ watchdir = g_strdup_printf("%s/%s", dir, op->filesrc);
+ watchfile = strrchr(watchdir, '/');
+ *(char *)watchfile = '\0';
+ watchfile++;
+ if (*watchfile == '\0') {
+ watchfile = NULL;
+ }
+ } else {
+ watchdir = g_strdup(dir);
+ watchfile = op->filesrc;
+ }
+ *op->watchid =
+ qemu_file_monitor_add_watch(mon,
+ watchdir,
+ watchfile,
+ qemu_file_monitor_test_handler,
+ &data,
+ &local_err);
+ g_free(watchdir);
+ if (*op->watchid < 0) {
+ g_printerr("Unable to add watch %s",
+ error_get_pretty(local_err));
+ goto cleanup;
+ }
+ if (debug) {
+ g_printerr("Watch ID %" PRIx64 "\n", *op->watchid);
+ }
+ if (g_hash_table_contains(ids, op->watchid)) {
+ g_printerr("Watch ID %" PRIx64 "already exists", *op->watchid);
+ goto cleanup;
+ }
+ g_hash_table_add(ids, op->watchid);
+ break;
+ case QFILE_MONITOR_TEST_OP_DEL_WATCH:
+ if (debug) {
+ g_printerr("Del watch %s %" PRIx64 "\n", dir, *op->watchid);
+ }
+ if (op->filesrc && strchr(op->filesrc, '/')) {
+ watchdir = g_strdup_printf("%s/%s", dir, op->filesrc);
+ watchfile = strrchr(watchdir, '/');
+ *(char *)watchfile = '\0';
+ } else {
+ watchdir = g_strdup(dir);
+ }
+ g_hash_table_remove(ids, op->watchid);
+ qemu_file_monitor_remove_watch(mon,
+ watchdir,
+ *op->watchid);
+ g_free(watchdir);
+ break;
+ case QFILE_MONITOR_TEST_OP_EVENT:
+ if (debug) {
+ g_printerr("Event id=%" PRIx64 " event=%d file=%s\n",
+ *op->watchid, op->eventid, op->filesrc);
+ }
+ if (!qemu_file_monitor_test_expect(
+ &data, *op->watchid, op->eventid, op->filesrc))
+ goto cleanup;
+ break;
case QFILE_MONITOR_TEST_OP_CREATE:
+ if (debug) {
+ g_printerr("Create %s\n", pathsrc);
+ }
fd = open(pathsrc, O_WRONLY | O_CREAT, 0700);
if (fd < 0) {
g_printerr("Unable to create %s: %s",
@@ -294,6 +511,9 @@ test_file_monitor_events(const void *opaque)
break;
case QFILE_MONITOR_TEST_OP_APPEND:
+ if (debug) {
+ g_printerr("Append %s\n", pathsrc);
+ }
fd = open(pathsrc, O_WRONLY | O_APPEND, 0700);
if (fd < 0) {
g_printerr("Unable to open %s: %s",
@@ -311,6 +531,9 @@ test_file_monitor_events(const void *opaque)
break;
case QFILE_MONITOR_TEST_OP_TRUNC:
+ if (debug) {
+ g_printerr("Truncate %s\n", pathsrc);
+ }
if (truncate(pathsrc, 4) < 0) {
g_printerr("Unable to truncate %s: %s",
pathsrc, strerror(errno));
@@ -319,6 +542,9 @@ test_file_monitor_events(const void *opaque)
break;
case QFILE_MONITOR_TEST_OP_RENAME:
+ if (debug) {
+ g_printerr("Rename %s -> %s\n", pathsrc, pathdst);
+ }
if (rename(pathsrc, pathdst) < 0) {
g_printerr("Unable to rename %s to %s: %s",
pathsrc, pathdst, strerror(errno));
@@ -327,6 +553,9 @@ test_file_monitor_events(const void *opaque)
break;
case QFILE_MONITOR_TEST_OP_UNLINK:
+ if (debug) {
+ g_printerr("Unlink %s\n", pathsrc);
+ }
if (unlink(pathsrc) < 0) {
g_printerr("Unable to unlink %s: %s",
pathsrc, strerror(errno));
@@ -335,6 +564,9 @@ test_file_monitor_events(const void *opaque)
break;
case QFILE_MONITOR_TEST_OP_TOUCH:
+ if (debug) {
+ g_printerr("Touch %s\n", pathsrc);
+ }
ubuf.actime = 1024;
ubuf.modtime = 1025;
if (utime(pathsrc, &ubuf) < 0) {
@@ -344,101 +576,39 @@ test_file_monitor_events(const void *opaque)
}
break;
- default:
- g_assert_not_reached();
- }
-
- g_free(pathsrc);
- g_free(pathdst);
- pathsrc = pathdst = NULL;
- }
-
-
- /*
- * Finally validate that we have received all the events
- * we expect to see for the combination of watches and
- * file operations
- */
- for (i = 0; i < plan->nops; i++) {
- const QFileMonitorTestOp *op = &(plan->ops[i]);
-
- switch (op->type) {
- case QFILE_MONITOR_TEST_OP_CREATE:
- for (j = 0; j < plan->nwatches; j++) {
- if (plan->watches[j].file &&
- !g_str_equal(plan->watches[j].file, op->filesrc))
- continue;
-
- if (!qemu_file_monitor_test_expect(
- &data, j, QFILE_MONITOR_EVENT_CREATED, op->filesrc))
- goto cleanup;
+ case QFILE_MONITOR_TEST_OP_MKDIR:
+ if (debug) {
+ g_printerr("Mkdir %s\n", pathsrc);
}
- break;
-
- case QFILE_MONITOR_TEST_OP_APPEND:
- case QFILE_MONITOR_TEST_OP_TRUNC:
- for (j = 0; j < plan->nwatches; j++) {
- if (plan->watches[j].file &&
- !g_str_equal(plan->watches[j].file, op->filesrc))
- continue;
-
- if (!qemu_file_monitor_test_expect(
- &data, j, QFILE_MONITOR_EVENT_MODIFIED, op->filesrc))
- goto cleanup;
- }
- break;
-
- case QFILE_MONITOR_TEST_OP_RENAME:
- for (j = 0; j < plan->nwatches; j++) {
- if (plan->watches[j].file &&
- !g_str_equal(plan->watches[j].file, op->filesrc))
- continue;
-
- if (!qemu_file_monitor_test_expect(
- &data, j, QFILE_MONITOR_EVENT_DELETED, op->filesrc))
- goto cleanup;
- }
-
- for (j = 0; j < plan->nwatches; j++) {
- if (plan->watches[j].file &&
- !g_str_equal(plan->watches[j].file, op->filedst))
- continue;
-
- if (!qemu_file_monitor_test_expect(
- &data, j, QFILE_MONITOR_EVENT_CREATED, op->filedst))
- goto cleanup;
+ if (mkdir(pathsrc, 0700) < 0) {
+ g_printerr("Unable to mkdir %s: %s",
+ pathsrc, strerror(errno));
+ goto cleanup;
}
break;
- case QFILE_MONITOR_TEST_OP_TOUCH:
- for (j = 0; j < plan->nwatches; j++) {
- if (plan->watches[j].file &&
- !g_str_equal(plan->watches[j].file, op->filesrc))
- continue;
-
- if (!qemu_file_monitor_test_expect(
- &data, j, QFILE_MONITOR_EVENT_ATTRIBUTES, op->filesrc))
- goto cleanup;
+ case QFILE_MONITOR_TEST_OP_RMDIR:
+ if (debug) {
+ g_printerr("Rmdir %s\n", pathsrc);
}
- break;
-
- case QFILE_MONITOR_TEST_OP_UNLINK:
- for (j = 0; j < plan->nwatches; j++) {
- if (plan->watches[j].file &&
- !g_str_equal(plan->watches[j].file, op->filesrc))
- continue;
-
- if (!qemu_file_monitor_test_expect(
- &data, j, QFILE_MONITOR_EVENT_DELETED, op->filesrc))
- goto cleanup;
+ if (rmdir(pathsrc) < 0) {
+ g_printerr("Unable to rmdir %s: %s",
+ pathsrc, strerror(errno));
+ goto cleanup;
}
break;
default:
g_assert_not_reached();
}
+
+ g_free(pathsrc);
+ g_free(pathdst);
+ pathsrc = pathdst = NULL;
}
+ g_assert_cmpint(g_hash_table_size(ids), ==, 0);
+
err = 0;
cleanup:
@@ -460,171 +630,42 @@ test_file_monitor_events(const void *opaque)
}
g_timer_destroy(timer);
- for (i = 0; i < plan->nops; i++) {
- const QFileMonitorTestOp *op = &(plan->ops[i]);
- pathsrc = g_strdup_printf("%s/%s", dir, op->filesrc);
- unlink(pathsrc);
- g_free(pathsrc);
- if (op->filedst) {
- pathdst = g_strdup_printf("%s/%s", dir, op->filedst);
- unlink(pathdst);
- g_free(pathdst);
- }
- }
-
qemu_file_monitor_free(mon);
g_list_foreach(data.records,
(GFunc)qemu_file_monitor_test_record_free, NULL);
g_list_free(data.records);
qemu_mutex_destroy(&data.lock);
if (dir) {
- rmdir(dir);
+ for (i = 0; i < G_N_ELEMENTS(ops); i++) {
+ const QFileMonitorTestOp *op = &(ops[i]);
+ char *path = g_strdup_printf("%s/%s",
+ dir, op->filesrc);
+ if (op->type == QFILE_MONITOR_TEST_OP_MKDIR) {
+ rmdir(path);
+ g_free(path);
+ } else {
+ unlink(path);
+ g_free(path);
+ if (op->filedst) {
+ path = g_strdup_printf("%s/%s",
+ dir, op->filedst);
+ unlink(path);
+ g_free(path);
+ }
+ }
+ }
+ if (rmdir(dir) < 0) {
+ g_printerr("Failed to remove %s: %s\n",
+ dir, strerror(errno));
+ abort();
+ }
}
+ g_hash_table_unref(ids);
g_free(dir);
g_assert(err == 0);
}
-/*
- * Set of structs which define which file name patterns
- * we're trying to watch against. NULL, means all files
- * in the directory
- */
-static const QFileMonitorTestWatch watches_any[] = {
- { NULL },
-};
-
-static const QFileMonitorTestWatch watches_one[] = {
- { "one.txt" },
-};
-
-static const QFileMonitorTestWatch watches_two[] = {
- { "two.txt" },
-};
-
-static const QFileMonitorTestWatch watches_many[] = {
- { NULL },
- { "one.txt" },
- { "two.txt" },
-};
-
-
-/*
- * Various sets of file operations we're going to
- * trigger and validate events for
- */
-static const QFileMonitorTestOp ops_create_one[] = {
- { .type = QFILE_MONITOR_TEST_OP_CREATE,
- .filesrc = "one.txt", }
-};
-
-static const QFileMonitorTestOp ops_delete_one[] = {
- { .type = QFILE_MONITOR_TEST_OP_CREATE,
- .filesrc = "one.txt", },
- { .type = QFILE_MONITOR_TEST_OP_UNLINK,
- .filesrc = "one.txt", }
-};
-
-static const QFileMonitorTestOp ops_create_many[] = {
- { .type = QFILE_MONITOR_TEST_OP_CREATE,
- .filesrc = "one.txt", },
- { .type = QFILE_MONITOR_TEST_OP_CREATE,
- .filesrc = "two.txt", },
- { .type = QFILE_MONITOR_TEST_OP_CREATE,
- .filesrc = "three.txt", }
-};
-
-static const QFileMonitorTestOp ops_rename_one[] = {
- { .type = QFILE_MONITOR_TEST_OP_CREATE,
- .filesrc = "one.txt", },
- { .type = QFILE_MONITOR_TEST_OP_RENAME,
- .filesrc = "one.txt", .filedst = "two.txt" }
-};
-
-static const QFileMonitorTestOp ops_rename_many[] = {
- { .type = QFILE_MONITOR_TEST_OP_CREATE,
- .filesrc = "one.txt", },
- { .type = QFILE_MONITOR_TEST_OP_CREATE,
- .filesrc = "two.txt", },
- { .type = QFILE_MONITOR_TEST_OP_RENAME,
- .filesrc = "one.txt", .filedst = "two.txt" }
-};
-
-static const QFileMonitorTestOp ops_append_one[] = {
- { .type = QFILE_MONITOR_TEST_OP_CREATE,
- .filesrc = "one.txt", },
- { .type = QFILE_MONITOR_TEST_OP_APPEND,
- .filesrc = "one.txt", },
-};
-
-static const QFileMonitorTestOp ops_trunc_one[] = {
- { .type = QFILE_MONITOR_TEST_OP_CREATE,
- .filesrc = "one.txt", },
- { .type = QFILE_MONITOR_TEST_OP_TRUNC,
- .filesrc = "one.txt", },
-};
-
-static const QFileMonitorTestOp ops_touch_one[] = {
- { .type = QFILE_MONITOR_TEST_OP_CREATE,
- .filesrc = "one.txt", },
- { .type = QFILE_MONITOR_TEST_OP_TOUCH,
- .filesrc = "one.txt", },
-};
-
-
-/*
- * No we define data sets for the combinatorial
- * expansion of file watches and operation sets
- */
-#define PLAN_DATA(o, w) \
- static const QFileMonitorTestPlan plan_ ## o ## _ ## w = { \
- .nops = G_N_ELEMENTS(ops_ ##o), \
- .ops = ops_ ##o, \
- .nwatches = G_N_ELEMENTS(watches_ ##w), \
- .watches = watches_ ## w, \
- }
-
-PLAN_DATA(create_one, any);
-PLAN_DATA(create_one, one);
-PLAN_DATA(create_one, two);
-PLAN_DATA(create_one, many);
-
-PLAN_DATA(delete_one, any);
-PLAN_DATA(delete_one, one);
-PLAN_DATA(delete_one, two);
-PLAN_DATA(delete_one, many);
-
-PLAN_DATA(create_many, any);
-PLAN_DATA(create_many, one);
-PLAN_DATA(create_many, two);
-PLAN_DATA(create_many, many);
-
-PLAN_DATA(rename_one, any);
-PLAN_DATA(rename_one, one);
-PLAN_DATA(rename_one, two);
-PLAN_DATA(rename_one, many);
-
-PLAN_DATA(rename_many, any);
-PLAN_DATA(rename_many, one);
-PLAN_DATA(rename_many, two);
-PLAN_DATA(rename_many, many);
-
-PLAN_DATA(append_one, any);
-PLAN_DATA(append_one, one);
-PLAN_DATA(append_one, two);
-PLAN_DATA(append_one, many);
-
-PLAN_DATA(trunc_one, any);
-PLAN_DATA(trunc_one, one);
-PLAN_DATA(trunc_one, two);
-PLAN_DATA(trunc_one, many);
-
-PLAN_DATA(touch_one, any);
-PLAN_DATA(touch_one, one);
-PLAN_DATA(touch_one, two);
-PLAN_DATA(touch_one, many);
-
-
int main(int argc, char **argv)
{
g_test_init(&argc, &argv, NULL);
@@ -633,53 +674,8 @@ int main(int argc, char **argv)
qemu_mutex_init(&evlock);
- /*
- * Register test cases for the combinatorial
- * expansion of file watches and operation sets
- */
- #define PLAN_REGISTER(o, w) \
- g_test_add_data_func("/util/filemonitor/" # o "/" # w, \
- &plan_ ## o ## _ ## w, test_file_monitor_events)
-
- PLAN_REGISTER(create_one, any);
- PLAN_REGISTER(create_one, one);
- PLAN_REGISTER(create_one, two);
- PLAN_REGISTER(create_one, many);
-
- PLAN_REGISTER(delete_one, any);
- PLAN_REGISTER(delete_one, one);
- PLAN_REGISTER(delete_one, two);
- PLAN_REGISTER(delete_one, many);
-
- PLAN_REGISTER(create_many, any);
- PLAN_REGISTER(create_many, one);
- PLAN_REGISTER(create_many, two);
- PLAN_REGISTER(create_many, many);
-
- PLAN_REGISTER(rename_one, any);
- PLAN_REGISTER(rename_one, one);
- PLAN_REGISTER(rename_one, two);
- PLAN_REGISTER(rename_one, many);
-
- PLAN_REGISTER(rename_many, any);
- PLAN_REGISTER(rename_many, one);
- PLAN_REGISTER(rename_many, two);
- PLAN_REGISTER(rename_many, many);
-
- PLAN_REGISTER(append_one, any);
- PLAN_REGISTER(append_one, one);
- PLAN_REGISTER(append_one, two);
- PLAN_REGISTER(append_one, many);
-
- PLAN_REGISTER(trunc_one, any);
- PLAN_REGISTER(trunc_one, one);
- PLAN_REGISTER(trunc_one, two);
- PLAN_REGISTER(trunc_one, many);
-
- PLAN_REGISTER(touch_one, any);
- PLAN_REGISTER(touch_one, one);
- PLAN_REGISTER(touch_one, two);
- PLAN_REGISTER(touch_one, many);
+ debug = getenv("FILEMONITOR_DEBUG") != NULL;
+ g_test_add_func("/util/filemonitor", test_file_monitor_events);
return g_test_run();
}