зеркало из https://github.com/mozilla/gecko-dev.git
Bug 909129 - fix Marionette imported scripts leak, add clearImportedScripts call, r=dburns
This commit is contained in:
Родитель
52b360943f
Коммит
d44875c406
|
@ -1186,6 +1186,14 @@ class Marionette(object):
|
|||
js = f.read()
|
||||
return self._send_message('importScript', 'ok', script=js)
|
||||
|
||||
def clear_imported_scripts(self):
|
||||
'''
|
||||
Clears all imported scripts in this context, ie: calling clear_imported_scripts in chrome
|
||||
context will clear only scripts you imported in chrome, and will leave the scripts
|
||||
you imported in content context.
|
||||
'''
|
||||
return self._send_message('clearImportedScripts', 'ok')
|
||||
|
||||
def add_cookie(self, cookie):
|
||||
"""
|
||||
Adds a cookie to your current session.
|
||||
|
|
|
@ -5,14 +5,125 @@
|
|||
|
||||
import os
|
||||
from marionette_test import MarionetteTestCase
|
||||
from errors import JavascriptException
|
||||
|
||||
class TestImportScript(MarionetteTestCase):
|
||||
def setUp(self):
|
||||
MarionetteTestCase.setUp(self)
|
||||
self.marionette.set_script_timeout(3000)
|
||||
|
||||
def clear_other_context(self):
|
||||
self.marionette.set_context("chrome")
|
||||
self.marionette.clear_imported_scripts()
|
||||
self.marionette.set_context("content")
|
||||
|
||||
def check_file_exists(self):
|
||||
self.marionette.set_context("chrome")
|
||||
exists = self.marionette.execute_async_script("""
|
||||
Components.utils.import("resource://gre/modules/FileUtils.jsm");
|
||||
let checkTimer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
|
||||
let f = function() {
|
||||
if (FileUtils == undefined) {
|
||||
checkTimer.initWithCallback(f, 100, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
|
||||
return;
|
||||
}
|
||||
let importedScripts = FileUtils.getFile('TmpD', ['marionetteContentScripts']);
|
||||
marionetteScriptFinished(importedScripts.exists());
|
||||
};
|
||||
checkTimer.initWithCallback(f, 100, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
|
||||
""")
|
||||
self.marionette.set_context("content")
|
||||
return exists
|
||||
|
||||
def get_file_size(self):
|
||||
self.marionette.set_context("chrome")
|
||||
size = self.marionette.execute_async_script("""
|
||||
Components.utils.import("resource://gre/modules/FileUtils.jsm");
|
||||
let checkTimer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
|
||||
let f = function() {
|
||||
if (FileUtils == undefined) {
|
||||
checkTimer.initWithCallback(f, 100, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
|
||||
return;
|
||||
}
|
||||
let importedScripts = FileUtils.getFile('TmpD', ['marionetteContentScripts']);
|
||||
marionetteScriptFinished(importedScripts.fileSize);
|
||||
};
|
||||
checkTimer.initWithCallback(f, 100, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
|
||||
""")
|
||||
self.marionette.set_context("content")
|
||||
return size
|
||||
|
||||
def test_import_script(self):
|
||||
js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))
|
||||
self.marionette.import_script(js)
|
||||
self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
|
||||
self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
|
||||
|
||||
def test_import_script_twice(self):
|
||||
js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))
|
||||
self.marionette.import_script(js)
|
||||
self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
|
||||
self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
|
||||
self.assertTrue(self.check_file_exists())
|
||||
file_size = self.get_file_size()
|
||||
self.assertNotEqual(file_size, None)
|
||||
self.marionette.import_script(js)
|
||||
file_size = self.get_file_size()
|
||||
self.assertEqual(file_size, self.get_file_size())
|
||||
self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
|
||||
self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
|
||||
|
||||
def test_import_two_scripts_twice(self):
|
||||
js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))
|
||||
self.marionette.import_script(js)
|
||||
self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
|
||||
self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
|
||||
self.assertTrue(self.check_file_exists())
|
||||
file_size = self.get_file_size()
|
||||
self.assertNotEqual(file_size, None)
|
||||
self.marionette.import_script(js)
|
||||
# same script should not append to file
|
||||
self.assertEqual(file_size, self.get_file_size())
|
||||
self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
|
||||
self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
|
||||
js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importanotherscript.js"))
|
||||
self.marionette.import_script(js)
|
||||
new_size = self.get_file_size()
|
||||
# new script should append to file
|
||||
self.assertNotEqual(file_size, new_size)
|
||||
file_size = new_size
|
||||
self.assertEqual("i'm yet another test function!",
|
||||
self.marionette.execute_script("return testAnotherFunc();"))
|
||||
self.assertEqual("i'm yet another test function!",
|
||||
self.marionette.execute_async_script("marionetteScriptFinished(testAnotherFunc());"))
|
||||
self.marionette.import_script(js)
|
||||
# same script should not append to file
|
||||
self.assertEqual(file_size, self.get_file_size())
|
||||
|
||||
def test_import_script_and_clear(self):
|
||||
js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))
|
||||
self.marionette.import_script(js)
|
||||
self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
|
||||
self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
|
||||
self.marionette.clear_imported_scripts()
|
||||
self.assertFalse(self.check_file_exists())
|
||||
self.assertRaises(JavascriptException, self.marionette.execute_script, "return testFunc();")
|
||||
self.assertRaises(JavascriptException, self.marionette.execute_async_script, "marionetteScriptFinished(testFunc());")
|
||||
|
||||
def test_import_script_and_clear_in_chrome(self):
|
||||
js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))
|
||||
self.marionette.import_script(js)
|
||||
self.assertTrue(self.check_file_exists())
|
||||
file_size = self.get_file_size()
|
||||
self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
|
||||
self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
|
||||
self.clear_other_context()
|
||||
# clearing other context's script file should not affect ours
|
||||
self.assertTrue(self.check_file_exists())
|
||||
self.assertEqual(file_size, self.get_file_size())
|
||||
self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
|
||||
self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
|
||||
|
||||
def test_importing_another_script_and_check_they_append(self):
|
||||
firstjs = os.path.abspath(
|
||||
os.path.join(__file__, os.path.pardir, "importscript.js"))
|
||||
|
@ -31,4 +142,41 @@ class TestImportScript(MarionetteTestCase):
|
|||
class TestImportScriptChrome(TestImportScript):
|
||||
def setUp(self):
|
||||
MarionetteTestCase.setUp(self)
|
||||
self.marionette.set_script_timeout(30000)
|
||||
self.marionette.set_context("chrome")
|
||||
|
||||
def clear_other_context(self):
|
||||
self.marionette.set_context("content")
|
||||
self.marionette.clear_imported_scripts()
|
||||
self.marionette.set_context("chrome")
|
||||
|
||||
def check_file_exists(self):
|
||||
return self.marionette.execute_async_script("""
|
||||
Components.utils.import("resource://gre/modules/FileUtils.jsm");
|
||||
let checkTimer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
|
||||
let f = function() {
|
||||
if (FileUtils == undefined) {
|
||||
checkTimer.initWithCallback(f, 100, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
|
||||
return;
|
||||
}
|
||||
let importedScripts = FileUtils.getFile('TmpD', ['marionetteChromeScripts']);
|
||||
marionetteScriptFinished(importedScripts.exists());
|
||||
};
|
||||
checkTimer.initWithCallback(f, 100, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
|
||||
""")
|
||||
|
||||
def get_file_size(self):
|
||||
return self.marionette.execute_async_script("""
|
||||
Components.utils.import("resource://gre/modules/FileUtils.jsm");
|
||||
let checkTimer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
|
||||
let f = function() {
|
||||
if (FileUtils == undefined) {
|
||||
checkTimer.initWithCallback(f, 100, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
|
||||
return;
|
||||
}
|
||||
let importedScripts = FileUtils.getFile('TmpD', ['marionetteChromeScripts']);
|
||||
marionetteScriptFinished(importedScripts.fileSize);
|
||||
};
|
||||
checkTimer.initWithCallback(f, 100, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
|
||||
""")
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ function registerSelf() {
|
|||
|
||||
if (register[0]) {
|
||||
listenerId = register[0].id;
|
||||
importedScripts = FileUtils.File(register[0].importedScripts);
|
||||
importedScripts = FileUtils.getFile('TmpD', ['marionetteContentScripts']);
|
||||
startListeners();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,7 +134,8 @@ function MarionetteServerConnection(aPrefix, aTransport, aServer)
|
|||
this.command_id = null;
|
||||
this.mainFrame = null; //topmost chrome frame
|
||||
this.curFrame = null; // chrome iframe that currently has focus
|
||||
this.importedScripts = FileUtils.getFile('TmpD', ['marionettescriptchrome']);
|
||||
this.importedScripts = FileUtils.getFile('TmpD', ['marionetteChromeScripts']);
|
||||
this.importedScriptHashes = {"chrome" : [], "content": []};
|
||||
this.currentFrameElement = null;
|
||||
this.testName = null;
|
||||
this.mozBrowserClose = null;
|
||||
|
@ -1991,7 +1992,8 @@ MarionetteServerConnection.prototype = {
|
|||
this.mainFrame.focus();
|
||||
}
|
||||
try {
|
||||
this.importedScripts.remove(false);
|
||||
FileUtils.getDir('TmpD', ['marionetteChromeScripts']).remove(true);
|
||||
FileUtils.getDir('TmpD', ['marionetteContentScripts']).remove(true);
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
|
@ -2054,6 +2056,23 @@ MarionetteServerConnection.prototype = {
|
|||
|
||||
importScript: function MDA_importScript(aRequest) {
|
||||
let command_id = this.command_id = this.getCommandId();
|
||||
let converter =
|
||||
Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].
|
||||
createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
|
||||
converter.charset = "UTF-8";
|
||||
let result = {};
|
||||
let data = converter.convertToByteArray(aRequest.script, result);
|
||||
let ch = Components.classes["@mozilla.org/security/hash;1"]
|
||||
.createInstance(Components.interfaces.nsICryptoHash);
|
||||
ch.init(ch.MD5);
|
||||
ch.update(data, data.length);
|
||||
let hash = ch.finish(true);
|
||||
if (this.importedScriptHashes[this.context].indexOf(hash) > -1) {
|
||||
//we have already imported this script
|
||||
this.sendOk(command_id);
|
||||
return;
|
||||
}
|
||||
this.importedScriptHashes[this.context].push(hash);
|
||||
if (this.context == "chrome") {
|
||||
let file;
|
||||
if (this.importedScripts.exists()) {
|
||||
|
@ -2079,6 +2098,21 @@ MarionetteServerConnection.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
clearImportedScripts: function MDA_clearImportedScripts(aRequest) {
|
||||
let command_id = this.command_id = this.getCommandId();
|
||||
let file;
|
||||
if (this.context == "chrome") {
|
||||
file = FileUtils.getFile('TmpD', ['marionetteChromeScripts']);
|
||||
}
|
||||
else {
|
||||
file = FileUtils.getFile('TmpD', ['marionetteContentScripts']);
|
||||
}
|
||||
if (file.exists()) {
|
||||
file.remove(true);
|
||||
}
|
||||
this.sendOk(command_id);
|
||||
},
|
||||
|
||||
/**
|
||||
* Takes a screenshot of a DOM node. If there is no node given a screenshot
|
||||
* of the window will be taken.
|
||||
|
@ -2196,7 +2230,6 @@ MarionetteServerConnection.prototype = {
|
|||
listenerWindow);
|
||||
}
|
||||
this.curBrowser.elementManager.seenItems[reg.id] = Cu.getWeakReference(listenerWindow);
|
||||
reg.importedScripts = this.importedScripts.path;
|
||||
if (nullPrevious && (this.curBrowser.curFrameId != null)) {
|
||||
if (!this.sendAsync("newSession",
|
||||
{ B2G: (appName == "B2G") },
|
||||
|
@ -2261,6 +2294,7 @@ MarionetteServerConnection.prototype.requestTypes = {
|
|||
"deleteSession": MarionetteServerConnection.prototype.deleteSession,
|
||||
"emulatorCmdResult": MarionetteServerConnection.prototype.emulatorCmdResult,
|
||||
"importScript": MarionetteServerConnection.prototype.importScript,
|
||||
"clearImportedScripts": MarionetteServerConnection.prototype.clearImportedScripts,
|
||||
"getAppCacheStatus": MarionetteServerConnection.prototype.getAppCacheStatus,
|
||||
"closeWindow": MarionetteServerConnection.prototype.closeWindow,
|
||||
"setTestName": MarionetteServerConnection.prototype.setTestName,
|
||||
|
|
Загрузка…
Ссылка в новой задаче