import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo

This commit is contained in:
Roy Tam 2018-01-19 03:59:58 +08:00
commit dcd9973243
150858 changed files with 23884658 additions and 0 deletions

View file

@ -0,0 +1,52 @@
/* 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/. */
#ifndef mozilla_nativefilewatcher_h__
#define mozilla_nativefilewatcher_h__
#include "nsINativeFileWatcher.h"
namespace mozilla {
class NativeFileWatcherService final : public nsINativeFileWatcherService
{
public:
NS_DECL_ISUPPORTS
NativeFileWatcherService()
{
};
nsresult Init()
{
return NS_OK;
};
NS_IMETHOD AddPath(const nsAString& aPathToWatch,
nsINativeFileWatcherCallback* aOnChange,
nsINativeFileWatcherErrorCallback* aOnError,
nsINativeFileWatcherSuccessCallback* aOnSuccess) override
{
return NS_ERROR_NOT_IMPLEMENTED;
};
NS_IMETHOD RemovePath(const nsAString& aPathToRemove,
nsINativeFileWatcherCallback* aOnChange,
nsINativeFileWatcherErrorCallback* aOnError,
nsINativeFileWatcherSuccessCallback* aOnSuccess) override
{
return NS_ERROR_NOT_IMPLEMENTED;
};
private:
~NativeFileWatcherService() { };
NativeFileWatcherService(const NativeFileWatcherService& other) = delete;
void operator=(const NativeFileWatcherService& other) = delete;
};
NS_IMPL_ISUPPORTS(NativeFileWatcherService, nsINativeFileWatcherService);
} // namespace mozilla
#endif // mozilla_nativefilewatcher_h__

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,50 @@
/* 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/. */
#ifndef mozilla_nativefilewatcher_h__
#define mozilla_nativefilewatcher_h__
#include "nsINativeFileWatcher.h"
#include "nsIObserver.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsThreadUtils.h"
// We need to include this header here for HANDLE definition.
#include <windows.h>
namespace mozilla {
class NativeFileWatcherService final : public nsINativeFileWatcherService,
public nsIObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSINATIVEFILEWATCHERSERVICE
NS_DECL_NSIOBSERVER
NativeFileWatcherService();
nsresult Init();
private:
// The |HANDLE| to the I/O Completion Port, owned by the main thread.
HANDLE mIOCompletionPort;
nsCOMPtr<nsIThread> mIOThread;
// The instance of the runnable dealing with the I/O.
nsCOMPtr<nsIRunnable> mWorkerIORunnable;
nsresult Uninit();
void WakeUpWorkerThread();
// Make the dtor private to make this object only deleted via its ::Release() method.
~NativeFileWatcherService();
NativeFileWatcherService(const NativeFileWatcherService& other) = delete;
void operator=(const NativeFileWatcherService& other) = delete;
};
} // namespace mozilla
#endif // mozilla_nativefilewatcher_h__

View file

@ -0,0 +1,23 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
XPCSHELL_TESTS_MANIFESTS += ['tests/xpcshell/xpcshell.ini']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
EXPORTS += ['NativeFileWatcherWin.h']
UNIFIED_SOURCES += [
'NativeFileWatcherWin.cpp',
]
else:
EXPORTS += ['NativeFileWatcherNotSupported.h']
XPIDL_MODULE = 'toolkit_filewatcher'
XPIDL_SOURCES += [
'nsINativeFileWatcher.idl',
]
FINAL_LIBRARY = 'xul'

View file

@ -0,0 +1,111 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=40: */
/* 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/. */
#include "nsISupports.idl"
/**
* The interface for the callback invoked when there is an error.
*/
[scriptable, function, uuid(5DAEDDC3-FC94-4880-8A4F-26D910B92662)]
interface nsINativeFileWatcherErrorCallback: nsISupports
{
/**
* @param xpcomError The XPCOM error code.
* @param osError The native OS error (errno under Unix, GetLastError under Windows).
*/
void complete(in nsresult xpcomError, in long osError);
};
/**
* The interface for the callback invoked when a change on a watched
* resource is detected.
*/
[scriptable, function, uuid(FE4D86C9-243F-4195-B544-AECE3DF4B86A)]
interface nsINativeFileWatcherCallback: nsISupports
{
/**
* @param resourcePath
* The path of the changed resource. If there were too many changes,
* the string "*" is passed.
* @param flags Reserved for future uses, not currently used.
*/
void changed(in AString resourcePath, in int32_t flags);
};
/**
* The interface for the callback invoked when a file watcher operation
* successfully completes.
*/
[scriptable, function, uuid(C3D7F542-681B-4ABD-9D65-9D799B29A42B)]
interface nsINativeFileWatcherSuccessCallback: nsISupports
{
/**
* @param resourcePath
* The path of the resource for which the operation completes.
*/
void complete(in AString resourcePath);
};
/**
* A service providing native implementations of path changes notification.
*/
[scriptable, builtinclass, uuid(B3A4E8D8-7DC8-47DB-A8B4-83736D7AC1AA)]
interface nsINativeFileWatcherService: nsISupports
{
/**
* Watches the passed path for changes. If it's a directory, every file
* it contains is watched. Recursively watches subdirectories. If the
* resource is already being watched, does nothing. If the passed path
* is a file, the behaviour is not specified.
*
* @param pathToWatch The path to watch for changes.
* @param onChange
* The callback invoked whenever a change on a watched
* resource is detected.
* @param onError
* The optional callback invoked whenever an error occurs.
* @param onSuccess
* The optional callback invoked when the file watcher starts
* watching the resource for changes.
*/
void addPath(in AString pathToWatch,
in nsINativeFileWatcherCallback onChange,
[optional] in nsINativeFileWatcherErrorCallback onError,
[optional] in nsINativeFileWatcherSuccessCallback onSuccess);
/**
* Removes the provided path from the watched resources. If the path
* was not being watched or the callbacks were not registered, silently
* ignores the request.
* Please note that the file watcher only considers the onChange callbacks
* when deciding to close a watch on a resource. If there are no more onChange
* callbacks associated to the watch, it gets closed (even though it still has
* some error callbacks associated).
*
* @param pathToUnwatch The path to un-watch.
* @param onChange
* The registered callback invoked whenever a change on a watched
* resource is detected.
* @param onError
* The optionally registered callback invoked whenever an error
* occurs.
* @param onSuccess
* The optional callback invoked when the file watcher stops
* watching the resource for changes.
*/
void removePath(in AString pathToUnwatch,
in nsINativeFileWatcherCallback onChange,
[optional] in nsINativeFileWatcherErrorCallback onError,
[optional] in nsINativeFileWatcherSuccessCallback onSuccess);
};
%{ C++
#define NATIVE_FILEWATCHER_SERVICE_CID {0x6F488507, 0x469D, 0x4350, {0xA6, 0x8D, 0x99, 0xC8, 0x7, 0xBE, 0xA, 0x78}}
#define NATIVE_FILEWATCHER_SERVICE_CONTRACTID "@mozilla.org/toolkit/filewatcher/native-file-watcher;1"
%}

View file

@ -0,0 +1,7 @@
"use strict";
module.exports = {
"extends": [
"../../../../../testing/xpcshell/xpcshell.eslintrc.js"
]
};

View file

@ -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)
);
}

View file

@ -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.");
}
});

View file

@ -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);
});

View file

@ -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)");
}
);
});

View file

@ -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]);
});

View file

@ -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);
});

View file

@ -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);
});

View file

@ -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);
});

View file

@ -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);
});

View file

@ -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);
});

View file

@ -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);
});

View file

@ -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;
});

View file

@ -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);
});

View file

@ -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);
});

View file

@ -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]