Skip to content

Karma 0.12 hangs with and IE11 #952

Closed

Description

@sylvain-hamel

After updating karma to 0.12, running tests on IE11 hangs. It works fine on IE10.

  • See the attached sample.
  • Run it as-is (with 0.12)
  • Tests all run to completion
  • Bug: karma hangs
  • You have to CTRL+Break to stop it OR you can kill iexplorer.exe
  • Change package.json to karma 0.10.0
  • Reinstall
  • Run again
  • Works fine

I'm willing to investigate. To get me started, do you any idea of what change from 0.10 to 0.12 could have caused this?


package.json

{
  "name": "karma-test",
  "version": "0.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "karma": "~0.12.0",
    "karma-ie-launcher": "~0.1.3"
  }
}

karma.conf.js

module.exports = function(config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine'],
    files: ['js/*.js'],
    exclude: [],
    preprocessors: {},
    reporters: ['dots'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: false,
    browsers: ['IE'],
    singleRun: true
  });
};

js/t.spec.js

describe('test', function(){
    it('works', function(){
        expect(1).toEqual(2);
    })
});

Activity

  1. vojtajina commented on Mar 16, 2014

    @vojtajina
    Contributor

    @sylvain-hamel thanks for reporting this. It would be great if you can look into it a bit more.

    The changelog of all the changes is here.

    There was a significant refactoring in the launcher, I think that might have introduced some issue:
    e6f36ca

  2. sylvain-hamel commented on Mar 16, 2014

    @sylvain-hamel
    ContributorAuthor

    Yep, I'll take a closer look. You can assign this issue to me if you want.

  3. sylvain-hamel commented on Mar 19, 2014

    @sylvain-hamel
    ContributorAuthor

    I found the change that causes this new behavior: karma 0.10 does not call webServer.close() whereas karma 0.12 does.

    server.js (karma 0.10)

      var disconnectBrowsers = function(code) {
        var sockets = socketServer.sockets.sockets;
        Object.getOwnPropertyNames(sockets).forEach(function(key) {
          sockets[key].removeAllListeners('disconnect');
        });
        globalEmitter.emitAsync('exit').then(function () {
            done(code || 0);
        });
      };
    

    server.js - karma 0.12

      var disconnectBrowsers = function(code) {
        var sockets = socketServer.sockets.sockets;
        Object.getOwnPropertyNames(sockets).forEach(function(key) {
          sockets[key].removeAllListeners('disconnect');
        });
        globalEmitter.emitAsync('exit').then(function () {
          webServer.close(function () {
            webServer.removeAllListeners();
            processWrapper.removeAllListeners();
            done(code || 0);
          });
        });
      };
    

    node's Server.close waits for connections to close but when running with IE11, there are pending connections even after killing the iexplore.exe process.

    More info on IE:

    When you launch iexplorer.exe, that spawns two processes. You can witness that by just running iexplorer.exe from the command-line and you'll see two processes in Task Manager. However

    • On IE10: If you kill the first process using Task Manager, the second process goes away.
    • On IE11: If you kill the first process using Task Manager, the second process remains there (apparently for no reason).

    My understanding of the root cause:

    • My guess is that with the arrival of IE11, they use the second process to act as some kind of proxy for the first process and handles connections to the server.
    • Because killing the first process no longer kills the second one AND because Karma now waits the server to close, karma ends up waiting indefinitely for the server to close.

    I see 3 options to fix that:

    1. stop calling webserver.close() in karma, as it used to be in karma 0.10
    2. implement a webserver close timeout in disconnectBrowsers, something like this (I tried it and it works):
      var disconnectBrowsers = function(code) {
        var sockets = socketServer.sockets.sockets;
        Object.getOwnPropertyNames(sockets).forEach(function(key) {
          sockets[key].removeAllListeners('disconnect');
        });
        globalEmitter.emitAsync('exit').then(function () {
          webServer.close(function () {
            webServer.removeAllListeners();
            processWrapper.removeAllListeners();
            done(code || 0);
          });
          ////////////////////////////////////////////////////////////////////////////
          // call done, which exits the current process after 3 sec
          ////////////////////////////////////////////////////////////////////////////
          setTimeout(done, 3000); 
        });
      };
    

    x
    3. Implement a hack in karma-ie-launcher to find and kill the second iexplorer process when the first one is killed by karma.

    I think that option 2 is the best because it is the simplest and protects karam against future clients (browsers) that would keep connections to the karma server.

    What do you think?

  4. dignifiedquire commented on Mar 19, 2014

    @dignifiedquire
    Member

    I agree with the suggestion of 2. My experience with server.close is a very mixed and it should always have a timeout to kill any connections that are left.

  5. added 3 commits that reference this issue on Mar 21, 2014
    32cbfa4
    ad5fa5e
    fe3dca7
  6. sylvain-hamel commented on Mar 27, 2014

    @sylvain-hamel
    ContributorAuthor

    We've been running with #973 for a week now. It works fine.

    However, each time our ci is triggered, a new extra process leaks out (as explained in a previous comment). After a few days, we start getting ERROR [launcher]: Cannot start IE. If I kill the 80 iexplore.exe processes and restart the build and then it works again. I don't know why exactly that prevents a new iexplore.exe from being spawned but it doesn’t really matter. 80 inactive processes is not good, even if it worked, at some point, the CI server would run out of memory and fail.

    I really think #973 is valid and necessary (solution 2). However I'll also implement solution 3 in karma-ie-launcher to get rid of the extra processes that accumulate.

    In the meantime, can you guys merge #973.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions