Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
test: fix flakiness of stringbytes-external
The tests used to rely on precise timing of when a JavaScript object
would be garbage collected to ensure that there is enough memory
available on the system. Switch the test to use a malloc/free pair
instead.

Ref: #5945
  • Loading branch information
ofrobots committed Apr 4, 2016
commit 4e6f03c22e2ca1fcb16cef0b2fc537969510fea7
24 changes: 24 additions & 0 deletions test/addons/stringbytes-external-exceed-max/binding.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <stdlib.h>
#include <node.h>
#include <v8.h>

void EnsureAllocation(const v8::FunctionCallbackInfo<v8::Value> &args) {
v8::Isolate* isolate = args.GetIsolate();
uintptr_t size = args[0]->IntegerValue();
v8::Local<v8::Boolean> success;

void* buffer = malloc(size);
if (buffer) {
success = v8::Boolean::New(isolate, true);
free(buffer);
} else {
success = v8::Boolean::New(isolate, false);
}
args.GetReturnValue().Set(success);
}

void init(v8::Local<v8::Object> target) {
NODE_SET_METHOD(target, "ensureAllocation", EnsureAllocation);
}

NODE_MODULE(binding, init);
8 changes: 8 additions & 0 deletions test/addons/stringbytes-external-exceed-max/binding.gyp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
'targets': [
{
'target_name': 'binding',
'sources': [ 'binding.cc' ]
}
]
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';
// Flags: --expose-gc

const common = require('../common');
const common = require('../../common');
const binding = require('./build/Release/binding');
const assert = require('assert');

const skipMessage =
Expand All @@ -10,24 +10,26 @@ if (!common.enoughTestMem) {
console.log(skipMessage);
return;
}
assert(typeof gc === 'function', 'Run this test with --expose-gc');

// v8 fails silently if string length > v8::String::kMaxLength
// v8::String::kMaxLength defined in v8.h
const kStringMaxLength = process.binding('buffer').kStringMaxLength;

try {
var buf = Buffer.allocUnsafe(kStringMaxLength + 1);
// Try to allocate memory first then force gc so future allocations succeed.
Buffer.allocUnsafe(2 * kStringMaxLength);
gc();
} catch (e) {
// If the exception is not due to memory confinement then rethrow it.
if (e.message !== 'Array buffer allocation failed') throw (e);
console.log(skipMessage);
return;
}

// Ensure we have enough memory available for future allocations to succeed.
if (!binding.ensureAllocation(2 * kStringMaxLength)) {
console.log(skipMessage);
return;
}

assert.throws(function() {
buf.toString('ascii');
}, /"toString\(\)" failed/);
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';
// Flags: --expose-gc

const common = require('../common');
const common = require('../../common');
const binding = require('./build/Release/binding');
const assert = require('assert');

const skipMessage =
Expand All @@ -10,24 +10,26 @@ if (!common.enoughTestMem) {
console.log(skipMessage);
return;
}
assert(typeof gc === 'function', 'Run this test with --expose-gc');

// v8 fails silently if string length > v8::String::kMaxLength
// v8::String::kMaxLength defined in v8.h
const kStringMaxLength = process.binding('buffer').kStringMaxLength;

try {
var buf = Buffer.allocUnsafe(kStringMaxLength + 1);
// Try to allocate memory first then force gc so future allocations succeed.
Buffer.allocUnsafe(2 * kStringMaxLength);
gc();
} catch (e) {
// If the exception is not due to memory confinement then rethrow it.
if (e.message !== 'Array buffer allocation failed') throw (e);
console.log(skipMessage);
return;
}

// Ensure we have enough memory available for future allocations to succeed.
if (!binding.ensureAllocation(2 * kStringMaxLength)) {
console.log(skipMessage);
return;
}

assert.throws(function() {
buf.toString('base64');
}, /"toString\(\)" failed/);
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';
// Flags: --expose-gc

const common = require('../common');
const common = require('../../common');
const binding = require('./build/Release/binding');
const assert = require('assert');

const skipMessage =
Expand All @@ -10,24 +10,26 @@ if (!common.enoughTestMem) {
console.log(skipMessage);
return;
}
assert(typeof gc === 'function', 'Run this test with --expose-gc');

// v8 fails silently if string length > v8::String::kMaxLength
// v8::String::kMaxLength defined in v8.h
const kStringMaxLength = process.binding('buffer').kStringMaxLength;

try {
var buf = Buffer.allocUnsafe(kStringMaxLength + 1);
// Try to allocate memory first then force gc so future allocations succeed.
Buffer.allocUnsafe(2 * kStringMaxLength);
gc();
} catch (e) {
// If the exception is not due to memory confinement then rethrow it.
if (e.message !== 'Array buffer allocation failed') throw (e);
console.log(skipMessage);
return;
}

// Ensure we have enough memory available for future allocations to succeed.
if (!binding.ensureAllocation(2 * kStringMaxLength)) {
console.log(skipMessage);
return;
}

assert.throws(function() {
buf.toString('binary');
}, /"toString\(\)" failed/);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';
// Flags: --expose-gc

const common = require('../common');
const common = require('../../common');
const binding = require('./build/Release/binding');
const assert = require('assert');

const skipMessage =
Expand All @@ -10,24 +10,26 @@ if (!common.enoughTestMem) {
console.log(skipMessage);
return;
}
assert(typeof gc === 'function', 'Run this test with --expose-gc');

// v8 fails silently if string length > v8::String::kMaxLength
// v8::String::kMaxLength defined in v8.h
const kStringMaxLength = process.binding('buffer').kStringMaxLength;

try {
var buf = Buffer.allocUnsafe(kStringMaxLength + 1);
// Try to allocate memory first then force gc so future allocations succeed.
Buffer.allocUnsafe(2 * kStringMaxLength);
gc();
} catch (e) {
// If the exception is not due to memory confinement then rethrow it.
if (e.message !== 'Array buffer allocation failed') throw (e);
console.log(skipMessage);
return;
}

// Ensure we have enough memory available for future allocations to succeed.
if (!binding.ensureAllocation(2 * kStringMaxLength)) {
console.log(skipMessage);
return;
}

assert.throws(function() {
buf.toString('hex');
}, /"toString\(\)" failed/);
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';
// Flags: --expose-gc

const common = require('../common');
const common = require('../../common');
const binding = require('./build/Release/binding');
const assert = require('assert');

const skipMessage =
Expand All @@ -10,24 +10,26 @@ if (!common.enoughTestMem) {
console.log(skipMessage);
return;
}
assert(typeof gc === 'function', 'Run this test with --expose-gc');

// v8 fails silently if string length > v8::String::kMaxLength
// v8::String::kMaxLength defined in v8.h
const kStringMaxLength = process.binding('buffer').kStringMaxLength;

try {
var buf = Buffer.allocUnsafe(kStringMaxLength + 1);
// Try to allocate memory first then force gc so future allocations succeed.
Buffer.allocUnsafe(2 * kStringMaxLength);
gc();
} catch (e) {
// If the exception is not due to memory confinement then rethrow it.
if (e.message !== 'Array buffer allocation failed') throw (e);
console.log(skipMessage);
return;
}

// Ensure we have enough memory available for future allocations to succeed.
if (!binding.ensureAllocation(2 * kStringMaxLength)) {
console.log(skipMessage);
return;
}

assert.throws(function() {
buf.toString();
}, /"toString\(\)" failed|Array buffer allocation failed/);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';
// Flags: --expose-gc

const common = require('../common');
const common = require('../../common');
const binding = require('./build/Release/binding');
const assert = require('assert');

const skipMessage =
Expand All @@ -10,23 +10,25 @@ if (!common.enoughTestMem) {
console.log(skipMessage);
return;
}
assert(typeof gc === 'function', 'Run this test with --expose-gc');

// v8 fails silently if string length > v8::String::kMaxLength
// v8::String::kMaxLength defined in v8.h
const kStringMaxLength = process.binding('buffer').kStringMaxLength;

try {
var buf = Buffer.allocUnsafe(kStringMaxLength + 2);
// Try to allocate memory first then force gc so future allocations succeed.
Buffer.allocUnsafe(2 * kStringMaxLength);
gc();
} catch (e) {
// If the exception is not due to memory confinement then rethrow it.
if (e.message !== 'Array buffer allocation failed') throw (e);
console.log(skipMessage);
return;
}

// Ensure we have enough memory available for future allocations to succeed.
if (!binding.ensureAllocation(2 * kStringMaxLength)) {
console.log(skipMessage);
return;
}

const maxString = buf.toString('utf16le');
assert.equal(maxString.length, (kStringMaxLength + 2) / 2);
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';
// Flags: --expose-gc

const common = require('../common');
const common = require('../../common');
const binding = require('./build/Release/binding');
const assert = require('assert');

const skipMessage =
Expand All @@ -10,24 +10,26 @@ if (!common.enoughTestMem) {
console.log(skipMessage);
return;
}
assert(typeof gc === 'function', 'Run this test with --expose-gc');

// v8 fails silently if string length > v8::String::kMaxLength
// v8::String::kMaxLength defined in v8.h
const kStringMaxLength = process.binding('buffer').kStringMaxLength;

try {
var buf = Buffer.allocUnsafe(kStringMaxLength * 2 + 2);
// Try to allocate memory first then force gc so future allocations succeed.
Buffer.allocUnsafe(2 * kStringMaxLength);
gc();
} catch (e) {
// If the exception is not due to memory confinement then rethrow it.
if (e.message !== 'Array buffer allocation failed') throw (e);
console.log(skipMessage);
return;
}

// Ensure we have enough memory available for future allocations to succeed.
if (!binding.ensureAllocation(2 * kStringMaxLength)) {
console.log(skipMessage);
return;
}

assert.throws(function() {
buf.toString('utf16le');
}, /"toString\(\)" failed/);