fs-ext
Version:
Extensions to core 'fs' module.
314 lines (243 loc) • 9.06 kB
JavaScript
;
// Stress test these APIs as published in extension module 'fs-ext'
// Specifically, try to exercise any memory leaks by simple repetition.
// fs.seek(fd, offset, whence, [callback])
//
// Asynchronous lseek(2).
//
// callback will be given two arguments (err, currFilePos).
//
// whence can be 0 (SEEK_SET) to set the new position in bytes to offset,
// 1 (SEEK_CUR) to set the new position to the current position plus offset
// bytes (can be negative), or 2 (SEEK_END) to set to the end of the file
// plus offset bytes (usually negative or zero to seek to the end of the file).
//
// fs.seekSync(fd, offset, whence)
//
// Synchronous lseek(2). Throws an exception on error. Returns current
// file position.
// Ideas for testing borrowed from bnoordhuis (Ben Noordhuis)
// console.log( require.resolve('../fs-ext'));
var assert = require('assert'),
path = require('path'),
util = require('util'),
fs = require('../fs-ext'),
os = require('os');
var tests_ok = 0,
tests_run = 0;
var debug_me = true;
debug_me = false;
var tmp_dir = os.tmpdir(),
file_path = path.join(tmp_dir, 'what.when.seek.test'),
file_path_not = path.join(tmp_dir, 'what.not.seek.test');
var file_fd,
result,
err;
// Report on test results - - - - - - - - - - - -
// Clean up and report on final success or failure of tests here
process.addListener('exit', function() {
console.log('');
console.log(' After all testing:');
display_memory_usage_now();
console.log(' End time is %s', new Date());
try {
fs.closeSync(file_fd);
}
catch (e) {
// might not be open, that's okay.
}
remove_file_wo_error(file_path);
console.log('Tests run: %d ok: %d', tests_run, tests_ok);
assert.equal(tests_ok, tests_run, 'One or more subtests failed');
});
// Test helpers - - - - - - - - - - - - - - -
function remove_file_wo_error(file_path) {
try {
fs.unlinkSync(file_path);
}
catch (e) {
// might not exist, that's okay.
}
}
function display_memory_usage_now() {
var usage = process.memoryUsage();
console.log(' memory: heapUsed %d rss %d',
usage.heapUsed, usage.rss);
console.log(' heapTotal %d vsize %d',
usage.heapTotal, usage.vsize);
}
function expect_value(api_name, err, value_seen, value_expected) {
var fault_msg;
if ( err ) {
if ( err instanceof Error ) {
fault_msg = api_name + '(): returned error ' + err.message;
}
else {
fault_msg = api_name + '(): returned error ' + err;
}
}
else if ( value_seen !== value_expected ) {
fault_msg = api_name + '(): wrong value ' + value_seen +
' (expecting ' + value_expected + ')';
}
if ( ! fault_msg ) {
tests_ok++;
if (debug_me) console.log(' OK: %s() returned ', api_name, value_seen);
}
else {
console.log('FAILURE: ' + fault_msg);
console.log(' ARGS: ', util.inspect(arguments));
}
}
function expect_errno(api_name, err, value_seen, expected_errno) {
var fault_msg;
if (debug_me) console.log(' expected_errno(err): ' + err );
if ( err ) {
if ( err instanceof Error ) {
if ( err.code !== undefined ) {
if ( err.code !== expected_errno ) {
fault_msg = api_name + '(): returned wrong errno \'' + err.message +
'\' (expecting ' + expected_errno + ')';
}
}
else {
fault_msg = api_name + '(): returned wrong error \'' + err + '\'';
}
}
else {
fault_msg = api_name + '(): returned wrong error \'' + err + '\'';
}
}
else {
fault_msg = api_name + '(): expected errno \'' + expected_errno +
'\', but got result ' + value_seen;
}
if ( ! fault_msg ) {
tests_ok++;
if (debug_me) console.log(' FAILED OK: ' + api_name );
}
else {
console.log('FAILURE: ' + fault_msg);
if (debug_me) console.log(' ARGS: ', util.inspect(arguments));
}
}
// Setup for testing - - - - - - - - - - - -
// We assume that test-fs-seek.js has run successfully before this
// test and so we omit several duplicate tests.
// Delete any prior copy of test data file(s)
remove_file_wo_error(file_path);
// Create a new file
tests_run++;
try {
file_fd = fs.openSync(file_path, 'w');
tests_ok++;
}
catch (e) {
console.log(' Unable to create test data file %j', file_path);
console.log(' Error was: %j', e);
}
if ( tests_run !== tests_ok ) {
process.exit(1);
}
// Stress testing - - - - - - - - - - - - -
var how_many_times,
how_many_secs,
how_many_done;
console.log(' Start time is %s', new Date());
console.log(' Before any testing:');
display_memory_usage_now();
console.log('');
// If we do quite a lot of nothing, how much does memory change?
if (0) {
how_many_secs = 5;
setTimeout(function ho_hum(){
how_many_secs -= 1;
if (how_many_secs > 0 ) {
setTimeout(ho_hum, 1000);
return;
}
console.log(' After "do nothing" testing for %d seconds:', how_many_secs);
display_memory_usage_now();
console.log(' Time is %s', new Date());
},
1000 );
}
// Repeat a successful seekSync() call
if ( 1 ) {
how_many_times = 10000000;
//how_many_times = 4;
for ( var i=0 ; i<how_many_times ; i++ ) {
tests_run++;
result = err = undefined;
result = fs.seekSync(file_fd, 0, 0);
expect_value('seekSync', err, result, 0);
}
console.log(' After %d calls to successful seekSync():', how_many_times);
display_memory_usage_now();
console.log(' Time is %s', new Date());
}
// Repeat a successful seek() call
if ( 1 ) {
how_many_times = 1000000;
//how_many_times = 4;
how_many_done = 0;
tests_run++;
fs.seek(file_fd, 0, 0, function func_good_seek_cb(err, result){
expect_value('seek', err, result, 0);
if (debug_me) console.log(' seek call counter %d', how_many_times );
how_many_done += 1;
if ( how_many_done < how_many_times ) {
tests_run++;
fs.seek(file_fd, 0, 0, func_good_seek_cb );
return;
}
console.log(' After %d calls to successful seek():', how_many_times);
display_memory_usage_now();
console.log(' Time is %s', new Date());
test_failing_seek();
});
}
else {
test_failing_seek();
}
function test_failing_seek() {
if (1) {
how_many_times = 1000000;
//how_many_times = 4;
how_many_done = 0;
tests_run++;
fs.seek(-99, 0, 0, function func_good_seek_cb(err, result){
expect_errno('seek', err, result, 'EBADF');
if (debug_me) console.log(' seek call counter %d', how_many_times );
how_many_done += 1;
if ( how_many_done < how_many_times ) {
tests_run++;
fs.seek(-99, 0, 0, func_good_seek_cb );
return;
}
console.log(' After %d calls to failing seek():', how_many_times);
display_memory_usage_now();
console.log(' Time is %s', new Date());
});
}
}
//------------------------------------------------------------------------------
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//- - - - - - - - - - - - - - - - - - - - - - - - - -
// ### fs.seek(fd, offset, whence, [callback])
// ### fs.seekSync(fd, offset, whence)
// err { "stack": "TypeError: Bad argument\n at Object.seekSync (/home/Tom/study/javascript/node.js/baudehlo-node-fs-ext-3a489b7_/fs-ext.js:80:18)\n at Object.<anonymous> (/home/Tom/study/javascript/node.js/baudehlo-node-fs-ext-3a489b7_/tests/test-fs-seek.js:101:12)\n at Module._compile (module.js:407:26)\n at Object..js (module.js:413:10)\n at Module.load (module.js:339:31)\n at Function._load (module.js:298:12)\n at Array.0 (module.js:426:10)\n at EventEmitter._tickCallback (node.js:126:26)",
// "message": "Bad argument"}
// err { "stack": "Error: EBADF, Bad file descriptor\n at Object.seekSync (/home/Tom/study/javascript/node.js/baudehlo-node-fs-ext-3a489b7_/fs-ext.js:80:18)\n at Object.<anonymous> (/home/Tom/study/javascript/node.js/baudehlo-node-fs-ext-3a489b7_/tests/test-fs-seek.js:137:12)\n at Module._compile (module.js:407:26)\n at Object..js (module.js:413:10)\n at Module.load (module.js:339:31)\n at Function._load (module.js:298:12)\n at Array.0 (module.js:426:10)\n at EventEmitter._tickCallback (node.js:126:26)",
// "message": "EBADF, Bad file descriptor",
// "errno": 9,
// "code": "EBADF"}
//XXX Does seek() return current position correctly?
// fseek() doesn't return positions, only ftell() does that
// ahh, but lseek() does return current positions !!!
//
// RETURN VALUE
// Upon successful completion, lseek() returns the resulting offset loca‐
// tion as measured in bytes from the beginning of the file. On error,
// the value (off_t) -1 is returned and errno is set to indicate the
// error.