Adding gc tests: fixing a memory leak with C++ URLRequest objects.
This commit is contained in:
parent
9b4e9c642a
commit
c198828e58
4 changed files with 95 additions and 27 deletions
|
@ -215,6 +215,7 @@ URLRequest::BuildArgsArray(ArgTypes... args) const {
|
||||||
|
|
||||||
template <typename... ArgTypes>
|
template <typename... ArgTypes>
|
||||||
void URLRequest::EmitRequestEvent(ArgTypes... args) {
|
void URLRequest::EmitRequestEvent(ArgTypes... args) {
|
||||||
|
v8::HandleScope handle_scope(isolate());
|
||||||
auto arguments = BuildArgsArray(args...);
|
auto arguments = BuildArgsArray(args...);
|
||||||
v8::Local<v8::Function> _emitRequestEvent;
|
v8::Local<v8::Function> _emitRequestEvent;
|
||||||
auto wrapper = GetWrapper();
|
auto wrapper = GetWrapper();
|
||||||
|
@ -225,6 +226,7 @@ void URLRequest::EmitRequestEvent(ArgTypes... args) {
|
||||||
|
|
||||||
template <typename... ArgTypes>
|
template <typename... ArgTypes>
|
||||||
void URLRequest::EmitResponseEvent(ArgTypes... args) {
|
void URLRequest::EmitResponseEvent(ArgTypes... args) {
|
||||||
|
v8::HandleScope handle_scope(isolate());
|
||||||
auto arguments = BuildArgsArray(args...);
|
auto arguments = BuildArgsArray(args...);
|
||||||
v8::Local<v8::Function> _emitResponseEvent;
|
v8::Local<v8::Function> _emitResponseEvent;
|
||||||
auto wrapper = GetWrapper();
|
auto wrapper = GetWrapper();
|
||||||
|
|
|
@ -95,7 +95,7 @@ URLRequest.prototype._emitRequestEvent = function (async, ...rest) {
|
||||||
URLRequest.prototype._emitResponseEvent = function (async, ...rest) {
|
URLRequest.prototype._emitResponseEvent = function (async, ...rest) {
|
||||||
if (async) {
|
if (async) {
|
||||||
process.nextTick(() => {
|
process.nextTick(() => {
|
||||||
this.clientRequest.emit.apply(this._response, rest)
|
this._response.emit.apply(this._response, rest)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
this._response.emit.apply(this._response, rest)
|
this._response.emit.apply(this._response, rest)
|
||||||
|
|
|
@ -26,7 +26,7 @@ const kOneKiloByte = 1024
|
||||||
const kOneMegaByte = kOneKiloByte * kOneKiloByte
|
const kOneMegaByte = kOneKiloByte * kOneKiloByte
|
||||||
|
|
||||||
describe('net module', function () {
|
describe('net module', function () {
|
||||||
this.timeout(0)
|
// this.timeout(0)
|
||||||
describe('HTTP basics', function () {
|
describe('HTTP basics', function () {
|
||||||
let server
|
let server
|
||||||
beforeEach(function (done) {
|
beforeEach(function (done) {
|
||||||
|
@ -1155,42 +1155,108 @@ describe('net module', function () {
|
||||||
urlRequest.end()
|
urlRequest.end()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('Stability and performance', function(done) {
|
describe('Stability and performance', function (done) {
|
||||||
let server
|
let server
|
||||||
beforeEach(function (done) {
|
beforeEach(function (done) {
|
||||||
server = http.createServer()
|
server = http.createServer()
|
||||||
server.listen(0, '127.0.0.1', function () {
|
server.listen(0, '127.0.0.1', function () {
|
||||||
server.url = 'http://127.0.0.1:' + server.address().port
|
server.url = 'http://127.0.0.1:' + server.address().port
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
server.close()
|
server.close()
|
||||||
server = null
|
server = null
|
||||||
})
|
})
|
||||||
|
|
||||||
it.only('should free unreferenced, never-started request objects', function(done) {
|
it('should free unreferenced, never-started request objects', function (done) {
|
||||||
const requestUrl = '/requestUrl'
|
const requestUrl = '/requestUrl'
|
||||||
ipcRenderer.on('api-net-spec-done', function() {
|
ipcRenderer.once('api-net-spec-unused-done', function () {
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
const testCode = `
|
ipcRenderer.send('eval', `
|
||||||
// Load the net module in the main browser process.
|
const {net} = require('electron')
|
||||||
const {net} = require('electron')
|
const urlRequest = net.request('${server.url}${requestUrl}')
|
||||||
const urlRequest = net.request('${server.url}${requestUrl}')
|
process.nextTick(function () {
|
||||||
process.nextTick(function() {
|
net._RequestGarbageCollectionForTesting()
|
||||||
net._RequestGarbageCollectionForTesting()
|
event.sender.send('api-net-spec-unused-done')
|
||||||
event.sender.send('api-net-spec-done')
|
})
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
it('should not collect on-going requests', function (done) {
|
||||||
|
const requestUrl = '/requestUrl'
|
||||||
|
server.on('request', function (request, response) {
|
||||||
|
switch (request.url) {
|
||||||
|
case requestUrl:
|
||||||
|
response.statusCode = 200
|
||||||
|
response.statusMessage = 'OK'
|
||||||
|
response.write(randomString(kOneKiloByte))
|
||||||
|
ipcRenderer.once('api-net-spec-ongoing-resume-response', function () {
|
||||||
|
response.write(randomString(kOneKiloByte))
|
||||||
|
response.end()
|
||||||
|
})
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
assert(false)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
`
|
ipcRenderer.once('api-net-spec-ongoing-done', function () {
|
||||||
ipcRenderer.send('eval', testCode)
|
done()
|
||||||
|
})
|
||||||
|
// Execute below code directly within the browser context without
|
||||||
|
// using the remote module.
|
||||||
|
ipcRenderer.send('eval', `
|
||||||
|
const {net} = require('electron')
|
||||||
|
const urlRequest = net.request('${server.url}${requestUrl}')
|
||||||
|
urlRequest.on('response', function (response) {
|
||||||
|
response.on('data', function () {
|
||||||
|
})
|
||||||
|
response.on('end', function () {
|
||||||
|
event.sender.send('api-net-spec-ongoing-done')
|
||||||
|
})
|
||||||
|
process.nextTick(function () {
|
||||||
|
// Trigger a garbage collection.
|
||||||
|
net._RequestGarbageCollectionForTesting()
|
||||||
|
event.sender.send('api-net-spec-ongoing-resume-response')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
urlRequest.end()
|
||||||
|
`)
|
||||||
})
|
})
|
||||||
it.skip('should not collect on-going requests', function(done) {
|
it('should collect unreferenced, ended requests', function (done) {
|
||||||
assert(false)
|
const requestUrl = '/requestUrl'
|
||||||
})
|
server.on('request', function (request, response) {
|
||||||
it.skip('should collect unreferenced, ended requests', function(done) {
|
switch (request.url) {
|
||||||
assert(false)
|
case requestUrl:
|
||||||
|
response.statusCode = 200
|
||||||
|
response.statusMessage = 'OK'
|
||||||
|
response.end()
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
assert(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
ipcRenderer.once('api-net-spec-done', function () {
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
ipcRenderer.send('eval', `
|
||||||
|
const {net} = require('electron')
|
||||||
|
const urlRequest = net.request('${server.url}${requestUrl}')
|
||||||
|
urlRequest.on('response', function (response) {
|
||||||
|
response.on('data', function () {
|
||||||
|
})
|
||||||
|
response.on('end', function () {
|
||||||
|
})
|
||||||
|
})
|
||||||
|
urlRequest.on('close', function () {
|
||||||
|
process.nextTick(function () {
|
||||||
|
net._RequestGarbageCollectionForTesting()
|
||||||
|
event.sender.send('api-net-spec-done')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
urlRequest.end()
|
||||||
|
`)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -8,7 +8,7 @@ const ipcMain = electron.ipcMain
|
||||||
const dialog = electron.dialog
|
const dialog = electron.dialog
|
||||||
const BrowserWindow = electron.BrowserWindow
|
const BrowserWindow = electron.BrowserWindow
|
||||||
const protocol = electron.protocol
|
const protocol = electron.protocol
|
||||||
const v8 = require('v8');
|
const v8 = require('v8')
|
||||||
|
|
||||||
const Coverage = require('electabul').Coverage
|
const Coverage = require('electabul').Coverage
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue