Skip to content

Commit

Permalink
feat(browser): add browserNoActivity configuration
Browse files Browse the repository at this point in the history
Add a new configuration option `browserNoActivityTimeout` with a default value of 10000 ms. If, during the execution, Karma does not receive any message from a browser within `browserNoActivityTimeout`, it disconnects the browser.
  • Loading branch information
vojtajina committed Dec 4, 2013
1 parent 434eb1d commit bca8faa
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 9 deletions.
10 changes: 10 additions & 0 deletions docs/config/01-configuration-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,16 @@ Usually any disconnection is considered as a failure, but this option allows to
a flaky network link between the karma server and the browsers.


## browserNoActivityTimeout
**Type:** Number

**Default:** `10000`

**Description:** How long does Karma wait for a message from a browser before disconnecting it (in ms).

If, during the execution, Karma does not receive any message from a browser within `browserNoActivityTimeout` ms, it will disconnect the browser.


## browsers
**Type:** Array

Expand Down
50 changes: 41 additions & 9 deletions lib/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ var DISCONNECTED = 5;


var Browser = function(id, fullName, /* capturedBrowsers */ collection, emitter, socket, timer,
/* config.browserDisconnectTimeout */ disconnectDelay) {
/* config.browserDisconnectTimeout */ disconnectDelay,
/* config.browserNoActivityTimeout */ noActivityTimeout) {

var name = helper.browserFullNameToShort(fullName);
var log = logger.create(name);
Expand All @@ -33,6 +34,33 @@ var Browser = function(id, fullName, /* capturedBrowsers */ collection, emitter,
}).join(', ');
};

var self = this;
var pendingDisconnect;
var disconnect = function(reason) {
self.state = DISCONNECTED;
self.disconnectsCount++;
log.warn('Disconnected (%d times)' + (reason || ''), self.disconnectsCount);
collection.remove(self);
};

var noActivityTimeoutId;
var refreshNoActivityTimeout = noActivityTimeout ? function() {
clearNoActivityTimeout();
noActivityTimeoutId = timer.setTimeout(function() {
self.lastResult.totalTimeEnd();
self.lastResult.disconnected = true;
disconnect(', because no message in ' + noActivityTimeout + ' ms.');
emitter.emit('browser_complete', self);
}, noActivityTimeout);
} : function() {};

var clearNoActivityTimeout = noActivityTimeout ? function() {
if (noActivityTimeoutId) {
timer.clearTimeout(noActivityTimeoutId);
noActivityTimeoutId = null;
}
} : function() {};

this.id = id;
this.fullName = fullName;
this.name = name;
Expand Down Expand Up @@ -68,6 +96,8 @@ var Browser = function(id, fullName, /* capturedBrowsers */ collection, emitter,

this.lastResult.error = true;
emitter.emit('browser_error', this, error);

refreshNoActivityTimeout();
};

this.onInfo = function(info) {
Expand All @@ -83,6 +113,8 @@ var Browser = function(id, fullName, /* capturedBrowsers */ collection, emitter,
if (helper.isDefined(info.log)) {
emitter.emit('browser_log', this, info.log, info.type);
}

refreshNoActivityTimeout();
};

this.onStart = function(info) {
Expand All @@ -94,6 +126,7 @@ var Browser = function(id, fullName, /* capturedBrowsers */ collection, emitter,
}

emitter.emit('browser_start', this, info);
refreshNoActivityTimeout();
};

this.onComplete = function(result) {
Expand All @@ -110,17 +143,10 @@ var Browser = function(id, fullName, /* capturedBrowsers */ collection, emitter,

emitter.emit('browsers_change', collection);
emitter.emit('browser_complete', this, result);
};

var self = this;
var disconnect = function() {
self.state = DISCONNECTED;
self.disconnectsCount++;
log.warn('Disconnected (%d times)', self.disconnectsCount);
collection.remove(self);
clearNoActivityTimeout();
};

var pendingDisconnect;
this.onDisconnect = function(_, disconnectedSocket) {
activeSockets.splice(activeSockets.indexOf(disconnectedSocket), 1);

Expand All @@ -141,6 +167,8 @@ var Browser = function(id, fullName, /* capturedBrowsers */ collection, emitter,
disconnect();
emitter.emit('browser_complete', self);
}, disconnectDelay);

clearNoActivityTimeout();
}
};

Expand All @@ -166,6 +194,8 @@ var Browser = function(id, fullName, /* capturedBrowsers */ collection, emitter,
if (pendingDisconnect) {
timer.clearTimeout(pendingDisconnect);
}

refreshNoActivityTimeout();
};

this.onResult = function(result) {
Expand All @@ -181,6 +211,7 @@ var Browser = function(id, fullName, /* capturedBrowsers */ collection, emitter,
this.lastResult.add(result);

emitter.emit('spec_complete', this, result);
refreshNoActivityTimeout();
};

this.serialize = function() {
Expand All @@ -197,6 +228,7 @@ var Browser = function(id, fullName, /* capturedBrowsers */ collection, emitter,
});

this.state = EXECUTING;
refreshNoActivityTimeout();
};
};

Expand Down
1 change: 1 addition & 0 deletions lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ var Config = function() {
};
this.browserDisconnectTimeout = 2000;
this.browserDisconnectTolerance = 0;
this.browserNoActivityTimeout = 10000;
};

var CONFIG_SYNTAX_HELP = ' module.exports = function(config) {\n' +
Expand Down
17 changes: 17 additions & 0 deletions test/unit/browser.spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -464,3 +464,20 @@ describe 'Browser', ->
socket.emit 'result', {success: true, suite: [], log: []}
expect(browser.lastResult.success).to.equal 1


it 'disconnect when no message during the run', ->
timer = createMockTimer()
browser = new Browser 'fake-id', 'Chrome 31.0', collection, emitter, socket, timer, 10, 20
browser.init()
browser.execute()

spyBrowserComplete = sinon.spy()
emitter.on 'browser_complete', spyBrowserComplete

socket.emit 'start', {total: 11}
socket.emit 'result', {success: true, suite: [], log: []}

timer.wind 20
expect(browser.state).to.equal Browser.STATE_DISCONNECTED
expect(browser.disconnectsCount).to.equal 1
expect(spyBrowserComplete).to.have.been.called

0 comments on commit bca8faa

Please sign in to comment.