summaryrefslogtreecommitdiff
path: root/deps/uv/test/test-fs-event.c
diff options
context:
space:
mode:
Diffstat (limited to 'deps/uv/test/test-fs-event.c')
-rw-r--r--deps/uv/test/test-fs-event.c273
1 files changed, 199 insertions, 74 deletions
diff --git a/deps/uv/test/test-fs-event.c b/deps/uv/test/test-fs-event.c
index 0a2ba33145..a0908ce575 100644
--- a/deps/uv/test/test-fs-event.c
+++ b/deps/uv/test/test-fs-event.c
@@ -37,11 +37,15 @@
static uv_fs_event_t fs_event;
static const char file_prefix[] = "fsevent-";
+static const int fs_event_file_count = 16;
+#if defined(__APPLE__) || defined(_WIN32)
+static const char file_prefix_in_subdir[] = "subdir";
+#endif
static uv_timer_t timer;
static int timer_cb_called;
static int close_cb_called;
-static const int fs_event_file_count = 128;
static int fs_event_created;
+static int fs_event_removed;
static int fs_event_cb_called;
#if defined(PATH_MAX)
static char fs_event_filename[PATH_MAX];
@@ -50,48 +54,45 @@ static char fs_event_filename[1024];
#endif /* defined(PATH_MAX) */
static int timer_cb_touch_called;
-static void fs_event_unlink_files(uv_timer_t* handle);
-
-static void create_dir(uv_loop_t* loop, const char* name) {
+static void create_dir(const char* name) {
int r;
uv_fs_t req;
- r = uv_fs_mkdir(loop, &req, name, 0755, NULL);
+ r = uv_fs_mkdir(NULL, &req, name, 0755, NULL);
ASSERT(r == 0 || r == UV_EEXIST);
uv_fs_req_cleanup(&req);
}
-static void create_file(uv_loop_t* loop, const char* name) {
+static void create_file(const char* name) {
int r;
uv_file file;
uv_fs_t req;
- r = uv_fs_open(loop, &req, name, O_WRONLY | O_CREAT,
- S_IWUSR | S_IRUSR, NULL);
+ r = uv_fs_open(NULL, &req, name, O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR, NULL);
ASSERT(r >= 0);
file = r;
uv_fs_req_cleanup(&req);
- r = uv_fs_close(loop, &req, file, NULL);
+ r = uv_fs_close(NULL, &req, file, NULL);
ASSERT(r == 0);
uv_fs_req_cleanup(&req);
}
-static void touch_file(uv_loop_t* loop, const char* name) {
+static void touch_file(const char* name) {
int r;
uv_file file;
uv_fs_t req;
uv_buf_t buf;
- r = uv_fs_open(loop, &req, name, O_RDWR, 0, NULL);
+ r = uv_fs_open(NULL, &req, name, O_RDWR, 0, NULL);
ASSERT(r >= 0);
file = r;
uv_fs_req_cleanup(&req);
buf = uv_buf_init("foo", 4);
- r = uv_fs_write(loop, &req, file, &buf, 1, -1, NULL);
+ r = uv_fs_write(NULL, &req, file, &buf, 1, -1, NULL);
ASSERT(r >= 0);
uv_fs_req_cleanup(&req);
- r = uv_fs_close(loop, &req, file, NULL);
+ r = uv_fs_close(NULL, &req, file, NULL);
ASSERT(r == 0);
uv_fs_req_cleanup(&req);
}
@@ -119,6 +120,56 @@ static void fs_event_cb_dir(uv_fs_event_t* handle, const char* filename,
uv_close((uv_handle_t*)handle, close_cb);
}
+static const char* fs_event_get_filename(int i) {
+ snprintf(fs_event_filename,
+ sizeof(fs_event_filename),
+ "watch_dir/%s%d",
+ file_prefix,
+ i);
+ return fs_event_filename;
+}
+
+static void fs_event_create_files(uv_timer_t* handle) {
+ /* Make sure we're not attempting to create files we do not intend */
+ ASSERT(fs_event_created < fs_event_file_count);
+
+ /* Create the file */
+ create_file(fs_event_get_filename(fs_event_created));
+
+ if (++fs_event_created < fs_event_file_count) {
+ /* Create another file on a different event loop tick. We do it this way
+ * to avoid fs events coalescing into one fs event. */
+ ASSERT(0 == uv_timer_start(&timer, fs_event_create_files, 1, 0));
+ }
+}
+
+static void fs_event_unlink_files(uv_timer_t* handle) {
+ int r;
+ int i;
+
+ /* NOTE: handle might be NULL if invoked not as timer callback */
+ if (handle == NULL) {
+ /* Unlink all files */
+ for (i = 0; i < 16; i++) {
+ r = remove(fs_event_get_filename(i));
+ if (handle != NULL)
+ ASSERT(r == 0);
+ }
+ } else {
+ /* Make sure we're not attempting to remove files we do not intend */
+ ASSERT(fs_event_removed < fs_event_file_count);
+
+ /* Remove the file */
+ ASSERT(0 == remove(fs_event_get_filename(fs_event_removed)));
+
+ if (++fs_event_removed < fs_event_file_count) {
+ /* Remove another file on a different event loop tick. We do it this way
+ * to avoid fs events coalescing into one fs event. */
+ ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files, 1, 0));
+ }
+ }
+}
+
static void fs_event_cb_dir_multi_file(uv_fs_event_t* handle,
const char* filename,
int events,
@@ -126,61 +177,92 @@ static void fs_event_cb_dir_multi_file(uv_fs_event_t* handle,
fs_event_cb_called++;
ASSERT(handle == &fs_event);
ASSERT(status == 0);
- ASSERT(events == UV_RENAME);
+ ASSERT(events == UV_CHANGE || UV_RENAME);
ASSERT(filename == NULL ||
strncmp(filename, file_prefix, sizeof(file_prefix) - 1) == 0);
- /* Stop watching dir when received events about all files:
- * both create and close events */
- if (fs_event_cb_called == 2 * fs_event_file_count) {
- ASSERT(0 == uv_fs_event_stop(handle));
+ if (fs_event_created + fs_event_removed == fs_event_file_count) {
+ /* Once we've processed all create events, delete all files */
+ ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files, 1, 0));
+ } else if (fs_event_cb_called == 2 * fs_event_file_count) {
+ /* Once we've processed all create and delete events, stop watching */
+ uv_close((uv_handle_t*) &timer, close_cb);
uv_close((uv_handle_t*) handle, close_cb);
}
}
-static const char* fs_event_get_filename(int i) {
+#if defined(__APPLE__) || defined(_WIN32)
+static const char* fs_event_get_filename_in_subdir(int i) {
snprintf(fs_event_filename,
sizeof(fs_event_filename),
- "watch_dir/%s%d",
+ "watch_dir/subdir/%s%d",
file_prefix,
i);
return fs_event_filename;
}
-static void fs_event_create_files(uv_timer_t* handle) {
- int i;
-
- /* Already created all files */
- if (fs_event_created == fs_event_file_count) {
- uv_close((uv_handle_t*) &timer, close_cb);
- return;
- }
+static void fs_event_create_files_in_subdir(uv_timer_t* handle) {
+ /* Make sure we're not attempting to create files we do not intend */
+ ASSERT(fs_event_created < fs_event_file_count);
- /* Create all files */
- for (i = 0; i < 16; i++, fs_event_created++)
- create_file(handle->loop, fs_event_get_filename(i));
+ /* Create the file */
+ create_file(fs_event_get_filename_in_subdir(fs_event_created));
- /* And unlink them */
- ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files, 50, 0));
+ if (++fs_event_created < fs_event_file_count) {
+ /* Create another file on a different event loop tick. We do it this way
+ * to avoid fs events coalescing into one fs event. */
+ ASSERT(0 == uv_timer_start(&timer, fs_event_create_files_in_subdir, 1, 0));
+ }
}
-void fs_event_unlink_files(uv_timer_t* handle) {
+static void fs_event_unlink_files_in_subdir(uv_timer_t* handle) {
int r;
int i;
/* NOTE: handle might be NULL if invoked not as timer callback */
+ if (handle == NULL) {
+ /* Unlink all files */
+ for (i = 0; i < 16; i++) {
+ r = remove(fs_event_get_filename_in_subdir(i));
+ if (handle != NULL)
+ ASSERT(r == 0);
+ }
+ } else {
+ /* Make sure we're not attempting to remove files we do not intend */
+ ASSERT(fs_event_removed < fs_event_file_count);
+
+ /* Remove the file */
+ ASSERT(0 == remove(fs_event_get_filename_in_subdir(fs_event_removed)));
- /* Unlink all files */
- for (i = 0; i < 16; i++) {
- r = remove(fs_event_get_filename(i));
- if (handle != NULL)
- ASSERT(r == 0);
+ if (++fs_event_removed < fs_event_file_count) {
+ /* Remove another file on a different event loop tick. We do it this way
+ * to avoid fs events coalescing into one fs event. */
+ ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files_in_subdir, 1, 0));
+ }
}
+}
+
+static void fs_event_cb_dir_multi_file_in_subdir(uv_fs_event_t* handle,
+ const char* filename,
+ int events,
+ int status) {
+ fs_event_cb_called++;
+ ASSERT(handle == &fs_event);
+ ASSERT(status == 0);
+ ASSERT(events == UV_CHANGE || UV_RENAME);
+ ASSERT(filename == NULL ||
+ strncmp(filename, file_prefix_in_subdir, sizeof(file_prefix_in_subdir) - 1) == 0);
- /* And create them again */
- if (handle != NULL)
- ASSERT(0 == uv_timer_start(&timer, fs_event_create_files, 50, 0));
+ if (fs_event_created + fs_event_removed == fs_event_file_count) {
+ /* Once we've processed all create events, delete all files */
+ ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files_in_subdir, 1, 0));
+ } else if (fs_event_cb_called == 2 * fs_event_file_count) {
+ /* Once we've processed all create and delete events, stop watching */
+ uv_close((uv_handle_t*) &timer, close_cb);
+ uv_close((uv_handle_t*) handle, close_cb);
+ }
}
+#endif
static void fs_event_cb_file(uv_fs_event_t* handle, const char* filename,
int events, int status) {
@@ -226,16 +308,16 @@ static void timer_cb_file(uv_timer_t* handle) {
++timer_cb_called;
if (timer_cb_called == 1) {
- touch_file(handle->loop, "watch_dir/file1");
+ touch_file("watch_dir/file1");
} else {
- touch_file(handle->loop, "watch_dir/file2");
+ touch_file("watch_dir/file2");
uv_close((uv_handle_t*)handle, close_cb);
}
}
static void timer_cb_touch(uv_timer_t* timer) {
uv_close((uv_handle_t*)timer, NULL);
- touch_file(timer->loop, "watch_file");
+ touch_file("watch_file");
timer_cb_touch_called++;
}
@@ -255,7 +337,7 @@ TEST_IMPL(fs_event_watch_dir) {
remove("watch_dir/file2");
remove("watch_dir/file1");
remove("watch_dir/");
- create_dir(loop, "watch_dir");
+ create_dir("watch_dir");
r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
@@ -268,8 +350,7 @@ TEST_IMPL(fs_event_watch_dir) {
uv_run(loop, UV_RUN_DEFAULT);
- ASSERT(fs_event_cb_called == 2 * fs_event_file_count);
- ASSERT(fs_event_created == fs_event_file_count);
+ ASSERT(fs_event_cb_called == fs_event_created + fs_event_removed);
ASSERT(close_cb_called == 2);
/* Cleanup */
@@ -282,6 +363,50 @@ TEST_IMPL(fs_event_watch_dir) {
return 0;
}
+TEST_IMPL(fs_event_watch_dir_recursive) {
+#if defined(__APPLE__) || defined(_WIN32)
+ uv_loop_t* loop;
+ int r;
+
+ /* Setup */
+ loop = uv_default_loop();
+ fs_event_unlink_files(NULL);
+ remove("watch_dir/file2");
+ remove("watch_dir/file1");
+ remove("watch_dir/subdir");
+ remove("watch_dir/");
+ create_dir("watch_dir");
+ create_dir("watch_dir/subdir");
+
+ r = uv_fs_event_init(loop, &fs_event);
+ ASSERT(r == 0);
+ r = uv_fs_event_start(&fs_event, fs_event_cb_dir_multi_file_in_subdir, "watch_dir", UV_FS_EVENT_RECURSIVE);
+ ASSERT(r == 0);
+ r = uv_timer_init(loop, &timer);
+ ASSERT(r == 0);
+ r = uv_timer_start(&timer, fs_event_create_files_in_subdir, 100, 0);
+ ASSERT(r == 0);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(fs_event_cb_called == fs_event_created + fs_event_removed);
+ ASSERT(close_cb_called == 2);
+
+ /* Cleanup */
+ fs_event_unlink_files_in_subdir(NULL);
+ remove("watch_dir/file2");
+ remove("watch_dir/file1");
+ remove("watch_dir/subdir");
+ remove("watch_dir/");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+#else
+ RETURN_SKIP("Recursive directory watching not supported on this platform.");
+#endif
+}
+
+
TEST_IMPL(fs_event_watch_file) {
uv_loop_t* loop = uv_default_loop();
int r;
@@ -290,9 +415,9 @@ TEST_IMPL(fs_event_watch_file) {
remove("watch_dir/file2");
remove("watch_dir/file1");
remove("watch_dir/");
- create_dir(loop, "watch_dir");
- create_file(loop, "watch_dir/file1");
- create_file(loop, "watch_dir/file2");
+ create_dir("watch_dir");
+ create_file("watch_dir/file1");
+ create_file("watch_dir/file2");
r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
@@ -348,7 +473,7 @@ TEST_IMPL(fs_event_watch_file_current_dir) {
/* Setup */
remove("watch_file");
- create_file(loop, "watch_file");
+ create_file("watch_file");
r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
@@ -389,8 +514,8 @@ TEST_IMPL(fs_event_no_callback_after_close) {
/* Setup */
remove("watch_dir/file1");
remove("watch_dir/");
- create_dir(loop, "watch_dir");
- create_file(loop, "watch_dir/file1");
+ create_dir("watch_dir");
+ create_file("watch_dir/file1");
r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
@@ -402,7 +527,7 @@ TEST_IMPL(fs_event_no_callback_after_close) {
uv_close((uv_handle_t*)&fs_event, close_cb);
- touch_file(loop, "watch_dir/file1");
+ touch_file("watch_dir/file1");
uv_run(loop, UV_RUN_DEFAULT);
ASSERT(fs_event_cb_called == 0);
@@ -423,8 +548,8 @@ TEST_IMPL(fs_event_no_callback_on_close) {
/* Setup */
remove("watch_dir/file1");
remove("watch_dir/");
- create_dir(loop, "watch_dir");
- create_file(loop, "watch_dir/file1");
+ create_dir("watch_dir");
+ create_file("watch_dir/file1");
r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
@@ -497,8 +622,8 @@ TEST_IMPL(fs_event_close_with_pending_event) {
loop = uv_default_loop();
- create_dir(loop, "watch_dir");
- create_file(loop, "watch_dir/file");
+ create_dir("watch_dir");
+ create_file("watch_dir/file");
r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
@@ -506,7 +631,7 @@ TEST_IMPL(fs_event_close_with_pending_event) {
ASSERT(r == 0);
/* Generate an fs event. */
- touch_file(loop, "watch_dir/file");
+ touch_file("watch_dir/file");
uv_close((uv_handle_t*)&fs_event, close_cb);
@@ -554,12 +679,12 @@ TEST_IMPL(fs_event_close_in_callback) {
loop = uv_default_loop();
- create_dir(loop, "watch_dir");
- create_file(loop, "watch_dir/file1");
- create_file(loop, "watch_dir/file2");
- create_file(loop, "watch_dir/file3");
- create_file(loop, "watch_dir/file4");
- create_file(loop, "watch_dir/file5");
+ create_dir("watch_dir");
+ create_file("watch_dir/file1");
+ create_file("watch_dir/file2");
+ create_file("watch_dir/file3");
+ create_file("watch_dir/file4");
+ create_file("watch_dir/file5");
r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
@@ -567,11 +692,11 @@ TEST_IMPL(fs_event_close_in_callback) {
ASSERT(r == 0);
/* Generate a couple of fs events. */
- touch_file(loop, "watch_dir/file1");
- touch_file(loop, "watch_dir/file2");
- touch_file(loop, "watch_dir/file3");
- touch_file(loop, "watch_dir/file4");
- touch_file(loop, "watch_dir/file5");
+ touch_file("watch_dir/file1");
+ touch_file("watch_dir/file2");
+ touch_file("watch_dir/file3");
+ touch_file("watch_dir/file4");
+ touch_file("watch_dir/file5");
uv_run(loop, UV_RUN_DEFAULT);
@@ -600,7 +725,7 @@ TEST_IMPL(fs_event_start_and_close) {
loop = uv_default_loop();
- create_dir(loop, "watch_dir");
+ create_dir("watch_dir");
r = uv_fs_event_init(loop, &fs_event1);
ASSERT(r == 0);
@@ -630,7 +755,7 @@ TEST_IMPL(fs_event_getpath) {
char buf[1024];
size_t len;
- create_dir(loop, "watch_dir");
+ create_dir("watch_dir");
r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
@@ -692,7 +817,7 @@ TEST_IMPL(fs_event_error_reporting) {
TEST_FILE_LIMIT(ARRAY_SIZE(loops) * 3);
remove("watch_dir/");
- create_dir(uv_default_loop(), "watch_dir");
+ create_dir("watch_dir");
/* Create a lot of loops, and start FSEventStream in each of them.
* Eventually, this should create enough streams to make FSEventStreamStart()