tntim96 / JSCover

JSCover is a JavaScript Code Coverage Tool that measures line, branch and function coverage
GNU General Public License v2.0
399 stars 84 forks source link

Memory leak in jscover? #207

Closed binodpanta closed 9 years ago

binodpanta commented 9 years ago

I have been running some tests using jsCover 1.0.18 and noted that jscover does not seem to be releasing memory. I had a run that ran 10 minutes or so, and I found jscvoer reached about 5GB committed memory after which is started throwing out of memory.

We call the the snapshot code like this after each test,

collect: jscover_json = (String) je .executeScript("return jscoverage_serializeCoverageToJSON();");

then post the data using the POSt like this later

post: String requestURL = "http://" + pageURL.getHost() + ":"

Is there a way to ask JSCover to 'reset'/'release' all its data, and start over? In other words, once we have posted the data, there does not seem to be a need for jscover to hold on to any data.

This will help stabilize our tests suites. I don't have a reproduction script here but I suspect you can run any test with jscover for a long time and observe this. If you have trouble with reproducing, I can try to put together my test case.

tntim96 commented 9 years ago

Are you running in proxy mode or server mode? What kind of tests are you running so I can try to replicate?

binodpanta commented 9 years ago

Hi

I using proxy mode as

-ws --proxy

Etc

I can send a sample test page tomorrow ( mine is qunit and dojo based based) although I think this could be reproducible with most any test page if you ran the same page on a loop a number of times. I ran with chrome+ webdriver.

-Binod

On Aug 3, 2015, at 19:13, tntim96 notifications@github.com wrote:

Are you running in proxy mode or server mode? What kind of tests are you running so I can try to replicate?

― Reply to this email directly or view it on GitHub.

binodpanta commented 9 years ago

Sorry for being sloppy about this but the page source of one of my test pages looks like this, if this helps with repro. It is not usable as provided of course, but at least hopefully gives an idea of what I am doing. My jscover is being hit with many tests like this and it runs out of memory after some time (even if I use -Xmx1025m -Xms1024m in the java invocation)

    <!DOCTYPE html>
    <html>

    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta http-equiv='cache-control' content='no-cache'>
        <meta http-equiv='expires' content='0'>
        <meta http-equiv='pragma' content='no-cache'>

        <base href="../../../../"></base>

    <!--[if IE]><script type="text/javascript">
        // Fix for IE ignoring relative base tags.
        // See http://stackoverflow.com/questions/3926197/html-base-tag-and-local-folder-path-with-internet-explorer
        (function() {
            var baseTag = document.getElementsByTagName('base')[0];
            baseTag.href = baseTag.href;
        })();
    </script><![endif]-->

        <title>JavaScript unit tests</title>
        <link rel="stylesheet" type="text/css" href="../../../tools/javascript/libs/qunit/qunit.css">
        <link rel="stylesheet" type="text/css" href="../../../../ui/webwidgets/src/css/TextComponentDefaultVisualFamily.css">
    </head>

    <body>
        <div>
            <div id="qunit-fixture"></div>
            <div id="qunit"></div>
        </div>

        <!-- Load dojo -->
        <script src="../../../../src/js/dojoConfigs/dojoConfig-test.js"></script>
        <script type="text/javascript" src="../../../../src/js/dojo/dojo/dojo.js"></script>

        <!-- Load QUnit -->
        <script type="text/javascript" src="../../../tools/javascript/libs/qunit/qunit.js"></script>

        <script type="text/javascript">
            QUnit.config.autostart = false;

            require(["Tests/unit_tests/plugins/tokenizer/TokenUnitTest"], function () {
                QUnit.start();
            });
    </script>
    </body>
    </html>
tntim96 commented 9 years ago

Why are you using the proxy if you're using QUnit? Why not use the JSCover server mode to serve this page?

binodpanta commented 9 years ago

Hi there

We use selenium to control the browser. We use proxy mode and point webdriver to use proxy then collect at end of test. Is using proxy not the most recommended approach?

On Aug 4, 2015, at 18:42, tntim96 notifications@github.com wrote:

Why are you using the proxy if you're using QUnit? Why not use the JSCover server mode to serve this page?

― Reply to this email directly or view it on GitHub.

tntim96 commented 9 years ago

You should use server mode if you can, and if you're using QUnit, it should be possible.

binodpanta commented 9 years ago

Hmm I use jscover with selenium based tests. However For this case I use webdriver only to control the browser hence find it easy to use proxy mode. But also anotjer reason is that the server serving the files is often not in my control. Does it still make sense not to use proxy node then?

-Binod

On Aug 4, 2015, at 20:48, tntim96 notifications@github.com wrote:

You should use server mode if you can, and if you're using QUnit, it should be possible.

― Reply to this email directly or view it on GitHub.

tntim96 commented 9 years ago

Proxy mode adds a lot of complications. If you are testing your JS while testing your application with Selenium, you'll have to use proxy mode or preferably pre-instrument with file-mode.

If you are just pointing at a HTML QUnit test, you can have the JSCover server serve that file, which is generally the easiest approach. I'm not sure if that's possible for your situation though.

binodpanta commented 9 years ago

I guess proxy is what I need then since I have to use the server developed internally for other reasons.

Are there any known issues with this mode? Is the memory leak somehow unique to proxy mode?

At this time I am trying to restart jscover after each test as a workaround.

Thanks

On Aug 4, 2015, at 22:09, tntim96 notifications@github.com wrote:

Proxy mode adds a lot of complications. If you are testing your JS while testing your application with Selenium, you'll have to use proxy mode or preferably pre-instrument with file-mode.

If you are just pointing at a HTML QUnit test, you can have the JSCover server serve that file, which is generally the easiest approach. I'm not sure if that's possible for your situation though.

― Reply to this email directly or view it on GitHub.

tntim96 commented 9 years ago

Proxy mode adds a lot of overhead, and if there is a memory-leak, I don't have enough details to pin-point the problem. You can achieve code-coverage by first instrumenting in file-mode. Take a look at this example of how to do it.

binodpanta commented 9 years ago

For me filesystem is hard to get right because I only offer the tooling and my users may have code that are in multiple locations I have no knowledge of. Their selenium based tests get coverage this way when coverage mode is on. Webserver mode issue is that users need to use a custom webserver. That is why I have found only proxy mode allowed my use case to work.

Thanks, -Binod

On Aug 5, 2015, at 18:15, tntim96 notifications@github.com wrote:

Proxy mode adds a lot of overhead, and if there is a memory-leak, I don't have enough details to pin-point the problem. You can achieve code-coverage by first instrumenting in file-mode. Take a look at this example of how to do it.

― Reply to this email directly or view it on GitHub.

binodpanta commented 8 years ago

We have come up with an interesting solution using mitm proxy and jscover which gets us ssl support too, we'll be glad to discuss/share if this can be useful

We also want to support source maps going forward esp with Babel ES6 and minifiication handling requirements, it might influence our tool choice somewhat. Are these two features in your priority list?

tntim96 commented 8 years ago

mitm proxy and jscover which gets us ssl support too, we'll be glad to discuss/share if this can be useful

Sure. That would be great. Do you have a running example in github or elsewhere that's public?

We also want to support source maps going forward esp with Babel ES6 and minifiication handling requirements, it might influence our tool choice somewhat. Are these two features in your priority list?

I've had this asked a few times, can see the benefit of it, and would like to add it in, but it would take a lot of time and effort. Branches and functions should instrument the same when minified, but the problem with line coverage is that it is instrumented per line, not per statement. As minification puts several, if not all, statements on one line, this would require a major architectural change. If you need it in the next several months, you'd probably have to look elsewhere.

I was looking at doing this in a new tool, JSCover2, but that is still a work in progress.

tntim96 commented 8 years ago

Actually, I've thought of another way this might work without a major change. Would the following approach be acceptable to you (if so I can probably start working on it straight away):

I'd like to know how your set-up works with mitm proxy first, and whether this is all of use to you.

Also, what compressor do you use (e.g. Uglify 2) and do you include multiple files in one?

Let me know and I'll take a closer look and might be able to provide a time-estimate.