Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Commit

Permalink
Added test case for recursive file watcher
Browse files Browse the repository at this point in the history
  • Loading branch information
ghostoy committed Sep 19, 2014
1 parent 5e83804 commit 37c44fb
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 5 deletions.
2 changes: 1 addition & 1 deletion include/uv-win.h
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
HANDLE dir_handle; \
int req_pending; \
uv_fs_event_cb cb; \
unsigned int win_flags; \
unsigned int fs_flags; \
WCHAR* filew; \
WCHAR* short_filew; \
WCHAR* dirw; \
Expand Down
7 changes: 3 additions & 4 deletions src/win/fs-event.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ static void uv_fs_event_queue_readdirchanges(uv_loop_t* loop,
if (!ReadDirectoryChangesW(handle->dir_handle,
handle->buffer,
uv_directory_watcher_buffer_size,
(handle->win_flags & UV_FS_EVENT_RECURSIVE) ? TRUE: FALSE,
(handle->fs_flags & UV_FS_EVENT_RECURSIVE) ? TRUE: FALSE,
FILE_NOTIFY_CHANGE_FILE_NAME |
FILE_NOTIFY_CHANGE_DIR_NAME |
FILE_NOTIFY_CHANGE_ATTRIBUTES |
Expand Down Expand Up @@ -152,8 +152,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
return UV_EINVAL;

handle->cb = cb;
// Added win_flags for recursive watcher
handle->win_flags = flags;
handle->fs_flags = flags;
handle->path = strdup(path);
if (!handle->path) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
Expand Down Expand Up @@ -254,7 +253,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
if (!ReadDirectoryChangesW(handle->dir_handle,
handle->buffer,
uv_directory_watcher_buffer_size,
(handle->win_flags & UV_FS_EVENT_RECURSIVE) ? TRUE: FALSE,
(handle->fs_flags & UV_FS_EVENT_RECURSIVE) ? TRUE: FALSE,
FILE_NOTIFY_CHANGE_FILE_NAME |
FILE_NOTIFY_CHANGE_DIR_NAME |
FILE_NOTIFY_CHANGE_ATTRIBUTES |
Expand Down
107 changes: 107 additions & 0 deletions test/test-fs-event.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

static uv_fs_event_t fs_event;
static const char file_prefix[] = "fsevent-";
static const char file_prefix_in_subdir[] = "subdir";
static uv_timer_t timer;
static int timer_cb_called;
static int close_cb_called;
Expand All @@ -51,6 +52,7 @@ static char fs_event_filename[1024];
static int timer_cb_touch_called;

static void fs_event_unlink_files(uv_timer_t* handle);
static void fs_event_unlink_files_in_subdir(uv_timer_t* handle);

static void create_dir(uv_loop_t* loop, const char* name) {
int r;
Expand Down Expand Up @@ -138,6 +140,25 @@ static void fs_event_cb_dir_multi_file(uv_fs_event_t* handle,
}
}

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_RENAME || events == UV_CHANGE);
ASSERT(filename == NULL ||
strncmp(filename, file_prefix_in_subdir, sizeof(file_prefix_in_subdir) - 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));
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),
Expand All @@ -147,6 +168,15 @@ static const char* fs_event_get_filename(int i) {
return fs_event_filename;
}

static const char* fs_event_get_filename_in_subdir(int i) {
snprintf(fs_event_filename,
sizeof(fs_event_filename),
"watch_dir/subdir/%s%d",
file_prefix,
i);
return fs_event_filename;
}

static void fs_event_create_files(uv_timer_t* handle) {
int i;

Expand All @@ -164,6 +194,42 @@ static void fs_event_create_files(uv_timer_t* handle) {
ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files, 50, 0));
}


static void fs_event_create_files_in_subdir(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;
}

/* Create all files */
for (i = 0; i < 16; i++, fs_event_created++)
create_file(handle->loop, fs_event_get_filename_in_subdir(i));

/* And unlink them */
ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files_in_subdir, 50, 0));
}

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 */

/* Unlink all files */
for (i = 0; i < 16; i++) {
r = remove(fs_event_get_filename_in_subdir(i));
if (handle != NULL)
ASSERT(r == 0);
}

/* And create them again */
if (handle != NULL)
ASSERT(0 == uv_timer_start(&timer, fs_event_create_files_in_subdir, 50, 0));
}

void fs_event_unlink_files(uv_timer_t* handle) {
int r;
int i;
Expand Down Expand Up @@ -282,6 +348,47 @@ TEST_IMPL(fs_event_watch_dir) {
return 0;
}

#if defined(__APPLE__) || defined(_WIN32)
TEST_IMPL(fs_event_watch_dir_recursive) {
uv_loop_t* loop = uv_default_loop();
int r;

/* Setup */
fs_event_unlink_files(NULL);
remove("watch_dir/file2");
remove("watch_dir/file1");
remove("watch_dir/subdir");
remove("watch_dir/");
create_dir(loop, "watch_dir");
create_dir(loop, "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 == 2 * fs_event_file_count);
ASSERT(fs_event_created == fs_event_file_count);
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;
}
#endif

TEST_IMPL(fs_event_watch_file) {
uv_loop_t* loop = uv_default_loop();
int r;
Expand Down
2 changes: 2 additions & 0 deletions test/test-list.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ TEST_DECLARE (fs_file_open_append)
TEST_DECLARE (fs_stat_missing_path)
TEST_DECLARE (fs_read_file_eof)
TEST_DECLARE (fs_event_watch_dir)
TEST_DECLARE (fs_event_watch_dir_recursive)
TEST_DECLARE (fs_event_watch_file)
TEST_DECLARE (fs_event_watch_file_twice)
TEST_DECLARE (fs_event_watch_file_current_dir)
Expand Down Expand Up @@ -595,6 +596,7 @@ TASK_LIST_START
TEST_ENTRY (fs_read_file_eof)
TEST_ENTRY (fs_file_open_append)
TEST_ENTRY (fs_event_watch_dir)
TEST_ENTRY (fs_event_watch_dir_recursive)
TEST_ENTRY (fs_event_watch_file)
TEST_ENTRY (fs_event_watch_file_twice)
TEST_ENTRY (fs_event_watch_file_current_dir)
Expand Down

0 comments on commit 37c44fb

Please sign in to comment.