Title: [188756] trunk
Revision
188756
Author
[email protected]
Date
2015-08-21 10:05:59 -0700 (Fri, 21 Aug 2015)

Log Message

Web Inspector: add a regression test for the fix introduced in r188679
https://bugs.webkit.org/show_bug.cgi?id=148223

Reviewed by Joseph Pecoraro.

Source/WebInspectorUI:

Turns out that we were possibly leaking a single DOMTree on reload.
Always clear the main frame's DOMTree as well as those of sub-frames.

* UserInterface/Base/Object.js: Add back single-fire listeners.
(WebInspector.Object.singleFireEventListener.let.wrappedCallback):
(WebInspector.Object.singleFireEventListener):
(WebInspector.Object.retainedObjectsWithPrototype):
(WebInspector.Object.prototype.singleFireEventListener):
(WebInspector.Object.prototype.retainedObjectsWithPrototype):
* UserInterface/Models/Frame.js:
(WebInspector.Frame.prototype.removeAllChildFrames): Clear own tree too.

LayoutTests:

Add a regression test to check the number of DOMTree instances that
listen to DOMTreeManager.

* TestExpectations: Don't skip the inspector/dom/ directory.
* http/tests/inspector/dom/disconnect-dom-tree-after-main-frame-navigation-expected.txt: Added.
* http/tests/inspector/dom/disconnect-dom-tree-after-main-frame-navigation.html: Added.
* http/tests/inspector/dom/resources/nested-frame-1-deep.html: Added.
* http/tests/inspector/dom/resources/nested-frame-2-deep.html: Added.
* http/tests/inspector/dom/resources/nested-frame-base.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (188755 => 188756)


--- trunk/LayoutTests/ChangeLog	2015-08-21 16:18:52 UTC (rev 188755)
+++ trunk/LayoutTests/ChangeLog	2015-08-21 17:05:59 UTC (rev 188756)
@@ -1,3 +1,20 @@
+2015-08-20  Brian Burg  <[email protected]>
+
+        Web Inspector: add a regression test for the fix introduced in r188679
+        https://bugs.webkit.org/show_bug.cgi?id=148223
+
+        Reviewed by Joseph Pecoraro.
+
+        Add a regression test to check the number of DOMTree instances that
+        listen to DOMTreeManager.
+
+        * TestExpectations: Don't skip the inspector/dom/ directory.
+        * http/tests/inspector/dom/disconnect-dom-tree-after-main-frame-navigation-expected.txt: Added.
+        * http/tests/inspector/dom/disconnect-dom-tree-after-main-frame-navigation.html: Added.
+        * http/tests/inspector/dom/resources/nested-frame-1-deep.html: Added.
+        * http/tests/inspector/dom/resources/nested-frame-2-deep.html: Added.
+        * http/tests/inspector/dom/resources/nested-frame-base.html: Added.
+
 2015-08-21  Chris Dumez  <[email protected]>
 
         Regression(r188698): http/tests/cache/disk-cache/disk-cache-revalidation-new-expire-header.html is very flaky

Modified: trunk/LayoutTests/TestExpectations (188755 => 188756)


--- trunk/LayoutTests/TestExpectations	2015-08-21 16:18:52 UTC (rev 188755)
+++ trunk/LayoutTests/TestExpectations	2015-08-21 17:05:59 UTC (rev 188756)
@@ -97,7 +97,10 @@
 webkit.org/b/129057 media/controls-styling-strict.html [ Pass Failure ]
 
 # These tests will be rewritten, just skip them until that time.
-webkit.org/b/148036 http/tests/inspector/ [ Skip ]
+webkit.org/b/148036 http/tests/inspector/console/ [ Skip ]
+webkit.org/b/148036 http/tests/inspector/css/ [ Skip ]
+webkit.org/b/148036 http/tests/inspector/page/ [ Skip ]
+webkit.org/b/148036 http/tests/inspector/replay/ [ Skip ]
 
 webkit.org/b/129639 inspector/dom/dom-search-crash.html [ Skip ]
 

Added: trunk/LayoutTests/http/tests/inspector/dom/disconnect-dom-tree-after-main-frame-navigation-expected.txt (0 => 188756)


--- trunk/LayoutTests/http/tests/inspector/dom/disconnect-dom-tree-after-main-frame-navigation-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/inspector/dom/disconnect-dom-tree-after-main-frame-navigation-expected.txt	2015-08-21 17:05:59 UTC (rev 188756)
@@ -0,0 +1,19 @@
+Testing that DOMTrees are not retained by DOMTreeManager across main frame navigations.
+
+
+
+== Running test suite: DOM.DisconnectTreeOnMainResourceChange
+-- Running test case: CheckLazyInitializationOfDOMTree
+PASS: There should not be a DOMTree listening to DOMTreeManager events initially.
+DOMTree instance count: 0
+
+-- Running test case: CheckDOMTreeCountAfterUsingGetter
+PASS: There should be a one DOMTree listening to DOMTreeManager events after creation.
+DOMTree instance count: 1
+PASS: There should be four DOMTrees listening to DOMTreeManager events after touching each Frame.
+DOMTree instance count: 4
+
+-- Running test case: CheckDOMTreeCountAfterReloading
+PASS: There should not be any DOMTrees listening to DOMTreeManager events after a main frame navigation.
+DOMTree instance count: 0
+

Added: trunk/LayoutTests/http/tests/inspector/dom/disconnect-dom-tree-after-main-frame-navigation.html (0 => 188756)


--- trunk/LayoutTests/http/tests/inspector/dom/disconnect-dom-tree-after-main-frame-navigation.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/inspector/dom/disconnect-dom-tree-after-main-frame-navigation.html	2015-08-21 17:05:59 UTC (rev 188756)
@@ -0,0 +1,68 @@
+<!doctype html>
+<html>
+<head>
+<script src=""
+<script>
+function test()
+{
+    let suite = InspectorTest.createAsyncSuite("DOM.DisconnectTreeOnMainResourceChange");
+
+    suite.addTestCase({
+        name: "CheckLazyInitializationOfDOMTree",
+        description: "Check that DOMTree instances are created lazily.",
+        test: (resolve, reject) => {
+            let instances = WebInspector.domTreeManager.retainedObjectsWithPrototype(WebInspector.DOMTree);
+            InspectorTest.expectThat(instances.size === 0, "There should not be a DOMTree listening to DOMTreeManager events initially.");
+            InspectorTest.log("DOMTree instance count: " + instances.size);
+            resolve();
+        }
+    });
+
+    suite.addTestCase({
+        name: "CheckDOMTreeCountAfterUsingGetter",
+        description: "Check that the count of connected DOMTrees is correct after initializing them.",
+        test: (resolve, reject) => {
+            let mainFrame = WebInspector.frameResourceManager.mainFrame;
+            mainFrame.domTree; // Force creation of the root DOM tree.
+
+            let instances = WebInspector.domTreeManager.retainedObjectsWithPrototype(WebInspector.DOMTree);
+            InspectorTest.expectThat(instances.size === 1, "There should be a one DOMTree listening to DOMTreeManager events after creation.");
+            InspectorTest.log("DOMTree instance count: " + instances.size);
+
+            // Force creation of child DOM trees.
+            mainFrame.childFrames[0].domTree;
+            mainFrame.childFrames[0].childFrames[0].domTree;
+            mainFrame.childFrames[0].childFrames[0].childFrames[0].domTree;
+
+            instances = WebInspector.domTreeManager.retainedObjectsWithPrototype(WebInspector.DOMTree);
+            InspectorTest.expectThat(instances.size === 4, "There should be four DOMTrees listening to DOMTreeManager events after touching each Frame.");
+            InspectorTest.log("DOMTree instance count: " + instances.size);
+
+            resolve();
+        }
+    });
+
+    suite.addTestCase({
+        name: "CheckDOMTreeCountAfterReloading",
+        description: "Check that the count of connected DOMTrees is correct after a reload.",
+        test: (resolve, reject) => {
+            WebInspector.Frame.singleFireEventListener(WebInspector.Frame.Event.MainResourceDidChange, (event) => {
+                let instances = WebInspector.domTreeManager.retainedObjectsWithPrototype(WebInspector.DOMTree);
+                InspectorTest.expectThat(instances.size === 0, "There should not be any DOMTrees listening to DOMTreeManager events after a main frame navigation.");
+                InspectorTest.log("DOMTree instance count: " + instances.size);
+                resolve();
+            });
+
+            InspectorTest.reloadPage();
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+    <p>Testing that DOMTrees are not retained by DOMTreeManager across main frame navigations.</p>
+    <iframe src=""
+</body>
+</html>

Added: trunk/LayoutTests/http/tests/inspector/dom/resources/nested-frame-1-deep.html (0 => 188756)


--- trunk/LayoutTests/http/tests/inspector/dom/resources/nested-frame-1-deep.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/inspector/dom/resources/nested-frame-1-deep.html	2015-08-21 17:05:59 UTC (rev 188756)
@@ -0,0 +1,7 @@
+<!doctype html>
+<html>
+<body>
+<div id="frameLabel">1-deep nested frames page.</div>
+<iframe src=""
+</body>
+</html>

Added: trunk/LayoutTests/http/tests/inspector/dom/resources/nested-frame-2-deep.html (0 => 188756)


--- trunk/LayoutTests/http/tests/inspector/dom/resources/nested-frame-2-deep.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/inspector/dom/resources/nested-frame-2-deep.html	2015-08-21 17:05:59 UTC (rev 188756)
@@ -0,0 +1,7 @@
+<!doctype html>
+<html>
+<body>
+<div id="frameLabel">2-deep nested frames page.</div>
+<iframe src=""
+</body>
+</html>

Added: trunk/LayoutTests/http/tests/inspector/dom/resources/nested-frame-base.html (0 => 188756)


--- trunk/LayoutTests/http/tests/inspector/dom/resources/nested-frame-base.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/inspector/dom/resources/nested-frame-base.html	2015-08-21 17:05:59 UTC (rev 188756)
@@ -0,0 +1,6 @@
+<!doctype html>
+<html>
+<body>
+<div id="frameLabel">Nested frame base page.</div>
+</body>
+</html>

Modified: trunk/Source/WebInspectorUI/ChangeLog (188755 => 188756)


--- trunk/Source/WebInspectorUI/ChangeLog	2015-08-21 16:18:52 UTC (rev 188755)
+++ trunk/Source/WebInspectorUI/ChangeLog	2015-08-21 17:05:59 UTC (rev 188756)
@@ -1,3 +1,22 @@
+2015-08-20  Brian Burg  <[email protected]>
+
+        Web Inspector: add a regression test for the fix introduced in r188679
+        https://bugs.webkit.org/show_bug.cgi?id=148223
+
+        Reviewed by Joseph Pecoraro.
+
+        Turns out that we were possibly leaking a single DOMTree on reload.
+        Always clear the main frame's DOMTree as well as those of sub-frames.
+
+        * UserInterface/Base/Object.js: Add back single-fire listeners.
+        (WebInspector.Object.singleFireEventListener.let.wrappedCallback):
+        (WebInspector.Object.singleFireEventListener):
+        (WebInspector.Object.retainedObjectsWithPrototype):
+        (WebInspector.Object.prototype.singleFireEventListener):
+        (WebInspector.Object.prototype.retainedObjectsWithPrototype):
+        * UserInterface/Models/Frame.js:
+        (WebInspector.Frame.prototype.removeAllChildFrames): Clear own tree too.
+
 2015-08-20  Joseph Pecoraro  <[email protected]>
 
         Web Inspector: Better Remember open tab types and order if using JSContext inspector

Modified: trunk/Source/WebInspectorUI/UserInterface/Base/Object.js (188755 => 188756)


--- trunk/Source/WebInspectorUI/UserInterface/Base/Object.js	2015-08-21 16:18:52 UTC (rev 188755)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Object.js	2015-08-21 17:05:59 UTC (rev 188756)
@@ -55,6 +55,16 @@
         listeners.push({thisObject, listener});
     }
 
+    static singleFireEventListener(eventType, listener, thisObject)
+    {
+        let wrappedCallback = function() {
+            this.removeEventListener(eventType, wrappedCallback, null);
+            listener.apply(thisObject, arguments);
+        }.bind(this);
+
+        this.addEventListener(eventType, wrappedCallback, null);
+    }
+
     static removeEventListener(eventType, listener, thisObject)
     {
         eventType = eventType || null;
@@ -100,12 +110,28 @@
         return true;
     }
 
+    // This should only be used within regression tests to detect leaks.
+    static retainedObjectsWithPrototype(proto)
+    {
+        let results = new Set;
+        for (let eventType in this._listeners) {
+            let recordsForEvent = this._listeners[eventType];
+            for (let listener of recordsForEvent) {
+                if (listener.thisObject instanceof proto)
+                    results.add(listener.thisObject);
+            }
+        }
+        return results;
+    }
+
     // Public
 
     addEventListener() { return WebInspector.Object.addEventListener.apply(this, arguments); }
+    singleFireEventListener() { return WebInspector.Object.singleFireEventListener.apply(this, arguments); }
     removeEventListener() { return WebInspector.Object.removeEventListener.apply(this, arguments); }
     removeAllListeners() { return WebInspector.Object.removeAllListeners.apply(this, arguments); }
     hasEventListeners() { return WebInspector.Object.hasEventListeners.apply(this, arguments); }
+    retainedObjectsWithPrototype() { return WebInspector.Object.retainedObjectsWithPrototype.apply(this, arguments); }
 
     dispatchEventToListeners(eventType, eventData)
     {

Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Frame.js (188755 => 188756)


--- trunk/Source/WebInspectorUI/UserInterface/Models/Frame.js	2015-08-21 16:18:52 UTC (rev 188755)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Frame.js	2015-08-21 17:05:59 UTC (rev 188756)
@@ -338,11 +338,10 @@
 
     removeAllChildFrames()
     {
-        if (!this._childFrames.length)
-            return;
+        this._detachFromParentFrame();
 
         for (let childFrame of this._childFrames)
-            childFrame._detachFromParentFrame();
+            childFrame.removeAllChildFrames();
 
         this._childFrames = [];
         this._childFrameIdentifierMap = {};
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to