summaryrefslogtreecommitdiffstats
path: root/third_party/WebKit/LayoutTests/resources/leak-check.js
blob: 414ee650563e86691fe4f96c68f54dd2ad9d30fa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// include resources/js-test.js before this file.

function getCounterValues(callback) {
    testRunner.resetTestHelperControllers();
    asyncGC(function() {
        var ret = {
          'numberOfLiveDocuments': window.internals.numberOfLiveDocuments(),
          'numberOfLiveAXObjects': window.internals.numberOfLiveAXObjects()
        };

        var refCountedInstances = JSON.parse(window.internals.dumpRefCountedInstanceCounts());
        for (typename in refCountedInstances)
            ret['numberOfInstances-'+typename] = refCountedInstances[typename];

        callback(ret);
    });

}

function compareValues(countersBefore, countersAfter, tolerance) {
    for (type in tolerance) {
        var before = countersBefore[type];
        var after = countersAfter[type];

        if (after - before <= tolerance[type])
            testPassed('The difference of counter "'+type+'" before and after the cycle is under the threshold of '+tolerance[type]+'.');
        else
            testFailed('counter "'+type+'" was '+before+' before and now '+after+' after the cycle. This exceeds the threshold of '+tolerance[type]+'.');
    }
}

function doLeakTest(src, tolerance) {
    var frame = document.createElement('iframe');
    document.body.appendChild(frame);
    function loadSourceIntoIframe(src, callback) {
        var originalSrc = frame.src;

        frame.onload = function() {
            if (frame.src === originalSrc)
                return true;

            callback();
            return true;
        };
        frame.src = src;
    }

    jsTestIsAsync = true;
    if (!window.internals) {
        debug("This test only runs on DumpRenderTree, as it requires existence of window.internals and cross-domain resource access check disabled.");
        finishJSTest();
    }

    loadSourceIntoIframe('about:blank', function() {
        // blank document loaded...
        getCounterValues(function(countersBefore) {
            loadSourceIntoIframe(src, function() {
                // target document loaded...

                loadSourceIntoIframe('about:blank', function() {
                    // target document unloaded...

                    // Measure counter values on next timer event. This is needed
                    // to correctly handle deref cycles for some ActiveDOMObjects
                    // such as XMLHttpRequest.
                    setTimeout(function() {
                        getCounterValues(function(countersAfter) {
                            compareValues(countersBefore, countersAfter, tolerance);
                            finishJSTest();
                        });
                    }, 0);
                });
            });
        });
    });
}

function htmlToUrl(html) {
    return 'data:text/html;charset=utf-8,' + html;
}

function grabScriptText(id) {
    return document.getElementById(id).innerText;
}

// include fast/js/resources/js-test-post.js after this file.