diff options
Diffstat (limited to 'toolkit/components/filewatcher/tests')
16 files changed, 831 insertions, 0 deletions
diff --git a/toolkit/components/filewatcher/tests/xpcshell/.eslintrc.js b/toolkit/components/filewatcher/tests/xpcshell/.eslintrc.js new file mode 100644 index 000000000..d35787cd2 --- /dev/null +++ b/toolkit/components/filewatcher/tests/xpcshell/.eslintrc.js @@ -0,0 +1,7 @@ +"use strict"; + +module.exports = { + "extends": [ + "../../../../../testing/xpcshell/xpcshell.eslintrc.js" + ] +}; diff --git a/toolkit/components/filewatcher/tests/xpcshell/head.js b/toolkit/components/filewatcher/tests/xpcshell/head.js new file mode 100644 index 000000000..73f8ac4f5 --- /dev/null +++ b/toolkit/components/filewatcher/tests/xpcshell/head.js @@ -0,0 +1,29 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +var {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components; + +Cu.import("resource://gre/modules/osfile.jsm", this); +Cu.import("resource://gre/modules/Promise.jsm", this); + +function makeWatcher() { + let watcher = + Cc['@mozilla.org/toolkit/filewatcher/native-file-watcher;1'] + .getService(Ci.nsINativeFileWatcherService); + return watcher; +} + +function promiseAddPath(watcher, resource, onChange=null, onError=null) { + return new Promise(resolve => + watcher.addPath(resource, onChange, onError, resolve) + ); +} + +function promiseRemovePath(watcher, resource, onChange=null, onError=null) { + return new Promise(resolve => + watcher.removePath(resource, onChange, onError, resolve) + ); +} diff --git a/toolkit/components/filewatcher/tests/xpcshell/test_arguments.js b/toolkit/components/filewatcher/tests/xpcshell/test_arguments.js new file mode 100644 index 000000000..7e62b1cb6 --- /dev/null +++ b/toolkit/components/filewatcher/tests/xpcshell/test_arguments.js @@ -0,0 +1,79 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +function run_test() { + // Set up profile. We will use profile path create some test files. + do_get_profile(); + + // Start executing the tests. + run_next_test(); +} + +/** + * Test for addPath usage with null arguments. + */ +add_task(function* test_null_args_addPath() { + + let watcher = makeWatcher(); + let testPath = 'someInvalidPath'; + + // Define a dummy callback function. In this test no callback is + // expected to be called. + let dummyFunc = function(changed) { + do_throw("Not expected in this test."); + }; + + // Check for error when passing a null first argument + try { + watcher.addPath(testPath, null, dummyFunc); + } catch (ex) { + if (ex.result != Cr.NS_ERROR_NULL_POINTER) + throw ex; + do_print("Initialisation thrown NS_ERROR_NULL_POINTER as expected."); + } + + // Check for error when passing both null arguments + try { + watcher.addPath(testPath, null, null); + } catch (ex) { + if (ex.result != Cr.NS_ERROR_NULL_POINTER) + throw ex; + do_print("Initialisation thrown NS_ERROR_NULL_POINTER as expected."); + } +}); + +/** + * Test for removePath usage with null arguments. + */ +add_task(function* test_null_args_removePath() { + + let watcher = makeWatcher(); + let testPath = 'someInvalidPath'; + + // Define a dummy callback function. In this test no callback is + // expected to be called. + let dummyFunc = function(changed) { + do_throw("Not expected in this test."); + }; + + // Check for error when passing a null first argument + try { + watcher.removePath(testPath, null, dummyFunc); + } catch (ex) { + if (ex.result != Cr.NS_ERROR_NULL_POINTER) + throw ex; + do_print("Initialisation thrown NS_ERROR_NULL_POINTER as expected."); + } + + // Check for error when passing both null arguments + try { + watcher.removePath(testPath, null, null); + } catch (ex) { + if (ex.result != Cr.NS_ERROR_NULL_POINTER) + throw ex; + do_print("Initialisation thrown NS_ERROR_NULL_POINTER as expected."); + } +}); diff --git a/toolkit/components/filewatcher/tests/xpcshell/test_no_error_callback.js b/toolkit/components/filewatcher/tests/xpcshell/test_no_error_callback.js new file mode 100644 index 000000000..e5ceb33e5 --- /dev/null +++ b/toolkit/components/filewatcher/tests/xpcshell/test_no_error_callback.js @@ -0,0 +1,69 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +function run_test() { + // Set up profile. We will use profile path create some test files. + do_get_profile(); + + // Start executing the tests. + run_next_test(); +} + +/** + * Test the component behaves correctly when no error callback is + * provided and an error occurs. + */ +add_task(function* test_error_with_no_error_callback() { + + let watcher = makeWatcher(); + let testPath = 'someInvalidPath'; + + // Define a dummy callback function. In this test no callback is + // expected to be called. + let dummyFunc = function(changed) { + do_throw("Not expected in this test."); + }; + + // We don't pass an error callback and try to watch an invalid + // path. + watcher.addPath(testPath, dummyFunc); +}); + +/** + * Test the component behaves correctly when no error callback is + * provided (no error should occur). + */ +add_task(function* test_watch_single_path_file_creation_no_error_cb() { + + // Create and watch a sub-directory of the profile directory so we don't + // catch notifications we're not interested in (i.e. "startupCache"). + let watchedDir = OS.Path.join(OS.Constants.Path.profileDir, "filewatcher_playground"); + yield OS.File.makeDir(watchedDir); + + let tempFileName = "test_filecreation.tmp"; + + // Instantiate and initialize the native watcher. + let watcher = makeWatcher(); + let deferred = Promise.defer(); + + // Watch the profile directory but do not pass an error callback. + yield promiseAddPath(watcher, watchedDir, deferred.resolve); + + // Create a file within the watched directory. + let tmpFilePath = OS.Path.join(watchedDir, tempFileName); + yield OS.File.writeAtomic(tmpFilePath, "some data"); + + // Wait until the watcher informs us that the file was created. + let changed = yield deferred.promise; + do_check_eq(changed, tmpFilePath); + + // Remove the watch and free the associated memory (we need to + // reuse 'deferred.resolve' to unregister). + watcher.removePath(watchedDir, deferred.resolve); + + // Remove the test directory and all of its content. + yield OS.File.removeDir(watchedDir); +}); diff --git a/toolkit/components/filewatcher/tests/xpcshell/test_remove_non_watched.js b/toolkit/components/filewatcher/tests/xpcshell/test_remove_non_watched.js new file mode 100644 index 000000000..1375584a3 --- /dev/null +++ b/toolkit/components/filewatcher/tests/xpcshell/test_remove_non_watched.js @@ -0,0 +1,39 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +function run_test() { + // Set up profile. We will use profile path create some test files. + do_get_profile(); + + // Start executing the tests. + run_next_test(); +} + +/** + * Test removing non watched path + */ +add_task(function* test_remove_not_watched() { + let nonExistingDir = + OS.Path.join(OS.Constants.Path.profileDir, "absolutelyNotExisting"); + + // Instantiate the native watcher. + let watcher = makeWatcher(); + + // Try to un-watch a path which wasn't being watched. + watcher.removePath( + nonExistingDir, + function(changed) { + do_throw("No change is expected in this test."); + }, + function(xpcomError, osError) { + // When removing a resource which wasn't being watched, it should silently + // ignore the request. + do_throw("Unexpected exception: " + + xpcomError + " (XPCOM) " + + osError + " (OS Error)"); + } + ); +}); diff --git a/toolkit/components/filewatcher/tests/xpcshell/test_shared_callback.js b/toolkit/components/filewatcher/tests/xpcshell/test_shared_callback.js new file mode 100644 index 000000000..482ba6b8b --- /dev/null +++ b/toolkit/components/filewatcher/tests/xpcshell/test_shared_callback.js @@ -0,0 +1,62 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +function run_test() { + // Set up profile. We will use profile path create some test files. + do_get_profile(); + + // Start executing the tests. + run_next_test(); +} + +/** + * Test the watcher correctly handles two watches sharing the same + * change callback. + */ +add_task(function* test_watch_with_shared_callback() { + + // Create and watch two sub-directories of the profile directory so we don't + // catch notifications we're not interested in (i.e. "startupCache"). + let watchedDirs = + [ + OS.Path.join(OS.Constants.Path.profileDir, "filewatcher_playground"), + OS.Path.join(OS.Constants.Path.profileDir, "filewatcher_playground2") + ]; + + yield OS.File.makeDir(watchedDirs[0]); + yield OS.File.makeDir(watchedDirs[1]); + + let tempFileName = "test_filecreation.tmp"; + + // Instantiate and initialize the native watcher. + let watcher = makeWatcher(); + let deferred = Promise.defer(); + + // Watch both directories using the same callbacks. + yield promiseAddPath(watcher, watchedDirs[0], deferred.resolve, deferred.reject); + yield promiseAddPath(watcher, watchedDirs[1], deferred.resolve, deferred.reject); + + // Remove the watch for the first directory, but keep watching + // for changes in the second: we need to make sure the callback + // survives the removal of the first watch. + watcher.removePath(watchedDirs[0], deferred.resolve, deferred.reject); + + // Create a file within the watched directory. + let tmpFilePath = OS.Path.join(watchedDirs[1], tempFileName); + yield OS.File.writeAtomic(tmpFilePath, "some data"); + + // Wait until the watcher informs us that the file was created. + let changed = yield deferred.promise; + do_check_eq(changed, tmpFilePath); + + // Remove the watch and free the associated memory (we need to + // reuse 'deferred.resolve' and 'deferred.reject' to unregister). + watcher.removePath(watchedDirs[1], deferred.resolve, deferred.reject); + + // Remove the test directories and all of their content. + yield OS.File.removeDir(watchedDirs[0]); + yield OS.File.removeDir(watchedDirs[1]); +}); diff --git a/toolkit/components/filewatcher/tests/xpcshell/test_watch_directory_creation_single.js b/toolkit/components/filewatcher/tests/xpcshell/test_watch_directory_creation_single.js new file mode 100644 index 000000000..a434ec751 --- /dev/null +++ b/toolkit/components/filewatcher/tests/xpcshell/test_watch_directory_creation_single.js @@ -0,0 +1,49 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +function run_test() { + // Set up profile. We will use profile path create some test files + do_get_profile(); + + // Start executing the tests + run_next_test(); +} + +/** + * Tests that the watcher correctly notifies of a directory creation when watching + * a single path. + */ +add_task(function* test_watch_single_path_directory_creation() { + + // Create and watch a sub-directory of the profile directory so we don't + // catch notifications we're not interested in (i.e. "startupCache"). + let watchedDir = OS.Path.join(OS.Constants.Path.profileDir, "filewatcher_playground"); + yield OS.File.makeDir(watchedDir); + + let tmpDirPath = OS.Path.join(watchedDir, "testdir"); + + // Instantiate and initialize the native watcher. + let watcher = makeWatcher(); + let deferred = Promise.defer(); + + // Add the profile directory to the watch list and wait for the file watcher + // to start watching. + yield promiseAddPath(watcher, watchedDir, deferred.resolve, deferred.reject); + + // Once ready, create a directory within the watched directory. + yield OS.File.makeDir(tmpDirPath); + + // Wait until the watcher informs us that the file has changed. + let changed = yield deferred.promise; + do_check_eq(changed, tmpDirPath); + + // Remove the watch and free the associated memory (we need to + // reuse 'deferred.resolve' and 'deferred.reject' to unregister). + yield promiseRemovePath(watcher, watchedDir, deferred.resolve, deferred.reject); + + // Clean up the test directory. + yield OS.File.removeDir(watchedDir); +}); diff --git a/toolkit/components/filewatcher/tests/xpcshell/test_watch_directory_deletion_single.js b/toolkit/components/filewatcher/tests/xpcshell/test_watch_directory_deletion_single.js new file mode 100644 index 000000000..2c74a9361 --- /dev/null +++ b/toolkit/components/filewatcher/tests/xpcshell/test_watch_directory_deletion_single.js @@ -0,0 +1,46 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +function run_test() { + // Set up profile. We will use profile path create some test files. + do_get_profile(); + + // Start executing the tests. + run_next_test(); +} + +/** + * Tests that the watcher correctly notifies of a directory deletion when watching + * a single path. + */ +add_task(function* test_watch_single_path_directory_deletion() { + + let watchedDir = OS.Constants.Path.profileDir; + let tempDirName = "test"; + let tmpDirPath = OS.Path.join(watchedDir, tempDirName); + + // Instantiate and initialize the native watcher. + let watcher = makeWatcher(); + let deferred = Promise.defer(); + + // Create a directory within the watched directory. + yield OS.File.makeDir(tmpDirPath); + + // Add the profile directory to the watch list and wait for the file watcher + // to start watching it. + yield promiseAddPath(watcher, watchedDir, deferred.resolve, deferred.reject); + + // Remove the directory. + OS.File.removeDir(tmpDirPath); + + // Wait until the watcher informs us that the file has changed. + let changed = yield deferred.promise; + do_check_eq(changed, tmpDirPath); + + // Remove the watch and free the associated memory (we need to + // reuse 'deferred.resolve' and 'deferred.reject' to unregister). + yield promiseRemovePath(watcher, watchedDir, deferred.resolve, deferred.reject); +}); diff --git a/toolkit/components/filewatcher/tests/xpcshell/test_watch_file_creation_single.js b/toolkit/components/filewatcher/tests/xpcshell/test_watch_file_creation_single.js new file mode 100644 index 000000000..9f87793f4 --- /dev/null +++ b/toolkit/components/filewatcher/tests/xpcshell/test_watch_file_creation_single.js @@ -0,0 +1,51 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +function run_test() { + // Set up profile. We will use profile path create some test files. + do_get_profile(); + + // Start executing the tests. + run_next_test(); +} + +/** + * Test the watcher correctly notifies of a file creation when watching + * a single path. + */ +add_task(function* test_watch_single_path_file_creation() { + + // Create and watch a sub-directory of the profile directory so we don't + // catch notifications we're not interested in (i.e. "startupCache"). + let watchedDir = OS.Path.join(OS.Constants.Path.profileDir, "filewatcher_playground"); + yield OS.File.makeDir(watchedDir); + + let tempFileName = "test_filecreation.tmp"; + + // Instantiate and initialize the native watcher. + let watcher = makeWatcher(); + let deferred = Promise.defer(); + + let tmpFilePath = OS.Path.join(watchedDir, tempFileName); + + // Add the profile directory to the watch list and wait for the file watcher + // to start watching. + yield promiseAddPath(watcher, watchedDir, deferred.resolve, deferred.reject); + + // create the file within the watched directory. + yield OS.File.writeAtomic(tmpFilePath, "some data"); + + // Wait until the watcher informs us that the file was created. + let changed = yield deferred.promise; + do_check_eq(changed, tmpFilePath); + + // Remove the watch and free the associated memory (we need to + // reuse 'deferred.resolve' and 'deferred.reject' to unregister). + yield promiseRemovePath(watcher, watchedDir, deferred.resolve, deferred.reject); + + // Remove the test directory and all of its content. + yield OS.File.removeDir(watchedDir); +}); diff --git a/toolkit/components/filewatcher/tests/xpcshell/test_watch_file_deletion_single.js b/toolkit/components/filewatcher/tests/xpcshell/test_watch_file_deletion_single.js new file mode 100644 index 000000000..97d2d61bc --- /dev/null +++ b/toolkit/components/filewatcher/tests/xpcshell/test_watch_file_deletion_single.js @@ -0,0 +1,54 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +function run_test() { + // Set up profile. We will use profile path create some test files. + do_get_profile(); + + // Start executing the tests. + run_next_test(); +} +/** + * Test the watcher correctly notifies of a file deletion when watching + * a single path. + */ +add_task(function* test_watch_single_path_file_deletion() { + + // Create and watch a sub-directory of the profile directory so we don't + // catch notifications we're not interested in (i.e. "startupCache"). + let watchedDir = OS.Path.join(OS.Constants.Path.profileDir, "filewatcher_playground"); + yield OS.File.makeDir(watchedDir); + + let tempFileName = "test_filedeletion.tmp"; + + // Instantiate and initialize the native watcher. + let watcher = makeWatcher(); + let deferred = Promise.defer(); + + // Create a file within the directory to be watched. We do this + // before watching the directory so we do not get the creation notification. + let tmpFilePath = OS.Path.join(watchedDir, tempFileName); + yield OS.File.writeAtomic(tmpFilePath, "some data"); + + // Add the profile directory to the watch list and wait for the file watcher + // to start watching it. + yield promiseAddPath(watcher, watchedDir, deferred.resolve, deferred.reject); + + // Remove the file we created (should trigger a notification). + do_print('Removing ' + tmpFilePath); + yield OS.File.remove(tmpFilePath); + + // Wait until the watcher informs us that the file was deleted. + let changed = yield deferred.promise; + do_check_eq(changed, tmpFilePath); + + // Remove the watch and free the associated memory (we need to + // reuse 'deferred.resolve' and 'deferred.reject' to unregister). + yield promiseRemovePath(watcher, watchedDir, deferred.resolve, deferred.reject); + + // Remove the test directory and all of its content. + yield OS.File.removeDir(watchedDir); +}); diff --git a/toolkit/components/filewatcher/tests/xpcshell/test_watch_file_modification_single.js b/toolkit/components/filewatcher/tests/xpcshell/test_watch_file_modification_single.js new file mode 100644 index 000000000..ba25fdff6 --- /dev/null +++ b/toolkit/components/filewatcher/tests/xpcshell/test_watch_file_modification_single.js @@ -0,0 +1,54 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +function run_test() { + // Set up profile. We will use profile path create some test files + do_get_profile(); + + // Start executing the tests + run_next_test(); +} + +/** + * Tests that the watcher correctly notifies of a file modification when watching + * a single path. + */ +add_task(function* test_watch_single_path_file_modification() { + + // Create and watch a sub-directory of the profile directory so we don't + // catch notifications we're not interested in (i.e. "startupCache"). + let watchedDir = OS.Path.join(OS.Constants.Path.profileDir, "filewatcher_playground"); + yield OS.File.makeDir(watchedDir); + + let tempFileName = "test_filemodification.tmp"; + + // Instantiate and initialize the native watcher. + let watcher = makeWatcher(); + let deferred = Promise.defer(); + + // Create a file within the directory to be watched. We do this + // before watching the directory so we do not get the creation notification. + let tmpFilePath = OS.Path.join(watchedDir, tempFileName); + yield OS.File.writeAtomic(tmpFilePath, "some data"); + + // Add the profile directory to the watch list and wait for the file watcher + // to start watching it. + yield promiseAddPath(watcher, watchedDir, deferred.resolve, deferred.reject); + + // Once ready, modify the file to trigger the notification. + yield OS.File.writeAtomic(tmpFilePath, "some new data"); + + // Wait until the watcher informs us that the file has changed. + let changed = yield deferred.promise; + do_check_eq(changed, tmpFilePath); + + // Remove the watch and free the associated memory (we need to + // reuse 'deferred.resolve' and 'deferred.reject' to unregister). + yield promiseRemovePath(watcher, watchedDir, deferred.resolve, deferred.reject); + + // Remove the test directory and all of its content. + yield OS.File.removeDir(watchedDir); +}); diff --git a/toolkit/components/filewatcher/tests/xpcshell/test_watch_many_changes.js b/toolkit/components/filewatcher/tests/xpcshell/test_watch_many_changes.js new file mode 100644 index 000000000..c236c6e1d --- /dev/null +++ b/toolkit/components/filewatcher/tests/xpcshell/test_watch_many_changes.js @@ -0,0 +1,73 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +function run_test() { + // Set up profile. We will use profile path create some test files + do_get_profile(); + + // Start executing the tests + run_next_test(); +} + +/** + * Test that we correctly handle watching directories when hundreds of files + * change simultaneously. + */ +add_task(function* test_fill_notification_buffer() { + + // Create and watch a sub-directory of the profile directory so we don't + // catch notifications we're not interested in (i.e. "startupCache"). + let watchedDir = OS.Path.join(OS.Constants.Path.profileDir, "filewatcher_playground"); + yield OS.File.makeDir(watchedDir); + + // The number of files to create. + let numberOfFiles = 100; + let fileNameBase = "testFile"; + + // This will be used to keep track of the number of changes within the watched + // directory. + let detectedChanges = 0; + + // We expect at least the following notifications for each file: + // - File creation + // - File deletion + let expectedChanges = numberOfFiles * 2; + + // Instantiate the native watcher. + let watcher = makeWatcher(); + let deferred = Promise.defer(); + + // Initialise the change callback. + let changeCallback = function(changed) { + do_print(changed + " has changed."); + + detectedChanges += 1; + + // Resolve the promise if we get all the expected changes. + if (detectedChanges >= expectedChanges) { + deferred.resolve(); + } + }; + + // Add the profile directory to the watch list and wait for the file watcher + // to start watching it. + yield promiseAddPath(watcher, watchedDir, changeCallback, deferred.reject); + + // Create and then remove the files within the watched directory. + for (let i = 0; i < numberOfFiles; i++) { + let tmpFilePath = OS.Path.join(watchedDir, fileNameBase + i); + yield OS.File.writeAtomic(tmpFilePath, "test content"); + yield OS.File.remove(tmpFilePath); + } + + // Wait until the watcher informs us that all the files were + // created, modified and removed. + yield deferred.promise; + + // Remove the watch and free the associated memory (we need to + // reuse 'changeCallback' and 'errorCallback' to unregister). + yield promiseRemovePath(watcher, watchedDir, changeCallback, deferred.reject); +}); diff --git a/toolkit/components/filewatcher/tests/xpcshell/test_watch_multi_paths.js b/toolkit/components/filewatcher/tests/xpcshell/test_watch_multi_paths.js new file mode 100644 index 000000000..c55b262f1 --- /dev/null +++ b/toolkit/components/filewatcher/tests/xpcshell/test_watch_multi_paths.js @@ -0,0 +1,114 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +function run_test() { + // Set up profile. We will use profile path create some test files + do_get_profile(); + + // Start executing the tests + run_next_test(); +} + +/** + * Tests the watcher by watching several resources. + * This test creates the specified number of directory inside the profile + * directory, adds each one of them to the watched list the creates + * a file in them in order to trigger the notification. + * The test keeps track of the number of times the changes callback is + * called in order to verify the success of the test. + */ +add_task(function* test_watch_multi_paths() { + + // The number of resources to watch. We expect changes for + // creating a file within each directory. + let resourcesToWatch = 5; + let watchedDir = OS.Constants.Path.profileDir; + + // The directories to be watched will be created with. + let tempDirNameBase = "FileWatcher_Test_"; + let tempFileName = "test.tmp"; + + // Instantiate the native watcher. + let watcher = makeWatcher(); + + // This will be used to keep track of the number of changes within the watched + // resources. + let detectedChanges = 0; + let watchedResources = 0; + let unwatchedResources = 0; + + let deferredChanges = Promise.defer(); + let deferredSuccesses = Promise.defer(); + let deferredShutdown = Promise.defer(); + + // Define the change callback function. + let changeCallback = function(changed) { + do_print(changed + " has changed."); + + detectedChanges += 1; + + // Resolve the promise if we get all the expected changes. + if (detectedChanges === resourcesToWatch) { + deferredChanges.resolve(); + } + }; + + // Define the watch success callback function. + let watchSuccessCallback = function(resourcePath) { + do_print(resourcePath + " is being watched."); + + watchedResources += 1; + + // Resolve the promise when all the resources are being + // watched. + if (watchedResources === resourcesToWatch) { + deferredSuccesses.resolve(); + } + }; + + // Define the watch success callback function. + let unwatchSuccessCallback = function(resourcePath) { + do_print(resourcePath + " is being un-watched."); + + unwatchedResources += 1; + + // Resolve the promise when all the resources are being + // watched. + if (unwatchedResources === resourcesToWatch) { + deferredShutdown.resolve(); + } + }; + + // Create the directories and add them to the watched resources list. + for (let i = 0; i < resourcesToWatch; i++) { + let tmpSubDirPath = OS.Path.join(watchedDir, tempDirNameBase + i); + do_print("Creating the " + tmpSubDirPath + " directory."); + yield OS.File.makeDir(tmpSubDirPath); + watcher.addPath(tmpSubDirPath, changeCallback, deferredChanges.reject, watchSuccessCallback); + } + + // Wait until the watcher informs us that all the desired resources + // are being watched. + yield deferredSuccesses.promise; + + // Create a file within each watched directory. + for (let i = 0; i < resourcesToWatch; i++) { + let tmpFilePath = OS.Path.join(watchedDir, tempDirNameBase + i, tempFileName); + yield OS.File.writeAtomic(tmpFilePath, "test content"); + } + + // Wait until the watcher informs us that all the files were created. + yield deferredChanges.promise; + + // Remove the directories we have created. + for (let i = 0; i < resourcesToWatch; i++) { + let tmpSubDirPath = OS.Path.join(watchedDir, tempDirNameBase + i); + watcher.removePath(tmpSubDirPath, changeCallback, deferredChanges.reject, unwatchSuccessCallback); + } + + // Wait until the watcher un-watches the resources. + yield deferredShutdown.promise; +}); diff --git a/toolkit/components/filewatcher/tests/xpcshell/test_watch_recursively.js b/toolkit/components/filewatcher/tests/xpcshell/test_watch_recursively.js new file mode 100644 index 000000000..13a3de8d3 --- /dev/null +++ b/toolkit/components/filewatcher/tests/xpcshell/test_watch_recursively.js @@ -0,0 +1,55 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +function run_test() { + // Set up profile. We will use profile path create some test files. + do_get_profile(); + + // Start executing the tests. + run_next_test(); +} + +/** + * Test the watcher correctly notifies of a file creation in a subdirectory + * of the watched sub-directory (recursion). + */ +add_task(function* test_watch_recursively() { + + // Create and watch a sub-directory of the profile directory so we don't + // catch notifications we're not interested in (i.e. "startupCache"). + let watchedDir = OS.Path.join(OS.Constants.Path.profileDir, "filewatcher_playground"); + yield OS.File.makeDir(watchedDir); + + // We need at least 2 levels of directories to test recursion. + let subdirectory = OS.Path.join(watchedDir, "level1"); + yield OS.File.makeDir(subdirectory); + + let tempFileName = "test_filecreation.tmp"; + + // Instantiate and initialize the native watcher. + let watcher = makeWatcher(); + let deferred = Promise.defer(); + + let tmpFilePath = OS.Path.join(subdirectory, tempFileName); + + // Add the profile directory to the watch list and wait for the file watcher + // to start watching it. + yield promiseAddPath(watcher, watchedDir, deferred.resolve, deferred.reject); + + // Create a file within the subdirectory of the watched directory. + yield OS.File.writeAtomic(tmpFilePath, "some data"); + + // Wait until the watcher informs us that the file was created. + let changed = yield deferred.promise; + do_check_eq(changed, tmpFilePath); + + // Remove the watch and free the associated memory (we need to + // reuse 'deferred.resolve' and 'deferred.reject' to unregister). + yield promiseRemovePath(watcher, watchedDir, deferred.resolve, deferred.reject); + + // Remove the test directory and all of its content. + yield OS.File.removeDir(watchedDir); +}); diff --git a/toolkit/components/filewatcher/tests/xpcshell/test_watch_resource.js b/toolkit/components/filewatcher/tests/xpcshell/test_watch_resource.js new file mode 100644 index 000000000..fffdff24b --- /dev/null +++ b/toolkit/components/filewatcher/tests/xpcshell/test_watch_resource.js @@ -0,0 +1,32 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +function run_test() { + // Set up profile. We will use profile path create some test files + do_get_profile(); + + // Start executing the tests + run_next_test(); +} + +/** + * Test watching non-existing path + */ +add_task(function* test_watching_non_existing() { + let notExistingDir = + OS.Path.join(OS.Constants.Path.profileDir, "absolutelyNotExisting"); + + // Instantiate the native watcher. + let watcher = makeWatcher(); + let deferred = Promise.defer(); + + // Try watch a path which doesn't exist. + watcher.addPath(notExistingDir, deferred.reject, deferred.resolve); + + // Wait until the watcher informs us that there was an error. + let error = yield deferred.promise; + do_check_eq(error, Components.results.NS_ERROR_FILE_NOT_FOUND); +}); diff --git a/toolkit/components/filewatcher/tests/xpcshell/xpcshell.ini b/toolkit/components/filewatcher/tests/xpcshell/xpcshell.ini new file mode 100644 index 000000000..d6cc968eb --- /dev/null +++ b/toolkit/components/filewatcher/tests/xpcshell/xpcshell.ini @@ -0,0 +1,18 @@ +[DEFAULT] +head = head.js +tail = +skip-if = os != "win" + +[test_arguments.js] +[test_no_error_callback.js] +[test_remove_non_watched.js] +[test_shared_callback.js] +[test_watch_file_creation_single.js] +[test_watch_file_deletion_single.js] +[test_watch_file_modification_single.js] +[test_watch_directory_creation_single.js] +[test_watch_directory_deletion_single.js] +[test_watch_many_changes.js] +[test_watch_multi_paths.js] +[test_watch_recursively.js] +[test_watch_resource.js] |